// 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" #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) bool ValidateDH() { std::cout << "\nDH validation suite running...\n\n"; FileSource f(CRYPTOPP_DATA_DIR "TestData/dh1024.dat", true, new HexDecoder()); DH dh(f); return SimpleKeyAgreementValidate(dh); } bool ValidateMQV() { std::cout << "\nMQV validation suite running...\n\n"; FileSource f(CRYPTOPP_DATA_DIR "TestData/mqv1024.dat", true, new HexDecoder()); MQV mqv(f); return AuthenticatedKeyAgreementValidate(mqv); } bool ValidateHMQV() { std::cout << "\nHMQV validation suite running...\n\n"; ECHMQV256 hmqvB(false); FileSource f256(CRYPTOPP_DATA_DIR "TestData/hmqv256.dat", true, new HexDecoder()); FileSource f384(CRYPTOPP_DATA_DIR "TestData/hmqv384.dat", true, new HexDecoder()); FileSource f512(CRYPTOPP_DATA_DIR "TestData/hmqv512.dat", true, new HexDecoder()); hmqvB.AccessGroupParameters().BERDecode(f256); std::cout << "HMQV with NIST P-256 and SHA-256:" << std::endl; if (hmqvB.GetCryptoParameters().Validate(GlobalRNG(), 3)) std::cout << "passed authenticated key agreement domain parameters validation (server)" << std::endl; else { std::cout << "FAILED authenticated key agreement domain parameters invalid (server)" << std::endl; return false; } const OID oid = ASN1::secp256r1(); ECHMQV< ECP >::Domain hmqvA(oid, true /*client*/); if (hmqvA.GetCryptoParameters().Validate(GlobalRNG(), 3)) std::cout << "passed authenticated key agreement domain parameters validation (client)" << std::endl; else { std::cout << "FAILED authenticated key agreement domain parameters invalid (client)" << std::endl; return false; } SecByteBlock sprivA(hmqvA.StaticPrivateKeyLength()), sprivB(hmqvB.StaticPrivateKeyLength()); SecByteBlock eprivA(hmqvA.EphemeralPrivateKeyLength()), eprivB(hmqvB.EphemeralPrivateKeyLength()); SecByteBlock spubA(hmqvA.StaticPublicKeyLength()), spubB(hmqvB.StaticPublicKeyLength()); SecByteBlock epubA(hmqvA.EphemeralPublicKeyLength()), epubB(hmqvB.EphemeralPublicKeyLength()); SecByteBlock valA(hmqvA.AgreedValueLength()), valB(hmqvB.AgreedValueLength()); hmqvA.GenerateStaticKeyPair(GlobalRNG(), sprivA, spubA); hmqvB.GenerateStaticKeyPair(GlobalRNG(), sprivB, spubB); hmqvA.GenerateEphemeralKeyPair(GlobalRNG(), eprivA, epubA); hmqvB.GenerateEphemeralKeyPair(GlobalRNG(), eprivB, epubB); std::memset(valA.begin(), 0x00, valA.size()); std::memset(valB.begin(), 0x11, valB.size()); if (!(hmqvA.Agree(valA, sprivA, eprivA, spubB, epubB) && hmqvB.Agree(valB, sprivB, eprivB, spubA, epubA))) { std::cout << "FAILED authenticated key agreement failed" << std::endl; return false; } if (memcmp(valA.begin(), valB.begin(), hmqvA.AgreedValueLength())) { std::cout << "FAILED authenticated agreed values not equal" << std::endl; return false; } std::cout << "passed authenticated key agreement" << std::endl; // Now test HMQV with NIST P-384 curve and SHA384 hash std::cout << std::endl; std::cout << "HMQV with NIST P-384 and SHA-384:" << std::endl; ECHMQV384 hmqvB384(false); hmqvB384.AccessGroupParameters().BERDecode(f384); if (hmqvB384.GetCryptoParameters().Validate(GlobalRNG(), 3)) std::cout << "passed authenticated key agreement domain parameters validation (server)" << std::endl; else { std::cout << "FAILED authenticated key agreement domain parameters invalid (server)" << std::endl; return false; } const OID oid384 = ASN1::secp384r1(); ECHMQV384 hmqvA384(oid384, true /*client*/); if (hmqvA384.GetCryptoParameters().Validate(GlobalRNG(), 3)) std::cout << "passed authenticated key agreement domain parameters validation (client)" << std::endl; else { std::cout << "FAILED authenticated key agreement domain parameters invalid (client)" << std::endl; return false; } SecByteBlock sprivA384(hmqvA384.StaticPrivateKeyLength()), sprivB384(hmqvB384.StaticPrivateKeyLength()); SecByteBlock eprivA384(hmqvA384.EphemeralPrivateKeyLength()), eprivB384(hmqvB384.EphemeralPrivateKeyLength()); SecByteBlock spubA384(hmqvA384.StaticPublicKeyLength()), spubB384(hmqvB384.StaticPublicKeyLength()); SecByteBlock epubA384(hmqvA384.EphemeralPublicKeyLength()), epubB384(hmqvB384.EphemeralPublicKeyLength()); SecByteBlock valA384(hmqvA384.AgreedValueLength()), valB384(hmqvB384.AgreedValueLength()); hmqvA384.GenerateStaticKeyPair(GlobalRNG(), sprivA384, spubA384); hmqvB384.GenerateStaticKeyPair(GlobalRNG(), sprivB384, spubB384); hmqvA384.GenerateEphemeralKeyPair(GlobalRNG(), eprivA384, epubA384); hmqvB384.GenerateEphemeralKeyPair(GlobalRNG(), eprivB384, epubB384); std::memset(valA384.begin(), 0x00, valA384.size()); std::memset(valB384.begin(), 0x11, valB384.size()); if (!(hmqvA384.Agree(valA384, sprivA384, eprivA384, spubB384, epubB384) && hmqvB384.Agree(valB384, sprivB384, eprivB384, spubA384, epubA384))) { std::cout << "FAILED authenticated key agreement failed" << std::endl; return false; } if (memcmp(valA384.begin(), valB384.begin(), hmqvA384.AgreedValueLength())) { std::cout << "FAILED authenticated agreed values not equal" << std::endl; return false; } std::cout << "passed authenticated key agreement" << std::endl; return true; } bool ValidateFHMQV() { std::cout << "\nFHMQV validation suite running...\n\n"; //ECFHMQV< ECP >::Domain fhmqvB(false /*server*/); ECFHMQV256 fhmqvB(false); FileSource f256(CRYPTOPP_DATA_DIR "TestData/fhmqv256.dat", true, new HexDecoder()); FileSource f384(CRYPTOPP_DATA_DIR "TestData/fhmqv384.dat", true, new HexDecoder()); FileSource f512(CRYPTOPP_DATA_DIR "TestData/fhmqv512.dat", true, new HexDecoder()); fhmqvB.AccessGroupParameters().BERDecode(f256); std::cout << "FHMQV with NIST P-256 and SHA-256:" << std::endl; if (fhmqvB.GetCryptoParameters().Validate(GlobalRNG(), 3)) std::cout << "passed authenticated key agreement domain parameters validation (server)" << std::endl; else { std::cout << "FAILED authenticated key agreement domain parameters invalid (server)" << std::endl; return false; } const OID oid = ASN1::secp256r1(); ECFHMQV< ECP >::Domain fhmqvA(oid, true /*client*/); if (fhmqvA.GetCryptoParameters().Validate(GlobalRNG(), 3)) std::cout << "passed authenticated key agreement domain parameters validation (client)" << std::endl; else { std::cout << "FAILED authenticated key agreement domain parameters invalid (client)" << std::endl; return false; } SecByteBlock sprivA(fhmqvA.StaticPrivateKeyLength()), sprivB(fhmqvB.StaticPrivateKeyLength()); SecByteBlock eprivA(fhmqvA.EphemeralPrivateKeyLength()), eprivB(fhmqvB.EphemeralPrivateKeyLength()); SecByteBlock spubA(fhmqvA.StaticPublicKeyLength()), spubB(fhmqvB.StaticPublicKeyLength()); SecByteBlock epubA(fhmqvA.EphemeralPublicKeyLength()), epubB(fhmqvB.EphemeralPublicKeyLength()); SecByteBlock valA(fhmqvA.AgreedValueLength()), valB(fhmqvB.AgreedValueLength()); fhmqvA.GenerateStaticKeyPair(GlobalRNG(), sprivA, spubA); fhmqvB.GenerateStaticKeyPair(GlobalRNG(), sprivB, spubB); fhmqvA.GenerateEphemeralKeyPair(GlobalRNG(), eprivA, epubA); fhmqvB.GenerateEphemeralKeyPair(GlobalRNG(), eprivB, epubB); std::memset(valA.begin(), 0x00, valA.size()); std::memset(valB.begin(), 0x11, valB.size()); if (!(fhmqvA.Agree(valA, sprivA, eprivA, spubB, epubB) && fhmqvB.Agree(valB, sprivB, eprivB, spubA, epubA))) { std::cout << "FAILED authenticated key agreement failed" << std::endl; return false; } if (memcmp(valA.begin(), valB.begin(), fhmqvA.AgreedValueLength())) { std::cout << "FAILED authenticated agreed values not equal" << std::endl; return false; } std::cout << "passed authenticated key agreement" << std::endl; // Now test FHMQV with NIST P-384 curve and SHA384 hash std::cout << std::endl; std::cout << "FHMQV with NIST P-384 and SHA-384:" << std::endl; ECHMQV384 fhmqvB384(false); fhmqvB384.AccessGroupParameters().BERDecode(f384); if (fhmqvB384.GetCryptoParameters().Validate(GlobalRNG(), 3)) std::cout << "passed authenticated key agreement domain parameters validation (server)" << std::endl; else { std::cout << "FAILED authenticated key agreement domain parameters invalid (server)" << std::endl; return false; } const OID oid384 = ASN1::secp384r1(); ECHMQV384 fhmqvA384(oid384, true /*client*/); if (fhmqvA384.GetCryptoParameters().Validate(GlobalRNG(), 3)) std::cout << "passed authenticated key agreement domain parameters validation (client)" << std::endl; else { std::cout << "FAILED authenticated key agreement domain parameters invalid (client)" << std::endl; return false; } SecByteBlock sprivA384(fhmqvA384.StaticPrivateKeyLength()), sprivB384(fhmqvB384.StaticPrivateKeyLength()); SecByteBlock eprivA384(fhmqvA384.EphemeralPrivateKeyLength()), eprivB384(fhmqvB384.EphemeralPrivateKeyLength()); SecByteBlock spubA384(fhmqvA384.StaticPublicKeyLength()), spubB384(fhmqvB384.StaticPublicKeyLength()); SecByteBlock epubA384(fhmqvA384.EphemeralPublicKeyLength()), epubB384(fhmqvB384.EphemeralPublicKeyLength()); SecByteBlock valA384(fhmqvA384.AgreedValueLength()), valB384(fhmqvB384.AgreedValueLength()); fhmqvA384.GenerateStaticKeyPair(GlobalRNG(), sprivA384, spubA384); fhmqvB384.GenerateStaticKeyPair(GlobalRNG(), sprivB384, spubB384); fhmqvA384.GenerateEphemeralKeyPair(GlobalRNG(), eprivA384, epubA384); fhmqvB384.GenerateEphemeralKeyPair(GlobalRNG(), eprivB384, epubB384); std::memset(valA384.begin(), 0x00, valA384.size()); std::memset(valB384.begin(), 0x11, valB384.size()); if (!(fhmqvA384.Agree(valA384, sprivA384, eprivA384, spubB384, epubB384) && fhmqvB384.Agree(valB384, sprivB384, eprivB384, spubA384, epubA384))) { std::cout << "FAILED authenticated key agreement failed" << std::endl; return false; } if (memcmp(valA384.begin(), valB384.begin(), fhmqvA384.AgreedValueLength())) { std::cout << "FAILED authenticated agreed values not equal" << std::endl; return false; } std::cout << "passed authenticated key agreement" << std::endl; return true; } bool ValidateLUC_DH() { std::cout << "\nLUC-DH validation suite running...\n\n"; FileSource f(CRYPTOPP_DATA_DIR "TestData/lucd512.dat", true, new HexDecoder()); LUC_DH dh(f); return SimpleKeyAgreementValidate(dh); } bool ValidateXTR_DH() { std::cout << "\nXTR-DH validation suite running...\n\n"; FileSource f(CRYPTOPP_DATA_DIR "TestData/xtrdh171.dat", 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; } NAMESPACE_END // Test NAMESPACE_END // CryptoPP