summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 df1d5ea6..a1d37bc2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -9,6 +9,15 @@
with the year, and rearrange a comparison to avoid a potentional signed
arithmetic overflow that would give the wrong result.
ok djm@
+ - 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@
20140108
- (djm) [regress/.cvsignore] Ignore regress test droppings; ok dtucker@
diff --git a/Makefile.in b/Makefile.in
index e789b476..4a930c66 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,4 +1,4 @@
-# $Id: Makefile.in,v 1.348 2013/12/08 04:53:28 djm Exp $
+# $Id: Makefile.in,v 1.349 2014/01/09 23:58:53 djm Exp $
# uncomment if you run a non bourne compatable shell. Ie. csh
#SHELL = @SH@
@@ -75,7 +75,7 @@ LIBSSH_OBJS=authfd.o authfile.o bufaux.o bufbn.o buffer.o \
msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \
jpake.o schnorr.o ssh-pkcs11.o krl.o smult_curve25519_ref.o \
kexc25519.o kexc25519c.o poly1305.o chacha.o cipher-chachapoly.o \
- ssh-ed25519.o \
+ ssh-ed25519.o digest.o \
sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o blocks.o \
SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
diff --git a/digest.c b/digest.c
new file mode 100644
index 00000000..59a8ffe0
--- /dev/null
+++ b/digest.c
@@ -0,0 +1,148 @@
+/* $OpenBSD: digest.c,v 1.1 2014/01/09 23:20:00 djm Exp $ */
+/*
+ * Copyright (c) 2013 Damien Miller <djm@mindrot.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "includes.h"
+
+#include <sys/types.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/bn.h> /* for buffer.h */
+#include <openssl/ec.h> /* for buffer.h */
+#include <openssl/evp.h>
+
+#include "buffer.h"
+#include "digest.h"
+
+struct ssh_digest_ctx {
+ int alg;
+ EVP_MD_CTX mdctx;
+};
+
+struct ssh_digest {
+ int id;
+ const char *name;
+ size_t digest_len;
+ const EVP_MD *(*mdfunc)(void);
+};
+
+/* NB. Indexed directly by algorithm number */
+const struct ssh_digest digests[] = {
+ { SSH_DIGEST_MD5, "MD5", 16, EVP_md5 },
+ { SSH_DIGEST_RIPEMD160, "RIPEMD160", 20, EVP_ripemd160 },
+ { SSH_DIGEST_SHA1, "SHA1", 20, EVP_sha1 },
+#ifdef HAVE_EVP_SHA256 /* XXX replace with local if missing */
+ { SSH_DIGEST_SHA256, "SHA256", 32, EVP_sha256 },
+ { SSH_DIGEST_SHA384, "SHA384", 48, EVP_sha384 },
+ { SSH_DIGEST_SHA512, "SHA512", 64, EVP_sha512 },
+#endif
+ { -1, NULL, 0, NULL },
+};
+
+static const struct ssh_digest *
+ssh_digest_by_alg(int alg)
+{
+ if (alg < 0 || alg >= SSH_DIGEST_MAX)
+ return NULL;
+ if (digests[alg].id != alg) /* sanity */
+ return NULL;
+ return &(digests[alg]);
+}
+
+size_t
+ssh_digest_bytes(int alg)
+{
+ const struct ssh_digest *digest = ssh_digest_by_alg(alg);
+
+ return digest == NULL ? 0 : digest->digest_len;
+}
+
+struct ssh_digest_ctx *
+ssh_digest_start(int alg)
+{
+ const struct ssh_digest *digest = ssh_digest_by_alg(alg);
+ struct ssh_digest_ctx *ret;
+
+ if (digest == NULL || ((ret = calloc(1, sizeof(*ret))) == NULL))
+ return NULL;
+ ret->alg = alg;
+ EVP_MD_CTX_init(&ret->mdctx);
+ if (EVP_DigestInit_ex(&ret->mdctx, digest->mdfunc(), NULL) != 1) {
+ free(ret);
+ return NULL;
+ }
+ return ret;
+}
+
+int
+ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen)
+{
+ if (EVP_DigestUpdate(&ctx->mdctx, m, mlen) != 1)
+ return -1;
+ return 0;
+}
+
+int
+ssh_digest_update_buffer(struct ssh_digest_ctx *ctx, const Buffer *b)
+{
+ return ssh_digest_update(ctx, buffer_ptr(b), buffer_len(b));
+}
+
+int
+ssh_digest_final(struct ssh_digest_ctx *ctx, u_char *d, size_t dlen)
+{
+ const struct ssh_digest *digest = ssh_digest_by_alg(ctx->alg);
+ u_int l = dlen;
+
+ if (dlen > UINT_MAX)
+ return -1;
+ if (dlen < digest->digest_len) /* No truncation allowed */
+ return -1;
+ if (EVP_DigestFinal_ex(&ctx->mdctx, d, &l) != 1)
+ return -1;
+ if (l != digest->digest_len) /* sanity */
+ return -1;
+ return 0;
+}
+
+void
+ssh_digest_free(struct ssh_digest_ctx *ctx)
+{
+ EVP_MD_CTX_cleanup(&ctx->mdctx);
+ memset(ctx, 0, sizeof(*ctx));
+}
+
+int
+ssh_digest_memory(int alg, const void *m, size_t mlen, u_char *d, size_t dlen)
+{
+ struct ssh_digest_ctx *ctx = ssh_digest_start(alg);
+
+ if (ctx == NULL)
+ return -1;
+ if (ssh_digest_update(ctx, m, mlen) != 0 ||
+ ssh_digest_final(ctx, d, dlen) != 0)
+ return -1;
+ ssh_digest_free(ctx);
+ return 0;
+}
+
+int
+ssh_digest_buffer(int alg, const Buffer *b, u_char *d, size_t dlen)
+{
+ return ssh_digest_memory(alg, buffer_ptr(b), buffer_len(b), d, dlen);
+}
diff --git a/digest.h b/digest.h
new file mode 100644
index 00000000..faefda3f
--- /dev/null
+++ b/digest.h
@@ -0,0 +1,55 @@
+/* $OpenBSD: digest.h,v 1.1 2014/01/09 23:20:00 djm Exp $ */
+/*
+ * Copyright (c) 2013 Damien Miller <djm@mindrot.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _DIGEST_H
+#define _DIGEST_H
+
+/* Maximum digest output length */
+#define SSH_DIGEST_MAX_LENGTH 64
+
+/* Digest algorithms */
+#define SSH_DIGEST_MD5 0
+#define SSH_DIGEST_RIPEMD160 1
+#define SSH_DIGEST_SHA1 2
+#define SSH_DIGEST_SHA256 3
+#define SSH_DIGEST_SHA384 4
+#define SSH_DIGEST_SHA512 5
+#define SSH_DIGEST_MAX 6
+
+/* Returns the algorithm's digest length in bytes or 0 for invalid algorithm */
+size_t ssh_digest_bytes(int alg);
+
+/* One-shot API */
+int ssh_digest_memory(int alg, const void *m, size_t mlen,
+ u_char *d, size_t dlen)
+ __attribute__((__bounded__(__buffer__, 2, 3)))
+ __attribute__((__bounded__(__buffer__, 4, 5)));
+int ssh_digest_buffer(int alg, const Buffer *b, u_char *d, size_t dlen)
+ __attribute__((__bounded__(__buffer__, 3, 4)));
+
+/* Update API */
+struct ssh_digest_ctx;
+struct ssh_digest_ctx *ssh_digest_start(int alg);
+int ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen)
+ __attribute__((__bounded__(__buffer__, 2, 3)));
+int ssh_digest_update_buffer(struct ssh_digest_ctx *ctx, const Buffer *b);
+int ssh_digest_final(struct ssh_digest_ctx *ctx, u_char *d, size_t dlen)
+ __attribute__((__bounded__(__buffer__, 2, 3)));
+void ssh_digest_free(struct ssh_digest_ctx *ctx);
+
+#endif /* _DIGEST_H */
+
diff --git a/hostfile.c b/hostfile.c
index 2ff4c48b..2778fb5d 100644
--- a/hostfile.c
+++ b/hostfile.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: hostfile.c,v 1.52 2013/07/12 00:19:58 djm Exp $ */
+/* $OpenBSD: hostfile.c,v 1.53 2014/01/09 23:20:00 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -57,6 +57,7 @@
#include "hostfile.h"
#include "log.h"
#include "misc.h"
+#include "digest.h"
struct hostkeys {
struct hostkey_entry *entries;
diff --git a/kex.c b/kex.c
index b38bae0f..dbb1a981 100644
--- a/kex.c
+++ b/kex.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kex.c,v 1.93 2013/11/07 11:58:27 dtucker Exp $ */
+/* $OpenBSD: kex.c,v 1.94 2014/01/09 23:20:00 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
*
@@ -49,6 +49,7 @@
#include "dispatch.h"
#include "monitor.h"
#include "roaming.h"
+#include "digest.h"
#if OPENSSL_VERSION_NUMBER >= 0x00907000L
# if defined(HAVE_EVP_SHA256)
@@ -66,26 +67,30 @@ struct kexalg {
char *name;
int type;
int ec_nid;
- const EVP_MD *(*mdfunc)(void);
+ int hash_alg;
};
static const struct kexalg kexalgs[] = {
- { KEX_DH1, KEX_DH_GRP1_SHA1, 0, EVP_sha1 },
- { KEX_DH14, KEX_DH_GRP14_SHA1, 0, EVP_sha1 },
- { KEX_DHGEX_SHA1, KEX_DH_GEX_SHA1, 0, EVP_sha1 },
+ { KEX_DH1, KEX_DH_GRP1_SHA1, 0, SSH_DIGEST_SHA1 },
+ { KEX_DH14, KEX_DH_GRP14_SHA1, 0, SSH_DIGEST_SHA1 },
+ { KEX_DHGEX_SHA1, KEX_DH_GEX_SHA1, 0, SSH_DIGEST_SHA1 },
#ifdef HAVE_EVP_SHA256
- { KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, EVP_sha256 },
+ { KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, SSH_DIGEST_SHA256 },
#endif
#ifdef OPENSSL_HAS_ECC
- { KEX_ECDH_SHA2_NISTP256, KEX_ECDH_SHA2, NID_X9_62_prime256v1, EVP_sha256 },
- { KEX_ECDH_SHA2_NISTP384, KEX_ECDH_SHA2, NID_secp384r1, EVP_sha384 },
+ { KEX_ECDH_SHA2_NISTP256, KEX_ECDH_SHA2,
+ NID_X9_62_prime256v1, SSH_DIGEST_SHA256 },
+ { KEX_ECDH_SHA2_NISTP384, KEX_ECDH_SHA2, NID_secp384r1,
+ SSH_DIGEST_SHA384 },
# ifdef OPENSSL_HAS_NISTP521
- { KEX_ECDH_SHA2_NISTP521, KEX_ECDH_SHA2, NID_secp521r1, EVP_sha512 },
+ { KEX_ECDH_SHA2_NISTP521, KEX_ECDH_SHA2, NID_secp521r1,
+ SSH_DIGEST_SHA512 },
# endif
#endif
+ { KEX_DH1, KEX_DH_GRP1_SHA1, 0, SSH_DIGEST_SHA1 },
#ifdef HAVE_EVP_SHA256
- { KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, EVP_sha256 },
+ { KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 },
#endif
- { NULL, -1, -1, NULL},
+ { NULL, -1, -1, -1},
};
char *
@@ -406,7 +411,7 @@ choose_kex(Kex *k, char *client, char *server)
if ((kexalg = kex_alg_by_name(k->name)) == NULL)
fatal("unsupported kex alg %s", k->name);
k->kex_type = kexalg->type;
- k->evp_md = kexalg->mdfunc();
+ k->hash_alg = kexalg->hash_alg;
k->ec_nid = kexalg->ec_nid;
}
@@ -532,27 +537,31 @@ derive_key(Kex *kex, int id, u_int need, u_char *hash, u_int hashlen,
BIGNUM *shared_secret)
{
Buffer b;
- EVP_MD_CTX md;
+ struct ssh_digest_ctx *hashctx;
char c = id;
u_int have;
- int mdsz;
+ size_t mdsz;
u_char *digest;
- if ((mdsz = EVP_MD_size(kex->evp_md)) <= 0)
- fatal("bad kex md size %d", mdsz);
+ if ((mdsz = ssh_digest_bytes(kex->hash_alg)) == 0)
+ fatal("bad kex md size %zu", mdsz);
digest = xmalloc(roundup(need, mdsz));
buffer_init(&b);
buffer_put_bignum2(&b, shared_secret);
/* K1 = HASH(K || H || "A" || session_id) */
- EVP_DigestInit(&md, kex->evp_md);
- if (!(datafellows & SSH_BUG_DERIVEKEY))
- EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
- EVP_DigestUpdate(&md, hash, hashlen);
- EVP_DigestUpdate(&md, &c, 1);
- EVP_DigestUpdate(&md, kex->session_id, kex->session_id_len);
- EVP_DigestFinal(&md, digest, NULL);
+ if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL)
+ fatal("%s: ssh_digest_start failed", __func__);
+ if (ssh_digest_update_buffer(hashctx, &b) != 0 ||
+ ssh_digest_update(hashctx, hash, hashlen) != 0 ||
+ ssh_digest_update(hashctx, &c, 1) != 0 ||
+ ssh_digest_update(hashctx, kex->session_id,
+ kex->session_id_len) != 0)
+ fatal("%s: ssh_digest_update failed", __func__);
+ if (ssh_digest_final(hashctx, digest, mdsz) != 0)
+ fatal("%s: ssh_digest_final failed", __func__);
+ ssh_digest_free(hashctx);
/*
* expand key:
@@ -560,12 +569,15 @@ derive_key(Kex *kex, int id, u_int need, u_char *hash, u_int hashlen,
* Key = K1 || K2 || ... || Kn
*/
for (have = mdsz; need > have; have += mdsz) {
- EVP_DigestInit(&md, kex->evp_md);
- if (!(datafellows & SSH_BUG_DERIVEKEY))
- EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
- EVP_DigestUpdate(&md, hash, hashlen);
- EVP_DigestUpdate(&md, digest, have);
- EVP_DigestFinal(&md, digest + have, NULL);
+ if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL)
+ fatal("%s: ssh_digest_start failed", __func__);
+ if (ssh_digest_update_buffer(hashctx, &b) != 0 ||
+ ssh_digest_update(hashctx, hash, hashlen) != 0 ||
+ ssh_digest_update(hashctx, digest, have) != 0)
+ fatal("%s: ssh_digest_update failed", __func__);
+ if (ssh_digest_final(hashctx, digest + have, mdsz) != 0)
+ fatal("%s: ssh_digest_final failed", __func__);
+ ssh_digest_free(hashctx);
}
buffer_free(&b);
#ifdef DEBUG_KEX
@@ -615,33 +627,33 @@ void
derive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus,
u_int8_t cookie[8], u_int8_t id[16])
{
- const EVP_MD *evp_md = EVP_md5();
- EVP_MD_CTX md;
- u_int8_t nbuf[2048], obuf[EVP_MAX_MD_SIZE];
+ u_int8_t nbuf[2048], obuf[SSH_DIGEST_MAX_LENGTH];
int len;
+ struct ssh_digest_ctx *hashctx;
- EVP_DigestInit(&md, evp_md);
+ if ((hashctx = ssh_digest_start(SSH_DIGEST_MD5)) == NULL)
+ fatal("%s: ssh_digest_start", __func__);
len = BN_num_bytes(host_modulus);
if (len < (512 / 8) || (u_int)len > sizeof(nbuf))
fatal("%s: bad host modulus (len %d)", __func__, len);
BN_bn2bin(host_modulus, nbuf);
- EVP_DigestUpdate(&md, nbuf, len);
+ if (ssh_digest_update(hashctx, nbuf, len) != 0)
+ fatal("%s: ssh_digest_update failed", __func__);
len = BN_num_bytes(server_modulus);
if (len < (512 / 8) || (u_int)len > sizeof(nbuf))
fatal("%s: bad server modulus (len %d)", __func__, len);
BN_bn2bin(server_modulus, nbuf);
- EVP_DigestUpdate(&md, nbuf, len);
-
- EVP_DigestUpdate(&md, cookie, 8);
-
- EVP_DigestFinal(&md, obuf, NULL);
- memcpy(id, obuf, 16);
+ if (ssh_digest_update(hashctx, nbuf, len) != 0 ||
+ ssh_digest_update(hashctx, cookie, 8) != 0)
+ fatal("%s: ssh_digest_update failed", __func__);
+ if (ssh_digest_final(hashctx, obuf, sizeof(obuf)) != 0)
+ fatal("%s: ssh_digest_final failed", __func__);
+ memcpy(id, obuf, ssh_digest_bytes(SSH_DIGEST_MD5));
memset(nbuf, 0, sizeof(nbuf));
memset(obuf, 0, sizeof(obuf));
- memset(&md, 0, sizeof(md));
}
#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH)
diff --git a/kex.h b/kex.h
index 800a6923..fbe4940e 100644
--- a/kex.h
+++ b/kex.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: kex.h,v 1.58 2013/11/07 11:58:27 dtucker Exp $ */
+/* $OpenBSD: kex.h,v 1.59 2014/01/09 23:20:00 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@@ -133,7 +133,7 @@ struct Kex {
Buffer peer;
sig_atomic_t done;
int flags;
- const EVP_MD *evp_md;
+ int hash_alg;
int ec_nid;
char *client_version_string;
char *server_version_string;
@@ -170,17 +170,17 @@ void
kex_dh_hash(char *, char *, char *, int, char *, int, u_char *, int,
BIGNUM *, BIGNUM *, BIGNUM *, u_char **, u_int *);
void
-kexgex_hash(const EVP_MD *, char *, char *, char *, int, char *,
+kexgex_hash(int, char *, char *, char *, int, char *,
int, u_char *, int, int, int, int, BIGNUM *, BIGNUM *, BIGNUM *,
BIGNUM *, BIGNUM *, u_char **, u_int *);
#ifdef OPENSSL_HAS_ECC
void
-kex_ecdh_hash(const EVP_MD *, const EC_GROUP *, char *, char *, char *, int,
+kex_ecdh_hash(int, const EC_GROUP *, char *, char *, char *, int,
char *, int, u_char *, int, const EC_POINT *, const EC_POINT *,
const BIGNUM *, u_char **, u_int *);
#endif
void
-kex_c25519_hash(const EVP_MD *, char *, char *, char *, int,
+kex_c25519_hash(int, char *, char *, char *, int,
char *, int, u_char *, int, const u_char *, const u_char *,
const BIGNUM *, u_char **, u_int *);
diff --git a/kexc25519.c b/kexc25519.c
index 348a7d50..8dd36399 100644
--- a/kexc25519.c
+++ b/kexc25519.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kexc25519.c,v 1.2 2013/11/02 22:02:14 markus Exp $ */
+/* $OpenBSD: kexc25519.c,v 1.3 2014/01/09 23:20:00 djm Exp $ */
/*
* Copyright (c) 2001, 2013 Markus Friedl. All rights reserved.
* Copyright (c) 2010 Damien Miller. All rights reserved.
@@ -41,6 +41,7 @@
#include "cipher.h"
#include "kex.h"
#include "log.h"
+#include "digest.h"
extern int crypto_scalarmult_curve25519(u_char a[CURVE25519_SIZE],
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],
void
kex_c25519_hash(
- const EVP_MD *evp_md,
+ int hash_alg,
char *client_version_string,
char *server_version_string,
char *ckexinit, int ckexinitlen,
@@ -90,8 +91,7 @@ kex_c25519_hash(
u_char **hash, u_int *hashlen)
{
Buffer b;
- EVP_MD_CTX md;
- static u_char digest[EVP_MAX_MD_SIZE];
+ static u_char digest[SSH_DIGEST_MAX_LENGTH];
buffer_init(&b);
buffer_put_cstring(&b, client_version_string);
@@ -113,15 +113,14 @@ kex_c25519_hash(
#ifdef DEBUG_KEX
buffer_dump(&b);
#endif
- EVP_DigestInit(&md, evp_md);
- EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
- EVP_DigestFinal(&md, digest, NULL);
+ if (ssh_digest_buffer(hash_alg, &b, digest, sizeof(digest)) != 0)
+ fatal("%s: digest_buffer failed", __func__);
buffer_free(&b);
#ifdef DEBUG_KEX
- dump_digest("hash", digest, EVP_MD_size(evp_md));
+ dump_digest("hash", digest, ssh_digest_bytes(hash_alg));
#endif
*hash = digest;
- *hashlen = EVP_MD_size(evp_md);
+ *hashlen = ssh_digest_bytes(hash_alg);
}
diff --git a/kexc25519c.c b/kexc25519c.c
index f741566c..4655c254 100644
--- a/kexc25519c.c
+++ b/kexc25519c.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kexc25519c.c,v 1.2 2013/11/02 22:02:14 markus Exp $ */
+/* $OpenBSD: kexc25519c.c,v 1.3 2014/01/09 23:20:00 djm Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
* Copyright (c) 2010 Damien Miller. All rights reserved.
@@ -97,7 +97,7 @@ kexc25519_client(Kex *kex)
/* calc and verify H */
kex_c25519_hash(
- kex->evp_md,
+ kex->hash_alg,
kex->client_version_string,
kex->server_version_string,
buffer_ptr(&kex->my), buffer_len(&kex->my),
diff --git a/kexc25519s.c b/kexc25519s.c
index 784841b8..dc4f56c8 100644
--- a/kexc25519s.c
+++ b/kexc25519s.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kexc25519s.c,v 1.2 2013/11/02 22:02:14 markus Exp $ */
+/* $OpenBSD: kexc25519s.c,v 1.3 2014/01/09 23:20:00 djm Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
* Copyright (c) 2010 Damien Miller. All rights reserved.
@@ -81,7 +81,7 @@ kexc25519_server(Kex *kex)
/* calc H */
key_to_blob(server_host_public, &server_host_key_blob, &sbloblen);
kex_c25519_hash(
- kex->evp_md,
+ kex->hash_alg,
kex->client_version_string,
kex->server_version_string,
buffer_ptr(&kex->peer), buffer_len(&kex->peer),
diff --git a/kexdh.c b/kexdh.c
index 56e22f5b..e7cdadc9 100644
--- a/kexdh.c
+++ b/kexdh.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kexdh.c,v 1.23 2006/08/03 03:34:42 deraadt Exp $ */
+/* $OpenBSD: kexdh.c,v 1.24 2014/01/09 23:20:00 djm Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
*
@@ -36,6 +36,8 @@
#include "key.h"
#include "cipher.h"
#include "kex.h"
+#include "digest.h"
+#include "log.h"
void
kex_dh_hash(
@@ -50,9 +52,7 @@ kex_dh_hash(
u_char **hash, u_int *hashlen)
{
Buffer b;
- static u_char digest[EVP_MAX_MD_SIZE];
- const EVP_MD *evp_md = EVP_sha1();
- EVP_MD_CTX md;
+ static u_char digest[SSH_DIGEST_MAX_LENGTH];
buffer_init(&b);
buffer_put_cstring(&b, client_version_string);
@@ -74,15 +74,14 @@ kex_dh_hash(
#ifdef DEBUG_KEX
buffer_dump(&b);
#endif
- EVP_DigestInit(&md, evp_md);
- EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
- EVP_DigestFinal(&md, digest, NULL);
+ if (ssh_digest_buffer(SSH_DIGEST_SHA1, &b, digest, sizeof(digest)) != 0)
+ fatal("%s: ssh_digest_buffer failed", __func__);
buffer_free(&b);
#ifdef DEBUG_KEX
- dump_digest("hash", digest, EVP_MD_size(evp_md));
+ dump_digest("hash", digest, ssh_digest_bytes(SSH_DIGEST_SHA1));
#endif
*hash = digest;
- *hashlen = EVP_MD_size(evp_md);
+ *hashlen = ssh_digest_bytes(SSH_DIGEST_SHA1);
}
diff --git a/kexecdh.c b/kexecdh.c
index c948fe20..c52c5e23 100644
--- a/kexecdh.c
+++ b/kexecdh.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kexecdh.c,v 1.4 2013/04/19 01:06:50 djm Exp $ */
+/* $OpenBSD: kexecdh.c,v 1.5 2014/01/09 23:20:00 djm Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
* Copyright (c) 2010 Damien Miller. All rights reserved.
@@ -44,10 +44,11 @@
#include "cipher.h"
#include "kex.h"
#include "log.h"
+#include "digest.h"
void
kex_ecdh_hash(
- const EVP_MD *evp_md,
+ int hash_alg,
const EC_GROUP *ec_group,
char *client_version_string,
char *server_version_string,
@@ -60,8 +61,7 @@ kex_ecdh_hash(
u_char **hash, u_int *hashlen)
{
Buffer b;
- EVP_MD_CTX md;
- static u_char digest[EVP_MAX_MD_SIZE];
+ static u_char digest[SSH_DIGEST_MAX_LENGTH];
buffer_init(&b);
buffer_put_cstring(&b, client_version_string);
@@ -83,17 +83,15 @@ kex_ecdh_hash(
#ifdef DEBUG_KEX
buffer_dump(&b);
#endif
- EVP_DigestInit(&md, evp_md);
- EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
- EVP_DigestFinal(&md, digest, NULL);
+ if (ssh_digest_buffer(hash_alg, &b, digest, sizeof(digest)) != 0)
+ fatal("%s: ssh_digest_buffer failed", __func__);
buffer_free(&b);
#ifdef DEBUG_KEX
- dump_digest("hash", digest, EVP_MD_size(evp_md));
+ dump_digest("hash", digest, ssh_digest_bytes(hash_alg));
#endif
*hash = digest;
- *hashlen = EVP_MD_size(evp_md);
+ *hashlen = ssh_digest_bytes(hash_alg);
}
-
#endif /* OPENSSL_HAS_ECC */
diff --git a/kexecdhc.c b/kexecdhc.c
index 6193836c..fc62cec5 100644
--- a/kexecdhc.c
+++ b/kexecdhc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kexecdhc.c,v 1.4 2013/05/17 00:13:13 djm Exp $ */
+/* $OpenBSD: kexecdhc.c,v 1.5 2014/01/09 23:20:00 djm Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
* Copyright (c) 2010 Damien Miller. All rights reserved.
@@ -124,7 +124,7 @@ kexecdh_client(Kex *kex)
/* calc and verify H */
kex_ecdh_hash(
- kex->evp_md,
+ kex->hash_alg,
group,
kex->client_version_string,
kex->server_version_string,
diff --git a/kexecdhs.c b/kexecdhs.c
index 431fd2c2..d1dd8c7f 100644
--- a/kexecdhs.c
+++ b/kexecdhs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kexecdhs.c,v 1.7 2013/11/02 22:24:24 markus Exp $ */
+/* $OpenBSD: kexecdhs.c,v 1.8 2014/01/09 23:20:00 djm Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
* Copyright (c) 2010 Damien Miller. All rights reserved.
@@ -109,7 +109,7 @@ kexecdh_server(Kex *kex)
/* calc H */
key_to_blob(server_host_public, &server_host_key_blob, &sbloblen);
kex_ecdh_hash(
- kex->evp_md,
+ kex->hash_alg,
group,
kex->client_version_string,
kex->server_version_string,
diff --git a/kexgex.c b/kexgex.c
index b60ab5c5..c2e6bc16 100644
--- a/kexgex.c
+++ b/kexgex.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kexgex.c,v 1.27 2006/08/03 03:34:42 deraadt Exp $ */
+/* $OpenBSD: kexgex.c,v 1.28 2014/01/09 23:20:00 djm Exp $ */
/*
* Copyright (c) 2000 Niels Provos. All rights reserved.
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -36,10 +36,12 @@
#include "cipher.h"
#include "kex.h"
#include "ssh2.h"
+#include "digest.h"
+#include "log.h"
void
kexgex_hash(
- const EVP_MD *evp_md,
+ int hash_alg,
char *client_version_string,
char *server_version_string,
char *ckexinit, int ckexinitlen,
@@ -52,8 +54,7 @@ kexgex_hash(
u_char **hash, u_int *hashlen)
{
Buffer b;
- static u_char digest[EVP_MAX_MD_SIZE];
- EVP_MD_CTX md;
+ static u_char digest[SSH_DIGEST_MAX_LENGTH];
buffer_init(&b);
buffer_put_cstring(&b, client_version_string);
@@ -84,15 +85,14 @@ kexgex_hash(
#ifdef DEBUG_KEXDH
buffer_dump(&b);
#endif
-
- EVP_DigestInit(&md, evp_md);
- EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
- EVP_DigestFinal(&md, digest, NULL);
+ if (ssh_digest_buffer(hash_alg, &b, digest, sizeof(digest)) != 0)
+ fatal("%s: ssh_digest_buffer failed", __func__);
buffer_free(&b);
- *hash = digest;
- *hashlen = EVP_MD_size(evp_md);
-#ifdef DEBUG_KEXDH
- dump_digest("hash", digest, *hashlen);
+
+#ifdef DEBUG_KEX
+ dump_digest("hash", digest, ssh_digest_bytes(hash_alg));
#endif
+ *hash = digest;
+ *hashlen = ssh_digest_bytes(hash_alg);
}
diff --git a/kexgexc.c b/kexgexc.c
index 5a3be200..ca771edf 100644
--- a/kexgexc.c
+++ b/kexgexc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kexgexc.c,v 1.13 2013/05/17 00:13:13 djm Exp $ */
+/* $OpenBSD: kexgexc.c,v 1.14 2014/01/09 23:20:00 djm Exp $ */
/*
* Copyright (c) 2000 Niels Provos. All rights reserved.
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -170,7 +170,7 @@ kexgex_client(Kex *kex)
/* calc and verify H */
kexgex_hash(
- kex->evp_md,
+ kex->hash_alg,
kex->client_version_string,
kex->server_version_string,
buffer_ptr(&kex->my), buffer_len(&kex->my),
diff --git a/kexgexs.c b/kexgexs.c
index 4e473fc7..90853403 100644
--- a/kexgexs.c
+++ b/kexgexs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kexgexs.c,v 1.16 2013/07/19 07:37:48 markus Exp $ */
+/* $OpenBSD: kexgexs.c,v 1.17 2014/01/09 23:20:00 djm Exp $ */
/*
* Copyright (c) 2000 Niels Provos. All rights reserved.
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -160,7 +160,7 @@ kexgex_server(Kex *kex)
/* calc H */
kexgex_hash(
- kex->evp_md,
+ kex->hash_alg,
kex->client_version_string,
kex->server_version_string,
buffer_ptr(&kex->peer), buffer_len(&kex->peer),
diff --git a/key.c b/key.c
index b0bb46f3..91423380 100644
--- a/key.c
+++ b/key.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: key.c,v 1.114 2013/12/29 04:20:04 djm Exp $ */
+/* $OpenBSD: key.c,v 1.115 2014/01/09 23:20:00 djm Exp $ */
/*
* read_bignum():
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -56,6 +56,7 @@
#include "log.h"
#include "misc.h"
#include "ssh2.h"
+#include "digest.h"
static int to_blob(const Key *, u_char **, u_int *, int);
static Key *key_from_blob2(const u_char *, u_int, int);
@@ -358,30 +359,26 @@ u_char*
key_fingerprint_raw(const Key *k, enum fp_type dgst_type,
u_int *dgst_raw_length)
{
- const EVP_MD *md = NULL;
- EVP_MD_CTX ctx;
u_char *blob = NULL;
u_char *retval = NULL;
u_int len = 0;
- int nlen, elen;
+ int nlen, elen, hash_alg = -1;
*dgst_raw_length = 0;
+ /* XXX switch to DIGEST_* directly? */
switch (dgst_type) {
case SSH_FP_MD5:
- md = EVP_md5();
+ hash_alg = SSH_DIGEST_MD5;
break;
case SSH_FP_SHA1:
-