From cc302847a84a2ac956c785ccbf9dfff1f094e3ed Mon Sep 17 00:00:00 2001
From: orignal <romakoshelkin@yandex.ru>
Date: Fri, 9 May 2014 19:34:12 -0400
Subject: [PATCH] replace tunnel encryption to AES-NI

---
 Tunnel.cpp     | 45 ++++++++++++++++++++++-----------------------
 Tunnel.h       | 13 +------------
 TunnelConfig.h |  7 ++++++-
 3 files changed, 29 insertions(+), 36 deletions(-)

diff --git a/Tunnel.cpp b/Tunnel.cpp
index 4b831fbc..8529df4b 100644
--- a/Tunnel.cpp
+++ b/Tunnel.cpp
@@ -57,10 +57,8 @@ namespace tunnel
 		while (hop)
 		{
 			for (size_t i = ind; i < numRecords; i++)
-			{	
-				m_CBCDecryption.SetKeyWithIV (hop->replyKey, 32, hop->replyIV);
-				m_CBCDecryption.ProcessData((uint8_t *)&records[i], (uint8_t *)&records[i], sizeof (I2NPBuildRequestRecordElGamalEncrypted));
-			}	
+				hop->decryption.Decrypt((uint8_t *)&records[i], 
+					sizeof (I2NPBuildRequestRecordElGamalEncrypted), (uint8_t *)&records[i]);
 			hop = hop->prev;
 			ind--;
 		}	
@@ -83,8 +81,7 @@ namespace tunnel
 			for (int i = 0; i < num; i++)
 			{			
 				uint8_t * record = msg + 1 + i*sizeof (I2NPBuildResponseRecord);
-				m_CBCDecryption.SetKeyWithIV(hop->replyKey, 32, hop->replyIV);
-				m_CBCDecryption.ProcessData(record, record, sizeof (I2NPBuildResponseRecord));
+				hop->decryption.Decrypt(record, sizeof (I2NPBuildResponseRecord), record);
 			}
 			hop = hop->prev;
 			num--;
@@ -99,21 +96,19 @@ namespace tunnel
 				// if any of participants declined the tunnel is not established
 				m_IsEstablished = false; 
 		}
+		if (m_IsEstablished) 
+		{
+			// change reply keys to layer keys
+			TunnelHopConfig * hop = m_Config->GetFirstHop ();
+			while (hop)
+			{
+				hop->decryption.SetKey (hop->layerKey);
+				hop->ivDecryption.SetKey (hop->ivKey);
+				hop = hop->next;
+			}	
+		}	
 		return m_IsEstablished;
 	}	
-	
-	void Tunnel::LayerDecrypt (const uint8_t * in, size_t len, const uint8_t * layerKey, 
-		const uint8_t * iv, uint8_t * out)
-	{
-		m_CBCDecryption.SetKeyWithIV (layerKey, 32, iv); 
-		m_CBCDecryption.ProcessData(out, in, len); 
-	}	
-
-	void Tunnel::IVDecrypt (const uint8_t * in, const uint8_t * ivKey, uint8_t * out)
-	{
-		m_ECBDecryption.SetKey (ivKey, 32); 
-		m_ECBDecryption.ProcessData(out, in, 16); 
-	}		
 
 	void Tunnel::EncryptTunnelMsg (I2NPMessage * tunnelMsg)
 	{
@@ -121,10 +116,14 @@ namespace tunnel
 		TunnelHopConfig * hop = m_Config->GetLastHop (); 
 		while (hop)
 		{	
-			// iv + data
-			IVDecrypt (payload, hop->ivKey, payload);
-			LayerDecrypt (payload + 16, TUNNEL_DATA_ENCRYPTED_SIZE, hop->layerKey, payload, payload+16);
-			IVDecrypt (payload, hop->ivKey, payload);
+			// iv
+			hop->ivDecryption.Decrypt ((i2p::crypto::ChipherBlock *)payload, (i2p::crypto::ChipherBlock *)payload);
+			// data
+			hop->decryption.SetIV (payload);
+			hop->decryption.Decrypt (payload + 16, TUNNEL_DATA_ENCRYPTED_SIZE, payload+16);
+			// double iv ecncryption
+			hop->ivDecryption.Decrypt ((i2p::crypto::ChipherBlock *)payload, (i2p::crypto::ChipherBlock *)payload);
+
 			hop = hop->prev;
 		}
 	}	
diff --git a/Tunnel.h b/Tunnel.h
index 16ffa9e4..dc345875 100644
--- a/Tunnel.h
+++ b/Tunnel.h
@@ -8,8 +8,6 @@
 #include <string>
 #include <thread>
 #include <mutex>
-#include <cryptopp/modes.h>
-#include <cryptopp/aes.h>
 #include "Queue.h"
 #include "TunnelConfig.h"
 #include "TunnelPool.h"
@@ -51,20 +49,11 @@ namespace tunnel
 			uint32_t GetNextTunnelID () const { return m_Config->GetFirstHop ()->tunnelID; };
 			const i2p::data::IdentHash& GetNextIdentHash () const { return m_Config->GetFirstHop ()->router->GetIdentHash (); };
 			
-		private:
-
-			void LayerDecrypt (const uint8_t * in, size_t len, const uint8_t * layerKey, 
-				const uint8_t * iv, uint8_t * out);
-			void IVDecrypt (const uint8_t * in, const uint8_t * ivKey, uint8_t * out);	
-			
 		private:
 
 			TunnelConfig * m_Config;
 			TunnelPool * m_Pool; // pool, tunnel belongs to, or null
-			bool m_IsEstablished, m_IsFailed; 
-
-			CryptoPP::ECB_Mode<CryptoPP::AES>::Decryption m_ECBDecryption;
-			CryptoPP::CBC_Mode<CryptoPP::AES>::Decryption m_CBCDecryption;
+			bool m_IsEstablished, m_IsFailed;
 	};	
 
 	class OutboundTunnel: public Tunnel 
diff --git a/TunnelConfig.h b/TunnelConfig.h
index b6eccda4..3db6c30e 100644
--- a/TunnelConfig.h
+++ b/TunnelConfig.h
@@ -4,6 +4,7 @@
 #include <inttypes.h>
 #include <sstream>
 #include <vector>
+#include "aes.h"
 #include "RouterInfo.h"
 #include "RouterContext.h"
 
@@ -22,7 +23,9 @@ namespace tunnel
 		bool isGateway, isEndpoint;	
 		
 		TunnelHopConfig * next, * prev;
-
+		i2p::crypto::CBCDecryption decryption;	
+		i2p::crypto::ECBDecryption ivDecryption;
+		
 		TunnelHopConfig (const i2p::data::RouterInfo * r)
 		{
 			CryptoPP::RandomNumberGenerator& rnd = i2p::context.GetRandomNumberGenerator ();
@@ -38,6 +41,8 @@ namespace tunnel
 
 			next = 0;
 			prev = 0;
+			decryption.SetKey (replyKey);
+			decryption.SetIV (replyIV);
 		}	
 
 		void SetNextRouter (const i2p::data::RouterInfo * r)