diff --git a/router/doc/tunnel.html b/router/doc/tunnel.html index 6b7ec90a9..102ccdedc 100644 --- a/router/doc/tunnel.html +++ b/router/doc/tunnel.html @@ -1,4 +1,4 @@ -$Id: tunnel.html,v 1.3 2005/01/12 14:22:40 jrandom Exp $ +$Id: tunnel.html,v 1.4 2005/01/12 19:57:36 jrandom Exp $
 1) Tunnel overview
 2) Tunnel operation
@@ -248,9 +248,9 @@ for certain whether any of the checksum blocks have been tagged, as that would
 corrupt the verification block (V[7]).

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.

+the IV so as to hamper key leakage. IV_WHITENER is a fixed 16 byte value.

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.

diff --git a/router/java/src/net/i2p/router/tunnel/GatewayMessage.java b/router/java/src/net/i2p/router/tunnel/GatewayMessage.java index 62d4a46a2..12f122afa 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 e6153c2b6..f6ef511dd 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);