From ffdcae47e3b5c493fa2428103f70f9920ba2b918 Mon Sep 17 00:00:00 2001
From: jrandom <jrandom>
Date: Fri, 14 Jan 2005 22:43:43 +0000
Subject: [PATCH] add some whitening to the IV as it goes down the path

---
 router/doc/tunnel.html                                     | 6 +++---
 router/java/src/net/i2p/router/tunnel/GatewayMessage.java  | 7 +++++++
 .../src/net/i2p/router/tunnel/TunnelMessageProcessor.java  | 2 ++
 3 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/router/doc/tunnel.html b/router/doc/tunnel.html
index 6b7ec90a9f..102ccdedce 100644
--- a/router/doc/tunnel.html
+++ b/router/doc/tunnel.html
@@ -1,4 +1,4 @@
-<code>$Id: tunnel.html,v 1.3 2005/01/12 14:22:40 jrandom Exp $</code>
+<code>$Id: tunnel.html,v 1.4 2005/01/12 19:57:36 jrandom Exp $</code>
 <pre>
 1) <a href="#tunnel.overview">Tunnel overview</a>
 2) <a href="#tunnel.operation">Tunnel operation</a>
@@ -248,9 +248,9 @@ for certain whether any of the checksum blocks have been tagged, as that would
 corrupt the verification block (V[7]).</p>
 
 <p>The IV[0] is a random 16 byte value, and IV[i] is the first 16 bytes of 
-H(D(IV[i-1], K[i-1])).  We don't use the same IV along the path, as that would
+H(D(IV[i-1], K[i-1]) xor IV_WHITENER).  We don't use the same IV along the path, as that would
 allow trivial collusion, and we use the hash of the decrypted value to propogate 
-the IV so as to hamper key leakage.</p>
+the IV so as to hamper key leakage.  IV_WHITENER is a fixed 16 byte value.</p>
 
 <p>When the gateway wants to send the message, they export the right row for the
 peer who is the first hop (usually the peer1.recv row) and forward that entirely.</p>
diff --git a/router/java/src/net/i2p/router/tunnel/GatewayMessage.java b/router/java/src/net/i2p/router/tunnel/GatewayMessage.java
index 62d4a46a28..12f122afac 100644
--- a/router/java/src/net/i2p/router/tunnel/GatewayMessage.java
+++ b/router/java/src/net/i2p/router/tunnel/GatewayMessage.java
@@ -54,6 +54,12 @@ public class GatewayMessage {
     private static final int COLUMNS = HOPS;
     private static final int HASH_ROWS = HOPS;
     
+    /** used to munge the IV during per-hop translations */
+    static final byte IV_WHITENER[] = new byte[] { (byte)0x31, (byte)0xd6, (byte)0x74, (byte)0x17, 
+                                                   (byte)0xa0, (byte)0xb6, (byte)0x28, (byte)0xed, 
+                                                   (byte)0xdf, (byte)0xee, (byte)0x5b, (byte)0x86, 
+                                                   (byte)0x74, (byte)0x61, (byte)0x50, (byte)0x7d };
+    
     public GatewayMessage(I2PAppContext ctx) {
         _context = ctx;
         _log = ctx.logManager().getLog(GatewayMessage.class);
@@ -135,6 +141,7 @@ public class GatewayMessage {
             
             // decrypt, since we're simulating what the participants do
             _context.aes().decryptBlock(_iv[i-1], 0, key, _iv[i], 0);
+            DataHelper.xor(_iv[i], 0, IV_WHITENER, 0, _iv[i], 0, IV_SIZE);
             Hash h = _context.sha().calculateHash(_iv[i]);
             System.arraycopy(h.getData(), 0, _iv[i], 0, IV_SIZE);
         }
diff --git a/router/java/src/net/i2p/router/tunnel/TunnelMessageProcessor.java b/router/java/src/net/i2p/router/tunnel/TunnelMessageProcessor.java
index e6153c2b6c..f6ef511dd2 100644
--- a/router/java/src/net/i2p/router/tunnel/TunnelMessageProcessor.java
+++ b/router/java/src/net/i2p/router/tunnel/TunnelMessageProcessor.java
@@ -87,7 +87,9 @@ public class TunnelMessageProcessor {
         }
         
         // update the IV for the next layer
+        
         ctx.aes().decryptBlock(data, 0, layerKey, data, 0);
+        DataHelper.xor(data, 0, GatewayMessage.IV_WHITENER, 0, data, 0, IV_SIZE);
         Hash h = ctx.sha().calculateHash(data, 0, IV_SIZE);
         System.arraycopy(h.getData(), 0, data, 0, IV_SIZE);
         
-- 
GitLab