diff options
author | Malfurious <m@lfurio.us> | 2024-10-24 06:44:24 -0400 |
---|---|---|
committer | Malfurious <m@lfurio.us> | 2024-10-24 06:44:24 -0400 |
commit | 512aa4c77b3dc0d72db713a9215ff65a98a99ec3 (patch) | |
tree | 6db82e0109dc987b5b021f81d4e8a0926eb75ff7 /cryptopp562/fipsalgt.cpp | |
parent | 428471d39fb8c205a9fad899c88c30a2cb7df685 (diff) | |
parent | 10affea371406c0ae4c080e5a19390a8e9bd154b (diff) | |
download | compass-512aa4c77b3dc0d72db713a9215ff65a98a99ec3.tar.gz compass-512aa4c77b3dc0d72db713a9215ff65a98a99ec3.zip |
Merge branch 'mbedtls'
Replace Crypto++ 5.6.2 with Mbed TLS 3.6.0
Newer compilers are starting to show the age of the crypto library we've
been using, as it is sometimes a pain to recompile compass lately. So,
the tracked version of Crypto++ was at least due for an upgrade.
However, I plan to soon begin reimplementing compass in C. So, I'm
taking this opportunity to first just migrate the cryptography library
to a newer C alternative. This branch does so, and integrates its use
into the current C++ version of compass.
* mbedtls:
Remove unnecessary exception handler catch block
Refactor random password generation to use mbedtls entropy source
Refactor SHA256 function to use mbedtls
Refactor AES functions to use mbedtls
Add Mbedtls library
Remove Crypto++ library
Diffstat (limited to 'cryptopp562/fipsalgt.cpp')
-rw-r--r-- | cryptopp562/fipsalgt.cpp | 1290 |
1 files changed, 0 insertions, 1290 deletions
diff --git a/cryptopp562/fipsalgt.cpp b/cryptopp562/fipsalgt.cpp deleted file mode 100644 index 92c254f..0000000 --- a/cryptopp562/fipsalgt.cpp +++ /dev/null @@ -1,1290 +0,0 @@ -// 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()); - OutputData(output, "Q ", pqg.GetSubgroupOrder()); - OutputData(output, "G ", pqg.GetSubgroupGenerator()); - - int n = atol(m_data["N"].c_str()); - for (int i=0; i<n; i++) - { - DSA::Signer priv; - priv.AccessKey().GenerateRandom(m_rng, pqg); - DSA::Verifier pub(priv); - - OutputData(output, "X ", priv.GetKey().GetPrivateExponent()); - OutputData(output, "Y ", pub.GetKey().GetPublicElement()); - AttachedTransformation()->Put((byte *)output.data(), output.size()); - output.resize(0); - } - } - else if (m_test == "PQGGen") - { - int n = atol(m_data["N"].c_str()); - for (int i=0; i<n; i++) - { - Integer p, q, h, g; - int counter; - - SecByteBlock seed(SHA::DIGESTSIZE); - do - { - m_rng.GenerateBlock(seed, seed.size()); - } - while (!DSA::GeneratePrimes(seed, seed.size()*8, counter, p, 1024, q)); - h.Randomize(m_rng, 2, p-2); - g = a_exp_b_mod_c(h, (p-1)/q, p); - - OutputData(output, "P ", p); - OutputData(output, "Q ", q); - OutputData(output, "G ", g); - OutputData(output, "Seed ", seed); - OutputData(output, "c ", counter); - OutputData(output, "H ", h, p.ByteCount()); - AttachedTransformation()->Put((byte *)output.data(), output.size()); - output.resize(0); - } - } - else if (m_test == "SigGen") - { - std::string &encodedKey = m_data["PrivKey"]; - int modLen = atol(m_bracketString.substr(6).c_str()); - DSA::PrivateKey priv; - - if (!encodedKey.empty()) - { - StringStore s(encodedKey); - priv.BERDecode(s); - if (priv.GetGroupParameters().GetModulus().BitCount() != modLen) - encodedKey.clear(); - } - - if (encodedKey.empty()) - { - priv.Initialize(m_rng, modLen); - StringSink s(encodedKey); - priv.DEREncode(s); - OutputData(output, "P ", priv.GetGroupParameters().GetModulus()); - OutputData(output, "Q ", priv.GetGroupParameters().GetSubgroupOrder()); - OutputData(output, "G ", priv.GetGroupParameters().GetSubgroupGenerator()); - } - - DSA::Signer signer(priv); - DSA::Verifier pub(signer); - OutputData(output, "Msg ", m_data["Msg"]); - OutputData(output, "Y ", pub.GetKey().GetPublicElement()); - - 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, "R ", R); - OutputData(output, "S ", S); - AttachedTransformation()->Put((byte *)output.data(), output.size()); - output.resize(0); - } - else if (m_test == "SigVer") - { - Integer p((m_data["P"] + "h").c_str()); - Integer q((m_data["Q"] + "h").c_str()); - Integer g((m_data["G"] + "h").c_str()); - Integer y((m_data["Y"] + "h").c_str()); - DSA::Verifier verifier(p, q, g, y); - - HexDecoder filter(new SignatureVerificationFilter(verifier)); - StringSource(m_data["R"], true, new Redirector(filter, Redirector::DATA_ONLY)); - StringSource(m_data["S"], true, new Redirector(filter, Redirector::DATA_ONLY)); - StringSource(m_data["Msg"], true, new Redirector(filter, Redirector::DATA_ONLY)); - filter.MessageEnd(); - byte b; - filter.Get(b); - OutputData(output, "Result ", b ? "P" : "F"); - AttachedTransformation()->Put((byte *)output.data(), output.size()); - output.resize(0); - } - else if (m_test == "PQGVer") - { - Integer p((m_data["P"] + "h").c_str()); - Integer q((m_data["Q"] + "h").c_str()); - Integer g((m_data["G"] + "h").c_str()); - Integer h((m_data["H"] + "h").c_str()); - int c = atol(m_data["c"].c_str()); - SecByteBlock seed(m_data["Seed"].size()/2); - StringSource(m_data["Seed"], true, new HexDecoder(new ArraySink(seed, seed.size()))); - - Integer p1, q1; - bool result = DSA::GeneratePrimes(seed, seed.size()*8, c, p1, 1024, q1, true); - result = result && (p1 == p && q1 == q); - result = result && g == a_exp_b_mod_c(h, (p-1)/q, p); - - OutputData(output, "Result ", result ? "P" : "F"); - AttachedTransformation()->Put((byte *)output.data(), output.size()); - output.resize(0); - } - - return; - } - - if (m_algorithm == "ECDSA") - { - std::map<std::string, OID> name2oid; - name2oid["P-192"] = ASN1::secp192r1(); - name2oid["P-224"] = ASN1::secp224r1(); - name2oid["P-256"] = ASN1::secp256r1(); - name2oid["P-384"] = ASN1::secp384r1(); - name2oid["P-521"] = ASN1::secp521r1(); - name2oid["K-163"] = ASN1::sect163k1(); - name2oid["K-233"] = ASN1::sect233k1(); - name2oid["K-283"] = ASN1::sect283k1(); - name2oid["K-409"] = ASN1::sect409k1(); - name2oid["K-571"] = ASN1::sect571k1(); - name2oid["B-163"] = ASN1::sect163r2(); - name2oid["B-233"] = ASN1::sect233r1(); - name2oid["B-283"] = ASN1::sect283r1(); - name2oid["B-409"] = ASN1::sect409r1(); - name2oid["B-571"] = ASN1::sect571r1(); - - if (m_test == "PKV") - { - bool pass; - if (m_bracketString[0] == 'P') - pass = EC_PKV<ECP>(m_rng, DecodeHex(m_data["Qx"]), DecodeHex(m_data["Qy"]), name2oid[m_bracketString]); - else - pass = EC_PKV<EC2N>(m_rng, DecodeHex(m_data["Qx"]), DecodeHex(m_data["Qy"]), name2oid[m_bracketString]); - - OutputData(output, "Result ", pass ? "P" : "F"); - } - else if (m_test == "KeyPair") - { - if (m_bracketString[0] == 'P') - EC_KeyPair<ECP>(output, atol(m_data["N"].c_str()), name2oid[m_bracketString]); - else - EC_KeyPair<EC2N>(output, atol(m_data["N"].c_str()), name2oid[m_bracketString]); - } - else if (m_test == "SigGen") - { - if (m_bracketString[0] == 'P') - EC_SigGen<ECP>(output, name2oid[m_bracketString]); - else - EC_SigGen<EC2N>(output, name2oid[m_bracketString]); - } - else if (m_test == "SigVer") - { - if (m_bracketString[0] == 'P') - EC_SigVer<ECP>(output, name2oid[m_bracketString]); - else - EC_SigVer<EC2N>(output, name2oid[m_bracketString]); - } - - AttachedTransformation()->Put((byte *)output.data(), output.size()); - output.resize(0); - return; - } - - if (m_algorithm == "RSA") - { - std::string shaAlg = m_data["SHAAlg"].substr(3); - - if (m_test == "Ver") - { - Integer n((m_data["n"] + "h").c_str()); - Integer e((m_data["e"] + "h").c_str()); - RSA::PublicKey pub; - pub.Initialize(n, e); - - member_ptr<PK_Verifier> pV(CreateRSA<PK_Verifier>(m_mode, shaAlg)); - pV->AccessMaterial().AssignFrom(pub); - - HexDecoder filter(new SignatureVerificationFilter(*pV)); - for (unsigned int i=m_data["S"].size(); i<pV->SignatureLength()*2; i++) - filter.Put('0'); - StringSource(m_data["S"], true, new Redirector(filter, Redirector::DATA_ONLY)); - StringSource(m_data["Msg"], true, new Redirector(filter, Redirector::DATA_ONLY)); - filter.MessageEnd(); - byte b; - filter.Get(b); - OutputData(output, "Result ", b ? "P" : "F"); - } - else - { - assert(m_test == "Gen"); - int modLen = atol(m_bracketString.substr(6).c_str()); - std::string &encodedKey = m_data["PrivKey"]; - RSA::PrivateKey priv; - - if (!encodedKey.empty()) - { - StringStore s(encodedKey); - priv.BERDecode(s); - if (priv.GetModulus().BitCount() != modLen) - encodedKey.clear(); - } - - if (encodedKey.empty()) - { - priv.Initialize(m_rng, modLen); - StringSink s(encodedKey); - priv.DEREncode(s); - OutputData(output, "n ", priv.GetModulus()); - OutputData(output, "e ", priv.GetPublicExponent(), modLen/8); - } - - member_ptr<PK_Signer> pS(CreateRSA<PK_Signer>(m_mode, shaAlg)); - pS->AccessMaterial().AssignFrom(priv); - - SecByteBlock sig(pS->SignatureLength()); - StringSource(m_data["Msg"], true, new HexDecoder(new SignerFilter(m_rng, *pS, new ArraySink(sig, sig.size())))); - OutputData(output, "SHAAlg ", m_data["SHAAlg"]); - OutputData(output, "Msg ", m_data["Msg"]); - OutputData(output, "S ", sig); - } - - AttachedTransformation()->Put((byte *)output.data(), output.size()); - output.resize(0); - return; - } - - if (m_algorithm == "SHA") - { - member_ptr<HashFunction> pHF; - - if (m_mode == "1") - pHF.reset(new SHA1); - else if (m_mode == "224") - pHF.reset(new SHA224); - else if (m_mode == "256") - pHF.reset(new SHA256); - else if (m_mode == "384") - pHF.reset(new SHA384); - else if (m_mode == "512") - pHF.reset(new SHA512); - - if (m_test == "MONTE") - { - SecByteBlock seed = m_data2[INPUT]; - SecByteBlock MD[1003]; - int i,j; - - for (j=0; j<100; j++) - { - MD[0] = MD[1] = MD[2] = seed; - for (i=3; i<1003; i++) - { - SecByteBlock Mi = MD[i-3] + MD[i-2] + MD[i-1]; - MD[i].resize(pHF->DigestSize()); - pHF->CalculateDigest(MD[i], Mi, Mi.size()); - } - seed = MD[1002]; - OutputData(output, "COUNT ", j); - OutputData(output, "MD ", seed); - AttachedTransformation()->Put((byte *)output.data(), output.size()); - output.resize(0); - } - } - else - { - SecByteBlock tag(pHF->DigestSize()); - SecByteBlock &msg(m_data2[INPUT]); - int len = atol(m_data["Len"].c_str()); - StringSource(msg.begin(), len/8, true, new HashFilter(*pHF, new ArraySink(tag, tag.size()))); - OutputData(output, "MD ", tag); - AttachedTransformation()->Put((byte *)output.data(), output.size()); - output.resize(0); - } - return; - } - - SecByteBlock &key = m_data2[KEY_T]; - - if (m_algorithm == "TDES") - { - if (!m_data["KEY1"].empty()) - { - const std::string keys[3] = {m_data["KEY1"], m_data["KEY2"], m_data["KEY3"]}; - key.resize(24); - HexDecoder hexDec(new ArraySink(key, key.size())); - for (int i=0; i<3; i++) - hexDec.Put((byte *)keys[i].data(), keys[i].size()); - - if (keys[0] == keys[2]) - { - if (keys[0] == keys[1]) - key.resize(8); - else - key.resize(16); - } - else - key.resize(24); - } - } - - if (m_algorithm == "RNG") - { - key.resize(24); - StringSource(m_data["Key1"] + m_data["Key2"] + m_data["Key3"], true, new HexDecoder(new ArraySink(key, key.size()))); - - SecByteBlock seed(m_data2[INPUT]), dt(m_data2[IV]), r(8); - X917RNG rng(new DES_EDE3::Encryption(key, key.size()), seed, dt); - - if (m_test == "MCT") - { - for (int i=0; i<10000; i++) - rng.GenerateBlock(r, r.size()); - } - else - { - rng.GenerateBlock(r, r.size()); - } - - OutputData(output, "R ", r); - AttachedTransformation()->Put((byte *)output.data(), output.size()); - output.resize(0); - return; - } - - if (m_algorithm == "HMAC") - { - member_ptr<MessageAuthenticationCode> pMAC; - - if (m_bracketString == "L=20") - pMAC.reset(new HMAC<SHA1>); - else if (m_bracketString == "L=28") - pMAC.reset(new HMAC<SHA224>); - else if (m_bracketString == "L=32") - pMAC.reset(new HMAC<SHA256>); - else if (m_bracketString == "L=48") - pMAC.reset(new HMAC<SHA384>); - else if (m_bracketString == "L=64") - pMAC.reset(new HMAC<SHA512>); - else - throw Exception(Exception::OTHER_ERROR, "TestDataParser: unexpected HMAC bracket string: " + m_bracketString); - - pMAC->SetKey(key, key.size()); - int Tlen = atol(m_data["Tlen"].c_str()); - SecByteBlock tag(Tlen); - StringSource(m_data["Msg"], true, new HexDecoder(new HashFilter(*pMAC, new ArraySink(tag, Tlen), false, Tlen))); - OutputData(output, "Mac ", tag); - AttachedTransformation()->Put((byte *)output.data(), output.size()); - output.resize(0); - return; - } - - member_ptr<BlockCipher> pBT; - if (m_algorithm == "DES") - pBT.reset(NewBT((DES*)0)); - else if (m_algorithm == "TDES") - { - if (key.size() == 8) - pBT.reset(NewBT((DES*)0)); - else if (key.size() == 16) - pBT.reset(NewBT((DES_EDE2*)0)); - else - pBT.reset(NewBT((DES_EDE3*)0)); - } - else if (m_algorithm == "SKIPJACK") - pBT.reset(NewBT((SKIPJACK*)0)); - else if (m_algorithm == "AES") - pBT.reset(NewBT((AES*)0)); - else - throw Exception(Exception::OTHER_ERROR, "TestDataParser: unexpected algorithm: " + m_algorithm); - - if (!pBT->IsValidKeyLength(key.size())) - key.CleanNew(pBT->DefaultKeyLength()); // for Scbcvrct - pBT->SetKey(key.data(), key.size()); - - SecByteBlock &iv = m_data2[IV]; - if (iv.empty()) - iv.CleanNew(pBT->BlockSize()); - - member_ptr<SymmetricCipher> pCipher; - unsigned int K = m_feedbackSize; - - if (m_mode == "ECB") - pCipher.reset(NewMode((ECB_Mode_ExternalCipher*)0, *pBT, iv)); - else if (m_mode == "CBC") - pCipher.reset(NewMode((CBC_Mode_ExternalCipher*)0, *pBT, iv)); - else if (m_mode == "CFB") - pCipher.reset(NewMode((CFB_Mode_ExternalCipher*)0, *pBT, iv)); - else if (m_mode == "OFB") - pCipher.reset(NewMode((OFB_Mode_ExternalCipher*)0, *pBT, iv)); - else - throw Exception(Exception::OTHER_ERROR, "TestDataParser: unexpected mode: " + m_mode); - - bool encrypt = m_encrypt; - - if (m_test == "MONTE") - { - SecByteBlock KEY[401]; - KEY[0] = key; - int keySize = key.size(); - int blockSize = pBT->BlockSize(); - - std::vector<SecByteBlock> IB(10001), OB(10001), PT(10001), CT(10001), RESULT(10001), TXT(10001), CV(10001); - PT[0] = GetData("PLAINTEXT"); - CT[0] = GetData("CIPHERTEXT"); - CV[0] = IB[0] = iv; - TXT[0] = GetData("TEXT"); - - int outerCount = (m_algorithm == "AES") ? 100 : 400; - int innerCount = (m_algorithm == "AES") ? 1000 : 10000; - - for (int i=0; i<outerCount; i++) - { - pBT->SetKey(KEY[i], keySize); - - for (int j=0; j<innerCount; j++) - { - if (m_mode == "ECB") - { - if (encrypt) - { - IB[j] = PT[j]; - CT[j].resize(blockSize); - pBT->ProcessBlock(IB[j], CT[j]); - PT[j+1] = CT[j]; - } - else - { - IB[j] = CT[j]; - PT[j].resize(blockSize); - pBT->ProcessBlock(IB[j], PT[j]); - CT[j+1] = PT[j]; - } - } - else if (m_mode == "OFB") - { - OB[j].resize(blockSize); - pBT->ProcessBlock(IB[j], OB[j]); - Xor(RESULT[j], OB[j], TXT[j]); - TXT[j+1] = IB[j]; - IB[j+1] = OB[j]; - } - else if (m_mode == "CBC") - { - if (encrypt) - { - Xor(IB[j], PT[j], CV[j]); - CT[j].resize(blockSize); - pBT->ProcessBlock(IB[j], CT[j]); - PT[j+1] = CV[j]; - CV[j+1] = CT[j]; - } - else - { - IB[j] = CT[j]; - OB[j].resize(blockSize); - pBT->ProcessBlock(IB[j], OB[j]); - Xor(PT[j], OB[j], CV[j]); - CV[j+1] = CT[j]; - CT[j+1] = PT[j]; - } - } - else if (m_mode == "CFB") - { - if (encrypt) - { - OB[j].resize(blockSize); - pBT->ProcessBlock(IB[j], OB[j]); - AssignLeftMostBits(CT[j], OB[j], K); - Xor(CT[j], CT[j], PT[j]); - AssignLeftMostBits(PT[j+1], IB[j], K); - IB[j+1].resize(blockSize); - memcpy(IB[j+1], IB[j]+K/8, blockSize-K/8); - memcpy(IB[j+1]+blockSize-K/8, CT[j], K/8); - } - else - { - OB[j].resize(blockSize); - pBT->ProcessBlock(IB[j], OB[j]); - AssignLeftMostBits(PT[j], OB[j], K); - Xor(PT[j], PT[j], CT[j]); - IB[j+1].resize(blockSize); - memcpy(IB[j+1], IB[j]+K/8, blockSize-K/8); - memcpy(IB[j+1]+blockSize-K/8, CT[j], K/8); - AssignLeftMostBits(CT[j+1], OB[j], K); - } - } - else - throw Exception(Exception::OTHER_ERROR, "TestDataParser: unexpected mode: " + m_mode); - } - - OutputData(output, COUNT, IntToString(i)); - OutputData(output, KEY_T, KEY[i]); - if (m_mode == "CBC") - OutputData(output, IV, CV[0]); - if (m_mode == "OFB" || m_mode == "CFB") - OutputData(output, IV, IB[0]); - if (m_mode == "ECB" || m_mode == "CBC" || m_mode == "CFB") - { - if (encrypt) - { - OutputData(output, INPUT, PT[0]); - OutputData(output, OUTPUT, CT[innerCount-1]); - KEY[i+1] = UpdateKey(KEY[i], &CT[0]); - } - else - { - OutputData(output, INPUT, CT[0]); - OutputData(output, OUTPUT, PT[innerCount-1]); - KEY[i+1] = UpdateKey(KEY[i], &PT[0]); - } - PT[0] = PT[innerCount]; - IB[0] = IB[innerCount]; - CV[0] = CV[innerCount]; - CT[0] = CT[innerCount]; - } - else if (m_mode == "OFB") - { - OutputData(output, INPUT, TXT[0]); - OutputData(output, OUTPUT, RESULT[innerCount-1]); - KEY[i+1] = UpdateKey(KEY[i], &RESULT[0]); - Xor(TXT[0], TXT[0], IB[innerCount-1]); - IB[0] = OB[innerCount-1]; - } - output += "\n"; - AttachedTransformation()->Put((byte *)output.data(), output.size()); - output.resize(0); - } - } - else if (m_test == "MCT") - { - SecByteBlock KEY[101]; - KEY[0] = key; - int keySize = key.size(); - int blockSize = pBT->BlockSize(); - - SecByteBlock ivs[101], inputs[1001], outputs[1001]; - ivs[0] = iv; - inputs[0] = m_data2[INPUT]; - - for (int i=0; i<100; i++) - { - pCipher->SetKey(KEY[i], keySize, MakeParameters(Name::IV(), (const byte *)ivs[i])(Name::FeedbackSize(), (int)K/8, false)); - - for (int j=0; j<1000; j++) - { - outputs[j] = inputs[j]; - pCipher->ProcessString(outputs[j], outputs[j].size()); - if (K==8 && m_mode == "CFB") - { - if (j<16) - inputs[j+1].Assign(ivs[i]+j, 1); - else - inputs[j+1] = outputs[j-16]; - } - else if (m_mode == "ECB") - inputs[j+1] = outputs[j]; - else if (j == 0) - inputs[j+1] = ivs[i]; - else - inputs[j+1] = outputs[j-1]; - } - - if (m_algorithm == "AES") - OutputData(output, COUNT, m_count++); - OutputData(output, KEY_T, KEY[i]); - if (m_mode != "ECB") - OutputData(output, IV, ivs[i]); - OutputData(output, INPUT, inputs[0]); - OutputData(output, OUTPUT, outputs[999]); - output += "\n"; - AttachedTransformation()->Put((byte *)output.data(), output.size()); - output.resize(0); - - KEY[i+1] = UpdateKey(KEY[i], outputs); - ivs[i+1].CleanNew(pCipher->IVSize()); - ivs[i+1] = UpdateKey(ivs[i+1], outputs); - if (K==8 && m_mode == "CFB") - inputs[0] = outputs[999-16]; - else if (m_mode == "ECB") - inputs[0] = outputs[999]; - else - inputs[0] = outputs[998]; - } - } - else - { - assert(m_test == "KAT"); - - SecByteBlock &input = m_data2[INPUT]; - SecByteBlock result(input.size()); - member_ptr<Filter> pFilter(new StreamTransformationFilter(*pCipher, new ArraySink(result, result.size()), StreamTransformationFilter::NO_PADDING)); - StringSource(input.data(), input.size(), true, pFilter.release()); - - OutputGivenData(output, COUNT, true); - OutputData(output, KEY_T, key); - OutputGivenData(output, IV, true); - OutputGivenData(output, INPUT); - OutputData(output, OUTPUT, result); - output += "\n"; - AttachedTransformation()->Put((byte *)output.data(), output.size()); - } - } - - std::vector<std::string> Tokenize(const std::string &line) - { - std::vector<std::string> result; - std::string s; - for (unsigned int i=0; i<line.size(); i++) - { - if (isalnum(line[i]) || line[i] == '^') - s += line[i]; - else if (!s.empty()) - { - result.push_back(s); - s = ""; - } - if (line[i] == '=') - result.push_back("="); - } - if (!s.empty()) - result.push_back(s); - return result; - } - - bool IsolatedMessageEnd(bool blocking) - { - if (!blocking) - throw BlockingInputOnly("TestDataParser"); - - m_line.resize(0); - m_inQueue.TransferTo(StringSink(m_line).Ref()); - - if (m_line[0] == '#') - return false; - - bool copyLine = false; - - if (m_line[0] == '[') - { - m_bracketString = m_line.substr(1, m_line.size()-2); - if (m_bracketString == "ENCRYPT") - SetEncrypt(true); - if (m_bracketString == "DECRYPT") - SetEncrypt(false); - copyLine = true; - } - - if (m_line.substr(0, 2) == "H>") - { - assert(m_test == "sha"); - m_bracketString = m_line.substr(2, m_line.size()-4); - m_line = m_line.substr(0, 13) + "Hashes<H"; - copyLine = true; - } - - if (m_line == "D>") - copyLine = true; - - if (m_line == "<D") - { - m_line += "\n"; - copyLine = true; - } - - if (copyLine) - { - m_line += '\n'; - AttachedTransformation()->Put((byte *)m_line.data(), m_line.size(), blocking); - return false; - } - - std::vector<std::string> tokens = Tokenize(m_line); - - if (m_algorithm == "DSA" && m_test == "sha") - { - for (unsigned int i = 0; i < tokens.size(); i++) - { - if (tokens[i] == "^") - DoTest(); - else if (tokens[i] != "") - m_compactString.push_back(atol(tokens[i].c_str())); - } - } - else - { - 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")))) - { - // copy input to output - std::string output = m_line + '\n'; - AttachedTransformation()->Put((byte *)output.data(), output.size()); - } - - for (unsigned int i = 0; i < tokens.size(); i++) - { - if (m_firstLine && m_algorithm != "DSA") - { - if (tokens[i] == "Encrypt" || tokens[i] == "OFB") - SetEncrypt(true); - else if (tokens[i] == "Decrypt") - SetEncrypt(false); - else if (tokens[i] == "Modes") - m_test = "MONTE"; - } - else - { - if (tokens[i] != "=") - continue; - - if (i == 0) - throw Exception(Exception::OTHER_ERROR, "TestDataParser: unexpected data: " + m_line); - - const std::string &key = tokens[i-1]; - std::string &data = m_data[key]; - data = (tokens.size() > i+1) ? tokens[i+1] : ""; - DataType t = m_nameToType[key]; - m_typeToName[t] = key; - m_data2[t] = DecodeHex(data); - - if (key == m_trigger || (t == OUTPUT && !m_data2[INPUT].empty() && !isspace(m_line[0]))) - DoTest(); - } - } - } - - m_firstLine = false; - - return false; - } - - inline const SecByteBlock & GetData(const std::string &key) - { - return m_data2[m_nameToType[key]]; - } - - static SecByteBlock DecodeHex(const std::string &data) - { - SecByteBlock data2(data.size() / 2); - StringSource(data, true, new HexDecoder(new ArraySink(data2, data2.size()))); - return data2; - } - - std::string m_algorithm, m_test, m_mode, m_line, m_bracketString, m_trigger; - unsigned int m_feedbackSize, m_blankLineTransition; - bool m_encrypt, m_firstLine; - - typedef std::map<std::string, DataType> NameToTypeMap; - NameToTypeMap m_nameToType; - typedef std::map<DataType, std::string> TypeToNameMap; - TypeToNameMap m_typeToName; - - typedef std::map<std::string, std::string> Map; - Map m_data; // raw data - typedef std::map<DataType, SecByteBlock> Map2; - Map2 m_data2; - int m_count; - - AutoSeededX917RNG<AES> m_rng; - std::vector<unsigned int> m_compactString; -}; - -int FIPS_140_AlgorithmTest(int argc, char **argv) -{ - argc--; - argv++; - - std::string algorithm = argv[1]; - std::string pathname = argv[2]; - unsigned int i = pathname.find_last_of("\\/"); - std::string filename = pathname.substr(i == std::string::npos ? 0 : i+1); - std::string dirname = pathname.substr(0, i); - - if (algorithm == "auto") - { - string algTable[] = {"AES", "ECDSA", "DSA", "HMAC", "RNG", "RSA", "TDES", "SKIPJACK", "SHA"}; // order is important here - for (i=0; i<sizeof(algTable)/sizeof(algTable[0]); i++) - { - if (dirname.find(algTable[i]) != std::string::npos) - { - algorithm = algTable[i]; - break; - } - } - } - - try - { - std::string mode; - if (algorithm == "SHA") - mode = IntToString(atol(filename.substr(3, 3).c_str())); - else if (algorithm == "RSA") - mode = filename.substr(6, 1); - else if (filename[0] == 'S' || filename[0] == 'T') - mode = filename.substr(1, 3); - else - mode = filename.substr(0, 3); - for (i = 0; i<mode.size(); i++) - mode[i] = toupper(mode[i]); - unsigned int feedbackSize = mode == "CFB" ? atoi(filename.substr(filename.find_first_of("0123456789")).c_str()) : 0; - std::string test; - if (algorithm == "DSA" || algorithm == "ECDSA") - test = filename.substr(0, filename.size() - 4); - else if (algorithm == "RSA") - test = filename.substr(3, 3); - else if (filename.find("Monte") != std::string::npos) - test = "MONTE"; - else if (filename.find("MCT") != std::string::npos) - test = "MCT"; - else - test = "KAT"; - bool encrypt = (filename.find("vrct") == std::string::npos); - - BufferedTransformation *pSink = NULL; - - if (argc > 3) - { - std::string outDir = argv[3]; - - if (outDir == "auto") - { - if (dirname.substr(dirname.size()-3) == "req") - outDir = dirname.substr(0, dirname.size()-3) + "resp"; - } - - if (*outDir.rbegin() != '\\' && *outDir.rbegin() != '/') - outDir += '/'; - std::string outPathname = outDir + filename.substr(0, filename.size() - 3) + "rsp"; - pSink = new FileSink(outPathname.c_str(), false); - } - else - pSink = new FileSink(cout); - - FileSource(pathname.c_str(), true, new LineBreakParser(new TestDataParser(algorithm, test, mode, feedbackSize, encrypt, pSink)), false); - } - catch (...) - { - cout << "file: " << filename << endl; - throw; - } - return 0; -} - -extern int (*AdhocTest)(int argc, char *argv[]); -static int s_i = (AdhocTest = &FIPS_140_AlgorithmTest, 0); -#endif |