-/* $OpenBSD: mac.c,v 1.14 2007/06/07 19:37:34 pvalchev Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
*
*/
#include "includes.h"
-
-#include <sys/types.h>
+RCSID("$OpenBSD: mac.c,v 1.2 2001/04/05 10:42:51 markus Exp $");
#include <openssl/hmac.h>
-#include <stdarg.h>
-#include <string.h>
-#include <signal.h>
-
#include "xmalloc.h"
+#include "getput.h"
#include "log.h"
#include "cipher.h"
-#include "buffer.h"
-#include "key.h"
#include "kex.h"
#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);
+ EVP_MD * (*mdfunc)(void);
int truncatebits; /* truncate digest if != 0 */
- int key_len; /* just for UMAC */
- int len; /* just for UMAC */
} macs[] = {
- { "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 }
+ { "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 }
};
-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)
+mac_init(Mac *mac, char *name)
{
int i;
-
for (i = 0; macs[i].name; i++) {
if (strcmp(name, macs[i].name) == 0) {
- if (mac != NULL)
- mac_setup_by_id(mac, i);
- debug2("mac_setup: found %s", name);
+ if (mac != NULL) {
+ mac->md = (*macs[i].mdfunc)();
+ mac->key_len = mac->mac_len = mac->md->md_size;
+ if (macs[i].truncatebits != 0)
+ mac->mac_len = macs[i].truncatebits/8;
+ }
+ debug2("mac_init: found %s", name);
return (0);
}
}
- debug2("mac_setup: unknown %s", name);
+ debug2("mac_init: unknown %s", name);
return (-1);
}
-int
-mac_init(Mac *mac)
-{
- if (mac->key == NULL)
- fatal("mac_init: no key");
- 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)
{
+ HMAC_CTX c;
static u_char m[EVP_MAX_MD_SIZE];
- u_char b[4], nonce[8];
+ 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 %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");
- }
+ fatal("mac_compute: mac too long");
+ HMAC_Init(&c, mac->key, mac->key_len, mac->md);
+ PUT_32BIT(b, seqno);
+ HMAC_Update(&c, b, sizeof(b));
+ HMAC_Update(&c, data, datalen);
+ HMAC_Final(&c, m, NULL);
+ HMAC_cleanup(&c);
return (m);
}
-void
-mac_clear(Mac *mac)
-{
- 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 */
#define MAC_SEP ","
int
return (0);
maclist = cp = xstrdup(names);
for ((p = strsep(&cp, MAC_SEP)); p && *p != '\0';
- (p = strsep(&cp, MAC_SEP))) {
- if (mac_setup(NULL, p) < 0) {
+ (p = strsep(&cp, MAC_SEP))) {
+ if (mac_init(NULL, p) < 0) {
debug("bad mac %s [%s]", p, names);
xfree(maclist);
return (0);