summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2014-02-04 11:02:42 +1100
committerDamien Miller <djm@mindrot.org>2014-02-04 11:02:42 +1100
commit4e8d937af79ce4e253f77ec93489d098b25becc3 (patch)
tree83b0293313eea8dfebcc7f906c5058f530238e8b
parent69d0d09f76bab5aec86fbf78489169f63bd16475 (diff)
- markus@cvs.openbsd.org 2014/01/27 18:58:14
[Makefile.in digest.c digest.h hostfile.c kex.h mac.c hmac.c hmac.h] replace openssl HMAC with an implementation based on our ssh_digest_* ok and feedback djm@
-rw-r--r--ChangeLog7
-rw-r--r--Makefile.in4
-rw-r--r--digest.c25
-rw-r--r--digest.h12
-rw-r--r--hmac.c197
-rw-r--r--hmac.h37
-rw-r--r--hostfile.c29
-rw-r--r--kex.h7
-rw-r--r--mac.c85
9 files changed, 332 insertions, 71 deletions
diff --git a/ChangeLog b/ChangeLog
index 46f157df..8b619de7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+20140204
+ - OpenBSD CVS Sync
+ - markus@cvs.openbsd.org 2014/01/27 18:58:14
+ [Makefile.in digest.c digest.h hostfile.c kex.h mac.c hmac.c hmac.h]
+ replace openssl HMAC with an implementation based on our ssh_digest_*
+ ok and feedback djm@
+
20140131
- (djm) [sandbox-seccomp-filter.c sandbox-systrace.c] Allow shutdown(2)
syscall from sandboxes; it may be called by packet_close.
diff --git a/Makefile.in b/Makefile.in
index 41f704bb..99ac27eb 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,4 +1,4 @@
-# $Id: Makefile.in,v 1.353 2014/01/31 22:25:19 tim Exp $
+# $Id: Makefile.in,v 1.354 2014/02/04 00:02:43 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 digest.o \
+ ssh-ed25519.o digest.o hmac.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
index a221819e..1a11b2b1 100644
--- a/digest.c
+++ b/digest.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: digest.c,v 1.3 2014/01/20 00:08:48 djm Exp $ */
+/* $OpenBSD: digest.c,v 1.4 2014/01/27 18:58:14 markus Exp $ */
/*
* Copyright (c) 2013 Damien Miller <djm@mindrot.org>
*
@@ -72,6 +72,12 @@ ssh_digest_bytes(int alg)
return digest == NULL ? 0 : digest->digest_len;
}
+size_t
+ssh_digest_blocksize(struct ssh_digest_ctx *ctx)
+{
+ return EVP_MD_CTX_block_size(&ctx->mdctx);
+}
+
struct ssh_digest_ctx *
ssh_digest_start(int alg)
{
@@ -90,6 +96,15 @@ ssh_digest_start(int alg)
}
int
+ssh_digest_copy_state(struct ssh_digest_ctx *from, struct ssh_digest_ctx *to)
+{
+ /* we have bcopy-style order while openssl has memcpy-style */
+ if (!EVP_MD_CTX_copy_ex(&to->mdctx, &from->mdctx))
+ return -1;
+ return 0;
+}
+
+int
ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen)
{
if (EVP_DigestUpdate(&ctx->mdctx, m, mlen) != 1)
@@ -123,9 +138,11 @@ ssh_digest_final(struct ssh_digest_ctx *ctx, u_char *d, size_t dlen)
void
ssh_digest_free(struct ssh_digest_ctx *ctx)
{
- EVP_MD_CTX_cleanup(&ctx->mdctx);
- memset(ctx, 0, sizeof(*ctx));
- free(ctx);
+ if (ctx != NULL) {
+ EVP_MD_CTX_cleanup(&ctx->mdctx);
+ memset(ctx, 0, sizeof(*ctx));
+ free(ctx);
+ }
}
int
diff --git a/digest.h b/digest.h
index faefda3f..0fb207fc 100644
--- a/digest.h
+++ b/digest.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: digest.h,v 1.1 2014/01/09 23:20:00 djm Exp $ */
+/* $OpenBSD: digest.h,v 1.2 2014/01/27 18:58:14 markus Exp $ */
/*
* Copyright (c) 2013 Damien Miller <djm@mindrot.org>
*
@@ -30,9 +30,18 @@
#define SSH_DIGEST_SHA512 5
#define SSH_DIGEST_MAX 6
+struct ssh_digest_ctx;
+
/* Returns the algorithm's digest length in bytes or 0 for invalid algorithm */
size_t ssh_digest_bytes(int alg);
+/* Returns the block size of the digest, e.g. for implementing HMAC */
+size_t ssh_digest_blocksize(struct ssh_digest_ctx *ctx);
+
+/* Copies internal state of digest of 'from' to 'to' */
+int ssh_digest_copy_state(struct ssh_digest_ctx *from,
+ struct ssh_digest_ctx *to);
+
/* One-shot API */
int ssh_digest_memory(int alg, const void *m, size_t mlen,
u_char *d, size_t dlen)
@@ -42,7 +51,6 @@ 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)));
diff --git a/hmac.c b/hmac.c
new file mode 100644
index 00000000..99317b0f
--- /dev/null
+++ b/hmac.c
@@ -0,0 +1,197 @@
+/* $OpenBSD: hmac.c,v 1.10 2014/01/31 16:39:19 tedu Exp $ */
+/*
+ * Copyright (c) 2014 Markus Friedl. All rights reserved.
+ *
+ * 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 <string.h>
+
+#include "buffer.h"
+#include "digest.h"
+#include "hmac.h"
+
+struct ssh_hmac_ctx {
+ int alg;
+ struct ssh_digest_ctx *ictx;
+ struct ssh_digest_ctx *octx;
+ struct ssh_digest_ctx *digest;
+ u_char *buf;
+ size_t buf_len;
+};
+
+size_t
+ssh_hmac_bytes(int alg)
+{
+ return ssh_digest_bytes(alg);
+}
+
+struct ssh_hmac_ctx *
+ssh_hmac_start(int alg)
+{
+ struct ssh_hmac_ctx *ret;
+
+ if ((ret = calloc(1, sizeof(*ret))) == NULL)
+ return NULL;
+ ret->alg = alg;
+ if ((ret->ictx = ssh_digest_start(alg)) == NULL ||
+ (ret->octx = ssh_digest_start(alg)) == NULL ||
+ (ret->digest = ssh_digest_start(alg)) == NULL)
+ goto fail;
+ ret->buf_len = ssh_digest_blocksize(ret->ictx);
+ if ((ret->buf = calloc(1, ret->buf_len)) == NULL)
+ goto fail;
+ return ret;
+fail:
+ ssh_hmac_free(ret);
+ return NULL;
+}
+
+int
+ssh_hmac_init(struct ssh_hmac_ctx *ctx, const void *key, size_t klen)
+{
+ size_t i;
+
+ /* reset ictx and octx if no is key given */
+ if (key != NULL) {
+ /* truncate long keys */
+ if (klen <= ctx->buf_len)
+ memcpy(ctx->buf, key, klen);
+ else if (ssh_digest_memory(ctx->alg, key, klen, ctx->buf,
+ ctx->buf_len) < 0)
+ return -1;
+ for (i = 0; i < ctx->buf_len; i++)
+ ctx->buf[i] ^= 0x36;
+ if (ssh_digest_update(ctx->ictx, ctx->buf, ctx->buf_len) < 0)
+ return -1;
+ for (i = 0; i < ctx->buf_len; i++)
+ ctx->buf[i] ^= 0x36 ^ 0x5c;
+ if (ssh_digest_update(ctx->octx, ctx->buf, ctx->buf_len) < 0)
+ return -1;
+ explicit_bzero(ctx->buf, ctx->buf_len);
+ }
+ /* start with ictx */
+ if (ssh_digest_copy_state(ctx->ictx, ctx->digest) < 0)
+ return -1;
+ return 0;
+}
+
+int
+ssh_hmac_update(struct ssh_hmac_ctx *ctx, const void *m, size_t mlen)
+{
+ return ssh_digest_update(ctx->digest, m, mlen);
+}
+
+int
+ssh_hmac_update_buffer(struct ssh_hmac_ctx *ctx, const Buffer *b)
+{
+ return ssh_digest_update_buffer(ctx->digest, b);
+}
+
+int
+ssh_hmac_final(struct ssh_hmac_ctx *ctx, u_char *d, size_t dlen)
+{
+ size_t len;
+
+ len = ssh_digest_bytes(ctx->alg);
+ if (dlen < len ||
+ ssh_digest_final(ctx->digest, ctx->buf, len))
+ return -1;
+ /* switch to octx */
+ if (ssh_digest_copy_state(ctx->octx, ctx->digest) < 0 ||
+ ssh_digest_update(ctx->digest, ctx->buf, len) < 0 ||
+ ssh_digest_final(ctx->digest, d, dlen) < 0)
+ return -1;
+ return 0;
+}
+
+void
+ssh_hmac_free(struct ssh_hmac_ctx *ctx)
+{
+ if (ctx != NULL) {
+ ssh_digest_free(ctx->ictx);
+ ssh_digest_free(ctx->octx);
+ ssh_digest_free(ctx->digest);
+ if (ctx->buf) {
+ explicit_bzero(ctx->buf, ctx->buf_len);
+ free(ctx->buf);
+ }
+ explicit_bzero(ctx, sizeof(*ctx));
+ free(ctx);
+ }
+}
+
+#ifdef TEST
+
+/* cc -DTEST hmac.c digest.c buffer.c cleanup.c fatal.c log.c xmalloc.c -lcrypto */
+static void
+hmac_test(void *key, size_t klen, void *m, size_t mlen, u_char *e, size_t elen)
+{
+ struct ssh_hmac_ctx *ctx;
+ size_t i;
+ u_char digest[16];
+
+ if ((ctx = ssh_hmac_start(SSH_DIGEST_MD5)) == NULL)
+ printf("ssh_hmac_start failed");
+ if (ssh_hmac_init(ctx, key, klen) < 0 ||
+ ssh_hmac_update(ctx, m, mlen) < 0 ||
+ ssh_hmac_final(ctx, digest, sizeof(digest)) < 0)
+ printf("ssh_hmac_xxx failed");
+ ssh_hmac_free(ctx);
+
+ if (memcmp(e, digest, elen)) {
+ for (i = 0; i < elen; i++)
+ printf("[%zd] %2.2x %2.2x\n", i, e[i], digest[i]);
+ printf("mismatch\n");
+ } else
+ printf("ok\n");
+}
+
+int
+main(int argc, char **argv)
+{
+ /* try test vectors from RFC 2104 */
+
+ u_char key1[16] = {
+ 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb,
+ 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb };
+ u_char *data1 = "Hi There";
+ u_char dig1[16] = {
+ 0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c,
+ 0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d };
+
+ u_char *key2 = "Jefe";
+ u_char *data2 = "what do ya want for nothing?";
+ u_char dig2[16] = {
+ 0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03,
+ 0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38 };
+
+ u_char key3[16];
+ u_char data3[50];
+ u_char dig3[16] = {
+ 0x56, 0xbe, 0x34, 0x52, 0x1d, 0x14, 0x4c, 0x88,
+ 0xdb, 0xb8, 0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6 };
+ memset(key3, 0xaa, sizeof(key3));
+ memset(data3, 0xdd, sizeof(data3));
+
+ hmac_test(key1, sizeof(key1), data1, strlen(data1), dig1, sizeof(dig1));
+ hmac_test(key2, strlen(key2), data2, strlen(data2), dig2, sizeof(dig2));
+ hmac_test(key3, sizeof(key3), data3, sizeof(data3), dig3, sizeof(dig3));
+
+ return 0;
+}
+
+#endif
diff --git a/hmac.h b/hmac.h
new file mode 100644
index 00000000..2374a695
--- /dev/null
+++ b/hmac.h
@@ -0,0 +1,37 @@
+/* $OpenBSD: hmac.h,v 1.6 2014/01/27 18:58:14 markus Exp $ */
+/*
+ * Copyright (c) 2014 Markus Friedl. All rights reserved.
+ *
+ * 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 _HMAC_H
+#define _HMAC_H
+
+/* Returns the algorithm's digest length in bytes or 0 for invalid algorithm */
+size_t ssh_hmac_bytes(int alg);
+
+struct ssh_hmac_ctx;
+struct ssh_hmac_ctx *ssh_hmac_start(int alg);
+
+/* Sets the state of the HMAC or resets the state if key == NULL */
+int ssh_hmac_init(struct ssh_hmac_ctx *ctx, const void *key, size_t klen)
+ __attribute__((__bounded__(__buffer__, 2, 3)));
+int ssh_hmac_update(struct ssh_hmac_ctx *ctx, const void *m, size_t mlen)
+ __attribute__((__bounded__(__buffer__, 2, 3)));
+int ssh_hmac_update_buffer(struct ssh_hmac_ctx *ctx, const Buffer *b);
+int ssh_hmac_final(struct ssh_hmac_ctx *ctx, u_char *d, size_t dlen)
+ __attribute__((__bounded__(__buffer__, 2, 3)));
+void ssh_hmac_free(struct ssh_hmac_ctx *ctx);
+
+#endif /* _HMAC_H */
diff --git a/hostfile.c b/hostfile.c
index 2778fb5d..0198cd00 100644
--- a/hostfile.c
+++ b/hostfile.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: hostfile.c,v 1.53 2014/01/09 23:20:00 djm Exp $ */
+/* $OpenBSD: hostfile.c,v 1.54 2014/01/27 18:58:14 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -42,9 +42,6 @@
#include <netinet/in.h>
-#include <openssl/hmac.h>
-#include <openssl/sha.h>
-
#include <resolv.h>
#include <stdarg.h>
#include <stdio.h>
@@ -58,6 +55,7 @@
#include "log.h"
#include "misc.h"
#include "digest.h"
+#include "hmac.h"
struct hostkeys {
struct hostkey_entry *entries;
@@ -102,9 +100,9 @@ extract_salt(const char *s, u_int l, u_char *salt, size_t salt_len)
debug2("extract_salt: salt decode error");
return (-1);
}
- if (ret != SHA_DIGEST_LENGTH) {
- debug2("extract_salt: expected salt len %d, got %d",
- SHA_DIGEST_LENGTH, ret);
+ if (ret != (int)ssh_hmac_bytes(SSH_DIGEST_SHA1)) {
+ debug2("extract_salt: expected salt len %zd, got %d",
+ ssh_hmac_bytes(SSH_DIGEST_SHA1), ret);
return (-1);
}
@@ -114,14 +112,13 @@ extract_salt(const char *s, u_int l, u_char *salt, size_t salt_len)
char *
host_hash(const char *host, const char *name_from_hostfile, u_int src_len)
{
- const EVP_MD *md = EVP_sha1();
- HMAC_CTX mac_ctx;
+ struct ssh_hmac_ctx *ctx;
u_char salt[256], result[256];
char uu_salt[512], uu_result[512];
static char encoded[1024];
u_int i, len;
- len = EVP_MD_size(md);
+ len = ssh_digest_bytes(SSH_DIGEST_SHA1);
if (name_from_hostfile == NULL) {
/* Create new salt */
@@ -134,14 +131,16 @@ host_hash(const char *host, const char *name_from_hostfile, u_int src_len)
return (NULL);
}
- HMAC_Init(&mac_ctx, salt, len, md);
- HMAC_Update(&mac_ctx, (u_char *)host, strlen(host));
- HMAC_Final(&mac_ctx, result, NULL);
- HMAC_cleanup(&mac_ctx);
+ if ((ctx = ssh_hmac_start(SSH_DIGEST_SHA1)) == NULL ||
+ ssh_hmac_init(ctx, salt, len) < 0 ||
+ ssh_hmac_update(ctx, host, strlen(host)) < 0 ||
+ ssh_hmac_final(ctx, result, sizeof(result)))
+ fatal("%s: ssh_hmac failed", __func__);
+ ssh_hmac_free(ctx);
if (__b64_ntop(salt, len, uu_salt, sizeof(uu_salt)) == -1 ||
__b64_ntop(result, len, uu_result, sizeof(uu_result)) == -1)
- fatal("host_hash: __b64_ntop failed");
+ fatal("%s: __b64_ntop failed", __func__);
snprintf(encoded, sizeof(encoded), "%s%s%c%s", HASH_MAGIC, uu_salt,
HASH_DELIM, uu_result);
diff --git a/kex.h b/kex.h
index 1aa3ec26..c85680ee 100644
--- a/kex.h
+++ b/kex.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: kex.h,v 1.61 2014/01/25 10:12:50 dtucker Exp $ */
+/* $OpenBSD: kex.h,v 1.62 2014/01/27 18:58:14 markus Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@@ -105,9 +105,8 @@ struct Mac {
u_int key_len;
int type;
int etm; /* Encrypt-then-MAC */
- const EVP_MD *evp_md;
- HMAC_CTX evp_ctx;
- struct umac_ctx *umac_ctx;
+ struct ssh_hmac_ctx *hmac_ctx;
+ struct umac_ctx *umac_ctx;
};
struct Comp {
int type;
diff --git a/mac.c b/mac.c
index d3a0b935..4c4a6bf5 100644
--- a/mac.c
+++ b/mac.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mac.c,v 1.26 2014/01/04 17:50:55 tedu Exp $ */
+/* $OpenBSD: mac.c,v 1.27 2014/01/27 18:58:14 markus Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
*
@@ -27,8 +27,6 @@
#include <sys/types.h>
-#include <openssl/hmac.h>
-
#include <stdarg.h>
#include <string.h>
#include <signal.h>
@@ -42,18 +40,20 @@
#include "mac.h"
#include "misc.h"
+#include "digest.h"
+#include "hmac.h"
#include "umac.h"
#include "openbsd-compat/openssl-compat.h"
-#define SSH_EVP 1 /* OpenSSL EVP-based MAC */
+#define SSH_DIGEST 1 /* SSH_DIGEST_XXX */
#define SSH_UMAC 2 /* UMAC (not integrated with OpenSSL) */
#define SSH_UMAC128 3
struct macalg {
char *name;
int type;
- const EVP_MD * (*mdfunc)(void);
+ int alg;
int truncatebits; /* truncate digest if != 0 */
int key_len; /* just for UMAC */
int len; /* just for UMAC */
@@ -62,33 +62,33 @@ struct macalg {
static const struct macalg macs[] = {
/* Encrypt-and-MAC (encrypt-and-authenticate) variants */
- { "hmac-sha1", SSH_EVP, EVP_sha1, 0, 0, 0, 0 },
- { "hmac-sha1-96", SSH_EVP, EVP_sha1, 96, 0, 0, 0 },
+ { "hmac-sha1", SSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 0 },
+ { "hmac-sha1-96", SSH_DIGEST, SSH_DIGEST_SHA1, 96, 0, 0, 0 },
#ifdef HAVE_EVP_SHA256
- { "hmac-sha2-256", SSH_EVP, EVP_sha256, 0, 0, 0, 0 },
- { "hmac-sha2-512", SSH_EVP, EVP_sha512, 0, 0, 0, 0 },
+ { "hmac-sha2-256", SSH_DIGEST, SSH_DIGEST_SHA256, 0, 0, 0, 0 },
+ { "hmac-sha2-512", SSH_DIGEST, SSH_DIGEST_SHA512, 0, 0, 0, 0 },
#endif
- { "hmac-md5", SSH_EVP, EVP_md5, 0, 0, 0, 0 },
- { "hmac-md5-96", SSH_EVP, EVP_md5, 96, 0, 0, 0 },
- { "hmac-ripemd160", SSH_EVP, EVP_ripemd160, 0, 0, 0, 0 },
- { "hmac-ripemd160@openssh.com", SSH_EVP, EVP_ripemd160, 0, 0, 0, 0 },
- { "umac-64@openssh.com", SSH_UMAC, NULL, 0, 128, 64, 0 },
- { "umac-128@openssh.com", SSH_UMAC128, NULL, 0, 128, 128, 0 },
+ { "hmac-md5", SSH_DIGEST, SSH_DIGEST_MD5, 0, 0, 0, 0 },
+ { "hmac-md5-96", SSH_DIGEST, SSH_DIGEST_MD5, 96, 0, 0, 0 },
+ { "hmac-ripemd160", SSH_DIGEST, SSH_DIGEST_RIPEMD160, 0, 0, 0, 0 },
+ { "hmac-ripemd160@openssh.com", SSH_DIGEST, SSH_DIGEST_RIPEMD160, 0, 0, 0, 0 },
+ { "umac-64@openssh.com", SSH_UMAC, 0, 0, 128, 64, 0 },
+ { "umac-128@openssh.com", SSH_UMAC128, 0, 0, 128, 128, 0 },
/* Encrypt-then-MAC variants */
- { "hmac-sha1-etm@openssh.com", SSH_EVP, EVP_sha1, 0, 0, 0, 1 },
- { "hmac-sha1-96-etm@openssh.com", SSH_EVP, EVP_sha1, 96, 0, 0, 1 },
+ { "hmac-sha1-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 1 },
+ { "hmac-sha1-96-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA1, 96, 0, 0, 1 },
#ifdef HAVE_EVP_SHA256
- { "hmac-sha2-256-etm@openssh.com", SSH_EVP, EVP_sha256, 0, 0, 0, 1 },
- { "hmac-sha2-512-etm@openssh.com", SSH_EVP, EVP_sha512, 0, 0, 0, 1 },
+ { "hmac-sha2-256-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA256, 0, 0, 0, 1 },
+ { "hmac-sha2-512-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA512, 0, 0, 0, 1 },
#endif
- { "hmac-md5-etm@openssh.com", SSH_EVP, EVP_md5, 0, 0, 0, 1 },
- { "hmac-md5-96-etm@openssh.com", SSH_EVP, EVP_md5, 96, 0, 0, 1 },
- { "hmac-ripemd160-etm@openssh.com", SSH_EVP, EVP_ripemd160, 0, 0, 0, 1 },
- { "umac-64-etm@openssh.com", SSH_UMAC, NULL, 0, 128, 64, 1 },
- { "umac-128-etm@openssh.com", SSH_UMAC128, NULL, 0, 128, 128, 1 },
+ { "hmac-md5-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_MD5, 0, 0, 0, 1 },
+ { "hmac-md5-96-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_MD5, 96, 0, 0, 1 },
+ { "hmac-ripemd160-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_RIPEMD160, 0, 0, 0, 1 },
+ { "umac-64-etm@openssh.com", SSH_UMAC, 0, 0, 128, 64, 1 },
+ { "umac-128-etm@openssh.com", SSH_UMAC128, 0, 0, 128, 128, 1 },
- { NULL, 0, NULL, 0, 0, 0, 0 }
+ { NULL, 0, 0, 0, 0, 0, 0 }
};
/* Returns a list of supported MACs separated by the specified char. */
@@ -113,14 +113,11 @@ mac_alg_list(char sep)
static void
mac_setup_by_alg(Mac *mac, const struct macalg *macalg)
{
- int evp_len;
-
mac->type = macalg->type;
- if (mac->type == SSH_EVP) {
- mac->evp_md = macalg->mdfunc();
- if ((evp_len = EVP_MD_size(mac->evp_md)) <= 0)
- fatal("mac %s len %d", mac->name, evp_len);
- mac->key_len = mac->mac_len = (u_int)evp_len;
+ if (mac->type == SSH_DIGEST) {
+ if ((mac->hmac_ctx = ssh_hmac_start(macalg->alg)) == NULL)
+ fatal("ssh_hmac_start(alg=%d) failed", macalg->alg);
+ mac->key_len = mac->mac_len = ssh_hmac_bytes(macalg->alg);
} else {
mac->mac_len = macalg->len / 8;
mac->key_len = macalg->key_len / 8;
@@ -154,11 +151,10 @@ mac_init(Mac *mac)
if (mac->key == NULL)
fatal("mac_init: no key");
switch (mac->type) {
- case SSH_EVP:
- if (mac->evp_md == NULL)
+ case SSH_DIGEST:
+ if (mac->hmac_ctx == NULL ||
+ ssh_hmac_init(mac->hmac_ctx, mac->key, mac->key_len) < 0)
return -1;
- HMAC_CTX_init(&mac->evp_ctx);
- HMAC_Init(&mac->evp_ctx, mac->key, mac->key_len, mac->evp_md);
return 0;
case SSH_UMAC:
mac->umac_ctx = umac_new(mac->key);
@@ -185,13 +181,14 @@ mac_compute(Mac *mac, u_int32_t seqno, u_char *data, int datalen)
mac->mac_len, sizeof(u));
switch (mac->type) {
- case SSH_EVP:
+ case SSH_DIGEST:
put_u32(b, seqno);
/* reset HMAC context */
- HMAC_Init(&mac->evp_ctx, NULL, 0, NULL);
- HMAC_Update(&mac->evp_ctx, b, sizeof(b));
- HMAC_Update(&mac->evp_ctx, data, datalen);
- HMAC_Final(&mac->evp_ctx, u.m, NULL);
+ if (ssh_hmac_init(mac->hmac_ctx, NULL, 0) < 0 ||
+ ssh_hmac_update(mac->hmac_ctx, b, sizeof(b)) < 0 ||
+ ssh_hmac_update(mac->hmac_ctx, data, datalen) < 0 ||
+ ssh_hmac_final(mac->hmac_ctx, u.m, sizeof(u.m)) < 0)
+ fatal("ssh_hmac failed");
break;
case SSH_UMAC:
put_u64(nonce, seqno);
@@ -218,9 +215,9 @@ mac_clear(Mac *mac)
} else if (mac->type == SSH_UMAC128) {
if (mac->umac_ctx != NULL)
umac128_delete(mac->umac_ctx);
- } else if (mac->evp_md != NULL)
- HMAC_cleanup(&mac->evp_ctx);
- mac->evp_md = NULL;
+ } else if (mac->hmac_ctx != NULL)
+ ssh_hmac_free(mac->hmac_ctx);
+ mac->hmac_ctx = NULL;
mac->umac_ctx = NULL;
}