[Bug 2521] New: subtract buffer size from computed rekey limit to avoid exceeding it
bugzilla-daemon at bugzilla.mindrot.org
bugzilla-daemon at bugzilla.mindrot.org
Wed Jan 6 09:09:48 AEDT 2016
https://bugzilla.mindrot.org/show_bug.cgi?id=2521
Bug ID: 2521
Summary: subtract buffer size from computed rekey limit to
avoid exceeding it
Product: Portable OpenSSH
Version: 6.8p1
Hardware: amd64
OS: Linux
Status: NEW
Severity: minor
Priority: P5
Component: sshd
Assignee: unassigned-bugs at mindrot.org
Reporter: olo at fb.com
Created attachment 2778
--> https://bugzilla.mindrot.org/attachment.cgi?id=2778&action=edit
The patch to rekey limit computation, based on GitHub commit 2c48eb1
I'm refiling this report in Bugzilla as a follow-up to my GitHub pull
request https://github.com/openssh/openssh-portable/pull/19 (which went
largely unnoticed).
The pull request changes the way in which the rekey limit is computed
based on cipher block size to address a problem with OpenSSH going over
the intended limit.
But first, a short background story:
In 2013, Red Hat has introduced a patch for OpenSSL that adds some
additional checks to its GCM implementation:
https://lists.fedoraproject.org/pipermail/scm-commits/Week-of-Mon-20131111/1144834.html
These checks are based on recommendations from NIST SP 800-38D:
http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
Among those, section 5.2.1.1 imposes a limit on plaintext length that
amounts to 64 GiB.
At Facebook, this was causing our scp transfers larger than 64 GiB to
die with a cipher_crypt: EVP_Cipher failed error.
The check implementing this limit has been recently rolled back by Red
Hat:
https://rhn.redhat.com/errata/RHBA-2015-0772.html
The reason for dropping it is stated in the package's ChangeLog:
Thu Mar 26 2015 Tomáš Mráz tmraz at redhat.com 1.0.1e-30.8
drop the AES-GCM restriction of 2^32 operations because the IV is
always 96 bits (32 bit fixed field + 64 bit invocation field)
According to our own analysis, the change does not remove an operations
count restriction (specified in Sec 8.3 of NIST SP 800-38D and
dependent on usage of a non-recommended IV configuration), but total
plaintext length restriction (specified in Sec 5.2.1.1, which is
unconditional).
Regardless of validity of the removed check, it has exposed what I
believe to be a bug in OpenSSH in the way that rekey limits (based on
data, instead of time) are handled.
Currently, if the rekey limit is not explicitly configured, it's
computed algorithmically based on the cipher's block size:
https://github.com/openssh/openssh-portable/blob/3f4ea3c9ab1d32d43c9222c4351f58ca11144156/packet.c#L1003
For a 128-bit block cipher like AES-GCM, this amounts to a limit of
exactly 64GiB - the same as the recommended by NIST.
However, since the check for exceeding the rekey limit (max_blocks_*
fields in the session state) is only performed in clientloop and
serverloop after processing a buffered batch of packets, the amount of
data encrypted/decrypted will almost always go above the limit for a
few blocks (depending on how much of them were in the buffer) before
rekeying is triggered.
In our case at Facebook, this was causing AES-GCM to go above the 64
GiB limit shortly before triggering rekeying and abort with an error,
unless a sufficiently lower RekeyLimit is explicitly set (which itself
can only be set to values less than 4GiB because of u32int being used,
but that's a different story).
My proposed fix is to deduce the maximum theoretical amount of buffered
blocks from the computed max_blocks value.
--
You are receiving this mail because:
You are watching the assignee of the bug.
More information about the openssh-bugs
mailing list