[mac.c myproposal.h umac.c]
     UMAC can use our local fallback implementation of AES when OpenSSL isn't
     available.  Glue code straight from Ted Krovetz's original umac.c.
     ok markus@
This commit is contained in:
Damien Miller 2014-05-15 14:35:03 +10:00
parent 05e82c3b96
commit 294c58a007
4 changed files with 23 additions and 17 deletions

View File

@ -66,6 +66,11 @@
Thanks also to Ben Hawkes, David Tomaschik, Ivan Fratric, Matthew Thanks also to Ben Hawkes, David Tomaschik, Ivan Fratric, Matthew
Dempsky and Ron Bowes for a detailed review. Dempsky and Ron Bowes for a detailed review.
- naddy@cvs.openbsd.org 2014/04/30 19:07:48
[mac.c myproposal.h umac.c]
UMAC can use our local fallback implementation of AES when OpenSSL isn't
available. Glue code straight from Ted Krovetz's original umac.c.
ok markus@
20140430 20140430
- (dtucker) [defines.h] Define __GNUC_PREREQ__ macro if we don't already - (dtucker) [defines.h] Define __GNUC_PREREQ__ macro if we don't already

16
mac.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: mac.c,v 1.29 2014/04/29 18:01:49 markus Exp $ */ /* $OpenBSD: mac.c,v 1.30 2014/04/30 19:07:48 naddy Exp $ */
/* /*
* Copyright (c) 2001 Markus Friedl. All rights reserved. * Copyright (c) 2001 Markus Friedl. All rights reserved.
* *
@ -72,10 +72,8 @@ static const struct macalg macs[] = {
{ "hmac-md5-96", SSH_DIGEST, SSH_DIGEST_MD5, 96, 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", SSH_DIGEST, SSH_DIGEST_RIPEMD160, 0, 0, 0, 0 },
{ "hmac-ripemd160@openssh.com", SSH_DIGEST, SSH_DIGEST_RIPEMD160, 0, 0, 0, 0 }, { "hmac-ripemd160@openssh.com", SSH_DIGEST, SSH_DIGEST_RIPEMD160, 0, 0, 0, 0 },
#ifdef WITH_OPENSSL
{ "umac-64@openssh.com", SSH_UMAC, 0, 0, 128, 64, 0 }, { "umac-64@openssh.com", SSH_UMAC, 0, 0, 128, 64, 0 },
{ "umac-128@openssh.com", SSH_UMAC128, 0, 0, 128, 128, 0 }, { "umac-128@openssh.com", SSH_UMAC128, 0, 0, 128, 128, 0 },
#endif
/* Encrypt-then-MAC variants */ /* Encrypt-then-MAC variants */
{ "hmac-sha1-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 1 }, { "hmac-sha1-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 1 },
@ -87,10 +85,8 @@ static const struct macalg macs[] = {
{ "hmac-md5-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_MD5, 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-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 }, { "hmac-ripemd160-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_RIPEMD160, 0, 0, 0, 1 },
#ifdef WITH_OPENSSL
{ "umac-64-etm@openssh.com", SSH_UMAC, 0, 0, 128, 64, 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 }, { "umac-128-etm@openssh.com", SSH_UMAC128, 0, 0, 128, 128, 1 },
#endif
{ NULL, 0, 0, 0, 0, 0, 0 } { NULL, 0, 0, 0, 0, 0, 0 }
}; };
@ -123,11 +119,9 @@ mac_setup_by_alg(Mac *mac, const struct macalg *macalg)
fatal("ssh_hmac_start(alg=%d) failed", macalg->alg); fatal("ssh_hmac_start(alg=%d) failed", macalg->alg);
mac->key_len = mac->mac_len = ssh_hmac_bytes(macalg->alg); mac->key_len = mac->mac_len = ssh_hmac_bytes(macalg->alg);
} else { } else {
#ifdef WITH_OPENSSL
mac->mac_len = macalg->len / 8; mac->mac_len = macalg->len / 8;
mac->key_len = macalg->key_len / 8; mac->key_len = macalg->key_len / 8;
mac->umac_ctx = NULL; mac->umac_ctx = NULL;
#endif
} }
if (macalg->truncatebits != 0) if (macalg->truncatebits != 0)
mac->mac_len = macalg->truncatebits / 8; mac->mac_len = macalg->truncatebits / 8;
@ -163,14 +157,12 @@ mac_init(Mac *mac)
ssh_hmac_init(mac->hmac_ctx, mac->key, mac->key_len) < 0) ssh_hmac_init(mac->hmac_ctx, mac->key, mac->key_len) < 0)
return -1; return -1;
return 0; return 0;
#ifdef WITH_OPENSSL
case SSH_UMAC: case SSH_UMAC:
mac->umac_ctx = umac_new(mac->key); mac->umac_ctx = umac_new(mac->key);
return 0; return 0;
case SSH_UMAC128: case SSH_UMAC128:
mac->umac_ctx = umac128_new(mac->key); mac->umac_ctx = umac128_new(mac->key);
return 0; return 0;
#endif
default: default:
return -1; return -1;
} }
@ -184,9 +176,7 @@ mac_compute(Mac *mac, u_int32_t seqno, u_char *data, int datalen)
u_int64_t for_align; u_int64_t for_align;
} u; } u;
u_char b[4]; u_char b[4];
#ifdef WITH_OPENSSL
u_char nonce[8]; u_char nonce[8];
#endif
if (mac->mac_len > sizeof(u)) if (mac->mac_len > sizeof(u))
fatal("mac_compute: mac too long %u %zu", fatal("mac_compute: mac too long %u %zu",
@ -202,7 +192,6 @@ mac_compute(Mac *mac, u_int32_t seqno, u_char *data, int datalen)
ssh_hmac_final(mac->hmac_ctx, u.m, sizeof(u.m)) < 0) ssh_hmac_final(mac->hmac_ctx, u.m, sizeof(u.m)) < 0)
fatal("ssh_hmac failed"); fatal("ssh_hmac failed");
break; break;
#ifdef WITH_OPENSSL
case SSH_UMAC: case SSH_UMAC:
put_u64(nonce, seqno); put_u64(nonce, seqno);
umac_update(mac->umac_ctx, data, datalen); umac_update(mac->umac_ctx, data, datalen);
@ -213,7 +202,6 @@ mac_compute(Mac *mac, u_int32_t seqno, u_char *data, int datalen)
umac128_update(mac->umac_ctx, data, datalen); umac128_update(mac->umac_ctx, data, datalen);
umac128_final(mac->umac_ctx, u.m, nonce); umac128_final(mac->umac_ctx, u.m, nonce);
break; break;
#endif
default: default:
fatal("mac_compute: unknown MAC type"); fatal("mac_compute: unknown MAC type");
} }
@ -223,7 +211,6 @@ mac_compute(Mac *mac, u_int32_t seqno, u_char *data, int datalen)
void void
mac_clear(Mac *mac) mac_clear(Mac *mac)
{ {
#ifdef WITH_OPENSSL
if (mac->type == SSH_UMAC) { if (mac->type == SSH_UMAC) {
if (mac->umac_ctx != NULL) if (mac->umac_ctx != NULL)
umac_delete(mac->umac_ctx); umac_delete(mac->umac_ctx);
@ -231,7 +218,6 @@ mac_clear(Mac *mac)
if (mac->umac_ctx != NULL) if (mac->umac_ctx != NULL)
umac128_delete(mac->umac_ctx); umac128_delete(mac->umac_ctx);
} else if (mac->hmac_ctx != NULL) } else if (mac->hmac_ctx != NULL)
#endif
ssh_hmac_free(mac->hmac_ctx); ssh_hmac_free(mac->hmac_ctx);
mac->hmac_ctx = NULL; mac->hmac_ctx = NULL;
mac->umac_ctx = NULL; mac->umac_ctx = NULL;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: myproposal.h,v 1.39 2014/04/29 18:01:49 markus Exp $ */ /* $OpenBSD: myproposal.h,v 1.40 2014/04/30 19:07:48 naddy Exp $ */
/* /*
* Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2000 Markus Friedl. All rights reserved.
@ -146,8 +146,12 @@
"aes128-ctr,aes192-ctr,aes256-ctr," \ "aes128-ctr,aes192-ctr,aes256-ctr," \
"chacha20-poly1305@openssh.com" "chacha20-poly1305@openssh.com"
#define KEX_SERVER_MAC \ #define KEX_SERVER_MAC \
"umac-64-etm@openssh.com," \
"umac-128-etm@openssh.com," \
"hmac-sha2-256-etm@openssh.com," \ "hmac-sha2-256-etm@openssh.com," \
"hmac-sha2-512-etm@openssh.com," \ "hmac-sha2-512-etm@openssh.com," \
"umac-64@openssh.com," \
"umac-128@openssh.com," \
"hmac-sha2-256," \ "hmac-sha2-256," \
"hmac-sha2-512" "hmac-sha2-512"

13
umac.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: umac.c,v 1.9 2014/04/20 02:30:25 djm Exp $ */ /* $OpenBSD: umac.c,v 1.10 2014/04/30 19:07:48 naddy Exp $ */
/* ----------------------------------------------------------------------- /* -----------------------------------------------------------------------
* *
* umac.c -- C Implementation UMAC Message Authentication * umac.c -- C Implementation UMAC Message Authentication
@ -154,6 +154,7 @@ typedef unsigned int UWORD; /* Register */
#define AES_BLOCK_LEN 16 #define AES_BLOCK_LEN 16
/* OpenSSL's AES */ /* OpenSSL's AES */
#ifdef WITH_OPENSSL
#include "openbsd-compat/openssl-compat.h" #include "openbsd-compat/openssl-compat.h"
#ifndef USE_BUILTIN_RIJNDAEL #ifndef USE_BUILTIN_RIJNDAEL
# include <openssl/aes.h> # include <openssl/aes.h>
@ -163,6 +164,16 @@ typedef AES_KEY aes_int_key[1];
AES_encrypt((u_char *)(in),(u_char *)(out),(AES_KEY *)int_key) AES_encrypt((u_char *)(in),(u_char *)(out),(AES_KEY *)int_key)
#define aes_key_setup(key,int_key) \ #define aes_key_setup(key,int_key) \
AES_set_encrypt_key((const u_char *)(key),UMAC_KEY_LEN*8,int_key) AES_set_encrypt_key((const u_char *)(key),UMAC_KEY_LEN*8,int_key)
#else
#include "rijndael.h"
#define AES_ROUNDS ((UMAC_KEY_LEN / 4) + 6)
typedef UINT8 aes_int_key[AES_ROUNDS+1][4][4]; /* AES internal */
#define aes_encryption(in,out,int_key) \
rijndaelEncrypt((u32 *)(int_key), AES_ROUNDS, (u8 *)(in), (u8 *)(out))
#define aes_key_setup(key,int_key) \
rijndaelKeySetupEnc((u32 *)(int_key), (const unsigned char *)(key), \
UMAC_KEY_LEN*8)
#endif
/* The user-supplied UMAC key is stretched using AES in a counter /* The user-supplied UMAC key is stretched using AES in a counter
* mode to supply all random bits needed by UMAC. The kdf function takes * mode to supply all random bits needed by UMAC. The kdf function takes