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>