File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / ntp / lib / isc / hmacmd5.c
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Tue May 29 12:08:38 2012 UTC (12 years, 1 month ago) by misho
CVS tags: MAIN, HEAD
Initial revision

    1: /*
    2:  * Copyright (C) 2004-2007  Internet Systems Consortium, Inc. ("ISC")
    3:  * Copyright (C) 2000, 2001  Internet Software Consortium.
    4:  *
    5:  * Permission to use, copy, modify, and/or distribute this software for any
    6:  * purpose with or without fee is hereby granted, provided that the above
    7:  * copyright notice and this permission notice appear in all copies.
    8:  *
    9:  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
   10:  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
   11:  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
   12:  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
   13:  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
   14:  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
   15:  * PERFORMANCE OF THIS SOFTWARE.
   16:  */
   17: 
   18: /* $Id: hmacmd5.c,v 1.1 2012/05/29 12:08:38 misho Exp $ */
   19: 
   20: /*! \file
   21:  * This code implements the HMAC-MD5 keyed hash algorithm
   22:  * described in RFC2104.
   23:  */
   24: 
   25: #include "config.h"
   26: 
   27: #include <isc/assertions.h>
   28: #include <isc/hmacmd5.h>
   29: #include <isc/md5.h>
   30: #include <isc/string.h>
   31: #include <isc/types.h>
   32: #include <isc/util.h>
   33: 
   34: #define PADLEN 64
   35: #define IPAD 0x36
   36: #define OPAD 0x5C
   37: 
   38: /*!
   39:  * Start HMAC-MD5 process.  Initialize an md5 context and digest the key.
   40:  */
   41: void
   42: isc_hmacmd5_init(isc_hmacmd5_t *ctx, const unsigned char *key,
   43: 		 unsigned int len)
   44: {
   45: 	unsigned char ipad[PADLEN];
   46: 	int i;
   47: 
   48: 	memset(ctx->key, 0, sizeof(ctx->key));
   49: 	if (len > sizeof(ctx->key)) {
   50: 		isc_md5_t md5ctx;
   51: 		isc_md5_init(&md5ctx);
   52: 		isc_md5_update(&md5ctx, key, len);
   53: 		isc_md5_final(&md5ctx, ctx->key);
   54: 	} else
   55: 		memcpy(ctx->key, key, len);
   56: 
   57: 	isc_md5_init(&ctx->md5ctx);
   58: 	memset(ipad, IPAD, sizeof(ipad));
   59: 	for (i = 0; i < PADLEN; i++)
   60: 		ipad[i] ^= ctx->key[i];
   61: 	isc_md5_update(&ctx->md5ctx, ipad, sizeof(ipad));
   62: }
   63: 
   64: void
   65: isc_hmacmd5_invalidate(isc_hmacmd5_t *ctx) {
   66: 	isc_md5_invalidate(&ctx->md5ctx);
   67: 	memset(ctx->key, 0, sizeof(ctx->key));
   68: }
   69: 
   70: /*!
   71:  * Update context to reflect the concatenation of another buffer full
   72:  * of bytes.
   73:  */
   74: void
   75: isc_hmacmd5_update(isc_hmacmd5_t *ctx, const unsigned char *buf,
   76: 		   unsigned int len)
   77: {
   78: 	isc_md5_update(&ctx->md5ctx, buf, len);
   79: }
   80: 
   81: /*!
   82:  * Compute signature - finalize MD5 operation and reapply MD5.
   83:  */
   84: void
   85: isc_hmacmd5_sign(isc_hmacmd5_t *ctx, unsigned char *digest) {
   86: 	unsigned char opad[PADLEN];
   87: 	int i;
   88: 
   89: 	isc_md5_final(&ctx->md5ctx, digest);
   90: 
   91: 	memset(opad, OPAD, sizeof(opad));
   92: 	for (i = 0; i < PADLEN; i++)
   93: 		opad[i] ^= ctx->key[i];
   94: 
   95: 	isc_md5_init(&ctx->md5ctx);
   96: 	isc_md5_update(&ctx->md5ctx, opad, sizeof(opad));
   97: 	isc_md5_update(&ctx->md5ctx, digest, ISC_MD5_DIGESTLENGTH);
   98: 	isc_md5_final(&ctx->md5ctx, digest);
   99: 	isc_hmacmd5_invalidate(ctx);
  100: }
  101: 
  102: /*!
  103:  * Verify signature - finalize MD5 operation and reapply MD5, then
  104:  * compare to the supplied digest.
  105:  */
  106: isc_boolean_t
  107: isc_hmacmd5_verify(isc_hmacmd5_t *ctx, unsigned char *digest) {
  108: 	return (isc_hmacmd5_verify2(ctx, digest, ISC_MD5_DIGESTLENGTH));
  109: }
  110: 
  111: isc_boolean_t
  112: isc_hmacmd5_verify2(isc_hmacmd5_t *ctx, unsigned char *digest, size_t len) {
  113: 	unsigned char newdigest[ISC_MD5_DIGESTLENGTH];
  114: 
  115: 	REQUIRE(len <= ISC_MD5_DIGESTLENGTH);
  116: 	isc_hmacmd5_sign(ctx, newdigest);
  117: 	return (ISC_TF(memcmp(digest, newdigest, len) == 0));
  118: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>