X-Git-Url: https://git.distorted.org.uk/u/mdw/catacomb/blobdiff_plain/d03ab969116fe715d569304c1c474749b2f64529..b2776fdf2a98ea586bbdad50eca4ed95e967b0d7:/hmac.h diff --git a/hmac.h b/hmac.h index 8849258..fffb093 100644 --- a/hmac.h +++ b/hmac.h @@ -1,13 +1,13 @@ /* -*-c-*- * - * $Id: hmac.h,v 1.1 1999/09/03 08:41:12 mdw Exp $ + * $Id: hmac.h,v 1.7 2004/04/08 01:36:15 mdw Exp $ * * Generic code for HMAC and NMAC * * (c) 1998 Straylight/Edgeware */ -/*----- Licensing notice --------------------------------------------------* +/*----- Licensing notice --------------------------------------------------* * * This file is part of Catacomb. * @@ -15,38 +15,32 @@ * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. - * + * * Catacomb is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. - * + * * You should have received a copy of the GNU Library General Public * License along with Catacomb; if not, write to the Free * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, * MA 02111-1307, USA. */ -/*----- Revision history --------------------------------------------------* - * - * $Log: hmac.h,v $ - * Revision 1.1 1999/09/03 08:41:12 mdw - * Initial import. - * - */ - /*----- Notes on the HMAC and NMAC constructions --------------------------* * - * Designed by Mihir Bellare, Ran Canetti and Hugo Krawczyk, NMAC is a - * method for constructing keyed message authentication algorithms from - * unkeyed hash functions. HMAC is an alternative formulation which doesn't - * require low-level access to the hash function's implementation. NMAC was - * designed to allow MD5 has a suitable underlying hash function, even though - * doubts were already being raised about its collision resistance. + * Designed by Mihir Bellare, Ran Canetti and Hugo Krawczyk, NMAC is a method + * for constructing keyed message authentication algorithms from unkeyed hash + * functions. It has been proven to provide useful security given reasonable + * assumptions about the underlying hash function. HMAC is an alternative + * formulation which doesn't require low-level access to the hash function's + * implementation. NMAC was designed to allow MD5 has a suitable underlying + * hash function, even though doubts were already being raised about its + * collision resistance. */ -#ifndef HMAC_H -#define HMAC_H +#ifndef CATACOMB_HMAC_H +#define CATACOMB_HMAC_H #ifdef __cplusplus extern "C" { @@ -54,13 +48,12 @@ /*----- Header files ------------------------------------------------------*/ -#include -#include +#include #include -#ifndef PARANOIA_H -# include "paranoia.h" +#ifndef CATACOMB_GMAC_H +# include "gmac.h" #endif /*----- Macros ------------------------------------------------------------*/ @@ -74,43 +67,30 @@ #define HMAC_DECL(PRE, pre) \ \ +/* --- An HMAC or NMAC key --- */ \ + \ typedef struct pre##_mackey { \ - octet ochain[PRE##_HASHSZ]; /* Chaining for outer hash */ \ - unsigned long ocount; /* Byte count for outer hash */ \ - octet ichain[PRE##_HASHSZ]; /* Chaining for inner hash */ \ - unsigned long icount; /* Byte count for inner hash */ \ + octet ochain[PRE##_STATESZ]; /* Chaining for outer hash */ \ + unsigned ocount; /* Byte count for outer hash */ \ + octet ichain[PRE##_STATESZ]; /* Chaining for inner hash */ \ + unsigned icount; /* Byte count for inner hash */ \ } pre##_mackey; \ \ +/* --- An HMAC or NMAC hashing context --- */ \ + \ typedef struct pre##_macctx { \ pre##_ctx ctx; /* Context for main hashing */ \ - octet chain[PRE##_HASHSZ]; /* Chaining for outer hash */ \ - unsigned long count; /* Byte count for outer hash */ \ + octet chain[PRE##_STATESZ]; /* Chaining for outer hash */ \ + unsigned count; /* Byte count for outer hash */ \ } pre##_macctx; \ \ -extern void pre##_nmac(pre##_mackey */*key*/, \ - const void */*ok*/, const void */*ik*/); \ - \ -extern void pre##_hmac(pre##_mackey */*key*/, \ - const void */*k*/, size_t /*sz*/); \ - \ -extern void pre##_macinit(pre##_macctx */*ctx*/, \ - const pre##_mackey */*key*/); \ +/* --- Other useful constants --- */ \ \ -extern void pre##_mac(pre##_macctx */*ctx*/, \ - const void */*buf*/, size_t /*sz*/); \ +extern const octet pre##_hmackeysz[]; \ +extern const octet pre##_nmackeysz[]; \ +extern const octet pre##_sslmackeysz[]; \ \ -extern void pre##_macdone(pre##_macctx */*ctx*/, void */*mac*/); - -/* --- @HMAC_DEF@ --- * - * - * Arguments: @PRE@, @pre@ = prefixes for the underlying hash function - * - * Use: Creates implementations for the HMAC and NMAC functions. - */ - -#define HMAC_DEF(PRE, pre) \ - \ -/* --- @pre_nmac@ --- * \ +/* --- @pre_nmacinit@ --- * \ * \ * Arguments: @pre_macctx *key@ = pointer to a MAC key object \ * @const void *ok@ = pointer to outer hash init vector \ @@ -121,14 +101,10 @@ extern void pre##_macdone(pre##_macctx */*ctx*/, void */*mac*/); * Use: Initializes a MAC key for doing NMAC hashing. \ */ \ \ -void pre##_nmac(pre##_mackey *key, const void *ok, const void *ik) \ -{ \ - memcpy(key->ochain, ok, PRE##_HASHSZ); \ - memcpy(key->ichain, ik, PRE##_HASHSZ); \ - key->ocount = key->icount = 0; \ -} \ +extern void pre##_nmacinit(pre##_mackey */*key*/, \ + const void */*ok*/, const void */*ik*/); \ \ -/* --- @pre_hmac@ --- * \ +/* --- @pre_hmacinit@ --- * \ * \ * Arguments: @pre_mackey *key@ = pointer to MAC key object \ * @const void *k@ = pointer to key to use \ @@ -143,38 +119,23 @@ void pre##_nmac(pre##_mackey *key, const void *ok, const void *ik) \ * use, as specified in RFC2104. \ */ \ \ -void pre##_hmac(pre##_mackey *key, const void *k, size_t sz) \ -{ \ - int i; \ - const octet *kbuf = k; \ - pre##_ctx ctx; \ - octet buf[PRE##_HASHSZ]; \ - \ - if (sz > PRE##_BUFSZ) { \ - pre##_init(&ctx); \ - pre##_hash(&ctx, k, sz); \ - pre##_done(&ctx, buf); \ - kbuf = buf; \ - sz = PRE##_HASHSZ; \ - } \ - \ - pre##_init(&ctx); \ - memset(ctx.buf, 0x5c, PRE##_BUFSZ); \ - for (i = 0; i < sz; i++) \ - ctx.buf[i] ^= kbuf[i]; \ - pre##_compress(&ctx, ctx.buf); \ - pre##_state(&ctx, key->ochain); \ +extern void pre##_hmacinit(pre##_mackey */*key*/, \ + const void */*k*/, size_t /*sz*/); \ \ - pre##_init(&ctx); \ - memset(ctx.buf, 0x36, PRE##_BUFSZ); \ - for (i = 0; i < sz; i++) \ - ctx.buf[i] ^= kbuf[i]; \ - pre##_compress(&ctx, ctx.buf); \ - pre##_state(&ctx, key->ichain); \ +/* --- @pre_sslmacinit@ --- * \ + * \ + * Arguments: @pre_mackey *key@ = pointer to MAC key object \ + * @const void *k@ = pointer to key to use \ + * @size_t sz@ = size of key data \ + * \ + * Returns: --- \ + * \ + * Use: Initializes a MAC key for doing hasing using the SSL3 \ + * variant of HMAC. \ + */ \ \ - key->ocount = key->icount = PRE##_BUFSZ; \ - BURN(ctx); \ -} \ +extern void pre##_sslmacinit(pre##_mackey */*key*/, \ + const void */*k*/, size_t /*sz*/); \ \ /* --- @pre_macinit@ --- * \ * \ @@ -186,14 +147,10 @@ void pre##_hmac(pre##_mackey *key, const void *k, size_t sz) \ * Use: Instantiates a MAC context from a key block. \ */ \ \ -void pre##_macinit(pre##_macctx *ctx, const pre##_mackey *key) \ -{ \ - memcpy(ctx->chain, key->ochain, PRE##_HASHSZ); \ - ctx->count = key->ocount; \ - pre##_set(&ctx->ctx, key->ichain, key->icount); \ -} \ +extern void pre##_macinit(pre##_macctx */*ctx*/, \ + const pre##_mackey */*key*/); \ \ -/* --- @pre_mac@ --- * \ +/* --- @pre_machash@ --- * \ * \ * Arguments: @pre_macctx *ctx@ = pointer to MAC context block \ * @const void *buf@ = pointer to buffer \ @@ -204,10 +161,8 @@ void pre##_macinit(pre##_macctx *ctx, const pre##_mackey *key) \ * Use: Hashes a buffer. \ */ \ \ -void pre##_mac(pre##_macctx *ctx, const void *buf, size_t sz) \ -{ \ - pre##_hash(&ctx->ctx, buf, sz); \ -} \ +extern void pre##_machash(pre##_macctx */*ctx*/, \ + const void */*buf*/, size_t /*sz*/); \ \ /* --- @pre_macdone@ --- * \ * \ @@ -219,98 +174,13 @@ void pre##_mac(pre##_macctx *ctx, const void *buf, size_t sz) \ * Use: Returns the result of a MAC computation. \ */ \ \ -void pre##_macdone(pre##_macctx *ctx, void *mac) \ -{ \ - pre##_done(&ctx->ctx, mac); \ - pre##_set(&ctx->ctx, ctx->chain, ctx->count); \ - pre##_hash(&ctx->ctx, mac, PRE##_HASHSZ); \ - pre##_done(&ctx->ctx, mac); \ -} \ +extern void pre##_macdone(pre##_macctx */*ctx*/, void */*mac*/); \ \ -HMAC_TEST(PRE, pre) \ - -/* --- @HMAC_TEST@ --- * - * - * Arguments: @PRE@, @pre@ = prefixes for hash-specfic definitions - * - * Use: Standard test rig for MAC functions. - */ - -#ifdef TEST_RIG - -#include -#include -#include - -#define HMAC_TEST(PRE, pre) \ - \ -static int macverify(dstr *v) \ -{ \ - pre##_macctx cctx; \ - pre##_mackey ckey; \ - int ok = 1; \ - int i; \ - octet *p; \ - int szs[] = { 1, 7, 192, -1, 0 }, *ip; \ - size_t csz; \ - dstr d; \ - \ - dstr_create(&d); \ - dstr_ensure(&d, PRE##_HASHSZ); \ - d.len = PRE##_HASHSZ; \ - \ - pre##_hmac(&ckey, v[1].buf, v[1].len); \ +/* --- Generic MAC interface --- */ \ \ - for (ip = szs; *ip; ip++) { \ - i = *ip; \ - csz = v[0].len; \ - if (i == -1) \ - i = csz; \ - if (i > csz) \ - continue; \ - p = (octet *)v[0].buf; \ - pre##_macinit(&cctx, &ckey); \ - while (csz) { \ - if (i > csz) \ - i = csz; \ - pre##_mac(&cctx, p, i); \ - p += i; \ - csz -= i; \ - } \ - pre##_macdone(&cctx, d.buf); \ - if (memcmp(d.buf, v[2].buf, PRE##_HASHSZ) != 0) { \ - printf("\nfail:\n\tstep = %i\n\tinput = `%s'\n\tkey = ", \ - *ip, v[0].buf); \ - type_hex.dump(&v[1], stdout); \ - fputs("\n\texpected = ", stdout); \ - type_hex.dump(&v[2], stdout); \ - fputs("\n\tcomputed = ", stdout); \ - type_hex.dump(&d, stdout); \ - putchar('\n'); \ - ok = 0; \ - } \ - } \ - \ - dstr_destroy(&d); \ - return (ok); \ -} \ - \ -static test_chunk macdefs[] = { \ - { #pre "-hmac", macverify, \ - { &type_string, &type_hex, &type_hex, 0 } }, \ - { 0, 0, { 0 } } \ -}; \ - \ -int main(int argc, char *argv[]) \ -{ \ - ego(argv[0]); \ - test_run(argc, argv, macdefs, SRCDIR"/tests/" #pre); \ - return (0); \ -} - -#else -# define HMAC_TEST(PRE, pre) -#endif +extern const gcmac pre##_hmac; \ +extern const gcmac pre##_nmac; \ +extern const gcmac pre##_sslmac; /*----- That's all, folks -------------------------------------------------*/