hmacsha.c revision 258945
1258945Sroberto/* 2258945Sroberto * Copyright (C) 2005-2007 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 17258945Sroberto/* $Id: hmacsha.c,v 1.8 2007/08/27 03:27:53 marka Exp $ */ 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> 29258945Sroberto#include <isc/sha1.h> 30258945Sroberto#include <isc/sha2.h> 31258945Sroberto#include <isc/string.h> 32258945Sroberto#include <isc/types.h> 33258945Sroberto#include <isc/util.h> 34258945Sroberto 35258945Sroberto#define IPAD 0x36 36258945Sroberto#define OPAD 0x5C 37258945Sroberto 38258945Sroberto/* 39258945Sroberto * Start HMAC-SHA1 process. Initialize an sha1 context and digest the key. 40258945Sroberto */ 41258945Srobertovoid 42258945Srobertoisc_hmacsha1_init(isc_hmacsha1_t *ctx, const unsigned char *key, 43258945Sroberto unsigned int len) 44258945Sroberto{ 45258945Sroberto unsigned char ipad[ISC_SHA1_BLOCK_LENGTH]; 46258945Sroberto unsigned int i; 47258945Sroberto 48258945Sroberto memset(ctx->key, 0, sizeof(ctx->key)); 49258945Sroberto if (len > sizeof(ctx->key)) { 50258945Sroberto isc_sha1_t sha1ctx; 51258945Sroberto isc_sha1_init(&sha1ctx); 52258945Sroberto isc_sha1_update(&sha1ctx, key, len); 53258945Sroberto isc_sha1_final(&sha1ctx, ctx->key); 54258945Sroberto } else 55258945Sroberto memcpy(ctx->key, key, len); 56258945Sroberto 57258945Sroberto isc_sha1_init(&ctx->sha1ctx); 58258945Sroberto memset(ipad, IPAD, sizeof(ipad)); 59258945Sroberto for (i = 0; i < ISC_SHA1_BLOCK_LENGTH; i++) 60258945Sroberto ipad[i] ^= ctx->key[i]; 61258945Sroberto isc_sha1_update(&ctx->sha1ctx, ipad, sizeof(ipad)); 62258945Sroberto} 63258945Sroberto 64258945Srobertovoid 65258945Srobertoisc_hmacsha1_invalidate(isc_hmacsha1_t *ctx) { 66258945Sroberto isc_sha1_invalidate(&ctx->sha1ctx); 67258945Sroberto memset(ctx->key, 0, sizeof(ctx->key)); 68258945Sroberto memset(ctx, 0, sizeof(ctx)); 69258945Sroberto} 70258945Sroberto 71258945Sroberto/* 72258945Sroberto * Update context to reflect the concatenation of another buffer full 73258945Sroberto * of bytes. 74258945Sroberto */ 75258945Srobertovoid 76258945Srobertoisc_hmacsha1_update(isc_hmacsha1_t *ctx, const unsigned char *buf, 77258945Sroberto unsigned int len) 78258945Sroberto{ 79258945Sroberto isc_sha1_update(&ctx->sha1ctx, buf, len); 80258945Sroberto} 81258945Sroberto 82258945Sroberto/* 83258945Sroberto * Compute signature - finalize SHA1 operation and reapply SHA1. 84258945Sroberto */ 85258945Srobertovoid 86258945Srobertoisc_hmacsha1_sign(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) { 87258945Sroberto unsigned char opad[ISC_SHA1_BLOCK_LENGTH]; 88258945Sroberto unsigned char newdigest[ISC_SHA1_DIGESTLENGTH]; 89258945Sroberto unsigned int i; 90258945Sroberto 91258945Sroberto REQUIRE(len <= ISC_SHA1_DIGESTLENGTH); 92258945Sroberto isc_sha1_final(&ctx->sha1ctx, newdigest); 93258945Sroberto 94258945Sroberto memset(opad, OPAD, sizeof(opad)); 95258945Sroberto for (i = 0; i < ISC_SHA1_BLOCK_LENGTH; i++) 96258945Sroberto opad[i] ^= ctx->key[i]; 97258945Sroberto 98258945Sroberto isc_sha1_init(&ctx->sha1ctx); 99258945Sroberto isc_sha1_update(&ctx->sha1ctx, opad, sizeof(opad)); 100258945Sroberto isc_sha1_update(&ctx->sha1ctx, newdigest, ISC_SHA1_DIGESTLENGTH); 101258945Sroberto isc_sha1_final(&ctx->sha1ctx, newdigest); 102258945Sroberto isc_hmacsha1_invalidate(ctx); 103258945Sroberto memcpy(digest, newdigest, len); 104258945Sroberto memset(newdigest, 0, sizeof(newdigest)); 105258945Sroberto} 106258945Sroberto 107258945Sroberto/* 108258945Sroberto * Verify signature - finalize SHA1 operation and reapply SHA1, then 109258945Sroberto * compare to the supplied digest. 110258945Sroberto */ 111258945Srobertoisc_boolean_t 112258945Srobertoisc_hmacsha1_verify(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) { 113258945Sroberto unsigned char newdigest[ISC_SHA1_DIGESTLENGTH]; 114258945Sroberto 115258945Sroberto REQUIRE(len <= ISC_SHA1_DIGESTLENGTH); 116258945Sroberto isc_hmacsha1_sign(ctx, newdigest, ISC_SHA1_DIGESTLENGTH); 117258945Sroberto return (ISC_TF(memcmp(digest, newdigest, len) == 0)); 118258945Sroberto} 119258945Sroberto 120258945Sroberto/* 121258945Sroberto * Start HMAC-SHA224 process. Initialize an sha224 context and digest the key. 122258945Sroberto */ 123258945Srobertovoid 124258945Srobertoisc_hmacsha224_init(isc_hmacsha224_t *ctx, const unsigned char *key, 125258945Sroberto unsigned int len) 126258945Sroberto{ 127258945Sroberto unsigned char ipad[ISC_SHA224_BLOCK_LENGTH]; 128258945Sroberto unsigned int i; 129258945Sroberto 130258945Sroberto memset(ctx->key, 0, sizeof(ctx->key)); 131258945Sroberto if (len > sizeof(ctx->key)) { 132258945Sroberto isc_sha224_t sha224ctx; 133258945Sroberto isc_sha224_init(&sha224ctx); 134258945Sroberto isc_sha224_update(&sha224ctx, key, len); 135258945Sroberto isc_sha224_final(ctx->key, &sha224ctx); 136258945Sroberto } else 137258945Sroberto memcpy(ctx->key, key, len); 138258945Sroberto 139258945Sroberto isc_sha224_init(&ctx->sha224ctx); 140258945Sroberto memset(ipad, IPAD, sizeof(ipad)); 141258945Sroberto for (i = 0; i < ISC_SHA224_BLOCK_LENGTH; i++) 142258945Sroberto ipad[i] ^= ctx->key[i]; 143258945Sroberto isc_sha224_update(&ctx->sha224ctx, ipad, sizeof(ipad)); 144258945Sroberto} 145258945Sroberto 146258945Srobertovoid 147258945Srobertoisc_hmacsha224_invalidate(isc_hmacsha224_t *ctx) { 148258945Sroberto memset(ctx->key, 0, sizeof(ctx->key)); 149258945Sroberto memset(ctx, 0, sizeof(ctx)); 150258945Sroberto} 151258945Sroberto 152258945Sroberto/* 153258945Sroberto * Update context to reflect the concatenation of another buffer full 154258945Sroberto * of bytes. 155258945Sroberto */ 156258945Srobertovoid 157258945Srobertoisc_hmacsha224_update(isc_hmacsha224_t *ctx, const unsigned char *buf, 158258945Sroberto unsigned int len) 159258945Sroberto{ 160258945Sroberto isc_sha224_update(&ctx->sha224ctx, buf, len); 161258945Sroberto} 162258945Sroberto 163258945Sroberto/* 164258945Sroberto * Compute signature - finalize SHA224 operation and reapply SHA224. 165258945Sroberto */ 166258945Srobertovoid 167258945Srobertoisc_hmacsha224_sign(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) { 168258945Sroberto unsigned char opad[ISC_SHA224_BLOCK_LENGTH]; 169258945Sroberto unsigned char newdigest[ISC_SHA224_DIGESTLENGTH]; 170258945Sroberto unsigned int i; 171258945Sroberto 172258945Sroberto REQUIRE(len <= ISC_SHA224_DIGESTLENGTH); 173258945Sroberto isc_sha224_final(newdigest, &ctx->sha224ctx); 174258945Sroberto 175258945Sroberto memset(opad, OPAD, sizeof(opad)); 176258945Sroberto for (i = 0; i < ISC_SHA224_BLOCK_LENGTH; i++) 177258945Sroberto opad[i] ^= ctx->key[i]; 178258945Sroberto 179258945Sroberto isc_sha224_init(&ctx->sha224ctx); 180258945Sroberto isc_sha224_update(&ctx->sha224ctx, opad, sizeof(opad)); 181258945Sroberto isc_sha224_update(&ctx->sha224ctx, newdigest, ISC_SHA224_DIGESTLENGTH); 182258945Sroberto isc_sha224_final(newdigest, &ctx->sha224ctx); 183258945Sroberto memcpy(digest, newdigest, len); 184258945Sroberto memset(newdigest, 0, sizeof(newdigest)); 185258945Sroberto} 186258945Sroberto 187258945Sroberto/* 188258945Sroberto * Verify signature - finalize SHA224 operation and reapply SHA224, then 189258945Sroberto * compare to the supplied digest. 190258945Sroberto */ 191258945Srobertoisc_boolean_t 192258945Srobertoisc_hmacsha224_verify(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) { 193258945Sroberto unsigned char newdigest[ISC_SHA224_DIGESTLENGTH]; 194258945Sroberto 195258945Sroberto REQUIRE(len <= ISC_SHA224_DIGESTLENGTH); 196258945Sroberto isc_hmacsha224_sign(ctx, newdigest, ISC_SHA224_DIGESTLENGTH); 197258945Sroberto return (ISC_TF(memcmp(digest, newdigest, len) == 0)); 198258945Sroberto} 199258945Sroberto 200258945Sroberto/* 201258945Sroberto * Start HMAC-SHA256 process. Initialize an sha256 context and digest the key. 202258945Sroberto */ 203258945Srobertovoid 204258945Srobertoisc_hmacsha256_init(isc_hmacsha256_t *ctx, const unsigned char *key, 205258945Sroberto unsigned int len) 206258945Sroberto{ 207258945Sroberto unsigned char ipad[ISC_SHA256_BLOCK_LENGTH]; 208258945Sroberto unsigned int i; 209258945Sroberto 210258945Sroberto memset(ctx->key, 0, sizeof(ctx->key)); 211258945Sroberto if (len > sizeof(ctx->key)) { 212258945Sroberto isc_sha256_t sha256ctx; 213258945Sroberto isc_sha256_init(&sha256ctx); 214258945Sroberto isc_sha256_update(&sha256ctx, key, len); 215258945Sroberto isc_sha256_final(ctx->key, &sha256ctx); 216258945Sroberto } else 217258945Sroberto memcpy(ctx->key, key, len); 218258945Sroberto 219258945Sroberto isc_sha256_init(&ctx->sha256ctx); 220258945Sroberto memset(ipad, IPAD, sizeof(ipad)); 221258945Sroberto for (i = 0; i < ISC_SHA256_BLOCK_LENGTH; i++) 222258945Sroberto ipad[i] ^= ctx->key[i]; 223258945Sroberto isc_sha256_update(&ctx->sha256ctx, ipad, sizeof(ipad)); 224258945Sroberto} 225258945Sroberto 226258945Srobertovoid 227258945Srobertoisc_hmacsha256_invalidate(isc_hmacsha256_t *ctx) { 228258945Sroberto memset(ctx->key, 0, sizeof(ctx->key)); 229258945Sroberto memset(ctx, 0, sizeof(ctx)); 230258945Sroberto} 231258945Sroberto 232258945Sroberto/* 233258945Sroberto * Update context to reflect the concatenation of another buffer full 234258945Sroberto * of bytes. 235258945Sroberto */ 236258945Srobertovoid 237258945Srobertoisc_hmacsha256_update(isc_hmacsha256_t *ctx, const unsigned char *buf, 238258945Sroberto unsigned int len) 239258945Sroberto{ 240258945Sroberto isc_sha256_update(&ctx->sha256ctx, buf, len); 241258945Sroberto} 242258945Sroberto 243258945Sroberto/* 244258945Sroberto * Compute signature - finalize SHA256 operation and reapply SHA256. 245258945Sroberto */ 246258945Srobertovoid 247258945Srobertoisc_hmacsha256_sign(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) { 248258945Sroberto unsigned char opad[ISC_SHA256_BLOCK_LENGTH]; 249258945Sroberto unsigned char newdigest[ISC_SHA256_DIGESTLENGTH]; 250258945Sroberto unsigned int i; 251258945Sroberto 252258945Sroberto REQUIRE(len <= ISC_SHA256_DIGESTLENGTH); 253258945Sroberto isc_sha256_final(newdigest, &ctx->sha256ctx); 254258945Sroberto 255258945Sroberto memset(opad, OPAD, sizeof(opad)); 256258945Sroberto for (i = 0; i < ISC_SHA256_BLOCK_LENGTH; i++) 257258945Sroberto opad[i] ^= ctx->key[i]; 258258945Sroberto 259258945Sroberto isc_sha256_init(&ctx->sha256ctx); 260258945Sroberto isc_sha256_update(&ctx->sha256ctx, opad, sizeof(opad)); 261258945Sroberto isc_sha256_update(&ctx->sha256ctx, newdigest, ISC_SHA256_DIGESTLENGTH); 262258945Sroberto isc_sha256_final(newdigest, &ctx->sha256ctx); 263258945Sroberto memcpy(digest, newdigest, len); 264258945Sroberto memset(newdigest, 0, sizeof(newdigest)); 265258945Sroberto} 266258945Sroberto 267258945Sroberto/* 268258945Sroberto * Verify signature - finalize SHA256 operation and reapply SHA256, then 269258945Sroberto * compare to the supplied digest. 270258945Sroberto */ 271258945Srobertoisc_boolean_t 272258945Srobertoisc_hmacsha256_verify(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) { 273258945Sroberto unsigned char newdigest[ISC_SHA256_DIGESTLENGTH]; 274258945Sroberto 275258945Sroberto REQUIRE(len <= ISC_SHA256_DIGESTLENGTH); 276258945Sroberto isc_hmacsha256_sign(ctx, newdigest, ISC_SHA256_DIGESTLENGTH); 277258945Sroberto return (ISC_TF(memcmp(digest, newdigest, len) == 0)); 278258945Sroberto} 279258945Sroberto 280258945Sroberto/* 281258945Sroberto * Start HMAC-SHA384 process. Initialize an sha384 context and digest the key. 282258945Sroberto */ 283258945Srobertovoid 284258945Srobertoisc_hmacsha384_init(isc_hmacsha384_t *ctx, const unsigned char *key, 285258945Sroberto unsigned int len) 286258945Sroberto{ 287258945Sroberto unsigned char ipad[ISC_SHA384_BLOCK_LENGTH]; 288258945Sroberto unsigned int i; 289258945Sroberto 290258945Sroberto memset(ctx->key, 0, sizeof(ctx->key)); 291258945Sroberto if (len > sizeof(ctx->key)) { 292258945Sroberto isc_sha384_t sha384ctx; 293258945Sroberto isc_sha384_init(&sha384ctx); 294258945Sroberto isc_sha384_update(&sha384ctx, key, len); 295258945Sroberto isc_sha384_final(ctx->key, &sha384ctx); 296258945Sroberto } else 297258945Sroberto memcpy(ctx->key, key, len); 298258945Sroberto 299258945Sroberto isc_sha384_init(&ctx->sha384ctx); 300258945Sroberto memset(ipad, IPAD, sizeof(ipad)); 301258945Sroberto for (i = 0; i < ISC_SHA384_BLOCK_LENGTH; i++) 302258945Sroberto ipad[i] ^= ctx->key[i]; 303258945Sroberto isc_sha384_update(&ctx->sha384ctx, ipad, sizeof(ipad)); 304258945Sroberto} 305258945Sroberto 306258945Srobertovoid 307258945Srobertoisc_hmacsha384_invalidate(isc_hmacsha384_t *ctx) { 308258945Sroberto memset(ctx->key, 0, sizeof(ctx->key)); 309258945Sroberto memset(ctx, 0, sizeof(ctx)); 310258945Sroberto} 311258945Sroberto 312258945Sroberto/* 313258945Sroberto * Update context to reflect the concatenation of another buffer full 314258945Sroberto * of bytes. 315258945Sroberto */ 316258945Srobertovoid 317258945Srobertoisc_hmacsha384_update(isc_hmacsha384_t *ctx, const unsigned char *buf, 318258945Sroberto unsigned int len) 319258945Sroberto{ 320258945Sroberto isc_sha384_update(&ctx->sha384ctx, buf, len); 321258945Sroberto} 322258945Sroberto 323258945Sroberto/* 324258945Sroberto * Compute signature - finalize SHA384 operation and reapply SHA384. 325258945Sroberto */ 326258945Srobertovoid 327258945Srobertoisc_hmacsha384_sign(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) { 328258945Sroberto unsigned char opad[ISC_SHA384_BLOCK_LENGTH]; 329258945Sroberto unsigned char newdigest[ISC_SHA384_DIGESTLENGTH]; 330258945Sroberto unsigned int i; 331258945Sroberto 332258945Sroberto REQUIRE(len <= ISC_SHA384_DIGESTLENGTH); 333258945Sroberto isc_sha384_final(newdigest, &ctx->sha384ctx); 334258945Sroberto 335258945Sroberto memset(opad, OPAD, sizeof(opad)); 336258945Sroberto for (i = 0; i < ISC_SHA384_BLOCK_LENGTH; i++) 337258945Sroberto opad[i] ^= ctx->key[i]; 338258945Sroberto 339258945Sroberto isc_sha384_init(&ctx->sha384ctx); 340258945Sroberto isc_sha384_update(&ctx->sha384ctx, opad, sizeof(opad)); 341258945Sroberto isc_sha384_update(&ctx->sha384ctx, newdigest, ISC_SHA384_DIGESTLENGTH); 342258945Sroberto isc_sha384_final(newdigest, &ctx->sha384ctx); 343258945Sroberto memcpy(digest, newdigest, len); 344258945Sroberto memset(newdigest, 0, sizeof(newdigest)); 345258945Sroberto} 346258945Sroberto 347258945Sroberto/* 348258945Sroberto * Verify signature - finalize SHA384 operation and reapply SHA384, then 349258945Sroberto * compare to the supplied digest. 350258945Sroberto */ 351258945Srobertoisc_boolean_t 352258945Srobertoisc_hmacsha384_verify(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) { 353258945Sroberto unsigned char newdigest[ISC_SHA384_DIGESTLENGTH]; 354258945Sroberto 355258945Sroberto REQUIRE(len <= ISC_SHA384_DIGESTLENGTH); 356258945Sroberto isc_hmacsha384_sign(ctx, newdigest, ISC_SHA384_DIGESTLENGTH); 357258945Sroberto return (ISC_TF(memcmp(digest, newdigest, len) == 0)); 358258945Sroberto} 359258945Sroberto 360258945Sroberto/* 361258945Sroberto * Start HMAC-SHA512 process. Initialize an sha512 context and digest the key. 362258945Sroberto */ 363258945Srobertovoid 364258945Srobertoisc_hmacsha512_init(isc_hmacsha512_t *ctx, const unsigned char *key, 365258945Sroberto unsigned int len) 366258945Sroberto{ 367258945Sroberto unsigned char ipad[ISC_SHA512_BLOCK_LENGTH]; 368258945Sroberto unsigned int i; 369258945Sroberto 370258945Sroberto memset(ctx->key, 0, sizeof(ctx->key)); 371258945Sroberto if (len > sizeof(ctx->key)) { 372258945Sroberto isc_sha512_t sha512ctx; 373258945Sroberto isc_sha512_init(&sha512ctx); 374258945Sroberto isc_sha512_update(&sha512ctx, key, len); 375258945Sroberto isc_sha512_final(ctx->key, &sha512ctx); 376258945Sroberto } else 377258945Sroberto memcpy(ctx->key, key, len); 378258945Sroberto 379258945Sroberto isc_sha512_init(&ctx->sha512ctx); 380258945Sroberto memset(ipad, IPAD, sizeof(ipad)); 381258945Sroberto for (i = 0; i < ISC_SHA512_BLOCK_LENGTH; i++) 382258945Sroberto ipad[i] ^= ctx->key[i]; 383258945Sroberto isc_sha512_update(&ctx->sha512ctx, ipad, sizeof(ipad)); 384258945Sroberto} 385258945Sroberto 386258945Srobertovoid 387258945Srobertoisc_hmacsha512_invalidate(isc_hmacsha512_t *ctx) { 388258945Sroberto memset(ctx->key, 0, sizeof(ctx->key)); 389258945Sroberto memset(ctx, 0, sizeof(ctx)); 390258945Sroberto} 391258945Sroberto 392258945Sroberto/* 393258945Sroberto * Update context to reflect the concatenation of another buffer full 394258945Sroberto * of bytes. 395258945Sroberto */ 396258945Srobertovoid 397258945Srobertoisc_hmacsha512_update(isc_hmacsha512_t *ctx, const unsigned char *buf, 398258945Sroberto unsigned int len) 399258945Sroberto{ 400258945Sroberto isc_sha512_update(&ctx->sha512ctx, buf, len); 401258945Sroberto} 402258945Sroberto 403258945Sroberto/* 404258945Sroberto * Compute signature - finalize SHA512 operation and reapply SHA512. 405258945Sroberto */ 406258945Srobertovoid 407258945Srobertoisc_hmacsha512_sign(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) { 408258945Sroberto unsigned char opad[ISC_SHA512_BLOCK_LENGTH]; 409258945Sroberto unsigned char newdigest[ISC_SHA512_DIGESTLENGTH]; 410258945Sroberto unsigned int i; 411258945Sroberto 412258945Sroberto REQUIRE(len <= ISC_SHA512_DIGESTLENGTH); 413258945Sroberto isc_sha512_final(newdigest, &ctx->sha512ctx); 414258945Sroberto 415258945Sroberto memset(opad, OPAD, sizeof(opad)); 416258945Sroberto for (i = 0; i < ISC_SHA512_BLOCK_LENGTH; i++) 417258945Sroberto opad[i] ^= ctx->key[i]; 418258945Sroberto 419258945Sroberto isc_sha512_init(&ctx->sha512ctx); 420258945Sroberto isc_sha512_update(&ctx->sha512ctx, opad, sizeof(opad)); 421258945Sroberto isc_sha512_update(&ctx->sha512ctx, newdigest, ISC_SHA512_DIGESTLENGTH); 422258945Sroberto isc_sha512_final(newdigest, &ctx->sha512ctx); 423258945Sroberto memcpy(digest, newdigest, len); 424258945Sroberto memset(newdigest, 0, sizeof(newdigest)); 425258945Sroberto} 426258945Sroberto 427258945Sroberto/* 428258945Sroberto * Verify signature - finalize SHA512 operation and reapply SHA512, then 429258945Sroberto * compare to the supplied digest. 430258945Sroberto */ 431258945Srobertoisc_boolean_t 432258945Srobertoisc_hmacsha512_verify(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) { 433258945Sroberto unsigned char newdigest[ISC_SHA512_DIGESTLENGTH]; 434258945Sroberto 435258945Sroberto REQUIRE(len <= ISC_SHA512_DIGESTLENGTH); 436258945Sroberto isc_hmacsha512_sign(ctx, newdigest, ISC_SHA512_DIGESTLENGTH); 437258945Sroberto return (ISC_TF(memcmp(digest, newdigest, len) == 0)); 438258945Sroberto} 439