blob: 9cf73a926bb7685a3dd52253c7d9a8e991063918 [file] [log] [blame]
Damien Miller0fde8ac2013-11-21 14:12:23 +11001This 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 encyption 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.
37
38The instance keyed by K_1 is a stream cipher that is used only
39to encrypt the 4 byte packet length field. The second instance,
40keyed by K_2, is used in conjunction with poly1305 to build an AEAD
41(Authenticated Encryption with Associated Data) that is used to encrypt
42and authenticate the entire packet.
43
44Two separate cipher instances are used here so as to keep the packet
45lengths confidential but not create an oracle for the packet payload
46cipher by decrypting and using the packet length prior to checking
47the MAC. By using an independently-keyed cipher instance to encrypt the
48length, an active attacker seeking to exploit the packet input handling
49as a decryption oracle can learn nothing about the payload contents or
Damien Miller114e5402013-12-05 10:22:57 +110050its MAC (assuming key derivation, ChaCha20 and Poly1305 are secure).
Damien Miller0fde8ac2013-11-21 14:12:23 +110051
52The AEAD is constructed as follows: for each packet, generate a Poly1305
53key by taking the first 256 bits of ChaCha20 stream output generated
54using K_2, an IV consisting of the packet sequence number encoded as an
55uint64 under the SSH wire encoding rules and a ChaCha20 block counter of
56zero. The K_2 ChaCha20 block counter is then set to the little-endian
57encoding of 1 (i.e. {1, 0, 0, 0, 0, 0, 0, 0}) and this instance is used
58for encryption of the packet payload.
59
60Packet Handling
61---------------
62
63When receiving a packet, the length must be decrypted first. When 4
64bytes of ciphertext length have been received, they may be decrypted
65using the K_1 key, a nonce consisting of the packet sequence number
66encoded as a uint64 under the usual SSH wire encoding and a zero block
67counter to obtain the plaintext length.
68
69Once the entire packet has been received, the MAC MUST be checked
70before decryption. A per-packet Poly1305 key is generated as described
71above and the MAC tag calculated using Poly1305 with this key over the
72ciphertext of the packet length and the payload together. The calculated
73MAC is then compared in constant time with the one appended to the
74packet and the packet decrypted using ChaCha20 as described above (with
75K_2, the packet sequence number as nonce and a starting block counter of
761).
77
78To send a packet, first encode the 4 byte length and encrypt it using
79K_1. Encrypt the packet payload (using K_2) and append it to the
80encrypted length. Finally, calculate a MAC tag and append it.
81
82Rekeying
83--------
84
85ChaCha20 must never reuse a {key, nonce} for encryption nor may it be
86used to encrypt more than 2^70 bytes under the same {key, nonce}. The
87SSH Transport protocol (RFC4253) recommends a far more conservative
88rekeying every 1GB of data sent or received. If this recommendation
89is followed, then chacha20-poly1305@openssh.com requires no special
90handling in this area.
91
92References
93----------
94
95[1] "ChaCha, a variant of Salsa20", Daniel Bernstein
96 http://cr.yp.to/chacha/chacha-20080128.pdf
97
98[2] "The Poly1305-AES message-authentication code", Daniel Bernstein
99 http://cr.yp.to/mac/poly1305-20050329.pdf
100
101[3] "ChaCha20 and Poly1305 based Cipher Suites for TLS", Adam Langley
102 http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-03
103
Damien Miller114e5402013-12-05 10:22:57 +1100104$OpenBSD: PROTOCOL.chacha20poly1305,v 1.2 2013/12/02 02:50:27 djm Exp $
Damien Miller0fde8ac2013-11-21 14:12:23 +1100105