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