forked from I2P_Developers/i2p.i2p
Tunnels: Move AES reply keys from HopConfig to TunnelCreatorConfig
to save space; not stored for participating tunnels.
This commit is contained in:
@ -96,12 +96,10 @@ public abstract class BuildMessageGenerator {
|
|||||||
}
|
}
|
||||||
SessionKey layerKey = hopConfig.getLayerKey();
|
SessionKey layerKey = hopConfig.getLayerKey();
|
||||||
SessionKey ivKey = hopConfig.getIVKey();
|
SessionKey ivKey = hopConfig.getIVKey();
|
||||||
SessionKey replyKey = hopConfig.getReplyKey();
|
SessionKey replyKey = cfg.getAESReplyKey(hop);
|
||||||
byte iv[] = hopConfig.getReplyIV();
|
byte iv[] = cfg.getAESReplyIV(hop);
|
||||||
if (iv == null) {
|
if (iv == null) {
|
||||||
iv = new byte[BuildRequestRecord.IV_SIZE];
|
throw new IllegalStateException();
|
||||||
ctx.random().nextBytes(iv);
|
|
||||||
hopConfig.setReplyIV(iv);
|
|
||||||
}
|
}
|
||||||
boolean isInGW = (cfg.isInbound() && (hop == 0));
|
boolean isInGW = (cfg.isInbound() && (hop == 0));
|
||||||
boolean isOutEnd = (!cfg.isInbound() && (hop + 1 >= cfg.getLength()));
|
boolean isOutEnd = (!cfg.isInbound() && (hop + 1 >= cfg.getLength()));
|
||||||
@ -152,9 +150,8 @@ public abstract class BuildMessageGenerator {
|
|||||||
// ok, now decrypt the record with all of the reply keys from cfg.getConfig(0) through hop-1
|
// ok, now decrypt the record with all of the reply keys from cfg.getConfig(0) through hop-1
|
||||||
int stop = (cfg.isInbound() ? 0 : 1);
|
int stop = (cfg.isInbound() ? 0 : 1);
|
||||||
for (int j = hop-1; j >= stop; j--) {
|
for (int j = hop-1; j >= stop; j--) {
|
||||||
HopConfig hopConfig = cfg.getConfig(j);
|
SessionKey key = cfg.getAESReplyKey(j);
|
||||||
SessionKey key = hopConfig.getReplyKey();
|
byte iv[] = cfg.getAESReplyIV(j);
|
||||||
byte iv[] = hopConfig.getReplyIV();
|
|
||||||
// corrupts the SDS
|
// corrupts the SDS
|
||||||
ctx.aes().decrypt(rec.getData(), 0, rec.getData(), 0, key, iv, TunnelBuildMessage.RECORD_SIZE);
|
ctx.aes().decrypt(rec.getData(), 0, rec.getData(), 0, key, iv, TunnelBuildMessage.RECORD_SIZE);
|
||||||
}
|
}
|
||||||
|
@ -108,9 +108,8 @@ public class BuildReplyHandler {
|
|||||||
end++;
|
end++;
|
||||||
// do we need to adjust this for the endpoint?
|
// do we need to adjust this for the endpoint?
|
||||||
for (int j = start; j >= end; j--) {
|
for (int j = start; j >= end; j--) {
|
||||||
HopConfig hopConfig = cfg.getConfig(j);
|
SessionKey replyKey = cfg.getAESReplyKey(j);
|
||||||
SessionKey replyKey = hopConfig.getReplyKey();
|
byte replyIV[] = cfg.getAESReplyIV(j);
|
||||||
byte replyIV[] = hopConfig.getReplyIV();
|
|
||||||
if (log.shouldLog(Log.DEBUG)) {
|
if (log.shouldLog(Log.DEBUG)) {
|
||||||
log.debug(reply.getUniqueId() + ": Decrypting record " + recordNum + "/" + hop + "/" + j + " with replyKey "
|
log.debug(reply.getUniqueId() + ": Decrypting record " + recordNum + "/" + hop + "/" + j + " with replyKey "
|
||||||
+ replyKey.toBase64() + "/" + Base64.encode(replyIV) + ": " + cfg);
|
+ replyKey.toBase64() + "/" + Base64.encode(replyIV) + ": " + cfg);
|
||||||
|
@ -37,9 +37,6 @@ public class HopConfig {
|
|||||||
//private int _messagesSent;
|
//private int _messagesSent;
|
||||||
//private int _oldMessagesSent;
|
//private int _oldMessagesSent;
|
||||||
|
|
||||||
/** IV length for {@link #getReplyIV} */
|
|
||||||
public static final int REPLY_IV_LENGTH = 16;
|
|
||||||
|
|
||||||
public HopConfig() {
|
public HopConfig() {
|
||||||
_creation = -1;
|
_creation = -1;
|
||||||
_expiration = -1;
|
_expiration = -1;
|
||||||
@ -90,35 +87,6 @@ public class HopConfig {
|
|||||||
public SessionKey getIVKey() { return _ivKey; }
|
public SessionKey getIVKey() { return _ivKey; }
|
||||||
public void setIVKey(SessionKey key) { _ivKey = key; }
|
public void setIVKey(SessionKey key) { _ivKey = key; }
|
||||||
|
|
||||||
/**
|
|
||||||
* Key to encrypt the reply sent for the tunnel creation crypto.
|
|
||||||
* Not used for participating tunnels, will return null,
|
|
||||||
* candidate for moving to TunnelCreatorConfig.
|
|
||||||
* @return key or null
|
|
||||||
*/
|
|
||||||
public SessionKey getReplyKey() { return _replyKey; }
|
|
||||||
public void setReplyKey(SessionKey key) { _replyKey = key; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* IV used to encrypt the reply sent for the tunnel creation crypto.
|
|
||||||
* Not used for participating tunnels, will return null,
|
|
||||||
* candidate for moving to TunnelCreatorConfig.
|
|
||||||
*
|
|
||||||
* @return 16 bytes or null
|
|
||||||
*/
|
|
||||||
public byte[] getReplyIV() { return _replyIV; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* IV used to encrypt the reply sent for the tunnel creation crypto
|
|
||||||
*
|
|
||||||
* @throws IllegalArgumentException if not 16 bytes
|
|
||||||
*/
|
|
||||||
public void setReplyIV(byte[] iv) {
|
|
||||||
if (iv.length != REPLY_IV_LENGTH)
|
|
||||||
throw new IllegalArgumentException();
|
|
||||||
_replyIV = iv;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** when does this tunnel expire (in ms since the epoch)? */
|
/** when does this tunnel expire (in ms since the epoch)? */
|
||||||
public long getExpiration() { return _expiration; }
|
public long getExpiration() { return _expiration; }
|
||||||
public void setExpiration(long when) { _expiration = when; }
|
public void setExpiration(long when) { _expiration = when; }
|
||||||
|
@ -41,8 +41,16 @@ public abstract class TunnelCreatorConfig implements TunnelInfo {
|
|||||||
private long _peakThroughputCurrentTotal;
|
private long _peakThroughputCurrentTotal;
|
||||||
private long _peakThroughputLastCoallesce = System.currentTimeMillis();
|
private long _peakThroughputLastCoallesce = System.currentTimeMillis();
|
||||||
private Hash _blankHash;
|
private Hash _blankHash;
|
||||||
private SessionKey[] _replyKeys;
|
private SessionKey[] _ChaReplyKeys;
|
||||||
private byte[][] _replyADs;
|
private byte[][] _ChaReplyADs;
|
||||||
|
private final SessionKey[] _AESReplyKeys;
|
||||||
|
private final byte[][] _AESReplyIVs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IV length for {@link #getAESReplyIV}
|
||||||
|
* @since 0.9.48 moved from HopConfig
|
||||||
|
*/
|
||||||
|
public static final int REPLY_IV_LENGTH = 16;
|
||||||
|
|
||||||
// Make configurable? - but can't easily get to pool options from here
|
// Make configurable? - but can't easily get to pool options from here
|
||||||
private static final int MAX_CONSECUTIVE_TEST_FAILURES = 3;
|
private static final int MAX_CONSECUTIVE_TEST_FAILURES = 3;
|
||||||
@ -70,6 +78,8 @@ public abstract class TunnelCreatorConfig implements TunnelInfo {
|
|||||||
}
|
}
|
||||||
_isInbound = isInbound;
|
_isInbound = isInbound;
|
||||||
_destination = destination;
|
_destination = destination;
|
||||||
|
_AESReplyKeys = new SessionKey[length];
|
||||||
|
_AESReplyIVs = new byte[length][];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -243,6 +253,36 @@ public abstract class TunnelCreatorConfig implements TunnelInfo {
|
|||||||
*/
|
*/
|
||||||
public void setPriority(int priority) { _priority = priority; }
|
public void setPriority(int priority) { _priority = priority; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key and IV to encrypt the reply sent for the tunnel creation crypto.
|
||||||
|
*
|
||||||
|
* @throws IllegalArgumentException if iv not 16 bytes
|
||||||
|
* @since 0.9.48 moved from HopConfig
|
||||||
|
*/
|
||||||
|
public void setAESReplyKeys(int hop, SessionKey key, byte[] iv) {
|
||||||
|
if (iv.length != REPLY_IV_LENGTH)
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
_AESReplyKeys[hop] = key;
|
||||||
|
_AESReplyIVs[hop] = iv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key to encrypt the reply sent for the tunnel creation crypto.
|
||||||
|
*
|
||||||
|
* @return key or null
|
||||||
|
* @throws IllegalArgumentException if iv not 16 bytes
|
||||||
|
* @since 0.9.48 moved from HopConfig
|
||||||
|
*/
|
||||||
|
public SessionKey getAESReplyKey(int hop) { return _AESReplyKeys[hop]; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IV used to encrypt the reply sent for the tunnel creation crypto.
|
||||||
|
*
|
||||||
|
* @return 16 bytes or null
|
||||||
|
* @since 0.9.48 moved from HopConfig
|
||||||
|
*/
|
||||||
|
public byte[] getAESReplyIV(int hop) { return _AESReplyIVs[hop]; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checksum for blank record
|
* Checksum for blank record
|
||||||
* @since 0.9.48
|
* @since 0.9.48
|
||||||
@ -260,12 +300,12 @@ public abstract class TunnelCreatorConfig implements TunnelInfo {
|
|||||||
* @since 0.9.48
|
* @since 0.9.48
|
||||||
*/
|
*/
|
||||||
public void setChaChaReplyKeys(int hop, SessionKey key, byte[] ad) {
|
public void setChaChaReplyKeys(int hop, SessionKey key, byte[] ad) {
|
||||||
if (_replyKeys == null) {
|
if (_ChaReplyKeys == null) {
|
||||||
_replyKeys = new SessionKey[_config.length];
|
_ChaReplyKeys = new SessionKey[_config.length];
|
||||||
_replyADs = new byte[_config.length][];
|
_ChaReplyADs = new byte[_config.length][];
|
||||||
}
|
}
|
||||||
_replyKeys[hop] = key;
|
_ChaReplyKeys[hop] = key;
|
||||||
_replyADs[hop] = ad;
|
_ChaReplyADs[hop] = ad;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -273,9 +313,9 @@ public abstract class TunnelCreatorConfig implements TunnelInfo {
|
|||||||
* @since 0.9.48
|
* @since 0.9.48
|
||||||
*/
|
*/
|
||||||
public boolean isEC(int hop) {
|
public boolean isEC(int hop) {
|
||||||
if (_replyKeys == null)
|
if (_ChaReplyKeys == null)
|
||||||
return false;
|
return false;
|
||||||
return _replyKeys[hop] != null;
|
return _ChaReplyKeys[hop] != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -283,9 +323,9 @@ public abstract class TunnelCreatorConfig implements TunnelInfo {
|
|||||||
* @since 0.9.48
|
* @since 0.9.48
|
||||||
*/
|
*/
|
||||||
public SessionKey getChaChaReplyKey(int hop) {
|
public SessionKey getChaChaReplyKey(int hop) {
|
||||||
if (_replyKeys == null)
|
if (_ChaReplyKeys == null)
|
||||||
return null;
|
return null;
|
||||||
return _replyKeys[hop];
|
return _ChaReplyKeys[hop];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -293,9 +333,9 @@ public abstract class TunnelCreatorConfig implements TunnelInfo {
|
|||||||
* @since 0.9.48
|
* @since 0.9.48
|
||||||
*/
|
*/
|
||||||
public byte[] getChaChaReplyAD(int hop) {
|
public byte[] getChaChaReplyAD(int hop) {
|
||||||
if (_replyADs == null)
|
if (_ChaReplyADs == null)
|
||||||
return null;
|
return null;
|
||||||
return _replyADs[hop];
|
return _ChaReplyADs[hop];
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -19,6 +19,7 @@ import net.i2p.router.TunnelManagerFacade;
|
|||||||
import net.i2p.router.TunnelPoolSettings;
|
import net.i2p.router.TunnelPoolSettings;
|
||||||
import net.i2p.router.tunnel.BuildMessageGenerator;
|
import net.i2p.router.tunnel.BuildMessageGenerator;
|
||||||
import net.i2p.router.tunnel.HopConfig;
|
import net.i2p.router.tunnel.HopConfig;
|
||||||
|
import net.i2p.router.tunnel.TunnelCreatorConfig;
|
||||||
import net.i2p.util.Log;
|
import net.i2p.util.Log;
|
||||||
import net.i2p.util.VersionComparator;
|
import net.i2p.util.VersionComparator;
|
||||||
|
|
||||||
@ -104,10 +105,9 @@ abstract class BuildRequestor {
|
|||||||
|
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
cfg.getConfig(i-1).setSendTunnelId(hop.getReceiveTunnelId());
|
cfg.getConfig(i-1).setSendTunnelId(hop.getReceiveTunnelId());
|
||||||
byte iv[] = new byte[16];
|
byte iv[] = new byte[TunnelCreatorConfig.REPLY_IV_LENGTH];
|
||||||
ctx.random().nextBytes(iv);
|
ctx.random().nextBytes(iv);
|
||||||
hop.setReplyIV(iv);
|
cfg.setAESReplyKeys(i, ctx.keyGenerator().generateSessionKey(), iv);
|
||||||
hop.setReplyKey(ctx.keyGenerator().generateSessionKey());
|
|
||||||
}
|
}
|
||||||
// This is in BuildExecutor.buildTunnel() now
|
// This is in BuildExecutor.buildTunnel() now
|
||||||
// And it was overwritten by the one in createTunnelBuildMessage() anyway!
|
// And it was overwritten by the one in createTunnelBuildMessage() anyway!
|
||||||
|
@ -172,10 +172,9 @@ public class BuildMessageTestStandalone extends TestCase {
|
|||||||
hop.setExpiration(now+10*60*1000);
|
hop.setExpiration(now+10*60*1000);
|
||||||
hop.setIVKey(ctx.keyGenerator().generateSessionKey());
|
hop.setIVKey(ctx.keyGenerator().generateSessionKey());
|
||||||
hop.setLayerKey(ctx.keyGenerator().generateSessionKey());
|
hop.setLayerKey(ctx.keyGenerator().generateSessionKey());
|
||||||
hop.setReplyKey(ctx.keyGenerator().generateSessionKey());
|
|
||||||
byte iv[] = new byte[BuildRequestRecord.IV_SIZE];
|
byte iv[] = new byte[BuildRequestRecord.IV_SIZE];
|
||||||
Arrays.fill(iv, (byte)i); // consistent for repeatability
|
Arrays.fill(iv, (byte)i); // consistent for repeatability
|
||||||
hop.setReplyIV(iv);
|
cfg.setAESReplyKeys(i, ctx.keyGenerator().generateSessionKey(), iv);
|
||||||
hop.setReceiveTunnelId(new TunnelId(i+1));
|
hop.setReceiveTunnelId(new TunnelId(i+1));
|
||||||
}
|
}
|
||||||
return cfg;
|
return cfg;
|
||||||
|
Reference in New Issue
Block a user