summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2014-01-10 10:58:53 +1100
committerDamien Miller <djm@mindrot.org>2014-01-10 10:58:53 +1100
commitb3051d01e505c9c2dc00faab472a0d06fa6b0e65 (patch)
treec0ca49b5fc4e5e1a066157b4dbd9c68cfcd41d63
parente00e413dd16eb747fb2c15a099971d91c13cf70f (diff)
- djm@cvs.openbsd.org 2014/01/09 23:20:00
[digest.c digest.h hostfile.c kex.c kex.h kexc25519.c kexc25519c.c] [kexc25519s.c kexdh.c kexecdh.c kexecdhc.c kexecdhs.c kexgex.c kexgexc.c] [kexgexs.c key.c key.h roaming_client.c roaming_common.c schnorr.c] [schnorr.h ssh-dss.c ssh-ecdsa.c ssh-rsa.c sshconnect2.c] Introduce digest API and use it to perform all hashing operations rather than calling OpenSSL EVP_Digest* directly. Will make it easier to build a reduced-feature OpenSSH without OpenSSL in future; feedback, ok markus@
-rw-r--r--ChangeLog9
-rw-r--r--Makefile.in4
-rw-r--r--digest.c148
-rw-r--r--digest.h55
-rw-r--r--hostfile.c3
-rw-r--r--kex.c94
-rw-r--r--kex.h10
-rw-r--r--kexc25519.c17
-rw-r--r--kexc25519c.c4
-rw-r--r--kexc25519s.c4
-rw-r--r--kexdh.c17
-rw-r--r--kexecdh.c18
-rw-r--r--kexecdhc.c4
-rw-r--r--kexecdhs.c4
-rw-r--r--kexgex.c24
-rw-r--r--kexgexc.c4
-rw-r--r--kexgexs.c4
-rw-r--r--key.c42
-rw-r--r--key.h4
-rw-r--r--roaming_client.c14
-rw-r--r--roaming_common.c14
-rw-r--r--schnorr.c57
-rw-r--r--schnorr.h8
-rw-r--r--ssh-dss.c31
-rw-r--r--ssh-ecdsa.c42
-rw-r--r--ssh-rsa.c54
-rw-r--r--sshconnect2.c4
27 files changed, 458 insertions, 235 deletions
diff --git a/ChangeLog b/ChangeLog
index df1d5ea6a..a1d37bc25 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -9,6 +9,15 @@
9 with the year, and rearrange a comparison to avoid a potentional signed 9 with the year, and rearrange a comparison to avoid a potentional signed
10 arithmetic overflow that would give the wrong result. 10 arithmetic overflow that would give the wrong result.
11 ok djm@ 11 ok djm@
12 - djm@cvs.openbsd.org 2014/01/09 23:20:00
13 [digest.c digest.h hostfile.c kex.c kex.h kexc25519.c kexc25519c.c]
14 [kexc25519s.c kexdh.c kexecdh.c kexecdhc.c kexecdhs.c kexgex.c kexgexc.c]
15 [kexgexs.c key.c key.h roaming_client.c roaming_common.c schnorr.c]
16 [schnorr.h ssh-dss.c ssh-ecdsa.c ssh-rsa.c sshconnect2.c]
17 Introduce digest API and use it to perform all hashing operations
18 rather than calling OpenSSL EVP_Digest* directly. Will make it easier
19 to build a reduced-feature OpenSSH without OpenSSL in future;
20 feedback, ok markus@
12 21
1320140108 2220140108
14 - (djm) [regress/.cvsignore] Ignore regress test droppings; ok dtucker@ 23 - (djm) [regress/.cvsignore] Ignore regress test droppings; ok dtucker@
diff --git a/Makefile.in b/Makefile.in
index e789b476a..4a930c665 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,4 +1,4 @@
1# $Id: Makefile.in,v 1.348 2013/12/08 04:53:28 djm Exp $ 1# $Id: Makefile.in,v 1.349 2014/01/09 23:58:53 djm Exp $
2 2
3# uncomment if you run a non bourne compatable shell. Ie. csh 3# uncomment if you run a non bourne compatable shell. Ie. csh
4#SHELL = @SH@ 4#SHELL = @SH@
@@ -75,7 +75,7 @@ LIBSSH_OBJS=authfd.o authfile.o bufaux.o bufbn.o buffer.o \
75 msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ 75 msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \
76 jpake.o schnorr.o ssh-pkcs11.o krl.o smult_curve25519_ref.o \ 76 jpake.o schnorr.o ssh-pkcs11.o krl.o smult_curve25519_ref.o \
77 kexc25519.o kexc25519c.o poly1305.o chacha.o cipher-chachapoly.o \ 77 kexc25519.o kexc25519c.o poly1305.o chacha.o cipher-chachapoly.o \
78 ssh-ed25519.o \ 78 ssh-ed25519.o digest.o \
79 sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o blocks.o \ 79 sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o blocks.o \
80 80
81SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ 81SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
diff --git a/digest.c b/digest.c
new file mode 100644
index 000000000..59a8ffe0d
--- /dev/null
+++ b/digest.c
@@ -0,0 +1,148 @@
1/* $OpenBSD: digest.c,v 1.1 2014/01/09 23:20:00 djm Exp $ */
2/*
3 * Copyright (c) 2013 Damien Miller <djm@mindrot.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include "includes.h"
19
20#include <sys/types.h>
21#include <limits.h>
22#include <stdlib.h>
23#include <string.h>
24
25#include <openssl/bn.h> /* for buffer.h */
26#include <openssl/ec.h> /* for buffer.h */
27#include <openssl/evp.h>
28
29#include "buffer.h"
30#include "digest.h"
31
32struct ssh_digest_ctx {
33 int alg;
34 EVP_MD_CTX mdctx;
35};
36
37struct ssh_digest {
38 int id;
39 const char *name;
40 size_t digest_len;
41 const EVP_MD *(*mdfunc)(void);
42};
43
44/* NB. Indexed directly by algorithm number */
45const struct ssh_digest digests[] = {
46 { SSH_DIGEST_MD5, "MD5", 16, EVP_md5 },
47 { SSH_DIGEST_RIPEMD160, "RIPEMD160", 20, EVP_ripemd160 },
48 { SSH_DIGEST_SHA1, "SHA1", 20, EVP_sha1 },
49#ifdef HAVE_EVP_SHA256 /* XXX replace with local if missing */
50 { SSH_DIGEST_SHA256, "SHA256", 32, EVP_sha256 },
51 { SSH_DIGEST_SHA384, "SHA384", 48, EVP_sha384 },
52 { SSH_DIGEST_SHA512, "SHA512", 64, EVP_sha512 },
53#endif
54 { -1, NULL, 0, NULL },
55};
56
57static const struct ssh_digest *
58ssh_digest_by_alg(int alg)
59{
60 if (alg < 0 || alg >= SSH_DIGEST_MAX)
61 return NULL;
62 if (digests[alg].id != alg) /* sanity */
63 return NULL;
64 return &(digests[alg]);
65}
66
67size_t
68ssh_digest_bytes(int alg)
69{
70 const struct ssh_digest *digest = ssh_digest_by_alg(alg);
71
72 return digest == NULL ? 0 : digest->digest_len;
73}
74
75struct ssh_digest_ctx *
76ssh_digest_start(int alg)
77{
78 const struct ssh_digest *digest = ssh_digest_by_alg(alg);
79 struct ssh_digest_ctx *ret;
80
81 if (digest == NULL || ((ret = calloc(1, sizeof(*ret))) == NULL))
82 return NULL;
83 ret->alg = alg;
84 EVP_MD_CTX_init(&ret->mdctx);
85 if (EVP_DigestInit_ex(&ret->mdctx, digest->mdfunc(), NULL) != 1) {
86 free(ret);
87 return NULL;
88 }
89 return ret;
90}
91
92int
93ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen)
94{
95 if (EVP_DigestUpdate(&ctx->mdctx, m, mlen) != 1)
96 return -1;
97 return 0;
98}
99
100int
101ssh_digest_update_buffer(struct ssh_digest_ctx *ctx, const Buffer *b)
102{
103 return ssh_digest_update(ctx, buffer_ptr(b), buffer_len(b));
104}
105
106int
107ssh_digest_final(struct ssh_digest_ctx *ctx, u_char *d, size_t dlen)
108{
109 const struct ssh_digest *digest = ssh_digest_by_alg(ctx->alg);
110 u_int l = dlen;
111
112 if (dlen > UINT_MAX)
113 return -1;
114 if (dlen < digest->digest_len) /* No truncation allowed */
115 return -1;
116 if (EVP_DigestFinal_ex(&ctx->mdctx, d, &l) != 1)
117 return -1;
118 if (l != digest->digest_len) /* sanity */
119 return -1;
120 return 0;
121}
122
123void
124ssh_digest_free(struct ssh_digest_ctx *ctx)
125{
126 EVP_MD_CTX_cleanup(&ctx->mdctx);
127 memset(ctx, 0, sizeof(*ctx));
128}
129
130int
131ssh_digest_memory(int alg, const void *m, size_t mlen, u_char *d, size_t dlen)
132{
133 struct ssh_digest_ctx *ctx = ssh_digest_start(alg);
134
135 if (ctx == NULL)
136 return -1;
137 if (ssh_digest_update(ctx, m, mlen) != 0 ||
138 ssh_digest_final(ctx, d, dlen) != 0)
139 return -1;
140 ssh_digest_free(ctx);
141 return 0;
142}
143
144int
145ssh_digest_buffer(int alg, const Buffer *b, u_char *d, size_t dlen)
146{
147 return ssh_digest_memory(alg, buffer_ptr(b), buffer_len(b), d, dlen);
148}
diff --git a/digest.h b/digest.h
new file mode 100644
index 000000000..faefda3f5
--- /dev/null
+++ b/digest.h
@@ -0,0 +1,55 @@
1/* $OpenBSD: digest.h,v 1.1 2014/01/09 23:20:00 djm Exp $ */
2/*
3 * Copyright (c) 2013 Damien Miller <djm@mindrot.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#ifndef _DIGEST_H
19#define _DIGEST_H
20
21/* Maximum digest output length */
22#define SSH_DIGEST_MAX_LENGTH 64
23
24/* Digest algorithms */
25#define SSH_DIGEST_MD5 0
26#define SSH_DIGEST_RIPEMD160 1
27#define SSH_DIGEST_SHA1 2
28#define SSH_DIGEST_SHA256 3
29#define SSH_DIGEST_SHA384 4
30#define SSH_DIGEST_SHA512 5
31#define SSH_DIGEST_MAX 6
32
33/* Returns the algorithm's digest length in bytes or 0 for invalid algorithm */
34size_t ssh_digest_bytes(int alg);
35
36/* One-shot API */
37int ssh_digest_memory(int alg, const void *m, size_t mlen,
38 u_char *d, size_t dlen)
39 __attribute__((__bounded__(__buffer__, 2, 3)))
40 __attribute__((__bounded__(__buffer__, 4, 5)));
41int ssh_digest_buffer(int alg, const Buffer *b, u_char *d, size_t dlen)
42 __attribute__((__bounded__(__buffer__, 3, 4)));
43
44/* Update API */
45struct ssh_digest_ctx;
46struct ssh_digest_ctx *ssh_digest_start(int alg);
47int ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen)
48 __attribute__((__bounded__(__buffer__, 2, 3)));
49int ssh_digest_update_buffer(struct ssh_digest_ctx *ctx, const Buffer *b);
50int ssh_digest_final(struct ssh_digest_ctx *ctx, u_char *d, size_t dlen)
51 __attribute__((__bounded__(__buffer__, 2, 3)));
52void ssh_digest_free(struct ssh_digest_ctx *ctx);
53
54#endif /* _DIGEST_H */
55
diff --git a/hostfile.c b/hostfile.c
index 2ff4c48b4..2778fb5df 100644
--- a/hostfile.c
+++ b/hostfile.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: hostfile.c,v 1.52 2013/07/12 00:19:58 djm Exp $ */ 1/* $OpenBSD: hostfile.c,v 1.53 2014/01/09 23:20:00 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -57,6 +57,7 @@
57#include "hostfile.h" 57#include "hostfile.h"
58#include "log.h" 58#include "log.h"
59#include "misc.h" 59#include "misc.h"
60#include "digest.h"
60 61
61struct hostkeys { 62struct hostkeys {
62 struct hostkey_entry *entries; 63 struct hostkey_entry *entries;
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)
diff --git a/kex.h b/kex.h
index 800a69233..fbe4940e8 100644
--- a/kex.h
+++ b/kex.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: kex.h,v 1.58 2013/11/07 11:58:27 dtucker Exp $ */ 1/* $OpenBSD: kex.h,v 1.59 2014/01/09 23:20:00 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 4 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@@ -133,7 +133,7 @@ struct Kex {
133 Buffer peer; 133 Buffer peer;
134 sig_atomic_t done; 134 sig_atomic_t done;
135 int flags; 135 int flags;
136 const EVP_MD *evp_md; 136 int hash_alg;
137 int ec_nid; 137 int ec_nid;
138 char *client_version_string; 138 char *client_version_string;
139 char *server_version_string; 139 char *server_version_string;
@@ -170,17 +170,17 @@ void
170kex_dh_hash(char *, char *, char *, int, char *, int, u_char *, int, 170kex_dh_hash(char *, char *, char *, int, char *, int, u_char *, int,
171 BIGNUM *, BIGNUM *, BIGNUM *, u_char **, u_int *); 171 BIGNUM *, BIGNUM *, BIGNUM *, u_char **, u_int *);
172void 172void
173kexgex_hash(const EVP_MD *, char *, char *, char *, int, char *, 173kexgex_hash(int, char *, char *, char *, int, char *,
174 int, u_char *, int, int, int, int, BIGNUM *, BIGNUM *, BIGNUM *, 174 int, u_char *, int, int, int, int, BIGNUM *, BIGNUM *, BIGNUM *,
175 BIGNUM *, BIGNUM *, u_char **, u_int *); 175 BIGNUM *, BIGNUM *, u_char **, u_int *);
176#ifdef OPENSSL_HAS_ECC 176#ifdef OPENSSL_HAS_ECC
177void 177void
178kex_ecdh_hash(const EVP_MD *, const EC_GROUP *, char *, char *, char *, int, 178kex_ecdh_hash(int, const EC_GROUP *, char *, char *, char *, int,
179 char *, int, u_char *, int, const EC_POINT *, const EC_POINT *, 179 char *, int, u_char *, int, const EC_POINT *, const EC_POINT *,
180 const BIGNUM *, u_char **, u_int *); 180 const BIGNUM *, u_char **, u_int *);
181#endif 181#endif
182void 182void
183kex_c25519_hash(const EVP_MD *, char *, char *, char *, int, 183kex_c25519_hash(int, char *, char *, char *, int,
184 char *, int, u_char *, int, const u_char *, const u_char *, 184 char *, int, u_char *, int, const u_char *, const u_char *,
185 const BIGNUM *, u_char **, u_int *); 185 const BIGNUM *, u_char **, u_int *);
186 186
diff --git a/kexc25519.c b/kexc25519.c
index 348a7d50d..8dd363991 100644
--- a/kexc25519.c
+++ b/kexc25519.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: kexc25519.c,v 1.2 2013/11/02 22:02:14 markus Exp $ */ 1/* $OpenBSD: kexc25519.c,v 1.3 2014/01/09 23:20:00 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2001, 2013 Markus Friedl. All rights reserved. 3 * Copyright (c) 2001, 2013 Markus Friedl. All rights reserved.
4 * Copyright (c) 2010 Damien Miller. All rights reserved. 4 * Copyright (c) 2010 Damien Miller. All rights reserved.
@@ -41,6 +41,7 @@
41#include "cipher.h" 41#include "cipher.h"
42#include "kex.h" 42#include "kex.h"
43#include "log.h" 43#include "log.h"
44#include "digest.h"
44 45
45extern int crypto_scalarmult_curve25519(u_char a[CURVE25519_SIZE], 46extern int crypto_scalarmult_curve25519(u_char a[CURVE25519_SIZE],
46 const u_char b[CURVE25519_SIZE], const u_char c[CURVE25519_SIZE]) 47 const u_char b[CURVE25519_SIZE], const u_char c[CURVE25519_SIZE])
@@ -78,7 +79,7 @@ kexc25519_shared_key(const u_char key[CURVE25519_SIZE],
78 79
79void 80void
80kex_c25519_hash( 81kex_c25519_hash(
81 const EVP_MD *evp_md, 82 int hash_alg,
82 char *client_version_string, 83 char *client_version_string,
83 char *server_version_string, 84 char *server_version_string,
84 char *ckexinit, int ckexinitlen, 85 char *ckexinit, int ckexinitlen,
@@ -90,8 +91,7 @@ kex_c25519_hash(
90 u_char **hash, u_int *hashlen) 91 u_char **hash, u_int *hashlen)
91{ 92{
92 Buffer b; 93 Buffer b;
93 EVP_MD_CTX md; 94 static u_char digest[SSH_DIGEST_MAX_LENGTH];
94 static u_char digest[EVP_MAX_MD_SIZE];
95 95
96 buffer_init(&b); 96 buffer_init(&b);
97 buffer_put_cstring(&b, client_version_string); 97 buffer_put_cstring(&b, client_version_string);
@@ -113,15 +113,14 @@ kex_c25519_hash(
113#ifdef DEBUG_KEX 113#ifdef DEBUG_KEX
114 buffer_dump(&b); 114 buffer_dump(&b);
115#endif 115#endif
116 EVP_DigestInit(&md, evp_md); 116 if (ssh_digest_buffer(hash_alg, &b, digest, sizeof(digest)) != 0)
117 EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); 117 fatal("%s: digest_buffer failed", __func__);
118 EVP_DigestFinal(&md, digest, NULL);
119 118
120 buffer_free(&b); 119 buffer_free(&b);
121 120
122#ifdef DEBUG_KEX 121#ifdef DEBUG_KEX
123 dump_digest("hash", digest, EVP_MD_size(evp_md)); 122 dump_digest("hash", digest, ssh_digest_bytes(hash_alg));
124#endif 123#endif
125 *hash = digest; 124 *hash = digest;
126 *hashlen = EVP_MD_size(evp_md); 125 *hashlen = ssh_digest_bytes(hash_alg);
127} 126}
diff --git a/kexc25519c.c b/kexc25519c.c
index f741566cc..4655c2542 100644
--- a/kexc25519c.c
+++ b/kexc25519c.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: kexc25519c.c,v 1.2 2013/11/02 22:02:14 markus Exp $ */ 1/* $OpenBSD: kexc25519c.c,v 1.3 2014/01/09 23:20:00 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2001 Markus Friedl. All rights reserved.
4 * Copyright (c) 2010 Damien Miller. All rights reserved. 4 * Copyright (c) 2010 Damien Miller. All rights reserved.
@@ -97,7 +97,7 @@ kexc25519_client(Kex *kex)
97 97
98 /* calc and verify H */ 98 /* calc and verify H */
99 kex_c25519_hash( 99 kex_c25519_hash(
100 kex->evp_md, 100 kex->hash_alg,
101 kex->client_version_string, 101 kex->client_version_string,
102 kex->server_version_string, 102 kex->server_version_string,
103 buffer_ptr(&kex->my), buffer_len(&kex->my), 103 buffer_ptr(&kex->my), buffer_len(&kex->my),
diff --git a/kexc25519s.c b/kexc25519s.c
index 784841b82..dc4f56c80 100644
--- a/kexc25519s.c
+++ b/kexc25519s.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: kexc25519s.c,v 1.2 2013/11/02 22:02:14 markus Exp $ */ 1/* $OpenBSD: kexc25519s.c,v 1.3 2014/01/09 23:20:00 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2001 Markus Friedl. All rights reserved.
4 * Copyright (c) 2010 Damien Miller. All rights reserved. 4 * Copyright (c) 2010 Damien Miller. All rights reserved.
@@ -81,7 +81,7 @@ kexc25519_server(Kex *kex)
81 /* calc H */ 81 /* calc H */
82 key_to_blob(server_host_public, &server_host_key_blob, &sbloblen); 82 key_to_blob(server_host_public, &server_host_key_blob, &sbloblen);
83 kex_c25519_hash( 83 kex_c25519_hash(
84 kex->evp_md, 84 kex->hash_alg,
85 kex->client_version_string, 85 kex->client_version_string,
86 kex->server_version_string, 86 kex->server_version_string,
87 buffer_ptr(&kex->peer), buffer_len(&kex->peer), 87 buffer_ptr(&kex->peer), buffer_len(&kex->peer),
diff --git a/kexdh.c b/kexdh.c
index 56e22f5bc..e7cdadc90 100644
--- a/kexdh.c
+++ b/kexdh.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: kexdh.c,v 1.23 2006/08/03 03:34:42 deraadt Exp $ */ 1/* $OpenBSD: kexdh.c,v 1.24 2014/01/09 23:20:00 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2001 Markus Friedl. All rights reserved.
4 * 4 *
@@ -36,6 +36,8 @@
36#include "key.h" 36#include "key.h"
37#include "cipher.h" 37#include "cipher.h"
38#include "kex.h" 38#include "kex.h"
39#include "digest.h"
40#include "log.h"
39 41
40void 42void
41kex_dh_hash( 43kex_dh_hash(
@@ -50,9 +52,7 @@ kex_dh_hash(
50 u_char **hash, u_int *hashlen) 52 u_char **hash, u_int *hashlen)
51{ 53{
52 Buffer b; 54 Buffer b;
53 static u_char digest[EVP_MAX_MD_SIZE]; 55 static u_char digest[SSH_DIGEST_MAX_LENGTH];
54 const EVP_MD *evp_md = EVP_sha1();
55 EVP_MD_CTX md;
56 56
57 buffer_init(&b); 57 buffer_init(&b);
58 buffer_put_cstring(&b, client_version_string); 58 buffer_put_cstring(&b, client_version_string);
@@ -74,15 +74,14 @@ kex_dh_hash(
74#ifdef DEBUG_KEX 74#ifdef DEBUG_KEX
75 buffer_dump(&b); 75 buffer_dump(&b);
76#endif 76#endif
77 EVP_DigestInit(&md, evp_md); 77 if (ssh_digest_buffer(SSH_DIGEST_SHA1, &b, digest, sizeof(digest)) != 0)
78 EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); 78 fatal("%s: ssh_digest_buffer failed", __func__);
79 EVP_DigestFinal(&md, digest, NULL);
80 79
81 buffer_free(&b); 80 buffer_free(&b);
82 81
83#ifdef DEBUG_KEX 82#ifdef DEBUG_KEX
84 dump_digest("hash", digest, EVP_MD_size(evp_md)); 83 dump_digest("hash", digest, ssh_digest_bytes(SSH_DIGEST_SHA1));
85#endif 84#endif
86 *hash = digest; 85 *hash = digest;
87 *hashlen = EVP_MD_size(evp_md); 86 *hashlen = ssh_digest_bytes(SSH_DIGEST_SHA1);
88} 87}
diff --git a/kexecdh.c b/kexecdh.c
index c948fe20a..c52c5e234 100644
--- a/kexecdh.c
+++ b/kexecdh.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: kexecdh.c,v 1.4 2013/04/19 01:06:50 djm Exp $ */ 1/* $OpenBSD: kexecdh.c,v 1.5 2014/01/09 23:20:00 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2001 Markus Friedl. All rights reserved.
4 * Copyright (c) 2010 Damien Miller. All rights reserved. 4 * Copyright (c) 2010 Damien Miller. All rights reserved.
@@ -44,10 +44,11 @@
44#include "cipher.h" 44#include "cipher.h"
45#include "kex.h" 45#include "kex.h"
46#include "log.h" 46#include "log.h"
47#include "digest.h"
47 48
48void 49void
49kex_ecdh_hash( 50kex_ecdh_hash(
50 const EVP_MD *evp_md, 51 int hash_alg,
51 const EC_GROUP *ec_group, 52 const EC_GROUP *ec_group,
52 char *client_version_string, 53 char *client_version_string,
53 char *server_version_string, 54 char *server_version_string,
@@ -60,8 +61,7 @@ kex_ecdh_hash(
60 u_char **hash, u_int *hashlen) 61 u_char **hash, u_int *hashlen)
61{ 62{
62 Buffer b; 63 Buffer b;
63 EVP_MD_CTX md; 64 static u_char digest[SSH_DIGEST_MAX_LENGTH];
64 static u_char digest[EVP_MAX_MD_SIZE];
65 65
66 buffer_init(&b); 66 buffer_init(&b);
67 buffer_put_cstring(&b, client_version_string); 67 buffer_put_cstring(&b, client_version_string);
@@ -83,17 +83,15 @@ kex_ecdh_hash(
83#ifdef DEBUG_KEX 83#ifdef DEBUG_KEX
84 buffer_dump(&b); 84 buffer_dump(&b);
85#endif 85#endif
86 EVP_DigestInit(&md, evp_md); 86 if (ssh_digest_buffer(hash_alg, &b, digest, sizeof(digest)) != 0)
87 EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); 87 fatal("%s: ssh_digest_buffer failed", __func__);
88 EVP_DigestFinal(&md, digest, NULL);
89 88
90 buffer_free(&b); 89 buffer_free(&b);
91 90
92#ifdef DEBUG_KEX 91#ifdef DEBUG_KEX
93 dump_digest("hash", digest, EVP_MD_size(evp_md)); 92 dump_digest("hash", digest, ssh_digest_bytes(hash_alg));
94#endif 93#endif
95 *hash = digest; 94 *hash = digest;
96 *hashlen = EVP_MD_size(evp_md); 95 *hashlen = ssh_digest_bytes(hash_alg);
97} 96}
98
99#endif /* OPENSSL_HAS_ECC */ 97#endif /* OPENSSL_HAS_ECC */
diff --git a/kexecdhc.c b/kexecdhc.c
index 6193836c7..fc62cec55 100644
--- a/kexecdhc.c
+++ b/kexecdhc.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: kexecdhc.c,v 1.4 2013/05/17 00:13:13 djm Exp $ */ 1/* $OpenBSD: kexecdhc.c,v 1.5 2014/01/09 23:20:00 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2001 Markus Friedl. All rights reserved.
4 * Copyright (c) 2010 Damien Miller. All rights reserved. 4 * Copyright (c) 2010 Damien Miller. All rights reserved.
@@ -124,7 +124,7 @@ kexecdh_client(Kex *kex)
124 124
125 /* calc and verify H */ 125 /* calc and verify H */
126 kex_ecdh_hash( 126 kex_ecdh_hash(
127 kex->evp_md, 127 kex->hash_alg,
128 group, 128 group,
129 kex->client_version_string, 129 kex->client_version_string,
130 kex->server_version_string, 130 kex->server_version_string,
diff --git a/kexecdhs.c b/kexecdhs.c
index 431fd2c2c..d1dd8c7fb 100644
--- a/kexecdhs.c
+++ b/kexecdhs.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: kexecdhs.c,v 1.7 2013/11/02 22:24:24 markus Exp $ */ 1/* $OpenBSD: kexecdhs.c,v 1.8 2014/01/09 23:20:00 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2001 Markus Friedl. All rights reserved.
4 * Copyright (c) 2010 Damien Miller. All rights reserved. 4 * Copyright (c) 2010 Damien Miller. All rights reserved.
@@ -109,7 +109,7 @@ kexecdh_server(Kex *kex)
109 /* calc H */ 109 /* calc H */
110 key_to_blob(server_host_public, &server_host_key_blob, &sbloblen); 110 key_to_blob(server_host_public, &server_host_key_blob, &sbloblen);
111 kex_ecdh_hash( 111 kex_ecdh_hash(
112 kex->evp_md, 112 kex->hash_alg,
113 group, 113 group,
114 kex->client_version_string, 114 kex->client_version_string,
115 kex->server_version_string, 115 kex->server_version_string,
diff --git a/kexgex.c b/kexgex.c
index b60ab5c53..c2e6bc16d 100644
--- a/kexgex.c
+++ b/kexgex.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: kexgex.c,v 1.27 2006/08/03 03:34:42 deraadt Exp $ */ 1/* $OpenBSD: kexgex.c,v 1.28 2014/01/09 23:20:00 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Niels Provos. All rights reserved. 3 * Copyright (c) 2000 Niels Provos. All rights reserved.
4 * Copyright (c) 2001 Markus Friedl. All rights reserved. 4 * Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -36,10 +36,12 @@
36#include "cipher.h" 36#include "cipher.h"
37#include "kex.h" 37#include "kex.h"
38#include "ssh2.h" 38#include "ssh2.h"
39#include "digest.h"
40#include "log.h"
39 41
40void 42void
41kexgex_hash( 43kexgex_hash(
42 const EVP_MD *evp_md, 44 int hash_alg,
43 char *client_version_string, 45 char *client_version_string,
44 char *server_version_string, 46 char *server_version_string,
45 char *ckexinit, int ckexinitlen, 47 char *ckexinit, int ckexinitlen,
@@ -52,8 +54,7 @@ kexgex_hash(
52 u_char **hash, u_int *hashlen) 54 u_char **hash, u_int *hashlen)
53{ 55{
54 Buffer b; 56 Buffer b;
55 static u_char digest[EVP_MAX_MD_SIZE]; 57 static u_char digest[SSH_DIGEST_MAX_LENGTH];
56 EVP_MD_CTX md;
57 58
58 buffer_init(&b); 59 buffer_init(&b);
59 buffer_put_cstring(&b, client_version_string); 60 buffer_put_cstring(&b, client_version_string);
@@ -84,15 +85,14 @@ kexgex_hash(
84#ifdef DEBUG_KEXDH 85#ifdef DEBUG_KEXDH
85 buffer_dump(&b); 86 buffer_dump(&b);
86#endif 87#endif
87 88 if (ssh_digest_buffer(hash_alg, &b, digest, sizeof(digest)) != 0)
88 EVP_DigestInit(&md, evp_md); 89 fatal("%s: ssh_digest_buffer failed", __func__);
89 EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
90 EVP_DigestFinal(&md, digest, NULL);
91 90
92 buffer_free(&b); 91 buffer_free(&b);
93 *hash = digest; 92
94 *hashlen = EVP_MD_size(evp_md); 93#ifdef DEBUG_KEX
95#ifdef DEBUG_KEXDH 94 dump_digest("hash", digest, ssh_digest_bytes(hash_alg));
96 dump_digest("hash", digest, *hashlen);
97#endif 95#endif
96 *hash = digest;
97 *hashlen = ssh_digest_bytes(hash_alg);
98} 98}
diff --git a/kexgexc.c b/kexgexc.c
index 5a3be2005..ca771edfe 100644
--- a/kexgexc.c
+++ b/kexgexc.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: kexgexc.c,v 1.13 2013/05/17 00:13:13 djm Exp $ */ 1/* $OpenBSD: kexgexc.c,v 1.14 2014/01/09 23:20:00 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Niels Provos. All rights reserved. 3 * Copyright (c) 2000 Niels Provos. All rights reserved.
4 * Copyright (c) 2001 Markus Friedl. All rights reserved. 4 * Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -170,7 +170,7 @@ kexgex_client(Kex *kex)
170 170
171 /* calc and verify H */ 171 /* calc and verify H */
172 kexgex_hash( 172 kexgex_hash(
173 kex->evp_md, 173 kex->hash_alg,
174 kex->client_version_string, 174 kex->client_version_string,
175 kex->server_version_string, 175 kex->server_version_string,
176 buffer_ptr(&kex->my), buffer_len(&kex->my), 176 buffer_ptr(&kex->my), buffer_len(&kex->my),
diff --git a/kexgexs.c b/kexgexs.c
index 4e473fc73..90853403e 100644
--- a/kexgexs.c
+++ b/kexgexs.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: kexgexs.c,v 1.16 2013/07/19 07:37:48 markus Exp $ */ 1/* $OpenBSD: kexgexs.c,v 1.17 2014/01/09 23:20:00 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Niels Provos. All rights reserved. 3 * Copyright (c) 2000 Niels Provos. All rights reserved.
4 * Copyright (c) 2001 Markus Friedl. All rights reserved. 4 * Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -160,7 +160,7 @@ kexgex_server(Kex *kex)
160 160
161 /* calc H */ 161 /* calc H */
162 kexgex_hash( 162 kexgex_hash(
163 kex->evp_md, 163 kex->hash_alg,
164 kex->client_version_string, 164 kex->client_version_string,
165 kex->server_version_string, 165 kex->server_version_string,
166 buffer_ptr(&kex->peer), buffer_len(&kex->peer), 166 buffer_ptr(&kex->peer), buffer_len(&kex->peer),
diff --git a/key.c b/key.c
index b0bb46f3d..914233808 100644
--- a/key.c
+++ b/key.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: key.c,v 1.114 2013/12/29 04:20:04 djm Exp $ */ 1/* $OpenBSD: key.c,v 1.115 2014/01/09 23:20:00 djm Exp $ */
2/* 2/*
3 * read_bignum(): 3 * read_bignum():
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -56,6 +56,7 @@
56#include "log.h" 56#include "log.h"
57#include "misc.h" 57#include "misc.h"
58#include "ssh2.h" 58#include "ssh2.h"
59#include "digest.h"
59 60
60static int to_blob(const Key *, u_char **, u_int *, int); 61static int to_blob(const Key *, u_char **, u_int *, int);
61static Key *key_from_blob2(const u_char *, u_int, int); 62static Key *key_from_blob2(const u_char *, u_int, int);
@@ -358,30 +359,26 @@ u_char*
358key_fingerprint_raw(const Key *k, enum fp_type dgst_type, 359key_fingerprint_raw(const Key *k, enum fp_type dgst_type,
359 u_int *dgst_raw_length) 360 u_int *dgst_raw_length)
360{ 361{
361 const EVP_MD *md = NULL;
362 EVP_MD_CTX ctx;
363 u_char *blob = NULL; 362 u_char *blob = NULL;
364 u_char *retval = NULL; 363 u_char *retval = NULL;
365 u_int len = 0; 364 u_int len = 0;
366 int nlen, elen; 365 int nlen, elen, hash_alg = -1;
367 366
368 *dgst_raw_length = 0; 367 *dgst_raw_length = 0;
369 368
369 /* XXX switch to DIGEST_* directly? */
370 switch (dgst_type) { 370 switch (dgst_type) {
371 case SSH_FP_MD5: 371 case SSH_FP_MD5:
372 md = EVP_md5(); 372 hash_alg = SSH_DIGEST_MD5;
373 break; 373 break;
374 case SSH_FP_SHA1: 374 case SSH_FP_SHA1:
375 md = EVP_sha1(); 375 hash_alg = SSH_DIGEST_SHA1;
376 break; 376 break;
377#ifdef HAVE_EVP_SHA256
378 case SSH_FP_SHA256: 377 case SSH_FP_SHA256:
379 md = EVP_sha256(); 378 hash_alg = SSH_DIGEST_SHA256;
380 break; 379 break;
381#endif
382 default: 380 default:
383 fatal("key_fingerprint_raw: bad digest type %d", 381 fatal("%s: bad digest type %d", __func__, dgst_type);
384 dgst_type);
385 } 382 }
386 switch (k->type) { 383 switch (k->type) {
387 case KEY_RSA1: 384 case KEY_RSA1:
@@ -410,18 +407,19 @@ key_fingerprint_raw(const Key *k, enum fp_type dgst_type,
410 case KEY_UNSPEC: 407 case KEY_UNSPEC:
411 return retval; 408 return retval;
412 default: 409 default:
413 fatal("key_fingerprint_raw: bad key type %d", k->type); 410 fatal("%s: bad key type %d", __func__, k->type);
414 break; 411 break;
415 } 412 }
416 if (blob != NULL) { 413 if (blob != NULL) {
417 retval = xmalloc(EVP_MAX_MD_SIZE); 414 retval = xmalloc(SSH_DIGEST_MAX_LENGTH);
418 EVP_DigestInit(&ctx, md); 415 if ((ssh_digest_memory(hash_alg, blob, len,
419 EVP_DigestUpdate(&ctx, blob, len); 416 retval, SSH_DIGEST_MAX_LENGTH)) != 0)
420 EVP_DigestFinal(&ctx, retval, dgst_raw_length); 417 fatal("%s: digest_memory failed", __func__);
421 memset(blob, 0, len); 418 memset(blob, 0, len);
422 free(blob); 419 free(blob);
420 *dgst_raw_length = ssh_digest_bytes(hash_alg);
423 } else { 421 } else {
424 fatal("key_fingerprint_raw: blob is null"); 422 fatal("%s: blob is null", __func__);
425 } 423 }
426 return retval; 424 return retval;
427} 425}
@@ -2211,8 +2209,8 @@ key_curve_nid_to_name(int nid)
2211} 2209}
2212 2210
2213#ifdef OPENSSL_HAS_ECC 2211#ifdef OPENSSL_HAS_ECC
2214const EVP_MD * 2212int
2215key_ec_nid_to_evpmd(int nid) 2213key_ec_nid_to_hash_alg(int nid)
2216{ 2214{
2217 int kbits = key_curve_nid_to_bits(nid); 2215 int kbits = key_curve_nid_to_bits(nid);
2218 2216
@@ -2220,11 +2218,11 @@ key_ec_nid_to_evpmd(int nid)
2220 fatal("%s: invalid nid %d", __func__, nid); 2218 fatal("%s: invalid nid %d", __func__, nid);
2221 /* RFC5656 section 6.2.1 */ 2219 /* RFC5656 section 6.2.1 */
2222 if (kbits <= 256) 2220 if (kbits <= 256)
2223 return EVP_sha256(); 2221 return SSH_DIGEST_SHA256;
2224 else if (kbits <= 384) 2222 else if (kbits <= 384)
2225 return EVP_sha384(); 2223 return SSH_DIGEST_SHA384;
2226 else 2224 else
2227 return EVP_sha512(); 2225 return SSH_DIGEST_SHA512;
2228} 2226}
2229 2227
2230int 2228int
diff --git a/key.h b/key.h
index 6a049d277..d8ad13d08 100644
--- a/key.h
+++ b/key.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: key.h,v 1.40 2013/12/06 13:39:49 markus Exp $ */ 1/* $OpenBSD: key.h,v 1.41 2014/01/09 23:20:00 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 4 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@@ -131,7 +131,7 @@ u_int key_curve_nid_to_bits(int);
131int key_ecdsa_bits_to_nid(int); 131int key_ecdsa_bits_to_nid(int);
132#ifdef OPENSSL_HAS_ECC 132#ifdef OPENSSL_HAS_ECC
133int key_ecdsa_key_to_nid(EC_KEY *); 133int key_ecdsa_key_to_nid(EC_KEY *);
134const EVP_MD *key_ec_nid_to_evpmd(int nid); 134int key_ec_nid_to_hash_alg(int nid);
135int key_ec_validate_public(const EC_GROUP *, const EC_POINT *); 135int key_ec_validate_public(const EC_GROUP *, const EC_POINT *);
136int key_ec_validate_private(const EC_KEY *); 136int key_ec_validate_private(const EC_KEY *);
137#endif 137#endif
diff --git a/roaming_client.c b/roaming_client.c
index 2fb623121..de049cdc1 100644
--- a/roaming_client.c
+++ b/roaming_client.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: roaming_client.c,v 1.6 2013/10/16 02:31:46 djm Exp $ */ 1/* $OpenBSD: roaming_client.c,v 1.7 2014/01/09 23:20:00 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2004-2009 AppGate Network Security AB 3 * Copyright (c) 2004-2009 AppGate Network Security AB
4 * 4 *
@@ -48,6 +48,7 @@
48#include "roaming.h" 48#include "roaming.h"
49#include "ssh2.h" 49#include "ssh2.h"
50#include "sshconnect.h" 50#include "sshconnect.h"
51#include "digest.h"
51 52
52/* import */ 53/* import */
53extern Options options; 54extern Options options;
@@ -90,10 +91,8 @@ request_roaming(void)
90static void 91static void
91roaming_auth_required(void) 92roaming_auth_required(void)
92{ 93{
93 u_char digest[SHA_DIGEST_LENGTH]; 94 u_char digest[SSH_DIGEST_MAX_LENGTH];
94 EVP_MD_CTX md;
95 Buffer b; 95 Buffer b;
96 const EVP_MD *evp_md = EVP_sha1();
97 u_int64_t chall, oldchall; 96 u_int64_t chall, oldchall;
98 97
99 chall = packet_get_int64(); 98 chall = packet_get_int64();
@@ -107,14 +106,13 @@ roaming_auth_required(void)
107 buffer_init(&b); 106 buffer_init(&b);
108 buffer_put_int64(&b, cookie); 107 buffer_put_int64(&b, cookie);
109 buffer_put_int64(&b, chall); 108 buffer_put_int64(&b, chall);
110 EVP_DigestInit(&md, evp_md); 109 if (ssh_digest_buffer(SSH_DIGEST_SHA1, &b, digest, sizeof(digest)) != 0)
111 EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); 110 fatal("%s: ssh_digest_buffer failed", __func__);
112 EVP_DigestFinal(&md, digest, NULL);
113 buffer_free(&b); 111 buffer_free(&b);
114 112
115 packet_start(SSH2_MSG_KEX_ROAMING_AUTH); 113 packet_start(SSH2_MSG_KEX_ROAMING_AUTH);
116 packet_put_int64(key1 ^ get_recv_bytes()); 114 packet_put_int64(key1 ^ get_recv_bytes());
117 packet_put_raw(digest, sizeof(digest)); 115 packet_put_raw(digest, ssh_digest_bytes(SSH_DIGEST_SHA1));
118 packet_send(); 116 packet_send();
119 117
120 oldkey1 = key1; 118 oldkey1 = key1;
diff --git a/roaming_common.c b/roaming_common.c
index 86b3372ef..787bef04a 100644
--- a/roaming_common.c
+++ b/roaming_common.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: roaming_common.c,v 1.11 2013/11/03 10:37:19 djm Exp $ */ 1/* $OpenBSD: roaming_common.c,v 1.12 2014/01/09 23:20:00 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2004-2009 AppGate Network Security AB 3 * Copyright (c) 2004-2009 AppGate Network Security AB
4 * 4 *
@@ -36,6 +36,7 @@
36#include "cipher.h" 36#include "cipher.h"
37#include "buffer.h" 37#include "buffer.h"
38#include "roaming.h" 38#include "roaming.h"
39#include "digest.h"
39 40
40static size_t out_buf_size = 0; 41static size_t out_buf_size = 0;
41static char *out_buf = NULL; 42static char *out_buf = NULL;
@@ -225,9 +226,7 @@ resend_bytes(int fd, u_int64_t *offset)
225void 226void
226calculate_new_key(u_int64_t *key, u_int64_t cookie, u_int64_t challenge) 227calculate_new_key(u_int64_t *key, u_int64_t cookie, u_int64_t challenge)
227{ 228{
228 const EVP_MD *md = EVP_sha1(); 229 u_char hash[SSH_DIGEST_MAX_LENGTH];
229 EVP_MD_CTX ctx;
230 u_char hash[EVP_MAX_MD_SIZE];
231 Buffer b; 230 Buffer b;
232 231
233 buffer_init(&b); 232 buffer_init(&b);
@@ -235,12 +234,11 @@ calculate_new_key(u_int64_t *key, u_int64_t cookie, u_int64_t challenge)
235 buffer_put_int64(&b, cookie); 234 buffer_put_int64(&b, cookie);
236 buffer_put_int64(&b, challenge); 235 buffer_put_int64(&b, challenge);
237 236
238 EVP_DigestInit(&ctx, md); 237 if (ssh_digest_buffer(SSH_DIGEST_SHA1, &b, hash, sizeof(hash)) != 0)
239 EVP_DigestUpdate(&ctx, buffer_ptr(&b), buffer_len(&b)); 238 fatal("%s: digest_buffer failed", __func__);
240 EVP_DigestFinal(&ctx, hash, NULL);
241 239
242 buffer_clear(&b); 240 buffer_clear(&b);
243 buffer_append(&b, hash, EVP_MD_size(md)); 241 buffer_append(&b, hash, ssh_digest_bytes(SSH_DIGEST_SHA1));
244 *key = buffer_get_int64(&b); 242 *key = buffer_get_int64(&b);
245 buffer_free(&b); 243 buffer_free(&b);
246} 244}
diff --git a/schnorr.c b/schnorr.c
index 93822fed4..aa3a57770 100644
--- a/schnorr.c
+++ b/schnorr.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: schnorr.c,v 1.8 2013/11/08 00:39:15 djm Exp $ */ 1/* $OpenBSD: schnorr.c,v 1.9 2014/01/09 23:20:00 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2008 Damien Miller. All rights reserved. 3 * Copyright (c) 2008 Damien Miller. All rights reserved.
4 * 4 *
@@ -41,6 +41,7 @@
41#include "log.h" 41#include "log.h"
42 42
43#include "schnorr.h" 43#include "schnorr.h"
44#include "digest.h"
44 45
45#include "openbsd-compat/openssl-compat.h" 46#include "openbsd-compat/openssl-compat.h"
46 47
@@ -57,12 +58,12 @@
57 58
58/* 59/*
59 * Calculate hash component of Schnorr signature H(g || g^v || g^x || id) 60 * Calculate hash component of Schnorr signature H(g || g^v || g^x || id)
60 * using the hash function defined by "evp_md". Returns signature as 61 * using the hash function defined by "hash_alg". Returns signature as
61 * bignum or NULL on error. 62 * bignum or NULL on error.
62 */ 63 */
63static BIGNUM * 64static BIGNUM *
64schnorr_hash(const BIGNUM *p, const BIGNUM *q, const BIGNUM *g, 65schnorr_hash(const BIGNUM *p, const BIGNUM *q, const BIGNUM *g,
65 const EVP_MD *evp_md, const BIGNUM *g_v, const BIGNUM *g_x, 66 int hash_alg, const BIGNUM *g_v, const BIGNUM *g_x,
66 const u_char *id, u_int idlen) 67 const u_char *id, u_int idlen)
67{ 68{
68 u_char *digest; 69 u_char *digest;
@@ -88,7 +89,7 @@ schnorr_hash(const BIGNUM *p, const BIGNUM *q, const BIGNUM *g,
88 89
89 SCHNORR_DEBUG_BUF((buffer_ptr(&b), buffer_len(&b), 90 SCHNORR_DEBUG_BUF((buffer_ptr(&b), buffer_len(&b),
90 "%s: hashblob", __func__)); 91 "%s: hashblob", __func__));
91 if (hash_buffer(buffer_ptr(&b), buffer_len(&b), evp_md, 92 if (hash_buffer(buffer_ptr(&b), buffer_len(&b), hash_alg,
92 &digest, &digest_len) != 0) { 93 &digest, &digest_len) != 0) {
93 error("%s: hash_buffer", __func__); 94 error("%s: hash_buffer", __func__);
94 goto out; 95 goto out;
@@ -113,7 +114,7 @@ schnorr_hash(const BIGNUM *p, const BIGNUM *q, const BIGNUM *g,
113/* 114/*
114 * Generate Schnorr signature to prove knowledge of private value 'x' used 115 * Generate Schnorr signature to prove knowledge of private value 'x' used
115 * in public exponent g^x, under group defined by 'grp_p', 'grp_q' and 'grp_g' 116 * in public exponent g^x, under group defined by 'grp_p', 'grp_q' and 'grp_g'
116 * using the hash function "evp_md". 117 * using the hash function "hash_alg".
117 * 'idlen' bytes from 'id' will be included in the signature hash as an anti- 118 * 'idlen' bytes from 'id' will be included in the signature hash as an anti-
118 * replay salt. 119 * replay salt.
119 * 120 *
@@ -123,7 +124,7 @@ schnorr_hash(const BIGNUM *p, const BIGNUM *q, const BIGNUM *g,
123 */ 124 */
124int 125int
125schnorr_sign(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, 126schnorr_sign(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
126 const EVP_MD *evp_md, const BIGNUM *x, const BIGNUM *g_x, 127 int hash_alg, const BIGNUM *x, const BIGNUM *g_x,
127 const u_char *id, u_int idlen, BIGNUM **r_p, BIGNUM **e_p) 128 const u_char *id, u_int idlen, BIGNUM **r_p, BIGNUM **e_p)
128{ 129{
129 int success = -1; 130 int success = -1;
@@ -173,7 +174,7 @@ schnorr_sign(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
173 SCHNORR_DEBUG_BN((g_v, "%s: g_v = ", __func__)); 174 SCHNORR_DEBUG_BN((g_v, "%s: g_v = ", __func__));
174 175
175 /* h = H(g || g^v || g^x || id) */ 176 /* h = H(g || g^v || g^x || id) */
176 if ((h = schnorr_hash(grp_p, grp_q, grp_g, evp_md, g_v, g_x, 177 if ((h = schnorr_hash(grp_p, grp_q, grp_g, hash_alg, g_v, g_x,
177 id, idlen)) == NULL) { 178 id, idlen)) == NULL) {
178 error("%s: schnorr_hash failed", __func__); 179 error("%s: schnorr_hash failed", __func__);
179 goto out; 180 goto out;
@@ -223,7 +224,7 @@ schnorr_sign_buf(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
223 Buffer b; 224 Buffer b;
224 BIGNUM *r, *e; 225 BIGNUM *r, *e;
225 226
226 if (schnorr_sign(grp_p, grp_q, grp_g, EVP_sha256(), 227 if (schnorr_sign(grp_p, grp_q, grp_g, SSH_DIGEST_SHA256,
227 x, g_x, id, idlen, &r, &e) != 0) 228 x, g_x, id, idlen, &r, &e) != 0)
228 return -1; 229 return -1;
229 230
@@ -248,13 +249,13 @@ schnorr_sign_buf(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
248/* 249/*
249 * Verify Schnorr signature { r (v - xh mod q), e (g^v mod p) } against 250 * Verify Schnorr signature { r (v - xh mod q), e (g^v mod p) } against
250 * public exponent g_x (g^x) under group defined by 'grp_p', 'grp_q' and 251 * public exponent g_x (g^x) under group defined by 'grp_p', 'grp_q' and
251 * 'grp_g' using hash "evp_md". 252 * 'grp_g' using hash "hash_alg".
252 * Signature hash will be salted with 'idlen' bytes from 'id'. 253 * Signature hash will be salted with 'idlen' bytes from 'id'.
253 * Returns -1 on failure, 0 on incorrect signature or 1 on matching signature. 254 * Returns -1 on failure, 0 on incorrect signature or 1 on matching signature.
254 */ 255 */
255int 256int
256schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, 257schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
257 const EVP_MD *evp_md, const BIGNUM *g_x, const u_char *id, u_int idlen, 258 int hash_alg, const BIGNUM *g_x, const u_char *id, u_int idlen,
258 const BIGNUM *r, const BIGNUM *e) 259 const BIGNUM *r, const BIGNUM *e)
259{ 260{
260 int success = -1; 261 int success = -1;
@@ -302,7 +303,7 @@ schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
302 303
303 SCHNORR_DEBUG_BN((g_xh, "%s: g_xh = ", __func__)); 304 SCHNORR_DEBUG_BN((g_xh, "%s: g_xh = ", __func__));
304 /* h = H(g || g^v || g^x || id) */ 305 /* h = H(g || g^v || g^x || id) */
305 if ((h = schnorr_hash(grp_p, grp_q, grp_g, evp_md, e, g_x, 306 if ((h = schnorr_hash(grp_p, grp_q, grp_g, hash_alg, e, g_x,
306 id, idlen)) == NULL) { 307 id, idlen)) == NULL) {
307 error("%s: schnorr_hash failed", __func__); 308 error("%s: schnorr_hash failed", __func__);
308 goto out; 309 goto out;
@@ -385,7 +386,7 @@ schnorr_verify_buf(const BIGNUM *grp_p, const BIGNUM *grp_q,
385 goto out; 386 goto out;
386 } 387 }
387 388
388 ret = schnorr_verify(grp_p, grp_q, grp_g, EVP_sha256(), 389 ret = schnorr_verify(grp_p, grp_q, grp_g, SSH_DIGEST_SHA256,
389 g_x, id, idlen, r, e); 390 g_x, id, idlen, r, e);
390 out: 391 out:
391 BN_clear_free(e); 392 BN_clear_free(e);
@@ -443,43 +444,33 @@ bn_rand_range_gt_one(const BIGNUM *high)
443 return NULL; 444 return NULL;
444} 445}
445 446
447/* XXX convert all callers of this to use ssh_digest_memory() directly */
446/* 448/*
447 * Hash contents of buffer 'b' with hash 'md'. Returns 0 on success, 449 * Hash contents of buffer 'b' with hash 'md'. Returns 0 on success,
448 * with digest via 'digestp' (caller to free) and length via 'lenp'. 450 * with digest via 'digestp' (caller to free) and length via 'lenp'.
449 * Returns -1 on failure. 451 * Returns -1 on failure.
450 */ 452 */
451int 453int
452hash_buffer(const u_char *buf, u_int len, const EVP_MD *md, 454hash_buffer(const u_char *buf, u_int len, int hash_alg,
453 u_char **digestp, u_int *lenp) 455 u_char **digestp, u_int *lenp)
454{ 456{
455 u_char digest[EVP_MAX_MD_SIZE]; 457 u_char digest[SSH_DIGEST_MAX_LENGTH];
456 u_int digest_len; 458 u_int digest_len = ssh_digest_bytes(hash_alg);
457 EVP_MD_CTX evp_md_ctx;
458 int success = -1;
459 459
460 EVP_MD_CTX_init(&evp_md_ctx); 460 if (digest_len == 0) {
461 461 error("%s: invalid hash", __func__);
462 if (EVP_DigestInit_ex(&evp_md_ctx, md, NULL) != 1) { 462 return -1;
463 error("%s: EVP_DigestInit_ex", __func__);
464 goto out;
465 }
466 if (EVP_DigestUpdate(&evp_md_ctx, buf, len) != 1) {
467 error("%s: EVP_DigestUpdate", __func__);
468 goto out;
469 } 463 }
470 if (EVP_DigestFinal_ex(&evp_md_ctx, digest, &digest_len) != 1) { 464 if (ssh_digest_memory(hash_alg, buf, len, digest, digest_len) != 0) {
471 error("%s: EVP_DigestFinal_ex", __func__); 465 error("%s: digest_memory failed", __func__);
472 goto out; 466 return -1;
473 } 467 }
474 *digestp = xmalloc(digest_len); 468 *digestp = xmalloc(digest_len);
475 *lenp = digest_len; 469 *lenp = digest_len;
476 memcpy(*digestp, digest, *lenp); 470 memcpy(*digestp, digest, *lenp);
477 success = 0;
478 out:
479 EVP_MD_CTX_cleanup(&evp_md_ctx);
480 bzero(digest, sizeof(digest)); 471 bzero(digest, sizeof(digest));
481 digest_len = 0; 472 digest_len = 0;
482 return success; 473 return 0;
483} 474}
484 475
485/* print formatted string followed by bignum */ 476/* print formatted string followed by bignum */
diff --git a/schnorr.h b/schnorr.h
index 9730b47ce..e2405c102 100644
--- a/schnorr.h
+++ b/schnorr.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: schnorr.h,v 1.1 2009/03/05 07:18:19 djm Exp $ */ 1/* $OpenBSD: schnorr.h,v 1.2 2014/01/09 23:20:00 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2009 Damien Miller. All rights reserved. 3 * Copyright (c) 2009 Damien Miller. All rights reserved.
4 * 4 *
@@ -27,7 +27,7 @@ struct modp_group {
27}; 27};
28 28
29BIGNUM *bn_rand_range_gt_one(const BIGNUM *high); 29BIGNUM *bn_rand_range_gt_one(const BIGNUM *high);
30int hash_buffer(const u_char *, u_int, const EVP_MD *, u_char **, u_int *); 30int hash_buffer(const u_char *, u_int, int, u_char **, u_int *);
31void debug3_bn(const BIGNUM *, const char *, ...) 31void debug3_bn(const BIGNUM *, const char *, ...)
32 __attribute__((__nonnull__ (2))) 32 __attribute__((__nonnull__ (2)))
33 __attribute__((format(printf, 2, 3))); 33 __attribute__((format(printf, 2, 3)));
@@ -40,7 +40,7 @@ void modp_group_free(struct modp_group *);
40/* Signature and verification functions */ 40/* Signature and verification functions */
41int 41int
42schnorr_sign(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, 42schnorr_sign(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
43 const EVP_MD *evp_md, const BIGNUM *x, const BIGNUM *g_x, 43 int hash_alg, const BIGNUM *x, const BIGNUM *g_x,
44 const u_char *id, u_int idlen, BIGNUM **r_p, BIGNUM **e_p); 44 const u_char *id, u_int idlen, BIGNUM **r_p, BIGNUM **e_p);
45int 45int
46schnorr_sign_buf(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, 46schnorr_sign_buf(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
@@ -48,7 +48,7 @@ schnorr_sign_buf(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
48 u_char **sig, u_int *siglen); 48 u_char **sig, u_int *siglen);
49int 49int
50schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, 50schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
51 const EVP_MD *evp_md, const BIGNUM *g_x, const u_char *id, u_int idlen, 51 int hash_alg, const BIGNUM *g_x, const u_char *id, u_int idlen,
52 const BIGNUM *r, const BIGNUM *e); 52 const BIGNUM *r, const BIGNUM *e);
53int 53int
54schnorr_verify_buf(const BIGNUM *grp_p, const BIGNUM *grp_q, 54schnorr_verify_buf(const BIGNUM *grp_p, const BIGNUM *grp_q,
diff --git a/ssh-dss.c b/ssh-dss.c
index a6292aa84..7b897475c 100644
--- a/ssh-dss.c
+++ b/ssh-dss.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-dss.c,v 1.29 2013/12/27 22:30:17 djm Exp $ */ 1/* $OpenBSD: ssh-dss.c,v 1.30 2014/01/09 23:20:00 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -38,6 +38,7 @@
38#include "compat.h" 38#include "compat.h"
39#include "log.h" 39#include "log.h"
40#include "key.h" 40#include "key.h"
41#include "digest.h"
41 42
42#define INTBLOB_LEN 20 43#define INTBLOB_LEN 20
43#define SIGBLOB_LEN (2*INTBLOB_LEN) 44#define SIGBLOB_LEN (2*INTBLOB_LEN)
@@ -47,10 +48,8 @@ ssh_dss_sign(const Key *key, u_char **sigp, u_int *lenp,
47 const u_char *data, u_int datalen) 48 const u_char *data, u_int datalen)
48{ 49{
49 DSA_SIG *sig; 50 DSA_SIG *sig;
50 const EVP_MD *evp_md = EVP_sha1(); 51 u_char digest[SSH_DIGEST_MAX_LENGTH], sigblob[SIGBLOB_LEN];
51 EVP_MD_CTX md; 52 u_int rlen, slen, len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1);
52 u_char digest[EVP_MAX_MD_SIZE], sigblob[SIGBLOB_LEN];
53 u_int rlen, slen, len, dlen;
54 Buffer b; 53 Buffer b;
55 54
56 if (key == NULL || key_type_plain(key->type) != KEY_DSA || 55 if (key == NULL || key_type_plain(key->type) != KEY_DSA ||
@@ -59,9 +58,11 @@ ssh_dss_sign(const Key *key, u_char **sigp, u_int *lenp,
59 return -1; 58 return -1;
60 } 59 }
61 60
62 EVP_DigestInit(&md, evp_md); 61 if (ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen,
63 EVP_DigestUpdate(&md, data, datalen); 62 digest, sizeof(digest)) != 0) {
64 EVP_DigestFinal(&md, digest, &dlen); 63 error("%s: ssh_digest_memory failed", __func__);
64 return -1;
65 }
65 66
66 sig = DSA_do_sign(digest, dlen, key->dsa); 67 sig = DSA_do_sign(digest, dlen, key->dsa);
67 memset(digest, 'd', sizeof(digest)); 68 memset(digest, 'd', sizeof(digest));
@@ -111,10 +112,8 @@ ssh_dss_verify(const Key *key, const u_char *signature, u_int signaturelen,
111 const u_char *data, u_int datalen) 112 const u_char *data, u_int datalen)
112{ 113{
113 DSA_SIG *sig; 114 DSA_SIG *sig;
114 const EVP_MD *evp_md = EVP_sha1(); 115 u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob;
115 EVP_MD_CTX md; 116 u_int len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1);
116 u_char digest[EVP_MAX_MD_SIZE], *sigblob;
117 u_int len, dlen;
118 int rlen, ret; 117 int rlen, ret;
119 Buffer b; 118 Buffer b;
120 119
@@ -173,9 +172,11 @@ ssh_dss_verify(const Key *key, const u_char *signature, u_int signaturelen,
173 free(sigblob); 172 free(sigblob);
174 173
175 /* sha1 the data */ 174 /* sha1 the data */
176 EVP_DigestInit(&md, evp_md); 175 if (ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen,
177 EVP_DigestUpdate(&md, data, datalen); 176 digest, sizeof(digest)) != 0) {
178 EVP_DigestFinal(&md, digest, &dlen); 177 error("%s: digest_memory failed", __func__);
178 return -1;
179 }
179 180
180 ret = DSA_do_verify(digest, dlen, sig, key->dsa); 181 ret = DSA_do_verify(digest, dlen, sig, key->dsa);
181 memset(digest, 'd', sizeof(digest)); 182 memset(digest, 'd', sizeof(digest));
diff --git a/ssh-ecdsa.c b/ssh-ecdsa.c
index 52f9e74c0..10ad9da60 100644
--- a/ssh-ecdsa.c
+++ b/ssh-ecdsa.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-ecdsa.c,v 1.7 2013/12/27 22:30:17 djm Exp $ */ 1/* $OpenBSD: ssh-ecdsa.c,v 1.8 2014/01/09 23:20:00 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * Copyright (c) 2010 Damien Miller. All rights reserved. 4 * Copyright (c) 2010 Damien Miller. All rights reserved.
@@ -42,15 +42,15 @@
42#include "compat.h" 42#include "compat.h"
43#include "log.h" 43#include "log.h"
44#include "key.h" 44#include "key.h"
45#include "digest.h"
45 46
46int 47int
47ssh_ecdsa_sign(const Key *key, u_char **sigp, u_int *lenp, 48ssh_ecdsa_sign(const Key *key, u_char **sigp, u_int *lenp,
48 const u_char *data, u_int datalen) 49 const u_char *data, u_int datalen)
49{ 50{
50 ECDSA_SIG *sig; 51 ECDSA_SIG *sig;
51 const EVP_MD *evp_md; 52 int hash_alg;
52 EVP_MD_CTX md; 53 u_char digest[SSH_DIGEST_MAX_LENGTH];
53 u_char digest[EVP_MAX_MD_SIZE];
54 u_int len, dlen; 54 u_int len, dlen;
55 Buffer b, bb; 55 Buffer b, bb;
56 56
@@ -60,10 +60,16 @@ ssh_ecdsa_sign(const Key *key, u_char **sigp, u_int *lenp,
60 return -1; 60 return -1;
61 } 61 }
62 62
63 evp_md = key_ec_nid_to_evpmd(key->ecdsa_nid); 63 hash_alg = key_ec_nid_to_hash_alg(key->ecdsa_nid);
64 EVP_DigestInit(&md, evp_md); 64 if ((dlen = ssh_digest_bytes(hash_alg)) == 0) {
65 EVP_DigestUpdate(&md, data, datalen); 65 error("%s: bad hash algorithm %d", __func__, hash_alg);
66 EVP_DigestFinal(&md, digest, &dlen); 66 return -1;
67 }
68 if (ssh_digest_memory(hash_alg, data, datalen,
69 digest, sizeof(digest)) != 0) {
70 error("%s: digest_memory failed", __func__);
71 return -1;
72 }
67 73
68 sig = ECDSA_do_sign(digest, dlen, key->ecdsa); 74 sig = ECDSA_do_sign(digest, dlen, key->ecdsa);
69 memset(digest, 'd', sizeof(digest)); 75 memset(digest, 'd', sizeof(digest));
@@ -98,9 +104,8 @@ ssh_ecdsa_verify(const Key *key, const u_char *signature, u_int signaturelen,
98 const u_char *data, u_int datalen) 104 const u_char *data, u_int datalen)
99{ 105{
100 ECDSA_SIG *sig; 106 ECDSA_SIG *sig;
101 const EVP_MD *evp_md; 107 int hash_alg;
102 EVP_MD_CTX md; 108 u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob;
103 u_char digest[EVP_MAX_MD_SIZE], *sigblob;
104 u_int len, dlen; 109 u_int len, dlen;
105 int rlen, ret; 110 int rlen, ret;
106 Buffer b, bb; 111 Buffer b, bb;
@@ -112,8 +117,6 @@ ssh_ecdsa_verify(const Key *key, const u_char *signature, u_int signaturelen,
112 return -1; 117 return -1;
113 } 118 }
114 119
115 evp_md = key_ec_nid_to_evpmd(key->ecdsa_nid);
116
117 /* fetch signature */ 120 /* fetch signature */
118 buffer_init(&b); 121 buffer_init(&b);
119 buffer_append(&b, signature, signaturelen); 122 buffer_append(&b, signature, signaturelen);
@@ -154,9 +157,16 @@ ssh_ecdsa_verify(const Key *key, const u_char *signature, u_int signaturelen,
154 free(sigblob); 157 free(sigblob);
155 158
156 /* hash the data */ 159 /* hash the data */
157 EVP_DigestInit(&md, evp_md); 160 hash_alg = key_ec_nid_to_hash_alg(key->ecdsa_nid);
158 EVP_DigestUpdate(&md, data, datalen); 161 if ((dlen = ssh_digest_bytes(hash_alg)) == 0) {
159 EVP_DigestFinal(&md, digest, &dlen); 162 error("%s: bad hash algorithm %d", __func__, hash_alg);
163 return -1;
164 }
165 if (ssh_digest_memory(hash_alg, data, datalen,
166 digest, sizeof(digest)) != 0) {
167 error("%s: digest_memory failed", __func__);
168 return -1;
169 }
160 170
161 ret = ECDSA_do_verify(digest, dlen, sig, key->ecdsa); 171 ret = ECDSA_do_verify(digest, dlen, sig, key->ecdsa);
162 memset(digest, 'd', sizeof(digest)); 172 memset(digest, 'd', sizeof(digest));
diff --git a/ssh-rsa.c b/ssh-rsa.c
index b1ac50b31..a2112d033 100644
--- a/ssh-rsa.c
+++ b/ssh-rsa.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-rsa.c,v 1.49 2013/12/30 23:52:27 djm Exp $ */ 1/* $OpenBSD: ssh-rsa.c,v 1.50 2014/01/09 23:20:00 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000, 2003 Markus Friedl <markus@openbsd.org> 3 * Copyright (c) 2000, 2003 Markus Friedl <markus@openbsd.org>
4 * 4 *
@@ -32,6 +32,7 @@
32#include "compat.h" 32#include "compat.h"
33#include "misc.h" 33#include "misc.h"
34#include "ssh.h" 34#include "ssh.h"
35#include "digest.h"
35 36
36static int openssh_RSA_verify(int, u_char *, u_int, u_char *, u_int, RSA *); 37static int openssh_RSA_verify(int, u_char *, u_int, u_char *, u_int, RSA *);
37 38
@@ -40,9 +41,8 @@ int
40ssh_rsa_sign(const Key *key, u_char **sigp, u_int *lenp, 41ssh_rsa_sign(const Key *key, u_char **sigp, u_int *lenp,
41 const u_char *data, u_int datalen) 42 const u_char *data, u_int datalen)
42{ 43{
43 const EVP_MD *evp_md; 44 int hash_alg;
44 EVP_MD_CTX md; 45 u_char digest[SSH_DIGEST_MAX_LENGTH], *sig;
45 u_char digest[EVP_MAX_MD_SIZE], *sig;
46 u_int slen, dlen, len; 46 u_int slen, dlen, len;
47 int ok, nid; 47 int ok, nid;
48 Buffer b; 48 Buffer b;
@@ -53,14 +53,18 @@ ssh_rsa_sign(const Key *key, u_char **sigp, u_int *lenp,
53 return -1; 53 return -1;
54 } 54 }
55 55
56 /* hash the data */
57 hash_alg = SSH_DIGEST_SHA1;
56 nid = NID_sha1; 58 nid = NID_sha1;
57 if ((evp_md = EVP_get_digestbynid(nid)) == NULL) { 59 if ((dlen = ssh_digest_bytes(hash_alg)) == 0) {
58 error("%s: EVP_get_digestbynid %d failed", __func__, nid); 60 error("%s: bad hash algorithm %d", __func__, hash_alg);
61 return -1;
62 }
63 if (ssh_digest_memory(hash_alg, data, datalen,
64 digest, sizeof(digest)) != 0) {
65 error("%s: ssh_digest_memory failed", __func__);
59 return -1; 66 return -1;
60 } 67 }
61 EVP_DigestInit(&md, evp_md);
62 EVP_DigestUpdate(&md, data, datalen);
63 EVP_DigestFinal(&md, digest, &dlen);
64 68
65 slen = RSA_size(key->rsa); 69 slen = RSA_size(key->rsa);
66 sig = xmalloc(slen); 70 sig = xmalloc(slen);
@@ -109,12 +113,11 @@ ssh_rsa_verify(const Key *key, const u_char *signature, u_int signaturelen,
109 const u_char *data, u_int datalen) 113 const u_char *data, u_int datalen)
110{ 114{
111 Buffer b; 115 Buffer b;
112 const EVP_MD *evp_md; 116 int hash_alg;
113 EVP_MD_CTX md;
114 char *ktype; 117 char *ktype;
115 u_char digest[EVP_MAX_MD_SIZE], *sigblob; 118 u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob;
116 u_int len, dlen, modlen; 119 u_int len, dlen, modlen;
117 int rlen, ret, nid; 120 int rlen, ret;
118 121
119 if (key == NULL || key_type_plain(key->type) != KEY_RSA || 122 if (key == NULL || key_type_plain(key->type) != KEY_RSA ||
120 key->rsa == NULL) { 123 key->rsa == NULL) {
@@ -161,17 +164,20 @@ ssh_rsa_verify(const Key *key, const u_char *signature, u_int signaturelen,
161 memset(sigblob, 0, diff); 164 memset(sigblob, 0, diff);
162 len = modlen; 165 len = modlen;
163 } 166 }
164 nid = NID_sha1; 167 /* hash the data */
165 if ((evp_md = EVP_get_digestbynid(nid)) == NULL) { 168 hash_alg = SSH_DIGEST_SHA1;
166 error("%s: EVP_get_digestbynid %d failed", __func__, nid); 169 if ((dlen = ssh_digest_bytes(hash_alg)) == 0) {
167 free(sigblob); 170 error("%s: bad hash algorithm %d", __func__, hash_alg);
171 return -1;
172 }
173 if (ssh_digest_memory(hash_alg, data, datalen,
174 digest, sizeof(digest)) != 0) {
175 error("%s: ssh_digest_memory failed", __func__);
168 return -1; 176 return -1;
169 } 177 }
170 EVP_DigestInit(&md, evp_md);
171 EVP_DigestUpdate(&md, data, datalen);
172 EVP_DigestFinal(&md, digest, &dlen);
173 178
174 ret = openssh_RSA_verify(nid, digest, dlen, sigblob, len, key->rsa); 179 ret = openssh_RSA_verify(hash_alg, digest, dlen, sigblob, len,
180 key->rsa);
175 memset(digest, 'd', sizeof(digest)); 181 memset(digest, 'd', sizeof(digest));
176 memset(sigblob, 's', len); 182 memset(sigblob, 's', len);
177 free(sigblob); 183 free(sigblob);
@@ -198,7 +204,7 @@ static const u_char id_sha1[] = {
198}; 204};
199 205
200static int 206static int
201openssh_RSA_verify(int type, u_char *hash, u_int hashlen, 207openssh_RSA_verify(int hash_alg, u_char *hash, u_int hashlen,
202 u_char *sigbuf, u_int siglen, RSA *rsa) 208 u_char *sigbuf, u_int siglen, RSA *rsa)
203{ 209{
204 u_int ret, rsasize, oidlen = 0, hlen = 0; 210 u_int ret, rsasize, oidlen = 0, hlen = 0;
@@ -207,8 +213,8 @@ openssh_RSA_verify(int type, u_char *hash, u_int hashlen,
207 u_char *decrypted = NULL; 213 u_char *decrypted = NULL;
208 214
209 ret = 0; 215 ret = 0;
210 switch (type) { 216 switch (hash_alg) {
211 case NID_sha1: 217 case SSH_DIGEST_SHA1:
212 oid = id_sha1; 218 oid = id_sha1;
213 oidlen = sizeof(id_sha1); 219 oidlen = sizeof(id_sha1);
214 hlen = 20; 220 hlen = 20;
diff --git a/sshconnect2.c b/sshconnect2.c
index 0d339b9c5..8acffc5c3 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshconnect2.c,v 1.200 2013/12/30 23:52:28 djm Exp $ */ 1/* $OpenBSD: sshconnect2.c,v 1.201 2014/01/09 23:20:00 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * Copyright (c) 2008 Damien Miller. All rights reserved. 4 * Copyright (c) 2008 Damien Miller. All rights reserved.
@@ -1006,7 +1006,7 @@ jpake_password_to_secret(Authctxt *authctxt, const char *crypt_scheme,
1006 debug3("%s: crypted = %s", __func__, crypted); 1006 debug3("%s: crypted = %s", __func__, crypted);
1007#endif 1007#endif
1008 1008
1009 if (hash_buffer(crypted, strlen(crypted), EVP_sha256(), 1009 if (hash_buffer(crypted, strlen(crypted), SSH_DIGEST_SHA1,
1010 &secret, &secret_len) != 0) 1010 &secret, &secret_len) != 0)
1011 fatal("%s: hash_buffer", __func__); 1011 fatal("%s: hash_buffer", __func__);
1012 1012