summaryrefslogtreecommitdiff
path: root/kex.c
diff options
context:
space:
mode:
Diffstat (limited to 'kex.c')
-rw-r--r--kex.c151
1 files changed, 91 insertions, 60 deletions
diff --git a/kex.c b/kex.c
index 1ec278245..49d0fc8fd 100644
--- a/kex.c
+++ b/kex.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: kex.c,v 1.91 2013/05/17 00:13:13 djm Exp $ */ 1/* $OpenBSD: kex.c,v 1.97 2014/01/25 20:35:37 markus Exp $ */
2/* 2/*
3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
4 * 4 *
@@ -49,6 +49,7 @@
49#include "dispatch.h" 49#include "dispatch.h"
50#include "monitor.h" 50#include "monitor.h"
51#include "roaming.h" 51#include "roaming.h"
52#include "digest.h"
52 53
53#ifdef GSSAPI 54#ifdef GSSAPI
54#include "ssh-gss.h" 55#include "ssh-gss.h"
@@ -70,33 +71,42 @@ struct kexalg {
70 char *name; 71 char *name;
71 int type; 72 int type;
72 int ec_nid; 73 int ec_nid;
73 const EVP_MD *(*mdfunc)(void); 74 int hash_alg;
74}; 75};
75static const struct kexalg kexalgs[] = { 76static const struct kexalg kexalgs[] = {
76 { KEX_DH1, KEX_DH_GRP1_SHA1, 0, EVP_sha1 }, 77 { KEX_DH1, KEX_DH_GRP1_SHA1, 0, SSH_DIGEST_SHA1 },
77 { KEX_DH14, KEX_DH_GRP14_SHA1, 0, EVP_sha1 }, 78 { KEX_DH14, KEX_DH_GRP14_SHA1, 0, SSH_DIGEST_SHA1 },
78 { KEX_DHGEX_SHA1, KEX_DH_GEX_SHA1, 0, EVP_sha1 }, 79 { KEX_DHGEX_SHA1, KEX_DH_GEX_SHA1, 0, SSH_DIGEST_SHA1 },
79#ifdef HAVE_EVP_SHA256 80#ifdef HAVE_EVP_SHA256
80 { KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, EVP_sha256 }, 81 { KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, SSH_DIGEST_SHA256 },
81#endif 82#endif
82#ifdef OPENSSL_HAS_ECC 83#ifdef OPENSSL_HAS_ECC
83 { KEX_ECDH_SHA2_NISTP256, KEX_ECDH_SHA2, NID_X9_62_prime256v1, EVP_sha256 }, 84 { KEX_ECDH_SHA2_NISTP256, KEX_ECDH_SHA2,
84 { KEX_ECDH_SHA2_NISTP384, KEX_ECDH_SHA2, NID_secp384r1, EVP_sha384 }, 85 NID_X9_62_prime256v1, SSH_DIGEST_SHA256 },
85 { KEX_ECDH_SHA2_NISTP521, KEX_ECDH_SHA2, NID_secp521r1, EVP_sha512 }, 86 { KEX_ECDH_SHA2_NISTP384, KEX_ECDH_SHA2, NID_secp384r1,
87 SSH_DIGEST_SHA384 },
88# ifdef OPENSSL_HAS_NISTP521
89 { KEX_ECDH_SHA2_NISTP521, KEX_ECDH_SHA2, NID_secp521r1,
90 SSH_DIGEST_SHA512 },
91# endif
92#endif
93 { KEX_DH1, KEX_DH_GRP1_SHA1, 0, SSH_DIGEST_SHA1 },
94#ifdef HAVE_EVP_SHA256
95 { KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 },
86#endif 96#endif
87 { NULL, -1, -1, NULL}, 97 { NULL, -1, -1, -1},
88}; 98};
89static const struct kexalg kexalg_prefixes[] = { 99static const struct kexalg kexalg_prefixes[] = {
90#ifdef GSSAPI 100#ifdef GSSAPI
91 { KEX_GSS_GEX_SHA1_ID, KEX_GSS_GEX_SHA1, 0, EVP_sha1 }, 101 { KEX_GSS_GEX_SHA1_ID, KEX_GSS_GEX_SHA1, 0, SSH_DIGEST_SHA1 },
92 { KEX_GSS_GRP1_SHA1_ID, KEX_GSS_GRP1_SHA1, 0, EVP_sha1 }, 102 { KEX_GSS_GRP1_SHA1_ID, KEX_GSS_GRP1_SHA1, 0, SSH_DIGEST_SHA1 },
93 { KEX_GSS_GRP14_SHA1_ID, KEX_GSS_GRP14_SHA1, 0, EVP_sha1 }, 103 { KEX_GSS_GRP14_SHA1_ID, KEX_GSS_GRP14_SHA1, 0, SSH_DIGEST_SHA1 },
94#endif 104#endif
95 { NULL, -1, -1, NULL }, 105 { NULL, -1, -1, -1 },
96}; 106};
97 107
98char * 108char *
99kex_alg_list(void) 109kex_alg_list(char sep)
100{ 110{
101 char *ret = NULL; 111 char *ret = NULL;
102 size_t nlen, rlen = 0; 112 size_t nlen, rlen = 0;
@@ -104,7 +114,7 @@ kex_alg_list(void)
104 114
105 for (k = kexalgs; k->name != NULL; k++) { 115 for (k = kexalgs; k->name != NULL; k++) {
106 if (ret != NULL) 116 if (ret != NULL)
107 ret[rlen++] = '\n'; 117 ret[rlen++] = sep;
108 nlen = strlen(k->name); 118 nlen = strlen(k->name);
109 ret = xrealloc(ret, 1, rlen + nlen + 2); 119 ret = xrealloc(ret, 1, rlen + nlen + 2);
110 memcpy(ret + rlen, k->name, nlen + 1); 120 memcpy(ret + rlen, k->name, nlen + 1);
@@ -417,7 +427,7 @@ choose_kex(Kex *k, char *client, char *server)
417 if ((kexalg = kex_alg_by_name(k->name)) == NULL) 427 if ((kexalg = kex_alg_by_name(k->name)) == NULL)
418 fatal("unsupported kex alg %s", k->name); 428 fatal("unsupported kex alg %s", k->name);
419 k->kex_type = kexalg->type; 429 k->kex_type = kexalg->type;
420 k->evp_md = kexalg->mdfunc(); 430 k->hash_alg = kexalg->hash_alg;
421 k->ec_nid = kexalg->ec_nid; 431 k->ec_nid = kexalg->ec_nid;
422} 432}
423 433
@@ -464,7 +474,7 @@ kex_choose_conf(Kex *kex)
464 char **my, **peer; 474 char **my, **peer;
465 char **cprop, **sprop; 475 char **cprop, **sprop;
466 int nenc, nmac, ncomp; 476 int nenc, nmac, ncomp;
467 u_int mode, ctos, need, authlen; 477 u_int mode, ctos, need, dh_need, authlen;
468 int first_kex_follows, type; 478 int first_kex_follows, type;
469 479
470 my = kex_buf2prop(&kex->my, NULL); 480 my = kex_buf2prop(&kex->my, NULL);
@@ -512,20 +522,21 @@ kex_choose_conf(Kex *kex)
512 choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]); 522 choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]);
513 choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS], 523 choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS],
514 sprop[PROPOSAL_SERVER_HOST_KEY_ALGS]); 524 sprop[PROPOSAL_SERVER_HOST_KEY_ALGS]);
515 need = 0; 525 need = dh_need = 0;
516 for (mode = 0; mode < MODE_MAX; mode++) { 526 for (mode = 0; mode < MODE_MAX; mode++) {
517 newkeys = kex->newkeys[mode]; 527 newkeys = kex->newkeys[mode];
518 if (need < newkeys->enc.key_len) 528 need = MAX(need, newkeys->enc.key_len);
519 need = newkeys->enc.key_len; 529 need = MAX(need, newkeys->enc.block_size);
520 if (need < newkeys->enc.block_size) 530 need = MAX(need, newkeys->enc.iv_len);
521 need = newkeys->enc.block_size; 531 need = MAX(need, newkeys->mac.key_len);
522 if (need < newkeys->enc.iv_len) 532 dh_need = MAX(dh_need, cipher_seclen(newkeys->enc.cipher));
523 need = newkeys->enc.iv_len; 533 dh_need = MAX(dh_need, newkeys->enc.block_size);
524 if (need < newkeys->mac.key_len) 534 dh_need = MAX(dh_need, newkeys->enc.iv_len);
525 need = newkeys->mac.key_len; 535 dh_need = MAX(dh_need, newkeys->mac.key_len);
526 } 536 }
527 /* XXX need runden? */ 537 /* XXX need runden? */
528 kex->we_need = need; 538 kex->we_need = need;
539 kex->dh_need = dh_need;
529 540
530 /* ignore the next message if the proposals do not match */ 541 /* ignore the next message if the proposals do not match */
531 if (first_kex_follows && !proposals_match(my, peer) && 542 if (first_kex_follows && !proposals_match(my, peer) &&
@@ -540,30 +551,34 @@ kex_choose_conf(Kex *kex)
540 551
541static u_char * 552static u_char *
542derive_key(Kex *kex, int id, u_int need, u_char *hash, u_int hashlen, 553derive_key(Kex *kex, int id, u_int need, u_char *hash, u_int hashlen,
543 BIGNUM *shared_secret) 554 const u_char *shared_secret, u_int slen)
544{ 555{
545 Buffer b; 556 Buffer b;
546 EVP_MD_CTX md; 557 struct ssh_digest_ctx *hashctx;
547 char c = id; 558 char c = id;
548 u_int have; 559 u_int have;
549 int mdsz; 560 size_t mdsz;
550 u_char *digest; 561 u_char *digest;
551 562
552 if ((mdsz = EVP_MD_size(kex->evp_md)) <= 0) 563 if ((mdsz = ssh_digest_bytes(kex->hash_alg)) == 0)
553 fatal("bad kex md size %d", mdsz); 564 fatal("bad kex md size %zu", mdsz);
554 digest = xmalloc(roundup(need, mdsz)); 565 digest = xmalloc(roundup(need, mdsz));
555 566
556 buffer_init(&b); 567 buffer_init(&b);
557 buffer_put_bignum2(&b, shared_secret); 568 buffer_append(&b, shared_secret, slen);
558 569
559 /* K1 = HASH(K || H || "A" || session_id) */ 570 /* K1 = HASH(K || H || "A" || session_id) */
560 EVP_DigestInit(&md, kex->evp_md); 571 if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL)
561 if (!(datafellows & SSH_BUG_DERIVEKEY)) 572 fatal("%s: ssh_digest_start failed", __func__);
562 EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); 573 if (ssh_digest_update_buffer(hashctx, &b) != 0 ||
563 EVP_DigestUpdate(&md, hash, hashlen); 574 ssh_digest_update(hashctx, hash, hashlen) != 0 ||
564 EVP_DigestUpdate(&md, &c, 1); 575 ssh_digest_update(hashctx, &c, 1) != 0 ||
565 EVP_DigestUpdate(&md, kex->session_id, kex->session_id_len); 576 ssh_digest_update(hashctx, kex->session_id,
566 EVP_DigestFinal(&md, digest, NULL); 577 kex->session_id_len) != 0)
578 fatal("%s: ssh_digest_update failed", __func__);
579 if (ssh_digest_final(hashctx, digest, mdsz) != 0)
580 fatal("%s: ssh_digest_final failed", __func__);
581 ssh_digest_free(hashctx);
567 582
568 /* 583 /*
569 * expand key: 584 * expand key:
@@ -571,12 +586,15 @@ derive_key(Kex *kex, int id, u_int need, u_char *hash, u_int hashlen,
571 * Key = K1 || K2 || ... || Kn 586 * Key = K1 || K2 || ... || Kn
572 */ 587 */
573 for (have = mdsz; need > have; have += mdsz) { 588 for (have = mdsz; need > have; have += mdsz) {
574 EVP_DigestInit(&md, kex->evp_md); 589 if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL)
575 if (!(datafellows & SSH_BUG_DERIVEKEY)) 590 fatal("%s: ssh_digest_start failed", __func__);
576 EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); 591 if (ssh_digest_update_buffer(hashctx, &b) != 0 ||
577 EVP_DigestUpdate(&md, hash, hashlen); 592 ssh_digest_update(hashctx, hash, hashlen) != 0 ||
578 EVP_DigestUpdate(&md, digest, have); 593 ssh_digest_update(hashctx, digest, have) != 0)
579 EVP_DigestFinal(&md, digest + have, NULL); 594 fatal("%s: ssh_digest_update failed", __func__);
595 if (ssh_digest_final(hashctx, digest + have, mdsz) != 0)
596 fatal("%s: ssh_digest_final failed", __func__);
597 ssh_digest_free(hashctx);
580 } 598 }
581 buffer_free(&b); 599 buffer_free(&b);
582#ifdef DEBUG_KEX 600#ifdef DEBUG_KEX
@@ -590,14 +608,15 @@ Newkeys *current_keys[MODE_MAX];
590 608
591#define NKEYS 6 609#define NKEYS 6
592void 610void
593kex_derive_keys(Kex *kex, u_char *hash, u_int hashlen, BIGNUM *shared_secret) 611kex_derive_keys(Kex *kex, u_char *hash, u_int hashlen,
612 const u_char *shared_secret, u_int slen)
594{ 613{
595 u_char *keys[NKEYS]; 614 u_char *keys[NKEYS];
596 u_int i, mode, ctos; 615 u_int i, mode, ctos;
597 616
598 for (i = 0; i < NKEYS; i++) { 617 for (i = 0; i < NKEYS; i++) {
599 keys[i] = derive_key(kex, 'A'+i, kex->we_need, hash, hashlen, 618 keys[i] = derive_key(kex, 'A'+i, kex->we_need, hash, hashlen,
600 shared_secret); 619 shared_secret, slen);
601 } 620 }
602 621
603 debug2("kex_derive_keys"); 622 debug2("kex_derive_keys");
@@ -612,6 +631,18 @@ kex_derive_keys(Kex *kex, u_char *hash, u_int hashlen, BIGNUM *shared_secret)
612 } 631 }
613} 632}
614 633
634void
635kex_derive_keys_bn(Kex *kex, u_char *hash, u_int hashlen, const BIGNUM *secret)
636{
637 Buffer shared_secret;
638
639 buffer_init(&shared_secret);
640 buffer_put_bignum2(&shared_secret, secret);
641 kex_derive_keys(kex, hash, hashlen,
642 buffer_ptr(&shared_secret), buffer_len(&shared_secret));
643 buffer_free(&shared_secret);
644}
645
615Newkeys * 646Newkeys *
616kex_get_newkeys(int mode) 647kex_get_newkeys(int mode)
617{ 648{
@@ -626,33 +657,33 @@ void
626derive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus, 657derive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus,
627 u_int8_t cookie[8], u_int8_t id[16]) 658 u_int8_t cookie[8], u_int8_t id[16])
628{ 659{
629 const EVP_MD *evp_md = EVP_md5(); 660 u_int8_t nbuf[2048], obuf[SSH_DIGEST_MAX_LENGTH];
630 EVP_MD_CTX md;
631 u_int8_t nbuf[2048], obuf[EVP_MAX_MD_SIZE];
632 int len; 661 int len;
662 struct ssh_digest_ctx *hashctx;
633 663
634 EVP_DigestInit(&md, evp_md); 664 if ((hashctx = ssh_digest_start(SSH_DIGEST_MD5)) == NULL)
665 fatal("%s: ssh_digest_start", __func__);
635 666
636 len = BN_num_bytes(host_modulus); 667 len = BN_num_bytes(host_modulus);
637 if (len < (512 / 8) || (u_int)len > sizeof(nbuf)) 668 if (len < (512 / 8) || (u_int)len > sizeof(nbuf))
638 fatal("%s: bad host modulus (len %d)", __func__, len); 669 fatal("%s: bad host modulus (len %d)", __func__, len);
639 BN_bn2bin(host_modulus, nbuf); 670 BN_bn2bin(host_modulus, nbuf);
640 EVP_DigestUpdate(&md, nbuf, len); 671 if (ssh_digest_update(hashctx, nbuf, len) != 0)
672 fatal("%s: ssh_digest_update failed", __func__);
641 673
642 len = BN_num_bytes(server_modulus); 674 len = BN_num_bytes(server_modulus);
643 if (len < (512 / 8) || (u_int)len > sizeof(nbuf)) 675 if (len < (512 / 8) || (u_int)len > sizeof(nbuf))
644 fatal("%s: bad server modulus (len %d)", __func__, len); 676 fatal("%s: bad server modulus (len %d)", __func__, len);
645 BN_bn2bin(server_modulus, nbuf); 677 BN_bn2bin(server_modulus, nbuf);
646 EVP_DigestUpdate(&md, nbuf, len); 678 if (ssh_digest_update(hashctx, nbuf, len) != 0 ||
647 679 ssh_digest_update(hashctx, cookie, 8) != 0)
648 EVP_DigestUpdate(&md, cookie, 8); 680 fatal("%s: ssh_digest_update failed", __func__);
649 681 if (ssh_digest_final(hashctx, obuf, sizeof(obuf)) != 0)
650 EVP_DigestFinal(&md, obuf, NULL); 682 fatal("%s: ssh_digest_final failed", __func__);
651 memcpy(id, obuf, 16); 683 memcpy(id, obuf, ssh_digest_bytes(SSH_DIGEST_MD5));
652 684
653 memset(nbuf, 0, sizeof(nbuf)); 685 memset(nbuf, 0, sizeof(nbuf));
654 memset(obuf, 0, sizeof(obuf)); 686 memset(obuf, 0, sizeof(obuf));
655 memset(&md, 0, sizeof(md));
656} 687}
657 688
658#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH) 689#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH)