File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / ntp / lib / isc / hmacsha.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue May 29 12:08:38 2012 UTC (12 years, 7 months ago) by misho
Branches: ntp, MAIN
CVS tags: v4_2_6p5p0, v4_2_6p5, HEAD
ntp 4.2.6p5

    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.1.1.1 2012/05/29 12:08:38 misho 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>