/* -*-c-*-
*
- * $Id: hmac.h,v 1.1 1999/09/03 08:41:12 mdw Exp $
+ * $Id: hmac.h,v 1.3 2000/06/17 11:23:57 mdw Exp $
*
* Generic code for HMAC and NMAC
*
/*----- Revision history --------------------------------------------------*
*
* $Log: hmac.h,v $
+ * Revision 1.3 2000/06/17 11:23:57 mdw
+ * New key size interface.
+ *
+ * Revision 1.2 1999/12/10 23:17:39 mdw
+ * Split mode macros into interface and implementation.
+ *
* 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" {
/*----- Header files ------------------------------------------------------*/
-#include <stdlib.h>
-#include <string.h>
+#include <stddef.h>
#include <mLib/bits.h>
-#ifndef PARANOIA_H
-# include "paranoia.h"
+#ifndef CATACOMB_GMAC_H
+# include "gmac.h"
#endif
/*----- Macros ------------------------------------------------------------*/
#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 */ \
+ unsigned ocount; /* Byte count for outer hash */ \
octet ichain[PRE##_HASHSZ]; /* Chaining for inner hash */ \
- unsigned long icount; /* Byte count 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 */ \
+ 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*/); \
- \
-extern void pre##_mac(pre##_macctx */*ctx*/, \
- const void */*buf*/, size_t /*sz*/); \
+/* --- Other useful constants --- */ \
\
-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) \
+extern const octet pre##_mackeysz[]; \
\
-/* --- @pre_nmac@ --- * \
+/* --- @pre_nmacinit@ --- * \
* \
* Arguments: @pre_macctx *key@ = pointer to a MAC key object \
* @const void *ok@ = pointer to outer hash init vector \
* 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 \
* 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); \
- \
- 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); \
- \
- key->ocount = key->icount = PRE##_BUFSZ; \
- BURN(ctx); \
-} \
+extern void pre##_hmacinit(pre##_mackey */*key*/, \
+ const void */*k*/, size_t /*sz*/); \
\
/* --- @pre_macinit@ --- * \
* \
* 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 \
* 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@ --- * \
* \
* 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); \
-} \
- \
-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 <mLib/dstr.h>
-#include <mLib/quis.h>
-#include <mLib/testrig.h>
-
-#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); \
+extern void pre##_macdone(pre##_macctx */*ctx*/, void */*mac*/); \
\
- 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; \
- } \
- } \
+/* --- Generic MAC interface --- */ \
\
- 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;
/*----- That's all, folks -------------------------------------------------*/