summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2013-11-21 14:12:23 +1100
committerDamien Miller <djm@mindrot.org>2013-11-21 14:12:23 +1100
commit0fde8acdad78a4d20cadae974376cc0165f645ee (patch)
tree6e6aa82b73163bcb412920050d98f82ca9f4e86e
parentfdb2306acdc3eb2bc46b6dfdaaf6005c650af22a (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@
-rw-r--r--ChangeLog17
-rw-r--r--Makefile.in4
-rw-r--r--PROTOCOL7
-rw-r--r--PROTOCOL.chacha20poly1305105
-rw-r--r--authfile.c6
-rw-r--r--chacha.c219
-rw-r--r--chacha.h35
-rw-r--r--cipher-chachapoly.c114
-rw-r--r--cipher-chachapoly.h41
-rw-r--r--cipher.c65
-rw-r--r--cipher.h11
-rw-r--r--dh.c38
-rw-r--r--myproposal.h3
-rw-r--r--packet.c24
-rw-r--r--poly1305.c158
-rw-r--r--poly1305.h22
-rw-r--r--servconf.c4
-rw-r--r--ssh.16
-rw-r--r--ssh.c6
-rw-r--r--ssh_config.518
-rw-r--r--sshd_config.518
21 files changed, 853 insertions, 68 deletions
diff --git a/ChangeLog b/ChangeLog
index cb4dae30e..28186e89f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -19,6 +19,23 @@
19 [canohost.c clientloop.c match.c readconf.c sftp.c] 19 [canohost.c clientloop.c match.c readconf.c sftp.c]
20 unsigned casts for ctype macros where neccessary 20 unsigned casts for ctype macros where neccessary
21 ok guenther millert markus 21 ok guenther millert markus
22 - djm@cvs.openbsd.org 2013/11/21 00:45:44
23 [Makefile.in PROTOCOL PROTOCOL.chacha20poly1305 authfile.c chacha.c]
24 [chacha.h cipher-chachapoly.c cipher-chachapoly.h cipher.c cipher.h]
25 [dh.c myproposal.h packet.c poly1305.c poly1305.h servconf.c ssh.1]
26 [ssh.c ssh_config.5 sshd_config.5] Add a new protocol 2 transport
27 cipher "chacha20-poly1305@openssh.com" that combines Daniel
28 Bernstein's ChaCha20 stream cipher and Poly1305 MAC to build an
29 authenticated encryption mode.
30
31 Inspired by and similar to Adam Langley's proposal for TLS:
32 http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-03
33 but differs in layout used for the MAC calculation and the use of a
34 second ChaCha20 instance to separately encrypt packet lengths.
35 Details are in the PROTOCOL.chacha20poly1305 file.
36
37 Feedback markus@, naddy@; manpage bits Loganden Velvindron @ AfriNIC
38 ok markus@ naddy@
22 39
2320131110 4020131110
24 - (dtucker) [regress/keytype.sh] Populate ECDSA key types to be tested by 41 - (dtucker) [regress/keytype.sh] Populate ECDSA key types to be tested by
diff --git a/Makefile.in b/Makefile.in
index e1c68c00b..91f39d4f3 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,4 +1,4 @@
1# $Id: Makefile.in,v 1.344 2013/11/08 13:17:41 dtucker Exp $ 1# $Id: Makefile.in,v 1.345 2013/11/21 03:12:23 djm Exp $
2 2
3# uncomment if you run a non bourne compatable shell. Ie. csh 3# uncomment if you run a non bourne compatable shell. Ie. csh
4#SHELL = @SH@ 4#SHELL = @SH@
@@ -74,7 +74,7 @@ LIBSSH_OBJS=authfd.o authfile.o bufaux.o bufbn.o buffer.o \
74 kexdh.o kexgex.o kexdhc.o kexgexc.o bufec.o kexecdh.o kexecdhc.o \ 74 kexdh.o kexgex.o kexdhc.o kexgexc.o bufec.o kexecdh.o kexecdhc.o \
75 msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ 75 msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \
76 jpake.o schnorr.o ssh-pkcs11.o krl.o smult_curve25519_ref.o \ 76 jpake.o schnorr.o ssh-pkcs11.o krl.o smult_curve25519_ref.o \
77 kexc25519.o kexc25519c.o 77 kexc25519.o kexc25519c.o poly1305.o chacha.o cipher-chachapoly.o
78 78
79SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ 79SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
80 sshconnect.o sshconnect1.o sshconnect2.o mux.o \ 80 sshconnect.o sshconnect1.o sshconnect2.o mux.o \
diff --git a/PROTOCOL b/PROTOCOL
index 0363314c0..cace97f88 100644
--- a/PROTOCOL
+++ b/PROTOCOL
@@ -91,6 +91,11 @@ an MAC algorithm. Additionally, if AES-GCM is selected as the cipher
91the exchanged MAC algorithms are ignored and there doesn't have to be 91the exchanged MAC algorithms are ignored and there doesn't have to be
92a matching MAC. 92a matching MAC.
93 93
941.7 transport: chacha20-poly1305@openssh.com authenticated encryption
95
96OpenSSH supports authenticated encryption using ChaCha20 and Poly1305
97as described in PROTOCOL.chacha20poly1305.
98
942. Connection protocol changes 992. Connection protocol changes
95 100
962.1. connection: Channel write close extension "eow@openssh.com" 1012.1. connection: Channel write close extension "eow@openssh.com"
@@ -345,4 +350,4 @@ respond with a SSH_FXP_STATUS message.
345This extension is advertised in the SSH_FXP_VERSION hello with version 350This extension is advertised in the SSH_FXP_VERSION hello with version
346"1". 351"1".
347 352
348$OpenBSD: PROTOCOL,v 1.21 2013/10/17 00:30:13 djm Exp $ 353$OpenBSD: PROTOCOL,v 1.22 2013/11/21 00:45:43 djm Exp $
diff --git a/PROTOCOL.chacha20poly1305 b/PROTOCOL.chacha20poly1305
new file mode 100644
index 000000000..c4b723aff
--- /dev/null
+++ b/PROTOCOL.chacha20poly1305
@@ -0,0 +1,105 @@
1This 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
50its MAC (assuming key derivation, ChaCha20 and Poly1306 are secure).
51
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
104$OpenBSD: PROTOCOL.chacha20poly1305,v 1.1 2013/11/21 00:45:43 djm Exp $
105
diff --git a/authfile.c b/authfile.c
index 63ae16bbd..d0c1089eb 100644
--- a/authfile.c
+++ b/authfile.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: authfile.c,v 1.97 2013/05/17 00:13:13 djm Exp $ */ 1/* $OpenBSD: authfile.c,v 1.98 2013/11/21 00:45:43 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -149,7 +149,7 @@ key_private_rsa1_to_blob(Key *key, Buffer *blob, const char *passphrase,
149 149
150 cipher_set_key_string(&ciphercontext, cipher, passphrase, 150 cipher_set_key_string(&ciphercontext, cipher, passphrase,
151 CIPHER_ENCRYPT); 151 CIPHER_ENCRYPT);
152 cipher_crypt(&ciphercontext, cp, 152 cipher_crypt(&ciphercontext, 0, cp,
153 buffer_ptr(&buffer), buffer_len(&buffer), 0, 0); 153 buffer_ptr(&buffer), buffer_len(&buffer), 0, 0);
154 cipher_cleanup(&ciphercontext); 154 cipher_cleanup(&ciphercontext);
155 memset(&ciphercontext, 0, sizeof(ciphercontext)); 155 memset(&ciphercontext, 0, sizeof(ciphercontext));
@@ -473,7 +473,7 @@ key_parse_private_rsa1(Buffer *blob, const char *passphrase, char **commentp)
473 /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */ 473 /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */
474 cipher_set_key_string(&ciphercontext, cipher, passphrase, 474 cipher_set_key_string(&ciphercontext, cipher, passphrase,
475 CIPHER_DECRYPT); 475 CIPHER_DECRYPT);
476 cipher_crypt(&ciphercontext, cp, 476 cipher_crypt(&ciphercontext, 0, cp,
477 buffer_ptr(&copy), buffer_len(&copy), 0, 0); 477 buffer_ptr(&copy), buffer_len(&copy), 0, 0);
478 cipher_cleanup(&ciphercontext); 478 cipher_cleanup(&ciphercontext);
479 memset(&ciphercontext, 0, sizeof(ciphercontext)); 479 memset(&ciphercontext, 0, sizeof(ciphercontext));
diff --git a/chacha.c b/chacha.c
new file mode 100644
index 000000000..a84c25ea8
--- /dev/null
+++ b/chacha.c
@@ -0,0 +1,219 @@
1/*
2chacha-merged.c version 20080118
3D. J. Bernstein
4Public domain.
5*/
6
7#include "includes.h"
8
9#include "chacha.h"
10
11/* $OpenBSD: chacha.c,v 1.1 2013/11/21 00:45:44 djm Exp $ */
12
13typedef unsigned char u8;
14typedef unsigned int u32;
15
16typedef struct chacha_ctx chacha_ctx;
17
18#define U8C(v) (v##U)
19#define U32C(v) (v##U)
20
21#define U8V(v) ((u8)(v) & U8C(0xFF))
22#define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF))
23
24#define ROTL32(v, n) \
25 (U32V((v) << (n)) | ((v) >> (32 - (n))))
26
27#define U8TO32_LITTLE(p) \
28 (((u32)((p)[0]) ) | \
29 ((u32)((p)[1]) << 8) | \
30 ((u32)((p)[2]) << 16) | \
31 ((u32)((p)[3]) << 24))
32
33#define U32TO8_LITTLE(p, v) \
34 do { \
35 (p)[0] = U8V((v) ); \
36 (p)[1] = U8V((v) >> 8); \
37 (p)[2] = U8V((v) >> 16); \
38 (p)[3] = U8V((v) >> 24); \
39 } while (0)
40
41#define ROTATE(v,c) (ROTL32(v,c))
42#define XOR(v,w) ((v) ^ (w))
43#define PLUS(v,w) (U32V((v) + (w)))
44#define PLUSONE(v) (PLUS((v),1))
45
46#define QUARTERROUND(a,b,c,d) \
47 a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \
48 c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \
49 a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \
50 c = PLUS(c,d); b = ROTATE(XOR(b,c), 7);
51
52static const char sigma[16] = "expand 32-byte k";
53static const char tau[16] = "expand 16-byte k";
54
55void
56chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits)
57{
58 const char *constants;
59
60 x->input[4] = U8TO32_LITTLE(k + 0);
61 x->input[5] = U8TO32_LITTLE(k + 4);
62 x->input[6] = U8TO32_LITTLE(k + 8);
63 x->input[7] = U8TO32_LITTLE(k + 12);
64 if (kbits == 256) { /* recommended */
65 k += 16;
66 constants = sigma;
67 } else { /* kbits == 128 */
68 constants = tau;
69 }
70 x->input[8] = U8TO32_LITTLE(k + 0);
71 x->input[9] = U8TO32_LITTLE(k + 4);
72 x->input[10] = U8TO32_LITTLE(k + 8);
73 x->input[11] = U8TO32_LITTLE(k + 12);
74 x->input[0] = U8TO32_LITTLE(constants + 0);
75 x->input[1] = U8TO32_LITTLE(constants + 4);
76 x->input[2] = U8TO32_LITTLE(constants + 8);
77 x->input[3] = U8TO32_LITTLE(constants + 12);
78}
79
80void
81chacha_ivsetup(chacha_ctx *x, const u8 *iv, const u8 *counter)
82{
83 x->input[12] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 0);
84 x->input[13] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 4);
85 x->input[14] = U8TO32_LITTLE(iv + 0);
86 x->input[15] = U8TO32_LITTLE(iv + 4);
87}
88
89void
90chacha_encrypt_bytes(chacha_ctx *x,const u8 *m,u8 *c,u32 bytes)
91{
92 u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
93 u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
94 u8 *ctarget = NULL;
95 u8 tmp[64];
96 u_int i;
97
98 if (!bytes) return;
99
100 j0 = x->input[0];
101 j1 = x->input[1];
102 j2 = x->input[2];
103 j3 = x->input[3];
104 j4 = x->input[4];
105 j5 = x->input[5];
106 j6 = x->input[6];
107 j7 = x->input[7];
108 j8 = x->input[8];
109 j9 = x->input[9];
110 j10 = x->input[10];
111 j11 = x->input[11];
112 j12 = x->input[12];
113 j13 = x->input[13];
114 j14 = x->input[14];
115 j15 = x->input[15];
116
117 for (;;) {
118 if (bytes < 64) {
119 for (i = 0;i < bytes;++i) tmp[i] = m[i];
120 m = tmp;
121 ctarget = c;
122 c = tmp;
123 }
124 x0 = j0;
125 x1 = j1;
126 x2 = j2;
127 x3 = j3;
128 x4 = j4;
129 x5 = j5;
130 x6 = j6;
131 x7 = j7;
132 x8 = j8;
133 x9 = j9;
134 x10 = j10;
135 x11 = j11;
136 x12 = j12;
137 x13 = j13;
138 x14 = j14;
139 x15 = j15;
140 for (i = 20;i > 0;i -= 2) {
141 QUARTERROUND( x0, x4, x8,x12)
142 QUARTERROUND( x1, x5, x9,x13)
143 QUARTERROUND( x2, x6,x10,x14)
144 QUARTERROUND( x3, x7,x11,x15)
145 QUARTERROUND( x0, x5,x10,x15)
146 QUARTERROUND( x1, x6,x11,x12)
147 QUARTERROUND( x2, x7, x8,x13)
148 QUARTERROUND( x3, x4, x9,x14)
149 }
150 x0 = PLUS(x0,j0);
151 x1 = PLUS(x1,j1);
152 x2 = PLUS(x2,j2);
153 x3 = PLUS(x3,j3);
154 x4 = PLUS(x4,j4);
155 x5 = PLUS(x5,j5);
156 x6 = PLUS(x6,j6);
157 x7 = PLUS(x7,j7);
158 x8 = PLUS(x8,j8);
159 x9 = PLUS(x9,j9);
160 x10 = PLUS(x10,j10);
161 x11 = PLUS(x11,j11);
162 x12 = PLUS(x12,j12);
163 x13 = PLUS(x13,j13);
164 x14 = PLUS(x14,j14);
165 x15 = PLUS(x15,j15);
166
167 x0 = XOR(x0,U8TO32_LITTLE(m + 0));
168 x1 = XOR(x1,U8TO32_LITTLE(m + 4));
169 x2 = XOR(x2,U8TO32_LITTLE(m + 8));
170 x3 = XOR(x3,U8TO32_LITTLE(m + 12));
171 x4 = XOR(x4,U8TO32_LITTLE(m + 16));
172 x5 = XOR(x5,U8TO32_LITTLE(m + 20));
173 x6 = XOR(x6,U8TO32_LITTLE(m + 24));
174 x7 = XOR(x7,U8TO32_LITTLE(m + 28));
175 x8 = XOR(x8,U8TO32_LITTLE(m + 32));
176 x9 = XOR(x9,U8TO32_LITTLE(m + 36));
177 x10 = XOR(x10,U8TO32_LITTLE(m + 40));
178 x11 = XOR(x11,U8TO32_LITTLE(m + 44));
179 x12 = XOR(x12,U8TO32_LITTLE(m + 48));
180 x13 = XOR(x13,U8TO32_LITTLE(m + 52));
181 x14 = XOR(x14,U8TO32_LITTLE(m + 56));
182 x15 = XOR(x15,U8TO32_LITTLE(m + 60));
183
184 j12 = PLUSONE(j12);
185 if (!j12) {
186 j13 = PLUSONE(j13);
187 /* stopping at 2^70 bytes per nonce is user's responsibility */
188 }
189
190 U32TO8_LITTLE(c + 0,x0);
191 U32TO8_LITTLE(c + 4,x1);
192 U32TO8_LITTLE(c + 8,x2);
193 U32TO8_LITTLE(c + 12,x3);
194 U32TO8_LITTLE(c + 16,x4);
195 U32TO8_LITTLE(c + 20,x5);
196 U32TO8_LITTLE(c + 24,x6);
197 U32TO8_LITTLE(c + 28,x7);
198 U32TO8_LITTLE(c + 32,x8);
199 U32TO8_LITTLE(c + 36,x9);
200 U32TO8_LITTLE(c + 40,x10);
201 U32TO8_LITTLE(c + 44,x11);
202 U32TO8_LITTLE(c + 48,x12);
203 U32TO8_LITTLE(c + 52,x13);
204 U32TO8_LITTLE(c + 56,x14);
205 U32TO8_LITTLE(c + 60,x15);
206
207 if (bytes <= 64) {
208 if (bytes < 64) {
209 for (i = 0;i < bytes;++i) ctarget[i] = c[i];
210 }
211 x->input[12] = j12;
212 x->input[13] = j13;
213 return;
214 }
215 bytes -= 64;
216 c += 64;
217 m += 64;
218 }
219}
diff --git a/chacha.h b/chacha.h
new file mode 100644
index 000000000..4ef42cc70
--- /dev/null
+++ b/chacha.h
@@ -0,0 +1,35 @@
1/* $OpenBSD: chacha.h,v 1.1 2013/11/21 00:45:44 djm Exp $ */
2
3/*
4chacha-merged.c version 20080118
5D. J. Bernstein
6Public domain.
7*/
8
9#ifndef CHACHA_H
10#define CHACHA_H
11
12#include <sys/types.h>
13
14struct chacha_ctx {
15 u_int input[16];
16};
17
18#define CHACHA_MINKEYLEN 16
19#define CHACHA_NONCELEN 8
20#define CHACHA_CTRLEN 8
21#define CHACHA_STATELEN (CHACHA_NONCELEN+CHACHA_CTRLEN)
22#define CHACHA_BLOCKLEN 64
23
24void chacha_keysetup(struct chacha_ctx *x, const u_char *k, u_int kbits)
25 __attribute__((__bounded__(__minbytes__, 2, CHACHA_MINKEYLEN)));
26void chacha_ivsetup(struct chacha_ctx *x, const u_char *iv, const u_char *ctr)
27 __attribute__((__bounded__(__minbytes__, 2, CHACHA_NONCELEN)))
28 __attribute__((__bounded__(__minbytes__, 3, CHACHA_CTRLEN)));
29void chacha_encrypt_bytes(struct chacha_ctx *x, const u_char *m,
30 u_char *c, u_int bytes)
31 __attribute__((__bounded__(__buffer__, 2, 4)))
32 __attribute__((__bounded__(__buffer__, 3, 4)));
33
34#endif /* CHACHA_H */
35
diff --git a/cipher-chachapoly.c b/cipher-chachapoly.c
new file mode 100644
index 000000000..20628ab5d
--- /dev/null
+++ b/cipher-chachapoly.c
@@ -0,0 +1,114 @@
1/*
2 * Copyright (c) 2013 Damien Miller <djm@mindrot.org>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17/* $OpenBSD: cipher-chachapoly.c,v 1.2 2013/11/21 02:50:00 djm Exp $ */
18
19#include "includes.h"
20
21#include <sys/types.h>
22#include <stdarg.h> /* needed for log.h */
23#include <string.h>
24#include <stdio.h> /* needed for misc.h */
25
26#include "log.h"
27#include "misc.h"
28#include "cipher-chachapoly.h"
29
30void chachapoly_init(struct chachapoly_ctx *ctx,
31 const u_char *key, u_int keylen)
32{
33 if (keylen != (32 + 32)) /* 2 x 256 bit keys */
34 fatal("%s: invalid keylen %u", __func__, keylen);
35 chacha_keysetup(&ctx->main_ctx, key, 256);
36 chacha_keysetup(&ctx->header_ctx, key + 32, 256);
37}
38
39/*
40 * chachapoly_crypt() operates as following:
41 * Copy 'aadlen' bytes (without en/decryption) from 'src' to 'dest'.
42 * Theses bytes are treated as additional authenticated data.
43 * En/Decrypt 'len' bytes at offset 'aadlen' from 'src' to 'dest'.
44 * Use POLY1305_TAGLEN bytes at offset 'len'+'aadlen' as the
45 * authentication tag.
46 * This tag is written on encryption and verified on decryption.
47 * Both 'aadlen' and 'authlen' can be set to 0.
48 */
49int
50chachapoly_crypt(struct chachapoly_ctx *ctx, u_int seqnr, u_char *dest,
51 const u_char *src, u_int len, u_int aadlen, u_int authlen, int do_encrypt)
52{
53 u_char seqbuf[8];
54 u_char one[8] = { 1, 0, 0, 0, 0, 0, 0, 0 }; /* NB. little-endian */
55 u_char expected_tag[POLY1305_TAGLEN], poly_key[POLY1305_KEYLEN];
56 int r = -1;
57
58 /*
59 * Run ChaCha20 once to generate the Poly1305 key. The IV is the
60 * packet sequence number.
61 */
62 bzero(poly_key, sizeof(poly_key));
63 put_u64(seqbuf, seqnr);
64 chacha_ivsetup(&ctx->main_ctx, seqbuf, NULL);
65 chacha_encrypt_bytes(&ctx->main_ctx,
66 poly_key, poly_key, sizeof(poly_key));
67 /* Set Chacha's block counter to 1 */
68 chacha_ivsetup(&ctx->main_ctx, seqbuf, one);
69
70 /* If decrypting, check tag before anything else */
71 if (!do_encrypt) {
72 const u_char *tag = src + aadlen + len;
73
74 poly1305_auth(expected_tag, src, aadlen + len, poly_key);
75 if (timingsafe_bcmp(expected_tag, tag, POLY1305_TAGLEN) != 0)
76 goto out;
77 }
78 /* Crypt additional data */
79 if (aadlen) {
80 chacha_ivsetup(&ctx->header_ctx, seqbuf, NULL);
81 chacha_encrypt_bytes(&ctx->header_ctx, src, dest, aadlen);
82 }
83 chacha_encrypt_bytes(&ctx->main_ctx, src + aadlen,
84 dest + aadlen, len);
85
86 /* If encrypting, calculate and append tag */
87 if (do_encrypt) {
88 poly1305_auth(dest + aadlen + len, dest, aadlen + len,
89 poly_key);
90 }
91 r = 0;
92
93 out:
94 bzero(expected_tag, sizeof(expected_tag));
95 bzero(seqbuf, sizeof(seqbuf));
96 bzero(poly_key, sizeof(poly_key));
97 return r;
98}
99
100int
101chachapoly_get_length(struct chachapoly_ctx *ctx,
102 u_int *plenp, u_int seqnr, const u_char *cp, u_int len)
103{
104 u_char buf[4], seqbuf[8];
105
106 if (len < 4)
107 return -1; /* Insufficient length */
108 put_u64(seqbuf, seqnr);
109 chacha_ivsetup(&ctx->header_ctx, seqbuf, NULL);
110 chacha_encrypt_bytes(&ctx->header_ctx, cp, buf, 4);
111 *plenp = get_u32(buf);
112 return 0;
113}
114
diff --git a/cipher-chachapoly.h b/cipher-chachapoly.h
new file mode 100644
index 000000000..1628693b2
--- /dev/null
+++ b/cipher-chachapoly.h
@@ -0,0 +1,41 @@
1/* $OpenBSD: cipher-chachapoly.h,v 1.1 2013/11/21 00:45:44 djm Exp $ */
2
3/*
4 * Copyright (c) Damien Miller 2013 <djm@mindrot.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18#ifndef CHACHA_POLY_AEAD_H
19#define CHACHA_POLY_AEAD_H
20
21#include <sys/types.h>
22#include "chacha.h"
23#include "poly1305.h"
24
25#define CHACHA_KEYLEN 32 /* Only 256 bit keys used here */
26
27struct chachapoly_ctx {
28 struct chacha_ctx main_ctx, header_ctx;
29};
30
31void chachapoly_init(struct chachapoly_ctx *cpctx,
32 const u_char *key, u_int keylen)
33 __attribute__((__bounded__(__buffer__, 2, 3)));
34int chachapoly_crypt(struct chachapoly_ctx *cpctx, u_int seqnr,
35 u_char *dest, const u_char *src, u_int len, u_int aadlen, u_int authlen,
36 int do_encrypt);
37int chachapoly_get_length(struct chachapoly_ctx *cpctx,
38 u_int *plenp, u_int seqnr, const u_char *cp, u_int len)
39 __attribute__((__bounded__(__buffer__, 4, 5)));
40
41#endif /* CHACHA_POLY_AEAD_H */
diff --git a/cipher.c b/cipher.c
index 54315f488..c4aec3923 100644
--- a/cipher.c
+++ b/cipher.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: cipher.c,v 1.90 2013/11/07 11:58:27 dtucker Exp $ */ 1/* $OpenBSD: cipher.c,v 1.91 2013/11/21 00:45:44 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -43,9 +43,11 @@
43 43
44#include <string.h> 44#include <string.h>
45#include <stdarg.h> 45#include <stdarg.h>
46#include <stdio.h>
46 47
47#include "xmalloc.h" 48#include "xmalloc.h"
48#include "log.h" 49#include "log.h"
50#include "misc.h"
49#include "cipher.h" 51#include "cipher.h"
50 52
51/* compatibility with old or broken OpenSSL versions */ 53/* compatibility with old or broken OpenSSL versions */
@@ -63,7 +65,9 @@ struct Cipher {
63 u_int iv_len; /* defaults to block_size */ 65 u_int iv_len; /* defaults to block_size */
64 u_int auth_len; 66 u_int auth_len;
65 u_int discard_len; 67 u_int discard_len;
66 u_int cbc_mode; 68 u_int flags;
69#define CFLAG_CBC (1<<0)
70#define CFLAG_CHACHAPOLY (1<<1)
67 const EVP_CIPHER *(*evptype)(void); 71 const EVP_CIPHER *(*evptype)(void);
68}; 72};
69 73
@@ -95,6 +99,8 @@ static const struct Cipher ciphers[] = {
95 { "aes256-gcm@openssh.com", 99 { "aes256-gcm@openssh.com",
96 SSH_CIPHER_SSH2, 16, 32, 12, 16, 0, 0, EVP_aes_256_gcm }, 100 SSH_CIPHER_SSH2, 16, 32, 12, 16, 0, 0, EVP_aes_256_gcm },
97#endif 101#endif
102 { "chacha20-poly1305@openssh.com",
103 SSH_CIPHER_SSH2, 8, 64, 0, 16, 0, CFLAG_CHACHAPOLY, NULL },
98 { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL } 104 { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL }
99}; 105};
100 106
@@ -102,7 +108,7 @@ static const struct Cipher ciphers[] = {
102 108
103/* Returns a list of supported ciphers separated by the specified char. */ 109/* Returns a list of supported ciphers separated by the specified char. */
104char * 110char *
105cipher_alg_list(char sep) 111cipher_alg_list(char sep, int auth_only)
106{ 112{
107 char *ret = NULL; 113 char *ret = NULL;
108 size_t nlen, rlen = 0; 114 size_t nlen, rlen = 0;
@@ -111,6 +117,8 @@ cipher_alg_list(char sep)
111 for (c = ciphers; c->name != NULL; c++) { 117 for (c = ciphers; c->name != NULL; c++) {
112 if (c->number != SSH_CIPHER_SSH2) 118 if (c->number != SSH_CIPHER_SSH2)
113 continue; 119 continue;
120 if (auth_only && c->auth_len == 0)
121 continue;
114 if (ret != NULL) 122 if (ret != NULL)
115 ret[rlen++] = sep; 123 ret[rlen++] = sep;
116 nlen = strlen(c->name); 124 nlen = strlen(c->name);
@@ -142,7 +150,12 @@ cipher_authlen(const Cipher *c)
142u_int 150u_int
143cipher_ivlen(const Cipher *c) 151cipher_ivlen(const Cipher *c)
144{ 152{
145 return (c->iv_len ? c->iv_len : c->block_size); 153 /*
154 * Default is cipher block size, except for chacha20+poly1305 that
155 * needs no IV. XXX make iv_len == -1 default?
156 */
157 return (c->iv_len != 0 || (c->flags & CFLAG_CHACHAPOLY) != 0) ?
158 c->iv_len : c->block_size;
146} 159}
147 160
148u_int 161u_int
@@ -154,7 +167,7 @@ cipher_get_number(const Cipher *c)
154u_int 167u_int
155cipher_is_cbc(const Cipher *c) 168cipher_is_cbc(const Cipher *c)
156{ 169{
157 return (c->cbc_mode); 170 return (c->flags & CFLAG_CBC) != 0;
158} 171}
159 172
160u_int 173u_int
@@ -274,8 +287,11 @@ cipher_init(CipherContext *cc, const Cipher *cipher,
274 ivlen, cipher->name); 287 ivlen, cipher->name);
275 cc->cipher = cipher; 288 cc->cipher = cipher;
276 289
290 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) {
291 chachapoly_init(&cc->cp_ctx, key, keylen);
292 return;
293 }
277 type = (*cipher->evptype)(); 294 type = (*cipher->evptype)();
278
279 EVP_CIPHER_CTX_init(&cc->evp); 295 EVP_CIPHER_CTX_init(&cc->evp);
280#ifdef SSH_OLD_EVP 296#ifdef SSH_OLD_EVP
281 if (type->key_len > 0 && type->key_len != keylen) { 297 if (type->key_len > 0 && type->key_len != keylen) {
@@ -330,9 +346,15 @@ cipher_init(CipherContext *cc, const Cipher *cipher,
330 * Both 'aadlen' and 'authlen' can be set to 0. 346 * Both 'aadlen' and 'authlen' can be set to 0.
331 */ 347 */
332void 348void
333cipher_crypt(CipherContext *cc, u_char *dest, const u_char *src, 349cipher_crypt(CipherContext *cc, u_int seqnr, u_char *dest, const u_char *src,
334 u_int len, u_int aadlen, u_int authlen) 350 u_int len, u_int aadlen, u_int authlen)
335{ 351{
352 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) {
353 if (chachapoly_crypt(&cc->cp_ctx, seqnr, dest, src, len, aadlen,
354 authlen, cc->encrypt) != 0)
355 fatal("Decryption integrity check failed");
356 return;
357 }
336 if (authlen) { 358 if (authlen) {
337 u_char lastiv[1]; 359 u_char lastiv[1];
338 360
@@ -374,10 +396,26 @@ cipher_crypt(CipherContext *cc, u_char *dest, const u_char *src,
374 } 396 }
375} 397}
376 398
399/* Extract the packet length, including any decryption necessary beforehand */
400int
401cipher_get_length(CipherContext *cc, u_int *plenp, u_int seqnr,
402 const u_char *cp, u_int len)
403{
404 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
405 return chachapoly_get_length(&cc->cp_ctx, plenp, seqnr,
406 cp, len);
407 if (len < 4)
408 return -1;
409 *plenp = get_u32(cp);
410 return 0;
411}
412
377void 413void
378cipher_cleanup(CipherContext *cc) 414cipher_cleanup(CipherContext *cc)
379{ 415{
380 if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0) 416 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
417 bzero(&cc->cp_ctx, sizeof(&cc->cp_ctx));
418 else if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0)
381 error("cipher_cleanup: EVP_CIPHER_CTX_cleanup failed"); 419 error("cipher_cleanup: EVP_CIPHER_CTX_cleanup failed");
382} 420}
383 421
@@ -417,6 +455,8 @@ cipher_get_keyiv_len(const CipherContext *cc)
417 455
418 if (c->number == SSH_CIPHER_3DES) 456 if (c->number == SSH_CIPHER_3DES)
419 ivlen = 24; 457 ivlen = 24;
458 else if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
459 ivlen = 0;
420 else 460 else
421 ivlen = EVP_CIPHER_CTX_iv_length(&cc->evp); 461 ivlen = EVP_CIPHER_CTX_iv_length(&cc->evp);
422 return (ivlen); 462 return (ivlen);
@@ -428,6 +468,12 @@ cipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len)
428 const Cipher *c = cc->cipher; 468 const Cipher *c = cc->cipher;
429 int evplen; 469 int evplen;
430 470
471 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) {
472 if (len != 0)
473 fatal("%s: wrong iv length %d != %d", __func__, len, 0);
474 return;
475 }
476
431 switch (c->number) { 477 switch (c->number) {
432 case SSH_CIPHER_SSH2: 478 case SSH_CIPHER_SSH2:
433 case SSH_CIPHER_DES: 479 case SSH_CIPHER_DES:
@@ -464,6 +510,9 @@ cipher_set_keyiv(CipherContext *cc, u_char *iv)
464 const Cipher *c = cc->cipher; 510 const Cipher *c = cc->cipher;
465 int evplen = 0; 511 int evplen = 0;
466 512
513 if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
514 return;
515
467 switch (c->number) { 516 switch (c->number) {
468 case SSH_CIPHER_SSH2: 517 case SSH_CIPHER_SSH2:
469 case SSH_CIPHER_DES: 518 case SSH_CIPHER_DES:
diff --git a/cipher.h b/cipher.h
index 46502348b..4e837a754 100644
--- a/cipher.h
+++ b/cipher.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: cipher.h,v 1.41 2013/11/07 11:58:27 dtucker Exp $ */ 1/* $OpenBSD: cipher.h,v 1.42 2013/11/21 00:45:44 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -38,6 +38,8 @@
38#define CIPHER_H 38#define CIPHER_H
39 39
40#include <openssl/evp.h> 40#include <openssl/evp.h>
41#include "cipher-chachapoly.h"
42
41/* 43/*
42 * Cipher types for SSH-1. New types can be added, but old types should not 44 * Cipher types for SSH-1. New types can be added, but old types should not
43 * be removed for compatibility. The maximum allowed value is 31. 45 * be removed for compatibility. The maximum allowed value is 31.
@@ -66,6 +68,7 @@ struct CipherContext {
66 int plaintext; 68 int plaintext;
67 int encrypt; 69 int encrypt;
68 EVP_CIPHER_CTX evp; 70 EVP_CIPHER_CTX evp;
71 struct chachapoly_ctx cp_ctx; /* XXX union with evp? */
69 const Cipher *cipher; 72 const Cipher *cipher;
70}; 73};
71 74
@@ -75,11 +78,13 @@ const Cipher *cipher_by_number(int);
75int cipher_number(const char *); 78int cipher_number(const char *);
76char *cipher_name(int); 79char *cipher_name(int);
77int ciphers_valid(const char *); 80int ciphers_valid(const char *);
78char *cipher_alg_list(char); 81char *cipher_alg_list(char, int);
79void cipher_init(CipherContext *, const Cipher *, const u_char *, u_int, 82void cipher_init(CipherContext *, const Cipher *, const u_char *, u_int,
80 const u_char *, u_int, int); 83 const u_char *, u_int, int);
81void cipher_crypt(CipherContext *, u_char *, const u_char *, 84void cipher_crypt(CipherContext *, u_int, u_char *, const u_char *,
82 u_int, u_int, u_int); 85 u_int, u_int, u_int);
86int cipher_get_length(CipherContext *, u_int *, u_int,
87 const u_char *, u_int);
83void cipher_cleanup(CipherContext *); 88void cipher_cleanup(CipherContext *);
84void cipher_set_key_string(CipherContext *, const Cipher *, const char *, int); 89void cipher_set_key_string(CipherContext *, const Cipher *, const char *, int);
85u_int cipher_blocksize(const Cipher *); 90u_int cipher_blocksize(const Cipher *);
diff --git a/dh.c b/dh.c
index d33af1fa7..3331cda6c 100644
--- a/dh.c
+++ b/dh.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: dh.c,v 1.52 2013/10/08 11:42:13 dtucker Exp $ */ 1/* $OpenBSD: dh.c,v 1.53 2013/11/21 00:45:44 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Niels Provos. All rights reserved. 3 * Copyright (c) 2000 Niels Provos. All rights reserved.
4 * 4 *
@@ -254,33 +254,19 @@ dh_pub_is_valid(DH *dh, BIGNUM *dh_pub)
254void 254void
255dh_gen_key(DH *dh, int need) 255dh_gen_key(DH *dh, int need)
256{ 256{
257 int i, bits_set, tries = 0; 257 int pbits;
258 258
259 if (need < 0) 259 if (need <= 0)
260 fatal("dh_gen_key: need < 0"); 260 fatal("%s: need <= 0", __func__);
261 if (dh->p == NULL) 261 if (dh->p == NULL)
262 fatal("dh_gen_key: dh->p == NULL"); 262 fatal("%s: dh->p == NULL", __func__);
263 if (need > INT_MAX / 2 || 2 * need >= BN_num_bits(dh->p)) 263 if ((pbits = BN_num_bits(dh->p)) <= 0)
264 fatal("dh_gen_key: group too small: %d (2*need %d)", 264 fatal("%s: bits(p) <= 0", __func__);
265 BN_num_bits(dh->p), 2*need); 265 dh->length = MIN(need * 2, pbits - 1);
266 do { 266 if (DH_generate_key(dh) == 0)
267 if (dh->priv_key != NULL) 267 fatal("%s: key generation failed", __func__);
268 BN_clear_free(dh->priv_key); 268 if (!dh_pub_is_valid(dh, dh->pub_key))
269 if ((dh->priv_key = BN_new()) == NULL) 269 fatal("%s: generated invalid key", __func__);
270 fatal("dh_gen_key: BN_new failed");
271 /* generate a 2*need bits random private exponent */
272 if (!BN_rand(dh->priv_key, 2*need, 0, 0))
273 fatal("dh_gen_key: BN_rand failed");
274 if (DH_generate_key(dh) == 0)
275 fatal("DH_generate_key");
276 for (i = 0, bits_set = 0; i <= BN_num_bits(dh->priv_key); i++)
277 if (BN_is_bit_set(dh->priv_key, i))
278 bits_set++;
279 debug2("dh_gen_key: priv key bits set: %d/%d",
280 bits_set, BN_num_bits(dh->priv_key));
281 if (tries++ > 10)
282 fatal("dh_gen_key: too many bad keys: giving up");
283 } while (!dh_pub_is_valid(dh, dh->pub_key));
284} 270}
285 271
286DH * 272DH *
diff --git a/myproposal.h b/myproposal.h
index 8da2ac91f..71dbc997e 100644
--- a/myproposal.h
+++ b/myproposal.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: myproposal.h,v 1.33 2013/11/02 21:59:15 markus Exp $ */ 1/* $OpenBSD: myproposal.h,v 1.34 2013/11/21 00:45:44 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000 Markus Friedl. All rights reserved. 4 * Copyright (c) 2000 Markus Friedl. All rights reserved.
@@ -104,6 +104,7 @@
104 "aes128-ctr,aes192-ctr,aes256-ctr," \ 104 "aes128-ctr,aes192-ctr,aes256-ctr," \
105 "arcfour256,arcfour128," \ 105 "arcfour256,arcfour128," \
106 AESGCM_CIPHER_MODES \ 106 AESGCM_CIPHER_MODES \
107 "chacha20-poly1305@openssh.com," \
107 "aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc," \ 108 "aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc," \
108 "aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se" 109 "aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se"
109 110
diff --git a/packet.c b/packet.c
index 90db33bdd..029bb4c98 100644
--- a/packet.c
+++ b/packet.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: packet.c,v 1.189 2013/11/08 00:39:15 djm Exp $ */ 1/* $OpenBSD: packet.c,v 1.190 2013/11/21 00:45:44 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -713,7 +713,7 @@ packet_send1(void)
713 buffer_append(&active_state->output, buf, 4); 713 buffer_append(&active_state->output, buf, 4);
714 cp = buffer_append_space(&active_state->output, 714 cp = buffer_append_space(&active_state->output,
715 buffer_len(&active_state->outgoing_packet)); 715 buffer_len(&active_state->outgoing_packet));
716 cipher_crypt(&active_state->send_context, cp, 716 cipher_crypt(&active_state->send_context, 0, cp,
717 buffer_ptr(&active_state->outgoing_packet), 717 buffer_ptr(&active_state->outgoing_packet),
718 buffer_len(&active_state->outgoing_packet), 0, 0); 718 buffer_len(&active_state->outgoing_packet), 0, 0);
719 719
@@ -946,8 +946,8 @@ packet_send2_wrapped(void)
946 } 946 }
947 /* encrypt packet and append to output buffer. */ 947 /* encrypt packet and append to output buffer. */
948 cp = buffer_append_space(&active_state->output, len + authlen); 948 cp = buffer_append_space(&active_state->output, len + authlen);
949 cipher_crypt(&active_state->send_context, cp, 949 cipher_crypt(&active_state->send_context, active_state->p_send.seqnr,
950 buffer_ptr(&active_state->outgoing_packet), 950 cp, buffer_ptr(&active_state->outgoing_packet),
951 len - aadlen, aadlen, authlen); 951 len - aadlen, aadlen, authlen);
952 /* append unencrypted MAC */ 952 /* append unencrypted MAC */
953 if (mac && mac->enabled) { 953 if (mac && mac->enabled) {
@@ -1208,7 +1208,7 @@ packet_read_poll1(void)
1208 /* Decrypt data to incoming_packet. */ 1208 /* Decrypt data to incoming_packet. */
1209 buffer_clear(&active_state->incoming_packet); 1209 buffer_clear(&active_state->incoming_packet);
1210 cp = buffer_append_space(&active_state->incoming_packet, padded_len); 1210 cp = buffer_append_space(&active_state->incoming_packet, padded_len);
1211 cipher_crypt(&active_state->receive_context, cp, 1211 cipher_crypt(&active_state->receive_context, 0, cp,
1212 buffer_ptr(&active_state->input), padded_len, 0, 0); 1212 buffer_ptr(&active_state->input), padded_len, 0, 0);
1213 1213
1214 buffer_consume(&active_state->input, padded_len); 1214 buffer_consume(&active_state->input, padded_len);
@@ -1279,10 +1279,12 @@ packet_read_poll2(u_int32_t *seqnr_p)
1279 aadlen = (mac && mac->enabled && mac->etm) || authlen ? 4 : 0; 1279 aadlen = (mac && mac->enabled && mac->etm) || authlen ? 4 : 0;
1280 1280
1281 if (aadlen && active_state->packlen == 0) { 1281 if (aadlen && active_state->packlen == 0) {
1282 if (buffer_len(&active_state->input) < 4) 1282 if (cipher_get_length(&active_state->receive_context,
1283 &active_state->packlen,
1284 active_state->p_read.seqnr,
1285 buffer_ptr(&active_state->input),
1286 buffer_len(&active_state->input)) != 0)
1283 return SSH_MSG_NONE; 1287 return SSH_MSG_NONE;
1284 cp = buffer_ptr(&active_state->input);
1285 active_state->packlen = get_u32(cp);
1286 if (active_state->packlen < 1 + 4 || 1288 if (active_state->packlen < 1 + 4 ||
1287 active_state->packlen > PACKET_MAX_SIZE) { 1289 active_state->packlen > PACKET_MAX_SIZE) {
1288#ifdef PACKET_DEBUG 1290#ifdef PACKET_DEBUG
@@ -1302,7 +1304,8 @@ packet_read_poll2(u_int32_t *seqnr_p)
1302 buffer_clear(&active_state->incoming_packet); 1304 buffer_clear(&active_state->incoming_packet);
1303 cp = buffer_append_space(&active_state->incoming_packet, 1305 cp = buffer_append_space(&active_state->incoming_packet,
1304 block_size); 1306 block_size);
1305 cipher_crypt(&active_state->receive_context, cp, 1307 cipher_crypt(&active_state->receive_context,
1308 active_state->p_read.seqnr, cp,
1306 buffer_ptr(&active_state->input), block_size, 0, 0); 1309 buffer_ptr(&active_state->input), block_size, 0, 0);
1307 cp = buffer_ptr(&active_state->incoming_packet); 1310 cp = buffer_ptr(&active_state->incoming_packet);
1308 active_state->packlen = get_u32(cp); 1311 active_state->packlen = get_u32(cp);
@@ -1357,7 +1360,8 @@ packet_read_poll2(u_int32_t *seqnr_p)
1357 macbuf = mac_compute(mac, active_state->p_read.seqnr, 1360 macbuf = mac_compute(mac, active_state->p_read.seqnr,
1358 buffer_ptr(&active_state->input), aadlen + need); 1361 buffer_ptr(&active_state->input), aadlen + need);
1359 cp = buffer_append_space(&active_state->incoming_packet, aadlen + need); 1362 cp = buffer_append_space(&active_state->incoming_packet, aadlen + need);
1360 cipher_crypt(&active_state->receive_context, cp, 1363 cipher_crypt(&active_state->receive_context,
1364 active_state->p_read.seqnr, cp,
1361 buffer_ptr(&active_state->input), need, aadlen, authlen); 1365 buffer_ptr(&active_state->input), need, aadlen, authlen);
1362 buffer_consume(&active_state->input, aadlen + need + authlen); 1366 buffer_consume(&active_state->input, aadlen + need + authlen);
1363 /* 1367 /*
diff --git a/poly1305.c b/poly1305.c
new file mode 100644
index 000000000..059cc60f7
--- /dev/null
+++ b/poly1305.c
@@ -0,0 +1,158 @@
1/*
2 * Public Domain poly1305 from Andrew M.
3 * poly1305-donna-unrolled.c from https://github.com/floodyberry/poly1305-donna
4 */
5
6/* $OpenBSD: poly1305.c,v 1.2 2013/11/21 02:50:00 djm Exp $ */
7
8#include "includes.h"
9
10#include <sys/types.h>
11#include <stdint.h>
12
13#include "poly1305.h"
14
15#define mul32x32_64(a,b) ((uint64_t)(a) * (b))
16
17#define U8TO32_LE(p) \
18 (((uint32_t)((p)[0])) | \
19 ((uint32_t)((p)[1]) << 8) | \
20 ((uint32_t)((p)[2]) << 16) | \
21 ((uint32_t)((p)[3]) << 24))
22
23#define U32TO8_LE(p, v) \
24 do { \
25 (p)[0] = (uint8_t)((v)); \
26 (p)[1] = (uint8_t)((v) >> 8); \
27 (p)[2] = (uint8_t)((v) >> 16); \
28 (p)[3] = (uint8_t)((v) >> 24); \
29 } while (0)
30
31void
32poly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m, size_t inlen, const unsigned char key[POLY1305_KEYLEN]) {
33 uint32_t t0,t1,t2,t3;
34 uint32_t h0,h1,h2,h3,h4;
35 uint32_t r0,r1,r2,r3,r4;
36 uint32_t s1,s2,s3,s4;
37 uint32_t b, nb;
38 size_t j;
39 uint64_t t[5];
40 uint64_t f0,f1,f2,f3;
41 uint32_t g0,g1,g2,g3,g4;
42 uint64_t c;
43 unsigned char mp[16];
44
45 /* clamp key */
46 t0 = U8TO32_LE(key+0);
47 t1 = U8TO32_LE(key+4);
48 t2 = U8TO32_LE(key+8);
49 t3 = U8TO32_LE(key+12);
50
51 /* precompute multipliers */
52 r0 = t0 & 0x3ffffff; t0 >>= 26; t0 |= t1 << 6;
53 r1 = t0 & 0x3ffff03; t1 >>= 20; t1 |= t2 << 12;
54 r2 = t1 & 0x3ffc0ff; t2 >>= 14; t2 |= t3 << 18;
55 r3 = t2 & 0x3f03fff; t3 >>= 8;
56 r4 = t3 & 0x00fffff;
57
58 s1 = r1 * 5;
59 s2 = r2 * 5;
60 s3 = r3 * 5;
61 s4 = r4 * 5;
62
63 /* init state */
64 h0 = 0;
65 h1 = 0;
66 h2 = 0;
67 h3 = 0;
68 h4 = 0;
69
70 /* full blocks */
71 if (inlen < 16) goto poly1305_donna_atmost15bytes;
72poly1305_donna_16bytes:
73 m += 16;
74 inlen -= 16;
75
76 t0 = U8TO32_LE(m-16);
77 t1 = U8TO32_LE(m-12);
78 t2 = U8TO32_LE(m-8);
79 t3 = U8TO32_LE(m-4);
80
81 h0 += t0 & 0x3ffffff;
82 h1 += ((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff;
83 h2 += ((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff;
84 h3 += ((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff;
85 h4 += (t3 >> 8) | (1 << 24);
86
87
88poly1305_donna_mul:
89 t[0] = mul32x32_64(h0,r0) + mul32x32_64(h1,s4) + mul32x32_64(h2,s3) + mul32x32_64(h3,s2) + mul32x32_64(h4,s1);
90 t[1] = mul32x32_64(h0,r1) + mul32x32_64(h1,r0) + mul32x32_64(h2,s4) + mul32x32_64(h3,s3) + mul32x32_64(h4,s2);
91 t[2] = mul32x32_64(h0,r2) + mul32x32_64(h1,r1) + mul32x32_64(h2,r0) + mul32x32_64(h3,s4) + mul32x32_64(h4,s3);
92 t[3] = mul32x32_64(h0,r3) + mul32x32_64(h1,r2) + mul32x32_64(h2,r1) + mul32x32_64(h3,r0) + mul32x32_64(h4,s4);
93 t[4] = mul32x32_64(h0,r4) + mul32x32_64(h1,r3) + mul32x32_64(h2,r2) + mul32x32_64(h3,r1) + mul32x32_64(h4,r0);
94
95 h0 = (uint32_t)t[0] & 0x3ffffff; c = (t[0] >> 26);
96 t[1] += c; h1 = (uint32_t)t[1] & 0x3ffffff; b = (uint32_t)(t[1] >> 26);
97 t[2] += b; h2 = (uint32_t)t[2] & 0x3ffffff; b = (uint32_t)(t[2] >> 26);
98 t[3] += b; h3 = (uint32_t)t[3] & 0x3ffffff; b = (uint32_t)(t[3] >> 26);
99 t[4] += b; h4 = (uint32_t)t[4] & 0x3ffffff; b = (uint32_t)(t[4] >> 26);
100 h0 += b * 5;
101
102 if (inlen >= 16) goto poly1305_donna_16bytes;
103
104 /* final bytes */
105poly1305_donna_atmost15bytes:
106 if (!inlen) goto poly1305_donna_finish;
107
108 for (j = 0; j < inlen; j++) mp[j] = m[j];
109 mp[j++] = 1;
110 for (; j < 16; j++) mp[j] = 0;
111 inlen = 0;
112
113 t0 = U8TO32_LE(mp+0);
114 t1 = U8TO32_LE(mp+4);
115 t2 = U8TO32_LE(mp+8);
116 t3 = U8TO32_LE(mp+12);
117
118 h0 += t0 & 0x3ffffff;
119 h1 += ((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff;
120 h2 += ((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff;
121 h3 += ((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff;
122 h4 += (t3 >> 8);
123
124 goto poly1305_donna_mul;
125
126poly1305_donna_finish:
127 b = h0 >> 26; h0 = h0 & 0x3ffffff;
128 h1 += b; b = h1 >> 26; h1 = h1 & 0x3ffffff;
129 h2 += b; b = h2 >> 26; h2 = h2 & 0x3ffffff;
130 h3 += b; b = h3 >> 26; h3 = h3 & 0x3ffffff;
131 h4 += b; b = h4 >> 26; h4 = h4 & 0x3ffffff;
132 h0 += b * 5; b = h0 >> 26; h0 = h0 & 0x3ffffff;
133 h1 += b;
134
135 g0 = h0 + 5; b = g0 >> 26; g0 &= 0x3ffffff;
136 g1 = h1 + b; b = g1 >> 26; g1 &= 0x3ffffff;
137 g2 = h2 + b; b = g2 >> 26; g2 &= 0x3ffffff;
138 g3 = h3 + b; b = g3 >> 26; g3 &= 0x3ffffff;
139 g4 = h4 + b - (1 << 26);
140
141 b = (g4 >> 31) - 1;
142 nb = ~b;
143 h0 = (h0 & nb) | (g0 & b);
144 h1 = (h1 & nb) | (g1 & b);
145 h2 = (h2 & nb) | (g2 & b);
146 h3 = (h3 & nb) | (g3 & b);
147 h4 = (h4 & nb) | (g4 & b);
148
149 f0 = ((h0 ) | (h1 << 26)) + (uint64_t)U8TO32_LE(&key[16]);
150 f1 = ((h1 >> 6) | (h2 << 20)) + (uint64_t)U8TO32_LE(&key[20]);
151 f2 = ((h2 >> 12) | (h3 << 14)) + (uint64_t)U8TO32_LE(&key[24]);
152 f3 = ((h3 >> 18) | (h4 << 8)) + (uint64_t)U8TO32_LE(&key[28]);
153
154 U32TO8_LE(&out[ 0], f0); f1 += (f0 >> 32);
155 U32TO8_LE(&out[ 4], f1); f2 += (f1 >> 32);
156 U32TO8_LE(&out[ 8], f2); f3 += (f2 >> 32);
157 U32TO8_LE(&out[12], f3);
158}
diff --git a/poly1305.h b/poly1305.h
new file mode 100644
index 000000000..a31fb7425
--- /dev/null
+++ b/poly1305.h
@@ -0,0 +1,22 @@
1/* $OpenBSD: poly1305.h,v 1.1 2013/11/21 00:45:44 djm Exp $ */
2
3/*
4 * Public Domain poly1305 from Andrew M.
5 * poly1305-donna-unrolled.c from https://github.com/floodyberry/poly1305-donna
6 */
7
8#ifndef POLY1305_H
9#define POLY1305_H
10
11#include <sys/types.h>
12
13#define POLY1305_KEYLEN 32
14#define POLY1305_TAGLEN 16
15
16void poly1305_auth(u_char out[POLY1305_TAGLEN], const u_char *m, size_t inlen,
17 const u_char key[POLY1305_KEYLEN])
18 __attribute__((__bounded__(__minbytes__, 1, POLY1305_TAGLEN)))
19 __attribute__((__bounded__(__buffer__, 2, 3)))
20 __attribute__((__bounded__(__minbytes__, 4, POLY1305_KEYLEN)));
21
22#endif /* POLY1305_H */
diff --git a/servconf.c b/servconf.c
index 3593223f7..cb21bd229 100644
--- a/servconf.c
+++ b/servconf.c
@@ -1,5 +1,5 @@
1 1
2/* $OpenBSD: servconf.c,v 1.245 2013/11/07 11:58:27 dtucker Exp $ */ 2/* $OpenBSD: servconf.c,v 1.246 2013/11/21 00:45:44 djm Exp $ */
3/* 3/*
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5 * All rights reserved 5 * All rights reserved
@@ -2038,7 +2038,7 @@ dump_config(ServerOptions *o)
2038 dump_cfg_string(sPidFile, o->pid_file); 2038 dump_cfg_string(sPidFile, o->pid_file);
2039 dump_cfg_string(sXAuthLocation, o->xauth_location); 2039 dump_cfg_string(sXAuthLocation, o->xauth_location);
2040 dump_cfg_string(sCiphers, o->ciphers ? o->ciphers : 2040 dump_cfg_string(sCiphers, o->ciphers ? o->ciphers :
2041 cipher_alg_list(',')); 2041 cipher_alg_list(',', 0));
2042 dump_cfg_string(sMacs, o->macs ? o->macs : mac_alg_list(',')); 2042 dump_cfg_string(sMacs, o->macs ? o->macs : mac_alg_list(','));
2043 dump_cfg_string(sBanner, o->banner); 2043 dump_cfg_string(sBanner, o->banner);
2044 dump_cfg_string(sForceCommand, o->adm_forced_command); 2044 dump_cfg_string(sForceCommand, o->adm_forced_command);
diff --git a/ssh.1 b/ssh.1
index 6369fc28b..73e208693 100644
--- a/ssh.1
+++ b/ssh.1
@@ -33,8 +33,8 @@
33.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 33.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35.\" 35.\"
36.\" $OpenBSD: ssh.1,v 1.339 2013/10/16 22:49:38 djm Exp $ 36.\" $OpenBSD: ssh.1,v 1.340 2013/11/21 00:45:44 djm Exp $
37.Dd $Mdocdate: October 16 2013 $ 37.Dd $Mdocdate: November 21 2013 $
38.Dt SSH 1 38.Dt SSH 1
39.Os 39.Os
40.Sh NAME 40.Sh NAME
@@ -504,6 +504,8 @@ for the algorithms supported for the specified version 2
504The queriable features are: 504The queriable features are:
505.Dq cipher 505.Dq cipher
506(supported symmetric ciphers), 506(supported symmetric ciphers),
507.Dq cipher-auth
508(supported symmetric ciphers that support authenticated encryption),
507.Dq MAC 509.Dq MAC
508(supported message integrity codes), 510(supported message integrity codes),
509.Dq KEX 511.Dq KEX
diff --git a/ssh.c b/ssh.c
index e2c43634a..58becd708 100644
--- a/ssh.c
+++ b/ssh.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh.c,v 1.392 2013/11/07 11:58:27 dtucker Exp $ */ 1/* $OpenBSD: ssh.c,v 1.393 2013/11/21 00:45:44 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -520,7 +520,9 @@ main(int ac, char **av)
520 case 'Q': /* deprecated */ 520 case 'Q': /* deprecated */
521 cp = NULL; 521 cp = NULL;
522 if (strcasecmp(optarg, "cipher") == 0) 522 if (strcasecmp(optarg, "cipher") == 0)
523 cp = cipher_alg_list('\n'); 523 cp = cipher_alg_list('\n', 0);
524 else if (strcasecmp(optarg, "cipher-auth") == 0)
525 cp = cipher_alg_list('\n', 1);
524 else if (strcasecmp(optarg, "mac") == 0) 526 else if (strcasecmp(optarg, "mac") == 0)
525 cp = mac_alg_list('\n'); 527 cp = mac_alg_list('\n');
526 else if (strcasecmp(optarg, "kex") == 0) 528 else if (strcasecmp(optarg, "kex") == 0)
diff --git a/ssh_config.5 b/ssh_config.5
index 8809568a6..9dbc76ca9 100644
--- a/ssh_config.5
+++ b/ssh_config.5
@@ -33,8 +33,8 @@
33.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 33.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35.\" 35.\"
36.\" $OpenBSD: ssh_config.5,v 1.179 2013/11/02 22:39:19 markus Exp $ 36.\" $OpenBSD: ssh_config.5,v 1.180 2013/11/21 00:45:44 djm Exp $
37.Dd $Mdocdate: November 2 2013 $ 37.Dd $Mdocdate: November 21 2013 $
38.Dt SSH_CONFIG 5 38.Dt SSH_CONFIG 5
39.Os 39.Os
40.Sh NAME 40.Sh NAME
@@ -334,7 +334,8 @@ The default is
334Specifies the ciphers allowed for protocol version 2 334Specifies the ciphers allowed for protocol version 2
335in order of preference. 335in order of preference.
336Multiple ciphers must be comma-separated. 336Multiple ciphers must be comma-separated.
337The supported ciphers are 337The supported ciphers are:
338.Pp
338.Dq 3des-cbc , 339.Dq 3des-cbc ,
339.Dq aes128-cbc , 340.Dq aes128-cbc ,
340.Dq aes192-cbc , 341.Dq aes192-cbc ,
@@ -348,15 +349,24 @@ The supported ciphers are
348.Dq arcfour256 , 349.Dq arcfour256 ,
349.Dq arcfour , 350.Dq arcfour ,
350.Dq blowfish-cbc , 351.Dq blowfish-cbc ,
352.Dq cast128-cbc ,
351and 353and
352.Dq cast128-cbc . 354.Dq chacha20-poly1305@openssh.com .
355.Pp
353The default is: 356The default is:
357.Pp
354.Bd -literal -offset 3n 358.Bd -literal -offset 3n
355aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128, 359aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,
356aes128-gcm@openssh.com,aes256-gcm@openssh.com, 360aes128-gcm@openssh.com,aes256-gcm@openssh.com,
361chacha20-poly1305@openssh.com,
357aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc, 362aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,
358aes256-cbc,arcfour 363aes256-cbc,arcfour
359.Ed 364.Ed
365.Pp
366The list of available ciphers may also be obtained using the
367.Fl Q
368option of
369.Xr ssh 1 .
360.It Cm ClearAllForwardings 370.It Cm ClearAllForwardings
361Specifies that all local, remote, and dynamic port forwardings 371Specifies that all local, remote, and dynamic port forwardings
362specified in the configuration files or on the command line be 372specified in the configuration files or on the command line be
diff --git a/sshd_config.5 b/sshd_config.5
index 02c45a7df..b9864fff2 100644
--- a/sshd_config.5
+++ b/sshd_config.5
@@ -33,8 +33,8 @@
33.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 33.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35.\" 35.\"
36.\" $OpenBSD: sshd_config.5,v 1.166 2013/11/02 22:39:19 markus Exp $ 36.\" $OpenBSD: sshd_config.5,v 1.167 2013/11/21 00:45:44 djm Exp $
37.Dd $Mdocdate: November 2 2013 $ 37.Dd $Mdocdate: November 21 2013 $
38.Dt SSHD_CONFIG 5 38.Dt SSHD_CONFIG 5
39.Os 39.Os
40.Sh NAME 40.Sh NAME
@@ -335,7 +335,8 @@ The default is not to
335.It Cm Ciphers 335.It Cm Ciphers
336Specifies the ciphers allowed for protocol version 2. 336Specifies the ciphers allowed for protocol version 2.
337Multiple ciphers must be comma-separated. 337Multiple ciphers must be comma-separated.
338The supported ciphers are 338The supported ciphers are:
339.Pp
339.Dq 3des-cbc , 340.Dq 3des-cbc ,
340.Dq aes128-cbc , 341.Dq aes128-cbc ,
341.Dq aes192-cbc , 342.Dq aes192-cbc ,
@@ -349,15 +350,24 @@ The supported ciphers are
349.Dq arcfour256 , 350.Dq arcfour256 ,
350.Dq arcfour , 351.Dq arcfour ,
351.Dq blowfish-cbc , 352.Dq blowfish-cbc ,
353.Dq cast128-cbc ,
352and 354and
353.Dq cast128-cbc . 355.Dq chacha20-poly1305@openssh.com .
356.Pp
354The default is: 357The default is:
358.Pp
355.Bd -literal -offset 3n 359.Bd -literal -offset 3n
356aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128, 360aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,
357aes128-gcm@openssh.com,aes256-gcm@openssh.com, 361aes128-gcm@openssh.com,aes256-gcm@openssh.com,
362chacha20-poly1305@openssh.com,
358aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc, 363aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,
359aes256-cbc,arcfour 364aes256-cbc,arcfour
360.Ed 365.Ed
366.Pp
367The list of available ciphers may also be obtained using the
368.Fl Q
369option of
370.Xr ssh 1 .
361.It Cm ClientAliveCountMax 371.It Cm ClientAliveCountMax
362Sets the number of client alive messages (see below) which may be 372Sets the number of client alive messages (see below) which may be
363sent without 373sent without