kex.c revision 1.137
1/* $OpenBSD: kex.c,v 1.137 2018/07/03 11:39:54 djm Exp $ */
2/*
3 * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26
27#include <signal.h>
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
31
32#ifdef WITH_OPENSSL
33#include <openssl/crypto.h>
34#endif
35
36#include "ssh2.h"
37#include "packet.h"
38#include "compat.h"
39#include "cipher.h"
40#include "sshkey.h"
41#include "kex.h"
42#include "log.h"
43#include "mac.h"
44#include "match.h"
45#include "misc.h"
46#include "dispatch.h"
47#include "monitor.h"
48
49#include "ssherr.h"
50#include "sshbuf.h"
51#include "digest.h"
52
53/* prototype */
54static int kex_choose_conf(struct ssh *);
55static int kex_input_newkeys(int, u_int32_t, struct ssh *);
56
57static const char *proposal_names[PROPOSAL_MAX] = {
58	"KEX algorithms",
59	"host key algorithms",
60	"ciphers ctos",
61	"ciphers stoc",
62	"MACs ctos",
63	"MACs stoc",
64	"compression ctos",
65	"compression stoc",
66	"languages ctos",
67	"languages stoc",
68};
69
70struct kexalg {
71	char *name;
72	u_int type;
73	int ec_nid;
74	int hash_alg;
75};
76static const struct kexalg kexalgs[] = {
77#ifdef WITH_OPENSSL
78	{ KEX_DH1, KEX_DH_GRP1_SHA1, 0, SSH_DIGEST_SHA1 },
79	{ KEX_DH14_SHA1, KEX_DH_GRP14_SHA1, 0, SSH_DIGEST_SHA1 },
80	{ KEX_DH14_SHA256, KEX_DH_GRP14_SHA256, 0, SSH_DIGEST_SHA256 },
81	{ KEX_DH16_SHA512, KEX_DH_GRP16_SHA512, 0, SSH_DIGEST_SHA512 },
82	{ KEX_DH18_SHA512, KEX_DH_GRP18_SHA512, 0, SSH_DIGEST_SHA512 },
83	{ KEX_DHGEX_SHA1, KEX_DH_GEX_SHA1, 0, SSH_DIGEST_SHA1 },
84	{ KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, SSH_DIGEST_SHA256 },
85	{ KEX_ECDH_SHA2_NISTP256, KEX_ECDH_SHA2,
86	    NID_X9_62_prime256v1, SSH_DIGEST_SHA256 },
87	{ KEX_ECDH_SHA2_NISTP384, KEX_ECDH_SHA2, NID_secp384r1,
88	    SSH_DIGEST_SHA384 },
89	{ KEX_ECDH_SHA2_NISTP521, KEX_ECDH_SHA2, NID_secp521r1,
90	    SSH_DIGEST_SHA512 },
91#endif
92	{ KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 },
93	{ KEX_CURVE25519_SHA256_OLD, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 },
94	{ NULL, -1, -1, -1},
95};
96
97char *
98kex_alg_list(char sep)
99{
100	char *ret = NULL, *tmp;
101	size_t nlen, rlen = 0;
102	const struct kexalg *k;
103
104	for (k = kexalgs; k->name != NULL; k++) {
105		if (ret != NULL)
106			ret[rlen++] = sep;
107		nlen = strlen(k->name);
108		if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) {
109			free(ret);
110			return NULL;
111		}
112		ret = tmp;
113		memcpy(ret + rlen, k->name, nlen + 1);
114		rlen += nlen;
115	}
116	return ret;
117}
118
119static const struct kexalg *
120kex_alg_by_name(const char *name)
121{
122	const struct kexalg *k;
123
124	for (k = kexalgs; k->name != NULL; k++) {
125		if (strcmp(k->name, name) == 0)
126			return k;
127	}
128	return NULL;
129}
130
131/* Validate KEX method name list */
132int
133kex_names_valid(const char *names)
134{
135	char *s, *cp, *p;
136
137	if (names == NULL || strcmp(names, "") == 0)
138		return 0;
139	if ((s = cp = strdup(names)) == NULL)
140		return 0;
141	for ((p = strsep(&cp, ",")); p && *p != '\0';
142	    (p = strsep(&cp, ","))) {
143		if (kex_alg_by_name(p) == NULL) {
144			error("Unsupported KEX algorithm \"%.100s\"", p);
145			free(s);
146			return 0;
147		}
148	}
149	debug3("kex names ok: [%s]", names);
150	free(s);
151	return 1;
152}
153
154/*
155 * Concatenate algorithm names, avoiding duplicates in the process.
156 * Caller must free returned string.
157 */
158char *
159kex_names_cat(const char *a, const char *b)
160{
161	char *ret = NULL, *tmp = NULL, *cp, *p, *m;
162	size_t len;
163
164	if (a == NULL || *a == '\0')
165		return NULL;
166	if (b == NULL || *b == '\0')
167		return strdup(a);
168	if (strlen(b) > 1024*1024)
169		return NULL;
170	len = strlen(a) + strlen(b) + 2;
171	if ((tmp = cp = strdup(b)) == NULL ||
172	    (ret = calloc(1, len)) == NULL) {
173		free(tmp);
174		return NULL;
175	}
176	strlcpy(ret, a, len);
177	for ((p = strsep(&cp, ",")); p && *p != '\0'; (p = strsep(&cp, ","))) {
178		if ((m = match_list(ret, p, NULL)) != NULL) {
179			free(m);
180			continue; /* Algorithm already present */
181		}
182		if (strlcat(ret, ",", len) >= len ||
183		    strlcat(ret, p, len) >= len) {
184			free(tmp);
185			free(ret);
186			return NULL; /* Shouldn't happen */
187		}
188	}
189	free(tmp);
190	return ret;
191}
192
193/*
194 * Assemble a list of algorithms from a default list and a string from a
195 * configuration file. The user-provided string may begin with '+' to
196 * indicate that it should be appended to the default or '-' that the
197 * specified names should be removed.
198 */
199int
200kex_assemble_names(const char *def, char **list)
201{
202	char *ret;
203
204	if (list == NULL || *list == NULL || **list == '\0') {
205		*list = strdup(def);
206		return 0;
207	}
208	if (**list == '+') {
209		if ((ret = kex_names_cat(def, *list + 1)) == NULL)
210			return SSH_ERR_ALLOC_FAIL;
211		free(*list);
212		*list = ret;
213	} else if (**list == '-') {
214		if ((ret = match_filter_list(def, *list + 1)) == NULL)
215			return SSH_ERR_ALLOC_FAIL;
216		free(*list);
217		*list = ret;
218	}
219
220	return 0;
221}
222
223/* put algorithm proposal into buffer */
224int
225kex_prop2buf(struct sshbuf *b, char *proposal[PROPOSAL_MAX])
226{
227	u_int i;
228	int r;
229
230	sshbuf_reset(b);
231
232	/*
233	 * add a dummy cookie, the cookie will be overwritten by
234	 * kex_send_kexinit(), each time a kexinit is set
235	 */
236	for (i = 0; i < KEX_COOKIE_LEN; i++) {
237		if ((r = sshbuf_put_u8(b, 0)) != 0)
238			return r;
239	}
240	for (i = 0; i < PROPOSAL_MAX; i++) {
241		if ((r = sshbuf_put_cstring(b, proposal[i])) != 0)
242			return r;
243	}
244	if ((r = sshbuf_put_u8(b, 0)) != 0 ||	/* first_kex_packet_follows */
245	    (r = sshbuf_put_u32(b, 0)) != 0)	/* uint32 reserved */
246		return r;
247	return 0;
248}
249
250/* parse buffer and return algorithm proposal */
251int
252kex_buf2prop(struct sshbuf *raw, int *first_kex_follows, char ***propp)
253{
254	struct sshbuf *b = NULL;
255	u_char v;
256	u_int i;
257	char **proposal = NULL;
258	int r;
259
260	*propp = NULL;
261	if ((proposal = calloc(PROPOSAL_MAX, sizeof(char *))) == NULL)
262		return SSH_ERR_ALLOC_FAIL;
263	if ((b = sshbuf_fromb(raw)) == NULL) {
264		r = SSH_ERR_ALLOC_FAIL;
265		goto out;
266	}
267	if ((r = sshbuf_consume(b, KEX_COOKIE_LEN)) != 0) /* skip cookie */
268		goto out;
269	/* extract kex init proposal strings */
270	for (i = 0; i < PROPOSAL_MAX; i++) {
271		if ((r = sshbuf_get_cstring(b, &(proposal[i]), NULL)) != 0)
272			goto out;
273		debug2("%s: %s", proposal_names[i], proposal[i]);
274	}
275	/* first kex follows / reserved */
276	if ((r = sshbuf_get_u8(b, &v)) != 0 ||	/* first_kex_follows */
277	    (r = sshbuf_get_u32(b, &i)) != 0)	/* reserved */
278		goto out;
279	if (first_kex_follows != NULL)
280		*first_kex_follows = v;
281	debug2("first_kex_follows %d ", v);
282	debug2("reserved %u ", i);
283	r = 0;
284	*propp = proposal;
285 out:
286	if (r != 0 && proposal != NULL)
287		kex_prop_free(proposal);
288	sshbuf_free(b);
289	return r;
290}
291
292void
293kex_prop_free(char **proposal)
294{
295	u_int i;
296
297	if (proposal == NULL)
298		return;
299	for (i = 0; i < PROPOSAL_MAX; i++)
300		free(proposal[i]);
301	free(proposal);
302}
303
304/* ARGSUSED */
305static int
306kex_protocol_error(int type, u_int32_t seq, struct ssh *ssh)
307{
308	int r;
309
310	error("kex protocol error: type %d seq %u", type, seq);
311	if ((r = sshpkt_start(ssh, SSH2_MSG_UNIMPLEMENTED)) != 0 ||
312	    (r = sshpkt_put_u32(ssh, seq)) != 0 ||
313	    (r = sshpkt_send(ssh)) != 0)
314		return r;
315	return 0;
316}
317
318static void
319kex_reset_dispatch(struct ssh *ssh)
320{
321	ssh_dispatch_range(ssh, SSH2_MSG_TRANSPORT_MIN,
322	    SSH2_MSG_TRANSPORT_MAX, &kex_protocol_error);
323}
324
325static int
326kex_send_ext_info(struct ssh *ssh)
327{
328	int r;
329	char *algs;
330
331	if ((algs = sshkey_alg_list(0, 1, 1, ',')) == NULL)
332		return SSH_ERR_ALLOC_FAIL;
333	/* XXX filter algs list by allowed pubkey/hostbased types */
334	if ((r = sshpkt_start(ssh, SSH2_MSG_EXT_INFO)) != 0 ||
335	    (r = sshpkt_put_u32(ssh, 1)) != 0 ||
336	    (r = sshpkt_put_cstring(ssh, "server-sig-algs")) != 0 ||
337	    (r = sshpkt_put_cstring(ssh, algs)) != 0 ||
338	    (r = sshpkt_send(ssh)) != 0)
339		goto out;
340	/* success */
341	r = 0;
342 out:
343	free(algs);
344	return r;
345}
346
347int
348kex_send_newkeys(struct ssh *ssh)
349{
350	int r;
351
352	kex_reset_dispatch(ssh);
353	if ((r = sshpkt_start(ssh, SSH2_MSG_NEWKEYS)) != 0 ||
354	    (r = sshpkt_send(ssh)) != 0)
355		return r;
356	debug("SSH2_MSG_NEWKEYS sent");
357	debug("expecting SSH2_MSG_NEWKEYS");
358	ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_input_newkeys);
359	if (ssh->kex->ext_info_c)
360		if ((r = kex_send_ext_info(ssh)) != 0)
361			return r;
362	return 0;
363}
364
365int
366kex_input_ext_info(int type, u_int32_t seq, struct ssh *ssh)
367{
368	struct kex *kex = ssh->kex;
369	u_int32_t i, ninfo;
370	char *name;
371	u_char *val;
372	size_t vlen;
373	int r;
374
375	debug("SSH2_MSG_EXT_INFO received");
376	ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, &kex_protocol_error);
377	if ((r = sshpkt_get_u32(ssh, &ninfo)) != 0)
378		return r;
379	for (i = 0; i < ninfo; i++) {
380		if ((r = sshpkt_get_cstring(ssh, &name, NULL)) != 0)
381			return r;
382		if ((r = sshpkt_get_string(ssh, &val, &vlen)) != 0) {
383			free(name);
384			return r;
385		}
386		if (strcmp(name, "server-sig-algs") == 0) {
387			/* Ensure no \0 lurking in value */
388			if (memchr(val, '\0', vlen) != NULL) {
389				error("%s: nul byte in %s", __func__, name);
390				return SSH_ERR_INVALID_FORMAT;
391			}
392			debug("%s: %s=<%s>", __func__, name, val);
393			kex->server_sig_algs = val;
394			val = NULL;
395		} else
396			debug("%s: %s (unrecognised)", __func__, name);
397		free(name);
398		free(val);
399	}
400	return sshpkt_get_end(ssh);
401}
402
403static int
404kex_input_newkeys(int type, u_int32_t seq, struct ssh *ssh)
405{
406	struct kex *kex = ssh->kex;
407	int r;
408
409	debug("SSH2_MSG_NEWKEYS received");
410	ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_protocol_error);
411	ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit);
412	if ((r = sshpkt_get_end(ssh)) != 0)
413		return r;
414	if ((r = ssh_set_newkeys(ssh, MODE_IN)) != 0)
415		return r;
416	kex->done = 1;
417	sshbuf_reset(kex->peer);
418	/* sshbuf_reset(kex->my); */
419	kex->flags &= ~KEX_INIT_SENT;
420	free(kex->name);
421	kex->name = NULL;
422	return 0;
423}
424
425int
426kex_send_kexinit(struct ssh *ssh)
427{
428	u_char *cookie;
429	struct kex *kex = ssh->kex;
430	int r;
431
432	if (kex == NULL)
433		return SSH_ERR_INTERNAL_ERROR;
434	if (kex->flags & KEX_INIT_SENT)
435		return 0;
436	kex->done = 0;
437
438	/* generate a random cookie */
439	if (sshbuf_len(kex->my) < KEX_COOKIE_LEN)
440		return SSH_ERR_INVALID_FORMAT;
441	if ((cookie = sshbuf_mutable_ptr(kex->my)) == NULL)
442		return SSH_ERR_INTERNAL_ERROR;
443	arc4random_buf(cookie, KEX_COOKIE_LEN);
444
445	if ((r = sshpkt_start(ssh, SSH2_MSG_KEXINIT)) != 0 ||
446	    (r = sshpkt_putb(ssh, kex->my)) != 0 ||
447	    (r = sshpkt_send(ssh)) != 0)
448		return r;
449	debug("SSH2_MSG_KEXINIT sent");
450	kex->flags |= KEX_INIT_SENT;
451	return 0;
452}
453
454/* ARGSUSED */
455int
456kex_input_kexinit(int type, u_int32_t seq, struct ssh *ssh)
457{
458	struct kex *kex = ssh->kex;
459	const u_char *ptr;
460	u_int i;
461	size_t dlen;
462	int r;
463
464	debug("SSH2_MSG_KEXINIT received");
465	if (kex == NULL)
466		return SSH_ERR_INVALID_ARGUMENT;
467
468	ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, NULL);
469	ptr = sshpkt_ptr(ssh, &dlen);
470	if ((r = sshbuf_put(kex->peer, ptr, dlen)) != 0)
471		return r;
472
473	/* discard packet */
474	for (i = 0; i < KEX_COOKIE_LEN; i++)
475		if ((r = sshpkt_get_u8(ssh, NULL)) != 0)
476			return r;
477	for (i = 0; i < PROPOSAL_MAX; i++)
478		if ((r = sshpkt_get_string(ssh, NULL, NULL)) != 0)
479			return r;
480	/*
481	 * XXX RFC4253 sec 7: "each side MAY guess" - currently no supported
482	 * KEX method has the server move first, but a server might be using
483	 * a custom method or one that we otherwise don't support. We should
484	 * be prepared to remember first_kex_follows here so we can eat a
485	 * packet later.
486	 * XXX2 - RFC4253 is kind of ambiguous on what first_kex_follows means
487	 * for cases where the server *doesn't* go first. I guess we should
488	 * ignore it when it is set for these cases, which is what we do now.
489	 */
490	if ((r = sshpkt_get_u8(ssh, NULL)) != 0 ||	/* first_kex_follows */
491	    (r = sshpkt_get_u32(ssh, NULL)) != 0 ||	/* reserved */
492	    (r = sshpkt_get_end(ssh)) != 0)
493			return r;
494
495	if (!(kex->flags & KEX_INIT_SENT))
496		if ((r = kex_send_kexinit(ssh)) != 0)
497			return r;
498	if ((r = kex_choose_conf(ssh)) != 0)
499		return r;
500
501	if (kex->kex_type < KEX_MAX && kex->kex[kex->kex_type] != NULL)
502		return (kex->kex[kex->kex_type])(ssh);
503
504	return SSH_ERR_INTERNAL_ERROR;
505}
506
507int
508kex_new(struct ssh *ssh, char *proposal[PROPOSAL_MAX], struct kex **kexp)
509{
510	struct kex *kex;
511	int r;
512
513	*kexp = NULL;
514	if ((kex = calloc(1, sizeof(*kex))) == NULL)
515		return SSH_ERR_ALLOC_FAIL;
516	if ((kex->peer = sshbuf_new()) == NULL ||
517	    (kex->my = sshbuf_new()) == NULL) {
518		r = SSH_ERR_ALLOC_FAIL;
519		goto out;
520	}
521	if ((r = kex_prop2buf(kex->my, proposal)) != 0)
522		goto out;
523	kex->done = 0;
524	kex_reset_dispatch(ssh);
525	ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit);
526	r = 0;
527	*kexp = kex;
528 out:
529	if (r != 0)
530		kex_free(kex);
531	return r;
532}
533
534void
535kex_free_newkeys(struct newkeys *newkeys)
536{
537	if (newkeys == NULL)
538		return;
539	if (newkeys->enc.key) {
540		explicit_bzero(newkeys->enc.key, newkeys->enc.key_len);
541		free(newkeys->enc.key);
542		newkeys->enc.key = NULL;
543	}
544	if (newkeys->enc.iv) {
545		explicit_bzero(newkeys->enc.iv, newkeys->enc.iv_len);
546		free(newkeys->enc.iv);
547		newkeys->enc.iv = NULL;
548	}
549	free(newkeys->enc.name);
550	explicit_bzero(&newkeys->enc, sizeof(newkeys->enc));
551	free(newkeys->comp.name);
552	explicit_bzero(&newkeys->comp, sizeof(newkeys->comp));
553	mac_clear(&newkeys->mac);
554	if (newkeys->mac.key) {
555		explicit_bzero(newkeys->mac.key, newkeys->mac.key_len);
556		free(newkeys->mac.key);
557		newkeys->mac.key = NULL;
558	}
559	free(newkeys->mac.name);
560	explicit_bzero(&newkeys->mac, sizeof(newkeys->mac));
561	explicit_bzero(newkeys, sizeof(*newkeys));
562	free(newkeys);
563}
564
565void
566kex_free(struct kex *kex)
567{
568	u_int mode;
569
570#ifdef WITH_OPENSSL
571	DH_free(kex->dh);
572	EC_KEY_free(kex->ec_client_key);
573#endif
574	for (mode = 0; mode < MODE_MAX; mode++) {
575		kex_free_newkeys(kex->newkeys[mode]);
576		kex->newkeys[mode] = NULL;
577	}
578	sshbuf_free(kex->peer);
579	sshbuf_free(kex->my);
580	free(kex->session_id);
581	free(kex->client_version_string);
582	free(kex->server_version_string);
583	free(kex->failed_choice);
584	free(kex->hostkey_alg);
585	free(kex->name);
586	free(kex);
587}
588
589int
590kex_setup(struct ssh *ssh, char *proposal[PROPOSAL_MAX])
591{
592	int r;
593
594	if ((r = kex_new(ssh, proposal, &ssh->kex)) != 0)
595		return r;
596	if ((r = kex_send_kexinit(ssh)) != 0) {		/* we start */
597		kex_free(ssh->kex);
598		ssh->kex = NULL;
599		return r;
600	}
601	return 0;
602}
603
604/*
605 * Request key re-exchange, returns 0 on success or a ssherr.h error
606 * code otherwise. Must not be called if KEX is incomplete or in-progress.
607 */
608int
609kex_start_rekex(struct ssh *ssh)
610{
611	if (ssh->kex == NULL) {
612		error("%s: no kex", __func__);
613		return SSH_ERR_INTERNAL_ERROR;
614	}
615	if (ssh->kex->done == 0) {
616		error("%s: requested twice", __func__);
617		return SSH_ERR_INTERNAL_ERROR;
618	}
619	ssh->kex->done = 0;
620	return kex_send_kexinit(ssh);
621}
622
623static int
624choose_enc(struct sshenc *enc, char *client, char *server)
625{
626	char *name = match_list(client, server, NULL);
627
628	if (name == NULL)
629		return SSH_ERR_NO_CIPHER_ALG_MATCH;
630	if ((enc->cipher = cipher_by_name(name)) == NULL) {
631		free(name);
632		return SSH_ERR_INTERNAL_ERROR;
633	}
634	enc->name = name;
635	enc->enabled = 0;
636	enc->iv = NULL;
637	enc->iv_len = cipher_ivlen(enc->cipher);
638	enc->key = NULL;
639	enc->key_len = cipher_keylen(enc->cipher);
640	enc->block_size = cipher_blocksize(enc->cipher);
641	return 0;
642}
643
644static int
645choose_mac(struct ssh *ssh, struct sshmac *mac, char *client, char *server)
646{
647	char *name = match_list(client, server, NULL);
648
649	if (name == NULL)
650		return SSH_ERR_NO_MAC_ALG_MATCH;
651	if (mac_setup(mac, name) < 0) {
652		free(name);
653		return SSH_ERR_INTERNAL_ERROR;
654	}
655	mac->name = name;
656	mac->key = NULL;
657	mac->enabled = 0;
658	return 0;
659}
660
661static int
662choose_comp(struct sshcomp *comp, char *client, char *server)
663{
664	char *name = match_list(client, server, NULL);
665
666	if (name == NULL)
667		return SSH_ERR_NO_COMPRESS_ALG_MATCH;
668	if (strcmp(name, "zlib@openssh.com") == 0) {
669		comp->type = COMP_DELAYED;
670	} else if (strcmp(name, "zlib") == 0) {
671		comp->type = COMP_ZLIB;
672	} else if (strcmp(name, "none") == 0) {
673		comp->type = COMP_NONE;
674	} else {
675		free(name);
676		return SSH_ERR_INTERNAL_ERROR;
677	}
678	comp->name = name;
679	return 0;
680}
681
682static int
683choose_kex(struct kex *k, char *client, char *server)
684{
685	const struct kexalg *kexalg;
686
687	k->name = match_list(client, server, NULL);
688
689	debug("kex: algorithm: %s", k->name ? k->name : "(no match)");
690	if (k->name == NULL)
691		return SSH_ERR_NO_KEX_ALG_MATCH;
692	if ((kexalg = kex_alg_by_name(k->name)) == NULL)
693		return SSH_ERR_INTERNAL_ERROR;
694	k->kex_type = kexalg->type;
695	k->hash_alg = kexalg->hash_alg;
696	k->ec_nid = kexalg->ec_nid;
697	return 0;
698}
699
700static int
701choose_hostkeyalg(struct kex *k, char *client, char *server)
702{
703	k->hostkey_alg = match_list(client, server, NULL);
704
705	debug("kex: host key algorithm: %s",
706	    k->hostkey_alg ? k->hostkey_alg : "(no match)");
707	if (k->hostkey_alg == NULL)
708		return SSH_ERR_NO_HOSTKEY_ALG_MATCH;
709	k->hostkey_type = sshkey_type_from_name(k->hostkey_alg);
710	if (k->hostkey_type == KEY_UNSPEC)
711		return SSH_ERR_INTERNAL_ERROR;
712	k->hostkey_nid = sshkey_ecdsa_nid_from_name(k->hostkey_alg);
713	return 0;
714}
715
716static int
717proposals_match(char *my[PROPOSAL_MAX], char *peer[PROPOSAL_MAX])
718{
719	static int check[] = {
720		PROPOSAL_KEX_ALGS, PROPOSAL_SERVER_HOST_KEY_ALGS, -1
721	};
722	int *idx;
723	char *p;
724
725	for (idx = &check[0]; *idx != -1; idx++) {
726		if ((p = strchr(my[*idx], ',')) != NULL)
727			*p = '\0';
728		if ((p = strchr(peer[*idx], ',')) != NULL)
729			*p = '\0';
730		if (strcmp(my[*idx], peer[*idx]) != 0) {
731			debug2("proposal mismatch: my %s peer %s",
732			    my[*idx], peer[*idx]);
733			return (0);
734		}
735	}
736	debug2("proposals match");
737	return (1);
738}
739
740static int
741kex_choose_conf(struct ssh *ssh)
742{
743	struct kex *kex = ssh->kex;
744	struct newkeys *newkeys;
745	char **my = NULL, **peer = NULL;
746	char **cprop, **sprop;
747	int nenc, nmac, ncomp;
748	u_int mode, ctos, need, dh_need, authlen;
749	int r, first_kex_follows;
750
751	debug2("local %s KEXINIT proposal", kex->server ? "server" : "client");
752	if ((r = kex_buf2prop(kex->my, NULL, &my)) != 0)
753		goto out;
754	debug2("peer %s KEXINIT proposal", kex->server ? "client" : "server");
755	if ((r = kex_buf2prop(kex->peer, &first_kex_follows, &peer)) != 0)
756		goto out;
757
758	if (kex->server) {
759		cprop=peer;
760		sprop=my;
761	} else {
762		cprop=my;
763		sprop=peer;
764	}
765
766	/* Check whether client supports ext_info_c */
767	if (kex->server) {
768		char *ext;
769
770		ext = match_list("ext-info-c", peer[PROPOSAL_KEX_ALGS], NULL);
771		kex->ext_info_c = (ext != NULL);
772		free(ext);
773	}
774
775	/* Algorithm Negotiation */
776	if ((r = choose_kex(kex, cprop[PROPOSAL_KEX_ALGS],
777	    sprop[PROPOSAL_KEX_ALGS])) != 0) {
778		kex->failed_choice = peer[PROPOSAL_KEX_ALGS];
779		peer[PROPOSAL_KEX_ALGS] = NULL;
780		goto out;
781	}
782	if ((r = choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS],
783	    sprop[PROPOSAL_SERVER_HOST_KEY_ALGS])) != 0) {
784		kex->failed_choice = peer[PROPOSAL_SERVER_HOST_KEY_ALGS];
785		peer[PROPOSAL_SERVER_HOST_KEY_ALGS] = NULL;
786		goto out;
787	}
788	for (mode = 0; mode < MODE_MAX; mode++) {
789		if ((newkeys = calloc(1, sizeof(*newkeys))) == NULL) {
790			r = SSH_ERR_ALLOC_FAIL;
791			goto out;
792		}
793		kex->newkeys[mode] = newkeys;
794		ctos = (!kex->server && mode == MODE_OUT) ||
795		    (kex->server && mode == MODE_IN);
796		nenc  = ctos ? PROPOSAL_ENC_ALGS_CTOS  : PROPOSAL_ENC_ALGS_STOC;
797		nmac  = ctos ? PROPOSAL_MAC_ALGS_CTOS  : PROPOSAL_MAC_ALGS_STOC;
798		ncomp = ctos ? PROPOSAL_COMP_ALGS_CTOS : PROPOSAL_COMP_ALGS_STOC;
799		if ((r = choose_enc(&newkeys->enc, cprop[nenc],
800		    sprop[nenc])) != 0) {
801			kex->failed_choice = peer[nenc];
802			peer[nenc] = NULL;
803			goto out;
804		}
805		authlen = cipher_authlen(newkeys->enc.cipher);
806		/* ignore mac for authenticated encryption */
807		if (authlen == 0 &&
808		    (r = choose_mac(ssh, &newkeys->mac, cprop[nmac],
809		    sprop[nmac])) != 0) {
810			kex->failed_choice = peer[nmac];
811			peer[nmac] = NULL;
812			goto out;
813		}
814		if ((r = choose_comp(&newkeys->comp, cprop[ncomp],
815		    sprop[ncomp])) != 0) {
816			kex->failed_choice = peer[ncomp];
817			peer[ncomp] = NULL;
818			goto out;
819		}
820		debug("kex: %s cipher: %s MAC: %s compression: %s",
821		    ctos ? "client->server" : "server->client",
822		    newkeys->enc.name,
823		    authlen == 0 ? newkeys->mac.name : "<implicit>",
824		    newkeys->comp.name);
825	}
826	need = dh_need = 0;
827	for (mode = 0; mode < MODE_MAX; mode++) {
828		newkeys = kex->newkeys[mode];
829		need = MAXIMUM(need, newkeys->enc.key_len);
830		need = MAXIMUM(need, newkeys->enc.block_size);
831		need = MAXIMUM(need, newkeys->enc.iv_len);
832		need = MAXIMUM(need, newkeys->mac.key_len);
833		dh_need = MAXIMUM(dh_need, cipher_seclen(newkeys->enc.cipher));
834		dh_need = MAXIMUM(dh_need, newkeys->enc.block_size);
835		dh_need = MAXIMUM(dh_need, newkeys->enc.iv_len);
836		dh_need = MAXIMUM(dh_need, newkeys->mac.key_len);
837	}
838	/* XXX need runden? */
839	kex->we_need = need;
840	kex->dh_need = dh_need;
841
842	/* ignore the next message if the proposals do not match */
843	if (first_kex_follows && !proposals_match(my, peer))
844		ssh->dispatch_skip_packets = 1;
845	r = 0;
846 out:
847	kex_prop_free(my);
848	kex_prop_free(peer);
849	return r;
850}
851
852static int
853derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen,
854    const struct sshbuf *shared_secret, u_char **keyp)
855{
856	struct kex *kex = ssh->kex;
857	struct ssh_digest_ctx *hashctx = NULL;
858	char c = id;
859	u_int have;
860	size_t mdsz;
861	u_char *digest;
862	int r;
863
864	if ((mdsz = ssh_digest_bytes(kex->hash_alg)) == 0)
865		return SSH_ERR_INVALID_ARGUMENT;
866	if ((digest = calloc(1, ROUNDUP(need, mdsz))) == NULL) {
867		r = SSH_ERR_ALLOC_FAIL;
868		goto out;
869	}
870
871	/* K1 = HASH(K || H || "A" || session_id) */
872	if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL ||
873	    ssh_digest_update_buffer(hashctx, shared_secret) != 0 ||
874	    ssh_digest_update(hashctx, hash, hashlen) != 0 ||
875	    ssh_digest_update(hashctx, &c, 1) != 0 ||
876	    ssh_digest_update(hashctx, kex->session_id,
877	    kex->session_id_len) != 0 ||
878	    ssh_digest_final(hashctx, digest, mdsz) != 0) {
879		r = SSH_ERR_LIBCRYPTO_ERROR;
880		goto out;
881	}
882	ssh_digest_free(hashctx);
883	hashctx = NULL;
884
885	/*
886	 * expand key:
887	 * Kn = HASH(K || H || K1 || K2 || ... || Kn-1)
888	 * Key = K1 || K2 || ... || Kn
889	 */
890	for (have = mdsz; need > have; have += mdsz) {
891		if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL ||
892		    ssh_digest_update_buffer(hashctx, shared_secret) != 0 ||
893		    ssh_digest_update(hashctx, hash, hashlen) != 0 ||
894		    ssh_digest_update(hashctx, digest, have) != 0 ||
895		    ssh_digest_final(hashctx, digest + have, mdsz) != 0) {
896			r = SSH_ERR_LIBCRYPTO_ERROR;
897			goto out;
898		}
899		ssh_digest_free(hashctx);
900		hashctx = NULL;
901	}
902#ifdef DEBUG_KEX
903	fprintf(stderr, "key '%c'== ", c);
904	dump_digest("key", digest, need);
905#endif
906	*keyp = digest;
907	digest = NULL;
908	r = 0;
909 out:
910	free(digest);
911	ssh_digest_free(hashctx);
912	return r;
913}
914
915#define NKEYS	6
916int
917kex_derive_keys(struct ssh *ssh, u_char *hash, u_int hashlen,
918    const struct sshbuf *shared_secret)
919{
920	struct kex *kex = ssh->kex;
921	u_char *keys[NKEYS];
922	u_int i, j, mode, ctos;
923	int r;
924
925	for (i = 0; i < NKEYS; i++) {
926		if ((r = derive_key(ssh, 'A'+i, kex->we_need, hash, hashlen,
927		    shared_secret, &keys[i])) != 0) {
928			for (j = 0; j < i; j++)
929				free(keys[j]);
930			return r;
931		}
932	}
933	for (mode = 0; mode < MODE_MAX; mode++) {
934		ctos = (!kex->server && mode == MODE_OUT) ||
935		    (kex->server && mode == MODE_IN);
936		kex->newkeys[mode]->enc.iv  = keys[ctos ? 0 : 1];
937		kex->newkeys[mode]->enc.key = keys[ctos ? 2 : 3];
938		kex->newkeys[mode]->mac.key = keys[ctos ? 4 : 5];
939	}
940	return 0;
941}
942
943#ifdef WITH_OPENSSL
944int
945kex_derive_keys_bn(struct ssh *ssh, u_char *hash, u_int hashlen,
946    const BIGNUM *secret)
947{
948	struct sshbuf *shared_secret;
949	int r;
950
951	if ((shared_secret = sshbuf_new()) == NULL)
952		return SSH_ERR_ALLOC_FAIL;
953	if ((r = sshbuf_put_bignum2(shared_secret, secret)) == 0)
954		r = kex_derive_keys(ssh, hash, hashlen, shared_secret);
955	sshbuf_free(shared_secret);
956	return r;
957}
958#endif
959
960
961#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH)
962void
963dump_digest(char *msg, u_char *digest, int len)
964{
965	fprintf(stderr, "%s\n", msg);
966	sshbuf_dump_data(digest, len, stderr);
967}
968#endif
969