123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- This document describes the chacha20-poly1305@openssh.com authenticated
- encryption cipher supported by OpenSSH.
- Background
- ----------
- ChaCha20 is a stream cipher designed by Daniel Bernstein and described
- in [1]. It operates by permuting 128 fixed bits, 128 or 256 bits of key,
- a 64 bit nonce and a 64 bit counter into 64 bytes of output. This output
- is used as a keystream, with any unused bytes simply discarded.
- Poly1305[2], also by Daniel Bernstein, is a one-time Carter-Wegman MAC
- that computes a 128 bit integrity tag given a message and a single-use
- 256 bit secret key.
- The chacha20-poly1305@openssh.com combines these two primitives into an
- authenticated encryption mode. The construction used is based on that
- proposed for TLS by Adam Langley in [3], but differs in the layout of
- data passed to the MAC and in the addition of encryption of the packet
- lengths.
- Negotiation
- -----------
- The chacha20-poly1305@openssh.com offers both encryption and
- authentication. As such, no separate MAC is required. If the
- chacha20-poly1305@openssh.com cipher is selected in key exchange,
- the offered MAC algorithms are ignored and no MAC is required to be
- negotiated.
- Detailed Construction
- ---------------------
- The chacha20-poly1305@openssh.com cipher requires 512 bits of key
- material as output from the SSH key exchange. This forms two 256 bit
- keys (K_1 and K_2), used by two separate instances of chacha20.
- The first 256 bits constitute K_2 and the second 256 bits become
- K_1.
- The instance keyed by K_1 is a stream cipher that is used only
- to encrypt the 4 byte packet length field. The second instance,
- keyed by K_2, is used in conjunction with poly1305 to build an AEAD
- (Authenticated Encryption with Associated Data) that is used to encrypt
- and authenticate the entire packet.
- Two separate cipher instances are used here so as to keep the packet
- lengths confidential but not create an oracle for the packet payload
- cipher by decrypting and using the packet length prior to checking
- the MAC. By using an independently-keyed cipher instance to encrypt the
- length, an active attacker seeking to exploit the packet input handling
- as a decryption oracle can learn nothing about the payload contents or
- its MAC (assuming key derivation, ChaCha20 and Poly1305 are secure).
- The AEAD is constructed as follows: for each packet, generate a Poly1305
- key by taking the first 256 bits of ChaCha20 stream output generated
- using K_2, an IV consisting of the packet sequence number encoded as an
- uint64 under the SSH wire encoding rules and a ChaCha20 block counter of
- zero. The K_2 ChaCha20 block counter is then set to the little-endian
- encoding of 1 (i.e. {1, 0, 0, 0, 0, 0, 0, 0}) and this instance is used
- for encryption of the packet payload.
- Packet Handling
- ---------------
- When receiving a packet, the length must be decrypted first. When 4
- bytes of ciphertext length have been received, they may be decrypted
- using the K_1 key, a nonce consisting of the packet sequence number
- encoded as a uint64 under the usual SSH wire encoding and a zero block
- counter to obtain the plaintext length.
- Once the entire packet has been received, the MAC MUST be checked
- before decryption. A per-packet Poly1305 key is generated as described
- above and the MAC tag calculated using Poly1305 with this key over the
- ciphertext of the packet length and the payload together. The calculated
- MAC is then compared in constant time with the one appended to the
- packet and the packet decrypted using ChaCha20 as described above (with
- K_2, the packet sequence number as nonce and a starting block counter of
- 1).
- To send a packet, first encode the 4 byte length and encrypt it using
- K_1. Encrypt the packet payload (using K_2) and append it to the
- encrypted length. Finally, calculate a MAC tag and append it.
- Rekeying
- --------
- 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.
- References
- ----------
- [1] "ChaCha, a variant of Salsa20", Daniel Bernstein
- http://cr.yp.to/chacha/chacha-20080128.pdf
- [2] "The Poly1305-AES message-authentication code", Daniel Bernstein
- http://cr.yp.to/mac/poly1305-20050329.pdf
- [3] "ChaCha20 and Poly1305 based Cipher Suites for TLS", Adam Langley
- http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-03
- $OpenBSD: PROTOCOL.chacha20poly1305,v 1.5 2020/02/21 00:04:43 dtucker Exp $
|