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