Home | History | Annotate | Line # | Download | only in dist
      1 /*	$NetBSD: kex.c,v 1.40 2026/04/08 18:58:40 christos Exp $	*/
      2 /* $OpenBSD: kex.c,v 1.193 2026/03/05 05:40:35 djm Exp $ */
      3 
      4 /*
      5  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26  */
     27 
     28 #include "includes.h"
     29 __RCSID("$NetBSD: kex.c,v 1.40 2026/04/08 18:58:40 christos Exp $");
     30 
     31 #include <sys/param.h>	/* MAX roundup */
     32 #include <sys/types.h>
     33 #include <errno.h>
     34 #include <signal.h>
     35 #include <stdarg.h>
     36 #include <stdio.h>
     37 #include <stdlib.h>
     38 #include <string.h>
     39 #include <unistd.h>
     40 
     41 #ifdef WITH_OPENSSL
     42 #include <openssl/crypto.h>
     43 #include <openssl/dh.h>
     44 #endif
     45 
     46 #include "ssh.h"
     47 #include "ssh2.h"
     48 #include "atomicio.h"
     49 #include "version.h"
     50 #include "packet.h"
     51 #include "compat.h"
     52 #include "cipher.h"
     53 #include "sshkey.h"
     54 #include "kex.h"
     55 #include "log.h"
     56 #include "mac.h"
     57 #include "match.h"
     58 #include "misc.h"
     59 #include "dispatch.h"
     60 #include "myproposal.h"
     61 
     62 #include "ssherr.h"
     63 #include "sshbuf.h"
     64 #include "digest.h"
     65 #include "xmalloc.h"
     66 
     67 /* prototype */
     68 static int kex_choose_conf(struct ssh *, uint32_t seq);
     69 static int kex_input_newkeys(int, uint32_t, struct ssh *);
     70 
     71 static const char * const proposal_names[PROPOSAL_MAX] = {
     72 	"KEX algorithms",
     73 	"host key algorithms",
     74 	"ciphers ctos",
     75 	"ciphers stoc",
     76 	"MACs ctos",
     77 	"MACs stoc",
     78 	"compression ctos",
     79 	"compression stoc",
     80 	"languages ctos",
     81 	"languages stoc",
     82 };
     83 
     84 /*
     85  * Fill out a proposal array with dynamically allocated values, which may
     86  * be modified as required for compatibility reasons.
     87  * Any of the options may be NULL, in which case the default is used.
     88  * Array contents must be freed by calling kex_proposal_free_entries.
     89  */
     90 void
     91 kex_proposal_populate_entries(struct ssh *ssh, char *prop[PROPOSAL_MAX],
     92     const char *kexalgos, const char *ciphers, const char *macs,
     93     const char *comp, const char *hkalgs)
     94 {
     95 	const char *defpropserver[PROPOSAL_MAX] = { KEX_SERVER };
     96 	const char *defpropclient[PROPOSAL_MAX] = { KEX_CLIENT };
     97 	const char **defprop = ssh->kex->server ? defpropserver : defpropclient;
     98 	u_int i;
     99 	char *cp;
    100 
    101 	if (prop == NULL)
    102 		fatal_f("proposal missing");
    103 
    104 	/* Append EXT_INFO signalling to KexAlgorithms */
    105 	if (kexalgos == NULL)
    106 		kexalgos = defprop[PROPOSAL_KEX_ALGS];
    107 	if ((cp = kex_names_cat(kexalgos, ssh->kex->server ?
    108 	    "ext-info-s,kex-strict-s-v00 (at) openssh.com" :
    109 	    "ext-info-c,kex-strict-c-v00 (at) openssh.com")) == NULL)
    110 		fatal_f("kex_names_cat");
    111 
    112 	for (i = 0; i < PROPOSAL_MAX; i++) {
    113 		switch(i) {
    114 		case PROPOSAL_KEX_ALGS:
    115 			prop[i] = compat_kex_proposal(ssh, cp);
    116 			break;
    117 		case PROPOSAL_ENC_ALGS_CTOS:
    118 		case PROPOSAL_ENC_ALGS_STOC:
    119 			prop[i] = xstrdup(ciphers ? ciphers : defprop[i]);
    120 			break;
    121 		case PROPOSAL_MAC_ALGS_CTOS:
    122 		case PROPOSAL_MAC_ALGS_STOC:
    123 			prop[i]  = xstrdup(macs ? macs : defprop[i]);
    124 			break;
    125 		case PROPOSAL_COMP_ALGS_CTOS:
    126 		case PROPOSAL_COMP_ALGS_STOC:
    127 			prop[i] = xstrdup(comp ? comp : defprop[i]);
    128 			break;
    129 		case PROPOSAL_SERVER_HOST_KEY_ALGS:
    130 			prop[i] = xstrdup(hkalgs ? hkalgs : defprop[i]);
    131 			break;
    132 		default:
    133 			prop[i] = xstrdup(defprop[i]);
    134 		}
    135 	}
    136 	free(cp);
    137 }
    138 
    139 void
    140 kex_proposal_free_entries(char *prop[PROPOSAL_MAX])
    141 {
    142 	u_int i;
    143 
    144 	for (i = 0; i < PROPOSAL_MAX; i++)
    145 		free(prop[i]);
    146 }
    147 
    148 /* put algorithm proposal into buffer */
    149 int
    150 kex_prop2buf(struct sshbuf *b, char *proposal[PROPOSAL_MAX])
    151 {
    152 	u_int i;
    153 	int r;
    154 
    155 	sshbuf_reset(b);
    156 
    157 	/*
    158 	 * add a dummy cookie, the cookie will be overwritten by
    159 	 * kex_send_kexinit(), each time a kexinit is set
    160 	 */
    161 	for (i = 0; i < KEX_COOKIE_LEN; i++) {
    162 		if ((r = sshbuf_put_u8(b, 0)) != 0)
    163 			return r;
    164 	}
    165 	for (i = 0; i < PROPOSAL_MAX; i++) {
    166 		if ((r = sshbuf_put_cstring(b, proposal[i])) != 0)
    167 			return r;
    168 	}
    169 	if ((r = sshbuf_put_u8(b, 0)) != 0 ||	/* first_kex_packet_follows */
    170 	    (r = sshbuf_put_u32(b, 0)) != 0)	/* uint32 reserved */
    171 		return r;
    172 	return 0;
    173 }
    174 
    175 /* parse buffer and return algorithm proposal */
    176 int
    177 kex_buf2prop(struct sshbuf *raw, int *first_kex_follows, char ***propp)
    178 {
    179 	struct sshbuf *b = NULL;
    180 	u_char v;
    181 	u_int i;
    182 	char **proposal = NULL;
    183 	int r;
    184 
    185 	*propp = NULL;
    186 	if ((proposal = calloc(PROPOSAL_MAX, sizeof(char *))) == NULL)
    187 		return SSH_ERR_ALLOC_FAIL;
    188 	if ((b = sshbuf_fromb(raw)) == NULL) {
    189 		r = SSH_ERR_ALLOC_FAIL;
    190 		goto out;
    191 	}
    192 	if ((r = sshbuf_consume(b, KEX_COOKIE_LEN)) != 0) { /* skip cookie */
    193 		error_fr(r, "consume cookie");
    194 		goto out;
    195 	}
    196 	/* extract kex init proposal strings */
    197 	for (i = 0; i < PROPOSAL_MAX; i++) {
    198 		if ((r = sshbuf_get_cstring(b, &(proposal[i]), NULL)) != 0) {
    199 			error_fr(r, "parse proposal %u", i);
    200 			goto out;
    201 		}
    202 		debug2("%s: %s", proposal_names[i], proposal[i]);
    203 	}
    204 	/* first kex follows / reserved */
    205 	if ((r = sshbuf_get_u8(b, &v)) != 0 ||	/* first_kex_follows */
    206 	    (r = sshbuf_get_u32(b, &i)) != 0) {	/* reserved */
    207 		error_fr(r, "parse");
    208 		goto out;
    209 	}
    210 	if (first_kex_follows != NULL)
    211 		*first_kex_follows = v;
    212 	debug2("first_kex_follows %d ", v);
    213 	debug2("reserved %u ", i);
    214 	r = 0;
    215 	*propp = proposal;
    216  out:
    217 	if (r != 0 && proposal != NULL)
    218 		kex_prop_free(proposal);
    219 	sshbuf_free(b);
    220 	return r;
    221 }
    222 
    223 void
    224 kex_prop_free(char **proposal)
    225 {
    226 	u_int i;
    227 
    228 	if (proposal == NULL)
    229 		return;
    230 	for (i = 0; i < PROPOSAL_MAX; i++)
    231 		free(proposal[i]);
    232 	free(proposal);
    233 }
    234 
    235 int
    236 kex_protocol_error(int type, uint32_t seq, struct ssh *ssh)
    237 {
    238 	int r;
    239 
    240 	/* If in strict mode, any unexpected message is an error */
    241 	if ((ssh->kex->flags & KEX_INITIAL) && ssh->kex->kex_strict) {
    242 		ssh_packet_disconnect(ssh, "strict KEX violation: "
    243 		    "unexpected packet type %u (seqnr %u)", type, seq);
    244 	}
    245 	error_f("type %u seq %u", type, seq);
    246 	if ((r = sshpkt_start(ssh, SSH2_MSG_UNIMPLEMENTED)) != 0 ||
    247 	    (r = sshpkt_put_u32(ssh, seq)) != 0 ||
    248 	    (r = sshpkt_send(ssh)) != 0)
    249 		return r;
    250 	return 0;
    251 }
    252 
    253 static void
    254 kex_reset_dispatch(struct ssh *ssh)
    255 {
    256 	ssh_dispatch_range(ssh, SSH2_MSG_TRANSPORT_MIN,
    257 	    SSH2_MSG_TRANSPORT_MAX, &kex_protocol_error);
    258 }
    259 
    260 void
    261 kex_set_server_sig_algs(struct ssh *ssh, const char *allowed_algs)
    262 {
    263 	char *alg, *oalgs, *algs, *sigalgs;
    264 	const char *sigalg;
    265 
    266 	/*
    267 	 * NB. allowed algorithms may contain certificate algorithms that
    268 	 * map to a specific plain signature type, e.g.
    269 	 * rsa-sha2-512-cert-v01 (at) openssh.com => rsa-sha2-512
    270 	 * We need to be careful here to match these, retain the mapping
    271 	 * and only add each signature algorithm once.
    272 	 */
    273 	if ((sigalgs = sshkey_alg_list(0, 1, 1, ',')) == NULL)
    274 		fatal_f("sshkey_alg_list failed");
    275 	oalgs = algs = xstrdup(allowed_algs);
    276 	free(ssh->kex->server_sig_algs);
    277 	ssh->kex->server_sig_algs = NULL;
    278 	for ((alg = strsep(&algs, ",")); alg != NULL && *alg != '\0';
    279 	    (alg = strsep(&algs, ","))) {
    280 		if ((sigalg = sshkey_sigalg_by_name(alg)) == NULL)
    281 			continue;
    282 		if (!kex_has_any_alg(sigalg, sigalgs))
    283 			continue;
    284 		/* Don't add an algorithm twice. */
    285 		if (ssh->kex->server_sig_algs != NULL &&
    286 		    kex_has_any_alg(sigalg, ssh->kex->server_sig_algs))
    287 			continue;
    288 		xextendf(&ssh->kex->server_sig_algs, ",", "%s", sigalg);
    289 	}
    290 	free(oalgs);
    291 	free(sigalgs);
    292 	if (ssh->kex->server_sig_algs == NULL)
    293 		ssh->kex->server_sig_algs = xstrdup("");
    294 }
    295 
    296 static int
    297 kex_compose_ext_info_server(struct ssh *ssh, struct sshbuf *m)
    298 {
    299 	int r;
    300 
    301 	if (ssh->kex->server_sig_algs == NULL &&
    302 	    (ssh->kex->server_sig_algs = sshkey_alg_list(0, 1, 1, ',')) == NULL)
    303 		return SSH_ERR_ALLOC_FAIL;
    304 	if ((r = sshbuf_put_u32(m, 4)) != 0 ||
    305 	    (r = sshbuf_put_cstring(m, "server-sig-algs")) != 0 ||
    306 	    (r = sshbuf_put_cstring(m, ssh->kex->server_sig_algs)) != 0 ||
    307 	    (r = sshbuf_put_cstring(m,
    308 	    "publickey-hostbound (at) openssh.com")) != 0 ||
    309 	    (r = sshbuf_put_cstring(m, "0")) != 0 ||
    310 	    (r = sshbuf_put_cstring(m, "ping (at) openssh.com")) != 0 ||
    311 	    (r = sshbuf_put_cstring(m, "0")) != 0 ||
    312 	    (r = sshbuf_put_cstring(m, "agent-forward")) != 0 ||
    313 	    (r = sshbuf_put_cstring(m, "0")) != 0) {
    314 		error_fr(r, "compose");
    315 		return r;
    316 	}
    317 	return 0;
    318 }
    319 
    320 static int
    321 kex_compose_ext_info_client(struct ssh *ssh, struct sshbuf *m)
    322 {
    323 	int r;
    324 
    325 	if ((r = sshbuf_put_u32(m, 1)) != 0 ||
    326 	    (r = sshbuf_put_cstring(m, "ext-info-in-auth (at) openssh.com")) != 0 ||
    327 	    (r = sshbuf_put_cstring(m, "0")) != 0) {
    328 		error_fr(r, "compose");
    329 		goto out;
    330 	}
    331 	/* success */
    332 	r = 0;
    333  out:
    334 	return r;
    335 }
    336 
    337 static int
    338 kex_maybe_send_ext_info(struct ssh *ssh)
    339 {
    340 	int r;
    341 	struct sshbuf *m = NULL;
    342 
    343 	if ((ssh->kex->flags & KEX_INITIAL) == 0)
    344 		return 0;
    345 	if (!ssh->kex->ext_info_c && !ssh->kex->ext_info_s)
    346 		return 0;
    347 
    348 	/* Compose EXT_INFO packet. */
    349 	if ((m = sshbuf_new()) == NULL)
    350 		fatal_f("sshbuf_new failed");
    351 	if (ssh->kex->ext_info_c &&
    352 	    (r = kex_compose_ext_info_server(ssh, m)) != 0)
    353 		goto fail;
    354 	if (ssh->kex->ext_info_s &&
    355 	    (r = kex_compose_ext_info_client(ssh, m)) != 0)
    356 		goto fail;
    357 
    358 	/* Send the actual KEX_INFO packet */
    359 	debug("Sending SSH2_MSG_EXT_INFO");
    360 	if ((r = sshpkt_start(ssh, SSH2_MSG_EXT_INFO)) != 0 ||
    361 	    (r = sshpkt_putb(ssh, m)) != 0 ||
    362 	    (r = sshpkt_send(ssh)) != 0) {
    363 		error_f("send EXT_INFO");
    364 		goto fail;
    365 	}
    366 
    367 	r = 0;
    368 
    369  fail:
    370 	sshbuf_free(m);
    371 	return r;
    372 }
    373 
    374 int
    375 kex_server_update_ext_info(struct ssh *ssh)
    376 {
    377 	int r;
    378 
    379 	if ((ssh->kex->flags & KEX_HAS_EXT_INFO_IN_AUTH) == 0)
    380 		return 0;
    381 
    382 	debug_f("Sending SSH2_MSG_EXT_INFO");
    383 	if ((r = sshpkt_start(ssh, SSH2_MSG_EXT_INFO)) != 0 ||
    384 	    (r = sshpkt_put_u32(ssh, 1)) != 0 ||
    385 	    (r = sshpkt_put_cstring(ssh, "server-sig-algs")) != 0 ||
    386 	    (r = sshpkt_put_cstring(ssh, ssh->kex->server_sig_algs)) != 0 ||
    387 	    (r = sshpkt_send(ssh)) != 0) {
    388 		error_f("send EXT_INFO");
    389 		return r;
    390 	}
    391 	return 0;
    392 }
    393 
    394 int
    395 kex_send_newkeys(struct ssh *ssh)
    396 {
    397 	int r;
    398 
    399 	kex_reset_dispatch(ssh);
    400 	if ((r = sshpkt_start(ssh, SSH2_MSG_NEWKEYS)) != 0 ||
    401 	    (r = sshpkt_send(ssh)) != 0)
    402 		return r;
    403 	debug("SSH2_MSG_NEWKEYS sent");
    404 	ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_input_newkeys);
    405 	if ((r = kex_maybe_send_ext_info(ssh)) != 0)
    406 		return r;
    407 	debug("expecting SSH2_MSG_NEWKEYS");
    408 	return 0;
    409 }
    410 
    411 /* Check whether an ext_info value contains the expected version string */
    412 static int
    413 kex_ext_info_check_ver(struct kex *kex, const char *name,
    414     const u_char *val, size_t len, const char *want_ver, u_int flag)
    415 {
    416 	if (memchr(val, '\0', len) != NULL) {
    417 		error("SSH2_MSG_EXT_INFO: %s value contains nul byte", name);
    418 		return SSH_ERR_INVALID_FORMAT;
    419 	}
    420 	debug_f("%s=<%s>", name, val);
    421 	if (strcmp((const char *)val, want_ver) == 0)
    422 		kex->flags |= flag;
    423 	else
    424 		debug_f("unsupported version of %s extension", name);
    425 	return 0;
    426 }
    427 
    428 static int
    429 kex_ext_info_client_parse(struct ssh *ssh, const char *name,
    430     const u_char *value, size_t vlen)
    431 {
    432 	int r;
    433 
    434 	/* NB. some messages are only accepted in the initial EXT_INFO */
    435 	if (strcmp(name, "server-sig-algs") == 0) {
    436 		/* Ensure no \0 lurking in value */
    437 		if (memchr(value, '\0', vlen) != NULL) {
    438 			error_f("nul byte in %s", name);
    439 			return SSH_ERR_INVALID_FORMAT;
    440 		}
    441 		debug_f("%s=<%s>", name, value);
    442 		free(ssh->kex->server_sig_algs);
    443 		ssh->kex->server_sig_algs = xstrdup((const char *)value);
    444 	} else if (ssh->kex->ext_info_received == 1 &&
    445 	    strcmp(name, "publickey-hostbound (at) openssh.com") == 0) {
    446 		if ((r = kex_ext_info_check_ver(ssh->kex, name, value, vlen,
    447 		    "0", KEX_HAS_PUBKEY_HOSTBOUND)) != 0) {
    448 			return r;
    449 		}
    450 	} else if (ssh->kex->ext_info_received == 1 &&
    451 	    strcmp(name, "ping (at) openssh.com") == 0) {
    452 		if ((r = kex_ext_info_check_ver(ssh->kex, name, value, vlen,
    453 		    "0", KEX_HAS_PING)) != 0) {
    454 			return r;
    455 		}
    456 	} else if (ssh->kex->ext_info_received == 1 &&
    457 	    strcmp(name, "agent-forward") == 0) {
    458 		if ((r = kex_ext_info_check_ver(ssh->kex, name, value, vlen,
    459 		    "0", KEX_HAS_NEWAGENT)) != 0) {
    460 			return r;
    461 		}
    462 	} else
    463 		debug_f("%s (unrecognised)", name);
    464 
    465 	return 0;
    466 }
    467 
    468 static int
    469 kex_ext_info_server_parse(struct ssh *ssh, const char *name,
    470     const u_char *value, size_t vlen)
    471 {
    472 	int r;
    473 
    474 	if (strcmp(name, "ext-info-in-auth (at) openssh.com") == 0) {
    475 		if ((r = kex_ext_info_check_ver(ssh->kex, name, value, vlen,
    476 		    "0", KEX_HAS_EXT_INFO_IN_AUTH)) != 0) {
    477 			return r;
    478 		}
    479 	} else
    480 		debug_f("%s (unrecognised)", name);
    481 	return 0;
    482 }
    483 
    484 int
    485 kex_input_ext_info(int type, uint32_t seq, struct ssh *ssh)
    486 {
    487 	struct kex *kex = ssh->kex;
    488 	const int max_ext_info = kex->server ? 1 : 2;
    489 	uint32_t i, ninfo;
    490 	char *name;
    491 	u_char *val;
    492 	size_t vlen;
    493 	int r;
    494 
    495 	debug("SSH2_MSG_EXT_INFO received");
    496 	if (++kex->ext_info_received > max_ext_info) {
    497 		error("too many SSH2_MSG_EXT_INFO messages sent by peer");
    498 		return dispatch_protocol_error(type, seq, ssh);
    499 	}
    500 	ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, &kex_protocol_error);
    501 	if ((r = sshpkt_get_u32(ssh, &ninfo)) != 0)
    502 		return r;
    503 	if (ninfo >= 1024) {
    504 		error("SSH2_MSG_EXT_INFO with too many entries, expected "
    505 		    "<=1024, received %u", ninfo);
    506 		return dispatch_protocol_error(type, seq, ssh);
    507 	}
    508 	for (i = 0; i < ninfo; i++) {
    509 		if ((r = sshpkt_get_cstring(ssh, &name, NULL)) != 0)
    510 			return r;
    511 		if ((r = sshpkt_get_string(ssh, &val, &vlen)) != 0) {
    512 			free(name);
    513 			return r;
    514 		}
    515 		debug3_f("extension %s", name);
    516 		if (kex->server) {
    517 			if ((r = kex_ext_info_server_parse(ssh, name,
    518 			    val, vlen)) != 0)
    519 				return r;
    520 		} else {
    521 			if ((r = kex_ext_info_client_parse(ssh, name,
    522 			    val, vlen)) != 0)
    523 				return r;
    524 		}
    525 		free(name);
    526 		free(val);
    527 	}
    528 	return sshpkt_get_end(ssh);
    529 }
    530 
    531 static int
    532 kex_input_newkeys(int type, uint32_t seq, struct ssh *ssh)
    533 {
    534 	struct kex *kex = ssh->kex;
    535 	int r, initial = (kex->flags & KEX_INITIAL) != 0;
    536 	char *cp, **prop;
    537 
    538 	debug("SSH2_MSG_NEWKEYS received");
    539 	if (kex->ext_info_c && initial)
    540 		ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, &kex_input_ext_info);
    541 	ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_protocol_error);
    542 	ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit);
    543 	if ((r = sshpkt_get_end(ssh)) != 0)
    544 		return r;
    545 	if ((r = ssh_set_newkeys(ssh, MODE_IN)) != 0)
    546 		return r;
    547 	if (initial) {
    548 		/* Remove initial KEX signalling from proposal for rekeying */
    549 		if ((r = kex_buf2prop(kex->my, NULL, &prop)) != 0)
    550 			return r;
    551 		if ((cp = match_filter_denylist(prop[PROPOSAL_KEX_ALGS],
    552 		    kex->server ?
    553 		    "ext-info-s,kex-strict-s-v00 (at) openssh.com" :
    554 		    "ext-info-c,kex-strict-c-v00 (at) openssh.com")) == NULL) {
    555 			error_f("match_filter_denylist failed");
    556 			goto fail;
    557 		}
    558 		free(prop[PROPOSAL_KEX_ALGS]);
    559 		prop[PROPOSAL_KEX_ALGS] = cp;
    560 		if ((r = kex_prop2buf(ssh->kex->my, prop)) != 0) {
    561 			error_f("kex_prop2buf failed");
    562  fail:
    563 			kex_proposal_free_entries(prop);
    564 			free(prop);
    565 			return SSH_ERR_INTERNAL_ERROR;
    566 		}
    567 		kex_proposal_free_entries(prop);
    568 		free(prop);
    569 	}
    570 	kex->done = 1;
    571 	kex->flags &= ~KEX_INITIAL;
    572 	sshbuf_reset(kex->peer);
    573 	kex->flags &= ~KEX_INIT_SENT;
    574 	return 0;
    575 }
    576 
    577 int
    578 kex_send_kexinit(struct ssh *ssh)
    579 {
    580 	u_char *cookie;
    581 	struct kex *kex = ssh->kex;
    582 	int r;
    583 
    584 	if (kex == NULL) {
    585 		error_f("no kex");
    586 		return SSH_ERR_INTERNAL_ERROR;
    587 	}
    588 	if (kex->flags & KEX_INIT_SENT)
    589 		return 0;
    590 	kex->done = 0;
    591 
    592 	/* generate a random cookie */
    593 	if (sshbuf_len(kex->my) < KEX_COOKIE_LEN) {
    594 		error_f("bad kex length: %zu < %d",
    595 		    sshbuf_len(kex->my), KEX_COOKIE_LEN);
    596 		return SSH_ERR_INVALID_FORMAT;
    597 	}
    598 	if ((cookie = sshbuf_mutable_ptr(kex->my)) == NULL) {
    599 		error_f("buffer error");
    600 		return SSH_ERR_INTERNAL_ERROR;
    601 	}
    602 	arc4random_buf(cookie, KEX_COOKIE_LEN);
    603 
    604 	if ((r = sshpkt_start(ssh, SSH2_MSG_KEXINIT)) != 0 ||
    605 	    (r = sshpkt_putb(ssh, kex->my)) != 0 ||
    606 	    (r = sshpkt_send(ssh)) != 0) {
    607 		error_fr(r, "compose reply");
    608 		return r;
    609 	}
    610 	debug("SSH2_MSG_KEXINIT sent");
    611 	kex->flags |= KEX_INIT_SENT;
    612 	return 0;
    613 }
    614 
    615 int
    616 kex_input_kexinit(int type, uint32_t seq, struct ssh *ssh)
    617 {
    618 	struct kex *kex = ssh->kex;
    619 	const u_char *ptr;
    620 	u_int i;
    621 	size_t dlen;
    622 	int r;
    623 
    624 	debug("SSH2_MSG_KEXINIT received");
    625 	if (kex == NULL) {
    626 		error_f("no kex");
    627 		return SSH_ERR_INTERNAL_ERROR;
    628 	}
    629 	free(kex->name);
    630 	kex->name = NULL;
    631 	ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_protocol_error);
    632 	ptr = sshpkt_ptr(ssh, &dlen);
    633 	if ((r = sshbuf_put(kex->peer, ptr, dlen)) != 0)
    634 		return r;
    635 
    636 	/* discard packet */
    637 	for (i = 0; i < KEX_COOKIE_LEN; i++) {
    638 		if ((r = sshpkt_get_u8(ssh, NULL)) != 0) {
    639 			error_fr(r, "discard cookie");
    640 			return r;
    641 		}
    642 	}
    643 	for (i = 0; i < PROPOSAL_MAX; i++) {
    644 		if ((r = sshpkt_get_string(ssh, NULL, NULL)) != 0) {
    645 			error_fr(r, "discard proposal");
    646 			return r;
    647 		}
    648 	}
    649 	/*
    650 	 * XXX RFC4253 sec 7: "each side MAY guess" - currently no supported
    651 	 * KEX method has the server move first, but a server might be using
    652 	 * a custom method or one that we otherwise don't support. We should
    653 	 * be prepared to remember first_kex_follows here so we can eat a
    654 	 * packet later.
    655 	 * XXX2 - RFC4253 is kind of ambiguous on what first_kex_follows means
    656 	 * for cases where the server *doesn't* go first. I guess we should
    657 	 * ignore it when it is set for these cases, which is what we do now.
    658 	 */
    659 	if ((r = sshpkt_get_u8(ssh, NULL)) != 0 ||	/* first_kex_follows */
    660 	    (r = sshpkt_get_u32(ssh, NULL)) != 0 ||	/* reserved */
    661 	    (r = sshpkt_get_end(ssh)) != 0)
    662 			return r;
    663 
    664 	if (!(kex->flags & KEX_INIT_SENT))
    665 		if ((r = kex_send_kexinit(ssh)) != 0)
    666 			return r;
    667 	if ((r = kex_choose_conf(ssh, seq)) != 0)
    668 		return r;
    669 
    670 	if (kex->kex_type < KEX_MAX && kex->kex[kex->kex_type] != NULL)
    671 		return (kex->kex[kex->kex_type])(ssh);
    672 
    673 	error_f("unknown kex type %u", kex->kex_type);
    674 	return SSH_ERR_INTERNAL_ERROR;
    675 }
    676 
    677 struct kex *
    678 kex_new(void)
    679 {
    680 	struct kex *kex;
    681 
    682 	if ((kex = calloc(1, sizeof(*kex))) == NULL ||
    683 	    (kex->peer = sshbuf_new()) == NULL ||
    684 	    (kex->my = sshbuf_new()) == NULL ||
    685 	    (kex->client_version = sshbuf_new()) == NULL ||
    686 	    (kex->server_version = sshbuf_new()) == NULL ||
    687 	    (kex->session_id = sshbuf_new()) == NULL) {
    688 		kex_free(kex);
    689 		return NULL;
    690 	}
    691 	return kex;
    692 }
    693 
    694 void
    695 kex_free_newkeys(struct newkeys *newkeys)
    696 {
    697 	if (newkeys == NULL)
    698 		return;
    699 	if (newkeys->enc.key) {
    700 		explicit_bzero(newkeys->enc.key, newkeys->enc.key_len);
    701 		free(newkeys->enc.key);
    702 		newkeys->enc.key = NULL;
    703 	}
    704 	if (newkeys->enc.iv) {
    705 		explicit_bzero(newkeys->enc.iv, newkeys->enc.iv_len);
    706 		free(newkeys->enc.iv);
    707 		newkeys->enc.iv = NULL;
    708 	}
    709 	free(newkeys->enc.name);
    710 	explicit_bzero(&newkeys->enc, sizeof(newkeys->enc));
    711 	free(newkeys->comp.name);
    712 	explicit_bzero(&newkeys->comp, sizeof(newkeys->comp));
    713 	mac_clear(&newkeys->mac);
    714 	if (newkeys->mac.key) {
    715 		explicit_bzero(newkeys->mac.key, newkeys->mac.key_len);
    716 		free(newkeys->mac.key);
    717 		newkeys->mac.key = NULL;
    718 	}
    719 	free(newkeys->mac.name);
    720 	explicit_bzero(&newkeys->mac, sizeof(newkeys->mac));
    721 	freezero(newkeys, sizeof(*newkeys));
    722 }
    723 
    724 void
    725 kex_free(struct kex *kex)
    726 {
    727 	u_int mode;
    728 
    729 	if (kex == NULL)
    730 		return;
    731 
    732 #ifdef WITH_OPENSSL
    733 	DH_free(kex->dh);
    734 	EC_KEY_free(kex->ec_client_key);
    735 #endif
    736 	for (mode = 0; mode < MODE_MAX; mode++) {
    737 		kex_free_newkeys(kex->newkeys[mode]);
    738 		kex->newkeys[mode] = NULL;
    739 	}
    740 	sshbuf_free(kex->peer);
    741 	sshbuf_free(kex->my);
    742 	sshbuf_free(kex->client_version);
    743 	sshbuf_free(kex->server_version);
    744 	sshbuf_free(kex->client_pub);
    745 	sshbuf_free(kex->session_id);
    746 	sshbuf_free(kex->initial_sig);
    747 	sshkey_free(kex->initial_hostkey);
    748 	free(kex->failed_choice);
    749 	free(kex->hostkey_alg);
    750 	free(kex->name);
    751 	free(kex->server_sig_algs);
    752 	free(kex);
    753 }
    754 
    755 int
    756 kex_ready(struct ssh *ssh, char *proposal[PROPOSAL_MAX])
    757 {
    758 	int r;
    759 
    760 	if ((r = kex_prop2buf(ssh->kex->my, proposal)) != 0)
    761 		return r;
    762 	ssh->kex->flags = KEX_INITIAL;
    763 	kex_reset_dispatch(ssh);
    764 	ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit);
    765 	return 0;
    766 }
    767 
    768 int
    769 kex_setup(struct ssh *ssh, char *proposal[PROPOSAL_MAX])
    770 {
    771 	int r;
    772 
    773 	if ((r = kex_ready(ssh, proposal)) != 0)
    774 		return r;
    775 	if ((r = kex_send_kexinit(ssh)) != 0) {		/* we start */
    776 		kex_free(ssh->kex);
    777 		ssh->kex = NULL;
    778 		return r;
    779 	}
    780 	return 0;
    781 }
    782 
    783 /*
    784  * Request key re-exchange, returns 0 on success or a ssherr.h error
    785  * code otherwise. Must not be called if KEX is incomplete or in-progress.
    786  */
    787 int
    788 kex_start_rekex(struct ssh *ssh)
    789 {
    790 	if (ssh->kex == NULL) {
    791 		error_f("no kex");
    792 		return SSH_ERR_INTERNAL_ERROR;
    793 	}
    794 	if (ssh->kex->done == 0) {
    795 		error_f("requested twice");
    796 		return SSH_ERR_INTERNAL_ERROR;
    797 	}
    798 	ssh->kex->done = 0;
    799 	return kex_send_kexinit(ssh);
    800 }
    801 
    802 static int
    803 choose_enc(struct sshenc *enc, char *client, char *server)
    804 {
    805 	char *name = match_list(client, server, NULL);
    806 
    807 	if (name == NULL)
    808 		return SSH_ERR_NO_CIPHER_ALG_MATCH;
    809 	if ((enc->cipher = cipher_by_name(name)) == NULL) {
    810 		error_f("unsupported cipher %s", name);
    811 		free(name);
    812 		return SSH_ERR_INTERNAL_ERROR;
    813 	}
    814 	enc->name = name;
    815 	enc->enabled = 0;
    816 	enc->iv = NULL;
    817 	enc->iv_len = cipher_ivlen(enc->cipher);
    818 	enc->key = NULL;
    819 	enc->key_len = cipher_keylen(enc->cipher);
    820 	enc->block_size = cipher_blocksize(enc->cipher);
    821 	return 0;
    822 }
    823 
    824 static int
    825 choose_mac(struct ssh *ssh, struct sshmac *mac, char *client, char *server)
    826 {
    827 	char *name = match_list(client, server, NULL);
    828 
    829 	if (name == NULL)
    830 		return SSH_ERR_NO_MAC_ALG_MATCH;
    831 	if (mac_setup(mac, name) < 0) {
    832 		error_f("unsupported MAC %s", name);
    833 		free(name);
    834 		return SSH_ERR_INTERNAL_ERROR;
    835 	}
    836 	mac->name = name;
    837 	mac->key = NULL;
    838 	mac->enabled = 0;
    839 	return 0;
    840 }
    841 
    842 static int
    843 choose_comp(struct sshcomp *comp, char *client, char *server)
    844 {
    845 	char *name = match_list(client, server, NULL);
    846 
    847 	if (name == NULL)
    848 		return SSH_ERR_NO_COMPRESS_ALG_MATCH;
    849 #ifdef WITH_ZLIB
    850 	if (strcmp(name, "zlib (at) openssh.com") == 0) {
    851 		comp->type = COMP_DELAYED;
    852 	} else
    853 #endif	/* WITH_ZLIB */
    854 	if (strcmp(name, "none") == 0) {
    855 		comp->type = COMP_NONE;
    856 	} else {
    857 		error_f("unsupported compression scheme %s", name);
    858 		free(name);
    859 		return SSH_ERR_INTERNAL_ERROR;
    860 	}
    861 	comp->name = name;
    862 	return 0;
    863 }
    864 
    865 static int
    866 choose_kex(struct kex *k, char *client, char *server)
    867 {
    868 	k->name = match_list(client, server, NULL);
    869 
    870 	debug("kex: algorithm: %s", k->name ? k->name : "(no match)");
    871 	if (k->name == NULL)
    872 		return SSH_ERR_NO_KEX_ALG_MATCH;
    873 	if (!kex_name_valid(k->name)) {
    874 		error_f("unsupported KEX method %s", k->name);
    875 		return SSH_ERR_INTERNAL_ERROR;
    876 	}
    877 	k->kex_type = kex_type_from_name(k->name);
    878 	k->hash_alg = kex_hash_from_name(k->name);
    879 	k->ec_nid = kex_nid_from_name(k->name);
    880 	return 0;
    881 }
    882 
    883 static int
    884 choose_hostkeyalg(struct kex *k, char *client, char *server)
    885 {
    886 	free(k->hostkey_alg);
    887 	k->hostkey_alg = match_list(client, server, NULL);
    888 
    889 	debug("kex: host key algorithm: %s",
    890 	    k->hostkey_alg ? k->hostkey_alg : "(no match)");
    891 	if (k->hostkey_alg == NULL)
    892 		return SSH_ERR_NO_HOSTKEY_ALG_MATCH;
    893 	k->hostkey_type = sshkey_type_from_name(k->hostkey_alg);
    894 	if (k->hostkey_type == KEY_UNSPEC) {
    895 		error_f("unsupported hostkey algorithm %s", k->hostkey_alg);
    896 		return SSH_ERR_INTERNAL_ERROR;
    897 	}
    898 	k->hostkey_nid = sshkey_ecdsa_nid_from_name(k->hostkey_alg);
    899 	return 0;
    900 }
    901 
    902 static int
    903 proposals_match(char *my[PROPOSAL_MAX], char *peer[PROPOSAL_MAX])
    904 {
    905 	static int check[] = {
    906 		PROPOSAL_KEX_ALGS, PROPOSAL_SERVER_HOST_KEY_ALGS, -1
    907 	};
    908 	int *idx;
    909 	char *p;
    910 
    911 	for (idx = &check[0]; *idx != -1; idx++) {
    912 		if ((p = strchr(my[*idx], ',')) != NULL)
    913 			*p = '\0';
    914 		if ((p = strchr(peer[*idx], ',')) != NULL)
    915 			*p = '\0';
    916 		if (strcmp(my[*idx], peer[*idx]) != 0) {
    917 			debug2("proposal mismatch: my %s peer %s",
    918 			    my[*idx], peer[*idx]);
    919 			return (0);
    920 		}
    921 	}
    922 	debug2("proposals match");
    923 	return (1);
    924 }
    925 
    926 static int
    927 kexalgs_contains(char **peer, const char *ext)
    928 {
    929 	return kex_has_any_alg(peer[PROPOSAL_KEX_ALGS], ext);
    930 }
    931 
    932 static int
    933 kex_choose_conf(struct ssh *ssh, uint32_t seq)
    934 {
    935 	struct kex *kex = ssh->kex;
    936 	struct newkeys *newkeys;
    937 	char **my = NULL, **peer = NULL;
    938 	char **cprop, **sprop;
    939 	int nenc, nmac, ncomp;
    940 	u_int mode, ctos, need, dh_need, authlen;
    941 	int log_flag = 0;
    942 	int r, first_kex_follows;
    943 
    944 	debug2("local %s KEXINIT proposal", kex->server ? "server" : "client");
    945 	if ((r = kex_buf2prop(kex->my, NULL, &my)) != 0)
    946 		goto out;
    947 	debug2("peer %s KEXINIT proposal", kex->server ? "client" : "server");
    948 	if ((r = kex_buf2prop(kex->peer, &first_kex_follows, &peer)) != 0)
    949 		goto out;
    950 
    951 	if (kex->server) {
    952 		cprop=peer;
    953 		sprop=my;
    954 	} else {
    955 		cprop=my;
    956 		sprop=peer;
    957 	}
    958 
    959 	/* Check whether peer supports ext_info/kex_strict */
    960 	if ((kex->flags & KEX_INITIAL) != 0) {
    961 		if (kex->server) {
    962 			kex->ext_info_c = kexalgs_contains(peer, "ext-info-c");
    963 			kex->kex_strict = kexalgs_contains(peer,
    964 			    "kex-strict-c-v00 (at) openssh.com");
    965 		} else {
    966 			kex->ext_info_s = kexalgs_contains(peer, "ext-info-s");
    967 			kex->kex_strict = kexalgs_contains(peer,
    968 			    "kex-strict-s-v00 (at) openssh.com");
    969 		}
    970 		if (kex->kex_strict) {
    971 			debug3_f("will use strict KEX ordering");
    972 			if (seq != 0)
    973 				ssh_packet_disconnect(ssh,
    974 				    "strict KEX violation: "
    975 				    "KEXINIT was not the first packet");
    976 		}
    977 	}
    978 
    979 	/* Check whether client supports rsa-sha2 algorithms */
    980 	if (kex->server && (kex->flags & KEX_INITIAL)) {
    981 		if (kex_has_any_alg(peer[PROPOSAL_SERVER_HOST_KEY_ALGS],
    982 		    "rsa-sha2-256,rsa-sha2-256-cert-v01 (at) openssh.com"))
    983 			kex->flags |= KEX_RSA_SHA2_256_SUPPORTED;
    984 		if (kex_has_any_alg(peer[PROPOSAL_SERVER_HOST_KEY_ALGS],
    985 		    "rsa-sha2-512,rsa-sha2-512-cert-v01 (at) openssh.com"))
    986 			kex->flags |= KEX_RSA_SHA2_512_SUPPORTED;
    987 	}
    988 
    989 	/* Algorithm Negotiation */
    990 	if ((r = choose_kex(kex, cprop[PROPOSAL_KEX_ALGS],
    991 	    sprop[PROPOSAL_KEX_ALGS])) != 0) {
    992 		kex->failed_choice = peer[PROPOSAL_KEX_ALGS];
    993 		peer[PROPOSAL_KEX_ALGS] = NULL;
    994 		goto out;
    995 	}
    996 	if ((r = choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS],
    997 	    sprop[PROPOSAL_SERVER_HOST_KEY_ALGS])) != 0) {
    998 		kex->failed_choice = peer[PROPOSAL_SERVER_HOST_KEY_ALGS];
    999 		peer[PROPOSAL_SERVER_HOST_KEY_ALGS] = NULL;
   1000 		goto out;
   1001 	}
   1002 	for (mode = 0; mode < MODE_MAX; mode++) {
   1003 		if ((newkeys = calloc(1, sizeof(*newkeys))) == NULL) {
   1004 			r = SSH_ERR_ALLOC_FAIL;
   1005 			goto out;
   1006 		}
   1007 		kex->newkeys[mode] = newkeys;
   1008 		ctos = (!kex->server && mode == MODE_OUT) ||
   1009 		    (kex->server && mode == MODE_IN);
   1010 		nenc  = ctos ? PROPOSAL_ENC_ALGS_CTOS  : PROPOSAL_ENC_ALGS_STOC;
   1011 		nmac  = ctos ? PROPOSAL_MAC_ALGS_CTOS  : PROPOSAL_MAC_ALGS_STOC;
   1012 		ncomp = ctos ? PROPOSAL_COMP_ALGS_CTOS : PROPOSAL_COMP_ALGS_STOC;
   1013 		if ((r = choose_enc(&newkeys->enc, cprop[nenc],
   1014 		    sprop[nenc])) != 0) {
   1015 			kex->failed_choice = peer[nenc];
   1016 			peer[nenc] = NULL;
   1017 			goto out;
   1018 		}
   1019 		authlen = cipher_authlen(newkeys->enc.cipher);
   1020 		/* ignore mac for authenticated encryption */
   1021 		if (authlen == 0 &&
   1022 		    (r = choose_mac(ssh, &newkeys->mac, cprop[nmac],
   1023 		    sprop[nmac])) != 0) {
   1024 			kex->failed_choice = peer[nmac];
   1025 			peer[nmac] = NULL;
   1026 			goto out;
   1027 		}
   1028 		if ((r = choose_comp(&newkeys->comp, cprop[ncomp],
   1029 		    sprop[ncomp])) != 0) {
   1030 			kex->failed_choice = peer[ncomp];
   1031 			peer[ncomp] = NULL;
   1032 			goto out;
   1033 		}
   1034 		debug("REQUESTED ENC.NAME is '%s'", newkeys->enc.name);
   1035 		if (strcmp(newkeys->enc.name, "none") == 0) {
   1036 			int auth_flag;
   1037 
   1038 			auth_flag = ssh_packet_authentication_state(ssh);
   1039 			debug("Requesting NONE. Authflag is %d", auth_flag);
   1040 			if (auth_flag == 1) {
   1041 				debug("None requested post authentication.");
   1042 			} else {
   1043 				fatal("Pre-authentication none cipher requests are not allowed.");
   1044 			}
   1045 		}
   1046 		debug("kex: %s cipher: %s MAC: %s compression: %s",
   1047 		    ctos ? "client->server" : "server->client",
   1048 		    newkeys->enc.name,
   1049 		    authlen == 0 ? newkeys->mac.name : "<implicit>",
   1050 		    newkeys->comp.name);
   1051 		/* client starts withctos = 0 && log flag = 0 and no log*/
   1052 		/* 2nd client pass ctos=1 and flag = 1 so no log*/
   1053 		/* server starts with ctos =1 && log_flag = 0 so log */
   1054 		/* 2nd sever pass ctos = 1 && log flag = 1 so no log*/
   1055 		/* -cjr*/
   1056 		if (ctos && !log_flag) {
   1057 			logit("SSH: Server;Ltype: Kex;Remote: %s-%d;Enc: %s;MAC: %s;Comp: %s",
   1058 			      ssh_remote_ipaddr(ssh),
   1059 			      ssh_remote_port(ssh),
   1060 			      newkeys->enc.name,
   1061 			      authlen == 0 ? newkeys->mac.name : "<implicit>",
   1062 			      newkeys->comp.name);
   1063 		}
   1064 		log_flag = 1;
   1065 	}
   1066 	need = dh_need = 0;
   1067 	for (mode = 0; mode < MODE_MAX; mode++) {
   1068 		newkeys = kex->newkeys[mode];
   1069 		need = MAXIMUM(need, newkeys->enc.key_len);
   1070 		need = MAXIMUM(need, newkeys->enc.block_size);
   1071 		need = MAXIMUM(need, newkeys->enc.iv_len);
   1072 		need = MAXIMUM(need, newkeys->mac.key_len);
   1073 		dh_need = MAXIMUM(dh_need, cipher_seclen(newkeys->enc.cipher));
   1074 		dh_need = MAXIMUM(dh_need, newkeys->enc.block_size);
   1075 		dh_need = MAXIMUM(dh_need, newkeys->enc.iv_len);
   1076 		dh_need = MAXIMUM(dh_need, newkeys->mac.key_len);
   1077 	}
   1078 	/* XXX need runden? */
   1079 	kex->we_need = need;
   1080 	kex->dh_need = dh_need;
   1081 
   1082 	/* ignore the next message if the proposals do not match */
   1083 	if (first_kex_follows && !proposals_match(my, peer))
   1084 		ssh->dispatch_skip_packets = 1;
   1085 	r = 0;
   1086  out:
   1087 	kex_prop_free(my);
   1088 	kex_prop_free(peer);
   1089 	return r;
   1090 }
   1091 
   1092 static int
   1093 derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen,
   1094     const struct sshbuf *shared_secret, u_char **keyp)
   1095 {
   1096 	struct kex *kex = ssh->kex;
   1097 	struct ssh_digest_ctx *hashctx = NULL;
   1098 	char c = id;
   1099 	u_int have;
   1100 	size_t mdsz;
   1101 	u_char *digest;
   1102 	int r;
   1103 
   1104 	if ((mdsz = ssh_digest_bytes(kex->hash_alg)) == 0)
   1105 		return SSH_ERR_INVALID_ARGUMENT;
   1106 	if ((digest = calloc(1, ROUNDUP(need, mdsz))) == NULL) {
   1107 		r = SSH_ERR_ALLOC_FAIL;
   1108 		goto out;
   1109 	}
   1110 
   1111 	/* K1 = HASH(K || H || "A" || session_id) */
   1112 	if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL ||
   1113 	    ssh_digest_update_buffer(hashctx, shared_secret) != 0 ||
   1114 	    ssh_digest_update(hashctx, hash, hashlen) != 0 ||
   1115 	    ssh_digest_update(hashctx, &c, 1) != 0 ||
   1116 	    ssh_digest_update_buffer(hashctx, kex->session_id) != 0 ||
   1117 	    ssh_digest_final(hashctx, digest, mdsz) != 0) {
   1118 		r = SSH_ERR_LIBCRYPTO_ERROR;
   1119 		error_f("KEX hash failed");
   1120 		goto out;
   1121 	}
   1122 	ssh_digest_free(hashctx);
   1123 	hashctx = NULL;
   1124 
   1125 	/*
   1126 	 * expand key:
   1127 	 * Kn = HASH(K || H || K1 || K2 || ... || Kn-1)
   1128 	 * Key = K1 || K2 || ... || Kn
   1129 	 */
   1130 	for (have = mdsz; need > have; have += mdsz) {
   1131 		if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL ||
   1132 		    ssh_digest_update_buffer(hashctx, shared_secret) != 0 ||
   1133 		    ssh_digest_update(hashctx, hash, hashlen) != 0 ||
   1134 		    ssh_digest_update(hashctx, digest, have) != 0 ||
   1135 		    ssh_digest_final(hashctx, digest + have, mdsz) != 0) {
   1136 			error_f("KDF failed");
   1137 			r = SSH_ERR_LIBCRYPTO_ERROR;
   1138 			goto out;
   1139 		}
   1140 		ssh_digest_free(hashctx);
   1141 		hashctx = NULL;
   1142 	}
   1143 #ifdef DEBUG_KEX
   1144 	fprintf(stderr, "key '%c'== ", c);
   1145 	dump_digest("key", digest, need);
   1146 #endif
   1147 	*keyp = digest;
   1148 	digest = NULL;
   1149 	r = 0;
   1150  out:
   1151 	free(digest);
   1152 	ssh_digest_free(hashctx);
   1153 	return r;
   1154 }
   1155 
   1156 #define NKEYS	6
   1157 int
   1158 kex_derive_keys(struct ssh *ssh, u_char *hash, u_int hashlen,
   1159     const struct sshbuf *shared_secret)
   1160 {
   1161 	struct kex *kex = ssh->kex;
   1162 	u_char *keys[NKEYS];
   1163 	u_int i, j, mode, ctos;
   1164 	int r;
   1165 
   1166 	/* save initial hash as session id */
   1167 	if ((kex->flags & KEX_INITIAL) != 0) {
   1168 		if (sshbuf_len(kex->session_id) != 0) {
   1169 			error_f("already have session ID at kex");
   1170 			return SSH_ERR_INTERNAL_ERROR;
   1171 		}
   1172 		if ((r = sshbuf_put(kex->session_id, hash, hashlen)) != 0)
   1173 			return r;
   1174 	} else if (sshbuf_len(kex->session_id) == 0) {
   1175 		error_f("no session ID in rekex");
   1176 		return SSH_ERR_INTERNAL_ERROR;
   1177 	}
   1178 	for (i = 0; i < NKEYS; i++) {
   1179 		if ((r = derive_key(ssh, 'A'+i, kex->we_need, hash, hashlen,
   1180 		    shared_secret, &keys[i])) != 0) {
   1181 			for (j = 0; j < i; j++)
   1182 				free(keys[j]);
   1183 			return r;
   1184 		}
   1185 	}
   1186 	for (mode = 0; mode < MODE_MAX; mode++) {
   1187 		ctos = (!kex->server && mode == MODE_OUT) ||
   1188 		    (kex->server && mode == MODE_IN);
   1189 		kex->newkeys[mode]->enc.iv  = keys[ctos ? 0 : 1];
   1190 		kex->newkeys[mode]->enc.key = keys[ctos ? 2 : 3];
   1191 		kex->newkeys[mode]->mac.key = keys[ctos ? 4 : 5];
   1192 	}
   1193 	return 0;
   1194 }
   1195 
   1196 int
   1197 kex_load_hostkey(struct ssh *ssh, struct sshkey **prvp, struct sshkey **pubp)
   1198 {
   1199 	struct kex *kex = ssh->kex;
   1200 
   1201 	*pubp = NULL;
   1202 	*prvp = NULL;
   1203 	if (kex->load_host_public_key == NULL ||
   1204 	    kex->load_host_private_key == NULL) {
   1205 		error_f("missing hostkey loader");
   1206 		return SSH_ERR_INVALID_ARGUMENT;
   1207 	}
   1208 	*pubp = kex->load_host_public_key(kex->hostkey_type,
   1209 	    kex->hostkey_nid, ssh);
   1210 	*prvp = kex->load_host_private_key(kex->hostkey_type,
   1211 	    kex->hostkey_nid, ssh);
   1212 	if (*pubp == NULL)
   1213 		return SSH_ERR_NO_HOSTKEY_LOADED;
   1214 	return 0;
   1215 }
   1216 
   1217 int
   1218 kex_verify_host_key(struct ssh *ssh, struct sshkey *server_host_key)
   1219 {
   1220 	struct kex *kex = ssh->kex;
   1221 
   1222 	if (kex->verify_host_key == NULL) {
   1223 		error_f("missing hostkey verifier");
   1224 		return SSH_ERR_INVALID_ARGUMENT;
   1225 	}
   1226 	if (server_host_key->type != kex->hostkey_type ||
   1227 	    (kex->hostkey_type == KEY_ECDSA &&
   1228 	    server_host_key->ecdsa_nid != kex->hostkey_nid))
   1229 		return SSH_ERR_KEY_TYPE_MISMATCH;
   1230 	if (kex->verify_host_key(server_host_key, ssh) == -1)
   1231 		return  SSH_ERR_SIGNATURE_INVALID;
   1232 	return 0;
   1233 }
   1234 
   1235 #if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH)
   1236 void
   1237 dump_digest(const char *msg, const u_char *digest, int len)
   1238 {
   1239 	fprintf(stderr, "%s\n", msg);
   1240 	sshbuf_dump_data(digest, len, stderr);
   1241 }
   1242 #endif
   1243 
   1244 /*
   1245  * Send a plaintext error message to the peer, suffixed by \r\n.
   1246  * Only used during banner exchange, and there only for the server.
   1247  */
   1248 static void
   1249 send_error(struct ssh *ssh, const char *msg)
   1250 {
   1251 	const char *crnl = "\r\n";
   1252 
   1253 	if (!ssh->kex->server)
   1254 		return;
   1255 
   1256 	if (atomicio(vwrite, ssh_packet_get_connection_out(ssh),
   1257 	    __UNCONST(msg), strlen(msg)) != strlen(msg) ||
   1258 	    atomicio(vwrite, ssh_packet_get_connection_out(ssh),
   1259 	    __UNCONST(crnl), strlen(crnl)) != strlen(crnl))
   1260 		error_f("write: %.100s", strerror(errno));
   1261 }
   1262 
   1263 /*
   1264  * Sends our identification string and waits for the peer's. Will block for
   1265  * up to timeout_ms (or indefinitely if timeout_ms <= 0).
   1266  * Returns on 0 success or a ssherr.h code on failure.
   1267  */
   1268 int
   1269 kex_exchange_identification(struct ssh *ssh, int timeout_ms,
   1270     const char *version_addendum)
   1271 {
   1272 	int remote_major, remote_minor, mismatch, oerrno = 0;
   1273 	size_t len, n;
   1274 	int r, expect_nl;
   1275 	u_char c;
   1276 	struct sshbuf *our_version = ssh->kex->server ?
   1277 	    ssh->kex->server_version : ssh->kex->client_version;
   1278 	struct sshbuf *peer_version = ssh->kex->server ?
   1279 	    ssh->kex->client_version : ssh->kex->server_version;
   1280 	char *our_version_string = NULL, *peer_version_string = NULL;
   1281 	char *cp, *remote_version = NULL;
   1282 
   1283 	/* Prepare and send our banner */
   1284 	sshbuf_reset(our_version);
   1285 	if (version_addendum != NULL && *version_addendum == '\0')
   1286 		version_addendum = NULL;
   1287 	if ((r = sshbuf_putf(our_version, "SSH-%d.%d-%s%s%s\r\n",
   1288 	    PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION,
   1289 	    version_addendum == NULL ? "" : " ",
   1290 	    version_addendum == NULL ? "" : version_addendum)) != 0) {
   1291 		oerrno = errno;
   1292 		error_fr(r, "sshbuf_putf");
   1293 		goto out;
   1294 	}
   1295 
   1296 	if (atomicio(vwrite, ssh_packet_get_connection_out(ssh),
   1297 	    sshbuf_mutable_ptr(our_version),
   1298 	    sshbuf_len(our_version)) != sshbuf_len(our_version)) {
   1299 		oerrno = errno;
   1300 		debug_f("write: %.100s", strerror(errno));
   1301 		r = SSH_ERR_SYSTEM_ERROR;
   1302 		goto out;
   1303 	}
   1304 	if ((r = sshbuf_consume_end(our_version, 2)) != 0) { /* trim \r\n */
   1305 		oerrno = errno;
   1306 		error_fr(r, "sshbuf_consume_end");
   1307 		goto out;
   1308 	}
   1309 	our_version_string = sshbuf_dup_string(our_version);
   1310 	if (our_version_string == NULL) {
   1311 		error_f("sshbuf_dup_string failed");
   1312 		r = SSH_ERR_ALLOC_FAIL;
   1313 		goto out;
   1314 	}
   1315 	debug("Local version string %.100s", our_version_string);
   1316 
   1317 	/* Read other side's version identification. */
   1318 	for (n = 0; ; n++) {
   1319 		if (n >= SSH_MAX_PRE_BANNER_LINES) {
   1320 			send_error(ssh, "No SSH identification string "
   1321 			    "received.");
   1322 			error_f("No SSH version received in first %u lines "
   1323 			    "from server", SSH_MAX_PRE_BANNER_LINES);
   1324 			r = SSH_ERR_INVALID_FORMAT;
   1325 			goto out;
   1326 		}
   1327 		sshbuf_reset(peer_version);
   1328 		expect_nl = 0;
   1329 		for (;;) {
   1330 			if (timeout_ms > 0) {
   1331 				r = waitrfd(ssh_packet_get_connection_in(ssh),
   1332 				    &timeout_ms, NULL);
   1333 				if (r == -1 && errno == ETIMEDOUT) {
   1334 					send_error(ssh, "Timed out waiting "
   1335 					    "for SSH identification string.");
   1336 					error("Connection timed out during "
   1337 					    "banner exchange");
   1338 					r = SSH_ERR_CONN_TIMEOUT;
   1339 					goto out;
   1340 				} else if (r == -1) {
   1341 					oerrno = errno;
   1342 					error_f("%s", strerror(errno));
   1343 					r = SSH_ERR_SYSTEM_ERROR;
   1344 					goto out;
   1345 				}
   1346 			}
   1347 
   1348 			len = atomicio(read, ssh_packet_get_connection_in(ssh),
   1349 			    &c, 1);
   1350 			if (len != 1 && errno == EPIPE) {
   1351 				verbose_f("Connection closed by remote host");
   1352 				r = SSH_ERR_CONN_CLOSED;
   1353 				goto out;
   1354 			} else if (len != 1) {
   1355 				oerrno = errno;
   1356 				error_f("read: %.100s", strerror(errno));
   1357 				r = SSH_ERR_SYSTEM_ERROR;
   1358 				goto out;
   1359 			}
   1360 			if (c == '\r') {
   1361 				expect_nl = 1;
   1362 				continue;
   1363 			}
   1364 			if (c == '\n')
   1365 				break;
   1366 			if (c == '\0' || expect_nl) {
   1367 				verbose_f("banner line contains invalid "
   1368 				    "characters");
   1369 				goto invalid;
   1370 			}
   1371 			if ((r = sshbuf_put_u8(peer_version, c)) != 0) {
   1372 				oerrno = errno;
   1373 				error_fr(r, "sshbuf_put");
   1374 				goto out;
   1375 			}
   1376 			if (sshbuf_len(peer_version) > SSH_MAX_BANNER_LEN) {
   1377 				verbose_f("banner line too long");
   1378 				goto invalid;
   1379 			}
   1380 		}
   1381 		/* Is this an actual protocol banner? */
   1382 		if (sshbuf_len(peer_version) > 4 &&
   1383 		    memcmp(sshbuf_ptr(peer_version), "SSH-", 4) == 0)
   1384 			break;
   1385 		/* If not, then just log the line and continue */
   1386 		if ((cp = sshbuf_dup_string(peer_version)) == NULL) {
   1387 			error_f("sshbuf_dup_string failed");
   1388 			r = SSH_ERR_ALLOC_FAIL;
   1389 			goto out;
   1390 		}
   1391 		/* Do not accept lines before the SSH ident from a client */
   1392 		if (ssh->kex->server) {
   1393 			verbose_f("client sent invalid protocol identifier "
   1394 			    "\"%.256s\"", cp);
   1395 			free(cp);
   1396 			goto invalid;
   1397 		}
   1398 		debug_f("banner line %zu: %s", n, cp);
   1399 		free(cp);
   1400 	}
   1401 	peer_version_string = sshbuf_dup_string(peer_version);
   1402 	if (peer_version_string == NULL)
   1403 		fatal_f("sshbuf_dup_string failed");
   1404 	/* XXX must be same size for sscanf */
   1405 	if ((remote_version = calloc(1, sshbuf_len(peer_version))) == NULL) {
   1406 		error_f("calloc failed");
   1407 		r = SSH_ERR_ALLOC_FAIL;
   1408 		goto out;
   1409 	}
   1410 
   1411 	/*
   1412 	 * Check that the versions match.  In future this might accept
   1413 	 * several versions and set appropriate flags to handle them.
   1414 	 */
   1415 	if (sscanf(peer_version_string, "SSH-%d.%d-%[^\n]\n",
   1416 	    &remote_major, &remote_minor, remote_version) != 3) {
   1417 		error("Bad remote protocol version identification: '%.100s'",
   1418 		    peer_version_string);
   1419  invalid:
   1420 		send_error(ssh, "Invalid SSH identification string.");
   1421 		r = SSH_ERR_INVALID_FORMAT;
   1422 		goto out;
   1423 	}
   1424 	debug("Remote protocol version %d.%d, remote software version %.100s",
   1425 	    remote_major, remote_minor, remote_version);
   1426 	compat_banner(ssh, remote_version);
   1427 
   1428 	mismatch = 0;
   1429 	switch (remote_major) {
   1430 	case 2:
   1431 		break;
   1432 	case 1:
   1433 		if (remote_minor != 99)
   1434 			mismatch = 1;
   1435 		break;
   1436 	default:
   1437 		mismatch = 1;
   1438 		break;
   1439 	}
   1440 	if (mismatch) {
   1441 		error("Protocol major versions differ: %d vs. %d",
   1442 		    PROTOCOL_MAJOR_2, remote_major);
   1443 		send_error(ssh, "Protocol major versions differ.");
   1444 		r = SSH_ERR_NO_PROTOCOL_VERSION;
   1445 		goto out;
   1446 	}
   1447 
   1448 	if (ssh->kex->server && (ssh->compat & SSH_BUG_PROBE) != 0) {
   1449 		logit("probed from %s port %d with %s.  Don't panic.",
   1450 		    ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
   1451 		    peer_version_string);
   1452 		r = SSH_ERR_CONN_CLOSED; /* XXX */
   1453 		goto out;
   1454 	}
   1455 	if (ssh->kex->server && (ssh->compat & SSH_BUG_SCANNER) != 0) {
   1456 		logit("scanned from %s port %d with %s.  Don't panic.",
   1457 		    ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
   1458 		    peer_version_string);
   1459 		r = SSH_ERR_CONN_CLOSED; /* XXX */
   1460 		goto out;
   1461 	}
   1462 	/* success */
   1463 	r = 0;
   1464  out:
   1465 	free(our_version_string);
   1466 	free(peer_version_string);
   1467 	free(remote_version);
   1468 	if (r == SSH_ERR_SYSTEM_ERROR)
   1469 		errno = oerrno;
   1470 	return r;
   1471 }
   1472 
   1473