IETF-SSH archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
AEAD in ssh
denis bider <ietf-ssh3%denisbider.com@localhost> writes:
> With regard to AEAD:
>
> I think we should just make the following simple and clear statement:
>
> MAC algorithms are secondary to encryption algorithms, and are
> evaluated only if the encryption algorithm is not AEAD. If an AEAD
> encryption algorithm is negotiated, the outcome of MAC negotiation is
> irrelevant and must be ignored. If no mutual MAC algorithms are
> available, this causes key exchange to fail if, and only if, the
> negotiated encryption algorithm is not AEAD.
That's only one part of it. I think the following points need clear
specification:
1. How to negotiate use of AEAD.
The above would work, I think.
Or one could specify a "n/a" mac name, which is a bit like "none",
except that negotiation fails if it's the output of the mac
negotiation and the negotiated cipher isn't an aead mechanism. Maybe
unnecessary, but it could also serve the second purpose as signalling
support for aead, in case the negotiation rules need tweaking (see
also next point). If defined, it should be mandatory (i.e., if the
agreed cipher is aead, but "n/a" mac isn't offered, connection should
fail).
2. How it interacts with first_kex_packet_follows.
Roughly, if everything is "guessed" correctly except the mac
algorithm (e.g, if the mac name-list is empty so mac negotiation
fails), and the agreed cipher is aead, the guess ought to
nevertheless be considered successful. The details must be made
crystal clear.
(And I'm open to tweaking the rules in other ways too, if new rules are
reliably signalled via some extension or by the "n/a" atom; it's
unclear to me if the first_kex_packet_follows logic really needs to
depend on anything else but the agreed key exchange mechanism and
maybe host_key_algorithm (I think I can argue that it's independent
of host_key_algorithm: Every reasonable keyexchange algorithm needs
input from the client, and the key exchange signature must depend on
that data. Hence the first kex packet should be independent of the
signature)).
3. If and how to encrypt the length field.
My strong opinion is that it ought to be encrypted. A spec for AEAD
in ssh should either specify fully how to do that, or give clear
guidelines in case some details must be left to the specification of
each AEAD mechanism. Roughly, one should use an independent cipher
instance (distinct key or disjoint nonce sequence or distinct ctr
value) to encrypt the length in a ctr-like mode.
4. What the "block size" used for padding purposes (RFC 4253, Sec. 6,
"Binary Packet Protocol") should be.
AEAD in the abstract doesn't expose any block size, so I'd be
inclined to say that we should always use 8, the ssh minimum. One
could tie it to the underlying block cipher if there is one, but it
makes little sense to me, given that it's the length *including* the
length field which must be a multiple of the "block size". And with
AEAD, the length field has to be separately encrypted, so by the
current rules, we're always going to be unaligned anyway.
5. Precisely which bytes go into the AEAD nonce, data, and plaintext,
when processing each packet.
Perhaps we should first take a step back and look at the binary
packet format:
uint32 packet_length
byte padding_length
byte[n1] payload; n1 = packet_length - padding_length - 1
byte[n2] random padding; n2 = padding_length
byte[m] mac (Message Authentication Code - MAC); m = mac_length
For AEAD, maybe it's better to think about it as applying the
padding to the *plaintext*. Then the plaintext input to the AEAD
algorithm would be
byte padding_length
byte[n1] payload; n1 = packet_length - padding_length - 1
byte[n2] random padding; n2 = padding_length
These n1+n2+1 = packet_length bytes of cleartext are transformed
using AEAD into packet_length+m bytes of ciphertext including an
authentication data.
For simplicity, drop all requirements on the padding length except
keeping the lower bound n2 >= 4.
The packet length field is encrypted separately producing 4 bytes of
encrypted length preceding the AEAD ciphertext on the wire. It can
also be included in the associated data, before or after encryption;
I'm not sure if there's any real benefit in doing that, but it might
make it a little more robust.
The existing RFC 5647 on aes-gcm is unclear on (1) and (2) (and
apparently not implemented that way in openssh). I disagree with its
choice for (3), this has been argued on the secsh list recently, I'll
not repeat it here.
I think it gets (5) right (without deep thinking about it. I note that
it departs from RFC 4253 by not including an explicit sequence number in
the authenticated data). For (4), it specifies that AEAD plaintext
*excluding* the length field must be a multiple of 16. Which makes some
sense, but (i) departs from the original rules, and (ii) is of little
benefit, since gcm doesn't require the input to be an integral number of
AES blocks.
Openssh's chacha-poly1305 is also pretty important. I don't have their
details in front of me, but at least the length *is* encrypted, using an
independent chacha instance. And it doesn't agree with the (later)
definition of chacha-poly1305 in RFC 7539.
In short, to write a good specification will require some non-trivial
amount of work. And I think it's pretty important work. Do you agree?
Are there any objections to the above direction? (I already know some
dislike encrypted lengths). What are the chances to reach rough
consensus?
Regards,
/Niels
--
Niels Möller. PGP-encrypted email is preferred. Keyid C0B98E26.
Internet email is subject to wholesale government surveillance.
Home |
Main Index |
Thread Index |
Old Index