[BACK]Return to PROTOCOL.chacha20poly1305 CVS log [TXT][DIR]Up to [local] / src / usr.bin / ssh

Annotation of src/usr.bin/ssh/PROTOCOL.chacha20poly1305, Revision HEAD

1.1       djm         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
1.4       djm        19: data passed to the MAC and in the addition of encryption of the packet
1.1       djm        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.
1.5       dtucker    37: The first 256 bits constitute K_2 and the second 256 bits become
1.3       djm        38: K_1.
1.1       djm        39:
                     40: The instance keyed by K_1 is a stream cipher that is used only
                     41: to encrypt the 4 byte packet length field. The second instance,
                     42: keyed by K_2, is used in conjunction with poly1305 to build an AEAD
                     43: (Authenticated Encryption with Associated Data) that is used to encrypt
                     44: and authenticate the entire packet.
                     45:
                     46: Two separate cipher instances are used here so as to keep the packet
                     47: lengths confidential but not create an oracle for the packet payload
                     48: cipher by decrypting and using the packet length prior to checking
                     49: the MAC. By using an independently-keyed cipher instance to encrypt the
                     50: length, an active attacker seeking to exploit the packet input handling
                     51: as a decryption oracle can learn nothing about the payload contents or
1.2       djm        52: its MAC (assuming key derivation, ChaCha20 and Poly1305 are secure).
1.1       djm        53:
                     54: The AEAD is constructed as follows: for each packet, generate a Poly1305
                     55: key by taking the first 256 bits of ChaCha20 stream output generated
                     56: using K_2, an IV consisting of the packet sequence number encoded as an
                     57: uint64 under the SSH wire encoding rules and a ChaCha20 block counter of
                     58: zero. The K_2 ChaCha20 block counter is then set to the little-endian
                     59: encoding of 1 (i.e. {1, 0, 0, 0, 0, 0, 0, 0}) and this instance is used
                     60: for encryption of the packet payload.
                     61:
                     62: Packet Handling
                     63: ---------------
                     64:
                     65: When receiving a packet, the length must be decrypted first. When 4
                     66: bytes of ciphertext length have been received, they may be decrypted
                     67: using the K_1 key, a nonce consisting of the packet sequence number
                     68: encoded as a uint64 under the usual SSH wire encoding and a zero block
                     69: counter to obtain the plaintext length.
                     70:
                     71: Once the entire packet has been received, the MAC MUST be checked
                     72: before decryption. A per-packet Poly1305 key is generated as described
                     73: above and the MAC tag calculated using Poly1305 with this key over the
                     74: ciphertext of the packet length and the payload together. The calculated
                     75: MAC is then compared in constant time with the one appended to the
                     76: packet and the packet decrypted using ChaCha20 as described above (with
                     77: K_2, the packet sequence number as nonce and a starting block counter of
                     78: 1).
                     79:
                     80: To send a packet, first encode the 4 byte length and encrypt it using
                     81: K_1. Encrypt the packet payload (using K_2) and append it to the
                     82: encrypted length. Finally, calculate a MAC tag and append it.
                     83:
                     84: Rekeying
                     85: --------
                     86:
                     87: ChaCha20 must never reuse a {key, nonce} for encryption nor may it be
                     88: used to encrypt more than 2^70 bytes under the same {key, nonce}. The
                     89: SSH Transport protocol (RFC4253) recommends a far more conservative
                     90: rekeying every 1GB of data sent or received. If this recommendation
                     91: is followed, then chacha20-poly1305@openssh.com requires no special
                     92: handling in this area.
                     93:
                     94: References
                     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:
1.5       dtucker   106: $OpenBSD: PROTOCOL.chacha20poly1305,v 1.4 2018/04/10 00:10:49 djm Exp $
1.1       djm       107: