Annotation of embedaddon/ntp/lib/isc/hmacsha.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (C) 2005-2007 Internet Systems Consortium, Inc. ("ISC")
! 3: *
! 4: * Permission to use, copy, modify, and/or distribute this software for any
! 5: * purpose with or without fee is hereby granted, provided that the above
! 6: * copyright notice and this permission notice appear in all copies.
! 7: *
! 8: * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
! 9: * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
! 10: * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
! 11: * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
! 12: * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
! 13: * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
! 14: * PERFORMANCE OF THIS SOFTWARE.
! 15: */
! 16:
! 17: /* $Id: hmacsha.c,v 1.8 2007/08/27 03:27:53 marka Exp $ */
! 18:
! 19: /*
! 20: * This code implements the HMAC-SHA1, HMAC-SHA224, HMAC-SHA256, HMAC-SHA384
! 21: * and HMAC-SHA512 keyed hash algorithm described in RFC 2104 and
! 22: * draft-ietf-dnsext-tsig-sha-01.txt.
! 23: */
! 24:
! 25: #include "config.h"
! 26:
! 27: #include <isc/assertions.h>
! 28: #include <isc/hmacsha.h>
! 29: #include <isc/sha1.h>
! 30: #include <isc/sha2.h>
! 31: #include <isc/string.h>
! 32: #include <isc/types.h>
! 33: #include <isc/util.h>
! 34:
! 35: #define IPAD 0x36
! 36: #define OPAD 0x5C
! 37:
! 38: /*
! 39: * Start HMAC-SHA1 process. Initialize an sha1 context and digest the key.
! 40: */
! 41: void
! 42: isc_hmacsha1_init(isc_hmacsha1_t *ctx, const unsigned char *key,
! 43: unsigned int len)
! 44: {
! 45: unsigned char ipad[ISC_SHA1_BLOCK_LENGTH];
! 46: unsigned int i;
! 47:
! 48: memset(ctx->key, 0, sizeof(ctx->key));
! 49: if (len > sizeof(ctx->key)) {
! 50: isc_sha1_t sha1ctx;
! 51: isc_sha1_init(&sha1ctx);
! 52: isc_sha1_update(&sha1ctx, key, len);
! 53: isc_sha1_final(&sha1ctx, ctx->key);
! 54: } else
! 55: memcpy(ctx->key, key, len);
! 56:
! 57: isc_sha1_init(&ctx->sha1ctx);
! 58: memset(ipad, IPAD, sizeof(ipad));
! 59: for (i = 0; i < ISC_SHA1_BLOCK_LENGTH; i++)
! 60: ipad[i] ^= ctx->key[i];
! 61: isc_sha1_update(&ctx->sha1ctx, ipad, sizeof(ipad));
! 62: }
! 63:
! 64: void
! 65: isc_hmacsha1_invalidate(isc_hmacsha1_t *ctx) {
! 66: isc_sha1_invalidate(&ctx->sha1ctx);
! 67: memset(ctx->key, 0, sizeof(ctx->key));
! 68: memset(ctx, 0, sizeof(ctx));
! 69: }
! 70:
! 71: /*
! 72: * Update context to reflect the concatenation of another buffer full
! 73: * of bytes.
! 74: */
! 75: void
! 76: isc_hmacsha1_update(isc_hmacsha1_t *ctx, const unsigned char *buf,
! 77: unsigned int len)
! 78: {
! 79: isc_sha1_update(&ctx->sha1ctx, buf, len);
! 80: }
! 81:
! 82: /*
! 83: * Compute signature - finalize SHA1 operation and reapply SHA1.
! 84: */
! 85: void
! 86: isc_hmacsha1_sign(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) {
! 87: unsigned char opad[ISC_SHA1_BLOCK_LENGTH];
! 88: unsigned char newdigest[ISC_SHA1_DIGESTLENGTH];
! 89: unsigned int i;
! 90:
! 91: REQUIRE(len <= ISC_SHA1_DIGESTLENGTH);
! 92: isc_sha1_final(&ctx->sha1ctx, newdigest);
! 93:
! 94: memset(opad, OPAD, sizeof(opad));
! 95: for (i = 0; i < ISC_SHA1_BLOCK_LENGTH; i++)
! 96: opad[i] ^= ctx->key[i];
! 97:
! 98: isc_sha1_init(&ctx->sha1ctx);
! 99: isc_sha1_update(&ctx->sha1ctx, opad, sizeof(opad));
! 100: isc_sha1_update(&ctx->sha1ctx, newdigest, ISC_SHA1_DIGESTLENGTH);
! 101: isc_sha1_final(&ctx->sha1ctx, newdigest);
! 102: isc_hmacsha1_invalidate(ctx);
! 103: memcpy(digest, newdigest, len);
! 104: memset(newdigest, 0, sizeof(newdigest));
! 105: }
! 106:
! 107: /*
! 108: * Verify signature - finalize SHA1 operation and reapply SHA1, then
! 109: * compare to the supplied digest.
! 110: */
! 111: isc_boolean_t
! 112: isc_hmacsha1_verify(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) {
! 113: unsigned char newdigest[ISC_SHA1_DIGESTLENGTH];
! 114:
! 115: REQUIRE(len <= ISC_SHA1_DIGESTLENGTH);
! 116: isc_hmacsha1_sign(ctx, newdigest, ISC_SHA1_DIGESTLENGTH);
! 117: return (ISC_TF(memcmp(digest, newdigest, len) == 0));
! 118: }
! 119:
! 120: /*
! 121: * Start HMAC-SHA224 process. Initialize an sha224 context and digest the key.
! 122: */
! 123: void
! 124: isc_hmacsha224_init(isc_hmacsha224_t *ctx, const unsigned char *key,
! 125: unsigned int len)
! 126: {
! 127: unsigned char ipad[ISC_SHA224_BLOCK_LENGTH];
! 128: unsigned int i;
! 129:
! 130: memset(ctx->key, 0, sizeof(ctx->key));
! 131: if (len > sizeof(ctx->key)) {
! 132: isc_sha224_t sha224ctx;
! 133: isc_sha224_init(&sha224ctx);
! 134: isc_sha224_update(&sha224ctx, key, len);
! 135: isc_sha224_final(ctx->key, &sha224ctx);
! 136: } else
! 137: memcpy(ctx->key, key, len);
! 138:
! 139: isc_sha224_init(&ctx->sha224ctx);
! 140: memset(ipad, IPAD, sizeof(ipad));
! 141: for (i = 0; i < ISC_SHA224_BLOCK_LENGTH; i++)
! 142: ipad[i] ^= ctx->key[i];
! 143: isc_sha224_update(&ctx->sha224ctx, ipad, sizeof(ipad));
! 144: }
! 145:
! 146: void
! 147: isc_hmacsha224_invalidate(isc_hmacsha224_t *ctx) {
! 148: memset(ctx->key, 0, sizeof(ctx->key));
! 149: memset(ctx, 0, sizeof(ctx));
! 150: }
! 151:
! 152: /*
! 153: * Update context to reflect the concatenation of another buffer full
! 154: * of bytes.
! 155: */
! 156: void
! 157: isc_hmacsha224_update(isc_hmacsha224_t *ctx, const unsigned char *buf,
! 158: unsigned int len)
! 159: {
! 160: isc_sha224_update(&ctx->sha224ctx, buf, len);
! 161: }
! 162:
! 163: /*
! 164: * Compute signature - finalize SHA224 operation and reapply SHA224.
! 165: */
! 166: void
! 167: isc_hmacsha224_sign(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) {
! 168: unsigned char opad[ISC_SHA224_BLOCK_LENGTH];
! 169: unsigned char newdigest[ISC_SHA224_DIGESTLENGTH];
! 170: unsigned int i;
! 171:
! 172: REQUIRE(len <= ISC_SHA224_DIGESTLENGTH);
! 173: isc_sha224_final(newdigest, &ctx->sha224ctx);
! 174:
! 175: memset(opad, OPAD, sizeof(opad));
! 176: for (i = 0; i < ISC_SHA224_BLOCK_LENGTH; i++)
! 177: opad[i] ^= ctx->key[i];
! 178:
! 179: isc_sha224_init(&ctx->sha224ctx);
! 180: isc_sha224_update(&ctx->sha224ctx, opad, sizeof(opad));
! 181: isc_sha224_update(&ctx->sha224ctx, newdigest, ISC_SHA224_DIGESTLENGTH);
! 182: isc_sha224_final(newdigest, &ctx->sha224ctx);
! 183: memcpy(digest, newdigest, len);
! 184: memset(newdigest, 0, sizeof(newdigest));
! 185: }
! 186:
! 187: /*
! 188: * Verify signature - finalize SHA224 operation and reapply SHA224, then
! 189: * compare to the supplied digest.
! 190: */
! 191: isc_boolean_t
! 192: isc_hmacsha224_verify(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) {
! 193: unsigned char newdigest[ISC_SHA224_DIGESTLENGTH];
! 194:
! 195: REQUIRE(len <= ISC_SHA224_DIGESTLENGTH);
! 196: isc_hmacsha224_sign(ctx, newdigest, ISC_SHA224_DIGESTLENGTH);
! 197: return (ISC_TF(memcmp(digest, newdigest, len) == 0));
! 198: }
! 199:
! 200: /*
! 201: * Start HMAC-SHA256 process. Initialize an sha256 context and digest the key.
! 202: */
! 203: void
! 204: isc_hmacsha256_init(isc_hmacsha256_t *ctx, const unsigned char *key,
! 205: unsigned int len)
! 206: {
! 207: unsigned char ipad[ISC_SHA256_BLOCK_LENGTH];
! 208: unsigned int i;
! 209:
! 210: memset(ctx->key, 0, sizeof(ctx->key));
! 211: if (len > sizeof(ctx->key)) {
! 212: isc_sha256_t sha256ctx;
! 213: isc_sha256_init(&sha256ctx);
! 214: isc_sha256_update(&sha256ctx, key, len);
! 215: isc_sha256_final(ctx->key, &sha256ctx);
! 216: } else
! 217: memcpy(ctx->key, key, len);
! 218:
! 219: isc_sha256_init(&ctx->sha256ctx);
! 220: memset(ipad, IPAD, sizeof(ipad));
! 221: for (i = 0; i < ISC_SHA256_BLOCK_LENGTH; i++)
! 222: ipad[i] ^= ctx->key[i];
! 223: isc_sha256_update(&ctx->sha256ctx, ipad, sizeof(ipad));
! 224: }
! 225:
! 226: void
! 227: isc_hmacsha256_invalidate(isc_hmacsha256_t *ctx) {
! 228: memset(ctx->key, 0, sizeof(ctx->key));
! 229: memset(ctx, 0, sizeof(ctx));
! 230: }
! 231:
! 232: /*
! 233: * Update context to reflect the concatenation of another buffer full
! 234: * of bytes.
! 235: */
! 236: void
! 237: isc_hmacsha256_update(isc_hmacsha256_t *ctx, const unsigned char *buf,
! 238: unsigned int len)
! 239: {
! 240: isc_sha256_update(&ctx->sha256ctx, buf, len);
! 241: }
! 242:
! 243: /*
! 244: * Compute signature - finalize SHA256 operation and reapply SHA256.
! 245: */
! 246: void
! 247: isc_hmacsha256_sign(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) {
! 248: unsigned char opad[ISC_SHA256_BLOCK_LENGTH];
! 249: unsigned char newdigest[ISC_SHA256_DIGESTLENGTH];
! 250: unsigned int i;
! 251:
! 252: REQUIRE(len <= ISC_SHA256_DIGESTLENGTH);
! 253: isc_sha256_final(newdigest, &ctx->sha256ctx);
! 254:
! 255: memset(opad, OPAD, sizeof(opad));
! 256: for (i = 0; i < ISC_SHA256_BLOCK_LENGTH; i++)
! 257: opad[i] ^= ctx->key[i];
! 258:
! 259: isc_sha256_init(&ctx->sha256ctx);
! 260: isc_sha256_update(&ctx->sha256ctx, opad, sizeof(opad));
! 261: isc_sha256_update(&ctx->sha256ctx, newdigest, ISC_SHA256_DIGESTLENGTH);
! 262: isc_sha256_final(newdigest, &ctx->sha256ctx);
! 263: memcpy(digest, newdigest, len);
! 264: memset(newdigest, 0, sizeof(newdigest));
! 265: }
! 266:
! 267: /*
! 268: * Verify signature - finalize SHA256 operation and reapply SHA256, then
! 269: * compare to the supplied digest.
! 270: */
! 271: isc_boolean_t
! 272: isc_hmacsha256_verify(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) {
! 273: unsigned char newdigest[ISC_SHA256_DIGESTLENGTH];
! 274:
! 275: REQUIRE(len <= ISC_SHA256_DIGESTLENGTH);
! 276: isc_hmacsha256_sign(ctx, newdigest, ISC_SHA256_DIGESTLENGTH);
! 277: return (ISC_TF(memcmp(digest, newdigest, len) == 0));
! 278: }
! 279:
! 280: /*
! 281: * Start HMAC-SHA384 process. Initialize an sha384 context and digest the key.
! 282: */
! 283: void
! 284: isc_hmacsha384_init(isc_hmacsha384_t *ctx, const unsigned char *key,
! 285: unsigned int len)
! 286: {
! 287: unsigned char ipad[ISC_SHA384_BLOCK_LENGTH];
! 288: unsigned int i;
! 289:
! 290: memset(ctx->key, 0, sizeof(ctx->key));
! 291: if (len > sizeof(ctx->key)) {
! 292: isc_sha384_t sha384ctx;
! 293: isc_sha384_init(&sha384ctx);
! 294: isc_sha384_update(&sha384ctx, key, len);
! 295: isc_sha384_final(ctx->key, &sha384ctx);
! 296: } else
! 297: memcpy(ctx->key, key, len);
! 298:
! 299: isc_sha384_init(&ctx->sha384ctx);
! 300: memset(ipad, IPAD, sizeof(ipad));
! 301: for (i = 0; i < ISC_SHA384_BLOCK_LENGTH; i++)
! 302: ipad[i] ^= ctx->key[i];
! 303: isc_sha384_update(&ctx->sha384ctx, ipad, sizeof(ipad));
! 304: }
! 305:
! 306: void
! 307: isc_hmacsha384_invalidate(isc_hmacsha384_t *ctx) {
! 308: memset(ctx->key, 0, sizeof(ctx->key));
! 309: memset(ctx, 0, sizeof(ctx));
! 310: }
! 311:
! 312: /*
! 313: * Update context to reflect the concatenation of another buffer full
! 314: * of bytes.
! 315: */
! 316: void
! 317: isc_hmacsha384_update(isc_hmacsha384_t *ctx, const unsigned char *buf,
! 318: unsigned int len)
! 319: {
! 320: isc_sha384_update(&ctx->sha384ctx, buf, len);
! 321: }
! 322:
! 323: /*
! 324: * Compute signature - finalize SHA384 operation and reapply SHA384.
! 325: */
! 326: void
! 327: isc_hmacsha384_sign(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) {
! 328: unsigned char opad[ISC_SHA384_BLOCK_LENGTH];
! 329: unsigned char newdigest[ISC_SHA384_DIGESTLENGTH];
! 330: unsigned int i;
! 331:
! 332: REQUIRE(len <= ISC_SHA384_DIGESTLENGTH);
! 333: isc_sha384_final(newdigest, &ctx->sha384ctx);
! 334:
! 335: memset(opad, OPAD, sizeof(opad));
! 336: for (i = 0; i < ISC_SHA384_BLOCK_LENGTH; i++)
! 337: opad[i] ^= ctx->key[i];
! 338:
! 339: isc_sha384_init(&ctx->sha384ctx);
! 340: isc_sha384_update(&ctx->sha384ctx, opad, sizeof(opad));
! 341: isc_sha384_update(&ctx->sha384ctx, newdigest, ISC_SHA384_DIGESTLENGTH);
! 342: isc_sha384_final(newdigest, &ctx->sha384ctx);
! 343: memcpy(digest, newdigest, len);
! 344: memset(newdigest, 0, sizeof(newdigest));
! 345: }
! 346:
! 347: /*
! 348: * Verify signature - finalize SHA384 operation and reapply SHA384, then
! 349: * compare to the supplied digest.
! 350: */
! 351: isc_boolean_t
! 352: isc_hmacsha384_verify(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) {
! 353: unsigned char newdigest[ISC_SHA384_DIGESTLENGTH];
! 354:
! 355: REQUIRE(len <= ISC_SHA384_DIGESTLENGTH);
! 356: isc_hmacsha384_sign(ctx, newdigest, ISC_SHA384_DIGESTLENGTH);
! 357: return (ISC_TF(memcmp(digest, newdigest, len) == 0));
! 358: }
! 359:
! 360: /*
! 361: * Start HMAC-SHA512 process. Initialize an sha512 context and digest the key.
! 362: */
! 363: void
! 364: isc_hmacsha512_init(isc_hmacsha512_t *ctx, const unsigned char *key,
! 365: unsigned int len)
! 366: {
! 367: unsigned char ipad[ISC_SHA512_BLOCK_LENGTH];
! 368: unsigned int i;
! 369:
! 370: memset(ctx->key, 0, sizeof(ctx->key));
! 371: if (len > sizeof(ctx->key)) {
! 372: isc_sha512_t sha512ctx;
! 373: isc_sha512_init(&sha512ctx);
! 374: isc_sha512_update(&sha512ctx, key, len);
! 375: isc_sha512_final(ctx->key, &sha512ctx);
! 376: } else
! 377: memcpy(ctx->key, key, len);
! 378:
! 379: isc_sha512_init(&ctx->sha512ctx);
! 380: memset(ipad, IPAD, sizeof(ipad));
! 381: for (i = 0; i < ISC_SHA512_BLOCK_LENGTH; i++)
! 382: ipad[i] ^= ctx->key[i];
! 383: isc_sha512_update(&ctx->sha512ctx, ipad, sizeof(ipad));
! 384: }
! 385:
! 386: void
! 387: isc_hmacsha512_invalidate(isc_hmacsha512_t *ctx) {
! 388: memset(ctx->key, 0, sizeof(ctx->key));
! 389: memset(ctx, 0, sizeof(ctx));
! 390: }
! 391:
! 392: /*
! 393: * Update context to reflect the concatenation of another buffer full
! 394: * of bytes.
! 395: */
! 396: void
! 397: isc_hmacsha512_update(isc_hmacsha512_t *ctx, const unsigned char *buf,
! 398: unsigned int len)
! 399: {
! 400: isc_sha512_update(&ctx->sha512ctx, buf, len);
! 401: }
! 402:
! 403: /*
! 404: * Compute signature - finalize SHA512 operation and reapply SHA512.
! 405: */
! 406: void
! 407: isc_hmacsha512_sign(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) {
! 408: unsigned char opad[ISC_SHA512_BLOCK_LENGTH];
! 409: unsigned char newdigest[ISC_SHA512_DIGESTLENGTH];
! 410: unsigned int i;
! 411:
! 412: REQUIRE(len <= ISC_SHA512_DIGESTLENGTH);
! 413: isc_sha512_final(newdigest, &ctx->sha512ctx);
! 414:
! 415: memset(opad, OPAD, sizeof(opad));
! 416: for (i = 0; i < ISC_SHA512_BLOCK_LENGTH; i++)
! 417: opad[i] ^= ctx->key[i];
! 418:
! 419: isc_sha512_init(&ctx->sha512ctx);
! 420: isc_sha512_update(&ctx->sha512ctx, opad, sizeof(opad));
! 421: isc_sha512_update(&ctx->sha512ctx, newdigest, ISC_SHA512_DIGESTLENGTH);
! 422: isc_sha512_final(newdigest, &ctx->sha512ctx);
! 423: memcpy(digest, newdigest, len);
! 424: memset(newdigest, 0, sizeof(newdigest));
! 425: }
! 426:
! 427: /*
! 428: * Verify signature - finalize SHA512 operation and reapply SHA512, then
! 429: * compare to the supplied digest.
! 430: */
! 431: isc_boolean_t
! 432: isc_hmacsha512_verify(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) {
! 433: unsigned char newdigest[ISC_SHA512_DIGESTLENGTH];
! 434:
! 435: REQUIRE(len <= ISC_SHA512_DIGESTLENGTH);
! 436: isc_hmacsha512_sign(ctx, newdigest, ISC_SHA512_DIGESTLENGTH);
! 437: return (ISC_TF(memcmp(digest, newdigest, len) == 0));
! 438: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>