Ah, with an internal block size [Is that what one calls it?] of 64 bytes. From: Damien Miller <djm@xxxxxxxxxxx> Sent: Wednesday, March 29, 2023 3:08 PM To: Robinson, Herbie <Herbie.Robinson@xxxxxxxxxxx> Cc: Chris Rapier <rapier@xxxxxxx>; Christian Weisgerber <naddy@xxxxxxxxxxxx>; openssh-unix-dev@xxxxxxxxxxx Subject: RE: [EXTERNAL] Re: ChaCha20 Rekey Frequency [EXTERNAL SENDER: This email originated from outside of Stratus Technologies. Do not click links or open attachments unless you recognize the sender and know the content is safe.] That's true for block ciphers, but ChaCha20+poly1305 is a stream cipher. On Wed, 29 Mar 2023, Robinson, Herbie wrote: > > I'm hardly an expert on this, but if I remember correctly, the rekey rate > for good security is mostly dependent on the cipher block size. I left my > reference books at home; so, I can't come up with a reference for you, but I > would take Chris' "I'm deeply unsure of what impact that would have on the > security of the cipher" comment seriously and switch to a cipher with a 128 > bit block length (AES or Camelia). > > > > From: openssh-unix-dev > <openssh-unix-dev-bounces+herbie.robinson=stratus.com@xxxxxxxxxxx<mailto:openssh-unix-dev-bounces+herbie.robinson=stratus.com@xxxxxxxxxxx>> On Behalf > Of Damien Miller > Sent: Wednesday, March 29, 2023 2:38 PM > To: Chris Rapier <rapier@xxxxxxx<mailto:rapier@xxxxxxx>> > Cc: Christian Weisgerber <naddy@xxxxxxxxxxxx<mailto:naddy@xxxxxxxxxxxx>>; openssh-unix-dev@xxxxxxxxxxx<mailto:openssh-unix-dev@xxxxxxxxxxx> > Subject: [EXTERNAL] Re: ChaCha20 Rekey Frequency > > > > [EXTERNAL SENDER: This email originated from outside of Stratus > Technologies. Do not click links or open attachments unless you recognize > the sender and know the content is safe.] > > On Wed, 29 Mar 2023, Chris Rapier wrote: > > > I was wondering if there was something specific to the internal chacha20 > > cipher as opposed to OpenSSL implementation. > > > > I can't just change the block size because it breaks compatibility. I can > do > > something like as a hack (though it would probably be better to do it with > the > > compat function): > > > > if (strstr(enc->name, "chacha")) > > *max_blocks = (u_int64_t)1 << (16*2); > > else if (enc->block_size >= 16) > > *max_blocks = (u_int64_t)1 << (enc->block_size*2); > > else > > *max_blocks = ((u_int64_t)1 << 30) / enc->block_size; > > if (state->rekey_limit) > > > > to force it to reduce the rekey rate but I'm deeply unsure of what impact > that > > would have on the security of the cipher as it's implemented. Especially > the > > without-openssl internal implementation. > > This is what I'm playing with at the moment: > > diff --git a/cipher.c b/cipher.c > index c7664a3..ec6fa4f 100644 > --- a/cipher.c > +++ b/cipher.c > @@ -150,6 +150,39 @@ cipher_blocksize(const struct sshcipher *c) > return (c->block_size); > } > > +uint64_t > +cipher_rekey_blocks(const struct sshcipher *c) > +{ > + /* > + * Chacha20-Poly1305 does not benefit from data-based rekeying, > + * per "The Security of ChaCha20-Poly1305 in the Multi-user Setting", > + * Degabriele, J. P., Govinden, J, Gunther, F. and Paterson K. > + * ACM CCS 2021; https://eprint.iacr.org/2023/085.pdf<https://eprint.iacr.org/2023/085.pdf> > + * > + * Cryptanalysis aside, we do still want do need to prevent the SSH > + * sequence number wrapping and also to rekey to provide some > + * protection for long lived sessions against key disclosure at the > + * endpoints, so arrange for rekeying every 2**32 blocks as the > + * 128-bit block ciphers do (i.e. every 32GB data). > + */ > + if ((c->flags & CFLAG_CHACHAPOLY) != 0) > + return (uint64_t)1 << 32; > + /* > + * The 2^(blocksize*2) limit is too expensive for 3DES, > + * so enforce a 1GB data limit for small blocksizes. > + * See discussion in RFC4344 section 3.2. > + */ > + if (c->block_size < 16) > + return ((uint64_t)1 << 30) / c->block_size; > + /* > + * Otherwise, use the RFC4344 s3.2 recommendation of 2**(L/4) blocks > + * before rekeying where L is the blocksize in bits. > + * Most other ciphers have a 128 bit blocksize, so this equates to > + * 2**32 blocks / 64GB data. > + */ > + return (uint64_t)1 << (c->block_size * 2); > +} > + > u_int > cipher_keylen(const struct sshcipher *c) > { > diff --git a/cipher.h b/cipher.h > index 1a591cd..68be9ed 100644 > --- a/cipher.h > +++ b/cipher.h > @@ -63,6 +63,7 @@ int cipher_get_length(struct sshcipher_ctx *, u_int *, > u_int, > const u_char *, u_int); > void cipher_free(struct sshcipher_ctx *); > u_int cipher_blocksize(const struct sshcipher *); > +uint64_t cipher_rekey_blocks(const struct sshcipher *); > u_int cipher_keylen(const struct sshcipher *); > u_int cipher_seclen(const struct sshcipher *); > u_int cipher_authlen(const struct sshcipher *); > diff --git a/packet.c b/packet.c > index a71820f..377f608 100644 > --- a/packet.c > +++ b/packet.c > @@ -55,6 +55,7 @@ > #include <poll.h> > #include <signal.h> > #include <time.h> > +#include <util.h> > > #ifdef WITH_ZLIB > #include <zlib.h> > @@ -850,6 +851,7 @@ ssh_set_newkeys(struct ssh *ssh, int mode) > const char *wmsg; > int r, crypt_type; > const char *dir = mode == MODE_OUT ? "out" : "in"; > + char blocks_s[FMT_SCALED_STRSIZE], bytes_s[FMT_SCALED_STRSIZE]; > > debug2_f("mode %d", mode); > > @@ -917,20 +919,18 @@ ssh_set_newkeys(struct ssh *ssh, int mode) > } > comp->enabled = 1; > } > - /* > - * The 2^(blocksize*2) limit is too expensive for 3DES, > - * so enforce a 1GB limit for small blocksizes. > - * See RFC4344 section 3.2. > - */ > - if (enc->block_size >= 16) > - *max_blocks = (u_int64_t)1 << (enc->block_size*2); > - else > - *max_blocks = ((u_int64_t)1 << 30) / enc->block_size; > + *max_blocks = cipher_rekey_blocks(enc->cipher); > if (state->rekey_limit) > *max_blocks = MINIMUM(*max_blocks, > state->rekey_limit / enc->block_size); > - debug("rekey %s after %llu blocks", dir, > - (unsigned long long)*max_blocks); > + > + strlcpy(blocks_s, "?", sizeof(blocks_s)); > + strlcpy(bytes_s, "?", sizeof(bytes_s)); > + if (*max_blocks * enc->block_size < LLONG_MAX) { > + fmt_scaled((long long)*max_blocks, blocks_s); > + fmt_scaled((long long)*max_blocks * enc->block_size, bytes_s); > + } > + debug("rekey %s after %s blocks / %sB data", dir, blocks_s, bytes_s); > return 0; > } > > _______________________________________________ > openssh-unix-dev mailing list > openssh-unix-dev@xxxxxxxxxxx<mailto:openssh-unix-dev@xxxxxxxxxxx> > https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev<https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev> > > > _______________________________________________ openssh-unix-dev mailing list openssh-unix-dev@xxxxxxxxxxx https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev