1This document describes the chacha20-poly1305@openssh.com authenticated 2encryption cipher supported by OpenSSH. 3 4Background 5---------- 6 7ChaCha20 is a stream cipher designed by Daniel Bernstein and described 8in [1]. It operates by permuting 128 fixed bits, 128 or 256 bits of key, 9a 64 bit nonce and a 64 bit counter into 64 bytes of output. This output 10is used as a keystream, with any unused bytes simply discarded. 11 12Poly1305[2], also by Daniel Bernstein, is a one-time Carter-Wegman MAC 13that computes a 128 bit integrity tag given a message and a single-use 14256 bit secret key. 15 16The chacha20-poly1305@openssh.com combines these two primitives into an 17authenticated encryption mode. The construction used is based on that 18proposed for TLS by Adam Langley in [3], but differs in the layout of 19data passed to the MAC and in the addition of encryption of the packet 20lengths. 21 22Negotiation 23----------- 24 25The chacha20-poly1305@openssh.com offers both encryption and 26authentication. As such, no separate MAC is required. If the 27chacha20-poly1305@openssh.com cipher is selected in key exchange, 28the offered MAC algorithms are ignored and no MAC is required to be 29negotiated. 30 31Detailed Construction 32--------------------- 33 34The chacha20-poly1305@openssh.com cipher requires 512 bits of key 35material as output from the SSH key exchange. This forms two 256 bit 36keys (K_1 and K_2), used by two separate instances of chacha20. 37The first 256 bits constitute K_2 and the second 256 bits become 38K_1. 39 40The instance keyed by K_1 is a stream cipher that is used only 41to encrypt the 4 byte packet length field. The second instance, 42keyed by K_2, is used in conjunction with poly1305 to build an AEAD 43(Authenticated Encryption with Associated Data) that is used to encrypt 44and authenticate the entire packet. 45 46Two separate cipher instances are used here so as to keep the packet 47lengths confidential but not create an oracle for the packet payload 48cipher by decrypting and using the packet length prior to checking 49the MAC. By using an independently-keyed cipher instance to encrypt the 50length, an active attacker seeking to exploit the packet input handling 51as a decryption oracle can learn nothing about the payload contents or 52its MAC (assuming key derivation, ChaCha20 and Poly1305 are secure). 53 54The AEAD is constructed as follows: for each packet, generate a Poly1305 55key by taking the first 256 bits of ChaCha20 stream output generated 56using K_2, an IV consisting of the packet sequence number encoded as an 57uint64 under the SSH wire encoding rules and a ChaCha20 block counter of 58zero. The K_2 ChaCha20 block counter is then set to the little-endian 59encoding of 1 (i.e. {1, 0, 0, 0, 0, 0, 0, 0}) and this instance is used 60for encryption of the packet payload. 61 62Packet Handling 63--------------- 64 65When receiving a packet, the length must be decrypted first. When 4 66bytes of ciphertext length have been received, they may be decrypted 67using the K_1 key, a nonce consisting of the packet sequence number 68encoded as a uint64 under the usual SSH wire encoding and a zero block 69counter to obtain the plaintext length. 70 71Once the entire packet has been received, the MAC MUST be checked 72before decryption. A per-packet Poly1305 key is generated as described 73above and the MAC tag calculated using Poly1305 with this key over the 74ciphertext of the packet length and the payload together. The calculated 75MAC is then compared in constant time with the one appended to the 76packet and the packet decrypted using ChaCha20 as described above (with 77K_2, the packet sequence number as nonce and a starting block counter of 781). 79 80To send a packet, first encode the 4 byte length and encrypt it using 81K_1. Encrypt the packet payload (using K_2) and append it to the 82encrypted length. Finally, calculate a MAC tag and append it. 83 84Rekeying 85-------- 86 87ChaCha20 must never reuse a {key, nonce} for encryption nor may it be 88used to encrypt more than 2^70 bytes under the same {key, nonce}. The 89SSH Transport protocol (RFC4253) recommends a far more conservative 90rekeying every 1GB of data sent or received. If this recommendation 91is followed, then chacha20-poly1305@openssh.com requires no special 92handling in this area. 93 94References 95---------- 96 97[1] "ChaCha, a variant of Salsa20", Daniel Bernstein 98 http://cr.yp.to/chacha/chacha-20080128.pdf 99 100[2] "The Poly1305-AES message-authentication code", Daniel Bernstein 101 http://cr.yp.to/mac/poly1305-20050329.pdf 102 103[3] "ChaCha20 and Poly1305 based Cipher Suites for TLS", Adam Langley 104 http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-03 105 106$OpenBSD: PROTOCOL.chacha20poly1305,v 1.5 2020/02/21 00:04:43 dtucker Exp $ 107 108