diff --git a/history.txt b/history.txt index 009a6533f..992f53881 100644 --- a/history.txt +++ b/history.txt @@ -1,3 +1,11 @@ +2020-12-23 zzz + * Crypto: Increase ratchet tag window + +2020-12-22 zzz + * Console: + - Add netdb search by enc. type + - Move readme files to war + 2020-12-21 zzz * SSU: Fix partial acks not being sent diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index fecba78d6..a6204817e 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -18,7 +18,7 @@ public class RouterVersion { /** deprecated */ public final static String ID = "Monotone"; public final static String VERSION = CoreVersion.VERSION; - public final static long BUILD = 7; + public final static long BUILD = 8; /** for example "-test" */ public final static String EXTRA = ""; diff --git a/router/java/src/net/i2p/router/crypto/ratchet/ECIESAEADEngine.java b/router/java/src/net/i2p/router/crypto/ratchet/ECIESAEADEngine.java index 7e291e644..133e8c4cf 100644 --- a/router/java/src/net/i2p/router/crypto/ratchet/ECIESAEADEngine.java +++ b/router/java/src/net/i2p/router/crypto/ratchet/ECIESAEADEngine.java @@ -198,6 +198,8 @@ public final class ECIESAEADEngine { } else { decrypted = x_decryptSlow(data, targetPrivateKey, keyManager); } + if (decrypted == null && _log.shouldDebug()) + _log.info("Decrypt fail NS/NSR/ES, possible tag: " + st); return decrypted; } @@ -863,6 +865,7 @@ public final class ECIESAEADEngine { * may be null for anonymous (N-in-IK) * @param keyManager ignored if priv is null * @param callback may be null, ignored if priv is null + * @return encrypted data or null on failure */ private byte[] x_encrypt(CloveSet cloves, PublicKey target, Destination to, PrivateKey priv, RatchetSKM keyManager, @@ -901,9 +904,15 @@ public final class ECIESAEADEngine { _log.debug("Encrypting as NSR to " + target + " with tag " + re.tag.toBase64()); return encryptNewSessionReply(cloves, target, state, re.tag, keyManager, callback); } - if (_log.shouldDebug()) - _log.debug("Encrypting as ES to " + target + " with key " + re.key + " and tag " + re.tag.toBase64()); byte rv[] = encryptExistingSession(cloves, target, re, callback, keyManager); + if (rv == null) { + if (_log.shouldWarn()) + _log.warn("ECIES ES encrypt fail"); + } else if (_log.shouldDebug()) + _log.debug("Encrypting as ES to " + target + " with key " + re.key + " and tag " + re.tag.toBase64() + + " fwd key: " + re.nextForwardKey + + " rev key: " + re.nextReverseKey + + "; " + rv.length + " bytes"); return rv; } @@ -1126,11 +1135,11 @@ public final class ECIESAEADEngine { SessionKeyAndNonce key = re.key; int nonce = key.getNonce(); byte encr[] = encryptAEADBlock(rawTag, payload, key, nonce); - System.arraycopy(rawTag, 0, encr, 0, TAGLEN); - if (callback != null) { - keyManager.registerCallback(target, re.keyID, nonce, callback); + if (encr != null) { + System.arraycopy(rawTag, 0, encr, 0, TAGLEN); + if (callback != null) + keyManager.registerCallback(target, re.keyID, nonce, callback); } - _log.debug("Encrypted ES: " + encr.length + " bytes"); return encr; } @@ -1155,7 +1164,11 @@ public final class ECIESAEADEngine { byte rawTag[] = tag.getData(); byte[] payload = createPayload(cloves, 0, ES_OVERHEAD); byte encr[] = encryptAEADBlock(rawTag, payload, key, 0); - System.arraycopy(rawTag, 0, encr, 0, TAGLEN); + if (encr != null) { + System.arraycopy(rawTag, 0, encr, 0, TAGLEN); + } else if (_log.shouldWarn()) { + _log.warn("ECIES ES encrypt fail"); + } return encr; } @@ -1184,7 +1197,7 @@ public final class ECIESAEADEngine { /** * * @param ad may be null - * @return space will be left at beginning for ad (tag) + * @return space will be left at beginning for ad (tag), null on error */ private final byte[] encryptAEADBlock(byte[] ad, byte data[], SessionKey key, long n) { ChaChaPolyCipherState chacha = new ChaChaPolyCipherState(); diff --git a/router/java/src/net/i2p/router/crypto/ratchet/RatchetSKM.java b/router/java/src/net/i2p/router/crypto/ratchet/RatchetSKM.java index 2e0981ec8..6e52c6a61 100644 --- a/router/java/src/net/i2p/router/crypto/ratchet/RatchetSKM.java +++ b/router/java/src/net/i2p/router/crypto/ratchet/RatchetSKM.java @@ -959,12 +959,12 @@ public class RatchetSKM extends SessionKeyManager implements SessionTagListener private static final int MIN_RCV_WINDOW_NSR = 12; private static final int MAX_RCV_WINDOW_NSR = 12; private static final int MIN_RCV_WINDOW_ES = 24; - private static final int MAX_RCV_WINDOW_ES = 160; + private static final int MAX_RCV_WINDOW_ES = 320; private static final String INFO_0 = "SessionReplyTags"; private static final String INFO_7 = "XDHRatchetTagSet"; private static final int MAX_SEND_ACKS = 16; - private static final int MAX_SEND_REVERSE_KEY = 64; + private static final int MAX_SEND_REVERSE_KEY = 128; /** * @param d may be null @@ -1435,8 +1435,14 @@ public class RatchetSKM extends SessionKeyManager implements SessionTagListener _tagSet.setDate(now); SessionKeyAndNonce skn = _tagSet.consumeNextKey(); // TODO PN - return new RatchetEntry(tag, skn, _tagSet.getID(), 0, _tagSet.getNextKey(), - getReverseSendKey(), getAcksToSend()); + NextSessionKey fwd = _tagSet.getNextKey(); + NextSessionKey rev = getReverseSendKey(); + if ((fwd != null || rev != null) && _log.shouldInfo()) + _log.info("Sending fwd key: " + fwd + + " rev key: " + rev + + " for " + _tagSet); + return new RatchetEntry(tag, skn, _tagSet.getID(), 0, fwd, + rev, getAcksToSend()); } else if (_log.shouldInfo()) { _log.info("Removing empty " + _tagSet); } diff --git a/router/java/src/net/i2p/router/crypto/ratchet/RatchetTagSet.java b/router/java/src/net/i2p/router/crypto/ratchet/RatchetTagSet.java index 486488341..cab7c0cff 100644 --- a/router/java/src/net/i2p/router/crypto/ratchet/RatchetTagSet.java +++ b/router/java/src/net/i2p/router/crypto/ratchet/RatchetTagSet.java @@ -424,14 +424,14 @@ class RatchetTagSet implements TagSetHandle { int lookAhead, trimBehind; if (_maxSize > _originalSize) { // grow from originalSize at N = 0 to - // maxSize at N = 4 * (maxSize - originalSize) + // maxSize at N = 2 * (maxSize - originalSize) // for typical loss rates, this keeps us at about maxSize, - // but worst case maxSize * 3/2 - lookAhead = Math.min(_maxSize, _originalSize + (usedTagNumber / 4)); - trimBehind = lookAhead / 2; + // but worst case about maxSize * 2 + lookAhead = Math.min(_maxSize, _originalSize + (usedTagNumber / 2)); + trimBehind = lookAhead; } else { lookAhead = _originalSize; - trimBehind = _originalSize / 2; + trimBehind = _originalSize; } // add as many as we need to maintain minSize from the tag used