hmacmd5.c revision 5b7abbef511cea0b568be0bc8d5b3120a0b9034d
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff/*
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
fcb54ce0a4f7377486df5bec83b3aa4711bf4131Mark Andrews * Copyright (C) 2000, 2001 Internet Software Consortium.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
ec5347e2c775f027573ce5648b910361aa926c01Automatic Updater * Permission to use, copy, modify, and/or distribute this software for any
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * purpose with or without fee is hereby granted, provided that the above
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * copyright notice and this permission notice appear in all copies.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * PERFORMANCE OF THIS SOFTWARE.
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff */
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff
a95a9de45ca739dab17ec1263186dbaaaba50d97Tatuya JINMEI 神明達哉/* $Id: hmacmd5.c,v 1.16 2009/02/06 23:47:42 tbox Exp $ */
9c3531d72aeaad6c5f01efe6a1c82023e1379e4dDavid Lawrence
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff/*! \file
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * This code implements the HMAC-MD5 keyed hash algorithm
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * described in RFC2104.
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff */
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley#include "config.h"
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff#include <isc/assertions.h>
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff#include <isc/hmacmd5.h>
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein#include <isc/md5.h>
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff#include <isc/platform.h>
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff#include <isc/safe.h>
9282e3c21a20f354e22ad3f092aea4956abaea5cMichael Graff#include <isc/string.h>
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff#include <isc/types.h>
9282e3c21a20f354e22ad3f092aea4956abaea5cMichael Graff#include <isc/util.h>
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff#ifdef ISC_PLATFORM_OPENSSLHASH
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff
058eeac2105c39e7cb31fb75ee0b473717ec3bbcMark Andrewsvoid
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrenceisc_hmacmd5_init(isc_hmacmd5_t *ctx, const unsigned char *key,
3024dbecbac365171bc6de0f3fa04951d6558be3Michael Graff unsigned int len)
5fca48054b5e791a2fa0c5015bc3b6fef4fcdce1Andreas Gustafsson{
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff HMAC_Init(ctx, (const void *) key, (int) len, EVP_md5());
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff}
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence
3ac63b472022ff92691d1fe69ac715a729671965Michael Graffvoid
440be4c866f6935ac069db79a414304507a664c2Michael Graffisc_hmacmd5_invalidate(isc_hmacmd5_t *ctx) {
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff HMAC_CTX_cleanup(ctx);
e45d323a2a0f4ca08d4b139546e60a5fa7bd3f0cMichael Graff}
29f28fe573d4b3b318b3b026d567c1eb86738015Michael Graff
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graffvoid
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graffisc_hmacmd5_update(isc_hmacmd5_t *ctx, const unsigned char *buf,
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff unsigned int len)
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff{
d1cbf714097e900ed1703529584d3e1a50e8a4a8Brian Wellington HMAC_Update(ctx, buf, (int) len);
bcf369e513a1cc2209e2a987f5772afa79813540Mark Andrews}
11efdeb076d65fa9f0c5fc067dc040e7c99dfba6Michael Graff
09f22ac5b09e70bc526015f37168ba33e21ea91fDavid Lawrencevoid
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graffisc_hmacmd5_sign(isc_hmacmd5_t *ctx, unsigned char *digest) {
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff HMAC_Final(ctx, digest, NULL);
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff HMAC_CTX_cleanup(ctx);
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff}
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#else
31fab17bcdbe302592a6c0dc5374ef56333ee879Michael Graff
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define PADLEN 64
bcf369e513a1cc2209e2a987f5772afa79813540Mark Andrews#define IPAD 0x36
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define OPAD 0x5C
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff/*!
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff * Start HMAC-MD5 process. Initialize an md5 context and digest the key.
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff */
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graffvoid
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graffisc_hmacmd5_init(isc_hmacmd5_t *ctx, const unsigned char *key,
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff unsigned int len)
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley{
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley unsigned char ipad[PADLEN];
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley int i;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff memset(ctx->key, 0, sizeof(ctx->key));
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff if (len > sizeof(ctx->key)) {
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein isc_md5_t md5ctx;
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff isc_md5_init(&md5ctx);
d947011dc393d9f9988d1349d585b246d19cc3c7Michael Graff isc_md5_update(&md5ctx, key, len);
49a940dc68b30d9e4f9e1bd3c0503d8b90bb1726Mark Andrews isc_md5_final(&md5ctx, ctx->key);
d947011dc393d9f9988d1349d585b246d19cc3c7Michael Graff } else
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff memcpy(ctx->key, key, len);
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff isc_md5_init(&ctx->md5ctx);
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff memset(ipad, IPAD, sizeof(ipad));
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff for (i = 0; i < PADLEN; i++)
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein ipad[i] ^= ctx->key[i];
7b5172166d816efabcdb22519b136ba124bb2619Brian Wellington isc_md5_update(&ctx->md5ctx, ipad, sizeof(ipad));
7b5172166d816efabcdb22519b136ba124bb2619Brian Wellington}
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graffvoid
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austeinisc_hmacmd5_invalidate(isc_hmacmd5_t *ctx) {
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff isc_md5_invalidate(&ctx->md5ctx);
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein memset(ctx->key, 0, sizeof(ctx->key));
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff}
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff/*!
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff * Update context to reflect the concatenation of another buffer full
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff * of bytes.
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff */
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graffvoid
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graffisc_hmacmd5_update(isc_hmacmd5_t *ctx, const unsigned char *buf,
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff unsigned int len)
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff{
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff isc_md5_update(&ctx->md5ctx, buf, len);
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff}
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff
213973a334f92d4aef4ef62b4538fc2e4d0e8082Michael Graff/*!
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff * Compute signature - finalize MD5 operation and reapply MD5.
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff */
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graffvoid
081cff0c33514a5dc63ab794fc199c07377ab756Mark Andrewsisc_hmacmd5_sign(isc_hmacmd5_t *ctx, unsigned char *digest) {
213973a334f92d4aef4ef62b4538fc2e4d0e8082Michael Graff unsigned char opad[PADLEN];
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff int i;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff
bcf369e513a1cc2209e2a987f5772afa79813540Mark Andrews isc_md5_final(&ctx->md5ctx, digest);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff memset(opad, OPAD, sizeof(opad));
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley for (i = 0; i < PADLEN; i++)
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff opad[i] ^= ctx->key[i];
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff isc_md5_init(&ctx->md5ctx);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_md5_update(&ctx->md5ctx, opad, sizeof(opad));
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff isc_md5_update(&ctx->md5ctx, digest, ISC_MD5_DIGESTLENGTH);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_md5_final(&ctx->md5ctx, digest);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_hmacmd5_invalidate(ctx);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater}
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater#endif /* !ISC_PLATFORM_OPENSSLHASH */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater/*!
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Verify signature - finalize MD5 operation and reapply MD5, then
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff * compare to the supplied digest.
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updaterisc_boolean_t
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updaterisc_hmacmd5_verify(isc_hmacmd5_t *ctx, unsigned char *digest) {
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff return (isc_hmacmd5_verify2(ctx, digest, ISC_MD5_DIGESTLENGTH));
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff}
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updaterisc_boolean_t
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updaterisc_hmacmd5_verify2(isc_hmacmd5_t *ctx, unsigned char *digest, size_t len) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater unsigned char newdigest[ISC_MD5_DIGESTLENGTH];
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater REQUIRE(len <= ISC_MD5_DIGESTLENGTH);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_hmacmd5_sign(ctx, newdigest);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater return (isc_safe_memcmp(digest, newdigest, len));
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater}
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater