// validat7.cpp - originally written and placed in the public domain by Wei Dai // CryptoPP::Test namespace added by JW in February 2017. // Source files split in July 2018 to expedite compiles. #include "pch.h" #define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 #include "cryptlib.h" #include "cpu.h" #include "validate.h" #include "asn.h" #include "oids.h" #include "sha.h" #include "sha3.h" #include "dh.h" #include "luc.h" #include "mqv.h" #include "xtr.h" #include "hmqv.h" #include "pubkey.h" #include "xtrcrypt.h" #include "eccrypto.h" // Curve25519 #include "xed25519.h" #include "donna.h" #include "naclite.h" #include #include #include // Aggressive stack checking with VS2005 SP1 and above. #if (_MSC_FULL_VER >= 140050727) # pragma strict_gs_check (on) #endif #if CRYPTOPP_MSC_VERSION # pragma warning(disable: 4505 4355) #endif NAMESPACE_BEGIN(CryptoPP) NAMESPACE_BEGIN(Test) ANONYMOUS_NAMESPACE_BEGIN inline bool operator==(const x25519& lhs, const x25519& rhs) { // This is a hack because the KeyAgreement classes do not make it easy to access the PrivateKey ByteQueue q1, q2; lhs.DEREncodePrivateKey(q1); rhs.DEREncodePrivateKey(q2); return q1 == q2; } inline bool operator!=(const x25519& lhs, const x25519& rhs) { return !operator==(lhs, rhs); } ANONYMOUS_NAMESPACE_END bool ValidateDH() { std::cout << "\nDH validation suite running...\n\n"; FileSource f(DataDir("TestData/dh1024.dat").c_str(), true, new HexDecoder); DH dh(f); return SimpleKeyAgreementValidate(dh); } bool ValidateX25519() { std::cout << "\nx25519 validation suite running...\n\n"; FileSource f(DataDir("TestData/x25519.dat").c_str(), true, new HexDecoder); x25519 dh(f); return SimpleKeyAgreementValidate(dh); } bool ValidateMQV() { std::cout << "\nMQV validation suite running...\n\n"; FileSource f(DataDir("TestData/mqv1024.dat").c_str(), true, new HexDecoder); MQV mqv(f); return AuthenticatedKeyAgreementValidate(mqv); } bool ValidateHMQV() { std::cout << "\nHMQV validation suite running...\n\n"; bool success = true, fail; FileSource f256(DataDir("TestData/hmqv256.dat").c_str(), true, new HexDecoder); FileSource f384(DataDir("TestData/hmqv384.dat").c_str(), true, new HexDecoder); FileSource f512(DataDir("TestData/hmqv512.dat").c_str(), true, new HexDecoder); ///////////////////////// std::cout << "HMQV with NIST P-256 and SHA-256:" << std::endl; ECHMQV256 hmqvB256(false); hmqvB256.AccessGroupParameters().BERDecode(f256); const OID oid = ASN1::secp256r1(); ECHMQV< ECP >::Domain hmqvA256(oid, true /*client*/); fail = !AuthenticatedKeyAgreementWithRolesValidate(hmqvA256, hmqvB256); success = !fail && success; if (fail == false) std::cout << "passed authenticated key agreement" << std::endl; else std::cout << "FAILED authenticated key agreement" << std::endl; ///////////////////////// std::cout << "HMQV with NIST P-384 and SHA-384:" << std::endl; ECHMQV384 hmqvB384(false); hmqvB384.AccessGroupParameters().BERDecode(f384); const OID oid384 = ASN1::secp384r1(); ECHMQV384 hmqvA384(oid384, true /*client*/); fail = !AuthenticatedKeyAgreementWithRolesValidate(hmqvA384, hmqvB384); success = !fail && success; if (fail == false) std::cout << "passed authenticated key agreement" << std::endl; else std::cout << "FAILED authenticated key agreement" << std::endl; ///////////////////////// std::cout << "HMQV with NIST P-521 and SHA-512:" << std::endl; ECHMQV512 hmqvB521(false); hmqvB521.AccessGroupParameters().BERDecode(f512); const OID oid521 = ASN1::secp521r1(); ECHMQV512 hmqvA521(oid521, true /*client*/); fail = !AuthenticatedKeyAgreementWithRolesValidate(hmqvA521, hmqvB521); success = !fail && success; if (fail == false) std::cout << "passed authenticated key agreement" << std::endl; else std::cout << "FAILED authenticated key agreement" << std::endl; return success; } bool ValidateFHMQV() { std::cout << "\nFHMQV validation suite running...\n\n"; bool success = true, fail; FileSource f256(DataDir("TestData/fhmqv256.dat").c_str(), true, new HexDecoder); FileSource f384(DataDir("TestData/fhmqv384.dat").c_str(), true, new HexDecoder); FileSource f512(DataDir("TestData/fhmqv512.dat").c_str(), true, new HexDecoder); ///////////////////////// std::cout << "FHMQV with NIST P-256 and SHA-256:" << std::endl; ECFHMQV256 fhmqvB256(false); fhmqvB256.AccessGroupParameters().BERDecode(f256); const OID oid = ASN1::secp256r1(); ECFHMQV< ECP >::Domain fhmqvA256(oid, true /*client*/); fail = !AuthenticatedKeyAgreementWithRolesValidate(fhmqvA256, fhmqvB256); success = !fail && success; if (fail == false) std::cout << "passed authenticated key agreement" << std::endl; else std::cout << "FAILED authenticated key agreement" << std::endl; ///////////////////////// std::cout << "FHMQV with NIST P-384 and SHA-384:" << std::endl; ECHMQV384 fhmqvB384(false); fhmqvB384.AccessGroupParameters().BERDecode(f384); const OID oid384 = ASN1::secp384r1(); ECHMQV384 fhmqvA384(oid384, true /*client*/); fail = !AuthenticatedKeyAgreementWithRolesValidate(fhmqvA384, fhmqvB384); success = !fail && success; if (fail == false) std::cout << "passed authenticated key agreement" << std::endl; else std::cout << "FAILED authenticated key agreement" << std::endl; ///////////////////////// std::cout << "FHMQV with NIST P-521 and SHA-512:" << std::endl; ECHMQV512 fhmqvB521(false); fhmqvB521.AccessGroupParameters().BERDecode(f512); const OID oid521 = ASN1::secp521r1(); ECHMQV512 fhmqvA521(oid521, true /*client*/); fail = !AuthenticatedKeyAgreementWithRolesValidate(fhmqvA521, fhmqvB521); success = !fail && success; if (fail == false) std::cout << "passed authenticated key agreement" << std::endl; else std::cout << "FAILED authenticated key agreement" << std::endl; return success; } bool ValidateLUC_DH() { std::cout << "\nLUC-DH validation suite running...\n\n"; FileSource f(DataDir("TestData/lucd512.dat").c_str(), true, new HexDecoder); LUC_DH dh(f); return SimpleKeyAgreementValidate(dh); } bool ValidateXTR_DH() { std::cout << "\nXTR-DH validation suite running...\n\n"; FileSource f(DataDir("TestData/xtrdh171.dat").c_str(), true, new HexDecoder); XTR_DH dh(f); return SimpleKeyAgreementValidate(dh); } bool ValidateECP_Agreement() { ECDH::Domain ecdhc(ASN1::secp192r1()); ECMQV::Domain ecmqvc(ASN1::secp192r1()); bool pass = SimpleKeyAgreementValidate(ecdhc); pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass; std::cout << "Turning on point compression..." << std::endl; ecdhc.AccessGroupParameters().SetPointCompression(true); ecmqvc.AccessGroupParameters().SetPointCompression(true); pass = SimpleKeyAgreementValidate(ecdhc) && pass; pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass; return pass; } bool ValidateEC2N_Agreement() { ECDH::Domain ecdhc(ASN1::sect193r1()); ECMQV::Domain ecmqvc(ASN1::sect193r1()); bool pass = SimpleKeyAgreementValidate(ecdhc); pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass; std::cout << "Turning on point compression..." << std::endl; ecdhc.AccessGroupParameters().SetPointCompression(true); ecmqvc.AccessGroupParameters().SetPointCompression(true); pass = SimpleKeyAgreementValidate(ecdhc) && pass; pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass; return pass; } // TestX25519 is slightly more comprehensive than ValidateX25519 // because it cross-validates against Bernstein's NaCL library. // TestX25519 called in Debug builds. bool TestX25519() { std::cout << "\nTesting curve25519 Key Agreements...\n\n"; const unsigned int AGREE_COUNT = 64; bool pass = true, fail; size_t i = 0; unsigned int failed = 0; SecByteBlock priv1(32), priv2(32), pub1(32), pub2(32), share1(32), share2(32); for (i=0, failed=0; i