Patrick Welche <prlw1@cam.ac.uk>
[netbsd-mini2440.git] / external / bsd / bind / dist / lib / isc / hmacmd5.c
blobadf610aaddc4326623b0d7ec29e08818040cebb7
1 /* $NetBSD$ */
3 /*
4 * Copyright (C) 2004-2007, 2009 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.16 2009/02/06 23:47:42 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/platform.h>
33 #include <isc/string.h>
34 #include <isc/types.h>
35 #include <isc/util.h>
37 #ifdef ISC_PLATFORM_OPENSSLHASH
39 void
40 isc_hmacmd5_init(isc_hmacmd5_t *ctx, const unsigned char *key,
41 unsigned int len)
43 HMAC_Init(ctx, (const void *) key, (int) len, EVP_md5());
46 void
47 isc_hmacmd5_invalidate(isc_hmacmd5_t *ctx) {
48 HMAC_CTX_cleanup(ctx);
51 void
52 isc_hmacmd5_update(isc_hmacmd5_t *ctx, const unsigned char *buf,
53 unsigned int len)
55 HMAC_Update(ctx, buf, (int) len);
58 void
59 isc_hmacmd5_sign(isc_hmacmd5_t *ctx, unsigned char *digest) {
60 HMAC_Final(ctx, digest, NULL);
61 HMAC_CTX_cleanup(ctx);
64 #else
66 #define PADLEN 64
67 #define IPAD 0x36
68 #define OPAD 0x5C
70 /*!
71 * Start HMAC-MD5 process. Initialize an md5 context and digest the key.
73 void
74 isc_hmacmd5_init(isc_hmacmd5_t *ctx, const unsigned char *key,
75 unsigned int len)
77 unsigned char ipad[PADLEN];
78 int i;
80 memset(ctx->key, 0, sizeof(ctx->key));
81 if (len > sizeof(ctx->key)) {
82 isc_md5_t md5ctx;
83 isc_md5_init(&md5ctx);
84 isc_md5_update(&md5ctx, key, len);
85 isc_md5_final(&md5ctx, ctx->key);
86 } else
87 memcpy(ctx->key, key, len);
89 isc_md5_init(&ctx->md5ctx);
90 memset(ipad, IPAD, sizeof(ipad));
91 for (i = 0; i < PADLEN; i++)
92 ipad[i] ^= ctx->key[i];
93 isc_md5_update(&ctx->md5ctx, ipad, sizeof(ipad));
96 void
97 isc_hmacmd5_invalidate(isc_hmacmd5_t *ctx) {
98 isc_md5_invalidate(&ctx->md5ctx);
99 memset(ctx->key, 0, sizeof(ctx->key));
103 * Update context to reflect the concatenation of another buffer full
104 * of bytes.
106 void
107 isc_hmacmd5_update(isc_hmacmd5_t *ctx, const unsigned char *buf,
108 unsigned int len)
110 isc_md5_update(&ctx->md5ctx, buf, len);
114 * Compute signature - finalize MD5 operation and reapply MD5.
116 void
117 isc_hmacmd5_sign(isc_hmacmd5_t *ctx, unsigned char *digest) {
118 unsigned char opad[PADLEN];
119 int i;
121 isc_md5_final(&ctx->md5ctx, digest);
123 memset(opad, OPAD, sizeof(opad));
124 for (i = 0; i < PADLEN; i++)
125 opad[i] ^= ctx->key[i];
127 isc_md5_init(&ctx->md5ctx);
128 isc_md5_update(&ctx->md5ctx, opad, sizeof(opad));
129 isc_md5_update(&ctx->md5ctx, digest, ISC_MD5_DIGESTLENGTH);
130 isc_md5_final(&ctx->md5ctx, digest);
131 isc_hmacmd5_invalidate(ctx);
133 #endif /* !ISC_PLATFORM_OPENSSLHASH */
136 * Verify signature - finalize MD5 operation and reapply MD5, then
137 * compare to the supplied digest.
139 isc_boolean_t
140 isc_hmacmd5_verify(isc_hmacmd5_t *ctx, unsigned char *digest) {
141 return (isc_hmacmd5_verify2(ctx, digest, ISC_MD5_DIGESTLENGTH));
144 isc_boolean_t
145 isc_hmacmd5_verify2(isc_hmacmd5_t *ctx, unsigned char *digest, size_t len) {
146 unsigned char newdigest[ISC_MD5_DIGESTLENGTH];
148 REQUIRE(len <= ISC_MD5_DIGESTLENGTH);
149 isc_hmacmd5_sign(ctx, newdigest);
150 return (ISC_TF(memcmp(digest, newdigest, len) == 0));