Import OpenSSH-6.7p1.
[dragonfly.git] / crypto / openssh / kex.c
bloba173e70e381cca6992fc891695745b8f85fd2223
1 /* $OpenBSD: kex.c,v 1.99 2014/04/29 18:01:49 markus Exp $ */
2 /*
3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
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.
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.
26 #include "includes.h"
28 #include <sys/param.h>
30 #include <signal.h>
31 #include <stdarg.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
36 #ifdef WITH_OPENSSL
37 #include <openssl/crypto.h>
38 #endif
40 #include "xmalloc.h"
41 #include "ssh2.h"
42 #include "buffer.h"
43 #include "packet.h"
44 #include "compat.h"
45 #include "cipher.h"
46 #include "key.h"
47 #include "kex.h"
48 #include "log.h"
49 #include "mac.h"
50 #include "match.h"
51 #include "dispatch.h"
52 #include "monitor.h"
53 #include "roaming.h"
54 #include "digest.h"
56 #if OPENSSL_VERSION_NUMBER >= 0x00907000L
57 # if defined(HAVE_EVP_SHA256)
58 # define evp_ssh_sha256 EVP_sha256
59 # else
60 extern const EVP_MD *evp_ssh_sha256(void);
61 # endif
62 #endif
64 /* prototype */
65 static void kex_kexinit_finish(Kex *);
66 static void kex_choose_conf(Kex *);
68 struct kexalg {
69 char *name;
70 int type;
71 int ec_nid;
72 int hash_alg;
74 static const struct kexalg kexalgs[] = {
75 #ifdef WITH_OPENSSL
76 { KEX_DH1, KEX_DH_GRP1_SHA1, 0, SSH_DIGEST_SHA1 },
77 { KEX_DH14, KEX_DH_GRP14_SHA1, 0, SSH_DIGEST_SHA1 },
78 { KEX_DHGEX_SHA1, KEX_DH_GEX_SHA1, 0, SSH_DIGEST_SHA1 },
79 #ifdef HAVE_EVP_SHA256
80 { KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, SSH_DIGEST_SHA256 },
81 #endif /* HAVE_EVP_SHA256 */
82 #ifdef OPENSSL_HAS_ECC
83 { KEX_ECDH_SHA2_NISTP256, KEX_ECDH_SHA2,
84 NID_X9_62_prime256v1, SSH_DIGEST_SHA256 },
85 { KEX_ECDH_SHA2_NISTP384, KEX_ECDH_SHA2, NID_secp384r1,
86 SSH_DIGEST_SHA384 },
87 # ifdef OPENSSL_HAS_NISTP521
88 { KEX_ECDH_SHA2_NISTP521, KEX_ECDH_SHA2, NID_secp521r1,
89 SSH_DIGEST_SHA512 },
90 # endif /* OPENSSL_HAS_NISTP521 */
91 #endif /* OPENSSL_HAS_ECC */
92 { KEX_DH1, KEX_DH_GRP1_SHA1, 0, SSH_DIGEST_SHA1 },
93 #endif /* WITH_OPENSSL */
94 #ifdef HAVE_EVP_SHA256
95 { KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 },
96 #endif /* HAVE_EVP_SHA256 */
97 { NULL, -1, -1, -1},
100 char *
101 kex_alg_list(char sep)
103 char *ret = NULL;
104 size_t nlen, rlen = 0;
105 const struct kexalg *k;
107 for (k = kexalgs; k->name != NULL; k++) {
108 if (ret != NULL)
109 ret[rlen++] = sep;
110 nlen = strlen(k->name);
111 ret = xrealloc(ret, 1, rlen + nlen + 2);
112 memcpy(ret + rlen, k->name, nlen + 1);
113 rlen += nlen;
115 return ret;
118 static const struct kexalg *
119 kex_alg_by_name(const char *name)
121 const struct kexalg *k;
123 for (k = kexalgs; k->name != NULL; k++) {
124 if (strcmp(k->name, name) == 0)
125 return k;
127 return NULL;
130 /* Validate KEX method name list */
132 kex_names_valid(const char *names)
134 char *s, *cp, *p;
136 if (names == NULL || strcmp(names, "") == 0)
137 return 0;
138 s = cp = xstrdup(names);
139 for ((p = strsep(&cp, ",")); p && *p != '\0';
140 (p = strsep(&cp, ","))) {
141 if (kex_alg_by_name(p) == NULL) {
142 error("Unsupported KEX algorithm \"%.100s\"", p);
143 free(s);
144 return 0;
147 debug3("kex names ok: [%s]", names);
148 free(s);
149 return 1;
152 /* put algorithm proposal into buffer */
153 static void
154 kex_prop2buf(Buffer *b, char *proposal[PROPOSAL_MAX])
156 u_int i;
158 buffer_clear(b);
160 * add a dummy cookie, the cookie will be overwritten by
161 * kex_send_kexinit(), each time a kexinit is set
163 for (i = 0; i < KEX_COOKIE_LEN; i++)
164 buffer_put_char(b, 0);
165 for (i = 0; i < PROPOSAL_MAX; i++)
166 buffer_put_cstring(b, proposal[i]);
167 buffer_put_char(b, 0); /* first_kex_packet_follows */
168 buffer_put_int(b, 0); /* uint32 reserved */
171 /* parse buffer and return algorithm proposal */
172 static char **
173 kex_buf2prop(Buffer *raw, int *first_kex_follows)
175 Buffer b;
176 u_int i;
177 char **proposal;
179 proposal = xcalloc(PROPOSAL_MAX, sizeof(char *));
181 buffer_init(&b);
182 buffer_append(&b, buffer_ptr(raw), buffer_len(raw));
183 /* skip cookie */
184 for (i = 0; i < KEX_COOKIE_LEN; i++)
185 buffer_get_char(&b);
186 /* extract kex init proposal strings */
187 for (i = 0; i < PROPOSAL_MAX; i++) {
188 proposal[i] = buffer_get_cstring(&b,NULL);
189 debug2("kex_parse_kexinit: %s", proposal[i]);
191 /* first kex follows / reserved */
192 i = buffer_get_char(&b);
193 if (first_kex_follows != NULL)
194 *first_kex_follows = i;
195 debug2("kex_parse_kexinit: first_kex_follows %d ", i);
196 i = buffer_get_int(&b);
197 debug2("kex_parse_kexinit: reserved %u ", i);
198 buffer_free(&b);
199 return proposal;
202 static void
203 kex_prop_free(char **proposal)
205 u_int i;
207 for (i = 0; i < PROPOSAL_MAX; i++)
208 free(proposal[i]);
209 free(proposal);
212 /* ARGSUSED */
213 static void
214 kex_protocol_error(int type, u_int32_t seq, void *ctxt)
216 error("Hm, kex protocol error: type %d seq %u", type, seq);
219 static void
220 kex_reset_dispatch(void)
222 dispatch_range(SSH2_MSG_TRANSPORT_MIN,
223 SSH2_MSG_TRANSPORT_MAX, &kex_protocol_error);
224 dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit);
227 void
228 kex_finish(Kex *kex)
230 kex_reset_dispatch();
232 packet_start(SSH2_MSG_NEWKEYS);
233 packet_send();
234 /* packet_write_wait(); */
235 debug("SSH2_MSG_NEWKEYS sent");
237 debug("expecting SSH2_MSG_NEWKEYS");
238 packet_read_expect(SSH2_MSG_NEWKEYS);
239 packet_check_eom();
240 debug("SSH2_MSG_NEWKEYS received");
242 kex->done = 1;
243 buffer_clear(&kex->peer);
244 /* buffer_clear(&kex->my); */
245 kex->flags &= ~KEX_INIT_SENT;
246 free(kex->name);
247 kex->name = NULL;
250 void
251 kex_send_kexinit(Kex *kex)
253 u_int32_t rnd = 0;
254 u_char *cookie;
255 u_int i;
257 if (kex == NULL) {
258 error("kex_send_kexinit: no kex, cannot rekey");
259 return;
261 if (kex->flags & KEX_INIT_SENT) {
262 debug("KEX_INIT_SENT");
263 return;
265 kex->done = 0;
267 /* generate a random cookie */
268 if (buffer_len(&kex->my) < KEX_COOKIE_LEN)
269 fatal("kex_send_kexinit: kex proposal too short");
270 cookie = buffer_ptr(&kex->my);
271 for (i = 0; i < KEX_COOKIE_LEN; i++) {
272 if (i % 4 == 0)
273 rnd = arc4random();
274 cookie[i] = rnd;
275 rnd >>= 8;
277 packet_start(SSH2_MSG_KEXINIT);
278 packet_put_raw(buffer_ptr(&kex->my), buffer_len(&kex->my));
279 packet_send();
280 debug("SSH2_MSG_KEXINIT sent");
281 kex->flags |= KEX_INIT_SENT;
284 /* ARGSUSED */
285 void
286 kex_input_kexinit(int type, u_int32_t seq, void *ctxt)
288 char *ptr;
289 u_int i, dlen;
290 Kex *kex = (Kex *)ctxt;
292 debug("SSH2_MSG_KEXINIT received");
293 if (kex == NULL)
294 fatal("kex_input_kexinit: no kex, cannot rekey");
296 ptr = packet_get_raw(&dlen);
297 buffer_append(&kex->peer, ptr, dlen);
299 /* discard packet */
300 for (i = 0; i < KEX_COOKIE_LEN; i++)
301 packet_get_char();
302 for (i = 0; i < PROPOSAL_MAX; i++)
303 free(packet_get_string(NULL));
305 * XXX RFC4253 sec 7: "each side MAY guess" - currently no supported
306 * KEX method has the server move first, but a server might be using
307 * a custom method or one that we otherwise don't support. We should
308 * be prepared to remember first_kex_follows here so we can eat a
309 * packet later.
310 * XXX2 - RFC4253 is kind of ambiguous on what first_kex_follows means
311 * for cases where the server *doesn't* go first. I guess we should
312 * ignore it when it is set for these cases, which is what we do now.
314 (void) packet_get_char(); /* first_kex_follows */
315 (void) packet_get_int(); /* reserved */
316 packet_check_eom();
318 kex_kexinit_finish(kex);
321 Kex *
322 kex_setup(char *proposal[PROPOSAL_MAX])
324 Kex *kex;
326 kex = xcalloc(1, sizeof(*kex));
327 buffer_init(&kex->peer);
328 buffer_init(&kex->my);
329 kex_prop2buf(&kex->my, proposal);
330 kex->done = 0;
332 kex_send_kexinit(kex); /* we start */
333 kex_reset_dispatch();
335 return kex;
338 static void
339 kex_kexinit_finish(Kex *kex)
341 if (!(kex->flags & KEX_INIT_SENT))
342 kex_send_kexinit(kex);
344 kex_choose_conf(kex);
346 if (kex->kex_type >= 0 && kex->kex_type < KEX_MAX &&
347 kex->kex[kex->kex_type] != NULL) {
348 (kex->kex[kex->kex_type])(kex);
349 } else {
350 fatal("Unsupported key exchange %d", kex->kex_type);
354 static void
355 choose_enc(Enc *enc, char *client, char *server)
357 char *name = match_list(client, server, NULL);
358 if (name == NULL)
359 fatal("no matching cipher found: client %s server %s",
360 client, server);
361 if ((enc->cipher = cipher_by_name(name)) == NULL)
362 fatal("matching cipher is not supported: %s", name);
363 enc->name = name;
364 enc->enabled = 0;
365 enc->iv = NULL;
366 enc->iv_len = cipher_ivlen(enc->cipher);
367 enc->key = NULL;
368 enc->key_len = cipher_keylen(enc->cipher);
369 enc->block_size = cipher_blocksize(enc->cipher);
372 static void
373 choose_mac(Mac *mac, char *client, char *server)
375 char *name = match_list(client, server, NULL);
376 if (name == NULL)
377 fatal("no matching mac found: client %s server %s",
378 client, server);
379 if (mac_setup(mac, name) < 0)
380 fatal("unsupported mac %s", name);
381 /* truncate the key */
382 if (datafellows & SSH_BUG_HMAC)
383 mac->key_len = 16;
384 mac->name = name;
385 mac->key = NULL;
386 mac->enabled = 0;
389 static void
390 choose_comp(Comp *comp, char *client, char *server)
392 char *name = match_list(client, server, NULL);
393 if (name == NULL)
394 fatal("no matching comp found: client %s server %s", client, server);
395 if (strcmp(name, "zlib@openssh.com") == 0) {
396 comp->type = COMP_DELAYED;
397 } else if (strcmp(name, "zlib") == 0) {
398 comp->type = COMP_ZLIB;
399 } else if (strcmp(name, "none") == 0) {
400 comp->type = COMP_NONE;
401 } else {
402 fatal("unsupported comp %s", name);
404 comp->name = name;
407 static void
408 choose_kex(Kex *k, char *client, char *server)
410 const struct kexalg *kexalg;
412 k->name = match_list(client, server, NULL);
413 if (k->name == NULL)
414 fatal("Unable to negotiate a key exchange method");
415 if ((kexalg = kex_alg_by_name(k->name)) == NULL)
416 fatal("unsupported kex alg %s", k->name);
417 k->kex_type = kexalg->type;
418 k->hash_alg = kexalg->hash_alg;
419 k->ec_nid = kexalg->ec_nid;
422 static void
423 choose_hostkeyalg(Kex *k, char *client, char *server)
425 char *hostkeyalg = match_list(client, server, NULL);
426 if (hostkeyalg == NULL)
427 fatal("no hostkey alg");
428 k->hostkey_type = key_type_from_name(hostkeyalg);
429 if (k->hostkey_type == KEY_UNSPEC)
430 fatal("bad hostkey alg '%s'", hostkeyalg);
431 free(hostkeyalg);
434 static int
435 proposals_match(char *my[PROPOSAL_MAX], char *peer[PROPOSAL_MAX])
437 static int check[] = {
438 PROPOSAL_KEX_ALGS, PROPOSAL_SERVER_HOST_KEY_ALGS, -1
440 int *idx;
441 char *p;
443 for (idx = &check[0]; *idx != -1; idx++) {
444 if ((p = strchr(my[*idx], ',')) != NULL)
445 *p = '\0';
446 if ((p = strchr(peer[*idx], ',')) != NULL)
447 *p = '\0';
448 if (strcmp(my[*idx], peer[*idx]) != 0) {
449 debug2("proposal mismatch: my %s peer %s",
450 my[*idx], peer[*idx]);
451 return (0);
454 debug2("proposals match");
455 return (1);
458 static void
459 kex_choose_conf(Kex *kex)
461 Newkeys *newkeys;
462 char **my, **peer;
463 char **cprop, **sprop;
464 int nenc, nmac, ncomp;
465 u_int mode, ctos, need, dh_need, authlen;
466 int first_kex_follows, type;
468 my = kex_buf2prop(&kex->my, NULL);
469 peer = kex_buf2prop(&kex->peer, &first_kex_follows);
471 if (kex->server) {
472 cprop=peer;
473 sprop=my;
474 } else {
475 cprop=my;
476 sprop=peer;
479 /* Check whether server offers roaming */
480 if (!kex->server) {
481 char *roaming;
482 roaming = match_list(KEX_RESUME, peer[PROPOSAL_KEX_ALGS], NULL);
483 if (roaming) {
484 kex->roaming = 1;
485 free(roaming);
489 /* Algorithm Negotiation */
490 for (mode = 0; mode < MODE_MAX; mode++) {
491 newkeys = xcalloc(1, sizeof(*newkeys));
492 kex->newkeys[mode] = newkeys;
493 ctos = (!kex->server && mode == MODE_OUT) ||
494 (kex->server && mode == MODE_IN);
495 nenc = ctos ? PROPOSAL_ENC_ALGS_CTOS : PROPOSAL_ENC_ALGS_STOC;
496 nmac = ctos ? PROPOSAL_MAC_ALGS_CTOS : PROPOSAL_MAC_ALGS_STOC;
497 ncomp = ctos ? PROPOSAL_COMP_ALGS_CTOS : PROPOSAL_COMP_ALGS_STOC;
498 choose_enc(&newkeys->enc, cprop[nenc], sprop[nenc]);
499 /* ignore mac for authenticated encryption */
500 authlen = cipher_authlen(newkeys->enc.cipher);
501 if (authlen == 0)
502 choose_mac(&newkeys->mac, cprop[nmac], sprop[nmac]);
503 choose_comp(&newkeys->comp, cprop[ncomp], sprop[ncomp]);
504 debug("kex: %s %s %s %s",
505 ctos ? "client->server" : "server->client",
506 newkeys->enc.name,
507 authlen == 0 ? newkeys->mac.name : "<implicit>",
508 newkeys->comp.name);
510 choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]);
511 choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS],
512 sprop[PROPOSAL_SERVER_HOST_KEY_ALGS]);
513 need = dh_need = 0;
514 for (mode = 0; mode < MODE_MAX; mode++) {
515 newkeys = kex->newkeys[mode];
516 need = MAX(need, newkeys->enc.key_len);
517 need = MAX(need, newkeys->enc.block_size);
518 need = MAX(need, newkeys->enc.iv_len);
519 need = MAX(need, newkeys->mac.key_len);
520 dh_need = MAX(dh_need, cipher_seclen(newkeys->enc.cipher));
521 dh_need = MAX(dh_need, newkeys->enc.block_size);
522 dh_need = MAX(dh_need, newkeys->enc.iv_len);
523 dh_need = MAX(dh_need, newkeys->mac.key_len);
525 /* XXX need runden? */
526 kex->we_need = need;
527 kex->dh_need = dh_need;
529 /* ignore the next message if the proposals do not match */
530 if (first_kex_follows && !proposals_match(my, peer) &&
531 !(datafellows & SSH_BUG_FIRSTKEX)) {
532 type = packet_read();
533 debug2("skipping next packet (type %u)", type);
536 kex_prop_free(my);
537 kex_prop_free(peer);
540 static u_char *
541 derive_key(Kex *kex, int id, u_int need, u_char *hash, u_int hashlen,
542 const u_char *shared_secret, u_int slen)
544 Buffer b;
545 struct ssh_digest_ctx *hashctx;
546 char c = id;
547 u_int have;
548 size_t mdsz;
549 u_char *digest;
551 if ((mdsz = ssh_digest_bytes(kex->hash_alg)) == 0)
552 fatal("bad kex md size %zu", mdsz);
553 digest = xmalloc(roundup(need, mdsz));
555 buffer_init(&b);
556 buffer_append(&b, shared_secret, slen);
558 /* K1 = HASH(K || H || "A" || session_id) */
559 if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL)
560 fatal("%s: ssh_digest_start failed", __func__);
561 if (ssh_digest_update_buffer(hashctx, &b) != 0 ||
562 ssh_digest_update(hashctx, hash, hashlen) != 0 ||
563 ssh_digest_update(hashctx, &c, 1) != 0 ||
564 ssh_digest_update(hashctx, kex->session_id,
565 kex->session_id_len) != 0)
566 fatal("%s: ssh_digest_update failed", __func__);
567 if (ssh_digest_final(hashctx, digest, mdsz) != 0)
568 fatal("%s: ssh_digest_final failed", __func__);
569 ssh_digest_free(hashctx);
572 * expand key:
573 * Kn = HASH(K || H || K1 || K2 || ... || Kn-1)
574 * Key = K1 || K2 || ... || Kn
576 for (have = mdsz; need > have; have += mdsz) {
577 if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL)
578 fatal("%s: ssh_digest_start failed", __func__);
579 if (ssh_digest_update_buffer(hashctx, &b) != 0 ||
580 ssh_digest_update(hashctx, hash, hashlen) != 0 ||
581 ssh_digest_update(hashctx, digest, have) != 0)
582 fatal("%s: ssh_digest_update failed", __func__);
583 if (ssh_digest_final(hashctx, digest + have, mdsz) != 0)
584 fatal("%s: ssh_digest_final failed", __func__);
585 ssh_digest_free(hashctx);
587 buffer_free(&b);
588 #ifdef DEBUG_KEX
589 fprintf(stderr, "key '%c'== ", c);
590 dump_digest("key", digest, need);
591 #endif
592 return digest;
595 Newkeys *current_keys[MODE_MAX];
597 #define NKEYS 6
598 void
599 kex_derive_keys(Kex *kex, u_char *hash, u_int hashlen,
600 const u_char *shared_secret, u_int slen)
602 u_char *keys[NKEYS];
603 u_int i, mode, ctos;
605 for (i = 0; i < NKEYS; i++) {
606 keys[i] = derive_key(kex, 'A'+i, kex->we_need, hash, hashlen,
607 shared_secret, slen);
610 debug2("kex_derive_keys");
611 for (mode = 0; mode < MODE_MAX; mode++) {
612 current_keys[mode] = kex->newkeys[mode];
613 kex->newkeys[mode] = NULL;
614 ctos = (!kex->server && mode == MODE_OUT) ||
615 (kex->server && mode == MODE_IN);
616 current_keys[mode]->enc.iv = keys[ctos ? 0 : 1];
617 current_keys[mode]->enc.key = keys[ctos ? 2 : 3];
618 current_keys[mode]->mac.key = keys[ctos ? 4 : 5];
622 #ifdef WITH_OPENSSL
623 void
624 kex_derive_keys_bn(Kex *kex, u_char *hash, u_int hashlen, const BIGNUM *secret)
626 Buffer shared_secret;
628 buffer_init(&shared_secret);
629 buffer_put_bignum2(&shared_secret, secret);
630 kex_derive_keys(kex, hash, hashlen,
631 buffer_ptr(&shared_secret), buffer_len(&shared_secret));
632 buffer_free(&shared_secret);
634 #endif
636 Newkeys *
637 kex_get_newkeys(int mode)
639 Newkeys *ret;
641 ret = current_keys[mode];
642 current_keys[mode] = NULL;
643 return ret;
646 #ifdef WITH_SSH1
647 void
648 derive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus,
649 u_int8_t cookie[8], u_int8_t id[16])
651 u_int8_t nbuf[2048], obuf[SSH_DIGEST_MAX_LENGTH];
652 int len;
653 struct ssh_digest_ctx *hashctx;
655 if ((hashctx = ssh_digest_start(SSH_DIGEST_MD5)) == NULL)
656 fatal("%s: ssh_digest_start", __func__);
658 len = BN_num_bytes(host_modulus);
659 if (len < (512 / 8) || (u_int)len > sizeof(nbuf))
660 fatal("%s: bad host modulus (len %d)", __func__, len);
661 BN_bn2bin(host_modulus, nbuf);
662 if (ssh_digest_update(hashctx, nbuf, len) != 0)
663 fatal("%s: ssh_digest_update failed", __func__);
665 len = BN_num_bytes(server_modulus);
666 if (len < (512 / 8) || (u_int)len > sizeof(nbuf))
667 fatal("%s: bad server modulus (len %d)", __func__, len);
668 BN_bn2bin(server_modulus, nbuf);
669 if (ssh_digest_update(hashctx, nbuf, len) != 0 ||
670 ssh_digest_update(hashctx, cookie, 8) != 0)
671 fatal("%s: ssh_digest_update failed", __func__);
672 if (ssh_digest_final(hashctx, obuf, sizeof(obuf)) != 0)
673 fatal("%s: ssh_digest_final failed", __func__);
674 memcpy(id, obuf, ssh_digest_bytes(SSH_DIGEST_MD5));
676 explicit_bzero(nbuf, sizeof(nbuf));
677 explicit_bzero(obuf, sizeof(obuf));
679 #endif
681 #if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH)
682 void
683 dump_digest(char *msg, u_char *digest, int len)
685 int i;
687 fprintf(stderr, "%s\n", msg);
688 for (i = 0; i < len; i++) {
689 fprintf(stderr, "%02x", digest[i]);
690 if (i%32 == 31)
691 fprintf(stderr, "\n");
692 else if (i%8 == 7)
693 fprintf(stderr, " ");
695 fprintf(stderr, "\n");
697 #endif