summaryrefslogtreecommitdiff
path: root/kex.c
diff options
context:
space:
mode:
Diffstat (limited to 'kex.c')
-rw-r--r--kex.c94
1 files changed, 53 insertions, 41 deletions
diff --git a/kex.c b/kex.c
index b38bae0f0..dbb1a9816 100644
--- a/kex.c
+++ b/kex.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: kex.c,v 1.93 2013/11/07 11:58:27 dtucker Exp $ */ 1/* $OpenBSD: kex.c,v 1.94 2014/01/09 23:20:00 djm 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#if OPENSSL_VERSION_NUMBER >= 0x00907000L 54#if OPENSSL_VERSION_NUMBER >= 0x00907000L
54# if defined(HAVE_EVP_SHA256) 55# if defined(HAVE_EVP_SHA256)
@@ -66,26 +67,30 @@ struct kexalg {
66 char *name; 67 char *name;
67 int type; 68 int type;
68 int ec_nid; 69 int ec_nid;
69 const EVP_MD *(*mdfunc)(void); 70 int hash_alg;
70}; 71};
71static const struct kexalg kexalgs[] = { 72static const struct kexalg kexalgs[] = {
72 { KEX_DH1, KEX_DH_GRP1_SHA1, 0, EVP_sha1 }, 73 { KEX_DH1, KEX_DH_GRP1_SHA1, 0, SSH_DIGEST_SHA1 },
73 { KEX_DH14, KEX_DH_GRP14_SHA1, 0, EVP_sha1 }, 74 { KEX_DH14, KEX_DH_GRP14_SHA1, 0, SSH_DIGEST_SHA1 },
74 { KEX_DHGEX_SHA1, KEX_DH_GEX_SHA1, 0, EVP_sha1 }, 75 { KEX_DHGEX_SHA1, KEX_DH_GEX_SHA1, 0, SSH_DIGEST_SHA1 },
75#ifdef HAVE_EVP_SHA256 76#ifdef HAVE_EVP_SHA256
76 { KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, EVP_sha256 }, 77 { KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, SSH_DIGEST_SHA256 },
77#endif 78#endif
78#ifdef OPENSSL_HAS_ECC 79#ifdef OPENSSL_HAS_ECC
79 { KEX_ECDH_SHA2_NISTP256, KEX_ECDH_SHA2, NID_X9_62_prime256v1, EVP_sha256 }, 80 { KEX_ECDH_SHA2_NISTP256, KEX_ECDH_SHA2,
80 { KEX_ECDH_SHA2_NISTP384, KEX_ECDH_SHA2, NID_secp384r1, EVP_sha384 }, 81 NID_X9_62_prime256v1, SSH_DIGEST_SHA256 },
82 { KEX_ECDH_SHA2_NISTP384, KEX_ECDH_SHA2, NID_secp384r1,
83 SSH_DIGEST_SHA384 },
81# ifdef OPENSSL_HAS_NISTP521 84# ifdef OPENSSL_HAS_NISTP521
82 { KEX_ECDH_SHA2_NISTP521, KEX_ECDH_SHA2, NID_secp521r1, EVP_sha512 }, 85 { KEX_ECDH_SHA2_NISTP521, KEX_ECDH_SHA2, NID_secp521r1,
86 SSH_DIGEST_SHA512 },
83# endif 87# endif
84#endif 88#endif
89 { KEX_DH1, KEX_DH_GRP1_SHA1, 0, SSH_DIGEST_SHA1 },
85#ifdef HAVE_EVP_SHA256 90#ifdef HAVE_EVP_SHA256
86 { KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, EVP_sha256 }, 91 { KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 },
87#endif 92#endif
88 { NULL, -1, -1, NULL}, 93 { NULL, -1, -1, -1},
89}; 94};
90 95
91char * 96char *
@@ -406,7 +411,7 @@ choose_kex(Kex *k, char *client, char *server)
406 if ((kexalg = kex_alg_by_name(k->name)) == NULL) 411 if ((kexalg = kex_alg_by_name(k->name)) == NULL)
407 fatal("unsupported kex alg %s", k->name); 412 fatal("unsupported kex alg %s", k->name);
408 k->kex_type = kexalg->type; 413 k->kex_type = kexalg->type;
409 k->evp_md = kexalg->mdfunc(); 414 k->hash_alg = kexalg->hash_alg;
410 k->ec_nid = kexalg->ec_nid; 415 k->ec_nid = kexalg->ec_nid;
411} 416}
412 417
@@ -532,27 +537,31 @@ derive_key(Kex *kex, int id, u_int need, u_char *hash, u_int hashlen,
532 BIGNUM *shared_secret) 537 BIGNUM *shared_secret)
533{ 538{
534 Buffer b; 539 Buffer b;
535 EVP_MD_CTX md; 540 struct ssh_digest_ctx *hashctx;
536 char c = id; 541 char c = id;
537 u_int have; 542 u_int have;
538 int mdsz; 543 size_t mdsz;
539 u_char *digest; 544 u_char *digest;
540 545
541 if ((mdsz = EVP_MD_size(kex->evp_md)) <= 0) 546 if ((mdsz = ssh_digest_bytes(kex->hash_alg)) == 0)
542 fatal("bad kex md size %d", mdsz); 547 fatal("bad kex md size %zu", mdsz);
543 digest = xmalloc(roundup(need, mdsz)); 548 digest = xmalloc(roundup(need, mdsz));
544 549
545 buffer_init(&b); 550 buffer_init(&b);
546 buffer_put_bignum2(&b, shared_secret); 551 buffer_put_bignum2(&b, shared_secret);
547 552
548 /* K1 = HASH(K || H || "A" || session_id) */ 553 /* K1 = HASH(K || H || "A" || session_id) */
549 EVP_DigestInit(&md, kex->evp_md); 554 if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL)
550 if (!(datafellows & SSH_BUG_DERIVEKEY)) 555 fatal("%s: ssh_digest_start failed", __func__);
551 EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); 556 if (ssh_digest_update_buffer(hashctx, &b) != 0 ||
552 EVP_DigestUpdate(&md, hash, hashlen); 557 ssh_digest_update(hashctx, hash, hashlen) != 0 ||
553 EVP_DigestUpdate(&md, &c, 1); 558 ssh_digest_update(hashctx, &c, 1) != 0 ||
554 EVP_DigestUpdate(&md, kex->session_id, kex->session_id_len); 559 ssh_digest_update(hashctx, kex->session_id,
555 EVP_DigestFinal(&md, digest, NULL); 560 kex->session_id_len) != 0)
561 fatal("%s: ssh_digest_update failed", __func__);
562 if (ssh_digest_final(hashctx, digest, mdsz) != 0)
563 fatal("%s: ssh_digest_final failed", __func__);
564 ssh_digest_free(hashctx);
556 565
557 /* 566 /*
558 * expand key: 567 * expand key:
@@ -560,12 +569,15 @@ derive_key(Kex *kex, int id, u_int need, u_char *hash, u_int hashlen,
560 * Key = K1 || K2 || ... || Kn 569 * Key = K1 || K2 || ... || Kn
561 */ 570 */
562 for (have = mdsz; need > have; have += mdsz) { 571 for (have = mdsz; need > have; have += mdsz) {
563 EVP_DigestInit(&md, kex->evp_md); 572 if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL)
564 if (!(datafellows & SSH_BUG_DERIVEKEY)) 573 fatal("%s: ssh_digest_start failed", __func__);
565 EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); 574 if (ssh_digest_update_buffer(hashctx, &b) != 0 ||
566 EVP_DigestUpdate(&md, hash, hashlen); 575 ssh_digest_update(hashctx, hash, hashlen) != 0 ||
567 EVP_DigestUpdate(&md, digest, have); 576 ssh_digest_update(hashctx, digest, have) != 0)
568 EVP_DigestFinal(&md, digest + have, NULL); 577 fatal("%s: ssh_digest_update failed", __func__);
578 if (ssh_digest_final(hashctx, digest + have, mdsz) != 0)
579 fatal("%s: ssh_digest_final failed", __func__);
580 ssh_digest_free(hashctx);
569 } 581 }
570 buffer_free(&b); 582 buffer_free(&b);
571#ifdef DEBUG_KEX 583#ifdef DEBUG_KEX
@@ -615,33 +627,33 @@ void
615derive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus, 627derive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus,
616 u_int8_t cookie[8], u_int8_t id[16]) 628 u_int8_t cookie[8], u_int8_t id[16])
617{ 629{
618 const EVP_MD *evp_md = EVP_md5(); 630 u_int8_t nbuf[2048], obuf[SSH_DIGEST_MAX_LENGTH];
619 EVP_MD_CTX md;
620 u_int8_t nbuf[2048], obuf[EVP_MAX_MD_SIZE];
621 int len; 631 int len;
632 struct ssh_digest_ctx *hashctx;
622 633
623 EVP_DigestInit(&md, evp_md); 634 if ((hashctx = ssh_digest_start(SSH_DIGEST_MD5)) == NULL)
635 fatal("%s: ssh_digest_start", __func__);
624 636
625 len = BN_num_bytes(host_modulus); 637 len = BN_num_bytes(host_modulus);
626 if (len < (512 / 8) || (u_int)len > sizeof(nbuf)) 638 if (len < (512 / 8) || (u_int)len > sizeof(nbuf))
627 fatal("%s: bad host modulus (len %d)", __func__, len); 639 fatal("%s: bad host modulus (len %d)", __func__, len);
628 BN_bn2bin(host_modulus, nbuf); 640 BN_bn2bin(host_modulus, nbuf);
629 EVP_DigestUpdate(&md, nbuf, len); 641 if (ssh_digest_update(hashctx, nbuf, len) != 0)
642 fatal("%s: ssh_digest_update failed", __func__);
630 643
631 len = BN_num_bytes(server_modulus); 644 len = BN_num_bytes(server_modulus);
632 if (len < (512 / 8) || (u_int)len > sizeof(nbuf)) 645 if (len < (512 / 8) || (u_int)len > sizeof(nbuf))
633 fatal("%s: bad server modulus (len %d)", __func__, len); 646 fatal("%s: bad server modulus (len %d)", __func__, len);
634 BN_bn2bin(server_modulus, nbuf); 647 BN_bn2bin(server_modulus, nbuf);
635 EVP_DigestUpdate(&md, nbuf, len); 648 if (ssh_digest_update(hashctx, nbuf, len) != 0 ||
636 649 ssh_digest_update(hashctx, cookie, 8) != 0)
637 EVP_DigestUpdate(&md, cookie, 8); 650 fatal("%s: ssh_digest_update failed", __func__);
638 651 if (ssh_digest_final(hashctx, obuf, sizeof(obuf)) != 0)
639 EVP_DigestFinal(&md, obuf, NULL); 652 fatal("%s: ssh_digest_final failed", __func__);
640 memcpy(id, obuf, 16); 653 memcpy(id, obuf, ssh_digest_bytes(SSH_DIGEST_MD5));
641 654
642 memset(nbuf, 0, sizeof(nbuf)); 655 memset(nbuf, 0, sizeof(nbuf));
643 memset(obuf, 0, sizeof(obuf)); 656 memset(obuf, 0, sizeof(obuf));
644 memset(&md, 0, sizeof(md));
645} 657}
646 658
647#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH) 659#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH)