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.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>