#include <stdio.h>
#include <assert.h>
#include <cryptopp/osrng.h>
#include <cryptopp/eccrypto.h>
#include <cryptopp/oids.h>
#if CRYPTOPP_VERSION >= 600
#define byte CryptoPP::byte
#endif
void hexdump(byte* data, int length) {
for (int i = 0; i < length; i++) {
if (std::isprint(data[i]))
printf("%c", data[i]);
else
printf("\\x%02x", data[i]);
}
printf("\n");
}
class NULLHash : public CryptoPP::IteratedHashWithStaticTransform
<CryptoPP::word32, CryptoPP::BigEndian, 32, 0, NULLHash, 0>
{
public:
static void InitState(HashWordType *state) {}
static void Transform(CryptoPP::word32 *digest, const CryptoPP::word32 *data) {}
static const char *StaticAlgorithmName() {return "NULL HASH";}
};
template <class EC, class COFACTOR_OPTION = CryptoPP::IncompatibleCofactorMultiplication, bool DHAES_MODE = true>
struct ECIES_PY
: public CryptoPP::DL_ES<
CryptoPP::DL_Keys_EC<EC>,
CryptoPP::DL_KeyAgreementAlgorithm_DH<typename EC::Point, COFACTOR_OPTION>,
CryptoPP::DL_KeyDerivationAlgorithm_P1363<typename EC::Point, DHAES_MODE, CryptoPP::P1363_KDF2<CryptoPP::SHA1> >,
CryptoPP::DL_EncryptionAlgorithm_Xor<CryptoPP::HMAC<NULLHash>, DHAES_MODE>,
ECIES_PY<EC> >
{
static std::string CRYPTOPP_API StaticAlgorithmName() {return "ECIES_PY";}
};
int main() {
const char *plaintext = "This is a big secret";
ECIES_PY<CryptoPP::ECP>::PrivateKey private_key;
ECIES_PY<CryptoPP::ECP>::PublicKey public_key;
CryptoPP::AutoSeededRandomPool rng;
private_key.Initialize(rng, CryptoPP::ASN1::secp256k1());
private_key.MakePublicKey(public_key);
ECIES_PY<CryptoPP::ECP>::Encryptor encryptor;
encryptor.AccessKey().AccessGroupParameters().Initialize(CryptoPP::ASN1::secp256k1());
encryptor.AccessKey().SetPublicElement(public_key.GetPublicElement());
encryptor.AccessKey().ThrowIfInvalid(rng, 3);
unsigned long data_encrypted_length = encryptor.CiphertextLength(strlen(plaintext));
byte data_encrypted[data_encrypted_length];
encryptor.Encrypt(rng, reinterpret_cast<const byte *>(plaintext), strlen(plaintext), data_encrypted);
printf("Encrypted: ");
hexdump(data_encrypted, data_encrypted_length);
ECIES_PY<CryptoPP::ECP>::Decryptor decryptor;
decryptor.AccessKey().Initialize(CryptoPP::ASN1::secp256k1(), private_key.GetPrivateExponent());
decryptor.AccessKey().ThrowIfInvalid(rng, 3);
unsigned long data_decrypted_max_length = decryptor.MaxPlaintextLength(data_encrypted_length);
byte data_decrypted[data_decrypted_max_length];
CryptoPP::DecodingResult res = decryptor.Decrypt(rng, reinterpret_cast<const byte *>(data_encrypted), data_encrypted_length, data_decrypted);
assert(res.isValidCoding);
printf("Decrypted: ");
hexdump(data_decrypted, res.messageLength);
return 0;
}
We have been using the code below with libcrypto++6 on Ubuntu for years. It uses a custom NULLHash implementation to reduce the size of the final ciphertext since we are not concerned with message integrity.I recently tested this with libcrypto 8.2 and the decrypted text is now partially corrupted, also I noticed plaintext is visible in the encrypted ciphertext. I then built a non-optimized libcrypto 6 and realized it also fails in the same manner.
...
I think this may have something to do with https://cryptopp.com/wiki/Elliptic_Curve_Integrated_Encryption_Scheme#Bouncy_Castle_Patch . That section needs to clearly state when the change occirs but it does not. I'll look up the info and get it added.
--
You received this message because you are subscribed to "Crypto++ Users". More information about Crypto++ and this group is available at http://www.cryptopp.com and http://groups.google.com/forum/#!forum/cryptopp-users.
---
You received this message because you are subscribed to the Google Groups "Crypto++ Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cryptopp-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/cryptopp-users/80a88957-276c-4eb8-b182-c353f1822e5e%40googlegroups.com.
If memory serves, ECIES standard required ^authenticated* encryption. That means - null hash wasn't allowed.Besides, there's Moxy Marlinspike principle: "If you don't enforce integrity, sooner or later you'll lose confidentiality as well."Having said that, I don't recall why that particular change was made, and am willing to experiment to see what would happen if it's replaced with MAC::DEFAULT_KEYLENGTH (but we'll need to review the algorithm to recall what is doing there!).
--
You received this message because you are subscribed to "Crypto++ Users". More information about Crypto++ and this group is available at http://www.cryptopp.com and http://groups.google.com/forum/#!forum/cryptopp-users.
---
You received this message because you are subscribed to the Google Groups "Crypto++ Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cryptopp-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/cryptopp-users/e7fa1c0d-a955-412d-9f25-825af2899fd5%40googlegroups.com.
I believe I found the issue.
DL_EncryptionAlgorithm_Xor::GetSymmetricKeyLength changed between 5.6.4 and 6.0.0:
size_t GetSymmetricKeyLength(size_t plaintextLength) const
- {return plaintextLength + MAC::DEFAULT_KEYLENGTH;}
+ {return plaintextLength + static_cast<size_t>(MAC::DIGESTSIZE);}
So, no - the above change does not look like a bug.
diff --git a/gfpcrypt.h b/gfpcrypt.h
index 1b26a56b..f15c397e 100644
--- a/gfpcrypt.h
+++ b/gfpcrypt.h
@@ -716,7 +716,7 @@ public:
if (DHAES_MODE)
{
macKey = key;
- cipherKey = key + MAC::DEFAULT_KEYLENGTH;
+ cipherKey = key + MAC::DIGESTSIZE;
}
else
{
@@ -748,7 +748,7 @@ public:
if (DHAES_MODE)
{
macKey = key;
- cipherKey = key + MAC::DEFAULT_KEYLENGTH;
+ cipherKey = key + MAC::DIGESTSIZE;
}
else
{
--
You received this message because you are subscribed to "Crypto++ Users". More information about Crypto++ and this group is available at http://www.cryptopp.com and http://groups.google.com/forum/#!forum/cryptopp-users.
---
You received this message because you are subscribed to the Google Groups "Crypto++ Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cryptopp-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/cryptopp-users/f9102d96-e126-44b1-b3f5-9aadb9d64016%40googlegroups.com.
What do you know, you're right! Thank you for finding the issue, and proposing the fix.Applied in the master.On Tue, Jul 2, 2019 at 9:54 AM Andrew Wason <recta...@gmail.com> wrote:
On Monday, July 1, 2019 at 9:58:12 PM UTC-4, Mouse wrote:So, no - the above change does not look like a bug.I don't think that change is the bug, the bug is that SymmetricEncrypt (and
SymmetricDecrypt) did not also change to use MAC::DIGESTSIZE at the same time. It continues to use MAC::DEFAULT_KEYLENGTHFixing that in master and it works properly with NULLHash:
Can you verify the issue has been cleared with your code?