diff options
author | Damien Miller <djm@mindrot.org> | 2014-01-10 10:58:53 +1100 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2014-01-10 10:58:53 +1100 |
commit | b3051d01e505c9c2dc00faab472a0d06fa6b0e65 (patch) | |
tree | c0ca49b5fc4e5e1a066157b4dbd9c68cfcd41d63 | |
parent | e00e413dd16eb747fb2c15a099971d91c13cf70f (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-- | ChangeLog | 9 | ||||
-rw-r--r-- | Makefile.in | 4 | ||||
-rw-r--r-- | digest.c | 148 | ||||
-rw-r--r-- | digest.h | 55 | ||||
-rw-r--r-- | hostfile.c | 3 | ||||
-rw-r--r-- | kex.c | 94 | ||||
-rw-r--r-- | kex.h | 10 | ||||
-rw-r--r-- | kexc25519.c | 17 | ||||
-rw-r--r-- | kexc25519c.c | 4 | ||||
-rw-r--r-- | kexc25519s.c | 4 | ||||
-rw-r--r-- | kexdh.c | 17 | ||||
-rw-r--r-- | kexecdh.c | 18 | ||||
-rw-r--r-- | kexecdhc.c | 4 | ||||
-rw-r--r-- | kexecdhs.c | 4 | ||||
-rw-r--r-- | kexgex.c | 24 | ||||
-rw-r--r-- | kexgexc.c | 4 | ||||
-rw-r--r-- | kexgexs.c | 4 | ||||
-rw-r--r-- | key.c | 42 | ||||
-rw-r--r-- | key.h | 4 | ||||
-rw-r--r-- | roaming_client.c | 14 | ||||
-rw-r--r-- | roaming_common.c | 14 | ||||
-rw-r--r-- | schnorr.c | 57 | ||||
-rw-r--r-- | schnorr.h | 8 | ||||
-rw-r--r-- | ssh-dss.c | 31 | ||||
-rw-r--r-- | ssh-ecdsa.c | 42 | ||||
-rw-r--r-- | ssh-rsa.c | 54 | ||||
-rw-r--r-- | sshconnect2.c | 4 |
27 files changed, 458 insertions, 235 deletions
@@ -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 | ||
13 | 20140108 | 22 | 20140108 |
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 | ||
81 | SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ | 81 | SSHOBJS= 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 | |||
32 | struct ssh_digest_ctx { | ||
33 | int alg; | ||
34 | EVP_MD_CTX mdctx; | ||
35 | }; | ||
36 | |||
37 | struct 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 */ | ||
45 | const 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 | |||
57 | static const struct ssh_digest * | ||
58 | ssh_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 | |||
67 | size_t | ||
68 | ssh_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 | |||
75 | struct ssh_digest_ctx * | ||
76 | ssh_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 | |||
92 | int | ||
93 | ssh_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 | |||
100 | int | ||
101 | ssh_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 | |||
106 | int | ||
107 | ssh_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 | |||
123 | void | ||
124 | ssh_digest_free(struct ssh_digest_ctx *ctx) | ||
125 | { | ||
126 | EVP_MD_CTX_cleanup(&ctx->mdctx); | ||
127 | memset(ctx, 0, sizeof(*ctx)); | ||
128 | } | ||
129 | |||
130 | int | ||
131 | ssh_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 | |||
144 | int | ||
145 | ssh_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 */ | ||
34 | size_t ssh_digest_bytes(int alg); | ||
35 | |||
36 | /* One-shot API */ | ||
37 | int 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))); | ||
41 | int ssh_digest_buffer(int alg, const Buffer *b, u_char *d, size_t dlen) | ||
42 | __attribute__((__bounded__(__buffer__, 3, 4))); | ||
43 | |||
44 | /* Update API */ | ||
45 | struct ssh_digest_ctx; | ||
46 | struct ssh_digest_ctx *ssh_digest_start(int alg); | ||
47 | int ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen) | ||
48 | __attribute__((__bounded__(__buffer__, 2, 3))); | ||
49 | int ssh_digest_update_buffer(struct ssh_digest_ctx *ctx, const Buffer *b); | ||
50 | int ssh_digest_final(struct ssh_digest_ctx *ctx, u_char *d, size_t dlen) | ||
51 | __attribute__((__bounded__(__buffer__, 2, 3))); | ||
52 | void 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 | ||
61 | struct hostkeys { | 62 | struct hostkeys { |
62 | struct hostkey_entry *entries; | 63 | struct hostkey_entry *entries; |
@@ -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 | }; |
71 | static const struct kexalg kexalgs[] = { | 72 | static 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 | ||
91 | char * | 96 | char * |
@@ -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 | |||
615 | derive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus, | 627 | derive_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) |
@@ -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 | |||
170 | kex_dh_hash(char *, char *, char *, int, char *, int, u_char *, int, | 170 | kex_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 *); |
172 | void | 172 | void |
173 | kexgex_hash(const EVP_MD *, char *, char *, char *, int, char *, | 173 | kexgex_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 |
177 | void | 177 | void |
178 | kex_ecdh_hash(const EVP_MD *, const EC_GROUP *, char *, char *, char *, int, | 178 | kex_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 |
182 | void | 182 | void |
183 | kex_c25519_hash(const EVP_MD *, char *, char *, char *, int, | 183 | kex_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 | ||
45 | extern int crypto_scalarmult_curve25519(u_char a[CURVE25519_SIZE], | 46 | extern 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 | ||
79 | void | 80 | void |
80 | kex_c25519_hash( | 81 | kex_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), |
@@ -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 | ||
40 | void | 42 | void |
41 | kex_dh_hash( | 43 | kex_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 | } |
@@ -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 | ||
48 | void | 49 | void |
49 | kex_ecdh_hash( | 50 | kex_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, |
@@ -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 | ||
40 | void | 42 | void |
41 | kexgex_hash( | 43 | kexgex_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 | } |
@@ -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), |
@@ -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), |
@@ -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 | ||
60 | static int to_blob(const Key *, u_char **, u_int *, int); | 61 | static int to_blob(const Key *, u_char **, u_int *, int); |
61 | static Key *key_from_blob2(const u_char *, u_int, int); | 62 | static Key *key_from_blob2(const u_char *, u_int, int); |
@@ -358,30 +359,26 @@ u_char* | |||
358 | key_fingerprint_raw(const Key *k, enum fp_type dgst_type, | 359 | key_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 |
2214 | const EVP_MD * | 2212 | int |
2215 | key_ec_nid_to_evpmd(int nid) | 2213 | key_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 | ||
2230 | int | 2228 | int |
@@ -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); | |||
131 | int key_ecdsa_bits_to_nid(int); | 131 | int key_ecdsa_bits_to_nid(int); |
132 | #ifdef OPENSSL_HAS_ECC | 132 | #ifdef OPENSSL_HAS_ECC |
133 | int key_ecdsa_key_to_nid(EC_KEY *); | 133 | int key_ecdsa_key_to_nid(EC_KEY *); |
134 | const EVP_MD *key_ec_nid_to_evpmd(int nid); | 134 | int key_ec_nid_to_hash_alg(int nid); |
135 | int key_ec_validate_public(const EC_GROUP *, const EC_POINT *); | 135 | int key_ec_validate_public(const EC_GROUP *, const EC_POINT *); |
136 | int key_ec_validate_private(const EC_KEY *); | 136 | int 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 */ |
53 | extern Options options; | 54 | extern Options options; |
@@ -90,10 +91,8 @@ request_roaming(void) | |||
90 | static void | 91 | static void |
91 | roaming_auth_required(void) | 92 | roaming_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 | ||
40 | static size_t out_buf_size = 0; | 41 | static size_t out_buf_size = 0; |
41 | static char *out_buf = NULL; | 42 | static char *out_buf = NULL; |
@@ -225,9 +226,7 @@ resend_bytes(int fd, u_int64_t *offset) | |||
225 | void | 226 | void |
226 | calculate_new_key(u_int64_t *key, u_int64_t cookie, u_int64_t challenge) | 227 | calculate_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 | } |
@@ -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 | */ |
63 | static BIGNUM * | 64 | static BIGNUM * |
64 | schnorr_hash(const BIGNUM *p, const BIGNUM *q, const BIGNUM *g, | 65 | schnorr_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 | */ |
124 | int | 125 | int |
125 | schnorr_sign(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, | 126 | schnorr_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 | */ |
255 | int | 256 | int |
256 | schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, | 257 | schnorr_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 | */ |
451 | int | 453 | int |
452 | hash_buffer(const u_char *buf, u_int len, const EVP_MD *md, | 454 | hash_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 */ |
@@ -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 | ||
29 | BIGNUM *bn_rand_range_gt_one(const BIGNUM *high); | 29 | BIGNUM *bn_rand_range_gt_one(const BIGNUM *high); |
30 | int hash_buffer(const u_char *, u_int, const EVP_MD *, u_char **, u_int *); | 30 | int hash_buffer(const u_char *, u_int, int, u_char **, u_int *); |
31 | void debug3_bn(const BIGNUM *, const char *, ...) | 31 | void 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 */ |
41 | int | 41 | int |
42 | schnorr_sign(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, | 42 | schnorr_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); |
45 | int | 45 | int |
46 | schnorr_sign_buf(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, | 46 | schnorr_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); |
49 | int | 49 | int |
50 | schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, | 50 | schnorr_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); |
53 | int | 53 | int |
54 | schnorr_verify_buf(const BIGNUM *grp_p, const BIGNUM *grp_q, | 54 | schnorr_verify_buf(const BIGNUM *grp_p, const BIGNUM *grp_q, |
@@ -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 | ||
46 | int | 47 | int |
47 | ssh_ecdsa_sign(const Key *key, u_char **sigp, u_int *lenp, | 48 | ssh_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)); |
@@ -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 | ||
36 | static int openssh_RSA_verify(int, u_char *, u_int, u_char *, u_int, RSA *); | 37 | static int openssh_RSA_verify(int, u_char *, u_int, u_char *, u_int, RSA *); |
37 | 38 | ||
@@ -40,9 +41,8 @@ int | |||
40 | ssh_rsa_sign(const Key *key, u_char **sigp, u_int *lenp, | 41 | ssh_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 | ||
200 | static int | 206 | static int |
201 | openssh_RSA_verify(int type, u_char *hash, u_int hashlen, | 207 | openssh_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 | ||