-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use MAC::DIGESTSIZE in ECIES SymmetricEncrypt/SymmetricDecrypt #857
Conversation
We may want to hold-off on this commit until we know it maintains backwards compatibility. It may not maintain it based on my tests. Here's the output of a test using Crypto++ 5.6.2 ECIES:
I plan on using the key, plaintext and ciphertext for an interop test. We should be able to obtain the decryption using Crypto++ 8.0 Here's the test program using Crypto++ 5.6.2 ECIES.
|
With reverted master:
Here's the modified source: #include "cryptlib.h"
#include "eccrypto.h"
#include "osrng.h"
#include "files.h"
#include "oids.h"
#include "hex.h"
#include "hmac.h"
#include "sha.h"
#include <iostream>
#include <string>
const char *PRIVKEY_HEX="3081C80201003081A406072A8648CE3D0201308198020101302006072A8648CE3D0101021500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF302C0414FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC04141C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA450429044A96B5688EF573284664698968C38BB913CBFC8223A628553168947D59DCC912042351377AC5FB3202150100000000000000000001F4C8F927AED3CA752257020101041C301A02010104150023A68821ABB99DBB8429ED2320D61A8EA4C6D81B";
#ifdef DECRYPT
const char *CT_HEX="04F6C1B1FAAC8AD5D396E713AEBD0CCE15CF44540863CCBF894DD0B838A13AB2907586827F9D9526A574133A74631171704C01A4080495696A91F0C0A4BD1EAA5957B8A9D2F77C98E3C5E3F44FA76E7383F31E0573A4EE6355FD6D31BB9E364C79D076C00DE9";
#endif /* DECRYPT */
using CryptoPP::byte;
inline byte* C2B(char* ptr) {
return reinterpret_cast<byte*>(ptr);
}
inline const byte* C2B(const char* ptr) {
return reinterpret_cast<const byte*>(ptr);
}
int main(int argc, char* argv[])
{
using namespace CryptoPP;
AutoSeededRandomPool prng;
HexEncoder encoder(new FileSink(std::cout));
StringSource spriv(PRIVKEY_HEX, true, new HexDecoder);
DL_PrivateKey_EC<ECP> key;
//key.Initialize(prng, ASN1::secp160r1());
key.BERDecode(spriv.Ref());
#ifdef DECRYPT
ECIES<ECP,SHA1,NoCofactorMultiplication,false,true>::Decryptor decryptor(key);
ECIES<ECP,SHA1,NoCofactorMultiplication,false,true>::Encryptor encryptor(key);
#else /* DECRYPT */
ECIES<ECP>::Decryptor decryptor(key);
ECIES<ECP>::Encryptor encryptor(key);
#endif /* DECRYPT */
std::cout << "SHA1 digestsize: " << SHA1::DIGESTSIZE << std::endl;
std::cout << "HMAC/SHA1 keysize: " << HMAC<SHA1>::DEFAULT_KEYLENGTH << std::endl;
std::cout << "Private key:" << std::endl;
decryptor.AccessKey().Save(encoder);
std::cout << std::endl;
const std::string plain = "Yoda said, Do or do not. There is no try.";
std::cout << "Plaintext:" << std::endl;
std::cout << plain << std::endl << "Plaintext size: " << plain.size() << std::endl;
std::string cipher;
size_t size = encryptor.CiphertextLength(plain.size());
cipher.resize(size);
std::cout << "Encryptor decided size = " << size << std::endl;
encryptor.Encrypt(prng, C2B(&plain[0]), plain.size(), C2B(&cipher[0]));
#ifdef DECRYPT
std::string ciph2;
StringSource(CT_HEX, true, new HexDecoder(new StringSink(ciph2)));
std::cout << "Ciphertext:" << std::endl;
StringSource(ciph2, true, new Redirector(encoder));
std::cout << std::endl;
std::cout << "Ciphertext size: " << ciph2.size() << std::endl;
#else /* DECRYPT */
std::cout << "Ciphertext:" << std::endl;
StringSource(cipher, true, new Redirector(encoder));
std::cout << std::endl;
std::cout << "Ciphertext size: " << cipher.size() << std::endl;
#endif /* DECRYPT */
#ifdef DECRYPT
size = decryptor.MaxPlaintextLength(ciph2.size());
std::string recover; recover.resize(size);
std::cout << "Expected recovered size: " << size << std::endl;
DecodingResult result = decryptor.Decrypt(prng, C2B(&ciph2[0]), ciph2.size(), C2B(&recover[0]));
#else /* DECRYPT */
size = decryptor.MaxPlaintextLength(cipher.size());
std::string recover; recover.resize(size);
std::cout << "Expected recovered size: " << size << std::endl;
DecodingResult result = decryptor.Decrypt(prng, C2B(&cipher[0]), cipher.size(), C2B(&recover[0]));
#endif /* DECRYPT */
if (!result.isValidCoding)
throw std::runtime_error("Failed to decrypt ciphertext");
recover.resize(result.messageLength);
std::cout << "Recovered:" << std::endl;
std::cout << recover << std::endl << "Recovered size: " << recover.size() << std::endl;
return 0;
} Trying with this patch enabled:
So, I don't understand why Travis CI fails:
|
On Tue, Jul 2, 2019 at 11:48 PM Mouse ***@***.***> wrote:
...
So, I don't understand why Travis CI fails:
$ ./cryptest.exe tv`:
. . . . .
Testing AsymmetricCipher algorithm DLIES(NoCofactorMultiplication, KDF2(SHA-1), XOR, HMAC(SHA-1), DHAES).
..
AlgorithmType: AsymmetricCipher
Ciphertext: B11D906CC5A8E71CA8962A8CC0AC4CAFF2DA00DC130C370F42D11FCF5C37DE046EBC07C7D457CA351CE456A043695D14ED055ADAD2B58BE0DF992685EF8B0D21597A43D7B3D9634A077CB70C4590CD73C20FAAACBC5649413EECA0C7B3CBF469E531299398F61496C51FE9FFE48AE9FE6034F104EFC562DE9529C776B86ADD4025AD6B0C3687B012F92C7B9E82F794E4FBE247D644
Comment: 1024-bit DLIES key
KeyFormat: DER
Name: DLIES(NoCofactorMultiplication, KDF2(SHA-1), XOR, HMAC(SHA-1), DHAES)
Plaintext: 76
PrivateKey: 308201370201003082011706072a8648ce3804013082010a02818100ba3ed941 10332be99b77a345da72a33146ca960498a6fc2e0e207fdeaadf69c3e5650df7 3255475854900b75af7f6aac021de687a1c166ecb2ab6ec6b9da82ad4fb0f48a 966a2b968406e18ba50947d7ee3bb1f13511cb4dde191f0ade1933d089c5e82a b8d283943d85ef0102e173abf2635aeac2f84cfc9ec6c4e8f3fbc4130281805d 1f6ca0881995f4cdbbd1a2ed395198a3654b024c537e1707103fef556fb4e1f2 b286fb992aa3ac2a4805bad7bfb556010ef343d0e0b3765955b7635ced4156a7 d87a454b3515cb420370c5d284a3ebf71dd8f89a88e5a6ef0c8f856f0c99e844 e2f4155c6941ca1ec2f7808170b9d5f931ad75617c267e4f63627479fde20902 01030417021501fdc788cd93f07dba3af2de42ae5aa3ede219919d
PublicKey: 308201a23082011706072a8648ce3804013082010a02818100ba3ed94110332b e99b77a345da72a33146ca960498a6fc2e0e207fdeaadf69c3e5650df7325547 5854900b75af7f6aac021de687a1c166ecb2ab6ec6b9da82ad4fb0f48a966a2b 968406e18ba50947d7ee3bb1f13511cb4dde191f0ade1933d089c5e82ab8d283 943d85ef0102e173abf2635aeac2f84cfc9ec6c4e8f3fbc4130281805d1f6ca0 881995f4cdbbd1a2ed395198a3654b024c537e1707103fef556fb4e1f2b286fb 992aa3ac2a4805bad7bfb556010ef343d0e0b3765955b7635ced4156a7d87a45 4b3515cb420370c5d284a3ebf71dd8f89a88e5a6ef0c8f856f0c99e844e2f415 5c6941ca1ec2f7808170b9d5f931ad75617c267e4f63627479fde20902010303 81840002818029eaa5b193357c200e0d42f374d4c003c633c77f4778fe40ad0b d035b87ae5da4e74110ec2b15eefe1bd8b9357534c85328382946d314e15b79f 7b854227012dfaac9bd862e73a5630e01327b36319765a3eb1434e108ef6421c 659e3f9223966759611429b3c86ed9937563efbfad8bfedcfa92db3d7d2157fe 2c8a33f08636
Source: generated by Wei Dai using Crypto++ 5.1
Test: DecryptMatch
Test FAILED.
Skipping to next test.
Lol... That is kind of funny in a morbid sort of way.
DLIES is an integrated encryption scheme over Integers. ECIES is an integrated encryption scheme over Elliptic Curves. Why is DLIES failing after an ECIES tweak???
Maybe you need a distclean. Or maybe there's a memory error in there somewhere.
|
I wish I knew. On the other hand, I think this tweak is for DLIES, not (just) ECIES - that would explain...
I have it in my build scripts, and I repeat it when I build manually. I'm thinking - the test-vectors are generated with 5.1 with the old defaults. Current tests are running with the new defaults (though this doesn't explain why in that case Travis started failing only now). In any case, configuring ECIES fit the old defaults, I could decrypt your test both with this patch, and without it. I'm stymied. |
On Wed, Jul 3, 2019 at 12:21 AM Mouse ***@***.***> wrote:
Why is DLIES failing after an ECIES tweak???
I wish I knew. On the other hand, I think this tweak is for DLIES, not (just) ECIES - that would explain...
Oh, right. The change impacted `DL_EncryptionAlgorithm_Xor::SymmetricEncrypt` (and decrypt), and it is used in both schemes.
|
So, what do we do? Keep the pre-patch version? Re-generate the test vectors with the patched code and the new defaults? Change the tests to instantiate DLAES with the old defaults...? I still do not understand why I could decrypt your test (after I changed the defaults to the pre-5.6) both with the patched code, and with the patch reverted. |
On Wed, Jul 3, 2019 at 12:49 AM Mouse ***@***.***> wrote:
So, what do we do? Keep the pre-patch version? Re-generate the test vectors with the patched code and the new defaults? Change the tests to instantiate DLAES with the old defaults...?
I still do not understand why I could decrypt your test (after I changed the defaults to the pre-5.6) both with the patched code, and with the patch reverted.
I'm going to check-in a ValidateECP_Legacy_Encrypt() that should allow
us to quickly vet changes and know if/where things are bent. That is,
we will know the new ECIES (with Botan and Bouncy Castle changes)
still works as expected with DHAES_MODE=false and LABEL_OCTETS=true.
Then, we can evaluate the landscape and figure out how to proceed.
|
Sounds like a plan. Except, this change affected not just ECP but DL. Probably we need a wider legacy check. |
I cut-in the legacy ECIES ECP test at Commit ce6d3c1306cf, and legacy ECIES EC2N test at Commit cd0d14563532. I also fixed my typo, and changed back to Can you guys give it a go and let us know what breaks? |
Do you want to take a crack at it? Checkout 5.6.2 with
Then, Then, use the test program to generate new data. There is already a keypair at Finally, plug it into a function like |
Sorry, I'm a bit dense today - so could you please provide more details?
Which test program? The
Re-used how and where? Do I need to copy that file from the 5.6.2 build? Or it didn't change since then?
You mean - write a new function I'm not sure I understand the actual plan and the specific goals:
|
Fixes #856