1261287SdesThis document describes the chacha20-poly1305@openssh.com authenticated
2261287Sdesencryption cipher supported by OpenSSH.
3261287Sdes
4261287SdesBackground
5261287Sdes----------
6261287Sdes
7261287SdesChaCha20 is a stream cipher designed by Daniel Bernstein and described
8261287Sdesin [1]. It operates by permuting 128 fixed bits, 128 or 256 bits of key,
9261287Sdesa 64 bit nonce and a 64 bit counter into 64 bytes of output. This output
10261287Sdesis used as a keystream, with any unused bytes simply discarded.
11261287Sdes
12261287SdesPoly1305[2], also by Daniel Bernstein, is a one-time Carter-Wegman MAC
13261287Sdesthat computes a 128 bit integrity tag given a message and a single-use
14261287Sdes256 bit secret key.
15261287Sdes
16261287SdesThe chacha20-poly1305@openssh.com combines these two primitives into an
17261287Sdesauthenticated encryption mode. The construction used is based on that
18261287Sdesproposed for TLS by Adam Langley in [3], but differs in the layout of
19261287Sdesdata passed to the MAC and in the addition of encyption of the packet
20261287Sdeslengths.
21261287Sdes
22261287SdesNegotiation
23261287Sdes-----------
24261287Sdes
25261287SdesThe chacha20-poly1305@openssh.com offers both encryption and
26261287Sdesauthentication. As such, no separate MAC is required. If the
27261287Sdeschacha20-poly1305@openssh.com cipher is selected in key exchange,
28261287Sdesthe offered MAC algorithms are ignored and no MAC is required to be
29261287Sdesnegotiated.
30261287Sdes
31261287SdesDetailed Construction
32261287Sdes---------------------
33261287Sdes
34261287SdesThe chacha20-poly1305@openssh.com cipher requires 512 bits of key
35261287Sdesmaterial as output from the SSH key exchange. This forms two 256 bit
36261287Sdeskeys (K_1 and K_2), used by two separate instances of chacha20.
37323124SdesThe first 256 bits consitute K_2 and the second 256 bits become
38323124SdesK_1.
39261287Sdes
40261287SdesThe instance keyed by K_1 is a stream cipher that is used only
41261287Sdesto encrypt the 4 byte packet length field. The second instance,
42261287Sdeskeyed by K_2, is used in conjunction with poly1305 to build an AEAD
43261287Sdes(Authenticated Encryption with Associated Data) that is used to encrypt
44261287Sdesand authenticate the entire packet.
45261287Sdes
46261287SdesTwo separate cipher instances are used here so as to keep the packet
47261287Sdeslengths confidential but not create an oracle for the packet payload
48261287Sdescipher by decrypting and using the packet length prior to checking
49261287Sdesthe MAC. By using an independently-keyed cipher instance to encrypt the
50261287Sdeslength, an active attacker seeking to exploit the packet input handling
51261287Sdesas a decryption oracle can learn nothing about the payload contents or
52261287Sdesits MAC (assuming key derivation, ChaCha20 and Poly1305 are secure).
53261287Sdes
54261287SdesThe AEAD is constructed as follows: for each packet, generate a Poly1305
55261287Sdeskey by taking the first 256 bits of ChaCha20 stream output generated
56261287Sdesusing K_2, an IV consisting of the packet sequence number encoded as an
57261287Sdesuint64 under the SSH wire encoding rules and a ChaCha20 block counter of
58261287Sdeszero. The K_2 ChaCha20 block counter is then set to the little-endian
59261287Sdesencoding of 1 (i.e. {1, 0, 0, 0, 0, 0, 0, 0}) and this instance is used
60261287Sdesfor encryption of the packet payload.
61261287Sdes
62261287SdesPacket Handling
63261287Sdes---------------
64261287Sdes
65261287SdesWhen receiving a packet, the length must be decrypted first. When 4
66261287Sdesbytes of ciphertext length have been received, they may be decrypted
67261287Sdesusing the K_1 key, a nonce consisting of the packet sequence number
68261287Sdesencoded as a uint64 under the usual SSH wire encoding and a zero block
69261287Sdescounter to obtain the plaintext length.
70261287Sdes
71261287SdesOnce the entire packet has been received, the MAC MUST be checked
72261287Sdesbefore decryption. A per-packet Poly1305 key is generated as described
73261287Sdesabove and the MAC tag calculated using Poly1305 with this key over the
74261287Sdesciphertext of the packet length and the payload together. The calculated
75261287SdesMAC is then compared in constant time with the one appended to the
76261287Sdespacket and the packet decrypted using ChaCha20 as described above (with
77261287SdesK_2, the packet sequence number as nonce and a starting block counter of
78261287Sdes1).
79261287Sdes
80261287SdesTo send a packet, first encode the 4 byte length and encrypt it using
81261287SdesK_1. Encrypt the packet payload (using K_2) and append it to the
82261287Sdesencrypted length. Finally, calculate a MAC tag and append it.
83261287Sdes
84261287SdesRekeying
85261287Sdes--------
86261287Sdes
87261287SdesChaCha20 must never reuse a {key, nonce} for encryption nor may it be
88261287Sdesused to encrypt more than 2^70 bytes under the same {key, nonce}. The
89261287SdesSSH Transport protocol (RFC4253) recommends a far more conservative
90261287Sdesrekeying every 1GB of data sent or received. If this recommendation
91261287Sdesis followed, then chacha20-poly1305@openssh.com requires no special
92261287Sdeshandling in this area.
93261287Sdes
94261287SdesReferences
95261287Sdes----------
96261287Sdes
97261287Sdes[1] "ChaCha, a variant of Salsa20", Daniel Bernstein
98261287Sdes    http://cr.yp.to/chacha/chacha-20080128.pdf
99261287Sdes
100261287Sdes[2] "The Poly1305-AES message-authentication code", Daniel Bernstein
101261287Sdes    http://cr.yp.to/mac/poly1305-20050329.pdf
102261287Sdes
103261287Sdes[3] "ChaCha20 and Poly1305 based Cipher Suites for TLS", Adam Langley
104261287Sdes    http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-03
105261287Sdes
106323124Sdes$OpenBSD: PROTOCOL.chacha20poly1305,v 1.3 2016/05/03 13:10:24 djm Exp $
107261287Sdes
108