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