1258945Sroberto/* 2280849Scy * Copyright (C) 2005-2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") 3258945Sroberto * 4258945Sroberto * Permission to use, copy, modify, and/or distribute this software for any 5258945Sroberto * purpose with or without fee is hereby granted, provided that the above 6258945Sroberto * copyright notice and this permission notice appear in all copies. 7258945Sroberto * 8258945Sroberto * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 9258945Sroberto * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10258945Sroberto * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 11258945Sroberto * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12258945Sroberto * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 13258945Sroberto * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14258945Sroberto * PERFORMANCE OF THIS SOFTWARE. 15258945Sroberto */ 16258945Sroberto 17280849Scy/* $Id$ */ 18258945Sroberto 19258945Sroberto/* 20258945Sroberto * This code implements the HMAC-SHA1, HMAC-SHA224, HMAC-SHA256, HMAC-SHA384 21258945Sroberto * and HMAC-SHA512 keyed hash algorithm described in RFC 2104 and 22258945Sroberto * draft-ietf-dnsext-tsig-sha-01.txt. 23258945Sroberto */ 24258945Sroberto 25258945Sroberto#include "config.h" 26258945Sroberto 27258945Sroberto#include <isc/assertions.h> 28258945Sroberto#include <isc/hmacsha.h> 29280849Scy#include <isc/platform.h> 30258945Sroberto#include <isc/sha1.h> 31258945Sroberto#include <isc/sha2.h> 32258945Sroberto#include <isc/string.h> 33258945Sroberto#include <isc/types.h> 34258945Sroberto#include <isc/util.h> 35258945Sroberto 36280849Scy#ifdef ISC_PLATFORM_OPENSSLHASH 37280849Scy 38280849Scyvoid 39280849Scyisc_hmacsha1_init(isc_hmacsha1_t *ctx, const unsigned char *key, 40280849Scy unsigned int len) 41280849Scy{ 42280849Scy HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha1()); 43280849Scy} 44280849Scy 45280849Scyvoid 46280849Scyisc_hmacsha1_invalidate(isc_hmacsha1_t *ctx) { 47280849Scy HMAC_CTX_cleanup(ctx); 48280849Scy} 49280849Scy 50280849Scyvoid 51280849Scyisc_hmacsha1_update(isc_hmacsha1_t *ctx, const unsigned char *buf, 52280849Scy unsigned int len) 53280849Scy{ 54280849Scy HMAC_Update(ctx, buf, (int) len); 55280849Scy} 56280849Scy 57280849Scyvoid 58280849Scyisc_hmacsha1_sign(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) { 59280849Scy unsigned char newdigest[ISC_SHA1_DIGESTLENGTH]; 60280849Scy 61280849Scy REQUIRE(len <= ISC_SHA1_DIGESTLENGTH); 62280849Scy 63280849Scy HMAC_Final(ctx, newdigest, NULL); 64280849Scy HMAC_CTX_cleanup(ctx); 65280849Scy memcpy(digest, newdigest, len); 66280849Scy memset(newdigest, 0, sizeof(newdigest)); 67280849Scy} 68280849Scy 69280849Scyvoid 70280849Scyisc_hmacsha224_init(isc_hmacsha224_t *ctx, const unsigned char *key, 71280849Scy unsigned int len) 72280849Scy{ 73280849Scy HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha224()); 74280849Scy} 75280849Scy 76280849Scyvoid 77280849Scyisc_hmacsha224_invalidate(isc_hmacsha224_t *ctx) { 78280849Scy HMAC_CTX_cleanup(ctx); 79280849Scy} 80280849Scy 81280849Scyvoid 82280849Scyisc_hmacsha224_update(isc_hmacsha224_t *ctx, const unsigned char *buf, 83280849Scy unsigned int len) 84280849Scy{ 85280849Scy HMAC_Update(ctx, buf, (int) len); 86280849Scy} 87280849Scy 88280849Scyvoid 89280849Scyisc_hmacsha224_sign(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) { 90280849Scy unsigned char newdigest[ISC_SHA224_DIGESTLENGTH]; 91280849Scy 92280849Scy REQUIRE(len <= ISC_SHA224_DIGESTLENGTH); 93280849Scy 94280849Scy HMAC_Final(ctx, newdigest, NULL); 95280849Scy HMAC_CTX_cleanup(ctx); 96280849Scy memcpy(digest, newdigest, len); 97280849Scy memset(newdigest, 0, sizeof(newdigest)); 98280849Scy} 99280849Scy 100280849Scyvoid 101280849Scyisc_hmacsha256_init(isc_hmacsha256_t *ctx, const unsigned char *key, 102280849Scy unsigned int len) 103280849Scy{ 104280849Scy HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha256()); 105280849Scy} 106280849Scy 107280849Scyvoid 108280849Scyisc_hmacsha256_invalidate(isc_hmacsha256_t *ctx) { 109280849Scy HMAC_CTX_cleanup(ctx); 110280849Scy} 111280849Scy 112280849Scyvoid 113280849Scyisc_hmacsha256_update(isc_hmacsha256_t *ctx, const unsigned char *buf, 114280849Scy unsigned int len) 115280849Scy{ 116280849Scy HMAC_Update(ctx, buf, (int) len); 117280849Scy} 118280849Scy 119280849Scyvoid 120280849Scyisc_hmacsha256_sign(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) { 121280849Scy unsigned char newdigest[ISC_SHA256_DIGESTLENGTH]; 122280849Scy 123280849Scy REQUIRE(len <= ISC_SHA256_DIGESTLENGTH); 124280849Scy 125280849Scy HMAC_Final(ctx, newdigest, NULL); 126280849Scy HMAC_CTX_cleanup(ctx); 127280849Scy memcpy(digest, newdigest, len); 128280849Scy memset(newdigest, 0, sizeof(newdigest)); 129280849Scy} 130280849Scy 131280849Scyvoid 132280849Scyisc_hmacsha384_init(isc_hmacsha384_t *ctx, const unsigned char *key, 133280849Scy unsigned int len) 134280849Scy{ 135280849Scy HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha384()); 136280849Scy} 137280849Scy 138280849Scyvoid 139280849Scyisc_hmacsha384_invalidate(isc_hmacsha384_t *ctx) { 140280849Scy HMAC_CTX_cleanup(ctx); 141280849Scy} 142280849Scy 143280849Scyvoid 144280849Scyisc_hmacsha384_update(isc_hmacsha384_t *ctx, const unsigned char *buf, 145280849Scy unsigned int len) 146280849Scy{ 147280849Scy HMAC_Update(ctx, buf, (int) len); 148280849Scy} 149280849Scy 150280849Scyvoid 151280849Scyisc_hmacsha384_sign(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) { 152280849Scy unsigned char newdigest[ISC_SHA384_DIGESTLENGTH]; 153280849Scy 154280849Scy REQUIRE(len <= ISC_SHA384_DIGESTLENGTH); 155280849Scy 156280849Scy HMAC_Final(ctx, newdigest, NULL); 157280849Scy HMAC_CTX_cleanup(ctx); 158280849Scy memcpy(digest, newdigest, len); 159280849Scy memset(newdigest, 0, sizeof(newdigest)); 160280849Scy} 161280849Scy 162280849Scyvoid 163280849Scyisc_hmacsha512_init(isc_hmacsha512_t *ctx, const unsigned char *key, 164280849Scy unsigned int len) 165280849Scy{ 166280849Scy HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha512()); 167280849Scy} 168280849Scy 169280849Scyvoid 170280849Scyisc_hmacsha512_invalidate(isc_hmacsha512_t *ctx) { 171280849Scy HMAC_CTX_cleanup(ctx); 172280849Scy} 173280849Scy 174280849Scyvoid 175280849Scyisc_hmacsha512_update(isc_hmacsha512_t *ctx, const unsigned char *buf, 176280849Scy unsigned int len) 177280849Scy{ 178280849Scy HMAC_Update(ctx, buf, (int) len); 179280849Scy} 180280849Scy 181280849Scyvoid 182280849Scyisc_hmacsha512_sign(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) { 183280849Scy unsigned char newdigest[ISC_SHA512_DIGESTLENGTH]; 184280849Scy 185280849Scy REQUIRE(len <= ISC_SHA512_DIGESTLENGTH); 186280849Scy 187280849Scy HMAC_Final(ctx, newdigest, NULL); 188280849Scy HMAC_CTX_cleanup(ctx); 189280849Scy memcpy(digest, newdigest, len); 190280849Scy memset(newdigest, 0, sizeof(newdigest)); 191280849Scy} 192280849Scy 193280849Scy#else 194280849Scy 195258945Sroberto#define IPAD 0x36 196258945Sroberto#define OPAD 0x5C 197258945Sroberto 198258945Sroberto/* 199258945Sroberto * Start HMAC-SHA1 process. Initialize an sha1 context and digest the key. 200258945Sroberto */ 201258945Srobertovoid 202258945Srobertoisc_hmacsha1_init(isc_hmacsha1_t *ctx, const unsigned char *key, 203258945Sroberto unsigned int len) 204258945Sroberto{ 205258945Sroberto unsigned char ipad[ISC_SHA1_BLOCK_LENGTH]; 206258945Sroberto unsigned int i; 207258945Sroberto 208258945Sroberto memset(ctx->key, 0, sizeof(ctx->key)); 209258945Sroberto if (len > sizeof(ctx->key)) { 210258945Sroberto isc_sha1_t sha1ctx; 211258945Sroberto isc_sha1_init(&sha1ctx); 212258945Sroberto isc_sha1_update(&sha1ctx, key, len); 213258945Sroberto isc_sha1_final(&sha1ctx, ctx->key); 214258945Sroberto } else 215258945Sroberto memcpy(ctx->key, key, len); 216258945Sroberto 217258945Sroberto isc_sha1_init(&ctx->sha1ctx); 218258945Sroberto memset(ipad, IPAD, sizeof(ipad)); 219258945Sroberto for (i = 0; i < ISC_SHA1_BLOCK_LENGTH; i++) 220258945Sroberto ipad[i] ^= ctx->key[i]; 221258945Sroberto isc_sha1_update(&ctx->sha1ctx, ipad, sizeof(ipad)); 222258945Sroberto} 223258945Sroberto 224258945Srobertovoid 225258945Srobertoisc_hmacsha1_invalidate(isc_hmacsha1_t *ctx) { 226258945Sroberto isc_sha1_invalidate(&ctx->sha1ctx); 227280849Scy memset(ctx, 0, sizeof(*ctx)); 228258945Sroberto} 229258945Sroberto 230258945Sroberto/* 231258945Sroberto * Update context to reflect the concatenation of another buffer full 232258945Sroberto * of bytes. 233258945Sroberto */ 234258945Srobertovoid 235258945Srobertoisc_hmacsha1_update(isc_hmacsha1_t *ctx, const unsigned char *buf, 236258945Sroberto unsigned int len) 237258945Sroberto{ 238258945Sroberto isc_sha1_update(&ctx->sha1ctx, buf, len); 239258945Sroberto} 240258945Sroberto 241258945Sroberto/* 242258945Sroberto * Compute signature - finalize SHA1 operation and reapply SHA1. 243258945Sroberto */ 244258945Srobertovoid 245258945Srobertoisc_hmacsha1_sign(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) { 246258945Sroberto unsigned char opad[ISC_SHA1_BLOCK_LENGTH]; 247258945Sroberto unsigned char newdigest[ISC_SHA1_DIGESTLENGTH]; 248258945Sroberto unsigned int i; 249258945Sroberto 250258945Sroberto REQUIRE(len <= ISC_SHA1_DIGESTLENGTH); 251258945Sroberto isc_sha1_final(&ctx->sha1ctx, newdigest); 252258945Sroberto 253258945Sroberto memset(opad, OPAD, sizeof(opad)); 254258945Sroberto for (i = 0; i < ISC_SHA1_BLOCK_LENGTH; i++) 255258945Sroberto opad[i] ^= ctx->key[i]; 256258945Sroberto 257258945Sroberto isc_sha1_init(&ctx->sha1ctx); 258258945Sroberto isc_sha1_update(&ctx->sha1ctx, opad, sizeof(opad)); 259258945Sroberto isc_sha1_update(&ctx->sha1ctx, newdigest, ISC_SHA1_DIGESTLENGTH); 260258945Sroberto isc_sha1_final(&ctx->sha1ctx, newdigest); 261258945Sroberto isc_hmacsha1_invalidate(ctx); 262258945Sroberto memcpy(digest, newdigest, len); 263258945Sroberto memset(newdigest, 0, sizeof(newdigest)); 264258945Sroberto} 265258945Sroberto 266258945Sroberto/* 267258945Sroberto * Start HMAC-SHA224 process. Initialize an sha224 context and digest the key. 268258945Sroberto */ 269258945Srobertovoid 270258945Srobertoisc_hmacsha224_init(isc_hmacsha224_t *ctx, const unsigned char *key, 271258945Sroberto unsigned int len) 272258945Sroberto{ 273258945Sroberto unsigned char ipad[ISC_SHA224_BLOCK_LENGTH]; 274258945Sroberto unsigned int i; 275258945Sroberto 276258945Sroberto memset(ctx->key, 0, sizeof(ctx->key)); 277258945Sroberto if (len > sizeof(ctx->key)) { 278258945Sroberto isc_sha224_t sha224ctx; 279258945Sroberto isc_sha224_init(&sha224ctx); 280258945Sroberto isc_sha224_update(&sha224ctx, key, len); 281258945Sroberto isc_sha224_final(ctx->key, &sha224ctx); 282258945Sroberto } else 283258945Sroberto memcpy(ctx->key, key, len); 284258945Sroberto 285258945Sroberto isc_sha224_init(&ctx->sha224ctx); 286258945Sroberto memset(ipad, IPAD, sizeof(ipad)); 287258945Sroberto for (i = 0; i < ISC_SHA224_BLOCK_LENGTH; i++) 288258945Sroberto ipad[i] ^= ctx->key[i]; 289258945Sroberto isc_sha224_update(&ctx->sha224ctx, ipad, sizeof(ipad)); 290258945Sroberto} 291258945Sroberto 292258945Srobertovoid 293258945Srobertoisc_hmacsha224_invalidate(isc_hmacsha224_t *ctx) { 294280849Scy memset(ctx, 0, sizeof(*ctx)); 295258945Sroberto} 296258945Sroberto 297258945Sroberto/* 298258945Sroberto * Update context to reflect the concatenation of another buffer full 299258945Sroberto * of bytes. 300258945Sroberto */ 301258945Srobertovoid 302258945Srobertoisc_hmacsha224_update(isc_hmacsha224_t *ctx, const unsigned char *buf, 303258945Sroberto unsigned int len) 304258945Sroberto{ 305258945Sroberto isc_sha224_update(&ctx->sha224ctx, buf, len); 306258945Sroberto} 307258945Sroberto 308258945Sroberto/* 309258945Sroberto * Compute signature - finalize SHA224 operation and reapply SHA224. 310258945Sroberto */ 311258945Srobertovoid 312258945Srobertoisc_hmacsha224_sign(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) { 313258945Sroberto unsigned char opad[ISC_SHA224_BLOCK_LENGTH]; 314258945Sroberto unsigned char newdigest[ISC_SHA224_DIGESTLENGTH]; 315258945Sroberto unsigned int i; 316258945Sroberto 317258945Sroberto REQUIRE(len <= ISC_SHA224_DIGESTLENGTH); 318258945Sroberto isc_sha224_final(newdigest, &ctx->sha224ctx); 319258945Sroberto 320258945Sroberto memset(opad, OPAD, sizeof(opad)); 321258945Sroberto for (i = 0; i < ISC_SHA224_BLOCK_LENGTH; i++) 322258945Sroberto opad[i] ^= ctx->key[i]; 323258945Sroberto 324258945Sroberto isc_sha224_init(&ctx->sha224ctx); 325258945Sroberto isc_sha224_update(&ctx->sha224ctx, opad, sizeof(opad)); 326258945Sroberto isc_sha224_update(&ctx->sha224ctx, newdigest, ISC_SHA224_DIGESTLENGTH); 327258945Sroberto isc_sha224_final(newdigest, &ctx->sha224ctx); 328258945Sroberto memcpy(digest, newdigest, len); 329258945Sroberto memset(newdigest, 0, sizeof(newdigest)); 330258945Sroberto} 331258945Sroberto 332258945Sroberto/* 333258945Sroberto * Start HMAC-SHA256 process. Initialize an sha256 context and digest the key. 334258945Sroberto */ 335258945Srobertovoid 336258945Srobertoisc_hmacsha256_init(isc_hmacsha256_t *ctx, const unsigned char *key, 337258945Sroberto unsigned int len) 338258945Sroberto{ 339258945Sroberto unsigned char ipad[ISC_SHA256_BLOCK_LENGTH]; 340258945Sroberto unsigned int i; 341258945Sroberto 342258945Sroberto memset(ctx->key, 0, sizeof(ctx->key)); 343258945Sroberto if (len > sizeof(ctx->key)) { 344258945Sroberto isc_sha256_t sha256ctx; 345258945Sroberto isc_sha256_init(&sha256ctx); 346258945Sroberto isc_sha256_update(&sha256ctx, key, len); 347258945Sroberto isc_sha256_final(ctx->key, &sha256ctx); 348258945Sroberto } else 349258945Sroberto memcpy(ctx->key, key, len); 350258945Sroberto 351258945Sroberto isc_sha256_init(&ctx->sha256ctx); 352258945Sroberto memset(ipad, IPAD, sizeof(ipad)); 353258945Sroberto for (i = 0; i < ISC_SHA256_BLOCK_LENGTH; i++) 354258945Sroberto ipad[i] ^= ctx->key[i]; 355258945Sroberto isc_sha256_update(&ctx->sha256ctx, ipad, sizeof(ipad)); 356258945Sroberto} 357258945Sroberto 358258945Srobertovoid 359258945Srobertoisc_hmacsha256_invalidate(isc_hmacsha256_t *ctx) { 360280849Scy memset(ctx, 0, sizeof(*ctx)); 361258945Sroberto} 362258945Sroberto 363258945Sroberto/* 364258945Sroberto * Update context to reflect the concatenation of another buffer full 365258945Sroberto * of bytes. 366258945Sroberto */ 367258945Srobertovoid 368258945Srobertoisc_hmacsha256_update(isc_hmacsha256_t *ctx, const unsigned char *buf, 369258945Sroberto unsigned int len) 370258945Sroberto{ 371258945Sroberto isc_sha256_update(&ctx->sha256ctx, buf, len); 372258945Sroberto} 373258945Sroberto 374258945Sroberto/* 375258945Sroberto * Compute signature - finalize SHA256 operation and reapply SHA256. 376258945Sroberto */ 377258945Srobertovoid 378258945Srobertoisc_hmacsha256_sign(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) { 379258945Sroberto unsigned char opad[ISC_SHA256_BLOCK_LENGTH]; 380258945Sroberto unsigned char newdigest[ISC_SHA256_DIGESTLENGTH]; 381258945Sroberto unsigned int i; 382258945Sroberto 383258945Sroberto REQUIRE(len <= ISC_SHA256_DIGESTLENGTH); 384258945Sroberto isc_sha256_final(newdigest, &ctx->sha256ctx); 385258945Sroberto 386258945Sroberto memset(opad, OPAD, sizeof(opad)); 387258945Sroberto for (i = 0; i < ISC_SHA256_BLOCK_LENGTH; i++) 388258945Sroberto opad[i] ^= ctx->key[i]; 389258945Sroberto 390258945Sroberto isc_sha256_init(&ctx->sha256ctx); 391258945Sroberto isc_sha256_update(&ctx->sha256ctx, opad, sizeof(opad)); 392258945Sroberto isc_sha256_update(&ctx->sha256ctx, newdigest, ISC_SHA256_DIGESTLENGTH); 393258945Sroberto isc_sha256_final(newdigest, &ctx->sha256ctx); 394258945Sroberto memcpy(digest, newdigest, len); 395258945Sroberto memset(newdigest, 0, sizeof(newdigest)); 396258945Sroberto} 397258945Sroberto 398258945Sroberto/* 399258945Sroberto * Start HMAC-SHA384 process. Initialize an sha384 context and digest the key. 400258945Sroberto */ 401258945Srobertovoid 402258945Srobertoisc_hmacsha384_init(isc_hmacsha384_t *ctx, const unsigned char *key, 403258945Sroberto unsigned int len) 404258945Sroberto{ 405258945Sroberto unsigned char ipad[ISC_SHA384_BLOCK_LENGTH]; 406258945Sroberto unsigned int i; 407258945Sroberto 408258945Sroberto memset(ctx->key, 0, sizeof(ctx->key)); 409258945Sroberto if (len > sizeof(ctx->key)) { 410258945Sroberto isc_sha384_t sha384ctx; 411258945Sroberto isc_sha384_init(&sha384ctx); 412258945Sroberto isc_sha384_update(&sha384ctx, key, len); 413258945Sroberto isc_sha384_final(ctx->key, &sha384ctx); 414258945Sroberto } else 415258945Sroberto memcpy(ctx->key, key, len); 416258945Sroberto 417258945Sroberto isc_sha384_init(&ctx->sha384ctx); 418258945Sroberto memset(ipad, IPAD, sizeof(ipad)); 419258945Sroberto for (i = 0; i < ISC_SHA384_BLOCK_LENGTH; i++) 420258945Sroberto ipad[i] ^= ctx->key[i]; 421258945Sroberto isc_sha384_update(&ctx->sha384ctx, ipad, sizeof(ipad)); 422258945Sroberto} 423258945Sroberto 424258945Srobertovoid 425258945Srobertoisc_hmacsha384_invalidate(isc_hmacsha384_t *ctx) { 426280849Scy memset(ctx, 0, sizeof(*ctx)); 427258945Sroberto} 428258945Sroberto 429258945Sroberto/* 430258945Sroberto * Update context to reflect the concatenation of another buffer full 431258945Sroberto * of bytes. 432258945Sroberto */ 433258945Srobertovoid 434258945Srobertoisc_hmacsha384_update(isc_hmacsha384_t *ctx, const unsigned char *buf, 435258945Sroberto unsigned int len) 436258945Sroberto{ 437258945Sroberto isc_sha384_update(&ctx->sha384ctx, buf, len); 438258945Sroberto} 439258945Sroberto 440258945Sroberto/* 441258945Sroberto * Compute signature - finalize SHA384 operation and reapply SHA384. 442258945Sroberto */ 443258945Srobertovoid 444258945Srobertoisc_hmacsha384_sign(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) { 445258945Sroberto unsigned char opad[ISC_SHA384_BLOCK_LENGTH]; 446258945Sroberto unsigned char newdigest[ISC_SHA384_DIGESTLENGTH]; 447258945Sroberto unsigned int i; 448258945Sroberto 449258945Sroberto REQUIRE(len <= ISC_SHA384_DIGESTLENGTH); 450258945Sroberto isc_sha384_final(newdigest, &ctx->sha384ctx); 451258945Sroberto 452258945Sroberto memset(opad, OPAD, sizeof(opad)); 453258945Sroberto for (i = 0; i < ISC_SHA384_BLOCK_LENGTH; i++) 454258945Sroberto opad[i] ^= ctx->key[i]; 455258945Sroberto 456258945Sroberto isc_sha384_init(&ctx->sha384ctx); 457258945Sroberto isc_sha384_update(&ctx->sha384ctx, opad, sizeof(opad)); 458258945Sroberto isc_sha384_update(&ctx->sha384ctx, newdigest, ISC_SHA384_DIGESTLENGTH); 459258945Sroberto isc_sha384_final(newdigest, &ctx->sha384ctx); 460258945Sroberto memcpy(digest, newdigest, len); 461258945Sroberto memset(newdigest, 0, sizeof(newdigest)); 462258945Sroberto} 463258945Sroberto 464258945Sroberto/* 465258945Sroberto * Start HMAC-SHA512 process. Initialize an sha512 context and digest the key. 466258945Sroberto */ 467258945Srobertovoid 468258945Srobertoisc_hmacsha512_init(isc_hmacsha512_t *ctx, const unsigned char *key, 469258945Sroberto unsigned int len) 470258945Sroberto{ 471258945Sroberto unsigned char ipad[ISC_SHA512_BLOCK_LENGTH]; 472258945Sroberto unsigned int i; 473258945Sroberto 474258945Sroberto memset(ctx->key, 0, sizeof(ctx->key)); 475258945Sroberto if (len > sizeof(ctx->key)) { 476258945Sroberto isc_sha512_t sha512ctx; 477258945Sroberto isc_sha512_init(&sha512ctx); 478258945Sroberto isc_sha512_update(&sha512ctx, key, len); 479258945Sroberto isc_sha512_final(ctx->key, &sha512ctx); 480258945Sroberto } else 481258945Sroberto memcpy(ctx->key, key, len); 482258945Sroberto 483258945Sroberto isc_sha512_init(&ctx->sha512ctx); 484258945Sroberto memset(ipad, IPAD, sizeof(ipad)); 485258945Sroberto for (i = 0; i < ISC_SHA512_BLOCK_LENGTH; i++) 486258945Sroberto ipad[i] ^= ctx->key[i]; 487258945Sroberto isc_sha512_update(&ctx->sha512ctx, ipad, sizeof(ipad)); 488258945Sroberto} 489258945Sroberto 490258945Srobertovoid 491258945Srobertoisc_hmacsha512_invalidate(isc_hmacsha512_t *ctx) { 492280849Scy memset(ctx, 0, sizeof(*ctx)); 493258945Sroberto} 494258945Sroberto 495258945Sroberto/* 496258945Sroberto * Update context to reflect the concatenation of another buffer full 497258945Sroberto * of bytes. 498258945Sroberto */ 499258945Srobertovoid 500258945Srobertoisc_hmacsha512_update(isc_hmacsha512_t *ctx, const unsigned char *buf, 501258945Sroberto unsigned int len) 502258945Sroberto{ 503258945Sroberto isc_sha512_update(&ctx->sha512ctx, buf, len); 504258945Sroberto} 505258945Sroberto 506258945Sroberto/* 507258945Sroberto * Compute signature - finalize SHA512 operation and reapply SHA512. 508258945Sroberto */ 509258945Srobertovoid 510258945Srobertoisc_hmacsha512_sign(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) { 511258945Sroberto unsigned char opad[ISC_SHA512_BLOCK_LENGTH]; 512258945Sroberto unsigned char newdigest[ISC_SHA512_DIGESTLENGTH]; 513258945Sroberto unsigned int i; 514258945Sroberto 515258945Sroberto REQUIRE(len <= ISC_SHA512_DIGESTLENGTH); 516258945Sroberto isc_sha512_final(newdigest, &ctx->sha512ctx); 517258945Sroberto 518258945Sroberto memset(opad, OPAD, sizeof(opad)); 519258945Sroberto for (i = 0; i < ISC_SHA512_BLOCK_LENGTH; i++) 520258945Sroberto opad[i] ^= ctx->key[i]; 521258945Sroberto 522258945Sroberto isc_sha512_init(&ctx->sha512ctx); 523258945Sroberto isc_sha512_update(&ctx->sha512ctx, opad, sizeof(opad)); 524258945Sroberto isc_sha512_update(&ctx->sha512ctx, newdigest, ISC_SHA512_DIGESTLENGTH); 525258945Sroberto isc_sha512_final(newdigest, &ctx->sha512ctx); 526258945Sroberto memcpy(digest, newdigest, len); 527258945Sroberto memset(newdigest, 0, sizeof(newdigest)); 528258945Sroberto} 529280849Scy#endif /* !ISC_PLATFORM_OPENSSLHASH */ 530258945Sroberto 531258945Sroberto/* 532280849Scy * Verify signature - finalize SHA1 operation and reapply SHA1, then 533280849Scy * compare to the supplied digest. 534280849Scy */ 535280849Scyisc_boolean_t 536280849Scyisc_hmacsha1_verify(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) { 537280849Scy unsigned char newdigest[ISC_SHA1_DIGESTLENGTH]; 538280849Scy 539280849Scy REQUIRE(len <= ISC_SHA1_DIGESTLENGTH); 540280849Scy isc_hmacsha1_sign(ctx, newdigest, ISC_SHA1_DIGESTLENGTH); 541298695Sdelphij return (ISC_TF(isc_tsmemcmp(digest, newdigest, len) == 0)); 542280849Scy} 543280849Scy 544280849Scy/* 545280849Scy * Verify signature - finalize SHA224 operation and reapply SHA224, then 546280849Scy * compare to the supplied digest. 547280849Scy */ 548280849Scyisc_boolean_t 549280849Scyisc_hmacsha224_verify(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) { 550280849Scy unsigned char newdigest[ISC_SHA224_DIGESTLENGTH]; 551280849Scy 552280849Scy REQUIRE(len <= ISC_SHA224_DIGESTLENGTH); 553280849Scy isc_hmacsha224_sign(ctx, newdigest, ISC_SHA224_DIGESTLENGTH); 554298695Sdelphij return (ISC_TF(isc_tsmemcmp(digest, newdigest, len) == 0)); 555280849Scy} 556280849Scy 557280849Scy/* 558280849Scy * Verify signature - finalize SHA256 operation and reapply SHA256, then 559280849Scy * compare to the supplied digest. 560280849Scy */ 561280849Scyisc_boolean_t 562280849Scyisc_hmacsha256_verify(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) { 563280849Scy unsigned char newdigest[ISC_SHA256_DIGESTLENGTH]; 564280849Scy 565280849Scy REQUIRE(len <= ISC_SHA256_DIGESTLENGTH); 566280849Scy isc_hmacsha256_sign(ctx, newdigest, ISC_SHA256_DIGESTLENGTH); 567298695Sdelphij return (ISC_TF(isc_tsmemcmp(digest, newdigest, len) == 0)); 568280849Scy} 569280849Scy 570280849Scy/* 571280849Scy * Verify signature - finalize SHA384 operation and reapply SHA384, then 572280849Scy * compare to the supplied digest. 573280849Scy */ 574280849Scyisc_boolean_t 575280849Scyisc_hmacsha384_verify(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) { 576280849Scy unsigned char newdigest[ISC_SHA384_DIGESTLENGTH]; 577280849Scy 578280849Scy REQUIRE(len <= ISC_SHA384_DIGESTLENGTH); 579280849Scy isc_hmacsha384_sign(ctx, newdigest, ISC_SHA384_DIGESTLENGTH); 580298695Sdelphij return (ISC_TF(isc_tsmemcmp(digest, newdigest, len) == 0)); 581280849Scy} 582280849Scy 583280849Scy/* 584258945Sroberto * Verify signature - finalize SHA512 operation and reapply SHA512, then 585258945Sroberto * compare to the supplied digest. 586258945Sroberto */ 587258945Srobertoisc_boolean_t 588258945Srobertoisc_hmacsha512_verify(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) { 589258945Sroberto unsigned char newdigest[ISC_SHA512_DIGESTLENGTH]; 590258945Sroberto 591258945Sroberto REQUIRE(len <= ISC_SHA512_DIGESTLENGTH); 592258945Sroberto isc_hmacsha512_sign(ctx, newdigest, ISC_SHA512_DIGESTLENGTH); 593298695Sdelphij return (ISC_TF(isc_tsmemcmp(digest, newdigest, len) == 0)); 594258945Sroberto} 595