diff options
author | Damien Miller <djm@mindrot.org> | 2013-11-21 14:12:23 +1100 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2013-11-21 14:12:23 +1100 |
commit | 0fde8acdad78a4d20cadae974376cc0165f645ee (patch) | |
tree | 6e6aa82b73163bcb412920050d98f82ca9f4e86e /PROTOCOL.chacha20poly1305 | |
parent | fdb2306acdc3eb2bc46b6dfdaaf6005c650af22a (diff) |
- djm@cvs.openbsd.org 2013/11/21 00:45:44
[Makefile.in PROTOCOL PROTOCOL.chacha20poly1305 authfile.c chacha.c]
[chacha.h cipher-chachapoly.c cipher-chachapoly.h cipher.c cipher.h]
[dh.c myproposal.h packet.c poly1305.c poly1305.h servconf.c ssh.1]
[ssh.c ssh_config.5 sshd_config.5] Add a new protocol 2 transport
cipher "chacha20-poly1305@openssh.com" that combines Daniel
Bernstein's ChaCha20 stream cipher and Poly1305 MAC to build an
authenticated encryption mode.
Inspired by and similar to Adam Langley's proposal for TLS:
http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-03
but differs in layout used for the MAC calculation and the use of a
second ChaCha20 instance to separately encrypt packet lengths.
Details are in the PROTOCOL.chacha20poly1305 file.
Feedback markus@, naddy@; manpage bits Loganden Velvindron @ AfriNIC
ok markus@ naddy@
Diffstat (limited to 'PROTOCOL.chacha20poly1305')
-rw-r--r-- | PROTOCOL.chacha20poly1305 | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/PROTOCOL.chacha20poly1305 b/PROTOCOL.chacha20poly1305 new file mode 100644 index 000000000..c4b723aff --- /dev/null +++ b/PROTOCOL.chacha20poly1305 | |||
@@ -0,0 +1,105 @@ | |||
1 | This document describes the chacha20-poly1305@openssh.com authenticated | ||
2 | encryption cipher supported by OpenSSH. | ||
3 | |||
4 | Background | ||
5 | ---------- | ||
6 | |||
7 | ChaCha20 is a stream cipher designed by Daniel Bernstein and described | ||
8 | in [1]. It operates by permuting 128 fixed bits, 128 or 256 bits of key, | ||
9 | a 64 bit nonce and a 64 bit counter into 64 bytes of output. This output | ||
10 | is used as a keystream, with any unused bytes simply discarded. | ||
11 | |||
12 | Poly1305[2], also by Daniel Bernstein, is a one-time Carter-Wegman MAC | ||
13 | that computes a 128 bit integrity tag given a message and a single-use | ||
14 | 256 bit secret key. | ||
15 | |||
16 | The chacha20-poly1305@openssh.com combines these two primitives into an | ||
17 | authenticated encryption mode. The construction used is based on that | ||
18 | proposed for TLS by Adam Langley in [3], but differs in the layout of | ||
19 | data passed to the MAC and in the addition of encyption of the packet | ||
20 | lengths. | ||
21 | |||
22 | Negotiation | ||
23 | ----------- | ||
24 | |||
25 | The chacha20-poly1305@openssh.com offers both encryption and | ||
26 | authentication. As such, no separate MAC is required. If the | ||
27 | chacha20-poly1305@openssh.com cipher is selected in key exchange, | ||
28 | the offered MAC algorithms are ignored and no MAC is required to be | ||
29 | negotiated. | ||
30 | |||
31 | Detailed Construction | ||
32 | --------------------- | ||
33 | |||
34 | The chacha20-poly1305@openssh.com cipher requires 512 bits of key | ||
35 | material as output from the SSH key exchange. This forms two 256 bit | ||
36 | keys (K_1 and K_2), used by two separate instances of chacha20. | ||
37 | |||
38 | The instance keyed by K_1 is a stream cipher that is used only | ||
39 | to encrypt the 4 byte packet length field. The second instance, | ||
40 | keyed by K_2, is used in conjunction with poly1305 to build an AEAD | ||
41 | (Authenticated Encryption with Associated Data) that is used to encrypt | ||
42 | and authenticate the entire packet. | ||
43 | |||
44 | Two separate cipher instances are used here so as to keep the packet | ||
45 | lengths confidential but not create an oracle for the packet payload | ||
46 | cipher by decrypting and using the packet length prior to checking | ||
47 | the MAC. By using an independently-keyed cipher instance to encrypt the | ||
48 | length, an active attacker seeking to exploit the packet input handling | ||
49 | as a decryption oracle can learn nothing about the payload contents or | ||
50 | its MAC (assuming key derivation, ChaCha20 and Poly1306 are secure). | ||
51 | |||
52 | The AEAD is constructed as follows: for each packet, generate a Poly1305 | ||
53 | key by taking the first 256 bits of ChaCha20 stream output generated | ||
54 | using K_2, an IV consisting of the packet sequence number encoded as an | ||
55 | uint64 under the SSH wire encoding rules and a ChaCha20 block counter of | ||
56 | zero. The K_2 ChaCha20 block counter is then set to the little-endian | ||
57 | encoding of 1 (i.e. {1, 0, 0, 0, 0, 0, 0, 0}) and this instance is used | ||
58 | for encryption of the packet payload. | ||
59 | |||
60 | Packet Handling | ||
61 | --------------- | ||
62 | |||
63 | When receiving a packet, the length must be decrypted first. When 4 | ||
64 | bytes of ciphertext length have been received, they may be decrypted | ||
65 | using the K_1 key, a nonce consisting of the packet sequence number | ||
66 | encoded as a uint64 under the usual SSH wire encoding and a zero block | ||
67 | counter to obtain the plaintext length. | ||
68 | |||
69 | Once the entire packet has been received, the MAC MUST be checked | ||
70 | before decryption. A per-packet Poly1305 key is generated as described | ||
71 | above and the MAC tag calculated using Poly1305 with this key over the | ||
72 | ciphertext of the packet length and the payload together. The calculated | ||
73 | MAC is then compared in constant time with the one appended to the | ||
74 | packet and the packet decrypted using ChaCha20 as described above (with | ||
75 | K_2, the packet sequence number as nonce and a starting block counter of | ||
76 | 1). | ||
77 | |||
78 | To send a packet, first encode the 4 byte length and encrypt it using | ||
79 | K_1. Encrypt the packet payload (using K_2) and append it to the | ||
80 | encrypted length. Finally, calculate a MAC tag and append it. | ||
81 | |||
82 | Rekeying | ||
83 | -------- | ||
84 | |||
85 | ChaCha20 must never reuse a {key, nonce} for encryption nor may it be | ||
86 | used to encrypt more than 2^70 bytes under the same {key, nonce}. The | ||
87 | SSH Transport protocol (RFC4253) recommends a far more conservative | ||
88 | rekeying every 1GB of data sent or received. If this recommendation | ||
89 | is followed, then chacha20-poly1305@openssh.com requires no special | ||
90 | handling in this area. | ||
91 | |||
92 | References | ||
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 | |||
104 | $OpenBSD: PROTOCOL.chacha20poly1305,v 1.1 2013/11/21 00:45:43 djm Exp $ | ||
105 | |||