xref: /freebsd/crypto/openssh/kex.c (revision 557f75e54ae47df936c7de8fb97ec70c4180a5c0)
1 /* $OpenBSD: kex.c,v 1.106 2015/04/17 13:25:52 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 "includes.h"
27 
28 #include <sys/param.h>	/* MAX roundup */
29 
30 #include <signal.h>
31 #include <stdarg.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 
36 #ifdef WITH_OPENSSL
37 #include <openssl/crypto.h>
38 #endif
39 
40 #include "ssh2.h"
41 #include "packet.h"
42 #include "compat.h"
43 #include "cipher.h"
44 #include "sshkey.h"
45 #include "kex.h"
46 #include "log.h"
47 #include "mac.h"
48 #include "match.h"
49 #include "misc.h"
50 #include "dispatch.h"
51 #include "monitor.h"
52 #include "roaming.h"
53 
54 #include "ssherr.h"
55 #include "sshbuf.h"
56 #include "digest.h"
57 
58 #if OPENSSL_VERSION_NUMBER >= 0x00907000L
59 # if defined(HAVE_EVP_SHA256)
60 # define evp_ssh_sha256 EVP_sha256
61 # else
62 extern const EVP_MD *evp_ssh_sha256(void);
63 # endif
64 #endif
65 
66 /* prototype */
67 static int kex_choose_conf(struct ssh *);
68 static int kex_input_newkeys(int, u_int32_t, void *);
69 
70 struct kexalg {
71 	char *name;
72 	u_int type;
73 	int ec_nid;
74 	int hash_alg;
75 };
76 static const struct kexalg kexalgs[] = {
77 #ifdef WITH_OPENSSL
78 	{ KEX_DH1, KEX_DH_GRP1_SHA1, 0, SSH_DIGEST_SHA1 },
79 	{ KEX_DH14, KEX_DH_GRP14_SHA1, 0, SSH_DIGEST_SHA1 },
80 	{ KEX_DHGEX_SHA1, KEX_DH_GEX_SHA1, 0, SSH_DIGEST_SHA1 },
81 #ifdef HAVE_EVP_SHA256
82 	{ KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, SSH_DIGEST_SHA256 },
83 #endif /* HAVE_EVP_SHA256 */
84 #ifdef OPENSSL_HAS_ECC
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 # ifdef OPENSSL_HAS_NISTP521
90 	{ KEX_ECDH_SHA2_NISTP521, KEX_ECDH_SHA2, NID_secp521r1,
91 	    SSH_DIGEST_SHA512 },
92 # endif /* OPENSSL_HAS_NISTP521 */
93 #endif /* OPENSSL_HAS_ECC */
94 #endif /* WITH_OPENSSL */
95 #if defined(HAVE_EVP_SHA256) || !defined(WITH_OPENSSL)
96 	{ KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 },
97 #endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */
98 	{ NULL, -1, -1, -1},
99 };
100 
101 char *
102 kex_alg_list(char sep)
103 {
104 	char *ret = NULL, *tmp;
105 	size_t nlen, rlen = 0;
106 	const struct kexalg *k;
107 
108 	for (k = kexalgs; k->name != NULL; k++) {
109 		if (ret != NULL)
110 			ret[rlen++] = sep;
111 		nlen = strlen(k->name);
112 		if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) {
113 			free(ret);
114 			return NULL;
115 		}
116 		ret = tmp;
117 		memcpy(ret + rlen, k->name, nlen + 1);
118 		rlen += nlen;
119 	}
120 	return ret;
121 }
122 
123 static const struct kexalg *
124 kex_alg_by_name(const char *name)
125 {
126 	const struct kexalg *k;
127 
128 	for (k = kexalgs; k->name != NULL; k++) {
129 		if (strcmp(k->name, name) == 0)
130 			return k;
131 	}
132 	return NULL;
133 }
134 
135 /* Validate KEX method name list */
136 int
137 kex_names_valid(const char *names)
138 {
139 	char *s, *cp, *p;
140 
141 	if (names == NULL || strcmp(names, "") == 0)
142 		return 0;
143 	if ((s = cp = strdup(names)) == NULL)
144 		return 0;
145 	for ((p = strsep(&cp, ",")); p && *p != '\0';
146 	    (p = strsep(&cp, ","))) {
147 		if (kex_alg_by_name(p) == NULL) {
148 			error("Unsupported KEX algorithm \"%.100s\"", p);
149 			free(s);
150 			return 0;
151 		}
152 	}
153 	debug3("kex names ok: [%s]", names);
154 	free(s);
155 	return 1;
156 }
157 
158 /* put algorithm proposal into buffer */
159 int
160 kex_prop2buf(struct sshbuf *b, char *proposal[PROPOSAL_MAX])
161 {
162 	u_int i;
163 	int r;
164 
165 	sshbuf_reset(b);
166 
167 	/*
168 	 * add a dummy cookie, the cookie will be overwritten by
169 	 * kex_send_kexinit(), each time a kexinit is set
170 	 */
171 	for (i = 0; i < KEX_COOKIE_LEN; i++) {
172 		if ((r = sshbuf_put_u8(b, 0)) != 0)
173 			return r;
174 	}
175 	for (i = 0; i < PROPOSAL_MAX; i++) {
176 		if ((r = sshbuf_put_cstring(b, proposal[i])) != 0)
177 			return r;
178 	}
179 	if ((r = sshbuf_put_u8(b, 0)) != 0 ||	/* first_kex_packet_follows */
180 	    (r = sshbuf_put_u32(b, 0)) != 0)	/* uint32 reserved */
181 		return r;
182 	return 0;
183 }
184 
185 /* parse buffer and return algorithm proposal */
186 int
187 kex_buf2prop(struct sshbuf *raw, int *first_kex_follows, char ***propp)
188 {
189 	struct sshbuf *b = NULL;
190 	u_char v;
191 	u_int i;
192 	char **proposal = NULL;
193 	int r;
194 
195 	*propp = NULL;
196 	if ((proposal = calloc(PROPOSAL_MAX, sizeof(char *))) == NULL)
197 		return SSH_ERR_ALLOC_FAIL;
198 	if ((b = sshbuf_fromb(raw)) == NULL) {
199 		r = SSH_ERR_ALLOC_FAIL;
200 		goto out;
201 	}
202 	if ((r = sshbuf_consume(b, KEX_COOKIE_LEN)) != 0) /* skip cookie */
203 		goto out;
204 	/* extract kex init proposal strings */
205 	for (i = 0; i < PROPOSAL_MAX; i++) {
206 		if ((r = sshbuf_get_cstring(b, &(proposal[i]), NULL)) != 0)
207 			goto out;
208 		debug2("kex_parse_kexinit: %s", proposal[i]);
209 	}
210 	/* first kex follows / reserved */
211 	if ((r = sshbuf_get_u8(b, &v)) != 0 ||
212 	    (r = sshbuf_get_u32(b, &i)) != 0)
213 		goto out;
214 	if (first_kex_follows != NULL)
215 		*first_kex_follows = i;
216 	debug2("kex_parse_kexinit: first_kex_follows %d ", v);
217 	debug2("kex_parse_kexinit: reserved %u ", i);
218 	r = 0;
219 	*propp = proposal;
220  out:
221 	if (r != 0 && proposal != NULL)
222 		kex_prop_free(proposal);
223 	sshbuf_free(b);
224 	return r;
225 }
226 
227 void
228 kex_prop_free(char **proposal)
229 {
230 	u_int i;
231 
232 	if (proposal == NULL)
233 		return;
234 	for (i = 0; i < PROPOSAL_MAX; i++)
235 		free(proposal[i]);
236 	free(proposal);
237 }
238 
239 /* ARGSUSED */
240 static int
241 kex_protocol_error(int type, u_int32_t seq, void *ctxt)
242 {
243 	error("Hm, kex protocol error: type %d seq %u", type, seq);
244 	return 0;
245 }
246 
247 static void
248 kex_reset_dispatch(struct ssh *ssh)
249 {
250 	ssh_dispatch_range(ssh, SSH2_MSG_TRANSPORT_MIN,
251 	    SSH2_MSG_TRANSPORT_MAX, &kex_protocol_error);
252 	ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit);
253 }
254 
255 int
256 kex_send_newkeys(struct ssh *ssh)
257 {
258 	int r;
259 
260 	kex_reset_dispatch(ssh);
261 	if ((r = sshpkt_start(ssh, SSH2_MSG_NEWKEYS)) != 0 ||
262 	    (r = sshpkt_send(ssh)) != 0)
263 		return r;
264 	debug("SSH2_MSG_NEWKEYS sent");
265 	debug("expecting SSH2_MSG_NEWKEYS");
266 	ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_input_newkeys);
267 	return 0;
268 }
269 
270 static int
271 kex_input_newkeys(int type, u_int32_t seq, void *ctxt)
272 {
273 	struct ssh *ssh = ctxt;
274 	struct kex *kex = ssh->kex;
275 	int r;
276 
277 	debug("SSH2_MSG_NEWKEYS received");
278 	ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_protocol_error);
279 	if ((r = sshpkt_get_end(ssh)) != 0)
280 		return r;
281 	kex->done = 1;
282 	sshbuf_reset(kex->peer);
283 	/* sshbuf_reset(kex->my); */
284 	kex->flags &= ~KEX_INIT_SENT;
285 	free(kex->name);
286 	kex->name = NULL;
287 	return 0;
288 }
289 
290 int
291 kex_send_kexinit(struct ssh *ssh)
292 {
293 	u_char *cookie;
294 	struct kex *kex = ssh->kex;
295 	int r;
296 
297 	if (kex == NULL)
298 		return SSH_ERR_INTERNAL_ERROR;
299 	if (kex->flags & KEX_INIT_SENT)
300 		return 0;
301 	kex->done = 0;
302 
303 	/* generate a random cookie */
304 	if (sshbuf_len(kex->my) < KEX_COOKIE_LEN)
305 		return SSH_ERR_INVALID_FORMAT;
306 	if ((cookie = sshbuf_mutable_ptr(kex->my)) == NULL)
307 		return SSH_ERR_INTERNAL_ERROR;
308 	arc4random_buf(cookie, KEX_COOKIE_LEN);
309 
310 	if ((r = sshpkt_start(ssh, SSH2_MSG_KEXINIT)) != 0 ||
311 	    (r = sshpkt_putb(ssh, kex->my)) != 0 ||
312 	    (r = sshpkt_send(ssh)) != 0)
313 		return r;
314 	debug("SSH2_MSG_KEXINIT sent");
315 	kex->flags |= KEX_INIT_SENT;
316 	return 0;
317 }
318 
319 /* ARGSUSED */
320 int
321 kex_input_kexinit(int type, u_int32_t seq, void *ctxt)
322 {
323 	struct ssh *ssh = ctxt;
324 	struct kex *kex = ssh->kex;
325 	const u_char *ptr;
326 	u_int i;
327 	size_t dlen;
328 	int r;
329 
330 	debug("SSH2_MSG_KEXINIT received");
331 	if (kex == NULL)
332 		return SSH_ERR_INVALID_ARGUMENT;
333 
334 	ptr = sshpkt_ptr(ssh, &dlen);
335 	if ((r = sshbuf_put(kex->peer, ptr, dlen)) != 0)
336 		return r;
337 
338 	/* discard packet */
339 	for (i = 0; i < KEX_COOKIE_LEN; i++)
340 		if ((r = sshpkt_get_u8(ssh, NULL)) != 0)
341 			return r;
342 	for (i = 0; i < PROPOSAL_MAX; i++)
343 		if ((r = sshpkt_get_string(ssh, NULL, NULL)) != 0)
344 			return r;
345 	/*
346 	 * XXX RFC4253 sec 7: "each side MAY guess" - currently no supported
347 	 * KEX method has the server move first, but a server might be using
348 	 * a custom method or one that we otherwise don't support. We should
349 	 * be prepared to remember first_kex_follows here so we can eat a
350 	 * packet later.
351 	 * XXX2 - RFC4253 is kind of ambiguous on what first_kex_follows means
352 	 * for cases where the server *doesn't* go first. I guess we should
353 	 * ignore it when it is set for these cases, which is what we do now.
354 	 */
355 	if ((r = sshpkt_get_u8(ssh, NULL)) != 0 ||	/* first_kex_follows */
356 	    (r = sshpkt_get_u32(ssh, NULL)) != 0 ||	/* reserved */
357 	    (r = sshpkt_get_end(ssh)) != 0)
358 			return r;
359 
360 	if (!(kex->flags & KEX_INIT_SENT))
361 		if ((r = kex_send_kexinit(ssh)) != 0)
362 			return r;
363 	if ((r = kex_choose_conf(ssh)) != 0)
364 		return r;
365 
366 	if (kex->kex_type < KEX_MAX && kex->kex[kex->kex_type] != NULL)
367 		return (kex->kex[kex->kex_type])(ssh);
368 
369 	return SSH_ERR_INTERNAL_ERROR;
370 }
371 
372 int
373 kex_new(struct ssh *ssh, char *proposal[PROPOSAL_MAX], struct kex **kexp)
374 {
375 	struct kex *kex;
376 	int r;
377 
378 	*kexp = NULL;
379 	if ((kex = calloc(1, sizeof(*kex))) == NULL)
380 		return SSH_ERR_ALLOC_FAIL;
381 	if ((kex->peer = sshbuf_new()) == NULL ||
382 	    (kex->my = sshbuf_new()) == NULL) {
383 		r = SSH_ERR_ALLOC_FAIL;
384 		goto out;
385 	}
386 	if ((r = kex_prop2buf(kex->my, proposal)) != 0)
387 		goto out;
388 	kex->done = 0;
389 	kex_reset_dispatch(ssh);
390 	r = 0;
391 	*kexp = kex;
392  out:
393 	if (r != 0)
394 		kex_free(kex);
395 	return r;
396 }
397 
398 void
399 kex_free_newkeys(struct newkeys *newkeys)
400 {
401 	if (newkeys == NULL)
402 		return;
403 	if (newkeys->enc.key) {
404 		explicit_bzero(newkeys->enc.key, newkeys->enc.key_len);
405 		free(newkeys->enc.key);
406 		newkeys->enc.key = NULL;
407 	}
408 	if (newkeys->enc.iv) {
409 		explicit_bzero(newkeys->enc.iv, newkeys->enc.block_size);
410 		free(newkeys->enc.iv);
411 		newkeys->enc.iv = NULL;
412 	}
413 	free(newkeys->enc.name);
414 	explicit_bzero(&newkeys->enc, sizeof(newkeys->enc));
415 	free(newkeys->comp.name);
416 	explicit_bzero(&newkeys->comp, sizeof(newkeys->comp));
417 	mac_clear(&newkeys->mac);
418 	if (newkeys->mac.key) {
419 		explicit_bzero(newkeys->mac.key, newkeys->mac.key_len);
420 		free(newkeys->mac.key);
421 		newkeys->mac.key = NULL;
422 	}
423 	free(newkeys->mac.name);
424 	explicit_bzero(&newkeys->mac, sizeof(newkeys->mac));
425 	explicit_bzero(newkeys, sizeof(*newkeys));
426 	free(newkeys);
427 }
428 
429 void
430 kex_free(struct kex *kex)
431 {
432 	u_int mode;
433 
434 #ifdef WITH_OPENSSL
435 	if (kex->dh)
436 		DH_free(kex->dh);
437 #ifdef OPENSSL_HAS_ECC
438 	if (kex->ec_client_key)
439 		EC_KEY_free(kex->ec_client_key);
440 #endif /* OPENSSL_HAS_ECC */
441 #endif /* WITH_OPENSSL */
442 	for (mode = 0; mode < MODE_MAX; mode++) {
443 		kex_free_newkeys(kex->newkeys[mode]);
444 		kex->newkeys[mode] = NULL;
445 	}
446 	sshbuf_free(kex->peer);
447 	sshbuf_free(kex->my);
448 	free(kex->session_id);
449 	free(kex->client_version_string);
450 	free(kex->server_version_string);
451 	free(kex);
452 }
453 
454 int
455 kex_setup(struct ssh *ssh, char *proposal[PROPOSAL_MAX])
456 {
457 	int r;
458 
459 	if ((r = kex_new(ssh, proposal, &ssh->kex)) != 0)
460 		return r;
461 	if ((r = kex_send_kexinit(ssh)) != 0) {		/* we start */
462 		kex_free(ssh->kex);
463 		ssh->kex = NULL;
464 		return r;
465 	}
466 	return 0;
467 }
468 
469 static int
470 choose_enc(struct sshenc *enc, char *client, char *server)
471 {
472 	char *name = match_list(client, server, NULL);
473 
474 	if (name == NULL)
475 		return SSH_ERR_NO_CIPHER_ALG_MATCH;
476 	if ((enc->cipher = cipher_by_name(name)) == NULL)
477 		return SSH_ERR_INTERNAL_ERROR;
478 	enc->name = name;
479 	enc->enabled = 0;
480 	enc->iv = NULL;
481 	enc->iv_len = cipher_ivlen(enc->cipher);
482 	enc->key = NULL;
483 	enc->key_len = cipher_keylen(enc->cipher);
484 	enc->block_size = cipher_blocksize(enc->cipher);
485 	return 0;
486 }
487 
488 static int
489 choose_mac(struct ssh *ssh, struct sshmac *mac, char *client, char *server)
490 {
491 	char *name = match_list(client, server, NULL);
492 
493 	if (name == NULL)
494 		return SSH_ERR_NO_MAC_ALG_MATCH;
495 	if (mac_setup(mac, name) < 0)
496 		return SSH_ERR_INTERNAL_ERROR;
497 	/* truncate the key */
498 	if (ssh->compat & SSH_BUG_HMAC)
499 		mac->key_len = 16;
500 	mac->name = name;
501 	mac->key = NULL;
502 	mac->enabled = 0;
503 	return 0;
504 }
505 
506 static int
507 choose_comp(struct sshcomp *comp, char *client, char *server)
508 {
509 	char *name = match_list(client, server, NULL);
510 
511 	if (name == NULL)
512 		return SSH_ERR_NO_COMPRESS_ALG_MATCH;
513 	if (strcmp(name, "zlib@openssh.com") == 0) {
514 		comp->type = COMP_DELAYED;
515 	} else if (strcmp(name, "zlib") == 0) {
516 		comp->type = COMP_ZLIB;
517 	} else if (strcmp(name, "none") == 0) {
518 		comp->type = COMP_NONE;
519 	} else {
520 		return SSH_ERR_INTERNAL_ERROR;
521 	}
522 	comp->name = name;
523 	return 0;
524 }
525 
526 static int
527 choose_kex(struct kex *k, char *client, char *server)
528 {
529 	const struct kexalg *kexalg;
530 
531 	k->name = match_list(client, server, NULL);
532 
533 	if (k->name == NULL)
534 		return SSH_ERR_NO_KEX_ALG_MATCH;
535 	if ((kexalg = kex_alg_by_name(k->name)) == NULL)
536 		return SSH_ERR_INTERNAL_ERROR;
537 	k->kex_type = kexalg->type;
538 	k->hash_alg = kexalg->hash_alg;
539 	k->ec_nid = kexalg->ec_nid;
540 	return 0;
541 }
542 
543 static int
544 choose_hostkeyalg(struct kex *k, char *client, char *server)
545 {
546 	char *hostkeyalg = match_list(client, server, NULL);
547 
548 	if (hostkeyalg == NULL)
549 		return SSH_ERR_NO_HOSTKEY_ALG_MATCH;
550 	k->hostkey_type = sshkey_type_from_name(hostkeyalg);
551 	if (k->hostkey_type == KEY_UNSPEC)
552 		return SSH_ERR_INTERNAL_ERROR;
553 	k->hostkey_nid = sshkey_ecdsa_nid_from_name(hostkeyalg);
554 	free(hostkeyalg);
555 	return 0;
556 }
557 
558 static int
559 proposals_match(char *my[PROPOSAL_MAX], char *peer[PROPOSAL_MAX])
560 {
561 	static int check[] = {
562 		PROPOSAL_KEX_ALGS, PROPOSAL_SERVER_HOST_KEY_ALGS, -1
563 	};
564 	int *idx;
565 	char *p;
566 
567 	for (idx = &check[0]; *idx != -1; idx++) {
568 		if ((p = strchr(my[*idx], ',')) != NULL)
569 			*p = '\0';
570 		if ((p = strchr(peer[*idx], ',')) != NULL)
571 			*p = '\0';
572 		if (strcmp(my[*idx], peer[*idx]) != 0) {
573 			debug2("proposal mismatch: my %s peer %s",
574 			    my[*idx], peer[*idx]);
575 			return (0);
576 		}
577 	}
578 	debug2("proposals match");
579 	return (1);
580 }
581 
582 static int
583 kex_choose_conf(struct ssh *ssh)
584 {
585 	struct kex *kex = ssh->kex;
586 	struct newkeys *newkeys;
587 	char **my = NULL, **peer = NULL;
588 	char **cprop, **sprop;
589 	int nenc, nmac, ncomp;
590 	u_int mode, ctos, need, dh_need, authlen;
591 	int r, first_kex_follows;
592 
593 	if ((r = kex_buf2prop(kex->my, NULL, &my)) != 0 ||
594 	    (r = kex_buf2prop(kex->peer, &first_kex_follows, &peer)) != 0)
595 		goto out;
596 
597 	if (kex->server) {
598 		cprop=peer;
599 		sprop=my;
600 	} else {
601 		cprop=my;
602 		sprop=peer;
603 	}
604 
605 	/* Check whether server offers roaming */
606 	if (!kex->server) {
607 		char *roaming = match_list(KEX_RESUME,
608 		    peer[PROPOSAL_KEX_ALGS], NULL);
609 
610 		if (roaming) {
611 			kex->roaming = 1;
612 			free(roaming);
613 		}
614 	}
615 
616 	/* Algorithm Negotiation */
617 	for (mode = 0; mode < MODE_MAX; mode++) {
618 		if ((newkeys = calloc(1, sizeof(*newkeys))) == NULL) {
619 			r = SSH_ERR_ALLOC_FAIL;
620 			goto out;
621 		}
622 		kex->newkeys[mode] = newkeys;
623 		ctos = (!kex->server && mode == MODE_OUT) ||
624 		    (kex->server && mode == MODE_IN);
625 		nenc  = ctos ? PROPOSAL_ENC_ALGS_CTOS  : PROPOSAL_ENC_ALGS_STOC;
626 		nmac  = ctos ? PROPOSAL_MAC_ALGS_CTOS  : PROPOSAL_MAC_ALGS_STOC;
627 		ncomp = ctos ? PROPOSAL_COMP_ALGS_CTOS : PROPOSAL_COMP_ALGS_STOC;
628 		if ((r = choose_enc(&newkeys->enc, cprop[nenc],
629 		    sprop[nenc])) != 0)
630 			goto out;
631 		authlen = cipher_authlen(newkeys->enc.cipher);
632 		/* ignore mac for authenticated encryption */
633 		if (authlen == 0 &&
634 		    (r = choose_mac(ssh, &newkeys->mac, cprop[nmac],
635 		    sprop[nmac])) != 0)
636 			goto out;
637 		if ((r = choose_comp(&newkeys->comp, cprop[ncomp],
638 		    sprop[ncomp])) != 0)
639 			goto out;
640 		debug("kex: %s %s %s %s",
641 		    ctos ? "client->server" : "server->client",
642 		    newkeys->enc.name,
643 		    authlen == 0 ? newkeys->mac.name : "<implicit>",
644 		    newkeys->comp.name);
645 	}
646 	if ((r = choose_kex(kex, cprop[PROPOSAL_KEX_ALGS],
647 	    sprop[PROPOSAL_KEX_ALGS])) != 0 ||
648 	    (r = choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS],
649 	    sprop[PROPOSAL_SERVER_HOST_KEY_ALGS])) != 0)
650 		goto out;
651 	need = dh_need = 0;
652 	for (mode = 0; mode < MODE_MAX; mode++) {
653 		newkeys = kex->newkeys[mode];
654 		need = MAX(need, newkeys->enc.key_len);
655 		need = MAX(need, newkeys->enc.block_size);
656 		need = MAX(need, newkeys->enc.iv_len);
657 		need = MAX(need, newkeys->mac.key_len);
658 		dh_need = MAX(dh_need, cipher_seclen(newkeys->enc.cipher));
659 		dh_need = MAX(dh_need, newkeys->enc.block_size);
660 		dh_need = MAX(dh_need, newkeys->enc.iv_len);
661 		dh_need = MAX(dh_need, newkeys->mac.key_len);
662 	}
663 	/* XXX need runden? */
664 	kex->we_need = need;
665 	kex->dh_need = dh_need;
666 
667 	/* ignore the next message if the proposals do not match */
668 	if (first_kex_follows && !proposals_match(my, peer) &&
669 	    !(ssh->compat & SSH_BUG_FIRSTKEX))
670 		ssh->dispatch_skip_packets = 1;
671 	r = 0;
672  out:
673 	kex_prop_free(my);
674 	kex_prop_free(peer);
675 	return r;
676 }
677 
678 static int
679 derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen,
680     const struct sshbuf *shared_secret, u_char **keyp)
681 {
682 	struct kex *kex = ssh->kex;
683 	struct ssh_digest_ctx *hashctx = NULL;
684 	char c = id;
685 	u_int have;
686 	size_t mdsz;
687 	u_char *digest;
688 	int r;
689 
690 	if ((mdsz = ssh_digest_bytes(kex->hash_alg)) == 0)
691 		return SSH_ERR_INVALID_ARGUMENT;
692 	if ((digest = calloc(1, roundup(need, mdsz))) == NULL) {
693 		r = SSH_ERR_ALLOC_FAIL;
694 		goto out;
695 	}
696 
697 	/* K1 = HASH(K || H || "A" || session_id) */
698 	if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL ||
699 	    ssh_digest_update_buffer(hashctx, shared_secret) != 0 ||
700 	    ssh_digest_update(hashctx, hash, hashlen) != 0 ||
701 	    ssh_digest_update(hashctx, &c, 1) != 0 ||
702 	    ssh_digest_update(hashctx, kex->session_id,
703 	    kex->session_id_len) != 0 ||
704 	    ssh_digest_final(hashctx, digest, mdsz) != 0) {
705 		r = SSH_ERR_LIBCRYPTO_ERROR;
706 		goto out;
707 	}
708 	ssh_digest_free(hashctx);
709 	hashctx = NULL;
710 
711 	/*
712 	 * expand key:
713 	 * Kn = HASH(K || H || K1 || K2 || ... || Kn-1)
714 	 * Key = K1 || K2 || ... || Kn
715 	 */
716 	for (have = mdsz; need > have; have += mdsz) {
717 		if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL ||
718 		    ssh_digest_update_buffer(hashctx, shared_secret) != 0 ||
719 		    ssh_digest_update(hashctx, hash, hashlen) != 0 ||
720 		    ssh_digest_update(hashctx, digest, have) != 0 ||
721 		    ssh_digest_final(hashctx, digest + have, mdsz) != 0) {
722 			r = SSH_ERR_LIBCRYPTO_ERROR;
723 			goto out;
724 		}
725 		ssh_digest_free(hashctx);
726 		hashctx = NULL;
727 	}
728 #ifdef DEBUG_KEX
729 	fprintf(stderr, "key '%c'== ", c);
730 	dump_digest("key", digest, need);
731 #endif
732 	*keyp = digest;
733 	digest = NULL;
734 	r = 0;
735  out:
736 	if (digest)
737 		free(digest);
738 	ssh_digest_free(hashctx);
739 	return r;
740 }
741 
742 #define NKEYS	6
743 int
744 kex_derive_keys(struct ssh *ssh, u_char *hash, u_int hashlen,
745     const struct sshbuf *shared_secret)
746 {
747 	struct kex *kex = ssh->kex;
748 	u_char *keys[NKEYS];
749 	u_int i, j, mode, ctos;
750 	int r;
751 
752 	for (i = 0; i < NKEYS; i++) {
753 		if ((r = derive_key(ssh, 'A'+i, kex->we_need, hash, hashlen,
754 		    shared_secret, &keys[i])) != 0) {
755 			for (j = 0; j < i; j++)
756 				free(keys[j]);
757 			return r;
758 		}
759 	}
760 	for (mode = 0; mode < MODE_MAX; mode++) {
761 		ctos = (!kex->server && mode == MODE_OUT) ||
762 		    (kex->server && mode == MODE_IN);
763 		kex->newkeys[mode]->enc.iv  = keys[ctos ? 0 : 1];
764 		kex->newkeys[mode]->enc.key = keys[ctos ? 2 : 3];
765 		kex->newkeys[mode]->mac.key = keys[ctos ? 4 : 5];
766 	}
767 	return 0;
768 }
769 
770 #ifdef WITH_OPENSSL
771 int
772 kex_derive_keys_bn(struct ssh *ssh, u_char *hash, u_int hashlen,
773     const BIGNUM *secret)
774 {
775 	struct sshbuf *shared_secret;
776 	int r;
777 
778 	if ((shared_secret = sshbuf_new()) == NULL)
779 		return SSH_ERR_ALLOC_FAIL;
780 	if ((r = sshbuf_put_bignum2(shared_secret, secret)) == 0)
781 		r = kex_derive_keys(ssh, hash, hashlen, shared_secret);
782 	sshbuf_free(shared_secret);
783 	return r;
784 }
785 #endif
786 
787 #ifdef WITH_SSH1
788 int
789 derive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus,
790     u_int8_t cookie[8], u_int8_t id[16])
791 {
792 	u_int8_t hbuf[2048], sbuf[2048], obuf[SSH_DIGEST_MAX_LENGTH];
793 	struct ssh_digest_ctx *hashctx = NULL;
794 	size_t hlen, slen;
795 	int r;
796 
797 	hlen = BN_num_bytes(host_modulus);
798 	slen = BN_num_bytes(server_modulus);
799 	if (hlen < (512 / 8) || (u_int)hlen > sizeof(hbuf) ||
800 	    slen < (512 / 8) || (u_int)slen > sizeof(sbuf))
801 		return SSH_ERR_KEY_BITS_MISMATCH;
802 	if (BN_bn2bin(host_modulus, hbuf) <= 0 ||
803 	    BN_bn2bin(server_modulus, sbuf) <= 0) {
804 		r = SSH_ERR_LIBCRYPTO_ERROR;
805 		goto out;
806 	}
807 	if ((hashctx = ssh_digest_start(SSH_DIGEST_MD5)) == NULL) {
808 		r = SSH_ERR_ALLOC_FAIL;
809 		goto out;
810 	}
811 	if (ssh_digest_update(hashctx, hbuf, hlen) != 0 ||
812 	    ssh_digest_update(hashctx, sbuf, slen) != 0 ||
813 	    ssh_digest_update(hashctx, cookie, 8) != 0 ||
814 	    ssh_digest_final(hashctx, obuf, sizeof(obuf)) != 0) {
815 		r = SSH_ERR_LIBCRYPTO_ERROR;
816 		goto out;
817 	}
818 	memcpy(id, obuf, ssh_digest_bytes(SSH_DIGEST_MD5));
819 	r = 0;
820  out:
821 	ssh_digest_free(hashctx);
822 	explicit_bzero(hbuf, sizeof(hbuf));
823 	explicit_bzero(sbuf, sizeof(sbuf));
824 	explicit_bzero(obuf, sizeof(obuf));
825 	return r;
826 }
827 #endif
828 
829 #if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH)
830 void
831 dump_digest(char *msg, u_char *digest, int len)
832 {
833 	fprintf(stderr, "%s\n", msg);
834 	sshbuf_dump_data(digest, len, stderr);
835 }
836 #endif
837