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