[kex.h mac.c mac.h monitor_wrap.c myproposal.h packet.c ssh.1]
     [ssh_config.5 sshd.8 sshd_config.5]
     Add a new MAC algorithm for data integrity, UMAC-64 (not default yet,
     must specify umac-64@openssh.com). Provides about 20% end-to-end speedup
     compared to hmac-md5. Represents a different approach to message
     authentication to that of HMAC that may be beneficial if HMAC based on
     one of its underlying hash algorithms is found to be vulnerable to a
     new attack.  http://www.ietf.org/rfc/rfc4418.txt
     in conjunction with and OK djm@
This commit is contained in:
Damien Miller 2007-06-11 14:01:42 +10:00
parent 835284b74c
commit e45796f7b4
14 changed files with 1512 additions and 58 deletions

View File

@ -1,7 +1,16 @@
20070611
- (djm) Bugzilla #1306: silence spurious error messages from hang-on-exit
fix; tested by dtucker@ and jochen.kirn AT gmail.com
- pvalchev@cvs.openbsd.org 2007/06/07 19:37:34
[kex.h mac.c mac.h monitor_wrap.c myproposal.h packet.c ssh.1]
[ssh_config.5 sshd.8 sshd_config.5]
Add a new MAC algorithm for data integrity, UMAC-64 (not default yet,
must specify umac-64@openssh.com). Provides about 20% end-to-end speedup
compared to hmac-md5. Represents a different approach to message
authentication to that of HMAC that may be beneficial if HMAC based on
one of its underlying hash algorithms is found to be vulnerable to a
new attack. http://www.ietf.org/rfc/rfc4418.txt
in conjunction with and OK djm@
20070605
- (dtucker) OpenBSD CVS Sync
- djm@cvs.openbsd.org 2007/05/22 10:18:52
@ -2976,4 +2985,4 @@
OpenServer 6 and add osr5bigcrypt support so when someone migrates
passwords between UnixWare and OpenServer they will still work. OK dtucker@
$Id: ChangeLog,v 1.4680 2007/06/11 03:03:16 djm Exp $
$Id: ChangeLog,v 1.4681 2007/06/11 04:01:42 djm Exp $

View File

@ -1,4 +1,4 @@
# $Id: Makefile.in,v 1.284 2007/03/25 08:26:01 dtucker Exp $
# $Id: Makefile.in,v 1.285 2007/06/11 04:01:42 djm Exp $
# uncomment if you run a non bourne compatable shell. Ie. csh
#SHELL = @SH@
@ -71,7 +71,7 @@ LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \
atomicio.o key.o dispatch.o kex.o mac.o uidswap.o uuencode.o misc.o \
monitor_fdpass.o rijndael.o ssh-dss.o ssh-rsa.o dh.o kexdh.o \
kexgex.o kexdhc.o kexgexc.o scard.o msg.o progressmeter.o dns.o \
entropy.o scard-opensc.o gss-genr.o
entropy.o scard-opensc.o gss-genr.o umac.o
SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
sshconnect.o sshconnect1.o sshconnect2.o

8
kex.h
View File

@ -1,4 +1,4 @@
/* $OpenBSD: kex.h,v 1.45 2007/06/05 06:52:37 djm Exp $ */
/* $OpenBSD: kex.h,v 1.46 2007/06/07 19:37:34 pvalchev Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@ -87,11 +87,13 @@ struct Enc {
struct Mac {
char *name;
int enabled;
const EVP_MD *md;
u_int mac_len;
u_char *key;
u_int key_len;
HMAC_CTX ctx;
int type;
const EVP_MD *evp_md;
HMAC_CTX evp_ctx;
struct umac_ctx *umac_ctx;
};
struct Comp {
int type;

107
mac.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: mac.c,v 1.13 2007/06/05 06:52:37 djm Exp $ */
/* $OpenBSD: mac.c,v 1.14 2007/06/07 19:37:34 pvalchev Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
*
@ -42,35 +42,57 @@
#include "mac.h"
#include "misc.h"
#include "umac.h"
#define SSH_EVP 1 /* OpenSSL EVP-based MAC */
#define SSH_UMAC 2 /* UMAC (not integrated with OpenSSL) */
struct {
char *name;
int type;
const EVP_MD * (*mdfunc)(void);
int truncatebits; /* truncate digest if != 0 */
int key_len; /* just for UMAC */
int len; /* just for UMAC */
} macs[] = {
{ "hmac-sha1", EVP_sha1, 0, },
{ "hmac-sha1-96", EVP_sha1, 96 },
{ "hmac-md5", EVP_md5, 0 },
{ "hmac-md5-96", EVP_md5, 96 },
{ "hmac-ripemd160", EVP_ripemd160, 0 },
{ "hmac-ripemd160@openssh.com", EVP_ripemd160, 0 },
{ NULL, NULL, 0 }
{ "hmac-sha1", SSH_EVP, EVP_sha1, 0, -1, -1 },
{ "hmac-sha1-96", SSH_EVP, EVP_sha1, 96, -1, -1 },
{ "hmac-md5", SSH_EVP, EVP_md5, 0, -1, -1 },
{ "hmac-md5-96", SSH_EVP, EVP_md5, 96, -1, -1 },
{ "hmac-ripemd160", SSH_EVP, EVP_ripemd160, 0, -1, -1 },
{ "hmac-ripemd160@openssh.com", SSH_EVP, EVP_ripemd160, 0, -1, -1 },
{ "umac-64@openssh.com", SSH_UMAC, NULL, 0, 128, 64 },
{ NULL, 0, NULL, 0, -1, -1 }
};
static void
mac_setup_by_id(Mac *mac, int which)
{
int evp_len;
mac->type = macs[which].type;
if (mac->type == SSH_EVP) {
mac->evp_md = (*macs[which].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;
} else {
mac->mac_len = macs[which].len / 8;
mac->key_len = macs[which].key_len / 8;
mac->umac_ctx = NULL;
}
if (macs[which].truncatebits != 0)
mac->mac_len = macs[which].truncatebits / 8;
}
int
mac_setup(Mac *mac, char *name)
{
int i, evp_len;
int i;
for (i = 0; macs[i].name; i++) {
if (strcmp(name, macs[i].name) == 0) {
if (mac != NULL) {
mac->md = (*macs[i].mdfunc)();
if ((evp_len = EVP_MD_size(mac->md)) <= 0)
fatal("mac %s len %d", name, evp_len);
mac->key_len = mac->mac_len = (u_int)evp_len;
if (macs[i].truncatebits != 0)
mac->mac_len = macs[i].truncatebits/8;
}
if (mac != NULL)
mac_setup_by_id(mac, i);
debug2("mac_setup: found %s", name);
return (0);
}
@ -79,34 +101,65 @@ mac_setup(Mac *mac, char *name)
return (-1);
}
void
int
mac_init(Mac *mac)
{
if (mac->key == NULL)
fatal("mac_init: no key");
HMAC_Init(&mac->ctx, mac->key, mac->key_len, mac->md);
switch (mac->type) {
case SSH_EVP:
if (mac->evp_md == NULL)
return -1;
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);
return 0;
default:
return -1;
}
}
u_char *
mac_compute(Mac *mac, u_int32_t seqno, u_char *data, int datalen)
{
static u_char m[EVP_MAX_MD_SIZE];
u_char b[4];
u_char b[4], nonce[8];
if (mac->mac_len > sizeof(m))
fatal("mac_compute: mac too long");
put_u32(b, seqno);
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);
fatal("mac_compute: mac too long %u %lu",
mac->mac_len, sizeof(m));
switch (mac->type) {
case SSH_EVP:
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, m, NULL);
break;
case SSH_UMAC:
put_u64(nonce, seqno);
umac_update(mac->umac_ctx, data, datalen);
umac_final(mac->umac_ctx, m, nonce);
break;
default:
fatal("mac_compute: unknown MAC type");
}
return (m);
}
void
mac_clear(Mac *mac)
{
HMAC_cleanup(&mac->ctx);
if (mac->type == SSH_UMAC) {
if (mac->umac_ctx != NULL)
umac_delete(mac->umac_ctx);
} else if (mac->evp_md != NULL)
HMAC_cleanup(&mac->evp_ctx);
mac->evp_md = NULL;
mac->umac_ctx = NULL;
}
/* XXX copied from ciphers_valid */

4
mac.h
View File

@ -1,4 +1,4 @@
/* $OpenBSD: mac.h,v 1.5 2007/06/05 06:52:37 djm Exp $ */
/* $OpenBSD: mac.h,v 1.6 2007/06/07 19:37:34 pvalchev Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
*
@ -25,6 +25,6 @@
int mac_valid(const char *);
int mac_setup(Mac *, char *);
void mac_init(Mac *);
int mac_init(Mac *);
u_char *mac_compute(Mac *, u_int32_t, u_char *, int);
void mac_clear(Mac *);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: monitor_wrap.c,v 1.56 2007/06/05 06:52:37 djm Exp $ */
/* $OpenBSD: monitor_wrap.c,v 1.57 2007/06/07 19:37:34 pvalchev Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* Copyright 2002 Markus Friedl <markus@openbsd.org>
@ -477,7 +477,7 @@ mm_newkeys_from_blob(u_char *blob, int blen)
/* Mac structure */
mac->name = buffer_get_string(&b, NULL);
if (mac->name == NULL || mac_setup(mac, mac->name) == -1)
fatal("%s: can not init mac %s", __func__, mac->name);
fatal("%s: can not setup mac %s", __func__, mac->name);
mac->enabled = buffer_get_int(&b);
mac->key = buffer_get_string(&b, &len);
if (len > mac->key_len)

View File

@ -1,4 +1,4 @@
/* $OpenBSD: myproposal.h,v 1.21 2006/03/25 22:22:43 djm Exp $ */
/* $OpenBSD: myproposal.h,v 1.22 2007/06/07 19:37:34 pvalchev Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
@ -47,7 +47,7 @@
"aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se," \
"aes128-ctr,aes192-ctr,aes256-ctr"
#define KEX_DEFAULT_MAC \
"hmac-md5,hmac-sha1,hmac-ripemd160," \
"hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160," \
"hmac-ripemd160@openssh.com," \
"hmac-sha1-96,hmac-md5-96"
#define KEX_DEFAULT_COMP "none,zlib@openssh.com,zlib"

View File

@ -1,4 +1,4 @@
/* $OpenBSD: packet.c,v 1.147 2007/06/05 06:52:37 djm Exp $ */
/* $OpenBSD: packet.c,v 1.148 2007/06/07 19:37:34 pvalchev Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -629,8 +629,7 @@ set_newkeys(int mode)
enc = &newkeys[mode]->enc;
mac = &newkeys[mode]->mac;
comp = &newkeys[mode]->comp;
if (mac->md != NULL)
mac_clear(mac);
mac_clear(mac);
xfree(enc->name);
xfree(enc->iv);
xfree(enc->key);
@ -645,10 +644,8 @@ set_newkeys(int mode)
enc = &newkeys[mode]->enc;
mac = &newkeys[mode]->mac;
comp = &newkeys[mode]->comp;
if (mac->md != NULL) {
mac_init(mac);
if (mac_init(mac) == 0)
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);

6
ssh.1
View File

@ -34,8 +34,8 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $OpenBSD: ssh.1,v 1.267 2007/05/31 19:20:16 jmc Exp $
.Dd $Mdocdate: May 31 2007 $
.\" $OpenBSD: ssh.1,v 1.268 2007/06/07 19:37:34 pvalchev Exp $
.Dd $Mdocdate: June 7 2007 $
.Dt SSH 1
.Os
.Sh NAME
@ -674,7 +674,7 @@ Both protocols support similar authentication methods,
but protocol 2 is preferred since
it provides additional mechanisms for confidentiality
(the traffic is encrypted using AES, 3DES, Blowfish, CAST128, or Arcfour)
and integrity (hmac-md5, hmac-sha1, hmac-ripemd160).
and integrity (hmac-md5, hmac-sha1, umac-64, hmac-ripemd160).
Protocol 1 lacks a strong mechanism for ensuring the
integrity of the connection.
.Pp

View File

@ -34,8 +34,8 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $OpenBSD: ssh_config.5,v 1.99 2007/05/31 19:20:16 jmc Exp $
.Dd $Mdocdate: May 31 2007 $
.\" $OpenBSD: ssh_config.5,v 1.100 2007/06/07 19:37:34 pvalchev Exp $
.Dd $Mdocdate: June 7 2007 $
.Dt SSH_CONFIG 5
.Os
.Sh NAME
@ -641,7 +641,7 @@ The MAC algorithm is used in protocol version 2
for data integrity protection.
Multiple algorithms must be comma-separated.
The default is:
.Dq hmac-md5,hmac-sha1,hmac-ripemd160,hmac-sha1-96,hmac-md5-96 .
.Dq hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160,hmac-sha1-96,hmac-md5-96 .
.It Cm NoHostAuthenticationForLocalhost
This option can be used if the home directory is shared across machines.
In this case localhost will refer to a different machine on each of

6
sshd.8
View File

@ -34,8 +34,8 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $OpenBSD: sshd.8,v 1.236 2007/05/31 19:20:16 jmc Exp $
.Dd $Mdocdate: May 31 2007 $
.\" $OpenBSD: sshd.8,v 1.237 2007/06/07 19:37:34 pvalchev Exp $
.Dd $Mdocdate: June 7 2007 $
.Dt SSHD 8
.Os
.Sh NAME
@ -276,7 +276,7 @@ The client selects the encryption algorithm
to use from those offered by the server.
Additionally, session integrity is provided
through a cryptographic message authentication code
(hmac-sha1 or hmac-md5).
(hmac-md5, hmac-sha1, umac-64 or hmac-ripemd160).
.Pp
Finally, the server and the client enter an authentication dialog.
The client tries to authenticate itself using

View File

@ -34,8 +34,8 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $OpenBSD: sshd_config.5,v 1.75 2007/05/31 19:20:17 jmc Exp $
.Dd $Mdocdate: May 31 2007 $
.\" $OpenBSD: sshd_config.5,v 1.76 2007/06/07 19:37:34 pvalchev Exp $
.Dd $Mdocdate: June 7 2007 $
.Dt SSHD_CONFIG 5
.Os
.Sh NAME
@ -489,7 +489,7 @@ The MAC algorithm is used in protocol version 2
for data integrity protection.
Multiple algorithms must be comma-separated.
The default is:
.Dq hmac-md5,hmac-sha1,hmac-ripemd160,hmac-sha1-96,hmac-md5-96 .
.Dq hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160,hmac-sha1-96,hmac-md5-96 .
.It Cm Match
Introduces a conditional block.
If all of the criteria on the

1270
umac.c Normal file

File diff suppressed because it is too large Load Diff

123
umac.h Normal file
View File

@ -0,0 +1,123 @@
/* $OpenBSD: umac.h,v 1.1 2007/06/07 19:37:34 pvalchev Exp $ */
/* -----------------------------------------------------------------------
*
* umac.h -- C Implementation UMAC Message Authentication
*
* Version 0.93a of rfc4418.txt -- 2006 July 14
*
* For a full description of UMAC message authentication see the UMAC
* world-wide-web page at http://www.cs.ucdavis.edu/~rogaway/umac
* Please report bugs and suggestions to the UMAC webpage.
*
* Copyright (c) 1999-2004 Ted Krovetz
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and with or without fee, is hereby
* granted provided that the above copyright notice appears in all copies
* and in supporting documentation, and that the name of the copyright
* holder not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
*
* Comments should be directed to Ted Krovetz (tdk@acm.org)
*
* ---------------------------------------------------------------------- */
/* ////////////////////// IMPORTANT NOTES /////////////////////////////////
*
* 1) This version does not work properly on messages larger than 16MB
*
* 2) If you set the switch to use SSE2, then all data must be 16-byte
* aligned
*
* 3) When calling the function umac(), it is assumed that msg is in
* a writable buffer of length divisible by 32 bytes. The message itself
* does not have to fill the entire buffer, but bytes beyond msg may be
* zeroed.
*
* 4) Two free AES implementations are supported by this implementation of
* UMAC. Paulo Barreto's version is in the public domain and can be found
* at http://www.esat.kuleuven.ac.be/~rijmen/rijndael/ (search for
* "Barreto"). The only two files needed are rijndael-alg-fst.c and
* rijndael-alg-fst.h.
* Brian Gladman's version is distributed with GNU Public lisence
* and can be found at http://fp.gladman.plus.com/AES/index.htm. It
* includes a fast IA-32 assembly version.
*
/////////////////////////////////////////////////////////////////////// */
#ifndef HEADER_UMAC_H
#define HEADER_UMAC_H
#ifdef __cplusplus
extern "C" {
#endif
struct umac_ctx *umac_new(u_char key[]);
/* Dynamically allocate a umac_ctx struct, initialize variables,
* generate subkeys from key.
*/
#if 0
int umac_reset(struct umac_ctx *ctx);
/* Reset a umac_ctx to begin authenicating a new message */
#endif
int umac_update(struct umac_ctx *ctx, u_char *input, long len);
/* Incorporate len bytes pointed to by input into context ctx */
int umac_final(struct umac_ctx *ctx, u_char tag[], u_char nonce[8]);
/* Incorporate any pending data and the ctr value, and return tag.
* This function returns error code if ctr < 0.
*/
int umac_delete(struct umac_ctx *ctx);
/* Deallocate the context structure */
#if 0
int umac(struct umac_ctx *ctx, u_char *input,
long len, u_char tag[],
u_char nonce[8]);
/* All-in-one implementation of the functions Reset, Update and Final */
#endif
/* uhash.h */
#if 0
typedef struct uhash_ctx *uhash_ctx_t;
/* The uhash_ctx structure is defined by the implementation of the */
/* UHASH functions. */
uhash_ctx_t uhash_alloc(u_char key[16]);
/* Dynamically allocate a uhash_ctx struct and generate subkeys using */
/* the kdf and kdf_key passed in. If kdf_key_len is 0 then RC6 is */
/* used to generate key with a fixed key. If kdf_key_len > 0 but kdf */
/* is NULL then the first 16 bytes pointed at by kdf_key is used as a */
/* key for an RC6 based KDF. */
int uhash_free(uhash_ctx_t ctx);
int uhash_set_params(uhash_ctx_t ctx,
void *params);
int uhash_reset(uhash_ctx_t ctx);
int uhash_update(uhash_ctx_t ctx,
u_char *input,
long len);
int uhash_final(uhash_ctx_t ctx,
u_char ouput[]);
int uhash(uhash_ctx_t ctx,
u_char *input,
long len,
u_char output[]);
#endif
#ifdef __cplusplus
}
#endif
#endif /* HEADER_UMAC_H */