From a3de8da1c0917e4a681c2822adf0ad79ff476550 Mon Sep 17 00:00:00 2001 From: dtucker Date: Tue, 5 Jun 2007 08:30:18 +0000 Subject: [PATCH] - djm@cvs.openbsd.org 2007/06/05 06:52:37 [kex.c monitor_wrap.c packet.c mac.h kex.h mac.c] Preserve MAC ctx between packets, saving 2xhash calls per-packet. Yields around a 12-16% end-to-end speedup for arcfour256/hmac-md5 patch from markus@ tested dtucker@ and myself, ok markus@ and me (I'm committing at his request) --- ChangeLog | 6 ++++++ kex.c | 4 ++-- kex.h | 4 +++- mac.c | 36 +++++++++++++++++++++++------------- mac.h | 6 ++++-- monitor_wrap.c | 4 ++-- packet.c | 12 ++++++++---- 7 files changed, 48 insertions(+), 24 deletions(-) diff --git a/ChangeLog b/ChangeLog index 34c48ef9..38b3726f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -18,6 +18,12 @@ - djm@cvs.openbsd.org 2007/06/02 09:04:58 [bufbn.c] memory leak on error path; from arnaud.lacombe.1 AT ulaval.ca + - djm@cvs.openbsd.org 2007/06/05 06:52:37 + [kex.c monitor_wrap.c packet.c mac.h kex.h mac.c] + Preserve MAC ctx between packets, saving 2xhash calls per-packet. + Yields around a 12-16% end-to-end speedup for arcfour256/hmac-md5 + patch from markus@ tested dtucker@ and myself, ok markus@ and me (I'm + committing at his request) 20070520 - (dtucker) OpenBSD CVS Sync diff --git a/kex.c b/kex.c index ad2e93cc..332fadf6 100644 --- a/kex.c +++ b/kex.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kex.c,v 1.78 2007/05/30 05:58:13 djm Exp $ */ +/* $OpenBSD: kex.c,v 1.79 2007/06/05 06:52:37 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * @@ -279,7 +279,7 @@ choose_mac(Mac *mac, char *client, char *server) if (name == NULL) fatal("no matching mac found: client %s server %s", client, server); - if (mac_init(mac, name) < 0) + if (mac_setup(mac, name) < 0) fatal("unsupported mac %s", name); /* truncate the key */ if (datafellows & SSH_BUG_HMAC) diff --git a/kex.h b/kex.h index b1b20f50..ecf43130 100644 --- a/kex.h +++ b/kex.h @@ -1,4 +1,4 @@ -/* $OpenBSD: kex.h,v 1.44 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: kex.h,v 1.45 2007/06/05 06:52:37 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -28,6 +28,7 @@ #include #include +#include #define KEX_DH1 "diffie-hellman-group1-sha1" #define KEX_DH14 "diffie-hellman-group14-sha1" @@ -90,6 +91,7 @@ struct Mac { u_int mac_len; u_char *key; u_int key_len; + HMAC_CTX ctx; }; struct Comp { int type; diff --git a/mac.c b/mac.c index e5d5bfa8..6a5fd476 100644 --- a/mac.c +++ b/mac.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mac.c,v 1.12 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: mac.c,v 1.13 2007/06/05 06:52:37 djm Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * @@ -57,7 +57,7 @@ struct { }; int -mac_init(Mac *mac, char *name) +mac_setup(Mac *mac, char *name) { int i, evp_len; @@ -71,34 +71,44 @@ mac_init(Mac *mac, char *name) if (macs[i].truncatebits != 0) mac->mac_len = macs[i].truncatebits/8; } - debug2("mac_init: found %s", name); + debug2("mac_setup: found %s", name); return (0); } } - debug2("mac_init: unknown %s", name); + debug2("mac_setup: unknown %s", name); return (-1); } +void +mac_init(Mac *mac) +{ + if (mac->key == NULL) + fatal("mac_init: no key"); + HMAC_Init(&mac->ctx, mac->key, mac->key_len, mac->md); +} + u_char * mac_compute(Mac *mac, u_int32_t seqno, u_char *data, int datalen) { - HMAC_CTX c; static u_char m[EVP_MAX_MD_SIZE]; u_char b[4]; - if (mac->key == NULL) - fatal("mac_compute: no key"); if (mac->mac_len > sizeof(m)) fatal("mac_compute: mac too long"); - HMAC_Init(&c, mac->key, mac->key_len, mac->md); put_u32(b, seqno); - HMAC_Update(&c, b, sizeof(b)); - HMAC_Update(&c, data, datalen); - HMAC_Final(&c, m, NULL); - HMAC_cleanup(&c); + HMAC_Init(&mac->ctx, NULL, 0, NULL); /* reset HMAC context */ + HMAC_Update(&mac->ctx, b, sizeof(b)); + HMAC_Update(&mac->ctx, data, datalen); + HMAC_Final(&mac->ctx, m, NULL); return (m); } +void +mac_clear(Mac *mac) +{ + HMAC_cleanup(&mac->ctx); +} + /* XXX copied from ciphers_valid */ #define MAC_SEP "," int @@ -111,7 +121,7 @@ mac_valid(const char *names) maclist = cp = xstrdup(names); for ((p = strsep(&cp, MAC_SEP)); p && *p != '\0'; (p = strsep(&cp, MAC_SEP))) { - if (mac_init(NULL, p) < 0) { + if (mac_setup(NULL, p) < 0) { debug("bad mac %s [%s]", p, names); xfree(maclist); return (0); diff --git a/mac.h b/mac.h index 960cc5c5..2010c9d3 100644 --- a/mac.h +++ b/mac.h @@ -1,4 +1,4 @@ -/* $OpenBSD: mac.h,v 1.4 2006/03/25 22:22:43 djm Exp $ */ +/* $OpenBSD: mac.h,v 1.5 2007/06/05 06:52:37 djm Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * @@ -24,5 +24,7 @@ */ int mac_valid(const char *); -int mac_init(Mac *, char *); +int mac_setup(Mac *, char *); +void mac_init(Mac *); u_char *mac_compute(Mac *, u_int32_t, u_char *, int); +void mac_clear(Mac *); diff --git a/monitor_wrap.c b/monitor_wrap.c index 27cc1c5f..61f7c688 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor_wrap.c,v 1.55 2007/02/19 10:45:58 dtucker Exp $ */ +/* $OpenBSD: monitor_wrap.c,v 1.56 2007/06/05 06:52:37 djm Exp $ */ /* * Copyright 2002 Niels Provos * Copyright 2002 Markus Friedl @@ -476,7 +476,7 @@ mm_newkeys_from_blob(u_char *blob, int blen) /* Mac structure */ mac->name = buffer_get_string(&b, NULL); - if (mac->name == NULL || mac_init(mac, mac->name) == -1) + if (mac->name == NULL || mac_setup(mac, mac->name) == -1) fatal("%s: can not init mac %s", __func__, mac->name); mac->enabled = buffer_get_int(&b); mac->key = buffer_get_string(&b, &len); diff --git a/packet.c b/packet.c index a2e9f598..27489801 100644 --- a/packet.c +++ b/packet.c @@ -1,4 +1,4 @@ -/* $OpenBSD: packet.c,v 1.146 2007/05/31 23:34:29 djm Exp $ */ +/* $OpenBSD: packet.c,v 1.147 2007/06/05 06:52:37 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -629,7 +629,8 @@ set_newkeys(int mode) enc = &newkeys[mode]->enc; mac = &newkeys[mode]->mac; comp = &newkeys[mode]->comp; - memset(mac->key, 0, mac->key_len); + if (mac->md != NULL) + mac_clear(mac); xfree(enc->name); xfree(enc->iv); xfree(enc->key); @@ -644,14 +645,17 @@ set_newkeys(int mode) enc = &newkeys[mode]->enc; mac = &newkeys[mode]->mac; comp = &newkeys[mode]->comp; - if (mac->md != NULL) + if (mac->md != NULL) { + mac_init(mac); mac->enabled = 1; + } DBG(debug("cipher_init_context: %d", mode)); cipher_init(cc, enc->cipher, enc->key, enc->key_len, enc->iv, enc->block_size, crypt_type); /* Deleting the keys does not gain extra security */ /* memset(enc->iv, 0, enc->block_size); - memset(enc->key, 0, enc->key_len); */ + memset(enc->key, 0, enc->key_len); + memset(mac->key, 0, mac->key_len); */ if ((comp->type == COMP_ZLIB || (comp->type == COMP_DELAYED && after_authentication)) && comp->enabled == 0) { -- 2.45.1