From 9f79bdae9bf8a9eaba52f6f61ba31157cc996fb5 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 19 Dec 2019 15:59:15 -0500 Subject: [PATCH] encryptor for ECIES-X25519-AEAD-Ratchet --- libi2pd/Crypto.cpp | 12 ++++++++++++ libi2pd/Crypto.h | 1 + libi2pd/CryptoKey.cpp | 16 ++++++++++++++++ libi2pd/CryptoKey.h | 16 +++++++++++++++- libi2pd/Identity.cpp | 3 +++ libi2pd/Identity.h | 1 + libi2pd/LeaseSet.cpp | 5 ++--- libi2pd/LeaseSet.h | 2 ++ 8 files changed, 52 insertions(+), 4 deletions(-) diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index 1c3f0b7b..567ae574 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -367,6 +367,18 @@ namespace crypto #endif } + void X25519Keys::SetPrivateKey (const uint8_t * priv) + { +#if OPENSSL_X25519 + if (m_Ctx) EVP_PKEY_CTX_free (m_Ctx); + if (m_Pkey) EVP_PKEY_free (m_Pkey); + m_Pkey = EVP_PKEY_new_raw_private_key (EVP_PKEY_X25519, NULL, priv, 32); + m_Ctx = EVP_PKEY_CTX_new (m_Pkey, NULL); +#else + memcpy (m_PrivateKey, priv, 32); +#endif + } + // ElGamal void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding) { diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index 785c0b9d..33490c8a 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -80,6 +80,7 @@ namespace crypto void GenerateKeys (); const uint8_t * GetPublicKey () const { return m_PublicKey; }; void GetPrivateKey (uint8_t * priv) const; + void SetPrivateKey (const uint8_t * priv); // wihout calculating public void Agree (const uint8_t * pub, uint8_t * shared); private: diff --git a/libi2pd/CryptoKey.cpp b/libi2pd/CryptoKey.cpp index f247f37e..df5dd38f 100644 --- a/libi2pd/CryptoKey.cpp +++ b/libi2pd/CryptoKey.cpp @@ -146,6 +146,22 @@ namespace crypto BN_free (x); BN_free (y); } + ECIESX25519AEADRatchetEncryptor::ECIESX25519AEADRatchetEncryptor (const uint8_t * pub) + { + memcpy (m_PublicKey, pub, 32); + } + + void ECIESX25519AEADRatchetEncryptor::Encrypt (const uint8_t * epriv, uint8_t * sharedSecret, BN_CTX * ctx, bool zeroPadding) + { + X25519Keys ep; + ep.SetPrivateKey (epriv); + ep.Agree (m_PublicKey, sharedSecret); + } + + ECIESX25519AEADRatchetDecryptor::ECIESX25519AEADRatchetDecryptor (const uint8_t * priv) + { + m_StaticKeys.SetPrivateKey (priv); + } bool ECIESX25519AEADRatchetDecryptor::Decrypt (const uint8_t * epub, uint8_t * sharedSecret, BN_CTX * ctx, bool zeroPadding) { diff --git a/libi2pd/CryptoKey.h b/libi2pd/CryptoKey.h index e7cde780..6412f4d3 100644 --- a/libi2pd/CryptoKey.h +++ b/libi2pd/CryptoKey.h @@ -119,11 +119,25 @@ namespace crypto // ECIES-X25519-AEAD-Ratchet + class ECIESX25519AEADRatchetEncryptor: public CryptoKeyEncryptor + { + public: + + ECIESX25519AEADRatchetEncryptor (const uint8_t * pub); + ~ECIESX25519AEADRatchetEncryptor () {}; + void Encrypt (const uint8_t * epriv, uint8_t * sharedSecret, BN_CTX * ctx, bool zeroPadding); + // agree with ephemeral priv and return in sharedSecret (32 bytes) + + private: + + uint8_t m_PublicKey[32]; + }; + class ECIESX25519AEADRatchetDecryptor: public CryptoKeyDecryptor { public: - ECIESX25519AEADRatchetDecryptor (const uint8_t * priv): m_StaticKeys (priv, nullptr) {}; + ECIESX25519AEADRatchetDecryptor (const uint8_t * priv); ~ECIESX25519AEADRatchetDecryptor () {}; bool Decrypt (const uint8_t * epub, uint8_t * sharedSecret, BN_CTX * ctx, bool zeroPadding); // agree with static and return in sharedSecret (32 bytes) diff --git a/libi2pd/Identity.cpp b/libi2pd/Identity.cpp index d217f41d..de94732f 100644 --- a/libi2pd/Identity.cpp +++ b/libi2pd/Identity.cpp @@ -417,6 +417,9 @@ namespace data case CRYPTO_KEY_TYPE_ELGAMAL: return std::make_shared(key); break; + case CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET: + return std::make_shared(key); + break; case CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC: case CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC_TEST: return std::make_shared(key); diff --git a/libi2pd/Identity.h b/libi2pd/Identity.h index 3bacf5da..f217f3c5 100644 --- a/libi2pd/Identity.h +++ b/libi2pd/Identity.h @@ -216,6 +216,7 @@ namespace data virtual bool IsDestination () const = 0; // for garlic const IdentHash& GetIdentHash () const { return GetIdentity ()->GetIdentHash (); }; + virtual CryptoKeyType GetEncryptionType () const { return GetIdentity ()->GetCryptoKeyType (); }; // override in LeaseSet2 }; class LocalDestination diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index b516f010..e6373dd9 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -355,7 +355,6 @@ namespace data offset += propertiesLen; // skip for now. TODO: implement properties if (offset + 1 >= len) return 0; // key sections - uint16_t currentKeyType = 0; int numKeySections = buf[offset]; offset++; for (int i = 0; i < numKeySections; i++) { @@ -368,10 +367,10 @@ namespace data // we pick first valid key, higher key type has higher priority 4-1-0 // if two keys with of the same type, pick first auto encryptor = i2p::data::IdentityEx::CreateEncryptor (keyType, buf + offset); - if (encryptor && (!m_Encryptor || keyType > currentKeyType)) + if (encryptor && (!m_Encryptor || keyType > m_EncryptionType)) { m_Encryptor = encryptor; // TODO: atomic - currentKeyType = keyType; + m_EncryptionType = keyType; } } offset += encryptionKeyLen; diff --git a/libi2pd/LeaseSet.h b/libi2pd/LeaseSet.h index 70aa7110..84d87e17 100644 --- a/libi2pd/LeaseSet.h +++ b/libi2pd/LeaseSet.h @@ -147,6 +147,7 @@ namespace data // implements RoutingDestination void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) const; + CryptoKeyType GetEncryptionType () const { return m_EncryptionType; }; private: @@ -167,6 +168,7 @@ namespace data uint32_t m_PublishedTimestamp = 0; bool m_IsPublic = true, m_IsPublishedEncrypted = false; std::shared_ptr m_TransientVerifier; + CryptoKeyType m_EncryptionType = CRYPTO_KEY_TYPE_ELGAMAL; std::shared_ptr m_Encryptor; // for standardLS2 };