summaryrefslogtreecommitdiffstats
path: root/usr.bin
diff options
context:
space:
mode:
authormarkus <markus@openbsd.org>2014-01-27 18:58:14 +0000
committermarkus <markus@openbsd.org>2014-01-27 18:58:14 +0000
commitf7baae32f687aeda5148a60d3303df7ceeea0f78 (patch)
treee237946e614fbccb7ec2d464f3704b3e51f2c11c /usr.bin
parentOnly remove COMPFILE if it exists. (diff)
downloadwireguard-openbsd-f7baae32f687aeda5148a60d3303df7ceeea0f78.tar.xz
wireguard-openbsd-f7baae32f687aeda5148a60d3303df7ceeea0f78.zip
replace openssl HMAC with an implementation based on our ssh_digest_*
ok and feedback djm@
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/ssh/digest.c25
-rw-r--r--usr.bin/ssh/digest.h12
-rw-r--r--usr.bin/ssh/hmac.c195
-rw-r--r--usr.bin/ssh/hmac.h37
-rw-r--r--usr.bin/ssh/hostfile.c29
-rw-r--r--usr.bin/ssh/kex.h7
-rw-r--r--usr.bin/ssh/lib/Makefile4
-rw-r--r--usr.bin/ssh/mac.c85
8 files changed, 324 insertions, 70 deletions
diff --git a/usr.bin/ssh/digest.c b/usr.bin/ssh/digest.c
index cb962e1c486..ec86366c5af 100644
--- a/usr.bin/ssh/digest.c
+++ b/usr.bin/ssh/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>
*
@@ -66,6 +66,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)
{
@@ -84,6 +90,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)
@@ -117,9 +132,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/usr.bin/ssh/digest.h b/usr.bin/ssh/digest.h
index faefda3f533..0fb207fcaa1 100644
--- a/usr.bin/ssh/digest.h
+++ b/usr.bin/ssh/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/usr.bin/ssh/hmac.c b/usr.bin/ssh/hmac.c
new file mode 100644
index 00000000000..cdd98ff1c79
--- /dev/null
+++ b/usr.bin/ssh/hmac.c
@@ -0,0 +1,195 @@
+/* $OpenBSD: hmac.c,v 1.9 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.
+ */
+
+#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;
+ 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) {
+ bzero(ctx->buf, ctx->buf_len);
+ free(ctx->buf);
+ }
+ 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/usr.bin/ssh/hmac.h b/usr.bin/ssh/hmac.h
new file mode 100644
index 00000000000..2374a695579
--- /dev/null
+++ b/usr.bin/ssh/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/usr.bin/ssh/hostfile.c b/usr.bin/ssh/hostfile.c
index 8225711a43c..e533a76495d 100644
--- a/usr.bin/ssh/hostfile.c
+++ b/usr.bin/ssh/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
@@ -40,9 +40,6 @@
#include <netinet/in.h>
-#include <openssl/hmac.h>
-#include <openssl/sha.h>
-
#include <resolv.h>
#include <stdio.h>
#include <stdlib.h>
@@ -55,6 +52,7 @@
#include "log.h"
#include "misc.h"
#include "digest.h"
+#include "hmac.h"
struct hostkeys {
struct hostkey_entry *entries;
@@ -99,9 +97,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);
}
@@ -111,14 +109,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 */
@@ -131,14 +128,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/usr.bin/ssh/kex.h b/usr.bin/ssh/kex.h
index 5904448c173..cc5381ffb47 100644
--- a/usr.bin/ssh/kex.h
+++ b/usr.bin/ssh/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.
@@ -102,9 +102,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/usr.bin/ssh/lib/Makefile b/usr.bin/ssh/lib/Makefile
index 362606ebcfb..217fd23663b 100644
--- a/usr.bin/ssh/lib/Makefile
+++ b/usr.bin/ssh/lib/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.71 2014/01/09 23:20:01 djm Exp $
+# $OpenBSD: Makefile,v 1.72 2014/01/27 18:58:14 markus Exp $
.PATH: ${.CURDIR}/..
.include "${.CURDIR}/../Makefile.inc"
@@ -14,7 +14,7 @@ SRCS= authfd.c authfile.c bufaux.c bufec.c bufbn.c buffer.c canohost.c \
kexdhc.c kexgexc.c kexecdhc.c msg.c progressmeter.c dns.c \
monitor_fdpass.c umac.c addrmatch.c schnorr.c jpake.c ssh-pkcs11.c \
krl.c smult_curve25519_ref.c kexc25519.c kexc25519c.c \
- chacha.c poly1305.c cipher-chachapoly.c ssh-ed25519.c digest.c
+ chacha.c poly1305.c cipher-chachapoly.c ssh-ed25519.c digest.c hmac.c
# ed25519, from supercop
SRCS+= sc25519.c ge25519.c fe25519.c ed25519.c verify.c hash.c blocks.c
diff --git a/usr.bin/ssh/mac.c b/usr.bin/ssh/mac.c
index b2bdb193848..8d4fc2d4c7d 100644
--- a/usr.bin/ssh/mac.c
+++ b/usr.bin/ssh/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.
*
@@ -39,16 +39,18 @@
#include "mac.h"
#include "misc.h"
+#include "digest.h"
+#include "hmac.h"
#include "umac.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 */
@@ -57,29 +59,29 @@ 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-sha2-256", SSH_EVP, EVP_sha256, 0, 0, 0, 0 },
- { "hmac-sha2-512", SSH_EVP, EVP_sha512, 0, 0, 0, 0 },
- { "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-sha1", SSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 0 },
+ { "hmac-sha1-96", SSH_DIGEST, SSH_DIGEST_SHA1, 96, 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 },
+ { "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-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-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 },
-
- { NULL, 0, NULL, 0, 0, 0, 0 }
+ { "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 },
+ { "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 },
+ { "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, 0, 0, 0, 0, 0 }
};
/* Returns a list of supported MACs separated by the specified char. */
@@ -104,14 +106,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;
@@ -145,11 +144,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);
@@ -176,13 +174,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);
@@ -209,9 +208,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;
}