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 ivKey = hopConfig.getIVKey();
|
||||
SessionKey replyKey = hopConfig.getReplyKey();
|
||||
byte iv[] = hopConfig.getReplyIV();
|
||||
SessionKey replyKey = cfg.getAESReplyKey(hop);
|
||||
byte iv[] = cfg.getAESReplyIV(hop);
|
||||
if (iv == null) {
|
||||
iv = new byte[BuildRequestRecord.IV_SIZE];
|
||||
ctx.random().nextBytes(iv);
|
||||
hopConfig.setReplyIV(iv);
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
boolean isInGW = (cfg.isInbound() && (hop == 0));
|
||||
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
|
||||
int stop = (cfg.isInbound() ? 0 : 1);
|
||||
for (int j = hop-1; j >= stop; j--) {
|
||||
HopConfig hopConfig = cfg.getConfig(j);
|
||||
SessionKey key = hopConfig.getReplyKey();
|
||||
byte iv[] = hopConfig.getReplyIV();
|
||||
SessionKey key = cfg.getAESReplyKey(j);
|
||||
byte iv[] = cfg.getAESReplyIV(j);
|
||||
// corrupts the SDS
|
||||
ctx.aes().decrypt(rec.getData(), 0, rec.getData(), 0, key, iv, TunnelBuildMessage.RECORD_SIZE);
|
||||
}
|
||||
|
@ -108,9 +108,8 @@ public class BuildReplyHandler {
|
||||
end++;
|
||||
// do we need to adjust this for the endpoint?
|
||||
for (int j = start; j >= end; j--) {
|
||||
HopConfig hopConfig = cfg.getConfig(j);
|
||||
SessionKey replyKey = hopConfig.getReplyKey();
|
||||
byte replyIV[] = hopConfig.getReplyIV();
|
||||
SessionKey replyKey = cfg.getAESReplyKey(j);
|
||||
byte replyIV[] = cfg.getAESReplyIV(j);
|
||||
if (log.shouldLog(Log.DEBUG)) {
|
||||
log.debug(reply.getUniqueId() + ": Decrypting record " + recordNum + "/" + hop + "/" + j + " with replyKey "
|
||||
+ replyKey.toBase64() + "/" + Base64.encode(replyIV) + ": " + cfg);
|
||||
|
@ -37,9 +37,6 @@ public class HopConfig {
|
||||
//private int _messagesSent;
|
||||
//private int _oldMessagesSent;
|
||||
|
||||
/** IV length for {@link #getReplyIV} */
|
||||
public static final int REPLY_IV_LENGTH = 16;
|
||||
|
||||
public HopConfig() {
|
||||
_creation = -1;
|
||||
_expiration = -1;
|
||||
@ -90,35 +87,6 @@ public class HopConfig {
|
||||
public SessionKey getIVKey() { return _ivKey; }
|
||||
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)? */
|
||||
public long getExpiration() { return _expiration; }
|
||||
public void setExpiration(long when) { _expiration = when; }
|
||||
|
@ -41,8 +41,16 @@ public abstract class TunnelCreatorConfig implements TunnelInfo {
|
||||
private long _peakThroughputCurrentTotal;
|
||||
private long _peakThroughputLastCoallesce = System.currentTimeMillis();
|
||||
private Hash _blankHash;
|
||||
private SessionKey[] _replyKeys;
|
||||
private byte[][] _replyADs;
|
||||
private SessionKey[] _ChaReplyKeys;
|
||||
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
|
||||
private static final int MAX_CONSECUTIVE_TEST_FAILURES = 3;
|
||||
@ -70,6 +78,8 @@ public abstract class TunnelCreatorConfig implements TunnelInfo {
|
||||
}
|
||||
_isInbound = isInbound;
|
||||
_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; }
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @since 0.9.48
|
||||
@ -260,12 +300,12 @@ public abstract class TunnelCreatorConfig implements TunnelInfo {
|
||||
* @since 0.9.48
|
||||
*/
|
||||
public void setChaChaReplyKeys(int hop, SessionKey key, byte[] ad) {
|
||||
if (_replyKeys == null) {
|
||||
_replyKeys = new SessionKey[_config.length];
|
||||
_replyADs = new byte[_config.length][];
|
||||
if (_ChaReplyKeys == null) {
|
||||
_ChaReplyKeys = new SessionKey[_config.length];
|
||||
_ChaReplyADs = new byte[_config.length][];
|
||||
}
|
||||
_replyKeys[hop] = key;
|
||||
_replyADs[hop] = ad;
|
||||
_ChaReplyKeys[hop] = key;
|
||||
_ChaReplyADs[hop] = ad;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -273,9 +313,9 @@ public abstract class TunnelCreatorConfig implements TunnelInfo {
|
||||
* @since 0.9.48
|
||||
*/
|
||||
public boolean isEC(int hop) {
|
||||
if (_replyKeys == null)
|
||||
if (_ChaReplyKeys == null)
|
||||
return false;
|
||||
return _replyKeys[hop] != null;
|
||||
return _ChaReplyKeys[hop] != null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -283,9 +323,9 @@ public abstract class TunnelCreatorConfig implements TunnelInfo {
|
||||
* @since 0.9.48
|
||||
*/
|
||||
public SessionKey getChaChaReplyKey(int hop) {
|
||||
if (_replyKeys == null)
|
||||
if (_ChaReplyKeys == null)
|
||||
return null;
|
||||
return _replyKeys[hop];
|
||||
return _ChaReplyKeys[hop];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -293,9 +333,9 @@ public abstract class TunnelCreatorConfig implements TunnelInfo {
|
||||
* @since 0.9.48
|
||||
*/
|
||||
public byte[] getChaChaReplyAD(int hop) {
|
||||
if (_replyADs == null)
|
||||
if (_ChaReplyADs == null)
|
||||
return null;
|
||||
return _replyADs[hop];
|
||||
return _ChaReplyADs[hop];
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -19,6 +19,7 @@ import net.i2p.router.TunnelManagerFacade;
|
||||
import net.i2p.router.TunnelPoolSettings;
|
||||
import net.i2p.router.tunnel.BuildMessageGenerator;
|
||||
import net.i2p.router.tunnel.HopConfig;
|
||||
import net.i2p.router.tunnel.TunnelCreatorConfig;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.VersionComparator;
|
||||
|
||||
@ -104,10 +105,9 @@ abstract class BuildRequestor {
|
||||
|
||||
if (i > 0)
|
||||
cfg.getConfig(i-1).setSendTunnelId(hop.getReceiveTunnelId());
|
||||
byte iv[] = new byte[16];
|
||||
byte iv[] = new byte[TunnelCreatorConfig.REPLY_IV_LENGTH];
|
||||
ctx.random().nextBytes(iv);
|
||||
hop.setReplyIV(iv);
|
||||
hop.setReplyKey(ctx.keyGenerator().generateSessionKey());
|
||||
cfg.setAESReplyKeys(i, ctx.keyGenerator().generateSessionKey(), iv);
|
||||
}
|
||||
// This is in BuildExecutor.buildTunnel() now
|
||||
// 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.setIVKey(ctx.keyGenerator().generateSessionKey());
|
||||
hop.setLayerKey(ctx.keyGenerator().generateSessionKey());
|
||||
hop.setReplyKey(ctx.keyGenerator().generateSessionKey());
|
||||
byte iv[] = new byte[BuildRequestRecord.IV_SIZE];
|
||||
Arrays.fill(iv, (byte)i); // consistent for repeatability
|
||||
hop.setReplyIV(iv);
|
||||
cfg.setAESReplyKeys(i, ctx.keyGenerator().generateSessionKey(), iv);
|
||||
hop.setReceiveTunnelId(new TunnelId(i+1));
|
||||
}
|
||||
return cfg;
|
||||
|
Reference in New Issue
Block a user