Annotation of embedaddon/ntp/lib/isc/hmacsha.c, revision 1.1.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>