1825eb42bSJan Lentfer /* 2825eb42bSJan Lentfer * FILE: sha2.c 3825eb42bSJan Lentfer * AUTHOR: Aaron D. Gifford - http://www.aarongifford.com/ 4825eb42bSJan Lentfer * 5825eb42bSJan Lentfer * Copyright (c) 2000-2001, Aaron D. Gifford 6825eb42bSJan Lentfer * All rights reserved. 7825eb42bSJan Lentfer * 8825eb42bSJan Lentfer * Modified by Jelte Jansen to fit in ldns, and not clash with any 9825eb42bSJan Lentfer * system-defined SHA code. 10825eb42bSJan Lentfer * Changes: 11825eb42bSJan Lentfer * - Renamed (external) functions and constants to fit ldns style 12825eb42bSJan Lentfer * - Removed _End and _Data functions 13825eb42bSJan Lentfer * - Added ldns_shaX(data, len, digest) convenience functions 14825eb42bSJan Lentfer * - Removed prototypes of _Transform functions and made those static 15825eb42bSJan Lentfer * 16825eb42bSJan Lentfer * Redistribution and use in source and binary forms, with or without 17825eb42bSJan Lentfer * modification, are permitted provided that the following conditions 18825eb42bSJan Lentfer * are met: 19825eb42bSJan Lentfer * 1. Redistributions of source code must retain the above copyright 20825eb42bSJan Lentfer * notice, this list of conditions and the following disclaimer. 21825eb42bSJan Lentfer * 2. Redistributions in binary form must reproduce the above copyright 22825eb42bSJan Lentfer * notice, this list of conditions and the following disclaimer in the 23825eb42bSJan Lentfer * documentation and/or other materials provided with the distribution. 24825eb42bSJan Lentfer * 3. Neither the name of the copyright holder nor the names of contributors 25825eb42bSJan Lentfer * may be used to endorse or promote products derived from this software 26825eb42bSJan Lentfer * without specific prior written permission. 27825eb42bSJan Lentfer * 28825eb42bSJan Lentfer * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND 29825eb42bSJan Lentfer * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 30825eb42bSJan Lentfer * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 31825eb42bSJan Lentfer * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE 32825eb42bSJan Lentfer * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 33825eb42bSJan Lentfer * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 34825eb42bSJan Lentfer * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35825eb42bSJan Lentfer * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36825eb42bSJan Lentfer * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 37825eb42bSJan Lentfer * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 38825eb42bSJan Lentfer * SUCH DAMAGE. 39825eb42bSJan Lentfer * 40825eb42bSJan Lentfer * $Id: sha2.c,v 1.1 2001/11/08 00:01:51 adg Exp adg $ 41825eb42bSJan Lentfer */ 42825eb42bSJan Lentfer 43825eb42bSJan Lentfer #include <ldns/config.h> 44825eb42bSJan Lentfer #include <string.h> /* memcpy()/memset() or bcopy()/bzero() */ 45825eb42bSJan Lentfer #include <assert.h> /* assert() */ 46825eb42bSJan Lentfer #include <ldns/sha2.h> 47825eb42bSJan Lentfer 48825eb42bSJan Lentfer /* 49825eb42bSJan Lentfer * ASSERT NOTE: 50825eb42bSJan Lentfer * Some sanity checking code is included using assert(). On my FreeBSD 51825eb42bSJan Lentfer * system, this additional code can be removed by compiling with NDEBUG 52825eb42bSJan Lentfer * defined. Check your own systems manpage on assert() to see how to 53825eb42bSJan Lentfer * compile WITHOUT the sanity checking code on your system. 54825eb42bSJan Lentfer * 55825eb42bSJan Lentfer * UNROLLED TRANSFORM LOOP NOTE: 56825eb42bSJan Lentfer * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform 57825eb42bSJan Lentfer * loop version for the hash transform rounds (defined using macros 58825eb42bSJan Lentfer * later in this file). Either define on the command line, for example: 59825eb42bSJan Lentfer * 60825eb42bSJan Lentfer * cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c 61825eb42bSJan Lentfer * 62825eb42bSJan Lentfer * or define below: 63825eb42bSJan Lentfer * 64825eb42bSJan Lentfer * #define SHA2_UNROLL_TRANSFORM 65825eb42bSJan Lentfer * 66825eb42bSJan Lentfer */ 67825eb42bSJan Lentfer 68825eb42bSJan Lentfer 69825eb42bSJan Lentfer /*** SHA-256/384/512 Machine Architecture Definitions *****************/ 70825eb42bSJan Lentfer /* 71825eb42bSJan Lentfer * BYTE_ORDER NOTE: 72825eb42bSJan Lentfer * 73825eb42bSJan Lentfer * Please make sure that your system defines BYTE_ORDER. If your 74825eb42bSJan Lentfer * architecture is little-endian, make sure it also defines 75825eb42bSJan Lentfer * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are 76825eb42bSJan Lentfer * equivilent. 77825eb42bSJan Lentfer * 78825eb42bSJan Lentfer * If your system does not define the above, then you can do so by 79825eb42bSJan Lentfer * hand like this: 80825eb42bSJan Lentfer * 81825eb42bSJan Lentfer * #define LITTLE_ENDIAN 1234 82825eb42bSJan Lentfer * #define BIG_ENDIAN 4321 83825eb42bSJan Lentfer * 84825eb42bSJan Lentfer * And for little-endian machines, add: 85825eb42bSJan Lentfer * 86825eb42bSJan Lentfer * #define BYTE_ORDER LITTLE_ENDIAN 87825eb42bSJan Lentfer * 88825eb42bSJan Lentfer * Or for big-endian machines: 89825eb42bSJan Lentfer * 90825eb42bSJan Lentfer * #define BYTE_ORDER BIG_ENDIAN 91825eb42bSJan Lentfer * 92825eb42bSJan Lentfer * The FreeBSD machine this was written on defines BYTE_ORDER 93825eb42bSJan Lentfer * appropriately by including <sys/types.h> (which in turn includes 94825eb42bSJan Lentfer * <machine/endian.h> where the appropriate definitions are actually 95825eb42bSJan Lentfer * made). 96825eb42bSJan Lentfer */ 97825eb42bSJan Lentfer #if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN) 98825eb42bSJan Lentfer #error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN 99825eb42bSJan Lentfer #endif 100825eb42bSJan Lentfer 101825eb42bSJan Lentfer typedef uint8_t sha2_byte; /* Exactly 1 byte */ 102825eb42bSJan Lentfer typedef uint32_t sha2_word32; /* Exactly 4 bytes */ 103fd185f4dSJan Lentfer #ifdef S_SPLINT_S 104fd185f4dSJan Lentfer typedef unsigned long long sha2_word64; /* lint 8 bytes */ 105fd185f4dSJan Lentfer #else 106825eb42bSJan Lentfer typedef uint64_t sha2_word64; /* Exactly 8 bytes */ 107fd185f4dSJan Lentfer #endif 108825eb42bSJan Lentfer 109825eb42bSJan Lentfer /*** SHA-256/384/512 Various Length Definitions ***********************/ 110825eb42bSJan Lentfer /* NOTE: Most of these are in sha2.h */ 111825eb42bSJan Lentfer #define ldns_sha256_SHORT_BLOCK_LENGTH (LDNS_SHA256_BLOCK_LENGTH - 8) 112825eb42bSJan Lentfer #define ldns_sha384_SHORT_BLOCK_LENGTH (LDNS_SHA384_BLOCK_LENGTH - 16) 113825eb42bSJan Lentfer #define ldns_sha512_SHORT_BLOCK_LENGTH (LDNS_SHA512_BLOCK_LENGTH - 16) 114825eb42bSJan Lentfer 115825eb42bSJan Lentfer 116825eb42bSJan Lentfer /*** ENDIAN REVERSAL MACROS *******************************************/ 117825eb42bSJan Lentfer #if BYTE_ORDER == LITTLE_ENDIAN 118825eb42bSJan Lentfer #define REVERSE32(w,x) { \ 119825eb42bSJan Lentfer sha2_word32 tmp = (w); \ 120825eb42bSJan Lentfer tmp = (tmp >> 16) | (tmp << 16); \ 121825eb42bSJan Lentfer (x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \ 122825eb42bSJan Lentfer } 123fd185f4dSJan Lentfer #ifndef S_SPLINT_S 124825eb42bSJan Lentfer #define REVERSE64(w,x) { \ 125825eb42bSJan Lentfer sha2_word64 tmp = (w); \ 126825eb42bSJan Lentfer tmp = (tmp >> 32) | (tmp << 32); \ 127825eb42bSJan Lentfer tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \ 128825eb42bSJan Lentfer ((tmp & 0x00ff00ff00ff00ffULL) << 8); \ 129825eb42bSJan Lentfer (x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \ 130825eb42bSJan Lentfer ((tmp & 0x0000ffff0000ffffULL) << 16); \ 131825eb42bSJan Lentfer } 132fd185f4dSJan Lentfer #else /* splint */ 133fd185f4dSJan Lentfer #define REVERSE64(w,x) /* splint */ 134fd185f4dSJan Lentfer #endif /* splint */ 135825eb42bSJan Lentfer #endif /* BYTE_ORDER == LITTLE_ENDIAN */ 136825eb42bSJan Lentfer 137825eb42bSJan Lentfer /* 138825eb42bSJan Lentfer * Macro for incrementally adding the unsigned 64-bit integer n to the 139825eb42bSJan Lentfer * unsigned 128-bit integer (represented using a two-element array of 140825eb42bSJan Lentfer * 64-bit words): 141825eb42bSJan Lentfer */ 142825eb42bSJan Lentfer #define ADDINC128(w,n) { \ 143825eb42bSJan Lentfer (w)[0] += (sha2_word64)(n); \ 144825eb42bSJan Lentfer if ((w)[0] < (n)) { \ 145825eb42bSJan Lentfer (w)[1]++; \ 146825eb42bSJan Lentfer } \ 147825eb42bSJan Lentfer } 148fd185f4dSJan Lentfer #ifdef S_SPLINT_S 149fd185f4dSJan Lentfer #undef ADDINC128 150fd185f4dSJan Lentfer #define ADDINC128(w,n) /* splint */ 151fd185f4dSJan Lentfer #endif 152825eb42bSJan Lentfer 153825eb42bSJan Lentfer /* 154825eb42bSJan Lentfer * Macros for copying blocks of memory and for zeroing out ranges 155825eb42bSJan Lentfer * of memory. Using these macros makes it easy to switch from 156825eb42bSJan Lentfer * using memset()/memcpy() and using bzero()/bcopy(). 157825eb42bSJan Lentfer * 158825eb42bSJan Lentfer * Please define either SHA2_USE_MEMSET_MEMCPY or define 159825eb42bSJan Lentfer * SHA2_USE_BZERO_BCOPY depending on which function set you 160825eb42bSJan Lentfer * choose to use: 161825eb42bSJan Lentfer */ 162825eb42bSJan Lentfer #if !defined(SHA2_USE_MEMSET_MEMCPY) && !defined(SHA2_USE_BZERO_BCOPY) 163825eb42bSJan Lentfer /* Default to memset()/memcpy() if no option is specified */ 164825eb42bSJan Lentfer #define SHA2_USE_MEMSET_MEMCPY 1 165825eb42bSJan Lentfer #endif 166825eb42bSJan Lentfer #if defined(SHA2_USE_MEMSET_MEMCPY) && defined(SHA2_USE_BZERO_BCOPY) 167825eb42bSJan Lentfer /* Abort with an error if BOTH options are defined */ 168825eb42bSJan Lentfer #error Define either SHA2_USE_MEMSET_MEMCPY or SHA2_USE_BZERO_BCOPY, not both! 169825eb42bSJan Lentfer #endif 170825eb42bSJan Lentfer 171825eb42bSJan Lentfer #ifdef SHA2_USE_MEMSET_MEMCPY 172825eb42bSJan Lentfer #define MEMSET_BZERO(p,l) memset((p), 0, (l)) 173825eb42bSJan Lentfer #define MEMCPY_BCOPY(d,s,l) memcpy((d), (s), (l)) 174825eb42bSJan Lentfer #endif 175825eb42bSJan Lentfer #ifdef SHA2_USE_BZERO_BCOPY 176825eb42bSJan Lentfer #define MEMSET_BZERO(p,l) bzero((p), (l)) 177825eb42bSJan Lentfer #define MEMCPY_BCOPY(d,s,l) bcopy((s), (d), (l)) 178825eb42bSJan Lentfer #endif 179825eb42bSJan Lentfer 180825eb42bSJan Lentfer 181825eb42bSJan Lentfer /*** THE SIX LOGICAL FUNCTIONS ****************************************/ 182825eb42bSJan Lentfer /* 183825eb42bSJan Lentfer * Bit shifting and rotation (used by the six SHA-XYZ logical functions: 184825eb42bSJan Lentfer * 185825eb42bSJan Lentfer * NOTE: The naming of R and S appears backwards here (R is a SHIFT and 186825eb42bSJan Lentfer * S is a ROTATION) because the SHA-256/384/512 description document 187825eb42bSJan Lentfer * (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this 188825eb42bSJan Lentfer * same "backwards" definition. 189825eb42bSJan Lentfer */ 190825eb42bSJan Lentfer /* Shift-right (used in SHA-256, SHA-384, and SHA-512): */ 191825eb42bSJan Lentfer #define R(b,x) ((x) >> (b)) 192825eb42bSJan Lentfer /* 32-bit Rotate-right (used in SHA-256): */ 193825eb42bSJan Lentfer #define S32(b,x) (((x) >> (b)) | ((x) << (32 - (b)))) 194825eb42bSJan Lentfer /* 64-bit Rotate-right (used in SHA-384 and SHA-512): */ 195825eb42bSJan Lentfer #define S64(b,x) (((x) >> (b)) | ((x) << (64 - (b)))) 196825eb42bSJan Lentfer 197825eb42bSJan Lentfer /* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */ 198825eb42bSJan Lentfer #define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) 199825eb42bSJan Lentfer #define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) 200825eb42bSJan Lentfer 201825eb42bSJan Lentfer /* Four of six logical functions used in SHA-256: */ 202825eb42bSJan Lentfer #define Sigma0_256(x) (S32(2, (x)) ^ S32(13, (x)) ^ S32(22, (x))) 203825eb42bSJan Lentfer #define Sigma1_256(x) (S32(6, (x)) ^ S32(11, (x)) ^ S32(25, (x))) 204825eb42bSJan Lentfer #define sigma0_256(x) (S32(7, (x)) ^ S32(18, (x)) ^ R(3 , (x))) 205825eb42bSJan Lentfer #define sigma1_256(x) (S32(17, (x)) ^ S32(19, (x)) ^ R(10, (x))) 206825eb42bSJan Lentfer 207825eb42bSJan Lentfer /* Four of six logical functions used in SHA-384 and SHA-512: */ 208825eb42bSJan Lentfer #define Sigma0_512(x) (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x))) 209825eb42bSJan Lentfer #define Sigma1_512(x) (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x))) 210825eb42bSJan Lentfer #define sigma0_512(x) (S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7, (x))) 211825eb42bSJan Lentfer #define sigma1_512(x) (S64(19, (x)) ^ S64(61, (x)) ^ R( 6, (x))) 212825eb42bSJan Lentfer 213825eb42bSJan Lentfer /*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/ 214825eb42bSJan Lentfer /* Hash constant words K for SHA-256: */ 215825eb42bSJan Lentfer static const sha2_word32 K256[64] = { 216825eb42bSJan Lentfer 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 217825eb42bSJan Lentfer 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 218825eb42bSJan Lentfer 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, 219825eb42bSJan Lentfer 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, 220825eb42bSJan Lentfer 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, 221825eb42bSJan Lentfer 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 222825eb42bSJan Lentfer 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 223825eb42bSJan Lentfer 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, 224825eb42bSJan Lentfer 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, 225825eb42bSJan Lentfer 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, 226825eb42bSJan Lentfer 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 227825eb42bSJan Lentfer 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 228825eb42bSJan Lentfer 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, 229825eb42bSJan Lentfer 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, 230825eb42bSJan Lentfer 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, 231825eb42bSJan Lentfer 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL 232825eb42bSJan Lentfer }; 233825eb42bSJan Lentfer 234825eb42bSJan Lentfer /* initial hash value H for SHA-256: */ 235825eb42bSJan Lentfer static const sha2_word32 ldns_sha256_initial_hash_value[8] = { 236825eb42bSJan Lentfer 0x6a09e667UL, 237825eb42bSJan Lentfer 0xbb67ae85UL, 238825eb42bSJan Lentfer 0x3c6ef372UL, 239825eb42bSJan Lentfer 0xa54ff53aUL, 240825eb42bSJan Lentfer 0x510e527fUL, 241825eb42bSJan Lentfer 0x9b05688cUL, 242825eb42bSJan Lentfer 0x1f83d9abUL, 243825eb42bSJan Lentfer 0x5be0cd19UL 244825eb42bSJan Lentfer }; 245825eb42bSJan Lentfer 246825eb42bSJan Lentfer /* Hash constant words K for SHA-384 and SHA-512: */ 247825eb42bSJan Lentfer static const sha2_word64 K512[80] = { 248825eb42bSJan Lentfer 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 249825eb42bSJan Lentfer 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, 250825eb42bSJan Lentfer 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 251825eb42bSJan Lentfer 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 252825eb42bSJan Lentfer 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 253825eb42bSJan Lentfer 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, 254825eb42bSJan Lentfer 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 255825eb42bSJan Lentfer 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, 256825eb42bSJan Lentfer 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 257825eb42bSJan Lentfer 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 258825eb42bSJan Lentfer 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 259825eb42bSJan Lentfer 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, 260825eb42bSJan Lentfer 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 261825eb42bSJan Lentfer 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, 262825eb42bSJan Lentfer 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 263825eb42bSJan Lentfer 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 264825eb42bSJan Lentfer 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 265825eb42bSJan Lentfer 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, 266825eb42bSJan Lentfer 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 267825eb42bSJan Lentfer 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, 268825eb42bSJan Lentfer 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 269825eb42bSJan Lentfer 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 270825eb42bSJan Lentfer 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 271825eb42bSJan Lentfer 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, 272825eb42bSJan Lentfer 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 273825eb42bSJan Lentfer 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, 274825eb42bSJan Lentfer 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 275825eb42bSJan Lentfer 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 276825eb42bSJan Lentfer 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 277825eb42bSJan Lentfer 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, 278825eb42bSJan Lentfer 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 279825eb42bSJan Lentfer 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, 280825eb42bSJan Lentfer 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 281825eb42bSJan Lentfer 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 282825eb42bSJan Lentfer 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 283825eb42bSJan Lentfer 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, 284825eb42bSJan Lentfer 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 285825eb42bSJan Lentfer 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, 286825eb42bSJan Lentfer 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 287825eb42bSJan Lentfer 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL 288825eb42bSJan Lentfer }; 289825eb42bSJan Lentfer 290825eb42bSJan Lentfer /* initial hash value H for SHA-384 */ 291825eb42bSJan Lentfer static const sha2_word64 sha384_initial_hash_value[8] = { 292825eb42bSJan Lentfer 0xcbbb9d5dc1059ed8ULL, 293825eb42bSJan Lentfer 0x629a292a367cd507ULL, 294825eb42bSJan Lentfer 0x9159015a3070dd17ULL, 295825eb42bSJan Lentfer 0x152fecd8f70e5939ULL, 296825eb42bSJan Lentfer 0x67332667ffc00b31ULL, 297825eb42bSJan Lentfer 0x8eb44a8768581511ULL, 298825eb42bSJan Lentfer 0xdb0c2e0d64f98fa7ULL, 299825eb42bSJan Lentfer 0x47b5481dbefa4fa4ULL 300825eb42bSJan Lentfer }; 301825eb42bSJan Lentfer 302825eb42bSJan Lentfer /* initial hash value H for SHA-512 */ 303825eb42bSJan Lentfer static const sha2_word64 sha512_initial_hash_value[8] = { 304825eb42bSJan Lentfer 0x6a09e667f3bcc908ULL, 305825eb42bSJan Lentfer 0xbb67ae8584caa73bULL, 306825eb42bSJan Lentfer 0x3c6ef372fe94f82bULL, 307825eb42bSJan Lentfer 0xa54ff53a5f1d36f1ULL, 308825eb42bSJan Lentfer 0x510e527fade682d1ULL, 309825eb42bSJan Lentfer 0x9b05688c2b3e6c1fULL, 310825eb42bSJan Lentfer 0x1f83d9abfb41bd6bULL, 311825eb42bSJan Lentfer 0x5be0cd19137e2179ULL 312825eb42bSJan Lentfer }; 313825eb42bSJan Lentfer 314825eb42bSJan Lentfer /*** SHA-256: *********************************************************/ 315825eb42bSJan Lentfer void ldns_sha256_init(ldns_sha256_CTX* context) { 316825eb42bSJan Lentfer if (context == (ldns_sha256_CTX*)0) { 317825eb42bSJan Lentfer return; 318825eb42bSJan Lentfer } 319825eb42bSJan Lentfer MEMCPY_BCOPY(context->state, ldns_sha256_initial_hash_value, LDNS_SHA256_DIGEST_LENGTH); 320825eb42bSJan Lentfer MEMSET_BZERO(context->buffer, LDNS_SHA256_BLOCK_LENGTH); 321825eb42bSJan Lentfer context->bitcount = 0; 322825eb42bSJan Lentfer } 323825eb42bSJan Lentfer 324825eb42bSJan Lentfer #ifdef SHA2_UNROLL_TRANSFORM 325825eb42bSJan Lentfer 326825eb42bSJan Lentfer /* Unrolled SHA-256 round macros: */ 327825eb42bSJan Lentfer 328825eb42bSJan Lentfer #if BYTE_ORDER == LITTLE_ENDIAN 329825eb42bSJan Lentfer 330825eb42bSJan Lentfer #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ 331825eb42bSJan Lentfer REVERSE32(*data++, W256[j]); \ 332825eb42bSJan Lentfer T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ 333825eb42bSJan Lentfer K256[j] + W256[j]; \ 334825eb42bSJan Lentfer (d) += T1; \ 335825eb42bSJan Lentfer (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ 336825eb42bSJan Lentfer j++ 337825eb42bSJan Lentfer 338825eb42bSJan Lentfer 339825eb42bSJan Lentfer #else /* BYTE_ORDER == LITTLE_ENDIAN */ 340825eb42bSJan Lentfer 341825eb42bSJan Lentfer #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ 342825eb42bSJan Lentfer T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ 343825eb42bSJan Lentfer K256[j] + (W256[j] = *data++); \ 344825eb42bSJan Lentfer (d) += T1; \ 345825eb42bSJan Lentfer (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ 346825eb42bSJan Lentfer j++ 347825eb42bSJan Lentfer 348825eb42bSJan Lentfer #endif /* BYTE_ORDER == LITTLE_ENDIAN */ 349825eb42bSJan Lentfer 350825eb42bSJan Lentfer #define ROUND256(a,b,c,d,e,f,g,h) \ 351825eb42bSJan Lentfer s0 = W256[(j+1)&0x0f]; \ 352825eb42bSJan Lentfer s0 = sigma0_256(s0); \ 353825eb42bSJan Lentfer s1 = W256[(j+14)&0x0f]; \ 354825eb42bSJan Lentfer s1 = sigma1_256(s1); \ 355825eb42bSJan Lentfer T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \ 356825eb42bSJan Lentfer (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \ 357825eb42bSJan Lentfer (d) += T1; \ 358825eb42bSJan Lentfer (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ 359825eb42bSJan Lentfer j++ 360825eb42bSJan Lentfer 361825eb42bSJan Lentfer static void ldns_sha256_Transform(ldns_sha256_CTX* context, 362825eb42bSJan Lentfer const sha2_word32* data) { 363825eb42bSJan Lentfer sha2_word32 a, b, c, d, e, f, g, h, s0, s1; 364825eb42bSJan Lentfer sha2_word32 T1, *W256; 365825eb42bSJan Lentfer int j; 366825eb42bSJan Lentfer 367825eb42bSJan Lentfer W256 = (sha2_word32*)context->buffer; 368825eb42bSJan Lentfer 369825eb42bSJan Lentfer /* initialize registers with the prev. intermediate value */ 370825eb42bSJan Lentfer a = context->state[0]; 371825eb42bSJan Lentfer b = context->state[1]; 372825eb42bSJan Lentfer c = context->state[2]; 373825eb42bSJan Lentfer d = context->state[3]; 374825eb42bSJan Lentfer e = context->state[4]; 375825eb42bSJan Lentfer f = context->state[5]; 376825eb42bSJan Lentfer g = context->state[6]; 377825eb42bSJan Lentfer h = context->state[7]; 378825eb42bSJan Lentfer 379825eb42bSJan Lentfer j = 0; 380825eb42bSJan Lentfer do { 381825eb42bSJan Lentfer /* Rounds 0 to 15 (unrolled): */ 382825eb42bSJan Lentfer ROUND256_0_TO_15(a,b,c,d,e,f,g,h); 383825eb42bSJan Lentfer ROUND256_0_TO_15(h,a,b,c,d,e,f,g); 384825eb42bSJan Lentfer ROUND256_0_TO_15(g,h,a,b,c,d,e,f); 385825eb42bSJan Lentfer ROUND256_0_TO_15(f,g,h,a,b,c,d,e); 386825eb42bSJan Lentfer ROUND256_0_TO_15(e,f,g,h,a,b,c,d); 387825eb42bSJan Lentfer ROUND256_0_TO_15(d,e,f,g,h,a,b,c); 388825eb42bSJan Lentfer ROUND256_0_TO_15(c,d,e,f,g,h,a,b); 389825eb42bSJan Lentfer ROUND256_0_TO_15(b,c,d,e,f,g,h,a); 390825eb42bSJan Lentfer } while (j < 16); 391825eb42bSJan Lentfer 392825eb42bSJan Lentfer /* Now for the remaining rounds to 64: */ 393825eb42bSJan Lentfer do { 394825eb42bSJan Lentfer ROUND256(a,b,c,d,e,f,g,h); 395825eb42bSJan Lentfer ROUND256(h,a,b,c,d,e,f,g); 396825eb42bSJan Lentfer ROUND256(g,h,a,b,c,d,e,f); 397825eb42bSJan Lentfer ROUND256(f,g,h,a,b,c,d,e); 398825eb42bSJan Lentfer ROUND256(e,f,g,h,a,b,c,d); 399825eb42bSJan Lentfer ROUND256(d,e,f,g,h,a,b,c); 400825eb42bSJan Lentfer ROUND256(c,d,e,f,g,h,a,b); 401825eb42bSJan Lentfer ROUND256(b,c,d,e,f,g,h,a); 402825eb42bSJan Lentfer } while (j < 64); 403825eb42bSJan Lentfer 404825eb42bSJan Lentfer /* Compute the current intermediate hash value */ 405825eb42bSJan Lentfer context->state[0] += a; 406825eb42bSJan Lentfer context->state[1] += b; 407825eb42bSJan Lentfer context->state[2] += c; 408825eb42bSJan Lentfer context->state[3] += d; 409825eb42bSJan Lentfer context->state[4] += e; 410825eb42bSJan Lentfer context->state[5] += f; 411825eb42bSJan Lentfer context->state[6] += g; 412825eb42bSJan Lentfer context->state[7] += h; 413825eb42bSJan Lentfer 414825eb42bSJan Lentfer /* Clean up */ 415825eb42bSJan Lentfer a = b = c = d = e = f = g = h = T1 = 0; 416825eb42bSJan Lentfer } 417825eb42bSJan Lentfer 418825eb42bSJan Lentfer #else /* SHA2_UNROLL_TRANSFORM */ 419825eb42bSJan Lentfer 420825eb42bSJan Lentfer static void ldns_sha256_Transform(ldns_sha256_CTX* context, 421825eb42bSJan Lentfer const sha2_word32* data) { 422825eb42bSJan Lentfer sha2_word32 a, b, c, d, e, f, g, h, s0, s1; 423825eb42bSJan Lentfer sha2_word32 T1, T2, *W256; 424825eb42bSJan Lentfer int j; 425825eb42bSJan Lentfer 426825eb42bSJan Lentfer W256 = (sha2_word32*)context->buffer; 427825eb42bSJan Lentfer 428825eb42bSJan Lentfer /* initialize registers with the prev. intermediate value */ 429825eb42bSJan Lentfer a = context->state[0]; 430825eb42bSJan Lentfer b = context->state[1]; 431825eb42bSJan Lentfer c = context->state[2]; 432825eb42bSJan Lentfer d = context->state[3]; 433825eb42bSJan Lentfer e = context->state[4]; 434825eb42bSJan Lentfer f = context->state[5]; 435825eb42bSJan Lentfer g = context->state[6]; 436825eb42bSJan Lentfer h = context->state[7]; 437825eb42bSJan Lentfer 438825eb42bSJan Lentfer j = 0; 439825eb42bSJan Lentfer do { 440825eb42bSJan Lentfer #if BYTE_ORDER == LITTLE_ENDIAN 441825eb42bSJan Lentfer /* Copy data while converting to host byte order */ 442825eb42bSJan Lentfer REVERSE32(*data++,W256[j]); 443825eb42bSJan Lentfer /* Apply the SHA-256 compression function to update a..h */ 444825eb42bSJan Lentfer T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j]; 445825eb42bSJan Lentfer #else /* BYTE_ORDER == LITTLE_ENDIAN */ 446825eb42bSJan Lentfer /* Apply the SHA-256 compression function to update a..h with copy */ 447825eb42bSJan Lentfer T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++); 448825eb42bSJan Lentfer #endif /* BYTE_ORDER == LITTLE_ENDIAN */ 449825eb42bSJan Lentfer T2 = Sigma0_256(a) + Maj(a, b, c); 450825eb42bSJan Lentfer h = g; 451825eb42bSJan Lentfer g = f; 452825eb42bSJan Lentfer f = e; 453825eb42bSJan Lentfer e = d + T1; 454825eb42bSJan Lentfer d = c; 455825eb42bSJan Lentfer c = b; 456825eb42bSJan Lentfer b = a; 457825eb42bSJan Lentfer a = T1 + T2; 458825eb42bSJan Lentfer 459825eb42bSJan Lentfer j++; 460825eb42bSJan Lentfer } while (j < 16); 461825eb42bSJan Lentfer 462825eb42bSJan Lentfer do { 463825eb42bSJan Lentfer /* Part of the message block expansion: */ 464825eb42bSJan Lentfer s0 = W256[(j+1)&0x0f]; 465825eb42bSJan Lentfer s0 = sigma0_256(s0); 466825eb42bSJan Lentfer s1 = W256[(j+14)&0x0f]; 467825eb42bSJan Lentfer s1 = sigma1_256(s1); 468825eb42bSJan Lentfer 469825eb42bSJan Lentfer /* Apply the SHA-256 compression function to update a..h */ 470825eb42bSJan Lentfer T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + 471825eb42bSJan Lentfer (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); 472825eb42bSJan Lentfer T2 = Sigma0_256(a) + Maj(a, b, c); 473825eb42bSJan Lentfer h = g; 474825eb42bSJan Lentfer g = f; 475825eb42bSJan Lentfer f = e; 476825eb42bSJan Lentfer e = d + T1; 477825eb42bSJan Lentfer d = c; 478825eb42bSJan Lentfer c = b; 479825eb42bSJan Lentfer b = a; 480825eb42bSJan Lentfer a = T1 + T2; 481825eb42bSJan Lentfer 482825eb42bSJan Lentfer j++; 483825eb42bSJan Lentfer } while (j < 64); 484825eb42bSJan Lentfer 485825eb42bSJan Lentfer /* Compute the current intermediate hash value */ 486825eb42bSJan Lentfer context->state[0] += a; 487825eb42bSJan Lentfer context->state[1] += b; 488825eb42bSJan Lentfer context->state[2] += c; 489825eb42bSJan Lentfer context->state[3] += d; 490825eb42bSJan Lentfer context->state[4] += e; 491825eb42bSJan Lentfer context->state[5] += f; 492825eb42bSJan Lentfer context->state[6] += g; 493825eb42bSJan Lentfer context->state[7] += h; 494825eb42bSJan Lentfer 495825eb42bSJan Lentfer /* Clean up */ 496825eb42bSJan Lentfer a = b = c = d = e = f = g = h = T1 = T2 = 0; 497825eb42bSJan Lentfer } 498825eb42bSJan Lentfer 499825eb42bSJan Lentfer #endif /* SHA2_UNROLL_TRANSFORM */ 500825eb42bSJan Lentfer 501825eb42bSJan Lentfer void ldns_sha256_update(ldns_sha256_CTX* context, const sha2_byte *data, size_t len) { 502fd185f4dSJan Lentfer size_t freespace, usedspace; 503825eb42bSJan Lentfer 504825eb42bSJan Lentfer if (len == 0) { 505825eb42bSJan Lentfer /* Calling with no data is valid - we do nothing */ 506825eb42bSJan Lentfer return; 507825eb42bSJan Lentfer } 508825eb42bSJan Lentfer 509825eb42bSJan Lentfer /* Sanity check: */ 510825eb42bSJan Lentfer assert(context != (ldns_sha256_CTX*)0 && data != (sha2_byte*)0); 511825eb42bSJan Lentfer 512825eb42bSJan Lentfer usedspace = (context->bitcount >> 3) % LDNS_SHA256_BLOCK_LENGTH; 513825eb42bSJan Lentfer if (usedspace > 0) { 514825eb42bSJan Lentfer /* Calculate how much free space is available in the buffer */ 515825eb42bSJan Lentfer freespace = LDNS_SHA256_BLOCK_LENGTH - usedspace; 516825eb42bSJan Lentfer 517825eb42bSJan Lentfer if (len >= freespace) { 518825eb42bSJan Lentfer /* Fill the buffer completely and process it */ 519825eb42bSJan Lentfer MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace); 520825eb42bSJan Lentfer context->bitcount += freespace << 3; 521825eb42bSJan Lentfer len -= freespace; 522825eb42bSJan Lentfer data += freespace; 523825eb42bSJan Lentfer ldns_sha256_Transform(context, (sha2_word32*)context->buffer); 524825eb42bSJan Lentfer } else { 525825eb42bSJan Lentfer /* The buffer is not yet full */ 526825eb42bSJan Lentfer MEMCPY_BCOPY(&context->buffer[usedspace], data, len); 527825eb42bSJan Lentfer context->bitcount += len << 3; 528825eb42bSJan Lentfer /* Clean up: */ 529825eb42bSJan Lentfer usedspace = freespace = 0; 530825eb42bSJan Lentfer return; 531825eb42bSJan Lentfer } 532825eb42bSJan Lentfer } 533825eb42bSJan Lentfer while (len >= LDNS_SHA256_BLOCK_LENGTH) { 534825eb42bSJan Lentfer /* Process as many complete blocks as we can */ 535825eb42bSJan Lentfer ldns_sha256_Transform(context, (sha2_word32*)data); 536825eb42bSJan Lentfer context->bitcount += LDNS_SHA256_BLOCK_LENGTH << 3; 537825eb42bSJan Lentfer len -= LDNS_SHA256_BLOCK_LENGTH; 538825eb42bSJan Lentfer data += LDNS_SHA256_BLOCK_LENGTH; 539825eb42bSJan Lentfer } 540825eb42bSJan Lentfer if (len > 0) { 541825eb42bSJan Lentfer /* There's left-overs, so save 'em */ 542825eb42bSJan Lentfer MEMCPY_BCOPY(context->buffer, data, len); 543825eb42bSJan Lentfer context->bitcount += len << 3; 544825eb42bSJan Lentfer } 545825eb42bSJan Lentfer /* Clean up: */ 546825eb42bSJan Lentfer usedspace = freespace = 0; 547825eb42bSJan Lentfer } 548825eb42bSJan Lentfer 549825eb42bSJan Lentfer void ldns_sha256_final(sha2_byte digest[], ldns_sha256_CTX* context) { 550825eb42bSJan Lentfer sha2_word32 *d = (sha2_word32*)digest; 551fd185f4dSJan Lentfer size_t usedspace; 552825eb42bSJan Lentfer 553825eb42bSJan Lentfer /* Sanity check: */ 554825eb42bSJan Lentfer assert(context != (ldns_sha256_CTX*)0); 555825eb42bSJan Lentfer 556825eb42bSJan Lentfer /* If no digest buffer is passed, we don't bother doing this: */ 557825eb42bSJan Lentfer if (digest != (sha2_byte*)0) { 558825eb42bSJan Lentfer usedspace = (context->bitcount >> 3) % LDNS_SHA256_BLOCK_LENGTH; 559825eb42bSJan Lentfer #if BYTE_ORDER == LITTLE_ENDIAN 560825eb42bSJan Lentfer /* Convert FROM host byte order */ 561825eb42bSJan Lentfer REVERSE64(context->bitcount,context->bitcount); 562825eb42bSJan Lentfer #endif 563825eb42bSJan Lentfer if (usedspace > 0) { 564825eb42bSJan Lentfer /* Begin padding with a 1 bit: */ 565825eb42bSJan Lentfer context->buffer[usedspace++] = 0x80; 566825eb42bSJan Lentfer 567825eb42bSJan Lentfer if (usedspace <= ldns_sha256_SHORT_BLOCK_LENGTH) { 568825eb42bSJan Lentfer /* Set-up for the last transform: */ 569825eb42bSJan Lentfer MEMSET_BZERO(&context->buffer[usedspace], ldns_sha256_SHORT_BLOCK_LENGTH - usedspace); 570825eb42bSJan Lentfer } else { 571825eb42bSJan Lentfer if (usedspace < LDNS_SHA256_BLOCK_LENGTH) { 572825eb42bSJan Lentfer MEMSET_BZERO(&context->buffer[usedspace], LDNS_SHA256_BLOCK_LENGTH - usedspace); 573825eb42bSJan Lentfer } 574825eb42bSJan Lentfer /* Do second-to-last transform: */ 575825eb42bSJan Lentfer ldns_sha256_Transform(context, (sha2_word32*)context->buffer); 576825eb42bSJan Lentfer 577825eb42bSJan Lentfer /* And set-up for the last transform: */ 578825eb42bSJan Lentfer MEMSET_BZERO(context->buffer, ldns_sha256_SHORT_BLOCK_LENGTH); 579825eb42bSJan Lentfer } 580825eb42bSJan Lentfer } else { 581825eb42bSJan Lentfer /* Set-up for the last transform: */ 582825eb42bSJan Lentfer MEMSET_BZERO(context->buffer, ldns_sha256_SHORT_BLOCK_LENGTH); 583825eb42bSJan Lentfer 584825eb42bSJan Lentfer /* Begin padding with a 1 bit: */ 585825eb42bSJan Lentfer *context->buffer = 0x80; 586825eb42bSJan Lentfer } 587825eb42bSJan Lentfer /* Set the bit count: */ 588825eb42bSJan Lentfer *(sha2_word64*)&context->buffer[ldns_sha256_SHORT_BLOCK_LENGTH] = context->bitcount; 589825eb42bSJan Lentfer 590825eb42bSJan Lentfer /* final transform: */ 591825eb42bSJan Lentfer ldns_sha256_Transform(context, (sha2_word32*)context->buffer); 592825eb42bSJan Lentfer 593825eb42bSJan Lentfer #if BYTE_ORDER == LITTLE_ENDIAN 594825eb42bSJan Lentfer { 595825eb42bSJan Lentfer /* Convert TO host byte order */ 596825eb42bSJan Lentfer int j; 597825eb42bSJan Lentfer for (j = 0; j < 8; j++) { 598825eb42bSJan Lentfer REVERSE32(context->state[j],context->state[j]); 599825eb42bSJan Lentfer *d++ = context->state[j]; 600825eb42bSJan Lentfer } 601825eb42bSJan Lentfer } 602825eb42bSJan Lentfer #else 603825eb42bSJan Lentfer MEMCPY_BCOPY(d, context->state, LDNS_SHA256_DIGEST_LENGTH); 604825eb42bSJan Lentfer #endif 605825eb42bSJan Lentfer } 606825eb42bSJan Lentfer 607825eb42bSJan Lentfer /* Clean up state data: */ 608*b5dedccaSJan Lentfer MEMSET_BZERO(context, sizeof(ldns_sha256_CTX)); 609825eb42bSJan Lentfer usedspace = 0; 610825eb42bSJan Lentfer } 611825eb42bSJan Lentfer 612825eb42bSJan Lentfer unsigned char * 613825eb42bSJan Lentfer ldns_sha256(unsigned char *data, unsigned int data_len, unsigned char *digest) 614825eb42bSJan Lentfer { 615825eb42bSJan Lentfer ldns_sha256_CTX ctx; 616825eb42bSJan Lentfer ldns_sha256_init(&ctx); 617825eb42bSJan Lentfer ldns_sha256_update(&ctx, data, data_len); 618825eb42bSJan Lentfer ldns_sha256_final(digest, &ctx); 619825eb42bSJan Lentfer return digest; 620825eb42bSJan Lentfer } 621825eb42bSJan Lentfer 622825eb42bSJan Lentfer /*** SHA-512: *********************************************************/ 623825eb42bSJan Lentfer void ldns_sha512_init(ldns_sha512_CTX* context) { 624825eb42bSJan Lentfer if (context == (ldns_sha512_CTX*)0) { 625825eb42bSJan Lentfer return; 626825eb42bSJan Lentfer } 627825eb42bSJan Lentfer MEMCPY_BCOPY(context->state, sha512_initial_hash_value, LDNS_SHA512_DIGEST_LENGTH); 628825eb42bSJan Lentfer MEMSET_BZERO(context->buffer, LDNS_SHA512_BLOCK_LENGTH); 629825eb42bSJan Lentfer context->bitcount[0] = context->bitcount[1] = 0; 630825eb42bSJan Lentfer } 631825eb42bSJan Lentfer 632825eb42bSJan Lentfer #ifdef SHA2_UNROLL_TRANSFORM 633825eb42bSJan Lentfer 634825eb42bSJan Lentfer /* Unrolled SHA-512 round macros: */ 635825eb42bSJan Lentfer #if BYTE_ORDER == LITTLE_ENDIAN 636825eb42bSJan Lentfer 637825eb42bSJan Lentfer #define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ 638825eb42bSJan Lentfer REVERSE64(*data++, W512[j]); \ 639825eb42bSJan Lentfer T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ 640825eb42bSJan Lentfer K512[j] + W512[j]; \ 641825eb42bSJan Lentfer (d) += T1, \ 642825eb42bSJan Lentfer (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \ 643825eb42bSJan Lentfer j++ 644825eb42bSJan Lentfer 645825eb42bSJan Lentfer 646825eb42bSJan Lentfer #else /* BYTE_ORDER == LITTLE_ENDIAN */ 647825eb42bSJan Lentfer 648825eb42bSJan Lentfer #define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ 649825eb42bSJan Lentfer T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ 650825eb42bSJan Lentfer K512[j] + (W512[j] = *data++); \ 651825eb42bSJan Lentfer (d) += T1; \ 652825eb42bSJan Lentfer (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ 653825eb42bSJan Lentfer j++ 654825eb42bSJan Lentfer 655825eb42bSJan Lentfer #endif /* BYTE_ORDER == LITTLE_ENDIAN */ 656825eb42bSJan Lentfer 657825eb42bSJan Lentfer #define ROUND512(a,b,c,d,e,f,g,h) \ 658825eb42bSJan Lentfer s0 = W512[(j+1)&0x0f]; \ 659825eb42bSJan Lentfer s0 = sigma0_512(s0); \ 660825eb42bSJan Lentfer s1 = W512[(j+14)&0x0f]; \ 661825eb42bSJan Lentfer s1 = sigma1_512(s1); \ 662825eb42bSJan Lentfer T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \ 663825eb42bSJan Lentfer (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \ 664825eb42bSJan Lentfer (d) += T1; \ 665825eb42bSJan Lentfer (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ 666825eb42bSJan Lentfer j++ 667825eb42bSJan Lentfer 668825eb42bSJan Lentfer static void ldns_sha512_Transform(ldns_sha512_CTX* context, 669825eb42bSJan Lentfer const sha2_word64* data) { 670825eb42bSJan Lentfer sha2_word64 a, b, c, d, e, f, g, h, s0, s1; 671825eb42bSJan Lentfer sha2_word64 T1, *W512 = (sha2_word64*)context->buffer; 672825eb42bSJan Lentfer int j; 673825eb42bSJan Lentfer 674825eb42bSJan Lentfer /* initialize registers with the prev. intermediate value */ 675825eb42bSJan Lentfer a = context->state[0]; 676825eb42bSJan Lentfer b = context->state[1]; 677825eb42bSJan Lentfer c = context->state[2]; 678825eb42bSJan Lentfer d = context->state[3]; 679825eb42bSJan Lentfer e = context->state[4]; 680825eb42bSJan Lentfer f = context->state[5]; 681825eb42bSJan Lentfer g = context->state[6]; 682825eb42bSJan Lentfer h = context->state[7]; 683825eb42bSJan Lentfer 684825eb42bSJan Lentfer j = 0; 685825eb42bSJan Lentfer do { 686825eb42bSJan Lentfer ROUND512_0_TO_15(a,b,c,d,e,f,g,h); 687825eb42bSJan Lentfer ROUND512_0_TO_15(h,a,b,c,d,e,f,g); 688825eb42bSJan Lentfer ROUND512_0_TO_15(g,h,a,b,c,d,e,f); 689825eb42bSJan Lentfer ROUND512_0_TO_15(f,g,h,a,b,c,d,e); 690825eb42bSJan Lentfer ROUND512_0_TO_15(e,f,g,h,a,b,c,d); 691825eb42bSJan Lentfer ROUND512_0_TO_15(d,e,f,g,h,a,b,c); 692825eb42bSJan Lentfer ROUND512_0_TO_15(c,d,e,f,g,h,a,b); 693825eb42bSJan Lentfer ROUND512_0_TO_15(b,c,d,e,f,g,h,a); 694825eb42bSJan Lentfer } while (j < 16); 695825eb42bSJan Lentfer 696825eb42bSJan Lentfer /* Now for the remaining rounds up to 79: */ 697825eb42bSJan Lentfer do { 698825eb42bSJan Lentfer ROUND512(a,b,c,d,e,f,g,h); 699825eb42bSJan Lentfer ROUND512(h,a,b,c,d,e,f,g); 700825eb42bSJan Lentfer ROUND512(g,h,a,b,c,d,e,f); 701825eb42bSJan Lentfer ROUND512(f,g,h,a,b,c,d,e); 702825eb42bSJan Lentfer ROUND512(e,f,g,h,a,b,c,d); 703825eb42bSJan Lentfer ROUND512(d,e,f,g,h,a,b,c); 704825eb42bSJan Lentfer ROUND512(c,d,e,f,g,h,a,b); 705825eb42bSJan Lentfer ROUND512(b,c,d,e,f,g,h,a); 706825eb42bSJan Lentfer } while (j < 80); 707825eb42bSJan Lentfer 708825eb42bSJan Lentfer /* Compute the current intermediate hash value */ 709825eb42bSJan Lentfer context->state[0] += a; 710825eb42bSJan Lentfer context->state[1] += b; 711825eb42bSJan Lentfer context->state[2] += c; 712825eb42bSJan Lentfer context->state[3] += d; 713825eb42bSJan Lentfer context->state[4] += e; 714825eb42bSJan Lentfer context->state[5] += f; 715825eb42bSJan Lentfer context->state[6] += g; 716825eb42bSJan Lentfer context->state[7] += h; 717825eb42bSJan Lentfer 718825eb42bSJan Lentfer /* Clean up */ 719825eb42bSJan Lentfer a = b = c = d = e = f = g = h = T1 = 0; 720825eb42bSJan Lentfer } 721825eb42bSJan Lentfer 722825eb42bSJan Lentfer #else /* SHA2_UNROLL_TRANSFORM */ 723825eb42bSJan Lentfer 724825eb42bSJan Lentfer static void ldns_sha512_Transform(ldns_sha512_CTX* context, 725825eb42bSJan Lentfer const sha2_word64* data) { 726825eb42bSJan Lentfer sha2_word64 a, b, c, d, e, f, g, h, s0, s1; 727825eb42bSJan Lentfer sha2_word64 T1, T2, *W512 = (sha2_word64*)context->buffer; 728825eb42bSJan Lentfer int j; 729825eb42bSJan Lentfer 730825eb42bSJan Lentfer /* initialize registers with the prev. intermediate value */ 731825eb42bSJan Lentfer a = context->state[0]; 732825eb42bSJan Lentfer b = context->state[1]; 733825eb42bSJan Lentfer c = context->state[2]; 734825eb42bSJan Lentfer d = context->state[3]; 735825eb42bSJan Lentfer e = context->state[4]; 736825eb42bSJan Lentfer f = context->state[5]; 737825eb42bSJan Lentfer g = context->state[6]; 738825eb42bSJan Lentfer h = context->state[7]; 739825eb42bSJan Lentfer 740825eb42bSJan Lentfer j = 0; 741825eb42bSJan Lentfer do { 742825eb42bSJan Lentfer #if BYTE_ORDER == LITTLE_ENDIAN 743825eb42bSJan Lentfer /* Convert TO host byte order */ 744825eb42bSJan Lentfer REVERSE64(*data++, W512[j]); 745825eb42bSJan Lentfer /* Apply the SHA-512 compression function to update a..h */ 746825eb42bSJan Lentfer T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j]; 747825eb42bSJan Lentfer #else /* BYTE_ORDER == LITTLE_ENDIAN */ 748825eb42bSJan Lentfer /* Apply the SHA-512 compression function to update a..h with copy */ 749825eb42bSJan Lentfer T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++); 750825eb42bSJan Lentfer #endif /* BYTE_ORDER == LITTLE_ENDIAN */ 751825eb42bSJan Lentfer T2 = Sigma0_512(a) + Maj(a, b, c); 752825eb42bSJan Lentfer h = g; 753825eb42bSJan Lentfer g = f; 754825eb42bSJan Lentfer f = e; 755825eb42bSJan Lentfer e = d + T1; 756825eb42bSJan Lentfer d = c; 757825eb42bSJan Lentfer c = b; 758825eb42bSJan Lentfer b = a; 759825eb42bSJan Lentfer a = T1 + T2; 760825eb42bSJan Lentfer 761825eb42bSJan Lentfer j++; 762825eb42bSJan Lentfer } while (j < 16); 763825eb42bSJan Lentfer 764825eb42bSJan Lentfer do { 765825eb42bSJan Lentfer /* Part of the message block expansion: */ 766825eb42bSJan Lentfer s0 = W512[(j+1)&0x0f]; 767825eb42bSJan Lentfer s0 = sigma0_512(s0); 768825eb42bSJan Lentfer s1 = W512[(j+14)&0x0f]; 769825eb42bSJan Lentfer s1 = sigma1_512(s1); 770825eb42bSJan Lentfer 771825eb42bSJan Lentfer /* Apply the SHA-512 compression function to update a..h */ 772825eb42bSJan Lentfer T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + 773825eb42bSJan Lentfer (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); 774825eb42bSJan Lentfer T2 = Sigma0_512(a) + Maj(a, b, c); 775825eb42bSJan Lentfer h = g; 776825eb42bSJan Lentfer g = f; 777825eb42bSJan Lentfer f = e; 778825eb42bSJan Lentfer e = d + T1; 779825eb42bSJan Lentfer d = c; 780825eb42bSJan Lentfer c = b; 781825eb42bSJan Lentfer b = a; 782825eb42bSJan Lentfer a = T1 + T2; 783825eb42bSJan Lentfer 784825eb42bSJan Lentfer j++; 785825eb42bSJan Lentfer } while (j < 80); 786825eb42bSJan Lentfer 787825eb42bSJan Lentfer /* Compute the current intermediate hash value */ 788825eb42bSJan Lentfer context->state[0] += a; 789825eb42bSJan Lentfer context->state[1] += b; 790825eb42bSJan Lentfer context->state[2] += c; 791825eb42bSJan Lentfer context->state[3] += d; 792825eb42bSJan Lentfer context->state[4] += e; 793825eb42bSJan Lentfer context->state[5] += f; 794825eb42bSJan Lentfer context->state[6] += g; 795825eb42bSJan Lentfer context->state[7] += h; 796825eb42bSJan Lentfer 797825eb42bSJan Lentfer /* Clean up */ 798825eb42bSJan Lentfer a = b = c = d = e = f = g = h = T1 = T2 = 0; 799825eb42bSJan Lentfer } 800825eb42bSJan Lentfer 801825eb42bSJan Lentfer #endif /* SHA2_UNROLL_TRANSFORM */ 802825eb42bSJan Lentfer 803825eb42bSJan Lentfer void ldns_sha512_update(ldns_sha512_CTX* context, const sha2_byte *data, size_t len) { 804fd185f4dSJan Lentfer size_t freespace, usedspace; 805825eb42bSJan Lentfer 806825eb42bSJan Lentfer if (len == 0) { 807825eb42bSJan Lentfer /* Calling with no data is valid - we do nothing */ 808825eb42bSJan Lentfer return; 809825eb42bSJan Lentfer } 810825eb42bSJan Lentfer 811825eb42bSJan Lentfer /* Sanity check: */ 812825eb42bSJan Lentfer assert(context != (ldns_sha512_CTX*)0 && data != (sha2_byte*)0); 813825eb42bSJan Lentfer 814825eb42bSJan Lentfer usedspace = (context->bitcount[0] >> 3) % LDNS_SHA512_BLOCK_LENGTH; 815825eb42bSJan Lentfer if (usedspace > 0) { 816825eb42bSJan Lentfer /* Calculate how much free space is available in the buffer */ 817825eb42bSJan Lentfer freespace = LDNS_SHA512_BLOCK_LENGTH - usedspace; 818825eb42bSJan Lentfer 819825eb42bSJan Lentfer if (len >= freespace) { 820825eb42bSJan Lentfer /* Fill the buffer completely and process it */ 821825eb42bSJan Lentfer MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace); 822825eb42bSJan Lentfer ADDINC128(context->bitcount, freespace << 3); 823825eb42bSJan Lentfer len -= freespace; 824825eb42bSJan Lentfer data += freespace; 825825eb42bSJan Lentfer ldns_sha512_Transform(context, (sha2_word64*)context->buffer); 826825eb42bSJan Lentfer } else { 827825eb42bSJan Lentfer /* The buffer is not yet full */ 828825eb42bSJan Lentfer MEMCPY_BCOPY(&context->buffer[usedspace], data, len); 829825eb42bSJan Lentfer ADDINC128(context->bitcount, len << 3); 830825eb42bSJan Lentfer /* Clean up: */ 831825eb42bSJan Lentfer usedspace = freespace = 0; 832825eb42bSJan Lentfer return; 833825eb42bSJan Lentfer } 834825eb42bSJan Lentfer } 835825eb42bSJan Lentfer while (len >= LDNS_SHA512_BLOCK_LENGTH) { 836825eb42bSJan Lentfer /* Process as many complete blocks as we can */ 837825eb42bSJan Lentfer ldns_sha512_Transform(context, (sha2_word64*)data); 838825eb42bSJan Lentfer ADDINC128(context->bitcount, LDNS_SHA512_BLOCK_LENGTH << 3); 839825eb42bSJan Lentfer len -= LDNS_SHA512_BLOCK_LENGTH; 840825eb42bSJan Lentfer data += LDNS_SHA512_BLOCK_LENGTH; 841825eb42bSJan Lentfer } 842825eb42bSJan Lentfer if (len > 0) { 843825eb42bSJan Lentfer /* There's left-overs, so save 'em */ 844825eb42bSJan Lentfer MEMCPY_BCOPY(context->buffer, data, len); 845825eb42bSJan Lentfer ADDINC128(context->bitcount, len << 3); 846825eb42bSJan Lentfer } 847825eb42bSJan Lentfer /* Clean up: */ 848825eb42bSJan Lentfer usedspace = freespace = 0; 849825eb42bSJan Lentfer } 850825eb42bSJan Lentfer 851825eb42bSJan Lentfer static void ldns_sha512_Last(ldns_sha512_CTX* context) { 852fd185f4dSJan Lentfer size_t usedspace; 853825eb42bSJan Lentfer 854825eb42bSJan Lentfer usedspace = (context->bitcount[0] >> 3) % LDNS_SHA512_BLOCK_LENGTH; 855825eb42bSJan Lentfer #if BYTE_ORDER == LITTLE_ENDIAN 856825eb42bSJan Lentfer /* Convert FROM host byte order */ 857825eb42bSJan Lentfer REVERSE64(context->bitcount[0],context->bitcount[0]); 858825eb42bSJan Lentfer REVERSE64(context->bitcount[1],context->bitcount[1]); 859825eb42bSJan Lentfer #endif 860825eb42bSJan Lentfer if (usedspace > 0) { 861825eb42bSJan Lentfer /* Begin padding with a 1 bit: */ 862825eb42bSJan Lentfer context->buffer[usedspace++] = 0x80; 863825eb42bSJan Lentfer 864825eb42bSJan Lentfer if (usedspace <= ldns_sha512_SHORT_BLOCK_LENGTH) { 865825eb42bSJan Lentfer /* Set-up for the last transform: */ 866825eb42bSJan Lentfer MEMSET_BZERO(&context->buffer[usedspace], ldns_sha512_SHORT_BLOCK_LENGTH - usedspace); 867825eb42bSJan Lentfer } else { 868825eb42bSJan Lentfer if (usedspace < LDNS_SHA512_BLOCK_LENGTH) { 869825eb42bSJan Lentfer MEMSET_BZERO(&context->buffer[usedspace], LDNS_SHA512_BLOCK_LENGTH - usedspace); 870825eb42bSJan Lentfer } 871825eb42bSJan Lentfer /* Do second-to-last transform: */ 872825eb42bSJan Lentfer ldns_sha512_Transform(context, (sha2_word64*)context->buffer); 873825eb42bSJan Lentfer 874825eb42bSJan Lentfer /* And set-up for the last transform: */ 875825eb42bSJan Lentfer MEMSET_BZERO(context->buffer, LDNS_SHA512_BLOCK_LENGTH - 2); 876825eb42bSJan Lentfer } 877825eb42bSJan Lentfer } else { 878825eb42bSJan Lentfer /* Prepare for final transform: */ 879825eb42bSJan Lentfer MEMSET_BZERO(context->buffer, ldns_sha512_SHORT_BLOCK_LENGTH); 880825eb42bSJan Lentfer 881825eb42bSJan Lentfer /* Begin padding with a 1 bit: */ 882825eb42bSJan Lentfer *context->buffer = 0x80; 883825eb42bSJan Lentfer } 884825eb42bSJan Lentfer /* Store the length of input data (in bits): */ 885825eb42bSJan Lentfer *(sha2_word64*)&context->buffer[ldns_sha512_SHORT_BLOCK_LENGTH] = context->bitcount[1]; 886825eb42bSJan Lentfer *(sha2_word64*)&context->buffer[ldns_sha512_SHORT_BLOCK_LENGTH+8] = context->bitcount[0]; 887825eb42bSJan Lentfer 888825eb42bSJan Lentfer /* final transform: */ 889825eb42bSJan Lentfer ldns_sha512_Transform(context, (sha2_word64*)context->buffer); 890825eb42bSJan Lentfer } 891825eb42bSJan Lentfer 892825eb42bSJan Lentfer void ldns_sha512_final(sha2_byte digest[], ldns_sha512_CTX* context) { 893825eb42bSJan Lentfer sha2_word64 *d = (sha2_word64*)digest; 894825eb42bSJan Lentfer 895825eb42bSJan Lentfer /* Sanity check: */ 896825eb42bSJan Lentfer assert(context != (ldns_sha512_CTX*)0); 897825eb42bSJan Lentfer 898825eb42bSJan Lentfer /* If no digest buffer is passed, we don't bother doing this: */ 899825eb42bSJan Lentfer if (digest != (sha2_byte*)0) { 900825eb42bSJan Lentfer ldns_sha512_Last(context); 901825eb42bSJan Lentfer 902825eb42bSJan Lentfer /* Save the hash data for output: */ 903825eb42bSJan Lentfer #if BYTE_ORDER == LITTLE_ENDIAN 904825eb42bSJan Lentfer { 905825eb42bSJan Lentfer /* Convert TO host byte order */ 906825eb42bSJan Lentfer int j; 907825eb42bSJan Lentfer for (j = 0; j < 8; j++) { 908825eb42bSJan Lentfer REVERSE64(context->state[j],context->state[j]); 909825eb42bSJan Lentfer *d++ = context->state[j]; 910825eb42bSJan Lentfer } 911825eb42bSJan Lentfer } 912825eb42bSJan Lentfer #else 913825eb42bSJan Lentfer MEMCPY_BCOPY(d, context->state, LDNS_SHA512_DIGEST_LENGTH); 914825eb42bSJan Lentfer #endif 915825eb42bSJan Lentfer } 916825eb42bSJan Lentfer 917825eb42bSJan Lentfer /* Zero out state data */ 918*b5dedccaSJan Lentfer MEMSET_BZERO(context, sizeof(ldns_sha512_CTX)); 919825eb42bSJan Lentfer } 920825eb42bSJan Lentfer 921825eb42bSJan Lentfer unsigned char * 922825eb42bSJan Lentfer ldns_sha512(unsigned char *data, unsigned int data_len, unsigned char *digest) 923825eb42bSJan Lentfer { 924825eb42bSJan Lentfer ldns_sha512_CTX ctx; 925825eb42bSJan Lentfer ldns_sha512_init(&ctx); 926825eb42bSJan Lentfer ldns_sha512_update(&ctx, data, data_len); 927825eb42bSJan Lentfer ldns_sha512_final(digest, &ctx); 928825eb42bSJan Lentfer return digest; 929825eb42bSJan Lentfer } 930825eb42bSJan Lentfer 931825eb42bSJan Lentfer /*** SHA-384: *********************************************************/ 932825eb42bSJan Lentfer void ldns_sha384_init(ldns_sha384_CTX* context) { 933825eb42bSJan Lentfer if (context == (ldns_sha384_CTX*)0) { 934825eb42bSJan Lentfer return; 935825eb42bSJan Lentfer } 936825eb42bSJan Lentfer MEMCPY_BCOPY(context->state, sha384_initial_hash_value, LDNS_SHA512_DIGEST_LENGTH); 937825eb42bSJan Lentfer MEMSET_BZERO(context->buffer, LDNS_SHA384_BLOCK_LENGTH); 938825eb42bSJan Lentfer context->bitcount[0] = context->bitcount[1] = 0; 939825eb42bSJan Lentfer } 940825eb42bSJan Lentfer 941825eb42bSJan Lentfer void ldns_sha384_update(ldns_sha384_CTX* context, const sha2_byte* data, size_t len) { 942825eb42bSJan Lentfer ldns_sha512_update((ldns_sha512_CTX*)context, data, len); 943825eb42bSJan Lentfer } 944825eb42bSJan Lentfer 945825eb42bSJan Lentfer void ldns_sha384_final(sha2_byte digest[], ldns_sha384_CTX* context) { 946825eb42bSJan Lentfer sha2_word64 *d = (sha2_word64*)digest; 947825eb42bSJan Lentfer 948825eb42bSJan Lentfer /* Sanity check: */ 949825eb42bSJan Lentfer assert(context != (ldns_sha384_CTX*)0); 950825eb42bSJan Lentfer 951825eb42bSJan Lentfer /* If no digest buffer is passed, we don't bother doing this: */ 952825eb42bSJan Lentfer if (digest != (sha2_byte*)0) { 953825eb42bSJan Lentfer ldns_sha512_Last((ldns_sha512_CTX*)context); 954825eb42bSJan Lentfer 955825eb42bSJan Lentfer /* Save the hash data for output: */ 956825eb42bSJan Lentfer #if BYTE_ORDER == LITTLE_ENDIAN 957825eb42bSJan Lentfer { 958825eb42bSJan Lentfer /* Convert TO host byte order */ 959825eb42bSJan Lentfer int j; 960825eb42bSJan Lentfer for (j = 0; j < 6; j++) { 961825eb42bSJan Lentfer REVERSE64(context->state[j],context->state[j]); 962825eb42bSJan Lentfer *d++ = context->state[j]; 963825eb42bSJan Lentfer } 964825eb42bSJan Lentfer } 965825eb42bSJan Lentfer #else 966825eb42bSJan Lentfer MEMCPY_BCOPY(d, context->state, LDNS_SHA384_DIGEST_LENGTH); 967825eb42bSJan Lentfer #endif 968825eb42bSJan Lentfer } 969825eb42bSJan Lentfer 970825eb42bSJan Lentfer /* Zero out state data */ 971*b5dedccaSJan Lentfer MEMSET_BZERO(context, sizeof(ldns_sha384_CTX)); 972825eb42bSJan Lentfer } 973825eb42bSJan Lentfer 974825eb42bSJan Lentfer unsigned char * 975825eb42bSJan Lentfer ldns_sha384(unsigned char *data, unsigned int data_len, unsigned char *digest) 976825eb42bSJan Lentfer { 977825eb42bSJan Lentfer ldns_sha384_CTX ctx; 978825eb42bSJan Lentfer ldns_sha384_init(&ctx); 979825eb42bSJan Lentfer ldns_sha384_update(&ctx, data, data_len); 980825eb42bSJan Lentfer ldns_sha384_final(digest, &ctx); 981825eb42bSJan Lentfer return digest; 982825eb42bSJan Lentfer } 983