mirror of
				https://github.com/PurpleI2P/i2pd.git
				synced 2025-11-04 00:20:46 +00:00 
			
		
		
		
	indetification of incoming garlic messages
This commit is contained in:
		
							parent
							
								
									152e579f7e
								
							
						
					
					
						commit
						2fc16ee13d
					
				
					 6 changed files with 30 additions and 25 deletions
				
			
		| 
						 | 
				
			
			@ -824,8 +824,8 @@ namespace client
 | 
			
		|||
 | 
			
		||||
	i2p::data::CryptoKeyType LeaseSetDestination::GetPreferredCryptoType () const
 | 
			
		||||
	{
 | 
			
		||||
		if (SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET))
 | 
			
		||||
		    return i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET;
 | 
			
		||||
		if (SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET))
 | 
			
		||||
		    return i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET;
 | 
			
		||||
		return i2p::data::CRYPTO_KEY_TYPE_ELGAMAL;   
 | 
			
		||||
	}	
 | 
			
		||||
		
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -229,7 +229,12 @@ namespace client
 | 
			
		|||
			// implements LocalDestination
 | 
			
		||||
			bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const;
 | 
			
		||||
			std::shared_ptr<const i2p::data::IdentityEx> GetIdentity () const { return m_Keys.GetPublic (); };
 | 
			
		||||
			bool SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const { return m_EncryptionKeyType == keyType; };
 | 
			
		||||
			bool SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const 
 | 
			
		||||
			{ 
 | 
			
		||||
				return keyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET ? 
 | 
			
		||||
					m_EncryptionKeyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET :
 | 
			
		||||
					m_EncryptionKeyType < i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET; 
 | 
			
		||||
			}
 | 
			
		||||
			const uint8_t * GetEncryptionPublicKey (i2p::data::CryptoKeyType keyType) const { return m_EncryptionPublicKey; };
 | 
			
		||||
 | 
			
		||||
		protected:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -127,7 +127,7 @@ namespace garlic
 | 
			
		|||
        if (!GetOwner ()) return false;
 | 
			
		||||
        // we are Bob
 | 
			
		||||
        // KDF1
 | 
			
		||||
        MixHash (GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET), 32); // h = SHA256(h || bpk)    
 | 
			
		||||
        MixHash (GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET), 32); // h = SHA256(h || bpk)    
 | 
			
		||||
		
 | 
			
		||||
		if (!i2p::crypto::GetElligator ()->Decode (buf, m_Aepk))
 | 
			
		||||
		{ 
 | 
			
		||||
| 
						 | 
				
			
			@ -138,7 +138,7 @@ namespace garlic
 | 
			
		|||
        MixHash (m_Aepk, 32); // h = SHA256(h || aepk)  
 | 
			
		||||
    
 | 
			
		||||
        uint8_t sharedSecret[32];
 | 
			
		||||
		GetOwner ()->Decrypt (m_Aepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET); // x25519(bsk, aepk)
 | 
			
		||||
		GetOwner ()->Decrypt (m_Aepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); // x25519(bsk, aepk)
 | 
			
		||||
		i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64)
 | 
			
		||||
		
 | 
			
		||||
        // decrypt flags/static    
 | 
			
		||||
| 
						 | 
				
			
			@ -160,7 +160,7 @@ namespace garlic
 | 
			
		|||
		{
 | 
			
		||||
			// static key, fs is apk
 | 
			
		||||
            memcpy (m_RemoteStaticKey, fs, 32);
 | 
			
		||||
			GetOwner ()->Decrypt (fs, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET); // x25519(bsk, apk)
 | 
			
		||||
			GetOwner ()->Decrypt (fs, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); // x25519(bsk, apk)
 | 
			
		||||
			i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64)
 | 
			
		||||
		}
 | 
			
		||||
		else // all zeros flags
 | 
			
		||||
| 
						 | 
				
			
			@ -242,7 +242,7 @@ namespace garlic
 | 
			
		|||
        // encrypt static key section
 | 
			
		||||
        uint8_t nonce[12];
 | 
			
		||||
		CreateNonce (0, nonce);
 | 
			
		||||
		if (!i2p::crypto::AEADChaCha20Poly1305 (GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET), 32, m_H, 32, m_CK + 32, nonce, out + offset, 48, true)) // encrypt
 | 
			
		||||
		if (!i2p::crypto::AEADChaCha20Poly1305 (GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET), 32, m_H, 32, m_CK + 32, nonce, out + offset, 48, true)) // encrypt
 | 
			
		||||
		{
 | 
			
		||||
			LogPrint (eLogWarning, "Garlic: Static section AEAD encryption failed ");
 | 
			
		||||
			return false;
 | 
			
		||||
| 
						 | 
				
			
			@ -250,7 +250,7 @@ namespace garlic
 | 
			
		|||
        MixHash (out + offset, 48); // h = SHA256(h || ciphertext)
 | 
			
		||||
        offset += 48;
 | 
			
		||||
        // KDF2 
 | 
			
		||||
        GetOwner ()->Decrypt (m_RemoteStaticKey, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET); // x25519 (ask, bpk)
 | 
			
		||||
        GetOwner ()->Decrypt (m_RemoteStaticKey, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); // x25519 (ask, bpk)
 | 
			
		||||
		i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64)
 | 
			
		||||
		// encrypt payload
 | 
			
		||||
		if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_CK + 32, nonce, out + offset, len + 16, true)) // encrypt
 | 
			
		||||
| 
						 | 
				
			
			@ -355,7 +355,7 @@ namespace garlic
 | 
			
		|||
		uint8_t sharedSecret[32];      
 | 
			
		||||
        m_EphemeralKeys.Agree (bepk, sharedSecret); // sharedSecret = x25519(aesk, bepk)  
 | 
			
		||||
		i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK, 32); // chainKey = HKDF(chainKey, sharedSecret, "", 32) 
 | 
			
		||||
		GetOwner ()->Decrypt (bepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET); // x25519 (ask, bepk)
 | 
			
		||||
		GetOwner ()->Decrypt (bepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); // x25519 (ask, bepk)
 | 
			
		||||
		i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64)
 | 
			
		||||
		uint8_t nonce[12];
 | 
			
		||||
		CreateNonce (0, nonce);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -466,8 +466,9 @@ namespace garlic
 | 
			
		|||
			LogPrint (eLogWarning, "Garlic: message length ", length, " exceeds I2NP message length ", msg->GetLength ());
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		auto mod = length & 0x0f; // %16
 | 
			
		||||
		buf += 4; // length
 | 
			
		||||
		auto it = m_Tags.find (SessionTag(buf));
 | 
			
		||||
		auto it = !mod ? m_Tags.find (SessionTag(buf)) : m_Tags.end (); // AES block is multiple of 16
 | 
			
		||||
		// AES tag might be used even if encryption type is not ElGamal/AES
 | 
			
		||||
		if (it != m_Tags.end ())
 | 
			
		||||
		{
 | 
			
		||||
| 
						 | 
				
			
			@ -487,15 +488,11 @@ namespace garlic
 | 
			
		|||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			// tag not found. Handle depending on encryption type
 | 
			
		||||
			if (SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET))
 | 
			
		||||
			{
 | 
			
		||||
				HandleECIESx25519 (buf, length);	
 | 
			
		||||
				return;
 | 
			
		||||
			}	
 | 
			
		||||
			// otherwise assume ElGamal/AES	
 | 
			
		||||
			// AES tag not found. Handle depending on encryption type		
 | 
			
		||||
			// try ElGamal/AES first if leading block is 514	
 | 
			
		||||
			ElGamalBlock elGamal;
 | 
			
		||||
			if (length >= 514 && Decrypt (buf, (uint8_t *)&elGamal, m_Ctx, i2p::data::CRYPTO_KEY_TYPE_ELGAMAL))
 | 
			
		||||
			if (mod == 2 && length >= 514 && SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ELGAMAL) &&
 | 
			
		||||
			    Decrypt (buf, (uint8_t *)&elGamal, m_Ctx, i2p::data::CRYPTO_KEY_TYPE_ELGAMAL))
 | 
			
		||||
			{
 | 
			
		||||
				auto decryption = std::make_shared<AESDecryption>(elGamal.sessionKey);
 | 
			
		||||
				uint8_t iv[32]; // IV is first 16 bytes
 | 
			
		||||
| 
						 | 
				
			
			@ -504,6 +501,9 @@ namespace garlic
 | 
			
		|||
				decryption->Decrypt(buf + 514, length - 514, buf + 514);
 | 
			
		||||
				HandleAESBlock (buf + 514, length - 514, decryption, msg->from);
 | 
			
		||||
			}
 | 
			
		||||
			else if (SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET))
 | 
			
		||||
			// otherwise ECIESx25519	
 | 
			
		||||
				HandleECIESx25519 (buf, length); // TODO: check tag first	
 | 
			
		||||
			else
 | 
			
		||||
				LogPrint (eLogError, "Garlic: Failed to decrypt message");	
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -679,8 +679,8 @@ namespace garlic
 | 
			
		|||
	std::shared_ptr<GarlicRoutingSession> GarlicDestination::GetRoutingSession (
 | 
			
		||||
		std::shared_ptr<const i2p::data::RoutingDestination> destination, bool attachLeaseSet)
 | 
			
		||||
	{
 | 
			
		||||
        if (destination->GetEncryptionType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET &&
 | 
			
		||||
            SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET))
 | 
			
		||||
        if (destination->GetEncryptionType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET &&
 | 
			
		||||
            SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET))
 | 
			
		||||
        {
 | 
			
		||||
            ECIESX25519AEADRatchetSessionPtr session;
 | 
			
		||||
            uint8_t staticKey[32];
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -412,7 +412,7 @@ namespace data
 | 
			
		|||
			case CRYPTO_KEY_TYPE_ELGAMAL:
 | 
			
		||||
				return std::make_shared<i2p::crypto::ElGamalEncryptor>(key);
 | 
			
		||||
			break;
 | 
			
		||||
			case CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET:
 | 
			
		||||
			case CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET:
 | 
			
		||||
				return std::make_shared<i2p::crypto::ECIESX25519AEADRatchetEncryptor>(key);
 | 
			
		||||
			break;
 | 
			
		||||
			case CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC:
 | 
			
		||||
| 
						 | 
				
			
			@ -672,7 +672,7 @@ namespace data
 | 
			
		|||
			case CRYPTO_KEY_TYPE_ECIES_GOSTR3410_CRYPTO_PRO_A_SHA256_AES256CBC:
 | 
			
		||||
				return std::make_shared<i2p::crypto::ECIESGOSTR3410Decryptor>(key);
 | 
			
		||||
			break;
 | 
			
		||||
			case CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET:
 | 
			
		||||
			case CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET:
 | 
			
		||||
				return std::make_shared<i2p::crypto::ECIESX25519AEADRatchetDecryptor>(key);
 | 
			
		||||
			break;
 | 
			
		||||
			default:
 | 
			
		||||
| 
						 | 
				
			
			@ -754,7 +754,7 @@ namespace data
 | 
			
		|||
			case CRYPTO_KEY_TYPE_ECIES_GOSTR3410_CRYPTO_PRO_A_SHA256_AES256CBC:
 | 
			
		||||
				i2p::crypto::CreateECIESGOSTR3410RandomKeys (priv, pub);
 | 
			
		||||
			break;
 | 
			
		||||
			case CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET:
 | 
			
		||||
			case CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET:
 | 
			
		||||
				i2p::crypto::CreateECIESX25519AEADRatchetRandomKeys (priv, pub);
 | 
			
		||||
			break;
 | 
			
		||||
			default:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -56,7 +56,7 @@ namespace data
 | 
			
		|||
 | 
			
		||||
	const uint16_t CRYPTO_KEY_TYPE_ELGAMAL = 0;
 | 
			
		||||
	const uint16_t CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC = 1;
 | 
			
		||||
	const uint16_t CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET = 4; 	
 | 
			
		||||
	const uint16_t CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET = 4; 	
 | 
			
		||||
	const uint16_t CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC_TEST = 65280; // TODO: remove later
 | 
			
		||||
	const uint16_t CRYPTO_KEY_TYPE_ECIES_GOSTR3410_CRYPTO_PRO_A_SHA256_AES256CBC = 65281; // TODO: use GOST R 34.11 instead SHA256 and GOST 28147-89 instead AES
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue