You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by tw...@apache.org on 2021/07/11 22:26:22 UTC
[mina-sshd] 01/03: [SSHD-1191] Abstract session: correct rekey
block count limit
This is an automated email from the ASF dual-hosted git repository.
twolf pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mina-sshd.git
commit 1c5987d4130f5883795d0098c69cf04cc619b11b
Author: Thomas Wolf <tw...@apache.org>
AuthorDate: Sun Jul 11 23:35:29 2021 +0200
[SSHD-1191] Abstract session: correct rekey block count limit
Follow the recommendation from RFC 4344: if the cipher block size
is smaller than 16, re-key after 1GB of data.[1] Otherwise, we'd
re-key far too often; for instance with a block size of 8 after 64k
blocks, i.e., after 512kB of data. Note that chacha20-poly1305 has
a block size of 8.
OpenSSH uses the same implementation.[2]
[1] https://datatracker.ietf.org/doc/html/rfc4344#section-3.2
[2]https://github.com/openssh/openssh-portable/blob/99981d5f/packet.c#L940
---
.../common/session/helpers/AbstractSession.java | 49 ++++++++++++++++++----
1 file changed, 40 insertions(+), 9 deletions(-)
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java b/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java
index 14da167..ffd0d2c 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java
@@ -1760,16 +1760,10 @@ public abstract class AbstractSession extends SessionHelper {
// TODO add support for configurable compression level
inCompression.init(Compression.Type.Inflater, -1);
- // see https://tools.ietf.org/html/rfc4344#section-3.2
- // select the lowest cipher size
- int avgCipherBlockSize = Math.min(inCipherSize, outCipherSize);
- long recommendedByteRekeyBlocks = 1L << Math.min((avgCipherBlockSize * Byte.SIZE) / 4,
- 63); // in case (block-size / 4) > 63
- long effectiveRekeyBlocksCount = CoreModuleProperties.REKEY_BLOCKS_LIMIT.getRequired(this);
- maxRekeyBlocks.set(effectiveRekeyBlocksCount > 0 ? effectiveRekeyBlocksCount : recommendedByteRekeyBlocks);
+ maxRekeyBlocks.set(determineRekeyBlockLimit(inCipherSize, outCipherSize));
if (debugEnabled) {
- log.debug("receiveNewKeys({}) inCipher={}, outCipher={}, recommended blocks limit={}, actual={}",
- this, inCipher, outCipher, recommendedByteRekeyBlocks, maxRekeyBlocks);
+ log.debug("receiveNewKeys({}) inCipher={}, outCipher={}, blocks limit={}", this, inCipher, outCipher,
+ maxRekeyBlocks);
}
inBytesCount.set(0L);
@@ -1783,6 +1777,43 @@ public abstract class AbstractSession extends SessionHelper {
}
/**
+ * Compute the number of blocks after which we should re-key again. See RFC 4344.
+ *
+ * @param inCipherBlockSize block size of the input cipher
+ * @param outCipherBlockSize block size of the output cipher
+ * @return the number of block after which re-keying occur at the latest
+ * @see <a href= "https://tools.ietf.org/html/rfc4344#section-3.2">RFC 4344, section 3.2</a>
+ */
+ protected long determineRekeyBlockLimit(int inCipherBlockSize, int outCipherBlockSize) {
+ // see https://tools.ietf.org/html/rfc4344#section-3.2
+ // select the lowest cipher size
+ long rekeyBlocksLimit = CoreModuleProperties.REKEY_BLOCKS_LIMIT.getRequired(this);
+ if (rekeyBlocksLimit <= 0) {
+ // Default per RFC 4344
+ int minCipherBlockBytes = Math.min(inCipherSize, outCipherSize);
+ if (minCipherBlockBytes >= 16) {
+ rekeyBlocksLimit = 1L << Math.min(minCipherBlockBytes * 2, 63);
+ } else {
+ // With a block size of 8 we'd end up with 2^16. That would re-key very often.
+ // RFC 4344: "If L is less than 128 [...], then, although it may be too
+ // expensive to rekey every 2**(L/4) blocks, it is still advisable for SSH
+ // implementations to follow the original recommendation in [RFC4253]: rekey at
+ // least once for every gigabyte of transmitted data."
+ //
+ // Note that chacha20-poly1305 has a block size of 8. The OpenSSH recommendation
+ // is: "ChaCha20 must never reuse a {key, nonce} for encryption nor may it be
+ // used to encrypt more than 2^70 bytes under the same {key, nonce}. The
+ // SSH Transport protocol (RFC4253) recommends a far more conservative
+ // rekeying every 1GB of data sent or received. If this recommendation
+ // is followed, then chacha20-poly1305@openssh.com requires no special
+ // handling in this area."
+ rekeyBlocksLimit = (1L << 30) / minCipherBlockBytes; // 1GB
+ }
+ }
+ return rekeyBlocksLimit;
+ }
+
+ /**
* Send a {@code SSH_MSG_UNIMPLEMENTED} packet. This packet should contain the sequence id of the unsupported
* packet: this number is assumed to be the last packet received.
*