11edbfe23SdjmThis document describes the chacha20-poly1305@openssh.com authenticated
21edbfe23Sdjmencryption cipher supported by OpenSSH.
31edbfe23Sdjm
41edbfe23SdjmBackground
51edbfe23Sdjm----------
61edbfe23Sdjm
71edbfe23SdjmChaCha20 is a stream cipher designed by Daniel Bernstein and described
81edbfe23Sdjmin [1]. It operates by permuting 128 fixed bits, 128 or 256 bits of key,
91edbfe23Sdjma 64 bit nonce and a 64 bit counter into 64 bytes of output. This output
101edbfe23Sdjmis used as a keystream, with any unused bytes simply discarded.
111edbfe23Sdjm
121edbfe23SdjmPoly1305[2], also by Daniel Bernstein, is a one-time Carter-Wegman MAC
131edbfe23Sdjmthat computes a 128 bit integrity tag given a message and a single-use
141edbfe23Sdjm256 bit secret key.
151edbfe23Sdjm
161edbfe23SdjmThe chacha20-poly1305@openssh.com combines these two primitives into an
171edbfe23Sdjmauthenticated encryption mode. The construction used is based on that
181edbfe23Sdjmproposed for TLS by Adam Langley in [3], but differs in the layout of
1927a1722dSdjmdata passed to the MAC and in the addition of encryption of the packet
201edbfe23Sdjmlengths.
211edbfe23Sdjm
221edbfe23SdjmNegotiation
231edbfe23Sdjm-----------
241edbfe23Sdjm
251edbfe23SdjmThe chacha20-poly1305@openssh.com offers both encryption and
261edbfe23Sdjmauthentication. As such, no separate MAC is required. If the
271edbfe23Sdjmchacha20-poly1305@openssh.com cipher is selected in key exchange,
281edbfe23Sdjmthe offered MAC algorithms are ignored and no MAC is required to be
291edbfe23Sdjmnegotiated.
301edbfe23Sdjm
311edbfe23SdjmDetailed Construction
321edbfe23Sdjm---------------------
331edbfe23Sdjm
341edbfe23SdjmThe chacha20-poly1305@openssh.com cipher requires 512 bits of key
351edbfe23Sdjmmaterial as output from the SSH key exchange. This forms two 256 bit
361edbfe23Sdjmkeys (K_1 and K_2), used by two separate instances of chacha20.
37*38ea1073SdtuckerThe first 256 bits constitute K_2 and the second 256 bits become
38e7d3cd44SdjmK_1.
391edbfe23Sdjm
401edbfe23SdjmThe instance keyed by K_1 is a stream cipher that is used only
411edbfe23Sdjmto encrypt the 4 byte packet length field. The second instance,
421edbfe23Sdjmkeyed by K_2, is used in conjunction with poly1305 to build an AEAD
431edbfe23Sdjm(Authenticated Encryption with Associated Data) that is used to encrypt
441edbfe23Sdjmand authenticate the entire packet.
451edbfe23Sdjm
461edbfe23SdjmTwo separate cipher instances are used here so as to keep the packet
471edbfe23Sdjmlengths confidential but not create an oracle for the packet payload
481edbfe23Sdjmcipher by decrypting and using the packet length prior to checking
491edbfe23Sdjmthe MAC. By using an independently-keyed cipher instance to encrypt the
501edbfe23Sdjmlength, an active attacker seeking to exploit the packet input handling
511edbfe23Sdjmas a decryption oracle can learn nothing about the payload contents or
520fcf43efSdjmits MAC (assuming key derivation, ChaCha20 and Poly1305 are secure).
531edbfe23Sdjm
541edbfe23SdjmThe AEAD is constructed as follows: for each packet, generate a Poly1305
551edbfe23Sdjmkey by taking the first 256 bits of ChaCha20 stream output generated
561edbfe23Sdjmusing K_2, an IV consisting of the packet sequence number encoded as an
571edbfe23Sdjmuint64 under the SSH wire encoding rules and a ChaCha20 block counter of
581edbfe23Sdjmzero. The K_2 ChaCha20 block counter is then set to the little-endian
591edbfe23Sdjmencoding of 1 (i.e. {1, 0, 0, 0, 0, 0, 0, 0}) and this instance is used
601edbfe23Sdjmfor encryption of the packet payload.
611edbfe23Sdjm
621edbfe23SdjmPacket Handling
631edbfe23Sdjm---------------
641edbfe23Sdjm
651edbfe23SdjmWhen receiving a packet, the length must be decrypted first. When 4
661edbfe23Sdjmbytes of ciphertext length have been received, they may be decrypted
671edbfe23Sdjmusing the K_1 key, a nonce consisting of the packet sequence number
681edbfe23Sdjmencoded as a uint64 under the usual SSH wire encoding and a zero block
691edbfe23Sdjmcounter to obtain the plaintext length.
701edbfe23Sdjm
711edbfe23SdjmOnce the entire packet has been received, the MAC MUST be checked
721edbfe23Sdjmbefore decryption. A per-packet Poly1305 key is generated as described
731edbfe23Sdjmabove and the MAC tag calculated using Poly1305 with this key over the
741edbfe23Sdjmciphertext of the packet length and the payload together. The calculated
751edbfe23SdjmMAC is then compared in constant time with the one appended to the
761edbfe23Sdjmpacket and the packet decrypted using ChaCha20 as described above (with
771edbfe23SdjmK_2, the packet sequence number as nonce and a starting block counter of
781edbfe23Sdjm1).
791edbfe23Sdjm
801edbfe23SdjmTo send a packet, first encode the 4 byte length and encrypt it using
811edbfe23SdjmK_1. Encrypt the packet payload (using K_2) and append it to the
821edbfe23Sdjmencrypted length. Finally, calculate a MAC tag and append it.
831edbfe23Sdjm
841edbfe23SdjmRekeying
851edbfe23Sdjm--------
861edbfe23Sdjm
871edbfe23SdjmChaCha20 must never reuse a {key, nonce} for encryption nor may it be
881edbfe23Sdjmused to encrypt more than 2^70 bytes under the same {key, nonce}. The
891edbfe23SdjmSSH Transport protocol (RFC4253) recommends a far more conservative
901edbfe23Sdjmrekeying every 1GB of data sent or received. If this recommendation
911edbfe23Sdjmis followed, then chacha20-poly1305@openssh.com requires no special
921edbfe23Sdjmhandling in this area.
931edbfe23Sdjm
941edbfe23SdjmReferences
951edbfe23Sdjm----------
961edbfe23Sdjm
971edbfe23Sdjm[1] "ChaCha, a variant of Salsa20", Daniel Bernstein
981edbfe23Sdjm    http://cr.yp.to/chacha/chacha-20080128.pdf
991edbfe23Sdjm
1001edbfe23Sdjm[2] "The Poly1305-AES message-authentication code", Daniel Bernstein
1011edbfe23Sdjm    http://cr.yp.to/mac/poly1305-20050329.pdf
1021edbfe23Sdjm
1031edbfe23Sdjm[3] "ChaCha20 and Poly1305 based Cipher Suites for TLS", Adam Langley
1041edbfe23Sdjm    http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-03
1051edbfe23Sdjm
106*38ea1073Sdtucker$OpenBSD: PROTOCOL.chacha20poly1305,v 1.5 2020/02/21 00:04:43 dtucker Exp $
1071edbfe23Sdjm
108