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 19280849Scy/* $FreeBSD: 258945 2013-12-04 21:33:17Z roberto $ */ 20258945Sroberto/* $KAME: sha2.c,v 1.8 2001/11/08 01:07:52 itojun Exp $ */ 21258945Sroberto 22258945Sroberto/* 23258945Sroberto * sha2.c 24258945Sroberto * 25258945Sroberto * Version 1.0.0beta1 26258945Sroberto * 27258945Sroberto * Written by Aaron D. Gifford <me@aarongifford.com> 28258945Sroberto * 29258945Sroberto * Copyright 2000 Aaron D. Gifford. All rights reserved. 30258945Sroberto * 31258945Sroberto * Redistribution and use in source and binary forms, with or without 32258945Sroberto * modification, are permitted provided that the following conditions 33258945Sroberto * are met: 34258945Sroberto * 1. Redistributions of source code must retain the above copyright 35258945Sroberto * notice, this list of conditions and the following disclaimer. 36258945Sroberto * 2. Redistributions in binary form must reproduce the above copyright 37258945Sroberto * notice, this list of conditions and the following disclaimer in the 38258945Sroberto * documentation and/or other materials provided with the distribution. 39258945Sroberto * 3. Neither the name of the copyright holder nor the names of contributors 40258945Sroberto * may be used to endorse or promote products derived from this software 41258945Sroberto * without specific prior written permission. 42258945Sroberto * 43258945Sroberto * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTOR(S) ``AS IS'' AND 44258945Sroberto * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 45258945Sroberto * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 46258945Sroberto * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE 47258945Sroberto * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 48258945Sroberto * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 49258945Sroberto * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 50258945Sroberto * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 51258945Sroberto * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 52258945Sroberto * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 53258945Sroberto * SUCH DAMAGE. 54258945Sroberto * 55258945Sroberto */ 56258945Sroberto 57258945Sroberto 58258945Sroberto#include <config.h> 59258945Sroberto 60258945Sroberto#include <isc/assertions.h> 61280849Scy#include <isc/platform.h> 62258945Sroberto#include <isc/sha2.h> 63258945Sroberto#include <isc/string.h> 64258945Sroberto#include <isc/util.h> 65258945Sroberto 66280849Scy#ifdef ISC_PLATFORM_OPENSSLHASH 67280849Scy 68280849Scyvoid 69280849Scyisc_sha224_init(isc_sha224_t *context) { 70280849Scy if (context == (isc_sha224_t *)0) { 71280849Scy return; 72280849Scy } 73280849Scy EVP_DigestInit(context, EVP_sha224()); 74280849Scy} 75280849Scy 76280849Scyvoid 77280849Scyisc_sha224_invalidate(isc_sha224_t *context) { 78280849Scy EVP_MD_CTX_cleanup(context); 79280849Scy} 80280849Scy 81280849Scyvoid 82280849Scyisc_sha224_update(isc_sha224_t *context, const isc_uint8_t* data, size_t len) { 83280849Scy if (len == 0U) { 84280849Scy /* Calling with no data is valid - we do nothing */ 85280849Scy return; 86280849Scy } 87280849Scy 88280849Scy /* Sanity check: */ 89280849Scy REQUIRE(context != (isc_sha224_t *)0 && data != (isc_uint8_t*)0); 90280849Scy 91280849Scy EVP_DigestUpdate(context, (const void *) data, len); 92280849Scy} 93280849Scy 94280849Scyvoid 95280849Scyisc_sha224_final(isc_uint8_t digest[], isc_sha224_t *context) { 96280849Scy /* Sanity check: */ 97280849Scy REQUIRE(context != (isc_sha224_t *)0); 98280849Scy 99280849Scy /* If no digest buffer is passed, we don't bother doing this: */ 100280849Scy if (digest != (isc_uint8_t*)0) { 101280849Scy EVP_DigestFinal(context, digest, NULL); 102280849Scy } else { 103280849Scy EVP_MD_CTX_cleanup(context); 104280849Scy } 105280849Scy} 106280849Scy 107280849Scyvoid 108280849Scyisc_sha256_init(isc_sha256_t *context) { 109280849Scy if (context == (isc_sha256_t *)0) { 110280849Scy return; 111280849Scy } 112280849Scy EVP_DigestInit(context, EVP_sha256()); 113280849Scy} 114280849Scy 115280849Scyvoid 116280849Scyisc_sha256_invalidate(isc_sha256_t *context) { 117280849Scy EVP_MD_CTX_cleanup(context); 118280849Scy} 119280849Scy 120280849Scyvoid 121280849Scyisc_sha256_update(isc_sha256_t *context, const isc_uint8_t *data, size_t len) { 122280849Scy if (len == 0U) { 123280849Scy /* Calling with no data is valid - we do nothing */ 124280849Scy return; 125280849Scy } 126280849Scy 127280849Scy /* Sanity check: */ 128280849Scy REQUIRE(context != (isc_sha256_t *)0 && data != (isc_uint8_t*)0); 129280849Scy 130280849Scy EVP_DigestUpdate(context, (const void *) data, len); 131280849Scy} 132280849Scy 133280849Scyvoid 134280849Scyisc_sha256_final(isc_uint8_t digest[], isc_sha256_t *context) { 135280849Scy /* Sanity check: */ 136280849Scy REQUIRE(context != (isc_sha256_t *)0); 137280849Scy 138280849Scy /* If no digest buffer is passed, we don't bother doing this: */ 139280849Scy if (digest != (isc_uint8_t*)0) { 140280849Scy EVP_DigestFinal(context, digest, NULL); 141280849Scy } else { 142280849Scy EVP_MD_CTX_cleanup(context); 143280849Scy } 144280849Scy} 145280849Scy 146280849Scyvoid 147280849Scyisc_sha512_init(isc_sha512_t *context) { 148280849Scy if (context == (isc_sha512_t *)0) { 149280849Scy return; 150280849Scy } 151280849Scy EVP_DigestInit(context, EVP_sha512()); 152280849Scy} 153280849Scy 154280849Scyvoid 155280849Scyisc_sha512_invalidate(isc_sha512_t *context) { 156280849Scy EVP_MD_CTX_cleanup(context); 157280849Scy} 158280849Scy 159280849Scyvoid isc_sha512_update(isc_sha512_t *context, const isc_uint8_t *data, size_t len) { 160280849Scy if (len == 0U) { 161280849Scy /* Calling with no data is valid - we do nothing */ 162280849Scy return; 163280849Scy } 164280849Scy 165280849Scy /* Sanity check: */ 166280849Scy REQUIRE(context != (isc_sha512_t *)0 && data != (isc_uint8_t*)0); 167280849Scy 168280849Scy EVP_DigestUpdate(context, (const void *) data, len); 169280849Scy} 170280849Scy 171280849Scyvoid isc_sha512_final(isc_uint8_t digest[], isc_sha512_t *context) { 172280849Scy /* Sanity check: */ 173280849Scy REQUIRE(context != (isc_sha512_t *)0); 174280849Scy 175280849Scy /* If no digest buffer is passed, we don't bother doing this: */ 176280849Scy if (digest != (isc_uint8_t*)0) { 177280849Scy EVP_DigestFinal(context, digest, NULL); 178280849Scy } else { 179280849Scy EVP_MD_CTX_cleanup(context); 180280849Scy } 181280849Scy} 182280849Scy 183280849Scyvoid 184280849Scyisc_sha384_init(isc_sha384_t *context) { 185280849Scy if (context == (isc_sha384_t *)0) { 186280849Scy return; 187280849Scy } 188280849Scy EVP_DigestInit(context, EVP_sha384()); 189280849Scy} 190280849Scy 191280849Scyvoid 192280849Scyisc_sha384_invalidate(isc_sha384_t *context) { 193280849Scy EVP_MD_CTX_cleanup(context); 194280849Scy} 195280849Scy 196280849Scyvoid 197280849Scyisc_sha384_update(isc_sha384_t *context, const isc_uint8_t* data, size_t len) { 198280849Scy if (len == 0U) { 199280849Scy /* Calling with no data is valid - we do nothing */ 200280849Scy return; 201280849Scy } 202280849Scy 203280849Scy /* Sanity check: */ 204280849Scy REQUIRE(context != (isc_sha512_t *)0 && data != (isc_uint8_t*)0); 205280849Scy 206280849Scy EVP_DigestUpdate(context, (const void *) data, len); 207280849Scy} 208280849Scy 209280849Scyvoid 210280849Scyisc_sha384_final(isc_uint8_t digest[], isc_sha384_t *context) { 211280849Scy /* Sanity check: */ 212280849Scy REQUIRE(context != (isc_sha384_t *)0); 213280849Scy 214280849Scy /* If no digest buffer is passed, we don't bother doing this: */ 215280849Scy if (digest != (isc_uint8_t*)0) { 216280849Scy EVP_DigestFinal(context, digest, NULL); 217280849Scy } else { 218280849Scy EVP_MD_CTX_cleanup(context); 219280849Scy } 220280849Scy} 221280849Scy 222280849Scy#else 223280849Scy 224258945Sroberto/* 225258945Sroberto * UNROLLED TRANSFORM LOOP NOTE: 226258945Sroberto * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform 227258945Sroberto * loop version for the hash transform rounds (defined using macros 228258945Sroberto * later in this file). Either define on the command line, for example: 229258945Sroberto * 230258945Sroberto * cc -DISC_SHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c 231258945Sroberto * 232258945Sroberto * or define below: 233258945Sroberto * 234258945Sroberto * \#define ISC_SHA2_UNROLL_TRANSFORM 235258945Sroberto * 236258945Sroberto */ 237258945Sroberto 238258945Sroberto/*** SHA-256/384/512 Machine Architecture Definitions *****************/ 239258945Sroberto/* 240258945Sroberto * BYTE_ORDER NOTE: 241258945Sroberto * 242258945Sroberto * Please make sure that your system defines BYTE_ORDER. If your 243258945Sroberto * architecture is little-endian, make sure it also defines 244258945Sroberto * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are 245258945Sroberto * equivalent. 246258945Sroberto * 247258945Sroberto * If your system does not define the above, then you can do so by 248258945Sroberto * hand like this: 249258945Sroberto * 250258945Sroberto * \#define LITTLE_ENDIAN 1234 251258945Sroberto * \#define BIG_ENDIAN 4321 252258945Sroberto * 253258945Sroberto * And for little-endian machines, add: 254258945Sroberto * 255258945Sroberto * \#define BYTE_ORDER LITTLE_ENDIAN 256258945Sroberto * 257258945Sroberto * Or for big-endian machines: 258258945Sroberto * 259258945Sroberto * \#define BYTE_ORDER BIG_ENDIAN 260258945Sroberto * 261258945Sroberto * The FreeBSD machine this was written on defines BYTE_ORDER 262258945Sroberto * appropriately by including <sys/types.h> (which in turn includes 263258945Sroberto * <machine/endian.h> where the appropriate definitions are actually 264258945Sroberto * made). 265258945Sroberto */ 266258945Sroberto#if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN) 267258945Sroberto#ifndef BYTE_ORDER 268258945Sroberto#ifndef BIG_ENDIAN 269258945Sroberto#define BIG_ENDIAN 4321 270258945Sroberto#endif 271258945Sroberto#ifndef LITTLE_ENDIAN 272258945Sroberto#define LITTLE_ENDIAN 1234 273258945Sroberto#endif 274258945Sroberto#ifdef WORDS_BIGENDIAN 275258945Sroberto#define BYTE_ORDER BIG_ENDIAN 276258945Sroberto#else 277258945Sroberto#define BYTE_ORDER LITTLE_ENDIAN 278258945Sroberto#endif 279258945Sroberto#else 280258945Sroberto#error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN 281258945Sroberto#endif 282258945Sroberto#endif 283258945Sroberto 284258945Sroberto/*** SHA-256/384/512 Various Length Definitions ***********************/ 285258945Sroberto/* NOTE: Most of these are in sha2.h */ 286258945Sroberto#define ISC_SHA256_SHORT_BLOCK_LENGTH (ISC_SHA256_BLOCK_LENGTH - 8) 287258945Sroberto#define ISC_SHA384_SHORT_BLOCK_LENGTH (ISC_SHA384_BLOCK_LENGTH - 16) 288258945Sroberto#define ISC_SHA512_SHORT_BLOCK_LENGTH (ISC_SHA512_BLOCK_LENGTH - 16) 289258945Sroberto 290258945Sroberto 291258945Sroberto/*** ENDIAN REVERSAL MACROS *******************************************/ 292258945Sroberto#if BYTE_ORDER == LITTLE_ENDIAN 293258945Sroberto#define REVERSE32(w,x) { \ 294258945Sroberto isc_uint32_t tmp = (w); \ 295258945Sroberto tmp = (tmp >> 16) | (tmp << 16); \ 296258945Sroberto (x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \ 297258945Sroberto} 298258945Sroberto#ifdef WIN32 299258945Sroberto#define REVERSE64(w,x) { \ 300258945Sroberto isc_uint64_t tmp = (w); \ 301258945Sroberto tmp = (tmp >> 32) | (tmp << 32); \ 302258945Sroberto tmp = ((tmp & 0xff00ff00ff00ff00UL) >> 8) | \ 303258945Sroberto ((tmp & 0x00ff00ff00ff00ffUL) << 8); \ 304258945Sroberto (x) = ((tmp & 0xffff0000ffff0000UL) >> 16) | \ 305258945Sroberto ((tmp & 0x0000ffff0000ffffUL) << 16); \ 306258945Sroberto} 307258945Sroberto#else 308258945Sroberto#define REVERSE64(w,x) { \ 309258945Sroberto isc_uint64_t tmp = (w); \ 310258945Sroberto tmp = (tmp >> 32) | (tmp << 32); \ 311258945Sroberto tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \ 312258945Sroberto ((tmp & 0x00ff00ff00ff00ffULL) << 8); \ 313258945Sroberto (x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \ 314258945Sroberto ((tmp & 0x0000ffff0000ffffULL) << 16); \ 315258945Sroberto} 316258945Sroberto#endif 317258945Sroberto#endif /* BYTE_ORDER == LITTLE_ENDIAN */ 318258945Sroberto 319258945Sroberto/* 320258945Sroberto * Macro for incrementally adding the unsigned 64-bit integer n to the 321258945Sroberto * unsigned 128-bit integer (represented using a two-element array of 322258945Sroberto * 64-bit words): 323258945Sroberto */ 324258945Sroberto#define ADDINC128(w,n) { \ 325258945Sroberto (w)[0] += (isc_uint64_t)(n); \ 326258945Sroberto if ((w)[0] < (n)) { \ 327258945Sroberto (w)[1]++; \ 328258945Sroberto } \ 329258945Sroberto} 330258945Sroberto 331258945Sroberto/*** THE SIX LOGICAL FUNCTIONS ****************************************/ 332258945Sroberto/* 333258945Sroberto * Bit shifting and rotation (used by the six SHA-XYZ logical functions: 334258945Sroberto * 335258945Sroberto * NOTE: The naming of R and S appears backwards here (R is a SHIFT and 336258945Sroberto * S is a ROTATION) because the SHA-256/384/512 description document 337258945Sroberto * (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this 338258945Sroberto * same "backwards" definition. 339258945Sroberto */ 340258945Sroberto/* Shift-right (used in SHA-256, SHA-384, and SHA-512): */ 341258945Sroberto#define R(b,x) ((x) >> (b)) 342258945Sroberto/* 32-bit Rotate-right (used in SHA-256): */ 343258945Sroberto#define S32(b,x) (((x) >> (b)) | ((x) << (32 - (b)))) 344258945Sroberto/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */ 345258945Sroberto#define S64(b,x) (((x) >> (b)) | ((x) << (64 - (b)))) 346258945Sroberto 347258945Sroberto/* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */ 348258945Sroberto#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) 349258945Sroberto#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) 350258945Sroberto 351258945Sroberto/* Four of six logical functions used in SHA-256: */ 352258945Sroberto#define Sigma0_256(x) (S32(2, (x)) ^ S32(13, (x)) ^ S32(22, (x))) 353258945Sroberto#define Sigma1_256(x) (S32(6, (x)) ^ S32(11, (x)) ^ S32(25, (x))) 354258945Sroberto#define sigma0_256(x) (S32(7, (x)) ^ S32(18, (x)) ^ R(3 , (x))) 355258945Sroberto#define sigma1_256(x) (S32(17, (x)) ^ S32(19, (x)) ^ R(10, (x))) 356258945Sroberto 357258945Sroberto/* Four of six logical functions used in SHA-384 and SHA-512: */ 358258945Sroberto#define Sigma0_512(x) (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x))) 359258945Sroberto#define Sigma1_512(x) (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x))) 360258945Sroberto#define sigma0_512(x) (S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7, (x))) 361258945Sroberto#define sigma1_512(x) (S64(19, (x)) ^ S64(61, (x)) ^ R( 6, (x))) 362258945Sroberto 363258945Sroberto/*** INTERNAL FUNCTION PROTOTYPES *************************************/ 364258945Sroberto/* NOTE: These should not be accessed directly from outside this 365258945Sroberto * library -- they are intended for private internal visibility/use 366258945Sroberto * only. 367258945Sroberto */ 368258945Srobertovoid isc_sha512_last(isc_sha512_t *); 369258945Srobertovoid isc_sha256_transform(isc_sha256_t *, const isc_uint32_t*); 370258945Srobertovoid isc_sha512_transform(isc_sha512_t *, const isc_uint64_t*); 371258945Sroberto 372258945Sroberto 373258945Sroberto/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/ 374258945Sroberto/* Hash constant words K for SHA-224 and SHA-256: */ 375258945Srobertostatic const isc_uint32_t K256[64] = { 376258945Sroberto 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 377258945Sroberto 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 378258945Sroberto 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, 379258945Sroberto 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, 380258945Sroberto 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, 381258945Sroberto 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 382258945Sroberto 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 383258945Sroberto 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, 384258945Sroberto 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, 385258945Sroberto 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, 386258945Sroberto 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 387258945Sroberto 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 388258945Sroberto 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, 389258945Sroberto 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, 390258945Sroberto 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, 391258945Sroberto 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL 392258945Sroberto}; 393258945Sroberto 394258945Sroberto/* Initial hash value H for SHA-224: */ 395258945Srobertostatic const isc_uint32_t sha224_initial_hash_value[8] = { 396258945Sroberto 0xc1059ed8UL, 397258945Sroberto 0x367cd507UL, 398258945Sroberto 0x3070dd17UL, 399258945Sroberto 0xf70e5939UL, 400258945Sroberto 0xffc00b31UL, 401258945Sroberto 0x68581511UL, 402258945Sroberto 0x64f98fa7UL, 403258945Sroberto 0xbefa4fa4UL 404258945Sroberto}; 405258945Sroberto 406258945Sroberto/* Initial hash value H for SHA-256: */ 407258945Srobertostatic const isc_uint32_t sha256_initial_hash_value[8] = { 408258945Sroberto 0x6a09e667UL, 409258945Sroberto 0xbb67ae85UL, 410258945Sroberto 0x3c6ef372UL, 411258945Sroberto 0xa54ff53aUL, 412258945Sroberto 0x510e527fUL, 413258945Sroberto 0x9b05688cUL, 414258945Sroberto 0x1f83d9abUL, 415258945Sroberto 0x5be0cd19UL 416258945Sroberto}; 417258945Sroberto 418258945Sroberto#ifdef WIN32 419258945Sroberto/* Hash constant words K for SHA-384 and SHA-512: */ 420258945Srobertostatic const isc_uint64_t K512[80] = { 421258945Sroberto 0x428a2f98d728ae22UL, 0x7137449123ef65cdUL, 422258945Sroberto 0xb5c0fbcfec4d3b2fUL, 0xe9b5dba58189dbbcUL, 423258945Sroberto 0x3956c25bf348b538UL, 0x59f111f1b605d019UL, 424258945Sroberto 0x923f82a4af194f9bUL, 0xab1c5ed5da6d8118UL, 425258945Sroberto 0xd807aa98a3030242UL, 0x12835b0145706fbeUL, 426258945Sroberto 0x243185be4ee4b28cUL, 0x550c7dc3d5ffb4e2UL, 427258945Sroberto 0x72be5d74f27b896fUL, 0x80deb1fe3b1696b1UL, 428258945Sroberto 0x9bdc06a725c71235UL, 0xc19bf174cf692694UL, 429258945Sroberto 0xe49b69c19ef14ad2UL, 0xefbe4786384f25e3UL, 430258945Sroberto 0x0fc19dc68b8cd5b5UL, 0x240ca1cc77ac9c65UL, 431258945Sroberto 0x2de92c6f592b0275UL, 0x4a7484aa6ea6e483UL, 432258945Sroberto 0x5cb0a9dcbd41fbd4UL, 0x76f988da831153b5UL, 433258945Sroberto 0x983e5152ee66dfabUL, 0xa831c66d2db43210UL, 434258945Sroberto 0xb00327c898fb213fUL, 0xbf597fc7beef0ee4UL, 435258945Sroberto 0xc6e00bf33da88fc2UL, 0xd5a79147930aa725UL, 436258945Sroberto 0x06ca6351e003826fUL, 0x142929670a0e6e70UL, 437258945Sroberto 0x27b70a8546d22ffcUL, 0x2e1b21385c26c926UL, 438258945Sroberto 0x4d2c6dfc5ac42aedUL, 0x53380d139d95b3dfUL, 439258945Sroberto 0x650a73548baf63deUL, 0x766a0abb3c77b2a8UL, 440258945Sroberto 0x81c2c92e47edaee6UL, 0x92722c851482353bUL, 441258945Sroberto 0xa2bfe8a14cf10364UL, 0xa81a664bbc423001UL, 442258945Sroberto 0xc24b8b70d0f89791UL, 0xc76c51a30654be30UL, 443258945Sroberto 0xd192e819d6ef5218UL, 0xd69906245565a910UL, 444258945Sroberto 0xf40e35855771202aUL, 0x106aa07032bbd1b8UL, 445258945Sroberto 0x19a4c116b8d2d0c8UL, 0x1e376c085141ab53UL, 446258945Sroberto 0x2748774cdf8eeb99UL, 0x34b0bcb5e19b48a8UL, 447258945Sroberto 0x391c0cb3c5c95a63UL, 0x4ed8aa4ae3418acbUL, 448258945Sroberto 0x5b9cca4f7763e373UL, 0x682e6ff3d6b2b8a3UL, 449258945Sroberto 0x748f82ee5defb2fcUL, 0x78a5636f43172f60UL, 450258945Sroberto 0x84c87814a1f0ab72UL, 0x8cc702081a6439ecUL, 451258945Sroberto 0x90befffa23631e28UL, 0xa4506cebde82bde9UL, 452258945Sroberto 0xbef9a3f7b2c67915UL, 0xc67178f2e372532bUL, 453258945Sroberto 0xca273eceea26619cUL, 0xd186b8c721c0c207UL, 454258945Sroberto 0xeada7dd6cde0eb1eUL, 0xf57d4f7fee6ed178UL, 455258945Sroberto 0x06f067aa72176fbaUL, 0x0a637dc5a2c898a6UL, 456258945Sroberto 0x113f9804bef90daeUL, 0x1b710b35131c471bUL, 457258945Sroberto 0x28db77f523047d84UL, 0x32caab7b40c72493UL, 458258945Sroberto 0x3c9ebe0a15c9bebcUL, 0x431d67c49c100d4cUL, 459258945Sroberto 0x4cc5d4becb3e42b6UL, 0x597f299cfc657e2aUL, 460258945Sroberto 0x5fcb6fab3ad6faecUL, 0x6c44198c4a475817UL 461258945Sroberto}; 462258945Sroberto 463258945Sroberto/* Initial hash value H for SHA-384: */ 464258945Srobertostatic const isc_uint64_t sha384_initial_hash_value[8] = { 465258945Sroberto 0xcbbb9d5dc1059ed8UL, 466258945Sroberto 0x629a292a367cd507UL, 467258945Sroberto 0x9159015a3070dd17UL, 468258945Sroberto 0x152fecd8f70e5939UL, 469258945Sroberto 0x67332667ffc00b31UL, 470258945Sroberto 0x8eb44a8768581511UL, 471258945Sroberto 0xdb0c2e0d64f98fa7UL, 472258945Sroberto 0x47b5481dbefa4fa4UL 473258945Sroberto}; 474258945Sroberto 475258945Sroberto/* Initial hash value H for SHA-512: */ 476258945Srobertostatic const isc_uint64_t sha512_initial_hash_value[8] = { 477258945Sroberto 0x6a09e667f3bcc908U, 478258945Sroberto 0xbb67ae8584caa73bUL, 479258945Sroberto 0x3c6ef372fe94f82bUL, 480258945Sroberto 0xa54ff53a5f1d36f1UL, 481258945Sroberto 0x510e527fade682d1UL, 482258945Sroberto 0x9b05688c2b3e6c1fUL, 483258945Sroberto 0x1f83d9abfb41bd6bUL, 484258945Sroberto 0x5be0cd19137e2179UL 485258945Sroberto}; 486258945Sroberto#else 487258945Sroberto/* Hash constant words K for SHA-384 and SHA-512: */ 488258945Srobertostatic const isc_uint64_t K512[80] = { 489258945Sroberto 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 490258945Sroberto 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, 491258945Sroberto 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 492258945Sroberto 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 493258945Sroberto 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 494258945Sroberto 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, 495258945Sroberto 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 496258945Sroberto 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, 497258945Sroberto 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 498258945Sroberto 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 499258945Sroberto 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 500258945Sroberto 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, 501258945Sroberto 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 502258945Sroberto 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, 503258945Sroberto 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 504258945Sroberto 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 505258945Sroberto 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 506258945Sroberto 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, 507258945Sroberto 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 508258945Sroberto 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, 509258945Sroberto 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 510258945Sroberto 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 511258945Sroberto 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 512258945Sroberto 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, 513258945Sroberto 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 514258945Sroberto 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, 515258945Sroberto 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 516258945Sroberto 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 517258945Sroberto 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 518258945Sroberto 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, 519258945Sroberto 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 520258945Sroberto 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, 521258945Sroberto 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 522258945Sroberto 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 523258945Sroberto 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 524258945Sroberto 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, 525258945Sroberto 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 526258945Sroberto 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, 527258945Sroberto 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 528258945Sroberto 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL 529258945Sroberto}; 530258945Sroberto 531258945Sroberto/* Initial hash value H for SHA-384: */ 532258945Srobertostatic const isc_uint64_t sha384_initial_hash_value[8] = { 533258945Sroberto 0xcbbb9d5dc1059ed8ULL, 534258945Sroberto 0x629a292a367cd507ULL, 535258945Sroberto 0x9159015a3070dd17ULL, 536258945Sroberto 0x152fecd8f70e5939ULL, 537258945Sroberto 0x67332667ffc00b31ULL, 538258945Sroberto 0x8eb44a8768581511ULL, 539258945Sroberto 0xdb0c2e0d64f98fa7ULL, 540258945Sroberto 0x47b5481dbefa4fa4ULL 541258945Sroberto}; 542258945Sroberto 543258945Sroberto/* Initial hash value H for SHA-512: */ 544258945Srobertostatic const isc_uint64_t sha512_initial_hash_value[8] = { 545258945Sroberto 0x6a09e667f3bcc908ULL, 546258945Sroberto 0xbb67ae8584caa73bULL, 547258945Sroberto 0x3c6ef372fe94f82bULL, 548258945Sroberto 0xa54ff53a5f1d36f1ULL, 549258945Sroberto 0x510e527fade682d1ULL, 550258945Sroberto 0x9b05688c2b3e6c1fULL, 551258945Sroberto 0x1f83d9abfb41bd6bULL, 552258945Sroberto 0x5be0cd19137e2179ULL 553258945Sroberto}; 554258945Sroberto#endif 555258945Sroberto 556258945Sroberto 557258945Sroberto/*** SHA-224: *********************************************************/ 558258945Srobertovoid 559258945Srobertoisc_sha224_init(isc_sha224_t *context) { 560258945Sroberto if (context == (isc_sha256_t *)0) { 561258945Sroberto return; 562258945Sroberto } 563258945Sroberto memcpy(context->state, sha224_initial_hash_value, 564258945Sroberto ISC_SHA256_DIGESTLENGTH); 565258945Sroberto memset(context->buffer, 0, ISC_SHA256_BLOCK_LENGTH); 566258945Sroberto context->bitcount = 0; 567258945Sroberto} 568258945Sroberto 569258945Srobertovoid 570280849Scyisc_sha224_invalidate(isc_sha224_t *context) { 571280849Scy memset(context, 0, sizeof(isc_sha224_t)); 572280849Scy} 573280849Scy 574280849Scyvoid 575258945Srobertoisc_sha224_update(isc_sha224_t *context, const isc_uint8_t* data, size_t len) { 576258945Sroberto isc_sha256_update((isc_sha256_t *)context, data, len); 577258945Sroberto} 578258945Sroberto 579258945Srobertovoid 580258945Srobertoisc_sha224_final(isc_uint8_t digest[], isc_sha224_t *context) { 581258945Sroberto isc_uint8_t sha256_digest[ISC_SHA256_DIGESTLENGTH]; 582258945Sroberto isc_sha256_final(sha256_digest, (isc_sha256_t *)context); 583258945Sroberto memcpy(digest, sha256_digest, ISC_SHA224_DIGESTLENGTH); 584258945Sroberto memset(sha256_digest, 0, ISC_SHA256_DIGESTLENGTH); 585258945Sroberto} 586258945Sroberto 587258945Sroberto/*** SHA-256: *********************************************************/ 588258945Srobertovoid 589258945Srobertoisc_sha256_init(isc_sha256_t *context) { 590258945Sroberto if (context == (isc_sha256_t *)0) { 591258945Sroberto return; 592258945Sroberto } 593258945Sroberto memcpy(context->state, sha256_initial_hash_value, 594258945Sroberto ISC_SHA256_DIGESTLENGTH); 595258945Sroberto memset(context->buffer, 0, ISC_SHA256_BLOCK_LENGTH); 596258945Sroberto context->bitcount = 0; 597258945Sroberto} 598258945Sroberto 599280849Scyvoid 600280849Scyisc_sha256_invalidate(isc_sha256_t *context) { 601280849Scy memset(context, 0, sizeof(isc_sha256_t)); 602280849Scy} 603280849Scy 604258945Sroberto#ifdef ISC_SHA2_UNROLL_TRANSFORM 605258945Sroberto 606258945Sroberto/* Unrolled SHA-256 round macros: */ 607258945Sroberto 608258945Sroberto#if BYTE_ORDER == LITTLE_ENDIAN 609258945Sroberto 610258945Sroberto#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ 611258945Sroberto REVERSE32(*data++, W256[j]); \ 612258945Sroberto T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ 613258945Sroberto K256[j] + W256[j]; \ 614258945Sroberto (d) += T1; \ 615258945Sroberto (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ 616258945Sroberto j++ 617258945Sroberto 618258945Sroberto 619258945Sroberto#else /* BYTE_ORDER == LITTLE_ENDIAN */ 620258945Sroberto 621258945Sroberto#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ 622258945Sroberto T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ 623258945Sroberto K256[j] + (W256[j] = *data++); \ 624258945Sroberto (d) += T1; \ 625258945Sroberto (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ 626258945Sroberto j++ 627258945Sroberto 628258945Sroberto#endif /* BYTE_ORDER == LITTLE_ENDIAN */ 629258945Sroberto 630258945Sroberto#define ROUND256(a,b,c,d,e,f,g,h) \ 631258945Sroberto s0 = W256[(j+1)&0x0f]; \ 632258945Sroberto s0 = sigma0_256(s0); \ 633258945Sroberto s1 = W256[(j+14)&0x0f]; \ 634258945Sroberto s1 = sigma1_256(s1); \ 635258945Sroberto T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \ 636258945Sroberto (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \ 637258945Sroberto (d) += T1; \ 638258945Sroberto (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ 639258945Sroberto j++ 640258945Sroberto 641258945Srobertovoid isc_sha256_transform(isc_sha256_t *context, const isc_uint32_t* data) { 642258945Sroberto isc_uint32_t a, b, c, d, e, f, g, h, s0, s1; 643258945Sroberto isc_uint32_t T1, *W256; 644258945Sroberto int j; 645258945Sroberto 646258945Sroberto W256 = (isc_uint32_t*)context->buffer; 647258945Sroberto 648258945Sroberto /* Initialize registers with the prev. intermediate value */ 649258945Sroberto a = context->state[0]; 650258945Sroberto b = context->state[1]; 651258945Sroberto c = context->state[2]; 652258945Sroberto d = context->state[3]; 653258945Sroberto e = context->state[4]; 654258945Sroberto f = context->state[5]; 655258945Sroberto g = context->state[6]; 656258945Sroberto h = context->state[7]; 657258945Sroberto 658258945Sroberto j = 0; 659258945Sroberto do { 660258945Sroberto /* Rounds 0 to 15 (unrolled): */ 661258945Sroberto ROUND256_0_TO_15(a,b,c,d,e,f,g,h); 662258945Sroberto ROUND256_0_TO_15(h,a,b,c,d,e,f,g); 663258945Sroberto ROUND256_0_TO_15(g,h,a,b,c,d,e,f); 664258945Sroberto ROUND256_0_TO_15(f,g,h,a,b,c,d,e); 665258945Sroberto ROUND256_0_TO_15(e,f,g,h,a,b,c,d); 666258945Sroberto ROUND256_0_TO_15(d,e,f,g,h,a,b,c); 667258945Sroberto ROUND256_0_TO_15(c,d,e,f,g,h,a,b); 668258945Sroberto ROUND256_0_TO_15(b,c,d,e,f,g,h,a); 669258945Sroberto } while (j < 16); 670258945Sroberto 671258945Sroberto /* Now for the remaining rounds to 64: */ 672258945Sroberto do { 673258945Sroberto ROUND256(a,b,c,d,e,f,g,h); 674258945Sroberto ROUND256(h,a,b,c,d,e,f,g); 675258945Sroberto ROUND256(g,h,a,b,c,d,e,f); 676258945Sroberto ROUND256(f,g,h,a,b,c,d,e); 677258945Sroberto ROUND256(e,f,g,h,a,b,c,d); 678258945Sroberto ROUND256(d,e,f,g,h,a,b,c); 679258945Sroberto ROUND256(c,d,e,f,g,h,a,b); 680258945Sroberto ROUND256(b,c,d,e,f,g,h,a); 681258945Sroberto } while (j < 64); 682258945Sroberto 683258945Sroberto /* Compute the current intermediate hash value */ 684258945Sroberto context->state[0] += a; 685258945Sroberto context->state[1] += b; 686258945Sroberto context->state[2] += c; 687258945Sroberto context->state[3] += d; 688258945Sroberto context->state[4] += e; 689258945Sroberto context->state[5] += f; 690258945Sroberto context->state[6] += g; 691258945Sroberto context->state[7] += h; 692258945Sroberto 693258945Sroberto /* Clean up */ 694258945Sroberto a = b = c = d = e = f = g = h = T1 = 0; 695280849Scy /* Avoid compiler warnings */ 696280849Scy POST(a); POST(b); POST(c); POST(d); POST(e); POST(f); 697280849Scy POST(g); POST(h); POST(T1); 698258945Sroberto} 699258945Sroberto 700258945Sroberto#else /* ISC_SHA2_UNROLL_TRANSFORM */ 701258945Sroberto 702258945Srobertovoid 703258945Srobertoisc_sha256_transform(isc_sha256_t *context, const isc_uint32_t* data) { 704258945Sroberto isc_uint32_t a, b, c, d, e, f, g, h, s0, s1; 705258945Sroberto isc_uint32_t T1, T2, *W256; 706258945Sroberto int j; 707258945Sroberto 708258945Sroberto W256 = (isc_uint32_t*)context->buffer; 709258945Sroberto 710258945Sroberto /* Initialize registers with the prev. intermediate value */ 711258945Sroberto a = context->state[0]; 712258945Sroberto b = context->state[1]; 713258945Sroberto c = context->state[2]; 714258945Sroberto d = context->state[3]; 715258945Sroberto e = context->state[4]; 716258945Sroberto f = context->state[5]; 717258945Sroberto g = context->state[6]; 718258945Sroberto h = context->state[7]; 719258945Sroberto 720258945Sroberto j = 0; 721258945Sroberto do { 722258945Sroberto#if BYTE_ORDER == LITTLE_ENDIAN 723258945Sroberto /* Copy data while converting to host byte order */ 724258945Sroberto REVERSE32(*data++,W256[j]); 725258945Sroberto /* Apply the SHA-256 compression function to update a..h */ 726258945Sroberto T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j]; 727258945Sroberto#else /* BYTE_ORDER == LITTLE_ENDIAN */ 728258945Sroberto /* Apply the SHA-256 compression function to update a..h with copy */ 729258945Sroberto T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++); 730258945Sroberto#endif /* BYTE_ORDER == LITTLE_ENDIAN */ 731258945Sroberto T2 = Sigma0_256(a) + Maj(a, b, c); 732258945Sroberto h = g; 733258945Sroberto g = f; 734258945Sroberto f = e; 735258945Sroberto e = d + T1; 736258945Sroberto d = c; 737258945Sroberto c = b; 738258945Sroberto b = a; 739258945Sroberto a = T1 + T2; 740258945Sroberto 741258945Sroberto j++; 742258945Sroberto } while (j < 16); 743258945Sroberto 744258945Sroberto do { 745258945Sroberto /* Part of the message block expansion: */ 746258945Sroberto s0 = W256[(j+1)&0x0f]; 747258945Sroberto s0 = sigma0_256(s0); 748258945Sroberto s1 = W256[(j+14)&0x0f]; 749258945Sroberto s1 = sigma1_256(s1); 750258945Sroberto 751258945Sroberto /* Apply the SHA-256 compression function to update a..h */ 752258945Sroberto T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + 753258945Sroberto (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); 754258945Sroberto T2 = Sigma0_256(a) + Maj(a, b, c); 755258945Sroberto h = g; 756258945Sroberto g = f; 757258945Sroberto f = e; 758258945Sroberto e = d + T1; 759258945Sroberto d = c; 760258945Sroberto c = b; 761258945Sroberto b = a; 762258945Sroberto a = T1 + T2; 763258945Sroberto 764258945Sroberto j++; 765258945Sroberto } while (j < 64); 766258945Sroberto 767258945Sroberto /* Compute the current intermediate hash value */ 768258945Sroberto context->state[0] += a; 769258945Sroberto context->state[1] += b; 770258945Sroberto context->state[2] += c; 771258945Sroberto context->state[3] += d; 772258945Sroberto context->state[4] += e; 773258945Sroberto context->state[5] += f; 774258945Sroberto context->state[6] += g; 775258945Sroberto context->state[7] += h; 776258945Sroberto 777258945Sroberto /* Clean up */ 778258945Sroberto a = b = c = d = e = f = g = h = T1 = T2 = 0; 779280849Scy /* Avoid compiler warnings */ 780280849Scy POST(a); POST(b); POST(c); POST(d); POST(e); POST(f); 781280849Scy POST(g); POST(h); POST(T1); POST(T2); 782258945Sroberto} 783258945Sroberto 784258945Sroberto#endif /* ISC_SHA2_UNROLL_TRANSFORM */ 785258945Sroberto 786258945Srobertovoid 787258945Srobertoisc_sha256_update(isc_sha256_t *context, const isc_uint8_t *data, size_t len) { 788258945Sroberto unsigned int freespace, usedspace; 789258945Sroberto 790258945Sroberto if (len == 0U) { 791258945Sroberto /* Calling with no data is valid - we do nothing */ 792258945Sroberto return; 793258945Sroberto } 794258945Sroberto 795258945Sroberto /* Sanity check: */ 796258945Sroberto REQUIRE(context != (isc_sha256_t *)0 && data != (isc_uint8_t*)0); 797258945Sroberto 798258945Sroberto usedspace = (unsigned int)((context->bitcount >> 3) % 799258945Sroberto ISC_SHA256_BLOCK_LENGTH); 800258945Sroberto if (usedspace > 0) { 801258945Sroberto /* Calculate how much free space is available in the buffer */ 802258945Sroberto freespace = ISC_SHA256_BLOCK_LENGTH - usedspace; 803258945Sroberto 804258945Sroberto if (len >= freespace) { 805258945Sroberto /* Fill the buffer completely and process it */ 806258945Sroberto memcpy(&context->buffer[usedspace], data, freespace); 807258945Sroberto context->bitcount += freespace << 3; 808258945Sroberto len -= freespace; 809258945Sroberto data += freespace; 810258945Sroberto isc_sha256_transform(context, 811258945Sroberto (isc_uint32_t*)context->buffer); 812258945Sroberto } else { 813258945Sroberto /* The buffer is not yet full */ 814258945Sroberto memcpy(&context->buffer[usedspace], data, len); 815258945Sroberto context->bitcount += len << 3; 816258945Sroberto /* Clean up: */ 817258945Sroberto usedspace = freespace = 0; 818280849Scy /* Avoid compiler warnings: */ 819280849Scy POST(usedspace); POST(freespace); 820258945Sroberto return; 821258945Sroberto } 822258945Sroberto } 823258945Sroberto while (len >= ISC_SHA256_BLOCK_LENGTH) { 824258945Sroberto /* Process as many complete blocks as we can */ 825258945Sroberto memcpy(context->buffer, data, ISC_SHA256_BLOCK_LENGTH); 826258945Sroberto isc_sha256_transform(context, (isc_uint32_t*)context->buffer); 827258945Sroberto context->bitcount += ISC_SHA256_BLOCK_LENGTH << 3; 828258945Sroberto len -= ISC_SHA256_BLOCK_LENGTH; 829258945Sroberto data += ISC_SHA256_BLOCK_LENGTH; 830258945Sroberto } 831258945Sroberto if (len > 0U) { 832258945Sroberto /* There's left-overs, so save 'em */ 833258945Sroberto memcpy(context->buffer, data, len); 834258945Sroberto context->bitcount += len << 3; 835258945Sroberto } 836258945Sroberto /* Clean up: */ 837258945Sroberto usedspace = freespace = 0; 838280849Scy /* Avoid compiler warnings: */ 839280849Scy POST(usedspace); POST(freespace); 840258945Sroberto} 841258945Sroberto 842258945Srobertovoid 843258945Srobertoisc_sha256_final(isc_uint8_t digest[], isc_sha256_t *context) { 844258945Sroberto isc_uint32_t *d = (isc_uint32_t*)digest; 845258945Sroberto unsigned int usedspace; 846258945Sroberto 847258945Sroberto /* Sanity check: */ 848258945Sroberto REQUIRE(context != (isc_sha256_t *)0); 849258945Sroberto 850258945Sroberto /* If no digest buffer is passed, we don't bother doing this: */ 851258945Sroberto if (digest != (isc_uint8_t*)0) { 852258945Sroberto usedspace = (unsigned int)((context->bitcount >> 3) % 853258945Sroberto ISC_SHA256_BLOCK_LENGTH); 854258945Sroberto#if BYTE_ORDER == LITTLE_ENDIAN 855258945Sroberto /* Convert FROM host byte order */ 856258945Sroberto REVERSE64(context->bitcount,context->bitcount); 857258945Sroberto#endif 858258945Sroberto if (usedspace > 0) { 859258945Sroberto /* Begin padding with a 1 bit: */ 860258945Sroberto context->buffer[usedspace++] = 0x80; 861258945Sroberto 862258945Sroberto if (usedspace <= ISC_SHA256_SHORT_BLOCK_LENGTH) { 863258945Sroberto /* Set-up for the last transform: */ 864258945Sroberto memset(&context->buffer[usedspace], 0, 865258945Sroberto ISC_SHA256_SHORT_BLOCK_LENGTH - usedspace); 866258945Sroberto } else { 867258945Sroberto if (usedspace < ISC_SHA256_BLOCK_LENGTH) { 868258945Sroberto memset(&context->buffer[usedspace], 0, 869258945Sroberto ISC_SHA256_BLOCK_LENGTH - 870258945Sroberto usedspace); 871258945Sroberto } 872258945Sroberto /* Do second-to-last transform: */ 873258945Sroberto isc_sha256_transform(context, 874258945Sroberto (isc_uint32_t*)context->buffer); 875258945Sroberto 876258945Sroberto /* And set-up for the last transform: */ 877258945Sroberto memset(context->buffer, 0, 878258945Sroberto ISC_SHA256_SHORT_BLOCK_LENGTH); 879258945Sroberto } 880258945Sroberto } else { 881258945Sroberto /* Set-up for the last transform: */ 882258945Sroberto memset(context->buffer, 0, ISC_SHA256_SHORT_BLOCK_LENGTH); 883258945Sroberto 884258945Sroberto /* Begin padding with a 1 bit: */ 885258945Sroberto *context->buffer = 0x80; 886258945Sroberto } 887258945Sroberto /* Set the bit count: */ 888258945Sroberto *(isc_uint64_t*)&context->buffer[ISC_SHA256_SHORT_BLOCK_LENGTH] = context->bitcount; 889258945Sroberto 890258945Sroberto /* Final transform: */ 891258945Sroberto isc_sha256_transform(context, (isc_uint32_t*)context->buffer); 892258945Sroberto 893258945Sroberto#if BYTE_ORDER == LITTLE_ENDIAN 894258945Sroberto { 895258945Sroberto /* Convert TO host byte order */ 896258945Sroberto int j; 897258945Sroberto for (j = 0; j < 8; j++) { 898258945Sroberto REVERSE32(context->state[j],context->state[j]); 899258945Sroberto *d++ = context->state[j]; 900258945Sroberto } 901258945Sroberto } 902258945Sroberto#else 903258945Sroberto memcpy(d, context->state, ISC_SHA256_DIGESTLENGTH); 904258945Sroberto#endif 905258945Sroberto } 906258945Sroberto 907258945Sroberto /* Clean up state data: */ 908280849Scy memset(context, 0, sizeof(*context)); 909258945Sroberto usedspace = 0; 910280849Scy POST(usedspace); 911258945Sroberto} 912258945Sroberto 913258945Sroberto/*** SHA-512: *********************************************************/ 914258945Srobertovoid 915258945Srobertoisc_sha512_init(isc_sha512_t *context) { 916258945Sroberto if (context == (isc_sha512_t *)0) { 917258945Sroberto return; 918258945Sroberto } 919258945Sroberto memcpy(context->state, sha512_initial_hash_value, 920258945Sroberto ISC_SHA512_DIGESTLENGTH); 921258945Sroberto memset(context->buffer, 0, ISC_SHA512_BLOCK_LENGTH); 922258945Sroberto context->bitcount[0] = context->bitcount[1] = 0; 923258945Sroberto} 924258945Sroberto 925280849Scyvoid 926280849Scyisc_sha512_invalidate(isc_sha512_t *context) { 927280849Scy memset(context, 0, sizeof(isc_sha512_t)); 928280849Scy} 929280849Scy 930258945Sroberto#ifdef ISC_SHA2_UNROLL_TRANSFORM 931258945Sroberto 932258945Sroberto/* Unrolled SHA-512 round macros: */ 933258945Sroberto#if BYTE_ORDER == LITTLE_ENDIAN 934258945Sroberto 935258945Sroberto#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ 936258945Sroberto REVERSE64(*data++, W512[j]); \ 937258945Sroberto T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ 938258945Sroberto K512[j] + W512[j]; \ 939258945Sroberto (d) += T1, \ 940258945Sroberto (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \ 941258945Sroberto j++ 942258945Sroberto 943258945Sroberto 944258945Sroberto#else /* BYTE_ORDER == LITTLE_ENDIAN */ 945258945Sroberto 946258945Sroberto#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ 947258945Sroberto T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ 948258945Sroberto K512[j] + (W512[j] = *data++); \ 949258945Sroberto (d) += T1; \ 950258945Sroberto (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ 951258945Sroberto j++ 952258945Sroberto 953258945Sroberto#endif /* BYTE_ORDER == LITTLE_ENDIAN */ 954258945Sroberto 955258945Sroberto#define ROUND512(a,b,c,d,e,f,g,h) \ 956258945Sroberto s0 = W512[(j+1)&0x0f]; \ 957258945Sroberto s0 = sigma0_512(s0); \ 958258945Sroberto s1 = W512[(j+14)&0x0f]; \ 959258945Sroberto s1 = sigma1_512(s1); \ 960258945Sroberto T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \ 961258945Sroberto (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \ 962258945Sroberto (d) += T1; \ 963258945Sroberto (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ 964258945Sroberto j++ 965258945Sroberto 966258945Srobertovoid isc_sha512_transform(isc_sha512_t *context, const isc_uint64_t* data) { 967258945Sroberto isc_uint64_t a, b, c, d, e, f, g, h, s0, s1; 968258945Sroberto isc_uint64_t T1, *W512 = (isc_uint64_t*)context->buffer; 969258945Sroberto int j; 970258945Sroberto 971258945Sroberto /* Initialize registers with the prev. intermediate value */ 972258945Sroberto a = context->state[0]; 973258945Sroberto b = context->state[1]; 974258945Sroberto c = context->state[2]; 975258945Sroberto d = context->state[3]; 976258945Sroberto e = context->state[4]; 977258945Sroberto f = context->state[5]; 978258945Sroberto g = context->state[6]; 979258945Sroberto h = context->state[7]; 980258945Sroberto 981258945Sroberto j = 0; 982258945Sroberto do { 983258945Sroberto ROUND512_0_TO_15(a,b,c,d,e,f,g,h); 984258945Sroberto ROUND512_0_TO_15(h,a,b,c,d,e,f,g); 985258945Sroberto ROUND512_0_TO_15(g,h,a,b,c,d,e,f); 986258945Sroberto ROUND512_0_TO_15(f,g,h,a,b,c,d,e); 987258945Sroberto ROUND512_0_TO_15(e,f,g,h,a,b,c,d); 988258945Sroberto ROUND512_0_TO_15(d,e,f,g,h,a,b,c); 989258945Sroberto ROUND512_0_TO_15(c,d,e,f,g,h,a,b); 990258945Sroberto ROUND512_0_TO_15(b,c,d,e,f,g,h,a); 991258945Sroberto } while (j < 16); 992258945Sroberto 993258945Sroberto /* Now for the remaining rounds up to 79: */ 994258945Sroberto do { 995258945Sroberto ROUND512(a,b,c,d,e,f,g,h); 996258945Sroberto ROUND512(h,a,b,c,d,e,f,g); 997258945Sroberto ROUND512(g,h,a,b,c,d,e,f); 998258945Sroberto ROUND512(f,g,h,a,b,c,d,e); 999258945Sroberto ROUND512(e,f,g,h,a,b,c,d); 1000258945Sroberto ROUND512(d,e,f,g,h,a,b,c); 1001258945Sroberto ROUND512(c,d,e,f,g,h,a,b); 1002258945Sroberto ROUND512(b,c,d,e,f,g,h,a); 1003258945Sroberto } while (j < 80); 1004258945Sroberto 1005258945Sroberto /* Compute the current intermediate hash value */ 1006258945Sroberto context->state[0] += a; 1007258945Sroberto context->state[1] += b; 1008258945Sroberto context->state[2] += c; 1009258945Sroberto context->state[3] += d; 1010258945Sroberto context->state[4] += e; 1011258945Sroberto context->state[5] += f; 1012258945Sroberto context->state[6] += g; 1013258945Sroberto context->state[7] += h; 1014258945Sroberto 1015258945Sroberto /* Clean up */ 1016258945Sroberto a = b = c = d = e = f = g = h = T1 = 0; 1017280849Scy /* Avoid compiler warnings */ 1018280849Scy POST(a); POST(b); POST(c); POST(d); POST(e); POST(f); 1019280849Scy POST(g); POST(h); POST(T1); 1020258945Sroberto} 1021258945Sroberto 1022258945Sroberto#else /* ISC_SHA2_UNROLL_TRANSFORM */ 1023258945Sroberto 1024258945Srobertovoid 1025258945Srobertoisc_sha512_transform(isc_sha512_t *context, const isc_uint64_t* data) { 1026258945Sroberto isc_uint64_t a, b, c, d, e, f, g, h, s0, s1; 1027258945Sroberto isc_uint64_t T1, T2, *W512 = (isc_uint64_t*)context->buffer; 1028258945Sroberto int j; 1029258945Sroberto 1030258945Sroberto /* Initialize registers with the prev. intermediate value */ 1031258945Sroberto a = context->state[0]; 1032258945Sroberto b = context->state[1]; 1033258945Sroberto c = context->state[2]; 1034258945Sroberto d = context->state[3]; 1035258945Sroberto e = context->state[4]; 1036258945Sroberto f = context->state[5]; 1037258945Sroberto g = context->state[6]; 1038258945Sroberto h = context->state[7]; 1039258945Sroberto 1040258945Sroberto j = 0; 1041258945Sroberto do { 1042258945Sroberto#if BYTE_ORDER == LITTLE_ENDIAN 1043258945Sroberto /* Convert TO host byte order */ 1044258945Sroberto REVERSE64(*data++, W512[j]); 1045258945Sroberto /* Apply the SHA-512 compression function to update a..h */ 1046258945Sroberto T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j]; 1047258945Sroberto#else /* BYTE_ORDER == LITTLE_ENDIAN */ 1048258945Sroberto /* Apply the SHA-512 compression function to update a..h with copy */ 1049258945Sroberto T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++); 1050258945Sroberto#endif /* BYTE_ORDER == LITTLE_ENDIAN */ 1051258945Sroberto T2 = Sigma0_512(a) + Maj(a, b, c); 1052258945Sroberto h = g; 1053258945Sroberto g = f; 1054258945Sroberto f = e; 1055258945Sroberto e = d + T1; 1056258945Sroberto d = c; 1057258945Sroberto c = b; 1058258945Sroberto b = a; 1059258945Sroberto a = T1 + T2; 1060258945Sroberto 1061258945Sroberto j++; 1062258945Sroberto } while (j < 16); 1063258945Sroberto 1064258945Sroberto do { 1065258945Sroberto /* Part of the message block expansion: */ 1066258945Sroberto s0 = W512[(j+1)&0x0f]; 1067258945Sroberto s0 = sigma0_512(s0); 1068258945Sroberto s1 = W512[(j+14)&0x0f]; 1069258945Sroberto s1 = sigma1_512(s1); 1070258945Sroberto 1071258945Sroberto /* Apply the SHA-512 compression function to update a..h */ 1072258945Sroberto T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + 1073258945Sroberto (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); 1074258945Sroberto T2 = Sigma0_512(a) + Maj(a, b, c); 1075258945Sroberto h = g; 1076258945Sroberto g = f; 1077258945Sroberto f = e; 1078258945Sroberto e = d + T1; 1079258945Sroberto d = c; 1080258945Sroberto c = b; 1081258945Sroberto b = a; 1082258945Sroberto a = T1 + T2; 1083258945Sroberto 1084258945Sroberto j++; 1085258945Sroberto } while (j < 80); 1086258945Sroberto 1087258945Sroberto /* Compute the current intermediate hash value */ 1088258945Sroberto context->state[0] += a; 1089258945Sroberto context->state[1] += b; 1090258945Sroberto context->state[2] += c; 1091258945Sroberto context->state[3] += d; 1092258945Sroberto context->state[4] += e; 1093258945Sroberto context->state[5] += f; 1094258945Sroberto context->state[6] += g; 1095258945Sroberto context->state[7] += h; 1096258945Sroberto 1097258945Sroberto /* Clean up */ 1098258945Sroberto a = b = c = d = e = f = g = h = T1 = T2 = 0; 1099280849Scy /* Avoid compiler warnings */ 1100280849Scy POST(a); POST(b); POST(c); POST(d); POST(e); POST(f); 1101280849Scy POST(g); POST(h); POST(T1); POST(T2); 1102258945Sroberto} 1103258945Sroberto 1104258945Sroberto#endif /* ISC_SHA2_UNROLL_TRANSFORM */ 1105258945Sroberto 1106258945Srobertovoid isc_sha512_update(isc_sha512_t *context, const isc_uint8_t *data, size_t len) { 1107258945Sroberto unsigned int freespace, usedspace; 1108258945Sroberto 1109258945Sroberto if (len == 0U) { 1110258945Sroberto /* Calling with no data is valid - we do nothing */ 1111258945Sroberto return; 1112258945Sroberto } 1113258945Sroberto 1114258945Sroberto /* Sanity check: */ 1115258945Sroberto REQUIRE(context != (isc_sha512_t *)0 && data != (isc_uint8_t*)0); 1116258945Sroberto 1117258945Sroberto usedspace = (unsigned int)((context->bitcount[0] >> 3) % 1118258945Sroberto ISC_SHA512_BLOCK_LENGTH); 1119258945Sroberto if (usedspace > 0) { 1120258945Sroberto /* Calculate how much free space is available in the buffer */ 1121258945Sroberto freespace = ISC_SHA512_BLOCK_LENGTH - usedspace; 1122258945Sroberto 1123258945Sroberto if (len >= freespace) { 1124258945Sroberto /* Fill the buffer completely and process it */ 1125258945Sroberto memcpy(&context->buffer[usedspace], data, freespace); 1126258945Sroberto ADDINC128(context->bitcount, freespace << 3); 1127258945Sroberto len -= freespace; 1128258945Sroberto data += freespace; 1129258945Sroberto isc_sha512_transform(context, 1130258945Sroberto (isc_uint64_t*)context->buffer); 1131258945Sroberto } else { 1132258945Sroberto /* The buffer is not yet full */ 1133258945Sroberto memcpy(&context->buffer[usedspace], data, len); 1134258945Sroberto ADDINC128(context->bitcount, len << 3); 1135258945Sroberto /* Clean up: */ 1136258945Sroberto usedspace = freespace = 0; 1137280849Scy /* Avoid compiler warnings: */ 1138280849Scy POST(usedspace); POST(freespace); 1139258945Sroberto return; 1140258945Sroberto } 1141258945Sroberto } 1142258945Sroberto while (len >= ISC_SHA512_BLOCK_LENGTH) { 1143258945Sroberto /* Process as many complete blocks as we can */ 1144258945Sroberto memcpy(context->buffer, data, ISC_SHA512_BLOCK_LENGTH); 1145258945Sroberto isc_sha512_transform(context, (isc_uint64_t*)context->buffer); 1146258945Sroberto ADDINC128(context->bitcount, ISC_SHA512_BLOCK_LENGTH << 3); 1147258945Sroberto len -= ISC_SHA512_BLOCK_LENGTH; 1148258945Sroberto data += ISC_SHA512_BLOCK_LENGTH; 1149258945Sroberto } 1150258945Sroberto if (len > 0U) { 1151258945Sroberto /* There's left-overs, so save 'em */ 1152258945Sroberto memcpy(context->buffer, data, len); 1153258945Sroberto ADDINC128(context->bitcount, len << 3); 1154258945Sroberto } 1155258945Sroberto /* Clean up: */ 1156258945Sroberto usedspace = freespace = 0; 1157280849Scy /* Avoid compiler warnings: */ 1158280849Scy POST(usedspace); POST(freespace); 1159258945Sroberto} 1160258945Sroberto 1161258945Srobertovoid isc_sha512_last(isc_sha512_t *context) { 1162258945Sroberto unsigned int usedspace; 1163258945Sroberto 1164258945Sroberto usedspace = (unsigned int)((context->bitcount[0] >> 3) % 1165258945Sroberto ISC_SHA512_BLOCK_LENGTH); 1166258945Sroberto#if BYTE_ORDER == LITTLE_ENDIAN 1167258945Sroberto /* Convert FROM host byte order */ 1168258945Sroberto REVERSE64(context->bitcount[0],context->bitcount[0]); 1169258945Sroberto REVERSE64(context->bitcount[1],context->bitcount[1]); 1170258945Sroberto#endif 1171258945Sroberto if (usedspace > 0) { 1172258945Sroberto /* Begin padding with a 1 bit: */ 1173258945Sroberto context->buffer[usedspace++] = 0x80; 1174258945Sroberto 1175258945Sroberto if (usedspace <= ISC_SHA512_SHORT_BLOCK_LENGTH) { 1176258945Sroberto /* Set-up for the last transform: */ 1177258945Sroberto memset(&context->buffer[usedspace], 0, 1178258945Sroberto ISC_SHA512_SHORT_BLOCK_LENGTH - usedspace); 1179258945Sroberto } else { 1180258945Sroberto if (usedspace < ISC_SHA512_BLOCK_LENGTH) { 1181258945Sroberto memset(&context->buffer[usedspace], 0, 1182258945Sroberto ISC_SHA512_BLOCK_LENGTH - usedspace); 1183258945Sroberto } 1184258945Sroberto /* Do second-to-last transform: */ 1185258945Sroberto isc_sha512_transform(context, 1186258945Sroberto (isc_uint64_t*)context->buffer); 1187258945Sroberto 1188258945Sroberto /* And set-up for the last transform: */ 1189258945Sroberto memset(context->buffer, 0, ISC_SHA512_BLOCK_LENGTH - 2); 1190258945Sroberto } 1191258945Sroberto } else { 1192258945Sroberto /* Prepare for final transform: */ 1193258945Sroberto memset(context->buffer, 0, ISC_SHA512_SHORT_BLOCK_LENGTH); 1194258945Sroberto 1195258945Sroberto /* Begin padding with a 1 bit: */ 1196258945Sroberto *context->buffer = 0x80; 1197258945Sroberto } 1198258945Sroberto /* Store the length of input data (in bits): */ 1199258945Sroberto *(isc_uint64_t*)&context->buffer[ISC_SHA512_SHORT_BLOCK_LENGTH] = context->bitcount[1]; 1200258945Sroberto *(isc_uint64_t*)&context->buffer[ISC_SHA512_SHORT_BLOCK_LENGTH+8] = context->bitcount[0]; 1201258945Sroberto 1202258945Sroberto /* Final transform: */ 1203258945Sroberto isc_sha512_transform(context, (isc_uint64_t*)context->buffer); 1204258945Sroberto} 1205258945Sroberto 1206258945Srobertovoid isc_sha512_final(isc_uint8_t digest[], isc_sha512_t *context) { 1207258945Sroberto isc_uint64_t *d = (isc_uint64_t*)digest; 1208258945Sroberto 1209258945Sroberto /* Sanity check: */ 1210258945Sroberto REQUIRE(context != (isc_sha512_t *)0); 1211258945Sroberto 1212258945Sroberto /* If no digest buffer is passed, we don't bother doing this: */ 1213258945Sroberto if (digest != (isc_uint8_t*)0) { 1214258945Sroberto isc_sha512_last(context); 1215258945Sroberto 1216258945Sroberto /* Save the hash data for output: */ 1217258945Sroberto#if BYTE_ORDER == LITTLE_ENDIAN 1218258945Sroberto { 1219258945Sroberto /* Convert TO host byte order */ 1220258945Sroberto int j; 1221258945Sroberto for (j = 0; j < 8; j++) { 1222258945Sroberto REVERSE64(context->state[j],context->state[j]); 1223258945Sroberto *d++ = context->state[j]; 1224258945Sroberto } 1225258945Sroberto } 1226258945Sroberto#else 1227258945Sroberto memcpy(d, context->state, ISC_SHA512_DIGESTLENGTH); 1228258945Sroberto#endif 1229258945Sroberto } 1230258945Sroberto 1231258945Sroberto /* Zero out state data */ 1232280849Scy memset(context, 0, sizeof(*context)); 1233258945Sroberto} 1234258945Sroberto 1235258945Sroberto 1236258945Sroberto/*** SHA-384: *********************************************************/ 1237258945Srobertovoid 1238258945Srobertoisc_sha384_init(isc_sha384_t *context) { 1239258945Sroberto if (context == (isc_sha384_t *)0) { 1240258945Sroberto return; 1241258945Sroberto } 1242258945Sroberto memcpy(context->state, sha384_initial_hash_value, 1243258945Sroberto ISC_SHA512_DIGESTLENGTH); 1244258945Sroberto memset(context->buffer, 0, ISC_SHA384_BLOCK_LENGTH); 1245258945Sroberto context->bitcount[0] = context->bitcount[1] = 0; 1246258945Sroberto} 1247258945Sroberto 1248258945Srobertovoid 1249280849Scyisc_sha384_invalidate(isc_sha384_t *context) { 1250280849Scy memset(context, 0, sizeof(isc_sha384_t)); 1251280849Scy} 1252280849Scy 1253280849Scyvoid 1254258945Srobertoisc_sha384_update(isc_sha384_t *context, const isc_uint8_t* data, size_t len) { 1255258945Sroberto isc_sha512_update((isc_sha512_t *)context, data, len); 1256258945Sroberto} 1257258945Sroberto 1258258945Srobertovoid 1259258945Srobertoisc_sha384_final(isc_uint8_t digest[], isc_sha384_t *context) { 1260258945Sroberto isc_uint64_t *d = (isc_uint64_t*)digest; 1261258945Sroberto 1262258945Sroberto /* Sanity check: */ 1263258945Sroberto REQUIRE(context != (isc_sha384_t *)0); 1264258945Sroberto 1265258945Sroberto /* If no digest buffer is passed, we don't bother doing this: */ 1266258945Sroberto if (digest != (isc_uint8_t*)0) { 1267258945Sroberto isc_sha512_last((isc_sha512_t *)context); 1268258945Sroberto 1269258945Sroberto /* Save the hash data for output: */ 1270258945Sroberto#if BYTE_ORDER == LITTLE_ENDIAN 1271258945Sroberto { 1272258945Sroberto /* Convert TO host byte order */ 1273258945Sroberto int j; 1274258945Sroberto for (j = 0; j < 6; j++) { 1275258945Sroberto REVERSE64(context->state[j],context->state[j]); 1276258945Sroberto *d++ = context->state[j]; 1277258945Sroberto } 1278258945Sroberto } 1279258945Sroberto#else 1280258945Sroberto memcpy(d, context->state, ISC_SHA384_DIGESTLENGTH); 1281258945Sroberto#endif 1282258945Sroberto } 1283258945Sroberto 1284258945Sroberto /* Zero out state data */ 1285280849Scy memset(context, 0, sizeof(*context)); 1286258945Sroberto} 1287280849Scy#endif /* !ISC_PLATFORM_OPENSSLHASH */ 1288258945Sroberto 1289280849Scy/* 1290280849Scy * Constant used by SHA256/384/512_End() functions for converting the 1291280849Scy * digest to a readable hexadecimal character string: 1292280849Scy */ 1293280849Scystatic const char *sha2_hex_digits = "0123456789abcdef"; 1294280849Scy 1295258945Srobertochar * 1296280849Scyisc_sha224_end(isc_sha224_t *context, char buffer[]) { 1297280849Scy isc_uint8_t digest[ISC_SHA224_DIGESTLENGTH], *d = digest; 1298280849Scy unsigned int i; 1299280849Scy 1300280849Scy /* Sanity check: */ 1301280849Scy REQUIRE(context != (isc_sha224_t *)0); 1302280849Scy 1303280849Scy if (buffer != (char*)0) { 1304280849Scy isc_sha224_final(digest, context); 1305280849Scy 1306280849Scy for (i = 0; i < ISC_SHA224_DIGESTLENGTH; i++) { 1307280849Scy *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; 1308280849Scy *buffer++ = sha2_hex_digits[*d & 0x0f]; 1309280849Scy d++; 1310280849Scy } 1311280849Scy *buffer = (char)0; 1312280849Scy } else { 1313280849Scy#ifdef ISC_PLATFORM_OPENSSLHASH 1314280849Scy EVP_MD_CTX_cleanup(context); 1315280849Scy#else 1316280849Scy memset(context, 0, sizeof(*context)); 1317280849Scy#endif 1318280849Scy } 1319280849Scy memset(digest, 0, ISC_SHA224_DIGESTLENGTH); 1320280849Scy return buffer; 1321280849Scy} 1322280849Scy 1323280849Scychar * 1324280849Scyisc_sha224_data(const isc_uint8_t *data, size_t len, 1325280849Scy char digest[ISC_SHA224_DIGESTSTRINGLENGTH]) 1326280849Scy{ 1327280849Scy isc_sha224_t context; 1328280849Scy 1329280849Scy isc_sha224_init(&context); 1330280849Scy isc_sha224_update(&context, data, len); 1331280849Scy return (isc_sha224_end(&context, digest)); 1332280849Scy} 1333280849Scy 1334280849Scychar * 1335280849Scyisc_sha256_end(isc_sha256_t *context, char buffer[]) { 1336280849Scy isc_uint8_t digest[ISC_SHA256_DIGESTLENGTH], *d = digest; 1337280849Scy unsigned int i; 1338280849Scy 1339280849Scy /* Sanity check: */ 1340280849Scy REQUIRE(context != (isc_sha256_t *)0); 1341280849Scy 1342280849Scy if (buffer != (char*)0) { 1343280849Scy isc_sha256_final(digest, context); 1344280849Scy 1345280849Scy for (i = 0; i < ISC_SHA256_DIGESTLENGTH; i++) { 1346280849Scy *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; 1347280849Scy *buffer++ = sha2_hex_digits[*d & 0x0f]; 1348280849Scy d++; 1349280849Scy } 1350280849Scy *buffer = (char)0; 1351280849Scy } else { 1352280849Scy#ifdef ISC_PLATFORM_OPENSSLHASH 1353280849Scy EVP_MD_CTX_cleanup(context); 1354280849Scy#else 1355280849Scy memset(context, 0, sizeof(*context)); 1356280849Scy#endif 1357280849Scy } 1358280849Scy memset(digest, 0, ISC_SHA256_DIGESTLENGTH); 1359280849Scy return buffer; 1360280849Scy} 1361280849Scy 1362280849Scychar * 1363280849Scyisc_sha256_data(const isc_uint8_t* data, size_t len, 1364280849Scy char digest[ISC_SHA256_DIGESTSTRINGLENGTH]) 1365280849Scy{ 1366280849Scy isc_sha256_t context; 1367280849Scy 1368280849Scy isc_sha256_init(&context); 1369280849Scy isc_sha256_update(&context, data, len); 1370280849Scy return (isc_sha256_end(&context, digest)); 1371280849Scy} 1372280849Scy 1373280849Scychar * 1374280849Scyisc_sha512_end(isc_sha512_t *context, char buffer[]) { 1375280849Scy isc_uint8_t digest[ISC_SHA512_DIGESTLENGTH], *d = digest; 1376280849Scy unsigned int i; 1377280849Scy 1378280849Scy /* Sanity check: */ 1379280849Scy REQUIRE(context != (isc_sha512_t *)0); 1380280849Scy 1381280849Scy if (buffer != (char*)0) { 1382280849Scy isc_sha512_final(digest, context); 1383280849Scy 1384280849Scy for (i = 0; i < ISC_SHA512_DIGESTLENGTH; i++) { 1385280849Scy *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; 1386280849Scy *buffer++ = sha2_hex_digits[*d & 0x0f]; 1387280849Scy d++; 1388280849Scy } 1389280849Scy *buffer = (char)0; 1390280849Scy } else { 1391280849Scy#ifdef ISC_PLATFORM_OPENSSLHASH 1392280849Scy EVP_MD_CTX_cleanup(context); 1393280849Scy#else 1394280849Scy memset(context, 0, sizeof(*context)); 1395280849Scy#endif 1396280849Scy } 1397280849Scy memset(digest, 0, ISC_SHA512_DIGESTLENGTH); 1398280849Scy return buffer; 1399280849Scy} 1400280849Scy 1401280849Scychar * 1402280849Scyisc_sha512_data(const isc_uint8_t *data, size_t len, 1403280849Scy char digest[ISC_SHA512_DIGESTSTRINGLENGTH]) 1404280849Scy{ 1405280849Scy isc_sha512_t context; 1406280849Scy 1407280849Scy isc_sha512_init(&context); 1408280849Scy isc_sha512_update(&context, data, len); 1409280849Scy return (isc_sha512_end(&context, digest)); 1410280849Scy} 1411280849Scy 1412280849Scychar * 1413258945Srobertoisc_sha384_end(isc_sha384_t *context, char buffer[]) { 1414258945Sroberto isc_uint8_t digest[ISC_SHA384_DIGESTLENGTH], *d = digest; 1415258945Sroberto unsigned int i; 1416258945Sroberto 1417258945Sroberto /* Sanity check: */ 1418258945Sroberto REQUIRE(context != (isc_sha384_t *)0); 1419258945Sroberto 1420258945Sroberto if (buffer != (char*)0) { 1421258945Sroberto isc_sha384_final(digest, context); 1422258945Sroberto 1423258945Sroberto for (i = 0; i < ISC_SHA384_DIGESTLENGTH; i++) { 1424258945Sroberto *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; 1425258945Sroberto *buffer++ = sha2_hex_digits[*d & 0x0f]; 1426258945Sroberto d++; 1427258945Sroberto } 1428258945Sroberto *buffer = (char)0; 1429258945Sroberto } else { 1430280849Scy#ifdef ISC_PLATFORM_OPENSSLHASH 1431280849Scy EVP_MD_CTX_cleanup(context); 1432280849Scy#else 1433280849Scy memset(context, 0, sizeof(*context)); 1434280849Scy#endif 1435258945Sroberto } 1436258945Sroberto memset(digest, 0, ISC_SHA384_DIGESTLENGTH); 1437258945Sroberto return buffer; 1438258945Sroberto} 1439258945Sroberto 1440280849Scychar * 1441258945Srobertoisc_sha384_data(const isc_uint8_t *data, size_t len, 1442258945Sroberto char digest[ISC_SHA384_DIGESTSTRINGLENGTH]) 1443258945Sroberto{ 1444258945Sroberto isc_sha384_t context; 1445258945Sroberto 1446258945Sroberto isc_sha384_init(&context); 1447258945Sroberto isc_sha384_update(&context, data, len); 1448258945Sroberto return (isc_sha384_end(&context, digest)); 1449258945Sroberto} 1450