From ce6d3c1306cfa3f78c938a66cccc8acc5d0ec2af Mon Sep 17 00:00:00 2001 From: Jeffrey Walton Date: Wed, 3 Jul 2019 01:41:23 -0400 Subject: [PATCH] Add legacy ECIES ECP cryptosystem and kat (GH #856) --- Filelist.txt | 1 + TestData/ecies_p160.dat | 1 + gfpcrypt.h | 8 +++---- validat3.cpp | 1 + validat8.cpp | 52 ++++++++++++++++++++++++++++++++++++++++- validate.h | 1 + 6 files changed, 58 insertions(+), 6 deletions(-) create mode 100644 TestData/ecies_p160.dat diff --git a/Filelist.txt b/Filelist.txt index 933d1226..345428b0 100644 --- a/Filelist.txt +++ b/Filelist.txt @@ -437,6 +437,7 @@ TestData/dlie2048.dat TestData/dsa1024.dat TestData/dsa1024b.dat TestData/dsa512.dat +TestData/ecies_p160.dat TestData/ed25519.dat TestData/ed25519_ver.dat TestData/ed25519v0.dat diff --git a/TestData/ecies_p160.dat b/TestData/ecies_p160.dat new file mode 100644 index 00000000..c360337a --- /dev/null +++ b/TestData/ecies_p160.dat @@ -0,0 +1 @@ +3081C80201003081A406072A8648CE3D0201308198020101302006072A8648CE3D0101021500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF302C0414FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC04141C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA450429044A96B5688EF573284664698968C38BB913CBFC8223A628553168947D59DCC912042351377AC5FB3202150100000000000000000001F4C8F927AED3CA752257020101041C301A02010104150023A68821ABB99DBB8429ED2320D61A8EA4C6D81B diff --git a/gfpcrypt.h b/gfpcrypt.h index bcc064e6..e0102df0 100644 --- a/gfpcrypt.h +++ b/gfpcrypt.h @@ -704,7 +704,7 @@ public: bool ParameterSupported(const char *name) const {return strcmp(name, Name::EncodingParameters()) == 0;} size_t GetSymmetricKeyLength(size_t plaintextLength) const - {return plaintextLength + static_cast(MAC::DIGESTSIZE);} + {return plaintextLength + static_cast(MAC::DEFAULT_KEYLENGTH);} size_t GetSymmetricCiphertextLength(size_t plaintextLength) const {return plaintextLength + static_cast(MAC::DIGESTSIZE);} size_t GetMaxSymmetricPlaintextLength(size_t ciphertextLength) const @@ -716,8 +716,7 @@ public: if (DHAES_MODE) { macKey = key; - //cipherKey = key + MAC::DIGESTSIZE; - cipherKey = key + MAC::DEDAULT_KEYLENGTH; + cipherKey = key + MAC::DEFAULT_KEYLENGTH; } else { @@ -749,8 +748,7 @@ public: if (DHAES_MODE) { macKey = key; - //cipherKey = key + MAC::DIGESTSIZE; - cipherKey = key + MAC::DEDAULT_KEYLENGTH; + cipherKey = key + MAC::DEFAULT_KEYLENGTH; } else { diff --git a/validat3.cpp b/validat3.cpp index 8f6367fb..1f84f24c 100644 --- a/validat3.cpp +++ b/validat3.cpp @@ -192,6 +192,7 @@ bool ValidateAll(bool thorough) pass=ValidateRW() && pass; pass=ValidateECP() && pass; pass=ValidateEC2N() && pass; + pass=ValidateECP_Legacy_Encrypt() && pass; pass=ValidateECDSA() && pass; pass=ValidateECDSA_RFC6979() && pass; pass=ValidateECGDSA(thorough) && pass; diff --git a/validat8.cpp b/validat8.cpp index 16d2daba..a1d032c0 100644 --- a/validat8.cpp +++ b/validat8.cpp @@ -38,6 +38,14 @@ NAMESPACE_BEGIN(CryptoPP) NAMESPACE_BEGIN(Test) +inline byte* C2B(char* ptr) { + return reinterpret_cast(ptr); +} + +inline const byte* C2B(const char* ptr) { + return reinterpret_cast(ptr); +} + bool ValidateRSA_Encrypt() { // Must be large enough for RSA-3072 to test SHA3_256 @@ -139,6 +147,7 @@ bool ValidateECP_Encrypt() return pass; } +// https://github.com/weidai11/cryptopp/issues/856 class NULLHash : public CryptoPP::IteratedHashWithStaticTransform { @@ -148,6 +157,7 @@ public: static const char *StaticAlgorithmName() {return "NULL HASH";} }; +// https://github.com/weidai11/cryptopp/issues/856 template struct ECIES_NULLDigest : public DL_ES< @@ -158,7 +168,7 @@ struct ECIES_NULLDigest ECIES > { // TODO: fix this after name is standardized - CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "ECIES NULLDigest";} + CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "ECIES-NULLDigest";} }; bool ValidateECP_NULLDigest_Encrypt() @@ -182,6 +192,46 @@ bool ValidateECP_NULLDigest_Encrypt() return pass; } +// Ensure interop with Crypto++ 5.6.4 and earlier +bool ValidateECP_Legacy_Encrypt() +{ + std::cout << "\nLegacy ECIES ECP validation suite running...\n\n"; + bool pass = true; + { + FileSource fc(DataDir("TestData/ecies_p160.dat").c_str(), true, new HexDecoder); + ECIES::Decryptor privC(fc); + ECIES::Encryptor pubC(privC); + + pass = CryptoSystemValidate(privC, pubC) && pass; + + // Test data generated by Crypto++ 5.6.2. + // Also see https://github.com/weidai11/cryptopp/pull/857. + const std::string plain = "Yoda said, Do or do not. There is no try."; + const std::string cipher = + "\x04\xF6\xC1\xB1\xFA\xAC\x8A\xD5\xD3\x96\xE7\x13\xAE\xBD\x0C\xCE" + "\x15\xCF\x44\x54\x08\x63\xCC\xBF\x89\x4D\xD0\xB8\x38\xA1\x3A\xB2" + "\x90\x75\x86\x82\x7F\x9D\x95\x26\xA5\x74\x13\x3A\x74\x63\x11\x71" + "\x70\x4C\x01\xA4\x08\x04\x95\x69\x6A\x91\xF0\xC0\xA4\xBD\x1E\xAA" + "\x59\x57\xB8\xA9\xD2\xF7\x7C\x98\xE3\xC5\xE3\xF4\x4F\xA7\x6E\x73" + "\x83\xF3\x1E\x05\x73\xA4\xEE\x63\x55\xFD\x6D\x31\xBB\x9E\x36\x4C" + "\x79\xD0\x76\xC0\x0D\xE9"; + + std::string recover; + recover.resize(privC.MaxPlaintextLength(cipher.size())); + + DecodingResult result = privC.Decrypt(GlobalRNG(), C2B(&cipher[0]), cipher.size(), C2B(&recover[0])); + if (result.isValidCoding) + recover.resize(result.messageLength); + else + recover.resize(0); + + pass = (plain == recover) && pass; + std::cout << (pass ? "passed " : "FAILED "); + std::cout << "decryption known answer\n"; + } + return pass; +} + bool ValidateEC2N_Encrypt() { // DEREncode() changed to Save() at Issue 569. diff --git a/validate.h b/validate.h index 6c3ec6ac..1a249a64 100644 --- a/validate.h +++ b/validate.h @@ -372,6 +372,7 @@ bool ValidateECP_Agreement(); bool ValidateECP_Encrypt(); bool ValidateECP_Sign(); +bool ValidateECP_Legacy_Encrypt(); bool ValidateECP_NULLDigest_Encrypt(); bool ValidateEC2N();