1 /* 2 * Portions Copyright (C) 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 AND NETWORK ASSOCIATES DISCLAIMS 9 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 10 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE 11 * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR 14 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 * 16 * See the COPYRIGHT file distributed with this work for additional 17 * information regarding copyright ownership. 18 * 19 * Portions Copyright (C) Network Associates, Inc. 20 * 21 * Permission to use, copy, modify, and/or distribute this software for any 22 * purpose with or without fee is hereby granted, provided that the above 23 * copyright notice and this permission notice appear in all copies. 24 * 25 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS 26 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 27 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE 28 * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 29 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 30 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR 31 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 32 */ 33 34 /* 35 * Principal Author: Brian Wellington 36 * $Id: hmac_link.c,v 1.9 2020/02/25 18:10:17 florian Exp $ 37 */ 38 39 #include <string.h> 40 41 #include <isc/buffer.h> 42 #include <isc/hmacsha.h> 43 #include <isc/sha1.h> 44 #include <isc/util.h> 45 46 #include <dst/result.h> 47 48 #include "dst_internal.h" 49 50 static isc_result_t hmacsha1_fromdns(dst_key_t *key, isc_buffer_t *data); 51 52 struct dst_hmacsha1_key { 53 unsigned char key[ISC_SHA1_BLOCK_LENGTH]; 54 }; 55 56 static isc_result_t 57 hmacsha1_createctx(dst_key_t *key, dst_context_t *dctx) { 58 isc_hmacsha1_t *hmacsha1ctx; 59 dst_hmacsha1_key_t *hkey = key->keydata.hmacsha1; 60 61 hmacsha1ctx = malloc(sizeof(isc_hmacsha1_t)); 62 if (hmacsha1ctx == NULL) 63 return (ISC_R_NOMEMORY); 64 isc_hmacsha1_init(hmacsha1ctx, hkey->key, ISC_SHA1_BLOCK_LENGTH); 65 dctx->ctxdata.hmacsha1ctx = hmacsha1ctx; 66 return (ISC_R_SUCCESS); 67 } 68 69 static void 70 hmacsha1_destroyctx(dst_context_t *dctx) { 71 isc_hmacsha1_t *hmacsha1ctx = dctx->ctxdata.hmacsha1ctx; 72 73 if (hmacsha1ctx != NULL) { 74 isc_hmacsha1_invalidate(hmacsha1ctx); 75 free(hmacsha1ctx); 76 dctx->ctxdata.hmacsha1ctx = NULL; 77 } 78 } 79 80 static isc_result_t 81 hmacsha1_adddata(dst_context_t *dctx, const isc_region_t *data) { 82 isc_hmacsha1_t *hmacsha1ctx = dctx->ctxdata.hmacsha1ctx; 83 84 isc_hmacsha1_update(hmacsha1ctx, data->base, data->length); 85 return (ISC_R_SUCCESS); 86 } 87 88 static isc_result_t 89 hmacsha1_sign(dst_context_t *dctx, isc_buffer_t *sig) { 90 isc_hmacsha1_t *hmacsha1ctx = dctx->ctxdata.hmacsha1ctx; 91 unsigned char *digest; 92 93 if (isc_buffer_availablelength(sig) < ISC_SHA1_DIGESTLENGTH) 94 return (ISC_R_NOSPACE); 95 digest = isc_buffer_used(sig); 96 isc_hmacsha1_sign(hmacsha1ctx, digest, ISC_SHA1_DIGESTLENGTH); 97 isc_buffer_add(sig, ISC_SHA1_DIGESTLENGTH); 98 99 return (ISC_R_SUCCESS); 100 } 101 102 static isc_result_t 103 hmacsha1_verify(dst_context_t *dctx, const isc_region_t *sig) { 104 isc_hmacsha1_t *hmacsha1ctx = dctx->ctxdata.hmacsha1ctx; 105 106 if (sig->length > ISC_SHA1_DIGESTLENGTH || sig->length == 0) 107 return (DST_R_VERIFYFAILURE); 108 109 if (isc_hmacsha1_verify(hmacsha1ctx, sig->base, sig->length)) 110 return (ISC_R_SUCCESS); 111 else 112 return (DST_R_VERIFYFAILURE); 113 } 114 115 static void 116 hmacsha1_destroy(dst_key_t *key) { 117 dst_hmacsha1_key_t *hkey = key->keydata.hmacsha1; 118 119 freezero(hkey, sizeof(*hkey)); 120 key->keydata.hmacsha1 = NULL; 121 } 122 123 static isc_result_t 124 hmacsha1_todns(const dst_key_t *key, isc_buffer_t *data) { 125 dst_hmacsha1_key_t *hkey; 126 unsigned int bytes; 127 128 REQUIRE(key->keydata.hmacsha1 != NULL); 129 130 hkey = key->keydata.hmacsha1; 131 132 bytes = (key->key_size + 7) / 8; 133 if (isc_buffer_availablelength(data) < bytes) 134 return (ISC_R_NOSPACE); 135 isc_buffer_putmem(data, hkey->key, bytes); 136 137 return (ISC_R_SUCCESS); 138 } 139 140 static isc_result_t 141 hmacsha1_fromdns(dst_key_t *key, isc_buffer_t *data) { 142 dst_hmacsha1_key_t *hkey; 143 int keylen; 144 isc_region_t r; 145 isc_sha1_t sha1ctx; 146 147 isc_buffer_remainingregion(data, &r); 148 if (r.length == 0) 149 return (ISC_R_SUCCESS); 150 151 hkey = malloc(sizeof(dst_hmacsha1_key_t)); 152 if (hkey == NULL) 153 return (ISC_R_NOMEMORY); 154 155 memset(hkey->key, 0, sizeof(hkey->key)); 156 157 if (r.length > ISC_SHA1_BLOCK_LENGTH) { 158 isc_sha1_init(&sha1ctx); 159 isc_sha1_update(&sha1ctx, r.base, r.length); 160 isc_sha1_final(&sha1ctx, hkey->key); 161 keylen = ISC_SHA1_DIGESTLENGTH; 162 } else { 163 memmove(hkey->key, r.base, r.length); 164 keylen = r.length; 165 } 166 167 key->key_size = keylen * 8; 168 key->keydata.hmacsha1 = hkey; 169 170 isc_buffer_forward(data, r.length); 171 172 return (ISC_R_SUCCESS); 173 } 174 175 static dst_func_t hmacsha1_functions = { 176 hmacsha1_createctx, 177 hmacsha1_destroyctx, 178 hmacsha1_adddata, 179 hmacsha1_sign, 180 hmacsha1_verify, 181 hmacsha1_destroy, 182 hmacsha1_todns, 183 hmacsha1_fromdns, 184 }; 185 186 isc_result_t 187 dst__hmacsha1_init(dst_func_t **funcp) { 188 REQUIRE(funcp != NULL); 189 if (*funcp == NULL) 190 *funcp = &hmacsha1_functions; 191 return (ISC_R_SUCCESS); 192 } 193 194 static isc_result_t hmacsha224_fromdns(dst_key_t *key, isc_buffer_t *data); 195 196 struct dst_hmacsha224_key { 197 unsigned char key[ISC_SHA224_BLOCK_LENGTH]; 198 }; 199 200 static isc_result_t 201 hmacsha224_createctx(dst_key_t *key, dst_context_t *dctx) { 202 isc_hmacsha224_t *hmacsha224ctx; 203 dst_hmacsha224_key_t *hkey = key->keydata.hmacsha224; 204 205 hmacsha224ctx = malloc(sizeof(isc_hmacsha224_t)); 206 if (hmacsha224ctx == NULL) 207 return (ISC_R_NOMEMORY); 208 isc_hmacsha224_init(hmacsha224ctx, hkey->key, ISC_SHA224_BLOCK_LENGTH); 209 dctx->ctxdata.hmacsha224ctx = hmacsha224ctx; 210 return (ISC_R_SUCCESS); 211 } 212 213 static void 214 hmacsha224_destroyctx(dst_context_t *dctx) { 215 isc_hmacsha224_t *hmacsha224ctx = dctx->ctxdata.hmacsha224ctx; 216 217 if (hmacsha224ctx != NULL) { 218 isc_hmacsha224_invalidate(hmacsha224ctx); 219 free(hmacsha224ctx); 220 dctx->ctxdata.hmacsha224ctx = NULL; 221 } 222 } 223 224 static isc_result_t 225 hmacsha224_adddata(dst_context_t *dctx, const isc_region_t *data) { 226 isc_hmacsha224_t *hmacsha224ctx = dctx->ctxdata.hmacsha224ctx; 227 228 isc_hmacsha224_update(hmacsha224ctx, data->base, data->length); 229 return (ISC_R_SUCCESS); 230 } 231 232 static isc_result_t 233 hmacsha224_sign(dst_context_t *dctx, isc_buffer_t *sig) { 234 isc_hmacsha224_t *hmacsha224ctx = dctx->ctxdata.hmacsha224ctx; 235 unsigned char *digest; 236 237 if (isc_buffer_availablelength(sig) < ISC_SHA224_DIGESTLENGTH) 238 return (ISC_R_NOSPACE); 239 digest = isc_buffer_used(sig); 240 isc_hmacsha224_sign(hmacsha224ctx, digest, ISC_SHA224_DIGESTLENGTH); 241 isc_buffer_add(sig, ISC_SHA224_DIGESTLENGTH); 242 243 return (ISC_R_SUCCESS); 244 } 245 246 static isc_result_t 247 hmacsha224_verify(dst_context_t *dctx, const isc_region_t *sig) { 248 isc_hmacsha224_t *hmacsha224ctx = dctx->ctxdata.hmacsha224ctx; 249 250 if (sig->length > ISC_SHA224_DIGESTLENGTH || sig->length == 0) 251 return (DST_R_VERIFYFAILURE); 252 253 if (isc_hmacsha224_verify(hmacsha224ctx, sig->base, sig->length)) 254 return (ISC_R_SUCCESS); 255 else 256 return (DST_R_VERIFYFAILURE); 257 } 258 259 static void 260 hmacsha224_destroy(dst_key_t *key) { 261 dst_hmacsha224_key_t *hkey = key->keydata.hmacsha224; 262 263 freezero(hkey, sizeof(*hkey)); 264 key->keydata.hmacsha224 = NULL; 265 } 266 267 static isc_result_t 268 hmacsha224_todns(const dst_key_t *key, isc_buffer_t *data) { 269 dst_hmacsha224_key_t *hkey; 270 unsigned int bytes; 271 272 REQUIRE(key->keydata.hmacsha224 != NULL); 273 274 hkey = key->keydata.hmacsha224; 275 276 bytes = (key->key_size + 7) / 8; 277 if (isc_buffer_availablelength(data) < bytes) 278 return (ISC_R_NOSPACE); 279 isc_buffer_putmem(data, hkey->key, bytes); 280 281 return (ISC_R_SUCCESS); 282 } 283 284 static isc_result_t 285 hmacsha224_fromdns(dst_key_t *key, isc_buffer_t *data) { 286 dst_hmacsha224_key_t *hkey; 287 int keylen; 288 isc_region_t r; 289 isc_sha224_t sha224ctx; 290 291 isc_buffer_remainingregion(data, &r); 292 if (r.length == 0) 293 return (ISC_R_SUCCESS); 294 295 hkey = malloc(sizeof(dst_hmacsha224_key_t)); 296 if (hkey == NULL) 297 return (ISC_R_NOMEMORY); 298 299 memset(hkey->key, 0, sizeof(hkey->key)); 300 301 if (r.length > ISC_SHA224_BLOCK_LENGTH) { 302 isc_sha224_init(&sha224ctx); 303 isc_sha224_update(&sha224ctx, r.base, r.length); 304 isc_sha224_final(hkey->key, &sha224ctx); 305 keylen = ISC_SHA224_DIGESTLENGTH; 306 } else { 307 memmove(hkey->key, r.base, r.length); 308 keylen = r.length; 309 } 310 311 key->key_size = keylen * 8; 312 key->keydata.hmacsha224 = hkey; 313 314 isc_buffer_forward(data, r.length); 315 316 return (ISC_R_SUCCESS); 317 } 318 319 static dst_func_t hmacsha224_functions = { 320 hmacsha224_createctx, 321 hmacsha224_destroyctx, 322 hmacsha224_adddata, 323 hmacsha224_sign, 324 hmacsha224_verify, 325 hmacsha224_destroy, 326 hmacsha224_todns, 327 hmacsha224_fromdns, 328 }; 329 330 isc_result_t 331 dst__hmacsha224_init(dst_func_t **funcp) { 332 REQUIRE(funcp != NULL); 333 if (*funcp == NULL) 334 *funcp = &hmacsha224_functions; 335 return (ISC_R_SUCCESS); 336 } 337 338 static isc_result_t hmacsha256_fromdns(dst_key_t *key, isc_buffer_t *data); 339 340 struct dst_hmacsha256_key { 341 unsigned char key[ISC_SHA256_BLOCK_LENGTH]; 342 }; 343 344 static isc_result_t 345 hmacsha256_createctx(dst_key_t *key, dst_context_t *dctx) { 346 isc_hmacsha256_t *hmacsha256ctx; 347 dst_hmacsha256_key_t *hkey = key->keydata.hmacsha256; 348 349 hmacsha256ctx = malloc(sizeof(isc_hmacsha256_t)); 350 if (hmacsha256ctx == NULL) 351 return (ISC_R_NOMEMORY); 352 isc_hmacsha256_init(hmacsha256ctx, hkey->key, ISC_SHA256_BLOCK_LENGTH); 353 dctx->ctxdata.hmacsha256ctx = hmacsha256ctx; 354 return (ISC_R_SUCCESS); 355 } 356 357 static void 358 hmacsha256_destroyctx(dst_context_t *dctx) { 359 isc_hmacsha256_t *hmacsha256ctx = dctx->ctxdata.hmacsha256ctx; 360 361 if (hmacsha256ctx != NULL) { 362 isc_hmacsha256_invalidate(hmacsha256ctx); 363 free(hmacsha256ctx); 364 dctx->ctxdata.hmacsha256ctx = NULL; 365 } 366 } 367 368 static isc_result_t 369 hmacsha256_adddata(dst_context_t *dctx, const isc_region_t *data) { 370 isc_hmacsha256_t *hmacsha256ctx = dctx->ctxdata.hmacsha256ctx; 371 372 isc_hmacsha256_update(hmacsha256ctx, data->base, data->length); 373 return (ISC_R_SUCCESS); 374 } 375 376 static isc_result_t 377 hmacsha256_sign(dst_context_t *dctx, isc_buffer_t *sig) { 378 isc_hmacsha256_t *hmacsha256ctx = dctx->ctxdata.hmacsha256ctx; 379 unsigned char *digest; 380 381 if (isc_buffer_availablelength(sig) < ISC_SHA256_DIGESTLENGTH) 382 return (ISC_R_NOSPACE); 383 digest = isc_buffer_used(sig); 384 isc_hmacsha256_sign(hmacsha256ctx, digest, ISC_SHA256_DIGESTLENGTH); 385 isc_buffer_add(sig, ISC_SHA256_DIGESTLENGTH); 386 387 return (ISC_R_SUCCESS); 388 } 389 390 static isc_result_t 391 hmacsha256_verify(dst_context_t *dctx, const isc_region_t *sig) { 392 isc_hmacsha256_t *hmacsha256ctx = dctx->ctxdata.hmacsha256ctx; 393 394 if (sig->length > ISC_SHA256_DIGESTLENGTH || sig->length == 0) 395 return (DST_R_VERIFYFAILURE); 396 397 if (isc_hmacsha256_verify(hmacsha256ctx, sig->base, sig->length)) 398 return (ISC_R_SUCCESS); 399 else 400 return (DST_R_VERIFYFAILURE); 401 } 402 403 static void 404 hmacsha256_destroy(dst_key_t *key) { 405 dst_hmacsha256_key_t *hkey = key->keydata.hmacsha256; 406 407 freezero(hkey, sizeof(*hkey)); 408 key->keydata.hmacsha256 = NULL; 409 } 410 411 static isc_result_t 412 hmacsha256_todns(const dst_key_t *key, isc_buffer_t *data) { 413 dst_hmacsha256_key_t *hkey; 414 unsigned int bytes; 415 416 REQUIRE(key->keydata.hmacsha256 != NULL); 417 418 hkey = key->keydata.hmacsha256; 419 420 bytes = (key->key_size + 7) / 8; 421 if (isc_buffer_availablelength(data) < bytes) 422 return (ISC_R_NOSPACE); 423 isc_buffer_putmem(data, hkey->key, bytes); 424 425 return (ISC_R_SUCCESS); 426 } 427 428 static isc_result_t 429 hmacsha256_fromdns(dst_key_t *key, isc_buffer_t *data) { 430 dst_hmacsha256_key_t *hkey; 431 int keylen; 432 isc_region_t r; 433 isc_sha256_t sha256ctx; 434 435 isc_buffer_remainingregion(data, &r); 436 if (r.length == 0) 437 return (ISC_R_SUCCESS); 438 439 hkey = malloc(sizeof(dst_hmacsha256_key_t)); 440 if (hkey == NULL) 441 return (ISC_R_NOMEMORY); 442 443 memset(hkey->key, 0, sizeof(hkey->key)); 444 445 if (r.length > ISC_SHA256_BLOCK_LENGTH) { 446 isc_sha256_init(&sha256ctx); 447 isc_sha256_update(&sha256ctx, r.base, r.length); 448 isc_sha256_final(hkey->key, &sha256ctx); 449 keylen = ISC_SHA256_DIGESTLENGTH; 450 } else { 451 memmove(hkey->key, r.base, r.length); 452 keylen = r.length; 453 } 454 455 key->key_size = keylen * 8; 456 key->keydata.hmacsha256 = hkey; 457 458 isc_buffer_forward(data, r.length); 459 460 return (ISC_R_SUCCESS); 461 } 462 463 static dst_func_t hmacsha256_functions = { 464 hmacsha256_createctx, 465 hmacsha256_destroyctx, 466 hmacsha256_adddata, 467 hmacsha256_sign, 468 hmacsha256_verify, 469 hmacsha256_destroy, 470 hmacsha256_todns, 471 hmacsha256_fromdns, 472 }; 473 474 isc_result_t 475 dst__hmacsha256_init(dst_func_t **funcp) { 476 REQUIRE(funcp != NULL); 477 if (*funcp == NULL) 478 *funcp = &hmacsha256_functions; 479 return (ISC_R_SUCCESS); 480 } 481 482 static isc_result_t hmacsha384_fromdns(dst_key_t *key, isc_buffer_t *data); 483 484 struct dst_hmacsha384_key { 485 unsigned char key[ISC_SHA384_BLOCK_LENGTH]; 486 }; 487 488 static isc_result_t 489 hmacsha384_createctx(dst_key_t *key, dst_context_t *dctx) { 490 isc_hmacsha384_t *hmacsha384ctx; 491 dst_hmacsha384_key_t *hkey = key->keydata.hmacsha384; 492 493 hmacsha384ctx = malloc(sizeof(isc_hmacsha384_t)); 494 if (hmacsha384ctx == NULL) 495 return (ISC_R_NOMEMORY); 496 isc_hmacsha384_init(hmacsha384ctx, hkey->key, ISC_SHA384_BLOCK_LENGTH); 497 dctx->ctxdata.hmacsha384ctx = hmacsha384ctx; 498 return (ISC_R_SUCCESS); 499 } 500 501 static void 502 hmacsha384_destroyctx(dst_context_t *dctx) { 503 isc_hmacsha384_t *hmacsha384ctx = dctx->ctxdata.hmacsha384ctx; 504 505 if (hmacsha384ctx != NULL) { 506 isc_hmacsha384_invalidate(hmacsha384ctx); 507 free(hmacsha384ctx); 508 dctx->ctxdata.hmacsha384ctx = NULL; 509 } 510 } 511 512 static isc_result_t 513 hmacsha384_adddata(dst_context_t *dctx, const isc_region_t *data) { 514 isc_hmacsha384_t *hmacsha384ctx = dctx->ctxdata.hmacsha384ctx; 515 516 isc_hmacsha384_update(hmacsha384ctx, data->base, data->length); 517 return (ISC_R_SUCCESS); 518 } 519 520 static isc_result_t 521 hmacsha384_sign(dst_context_t *dctx, isc_buffer_t *sig) { 522 isc_hmacsha384_t *hmacsha384ctx = dctx->ctxdata.hmacsha384ctx; 523 unsigned char *digest; 524 525 if (isc_buffer_availablelength(sig) < ISC_SHA384_DIGESTLENGTH) 526 return (ISC_R_NOSPACE); 527 digest = isc_buffer_used(sig); 528 isc_hmacsha384_sign(hmacsha384ctx, digest, ISC_SHA384_DIGESTLENGTH); 529 isc_buffer_add(sig, ISC_SHA384_DIGESTLENGTH); 530 531 return (ISC_R_SUCCESS); 532 } 533 534 static isc_result_t 535 hmacsha384_verify(dst_context_t *dctx, const isc_region_t *sig) { 536 isc_hmacsha384_t *hmacsha384ctx = dctx->ctxdata.hmacsha384ctx; 537 538 if (sig->length > ISC_SHA384_DIGESTLENGTH || sig->length == 0) 539 return (DST_R_VERIFYFAILURE); 540 541 if (isc_hmacsha384_verify(hmacsha384ctx, sig->base, sig->length)) 542 return (ISC_R_SUCCESS); 543 else 544 return (DST_R_VERIFYFAILURE); 545 } 546 547 static void 548 hmacsha384_destroy(dst_key_t *key) { 549 dst_hmacsha384_key_t *hkey = key->keydata.hmacsha384; 550 551 freezero(hkey, sizeof(*hkey)); 552 key->keydata.hmacsha384 = NULL; 553 } 554 555 static isc_result_t 556 hmacsha384_todns(const dst_key_t *key, isc_buffer_t *data) { 557 dst_hmacsha384_key_t *hkey; 558 unsigned int bytes; 559 560 REQUIRE(key->keydata.hmacsha384 != NULL); 561 562 hkey = key->keydata.hmacsha384; 563 564 bytes = (key->key_size + 7) / 8; 565 if (isc_buffer_availablelength(data) < bytes) 566 return (ISC_R_NOSPACE); 567 isc_buffer_putmem(data, hkey->key, bytes); 568 569 return (ISC_R_SUCCESS); 570 } 571 572 static isc_result_t 573 hmacsha384_fromdns(dst_key_t *key, isc_buffer_t *data) { 574 dst_hmacsha384_key_t *hkey; 575 int keylen; 576 isc_region_t r; 577 isc_sha384_t sha384ctx; 578 579 isc_buffer_remainingregion(data, &r); 580 if (r.length == 0) 581 return (ISC_R_SUCCESS); 582 583 hkey = malloc(sizeof(dst_hmacsha384_key_t)); 584 if (hkey == NULL) 585 return (ISC_R_NOMEMORY); 586 587 memset(hkey->key, 0, sizeof(hkey->key)); 588 589 if (r.length > ISC_SHA384_BLOCK_LENGTH) { 590 isc_sha384_init(&sha384ctx); 591 isc_sha384_update(&sha384ctx, r.base, r.length); 592 isc_sha384_final(hkey->key, &sha384ctx); 593 keylen = ISC_SHA384_DIGESTLENGTH; 594 } else { 595 memmove(hkey->key, r.base, r.length); 596 keylen = r.length; 597 } 598 599 key->key_size = keylen * 8; 600 key->keydata.hmacsha384 = hkey; 601 602 isc_buffer_forward(data, r.length); 603 604 return (ISC_R_SUCCESS); 605 } 606 607 static dst_func_t hmacsha384_functions = { 608 hmacsha384_createctx, 609 hmacsha384_destroyctx, 610 hmacsha384_adddata, 611 hmacsha384_sign, 612 hmacsha384_verify, 613 hmacsha384_destroy, 614 hmacsha384_todns, 615 hmacsha384_fromdns, 616 }; 617 618 isc_result_t 619 dst__hmacsha384_init(dst_func_t **funcp) { 620 REQUIRE(funcp != NULL); 621 if (*funcp == NULL) 622 *funcp = &hmacsha384_functions; 623 return (ISC_R_SUCCESS); 624 } 625 626 static isc_result_t hmacsha512_fromdns(dst_key_t *key, isc_buffer_t *data); 627 628 struct dst_hmacsha512_key { 629 unsigned char key[ISC_SHA512_BLOCK_LENGTH]; 630 }; 631 632 static isc_result_t 633 hmacsha512_createctx(dst_key_t *key, dst_context_t *dctx) { 634 isc_hmacsha512_t *hmacsha512ctx; 635 dst_hmacsha512_key_t *hkey = key->keydata.hmacsha512; 636 637 hmacsha512ctx = malloc(sizeof(isc_hmacsha512_t)); 638 if (hmacsha512ctx == NULL) 639 return (ISC_R_NOMEMORY); 640 isc_hmacsha512_init(hmacsha512ctx, hkey->key, ISC_SHA512_BLOCK_LENGTH); 641 dctx->ctxdata.hmacsha512ctx = hmacsha512ctx; 642 return (ISC_R_SUCCESS); 643 } 644 645 static void 646 hmacsha512_destroyctx(dst_context_t *dctx) { 647 isc_hmacsha512_t *hmacsha512ctx = dctx->ctxdata.hmacsha512ctx; 648 649 if (hmacsha512ctx != NULL) { 650 isc_hmacsha512_invalidate(hmacsha512ctx); 651 free(hmacsha512ctx); 652 dctx->ctxdata.hmacsha512ctx = NULL; 653 } 654 } 655 656 static isc_result_t 657 hmacsha512_adddata(dst_context_t *dctx, const isc_region_t *data) { 658 isc_hmacsha512_t *hmacsha512ctx = dctx->ctxdata.hmacsha512ctx; 659 660 isc_hmacsha512_update(hmacsha512ctx, data->base, data->length); 661 return (ISC_R_SUCCESS); 662 } 663 664 static isc_result_t 665 hmacsha512_sign(dst_context_t *dctx, isc_buffer_t *sig) { 666 isc_hmacsha512_t *hmacsha512ctx = dctx->ctxdata.hmacsha512ctx; 667 unsigned char *digest; 668 669 if (isc_buffer_availablelength(sig) < ISC_SHA512_DIGESTLENGTH) 670 return (ISC_R_NOSPACE); 671 digest = isc_buffer_used(sig); 672 isc_hmacsha512_sign(hmacsha512ctx, digest, ISC_SHA512_DIGESTLENGTH); 673 isc_buffer_add(sig, ISC_SHA512_DIGESTLENGTH); 674 675 return (ISC_R_SUCCESS); 676 } 677 678 static isc_result_t 679 hmacsha512_verify(dst_context_t *dctx, const isc_region_t *sig) { 680 isc_hmacsha512_t *hmacsha512ctx = dctx->ctxdata.hmacsha512ctx; 681 682 if (sig->length > ISC_SHA512_DIGESTLENGTH || sig->length == 0) 683 return (DST_R_VERIFYFAILURE); 684 685 if (isc_hmacsha512_verify(hmacsha512ctx, sig->base, sig->length)) 686 return (ISC_R_SUCCESS); 687 else 688 return (DST_R_VERIFYFAILURE); 689 } 690 691 static void 692 hmacsha512_destroy(dst_key_t *key) { 693 dst_hmacsha512_key_t *hkey = key->keydata.hmacsha512; 694 695 freezero(hkey, sizeof(*hkey)); 696 key->keydata.hmacsha512 = NULL; 697 } 698 699 static isc_result_t 700 hmacsha512_todns(const dst_key_t *key, isc_buffer_t *data) { 701 dst_hmacsha512_key_t *hkey; 702 unsigned int bytes; 703 704 REQUIRE(key->keydata.hmacsha512 != NULL); 705 706 hkey = key->keydata.hmacsha512; 707 708 bytes = (key->key_size + 7) / 8; 709 if (isc_buffer_availablelength(data) < bytes) 710 return (ISC_R_NOSPACE); 711 isc_buffer_putmem(data, hkey->key, bytes); 712 713 return (ISC_R_SUCCESS); 714 } 715 716 static isc_result_t 717 hmacsha512_fromdns(dst_key_t *key, isc_buffer_t *data) { 718 dst_hmacsha512_key_t *hkey; 719 int keylen; 720 isc_region_t r; 721 isc_sha512_t sha512ctx; 722 723 isc_buffer_remainingregion(data, &r); 724 if (r.length == 0) 725 return (ISC_R_SUCCESS); 726 727 hkey = malloc(sizeof(dst_hmacsha512_key_t)); 728 if (hkey == NULL) 729 return (ISC_R_NOMEMORY); 730 731 memset(hkey->key, 0, sizeof(hkey->key)); 732 733 if (r.length > ISC_SHA512_BLOCK_LENGTH) { 734 isc_sha512_init(&sha512ctx); 735 isc_sha512_update(&sha512ctx, r.base, r.length); 736 isc_sha512_final(hkey->key, &sha512ctx); 737 keylen = ISC_SHA512_DIGESTLENGTH; 738 } else { 739 memmove(hkey->key, r.base, r.length); 740 keylen = r.length; 741 } 742 743 key->key_size = keylen * 8; 744 key->keydata.hmacsha512 = hkey; 745 746 isc_buffer_forward(data, r.length); 747 748 return (ISC_R_SUCCESS); 749 } 750 751 static dst_func_t hmacsha512_functions = { 752 hmacsha512_createctx, 753 hmacsha512_destroyctx, 754 hmacsha512_adddata, 755 hmacsha512_sign, 756 hmacsha512_verify, 757 hmacsha512_destroy, 758 hmacsha512_todns, 759 hmacsha512_fromdns, 760 }; 761 762 isc_result_t 763 dst__hmacsha512_init(dst_func_t **funcp) { 764 REQUIRE(funcp != NULL); 765 if (*funcp == NULL) 766 *funcp = &hmacsha512_functions; 767 return (ISC_R_SUCCESS); 768 } 769 770 /*! \file */ 771