1253119Sdelphij/* $KAME: sha2.c,v 1.11 2004/06/02 09:52:45 itojun Exp $ */ 278064Sume 378064Sume/* 478064Sume * sha2.c 578064Sume * 678064Sume * Version 1.0.0beta1 778064Sume * 878064Sume * Written by Aaron D. Gifford <me@aarongifford.com> 978064Sume * 1078064Sume * Copyright 2000 Aaron D. Gifford. All rights reserved. 1178064Sume * 1278064Sume * Redistribution and use in source and binary forms, with or without 1378064Sume * modification, are permitted provided that the following conditions 1478064Sume * are met: 1578064Sume * 1. Redistributions of source code must retain the above copyright 1678064Sume * notice, this list of conditions and the following disclaimer. 1778064Sume * 2. Redistributions in binary form must reproduce the above copyright 1878064Sume * notice, this list of conditions and the following disclaimer in the 1978064Sume * documentation and/or other materials provided with the distribution. 2078064Sume * 3. Neither the name of the copyright holder nor the names of contributors 2178064Sume * may be used to endorse or promote products derived from this software 2278064Sume * without specific prior written permission. 2378064Sume * 2478064Sume * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTOR(S) ``AS IS'' AND 2578064Sume * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2678064Sume * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2778064Sume * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE 2878064Sume * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2978064Sume * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3078064Sume * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3178064Sume * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3278064Sume * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3378064Sume * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3478064Sume * SUCH DAMAGE. 35253119Sdelphij * 3678064Sume */ 3778064Sume 38116174Sobrien#include <sys/cdefs.h> 39116174Sobrien__FBSDID("$FreeBSD$"); 4078064Sume 4178064Sume#include <sys/types.h> 4278064Sume#include <sys/time.h> 43106287Sphk#ifdef _KERNEL 4478064Sume#include <sys/systm.h> 45106287Sphk#else 46106287Sphk#include <string.h> 47106287Sphk#endif 4878064Sume#include <machine/endian.h> 4978064Sume#include <crypto/sha2/sha2.h> 5078064Sume 5178064Sume/* 5278064Sume * ASSERT NOTE: 5378064Sume * Some sanity checking code is included using assert(). On my FreeBSD 5478064Sume * system, this additional code can be removed by compiling with NDEBUG 5578064Sume * defined. Check your own systems manpage on assert() to see how to 5678064Sume * compile WITHOUT the sanity checking code on your system. 5778064Sume * 5878064Sume * UNROLLED TRANSFORM LOOP NOTE: 5978064Sume * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform 6078064Sume * loop version for the hash transform rounds (defined using macros 6178064Sume * later in this file). Either define on the command line, for example: 6278064Sume * 6378064Sume * cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c 6478064Sume * 6578064Sume * or define below: 6678064Sume * 6778064Sume * #define SHA2_UNROLL_TRANSFORM 6878064Sume * 6978064Sume */ 7078064Sume 71253119Sdelphij#if defined(_KERNEL) && defined(__FreeBSD__) 7278064Sume#define assert(x) 73253090Srmh#else 74253090Srmh#include <assert.h> 7578064Sume#endif 7678064Sume 7778064Sume 7878064Sume/*** SHA-256/384/512 Machine Architecture Definitions *****************/ 7978064Sume/* 8078064Sume * BYTE_ORDER NOTE: 8178064Sume * 8278064Sume * Please make sure that your system defines BYTE_ORDER. If your 8378064Sume * architecture is little-endian, make sure it also defines 8478064Sume * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are 8578064Sume * equivilent. 8678064Sume * 8778064Sume * If your system does not define the above, then you can do so by 8878064Sume * hand like this: 8978064Sume * 9078064Sume * #define LITTLE_ENDIAN 1234 9178064Sume * #define BIG_ENDIAN 4321 9278064Sume * 9378064Sume * And for little-endian machines, add: 9478064Sume * 9578064Sume * #define BYTE_ORDER LITTLE_ENDIAN 9678064Sume * 9778064Sume * Or for big-endian machines: 9878064Sume * 9978064Sume * #define BYTE_ORDER BIG_ENDIAN 10078064Sume * 10178064Sume * The FreeBSD machine this was written on defines BYTE_ORDER 10278064Sume * appropriately by including <sys/types.h> (which in turn includes 10378064Sume * <machine/endian.h> where the appropriate definitions are actually 10478064Sume * made). 10578064Sume */ 10678064Sume#if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN) 10778064Sume#error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN 10878064Sume#endif 10978064Sume 11078064Sume/* 11178064Sume * Define the followingsha2_* types to types of the correct length on 11278064Sume * the native archtecture. Most BSD systems and Linux define u_intXX_t 11378064Sume * types. Machines with very recent ANSI C headers, can use the 11478064Sume * uintXX_t definintions from inttypes.h by defining SHA2_USE_INTTYPES_H 11578064Sume * during compile or in the sha.h header file. 11678064Sume * 11778064Sume * Machines that support neither u_intXX_t nor inttypes.h's uintXX_t 11878064Sume * will need to define these three typedefs below (and the appropriate 11978064Sume * ones in sha.h too) by hand according to their system architecture. 12078064Sume * 12178064Sume * Thank you, Jun-ichiro itojun Hagino, for suggesting using u_intXX_t 12278064Sume * types and pointing out recent ANSI C support for uintXX_t in inttypes.h. 12378064Sume */ 12478064Sume#if 0 /*def SHA2_USE_INTTYPES_H*/ 12578064Sume 12678064Sumetypedef uint8_t sha2_byte; /* Exactly 1 byte */ 12778064Sumetypedef uint32_t sha2_word32; /* Exactly 4 bytes */ 12878064Sumetypedef uint64_t sha2_word64; /* Exactly 8 bytes */ 12978064Sume 13078064Sume#else /* SHA2_USE_INTTYPES_H */ 13178064Sume 13278064Sumetypedef u_int8_t sha2_byte; /* Exactly 1 byte */ 13378064Sumetypedef u_int32_t sha2_word32; /* Exactly 4 bytes */ 13478064Sumetypedef u_int64_t sha2_word64; /* Exactly 8 bytes */ 13578064Sume 13678064Sume#endif /* SHA2_USE_INTTYPES_H */ 13778064Sume 13878064Sume 13978064Sume/*** SHA-256/384/512 Various Length Definitions ***********************/ 14078064Sume/* NOTE: Most of these are in sha2.h */ 14178064Sume#define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8) 14278064Sume#define SHA384_SHORT_BLOCK_LENGTH (SHA384_BLOCK_LENGTH - 16) 14378064Sume#define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16) 14478064Sume 14578064Sume 14678064Sume/*** ENDIAN REVERSAL MACROS *******************************************/ 14778064Sume#if BYTE_ORDER == LITTLE_ENDIAN 14878064Sume#define REVERSE32(w,x) { \ 14978064Sume sha2_word32 tmp = (w); \ 15078064Sume tmp = (tmp >> 16) | (tmp << 16); \ 15178064Sume (x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \ 15278064Sume} 15378064Sume#define REVERSE64(w,x) { \ 15478064Sume sha2_word64 tmp = (w); \ 15578064Sume tmp = (tmp >> 32) | (tmp << 32); \ 15678064Sume tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \ 15778064Sume ((tmp & 0x00ff00ff00ff00ffULL) << 8); \ 15878064Sume (x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \ 15978064Sume ((tmp & 0x0000ffff0000ffffULL) << 16); \ 16078064Sume} 16178064Sume#endif /* BYTE_ORDER == LITTLE_ENDIAN */ 16278064Sume 16378064Sume/* 16478064Sume * Macro for incrementally adding the unsigned 64-bit integer n to the 16578064Sume * unsigned 128-bit integer (represented using a two-element array of 16678064Sume * 64-bit words): 16778064Sume */ 16878064Sume#define ADDINC128(w,n) { \ 16978064Sume (w)[0] += (sha2_word64)(n); \ 17078064Sume if ((w)[0] < (n)) { \ 17178064Sume (w)[1]++; \ 17278064Sume } \ 17378064Sume} 17478064Sume 17578064Sume/*** THE SIX LOGICAL FUNCTIONS ****************************************/ 17678064Sume/* 17778064Sume * Bit shifting and rotation (used by the six SHA-XYZ logical functions: 17878064Sume * 17978064Sume * NOTE: The naming of R and S appears backwards here (R is a SHIFT and 18078064Sume * S is a ROTATION) because the SHA-256/384/512 description document 18178064Sume * (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this 18278064Sume * same "backwards" definition. 18378064Sume */ 18478064Sume/* Shift-right (used in SHA-256, SHA-384, and SHA-512): */ 18578064Sume#define R(b,x) ((x) >> (b)) 18678064Sume/* 32-bit Rotate-right (used in SHA-256): */ 18778064Sume#define S32(b,x) (((x) >> (b)) | ((x) << (32 - (b)))) 18878064Sume/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */ 18978064Sume#define S64(b,x) (((x) >> (b)) | ((x) << (64 - (b)))) 19078064Sume 19178064Sume/* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */ 19278064Sume#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) 19378064Sume#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) 19478064Sume 19578064Sume/* Four of six logical functions used in SHA-256: */ 19678064Sume#define Sigma0_256(x) (S32(2, (x)) ^ S32(13, (x)) ^ S32(22, (x))) 19778064Sume#define Sigma1_256(x) (S32(6, (x)) ^ S32(11, (x)) ^ S32(25, (x))) 19878064Sume#define sigma0_256(x) (S32(7, (x)) ^ S32(18, (x)) ^ R(3 , (x))) 19978064Sume#define sigma1_256(x) (S32(17, (x)) ^ S32(19, (x)) ^ R(10, (x))) 20078064Sume 20178064Sume/* Four of six logical functions used in SHA-384 and SHA-512: */ 20278064Sume#define Sigma0_512(x) (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x))) 20378064Sume#define Sigma1_512(x) (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x))) 20478064Sume#define sigma0_512(x) (S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7, (x))) 20578064Sume#define sigma1_512(x) (S64(19, (x)) ^ S64(61, (x)) ^ R( 6, (x))) 20678064Sume 20778064Sume/*** INTERNAL FUNCTION PROTOTYPES *************************************/ 20878064Sume/* NOTE: These should not be accessed directly from outside this 20978064Sume * library -- they are intended for private internal visibility/use 21078064Sume * only. 21178064Sume */ 212218918Sbrucecstatic void SHA512_Last(SHA512_CTX*); 213218918Sbrucecstatic void SHA256_Transform(SHA256_CTX*, const sha2_word32*); 214218918Sbrucecstatic void SHA512_Transform(SHA512_CTX*, const sha2_word64*); 21578064Sume 21678064Sume 21778064Sume/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/ 21878064Sume/* Hash constant words K for SHA-256: */ 219100081Smarkmstatic const sha2_word32 K256[64] = { 22078064Sume 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 22178064Sume 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 22278064Sume 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, 22378064Sume 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, 22478064Sume 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, 22578064Sume 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 22678064Sume 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 22778064Sume 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, 22878064Sume 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, 22978064Sume 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, 23078064Sume 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 23178064Sume 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 23278064Sume 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, 23378064Sume 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, 23478064Sume 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, 23578064Sume 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL 23678064Sume}; 23778064Sume 23878064Sume/* Initial hash value H for SHA-256: */ 239100081Smarkmstatic const sha2_word32 sha256_initial_hash_value[8] = { 24078064Sume 0x6a09e667UL, 24178064Sume 0xbb67ae85UL, 24278064Sume 0x3c6ef372UL, 24378064Sume 0xa54ff53aUL, 24478064Sume 0x510e527fUL, 24578064Sume 0x9b05688cUL, 24678064Sume 0x1f83d9abUL, 24778064Sume 0x5be0cd19UL 24878064Sume}; 24978064Sume 25078064Sume/* Hash constant words K for SHA-384 and SHA-512: */ 251100081Smarkmstatic const sha2_word64 K512[80] = { 25278064Sume 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 25378064Sume 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, 25478064Sume 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 25578064Sume 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 25678064Sume 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 25778064Sume 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, 25878064Sume 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 25978064Sume 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, 26078064Sume 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 26178064Sume 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 26278064Sume 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 26378064Sume 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, 26478064Sume 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 26578064Sume 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, 26678064Sume 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 26778064Sume 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 26878064Sume 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 26978064Sume 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, 27078064Sume 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 27178064Sume 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, 27278064Sume 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 27378064Sume 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 27478064Sume 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 27578064Sume 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, 27678064Sume 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 27778064Sume 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, 27878064Sume 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 27978064Sume 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 28078064Sume 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 28178064Sume 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, 28278064Sume 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 28378064Sume 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, 28478064Sume 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 28578064Sume 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 28678064Sume 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 28778064Sume 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, 28878064Sume 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 28978064Sume 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, 29078064Sume 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 29178064Sume 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL 29278064Sume}; 29378064Sume 29478064Sume/* Initial hash value H for SHA-384 */ 295100081Smarkmstatic const sha2_word64 sha384_initial_hash_value[8] = { 29678064Sume 0xcbbb9d5dc1059ed8ULL, 29778064Sume 0x629a292a367cd507ULL, 29878064Sume 0x9159015a3070dd17ULL, 29978064Sume 0x152fecd8f70e5939ULL, 30078064Sume 0x67332667ffc00b31ULL, 30178064Sume 0x8eb44a8768581511ULL, 30278064Sume 0xdb0c2e0d64f98fa7ULL, 30378064Sume 0x47b5481dbefa4fa4ULL 30478064Sume}; 30578064Sume 30678064Sume/* Initial hash value H for SHA-512 */ 307100081Smarkmstatic const sha2_word64 sha512_initial_hash_value[8] = { 30878064Sume 0x6a09e667f3bcc908ULL, 30978064Sume 0xbb67ae8584caa73bULL, 31078064Sume 0x3c6ef372fe94f82bULL, 31178064Sume 0xa54ff53a5f1d36f1ULL, 31278064Sume 0x510e527fade682d1ULL, 31378064Sume 0x9b05688c2b3e6c1fULL, 31478064Sume 0x1f83d9abfb41bd6bULL, 31578064Sume 0x5be0cd19137e2179ULL 31678064Sume}; 31778064Sume 31878064Sume/* 31978064Sume * Constant used by SHA256/384/512_End() functions for converting the 32078064Sume * digest to a readable hexadecimal character string: 32178064Sume */ 32278064Sumestatic const char *sha2_hex_digits = "0123456789abcdef"; 32378064Sume 32478064Sume 32578064Sume/*** SHA-256: *********************************************************/ 32678064Sumevoid SHA256_Init(SHA256_CTX* context) { 32778064Sume if (context == (SHA256_CTX*)0) { 32878064Sume return; 32978064Sume } 33078064Sume bcopy(sha256_initial_hash_value, context->state, SHA256_DIGEST_LENGTH); 33178064Sume bzero(context->buffer, SHA256_BLOCK_LENGTH); 33278064Sume context->bitcount = 0; 33378064Sume} 33478064Sume 33578064Sume#ifdef SHA2_UNROLL_TRANSFORM 33678064Sume 33778064Sume/* Unrolled SHA-256 round macros: */ 33878064Sume 33978064Sume#if BYTE_ORDER == LITTLE_ENDIAN 34078064Sume 34178064Sume#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ 34278064Sume REVERSE32(*data++, W256[j]); \ 34378064Sume T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ 34478064Sume K256[j] + W256[j]; \ 34578064Sume (d) += T1; \ 34678064Sume (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ 34778064Sume j++ 34878064Sume 34978064Sume 35078064Sume#else /* BYTE_ORDER == LITTLE_ENDIAN */ 35178064Sume 35278064Sume#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ 35378064Sume T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ 35478064Sume K256[j] + (W256[j] = *data++); \ 35578064Sume (d) += T1; \ 35678064Sume (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ 35778064Sume j++ 35878064Sume 35978064Sume#endif /* BYTE_ORDER == LITTLE_ENDIAN */ 36078064Sume 36178064Sume#define ROUND256(a,b,c,d,e,f,g,h) \ 36278064Sume s0 = W256[(j+1)&0x0f]; \ 36378064Sume s0 = sigma0_256(s0); \ 36478064Sume s1 = W256[(j+14)&0x0f]; \ 36578064Sume s1 = sigma1_256(s1); \ 36678064Sume T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \ 36778064Sume (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \ 36878064Sume (d) += T1; \ 36978064Sume (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ 37078064Sume j++ 37178064Sume 372218918Sbrucecstatic void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) { 37378064Sume sha2_word32 a, b, c, d, e, f, g, h, s0, s1; 37478064Sume sha2_word32 T1, *W256; 37578064Sume int j; 37678064Sume 37778064Sume W256 = (sha2_word32*)context->buffer; 37878064Sume 37978064Sume /* Initialize registers with the prev. intermediate value */ 38078064Sume a = context->state[0]; 38178064Sume b = context->state[1]; 38278064Sume c = context->state[2]; 38378064Sume d = context->state[3]; 38478064Sume e = context->state[4]; 38578064Sume f = context->state[5]; 38678064Sume g = context->state[6]; 38778064Sume h = context->state[7]; 38878064Sume 38978064Sume j = 0; 39078064Sume do { 39178064Sume /* Rounds 0 to 15 (unrolled): */ 39278064Sume ROUND256_0_TO_15(a,b,c,d,e,f,g,h); 39378064Sume ROUND256_0_TO_15(h,a,b,c,d,e,f,g); 39478064Sume ROUND256_0_TO_15(g,h,a,b,c,d,e,f); 39578064Sume ROUND256_0_TO_15(f,g,h,a,b,c,d,e); 39678064Sume ROUND256_0_TO_15(e,f,g,h,a,b,c,d); 39778064Sume ROUND256_0_TO_15(d,e,f,g,h,a,b,c); 39878064Sume ROUND256_0_TO_15(c,d,e,f,g,h,a,b); 39978064Sume ROUND256_0_TO_15(b,c,d,e,f,g,h,a); 40078064Sume } while (j < 16); 40178064Sume 40278064Sume /* Now for the remaining rounds to 64: */ 40378064Sume do { 40478064Sume ROUND256(a,b,c,d,e,f,g,h); 40578064Sume ROUND256(h,a,b,c,d,e,f,g); 40678064Sume ROUND256(g,h,a,b,c,d,e,f); 40778064Sume ROUND256(f,g,h,a,b,c,d,e); 40878064Sume ROUND256(e,f,g,h,a,b,c,d); 40978064Sume ROUND256(d,e,f,g,h,a,b,c); 41078064Sume ROUND256(c,d,e,f,g,h,a,b); 41178064Sume ROUND256(b,c,d,e,f,g,h,a); 41278064Sume } while (j < 64); 41378064Sume 41478064Sume /* Compute the current intermediate hash value */ 41578064Sume context->state[0] += a; 41678064Sume context->state[1] += b; 41778064Sume context->state[2] += c; 41878064Sume context->state[3] += d; 41978064Sume context->state[4] += e; 42078064Sume context->state[5] += f; 42178064Sume context->state[6] += g; 42278064Sume context->state[7] += h; 42378064Sume 42478064Sume /* Clean up */ 42578064Sume a = b = c = d = e = f = g = h = T1 = 0; 42678064Sume} 42778064Sume 42878064Sume#else /* SHA2_UNROLL_TRANSFORM */ 42978064Sume 430218918Sbrucecstatic void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) { 43178064Sume sha2_word32 a, b, c, d, e, f, g, h, s0, s1; 43278064Sume sha2_word32 T1, T2, *W256; 43378064Sume int j; 43478064Sume 43578064Sume W256 = (sha2_word32*)context->buffer; 43678064Sume 43778064Sume /* Initialize registers with the prev. intermediate value */ 43878064Sume a = context->state[0]; 43978064Sume b = context->state[1]; 44078064Sume c = context->state[2]; 44178064Sume d = context->state[3]; 44278064Sume e = context->state[4]; 44378064Sume f = context->state[5]; 44478064Sume g = context->state[6]; 44578064Sume h = context->state[7]; 44678064Sume 44778064Sume j = 0; 44878064Sume do { 44978064Sume#if BYTE_ORDER == LITTLE_ENDIAN 45078064Sume /* Copy data while converting to host byte order */ 45178064Sume REVERSE32(*data++,W256[j]); 45278064Sume /* Apply the SHA-256 compression function to update a..h */ 45378064Sume T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j]; 45478064Sume#else /* BYTE_ORDER == LITTLE_ENDIAN */ 45578064Sume /* Apply the SHA-256 compression function to update a..h with copy */ 45678064Sume T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++); 45778064Sume#endif /* BYTE_ORDER == LITTLE_ENDIAN */ 45878064Sume T2 = Sigma0_256(a) + Maj(a, b, c); 45978064Sume h = g; 46078064Sume g = f; 46178064Sume f = e; 46278064Sume e = d + T1; 46378064Sume d = c; 46478064Sume c = b; 46578064Sume b = a; 46678064Sume a = T1 + T2; 46778064Sume 46878064Sume j++; 46978064Sume } while (j < 16); 47078064Sume 47178064Sume do { 47278064Sume /* Part of the message block expansion: */ 47378064Sume s0 = W256[(j+1)&0x0f]; 47478064Sume s0 = sigma0_256(s0); 47578064Sume s1 = W256[(j+14)&0x0f]; 47678064Sume s1 = sigma1_256(s1); 47778064Sume 47878064Sume /* Apply the SHA-256 compression function to update a..h */ 47978064Sume T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + 48078064Sume (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); 48178064Sume T2 = Sigma0_256(a) + Maj(a, b, c); 48278064Sume h = g; 48378064Sume g = f; 48478064Sume f = e; 48578064Sume e = d + T1; 48678064Sume d = c; 48778064Sume c = b; 48878064Sume b = a; 48978064Sume a = T1 + T2; 49078064Sume 49178064Sume j++; 49278064Sume } while (j < 64); 49378064Sume 49478064Sume /* Compute the current intermediate hash value */ 49578064Sume context->state[0] += a; 49678064Sume context->state[1] += b; 49778064Sume context->state[2] += c; 49878064Sume context->state[3] += d; 49978064Sume context->state[4] += e; 50078064Sume context->state[5] += f; 50178064Sume context->state[6] += g; 50278064Sume context->state[7] += h; 50378064Sume 50478064Sume /* Clean up */ 50578064Sume a = b = c = d = e = f = g = h = T1 = T2 = 0; 50678064Sume} 50778064Sume 50878064Sume#endif /* SHA2_UNROLL_TRANSFORM */ 50978064Sume 51078064Sumevoid SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) { 51178064Sume unsigned int freespace, usedspace; 51278064Sume 51378064Sume if (len == 0) { 51478064Sume /* Calling with no data is valid - we do nothing */ 51578064Sume return; 51678064Sume } 51778064Sume 51878064Sume /* Sanity check: */ 51978064Sume assert(context != (SHA256_CTX*)0 && data != (sha2_byte*)0); 52078064Sume 52178064Sume usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; 52278064Sume if (usedspace > 0) { 52378064Sume /* Calculate how much free space is available in the buffer */ 52478064Sume freespace = SHA256_BLOCK_LENGTH - usedspace; 52578064Sume 52678064Sume if (len >= freespace) { 52778064Sume /* Fill the buffer completely and process it */ 52878064Sume bcopy(data, &context->buffer[usedspace], freespace); 52978064Sume context->bitcount += freespace << 3; 53078064Sume len -= freespace; 53178064Sume data += freespace; 53278064Sume SHA256_Transform(context, (sha2_word32*)context->buffer); 53378064Sume } else { 53478064Sume /* The buffer is not yet full */ 53578064Sume bcopy(data, &context->buffer[usedspace], len); 53678064Sume context->bitcount += len << 3; 53778064Sume /* Clean up: */ 53878064Sume usedspace = freespace = 0; 53978064Sume return; 54078064Sume } 54178064Sume } 54278064Sume while (len >= SHA256_BLOCK_LENGTH) { 54378064Sume /* Process as many complete blocks as we can */ 54478358Sume SHA256_Transform(context, (const sha2_word32*)data); 54578064Sume context->bitcount += SHA256_BLOCK_LENGTH << 3; 54678064Sume len -= SHA256_BLOCK_LENGTH; 54778064Sume data += SHA256_BLOCK_LENGTH; 54878064Sume } 54978064Sume if (len > 0) { 55078064Sume /* There's left-overs, so save 'em */ 55178064Sume bcopy(data, context->buffer, len); 55278064Sume context->bitcount += len << 3; 55378064Sume } 55478064Sume /* Clean up: */ 55578064Sume usedspace = freespace = 0; 55678064Sume} 55778064Sume 55878064Sumevoid SHA256_Final(sha2_byte digest[], SHA256_CTX* context) { 55978064Sume sha2_word32 *d = (sha2_word32*)digest; 56078064Sume unsigned int usedspace; 56178064Sume 56278064Sume /* Sanity check: */ 56378064Sume assert(context != (SHA256_CTX*)0); 56478064Sume 56578064Sume /* If no digest buffer is passed, we don't bother doing this: */ 56678064Sume if (digest != (sha2_byte*)0) { 56778064Sume usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; 56878064Sume#if BYTE_ORDER == LITTLE_ENDIAN 56978064Sume /* Convert FROM host byte order */ 57078064Sume REVERSE64(context->bitcount,context->bitcount); 57178064Sume#endif 57278064Sume if (usedspace > 0) { 57378064Sume /* Begin padding with a 1 bit: */ 57478064Sume context->buffer[usedspace++] = 0x80; 57578064Sume 57691313Sume if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) { 57778064Sume /* Set-up for the last transform: */ 57878064Sume bzero(&context->buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace); 57978064Sume } else { 58078064Sume if (usedspace < SHA256_BLOCK_LENGTH) { 58178064Sume bzero(&context->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace); 58278064Sume } 58378064Sume /* Do second-to-last transform: */ 58478064Sume SHA256_Transform(context, (sha2_word32*)context->buffer); 58578064Sume 58678064Sume /* And set-up for the last transform: */ 58778064Sume bzero(context->buffer, SHA256_SHORT_BLOCK_LENGTH); 58878064Sume } 58978064Sume } else { 59078064Sume /* Set-up for the last transform: */ 59178064Sume bzero(context->buffer, SHA256_SHORT_BLOCK_LENGTH); 59278064Sume 59378064Sume /* Begin padding with a 1 bit: */ 59478064Sume *context->buffer = 0x80; 59578064Sume } 59678064Sume /* Set the bit count: */ 59778064Sume *(sha2_word64*)&context->buffer[SHA256_SHORT_BLOCK_LENGTH] = context->bitcount; 59878064Sume 59978064Sume /* Final transform: */ 60078064Sume SHA256_Transform(context, (sha2_word32*)context->buffer); 60178064Sume 60278064Sume#if BYTE_ORDER == LITTLE_ENDIAN 60378064Sume { 60478064Sume /* Convert TO host byte order */ 60578064Sume int j; 60678064Sume for (j = 0; j < 8; j++) { 60778064Sume REVERSE32(context->state[j],context->state[j]); 60878064Sume *d++ = context->state[j]; 60978064Sume } 61078064Sume } 61178064Sume#else 61278064Sume bcopy(context->state, d, SHA256_DIGEST_LENGTH); 61378064Sume#endif 61478064Sume } 61578064Sume 61678064Sume /* Clean up state data: */ 617119890Sphk bzero(context, sizeof(*context)); 61878064Sume usedspace = 0; 61978064Sume} 62078064Sume 62178064Sumechar *SHA256_End(SHA256_CTX* context, char buffer[]) { 62278064Sume sha2_byte digest[SHA256_DIGEST_LENGTH], *d = digest; 62378064Sume int i; 62478064Sume 62578064Sume /* Sanity check: */ 62678064Sume assert(context != (SHA256_CTX*)0); 62778064Sume 62878064Sume if (buffer != (char*)0) { 62978064Sume SHA256_Final(digest, context); 63078064Sume 63178064Sume for (i = 0; i < SHA256_DIGEST_LENGTH; i++) { 63278064Sume *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; 63378064Sume *buffer++ = sha2_hex_digits[*d & 0x0f]; 63478064Sume d++; 63578064Sume } 63678064Sume *buffer = (char)0; 63778064Sume } else { 638119890Sphk bzero(context, sizeof(*context)); 63978064Sume } 64078064Sume bzero(digest, SHA256_DIGEST_LENGTH); 64178064Sume return buffer; 64278064Sume} 64378064Sume 64478064Sumechar* SHA256_Data(const sha2_byte* data, size_t len, char digest[SHA256_DIGEST_STRING_LENGTH]) { 64578064Sume SHA256_CTX context; 64678064Sume 64778064Sume SHA256_Init(&context); 64878064Sume SHA256_Update(&context, data, len); 64978064Sume return SHA256_End(&context, digest); 65078064Sume} 65178064Sume 65278064Sume 65378064Sume/*** SHA-512: *********************************************************/ 65478064Sumevoid SHA512_Init(SHA512_CTX* context) { 65578064Sume if (context == (SHA512_CTX*)0) { 65678064Sume return; 65778064Sume } 65878064Sume bcopy(sha512_initial_hash_value, context->state, SHA512_DIGEST_LENGTH); 65978064Sume bzero(context->buffer, SHA512_BLOCK_LENGTH); 66078064Sume context->bitcount[0] = context->bitcount[1] = 0; 66178064Sume} 66278064Sume 66378064Sume#ifdef SHA2_UNROLL_TRANSFORM 66478064Sume 66578064Sume/* Unrolled SHA-512 round macros: */ 66678064Sume#if BYTE_ORDER == LITTLE_ENDIAN 66778064Sume 66878064Sume#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ 66978064Sume REVERSE64(*data++, W512[j]); \ 67078064Sume T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ 67178064Sume K512[j] + W512[j]; \ 67278064Sume (d) += T1, \ 67378064Sume (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \ 67478064Sume j++ 67578064Sume 67678064Sume 67778064Sume#else /* BYTE_ORDER == LITTLE_ENDIAN */ 67878064Sume 67978064Sume#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ 68078064Sume T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ 68178064Sume K512[j] + (W512[j] = *data++); \ 68278064Sume (d) += T1; \ 68378064Sume (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ 68478064Sume j++ 68578064Sume 68678064Sume#endif /* BYTE_ORDER == LITTLE_ENDIAN */ 68778064Sume 68878064Sume#define ROUND512(a,b,c,d,e,f,g,h) \ 68978064Sume s0 = W512[(j+1)&0x0f]; \ 69078064Sume s0 = sigma0_512(s0); \ 69178064Sume s1 = W512[(j+14)&0x0f]; \ 69278064Sume s1 = sigma1_512(s1); \ 69378064Sume T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \ 69478064Sume (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \ 69578064Sume (d) += T1; \ 69678064Sume (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ 69778064Sume j++ 69878064Sume 699218918Sbrucecstatic void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) { 70078064Sume sha2_word64 a, b, c, d, e, f, g, h, s0, s1; 70178064Sume sha2_word64 T1, *W512 = (sha2_word64*)context->buffer; 70278064Sume int j; 70378064Sume 70478064Sume /* Initialize registers with the prev. intermediate value */ 70578064Sume a = context->state[0]; 70678064Sume b = context->state[1]; 70778064Sume c = context->state[2]; 70878064Sume d = context->state[3]; 70978064Sume e = context->state[4]; 71078064Sume f = context->state[5]; 71178064Sume g = context->state[6]; 71278064Sume h = context->state[7]; 71378064Sume 71478064Sume j = 0; 71578064Sume do { 71678064Sume ROUND512_0_TO_15(a,b,c,d,e,f,g,h); 71778064Sume ROUND512_0_TO_15(h,a,b,c,d,e,f,g); 71878064Sume ROUND512_0_TO_15(g,h,a,b,c,d,e,f); 71978064Sume ROUND512_0_TO_15(f,g,h,a,b,c,d,e); 72078064Sume ROUND512_0_TO_15(e,f,g,h,a,b,c,d); 72178064Sume ROUND512_0_TO_15(d,e,f,g,h,a,b,c); 72278064Sume ROUND512_0_TO_15(c,d,e,f,g,h,a,b); 72378064Sume ROUND512_0_TO_15(b,c,d,e,f,g,h,a); 72478064Sume } while (j < 16); 72578064Sume 72678064Sume /* Now for the remaining rounds up to 79: */ 72778064Sume do { 72878064Sume ROUND512(a,b,c,d,e,f,g,h); 72978064Sume ROUND512(h,a,b,c,d,e,f,g); 73078064Sume ROUND512(g,h,a,b,c,d,e,f); 73178064Sume ROUND512(f,g,h,a,b,c,d,e); 73278064Sume ROUND512(e,f,g,h,a,b,c,d); 73378064Sume ROUND512(d,e,f,g,h,a,b,c); 73478064Sume ROUND512(c,d,e,f,g,h,a,b); 73578064Sume ROUND512(b,c,d,e,f,g,h,a); 73678064Sume } while (j < 80); 73778064Sume 73878064Sume /* Compute the current intermediate hash value */ 73978064Sume context->state[0] += a; 74078064Sume context->state[1] += b; 74178064Sume context->state[2] += c; 74278064Sume context->state[3] += d; 74378064Sume context->state[4] += e; 74478064Sume context->state[5] += f; 74578064Sume context->state[6] += g; 74678064Sume context->state[7] += h; 74778064Sume 74878064Sume /* Clean up */ 74978064Sume a = b = c = d = e = f = g = h = T1 = 0; 75078064Sume} 75178064Sume 75278064Sume#else /* SHA2_UNROLL_TRANSFORM */ 75378064Sume 754218918Sbrucecstatic void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) { 75578064Sume sha2_word64 a, b, c, d, e, f, g, h, s0, s1; 756163602Skevlo sha2_word64 T1 = 0, T2 = 0, *W512 = (sha2_word64*)context->buffer; 75778064Sume int j; 75878064Sume 75978064Sume /* Initialize registers with the prev. intermediate value */ 76078064Sume a = context->state[0]; 76178064Sume b = context->state[1]; 76278064Sume c = context->state[2]; 76378064Sume d = context->state[3]; 76478064Sume e = context->state[4]; 76578064Sume f = context->state[5]; 76678064Sume g = context->state[6]; 76778064Sume h = context->state[7]; 76878064Sume 76978064Sume j = 0; 77078064Sume do { 77178064Sume#if BYTE_ORDER == LITTLE_ENDIAN 77278064Sume /* Convert TO host byte order */ 77378064Sume REVERSE64(*data++, W512[j]); 77478064Sume /* Apply the SHA-512 compression function to update a..h */ 77578064Sume T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j]; 77678064Sume#else /* BYTE_ORDER == LITTLE_ENDIAN */ 77778064Sume /* Apply the SHA-512 compression function to update a..h with copy */ 77878064Sume T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++); 77978064Sume#endif /* BYTE_ORDER == LITTLE_ENDIAN */ 78078064Sume T2 = Sigma0_512(a) + Maj(a, b, c); 78178064Sume h = g; 78278064Sume g = f; 78378064Sume f = e; 78478064Sume e = d + T1; 78578064Sume d = c; 78678064Sume c = b; 78778064Sume b = a; 78878064Sume a = T1 + T2; 78978064Sume 79078064Sume j++; 79178064Sume } while (j < 16); 79278064Sume 79378064Sume do { 79478064Sume /* Part of the message block expansion: */ 79578064Sume s0 = W512[(j+1)&0x0f]; 79678064Sume s0 = sigma0_512(s0); 79778064Sume s1 = W512[(j+14)&0x0f]; 79878064Sume s1 = sigma1_512(s1); 79978064Sume 80078064Sume /* Apply the SHA-512 compression function to update a..h */ 80178064Sume T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + 80278064Sume (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); 80378064Sume T2 = Sigma0_512(a) + Maj(a, b, c); 80478064Sume h = g; 80578064Sume g = f; 80678064Sume f = e; 80778064Sume e = d + T1; 80878064Sume d = c; 80978064Sume c = b; 81078064Sume b = a; 81178064Sume a = T1 + T2; 81278064Sume 81378064Sume j++; 81478064Sume } while (j < 80); 81578064Sume 81678064Sume /* Compute the current intermediate hash value */ 81778064Sume context->state[0] += a; 81878064Sume context->state[1] += b; 81978064Sume context->state[2] += c; 82078064Sume context->state[3] += d; 82178064Sume context->state[4] += e; 82278064Sume context->state[5] += f; 82378064Sume context->state[6] += g; 82478064Sume context->state[7] += h; 82578064Sume 82678064Sume /* Clean up */ 82778064Sume a = b = c = d = e = f = g = h = T1 = T2 = 0; 82878064Sume} 82978064Sume 83078064Sume#endif /* SHA2_UNROLL_TRANSFORM */ 83178064Sume 83278064Sumevoid SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) { 83378064Sume unsigned int freespace, usedspace; 83478064Sume 83578064Sume if (len == 0) { 83678064Sume /* Calling with no data is valid - we do nothing */ 83778064Sume return; 83878064Sume } 83978064Sume 84078064Sume /* Sanity check: */ 84178064Sume assert(context != (SHA512_CTX*)0 && data != (sha2_byte*)0); 84278064Sume 84378064Sume usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; 84478064Sume if (usedspace > 0) { 84578064Sume /* Calculate how much free space is available in the buffer */ 84678064Sume freespace = SHA512_BLOCK_LENGTH - usedspace; 84778064Sume 84878064Sume if (len >= freespace) { 84978064Sume /* Fill the buffer completely and process it */ 85078064Sume bcopy(data, &context->buffer[usedspace], freespace); 85178064Sume ADDINC128(context->bitcount, freespace << 3); 85278064Sume len -= freespace; 85378064Sume data += freespace; 85478064Sume SHA512_Transform(context, (sha2_word64*)context->buffer); 85578064Sume } else { 85678064Sume /* The buffer is not yet full */ 85778064Sume bcopy(data, &context->buffer[usedspace], len); 85878064Sume ADDINC128(context->bitcount, len << 3); 85978064Sume /* Clean up: */ 86078064Sume usedspace = freespace = 0; 86178064Sume return; 86278064Sume } 86378064Sume } 86478064Sume while (len >= SHA512_BLOCK_LENGTH) { 86578064Sume /* Process as many complete blocks as we can */ 86678358Sume SHA512_Transform(context, (const sha2_word64*)data); 86778064Sume ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3); 86878064Sume len -= SHA512_BLOCK_LENGTH; 86978064Sume data += SHA512_BLOCK_LENGTH; 87078064Sume } 87178064Sume if (len > 0) { 87278064Sume /* There's left-overs, so save 'em */ 87378064Sume bcopy(data, context->buffer, len); 87478064Sume ADDINC128(context->bitcount, len << 3); 87578064Sume } 87678064Sume /* Clean up: */ 87778064Sume usedspace = freespace = 0; 87878064Sume} 87978064Sume 880218918Sbrucecstatic void SHA512_Last(SHA512_CTX* context) { 88178064Sume unsigned int usedspace; 88278064Sume 88378064Sume usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; 88478064Sume#if BYTE_ORDER == LITTLE_ENDIAN 88578064Sume /* Convert FROM host byte order */ 88678064Sume REVERSE64(context->bitcount[0],context->bitcount[0]); 88778064Sume REVERSE64(context->bitcount[1],context->bitcount[1]); 88878064Sume#endif 88978064Sume if (usedspace > 0) { 89078064Sume /* Begin padding with a 1 bit: */ 89178064Sume context->buffer[usedspace++] = 0x80; 89278064Sume 89391313Sume if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) { 89478064Sume /* Set-up for the last transform: */ 89578064Sume bzero(&context->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace); 89678064Sume } else { 89778064Sume if (usedspace < SHA512_BLOCK_LENGTH) { 89878064Sume bzero(&context->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace); 89978064Sume } 90078064Sume /* Do second-to-last transform: */ 90178064Sume SHA512_Transform(context, (sha2_word64*)context->buffer); 90278064Sume 90378064Sume /* And set-up for the last transform: */ 90478064Sume bzero(context->buffer, SHA512_BLOCK_LENGTH - 2); 90578064Sume } 90678064Sume } else { 90778064Sume /* Prepare for final transform: */ 90878064Sume bzero(context->buffer, SHA512_SHORT_BLOCK_LENGTH); 90978064Sume 91078064Sume /* Begin padding with a 1 bit: */ 91178064Sume *context->buffer = 0x80; 91278064Sume } 91378064Sume /* Store the length of input data (in bits): */ 91478064Sume *(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH] = context->bitcount[1]; 91578064Sume *(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH+8] = context->bitcount[0]; 91678064Sume 91778064Sume /* Final transform: */ 91878064Sume SHA512_Transform(context, (sha2_word64*)context->buffer); 91978064Sume} 92078064Sume 92178064Sumevoid SHA512_Final(sha2_byte digest[], SHA512_CTX* context) { 92278064Sume sha2_word64 *d = (sha2_word64*)digest; 92378064Sume 92478064Sume /* Sanity check: */ 92578064Sume assert(context != (SHA512_CTX*)0); 92678064Sume 92778064Sume /* If no digest buffer is passed, we don't bother doing this: */ 92878064Sume if (digest != (sha2_byte*)0) { 92978064Sume SHA512_Last(context); 93078064Sume 93178064Sume /* Save the hash data for output: */ 93278064Sume#if BYTE_ORDER == LITTLE_ENDIAN 93378064Sume { 93478064Sume /* Convert TO host byte order */ 93578064Sume int j; 93678064Sume for (j = 0; j < 8; j++) { 93778064Sume REVERSE64(context->state[j],context->state[j]); 93878064Sume *d++ = context->state[j]; 93978064Sume } 94078064Sume } 94178064Sume#else 94278064Sume bcopy(context->state, d, SHA512_DIGEST_LENGTH); 94378064Sume#endif 94478064Sume } 94578064Sume 94678064Sume /* Zero out state data */ 947119890Sphk bzero(context, sizeof(*context)); 94878064Sume} 94978064Sume 95078064Sumechar *SHA512_End(SHA512_CTX* context, char buffer[]) { 95178064Sume sha2_byte digest[SHA512_DIGEST_LENGTH], *d = digest; 95278064Sume int i; 95378064Sume 95478064Sume /* Sanity check: */ 95578064Sume assert(context != (SHA512_CTX*)0); 95678064Sume 95778064Sume if (buffer != (char*)0) { 95878064Sume SHA512_Final(digest, context); 95978064Sume 96078064Sume for (i = 0; i < SHA512_DIGEST_LENGTH; i++) { 96178064Sume *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; 96278064Sume *buffer++ = sha2_hex_digits[*d & 0x0f]; 96378064Sume d++; 96478064Sume } 96578064Sume *buffer = (char)0; 96678064Sume } else { 967119890Sphk bzero(context, sizeof(*context)); 96878064Sume } 96978064Sume bzero(digest, SHA512_DIGEST_LENGTH); 97078064Sume return buffer; 97178064Sume} 97278064Sume 97378064Sumechar* SHA512_Data(const sha2_byte* data, size_t len, char digest[SHA512_DIGEST_STRING_LENGTH]) { 97478064Sume SHA512_CTX context; 97578064Sume 97678064Sume SHA512_Init(&context); 97778064Sume SHA512_Update(&context, data, len); 97878064Sume return SHA512_End(&context, digest); 97978064Sume} 98078064Sume 98178064Sume 98278064Sume/*** SHA-384: *********************************************************/ 98378064Sumevoid SHA384_Init(SHA384_CTX* context) { 98478064Sume if (context == (SHA384_CTX*)0) { 98578064Sume return; 98678064Sume } 98778064Sume bcopy(sha384_initial_hash_value, context->state, SHA512_DIGEST_LENGTH); 98878064Sume bzero(context->buffer, SHA384_BLOCK_LENGTH); 98978064Sume context->bitcount[0] = context->bitcount[1] = 0; 99078064Sume} 99178064Sume 99278064Sumevoid SHA384_Update(SHA384_CTX* context, const sha2_byte* data, size_t len) { 99378064Sume SHA512_Update((SHA512_CTX*)context, data, len); 99478064Sume} 99578064Sume 99678064Sumevoid SHA384_Final(sha2_byte digest[], SHA384_CTX* context) { 99778064Sume sha2_word64 *d = (sha2_word64*)digest; 99878064Sume 99978064Sume /* Sanity check: */ 100078064Sume assert(context != (SHA384_CTX*)0); 100178064Sume 100278064Sume /* If no digest buffer is passed, we don't bother doing this: */ 100378064Sume if (digest != (sha2_byte*)0) { 100478064Sume SHA512_Last((SHA512_CTX*)context); 100578064Sume 100678064Sume /* Save the hash data for output: */ 100778064Sume#if BYTE_ORDER == LITTLE_ENDIAN 100878064Sume { 100978064Sume /* Convert TO host byte order */ 101078064Sume int j; 101178064Sume for (j = 0; j < 6; j++) { 101278064Sume REVERSE64(context->state[j],context->state[j]); 101378064Sume *d++ = context->state[j]; 101478064Sume } 101578064Sume } 101678064Sume#else 101778064Sume bcopy(context->state, d, SHA384_DIGEST_LENGTH); 101878064Sume#endif 101978064Sume } 102078064Sume 102178064Sume /* Zero out state data */ 1022119890Sphk bzero(context, sizeof(*context)); 102378064Sume} 102478064Sume 102578064Sumechar *SHA384_End(SHA384_CTX* context, char buffer[]) { 102678064Sume sha2_byte digest[SHA384_DIGEST_LENGTH], *d = digest; 102778064Sume int i; 102878064Sume 102978064Sume /* Sanity check: */ 103078064Sume assert(context != (SHA384_CTX*)0); 103178064Sume 103278064Sume if (buffer != (char*)0) { 103378064Sume SHA384_Final(digest, context); 103478064Sume 103578064Sume for (i = 0; i < SHA384_DIGEST_LENGTH; i++) { 103678064Sume *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; 103778064Sume *buffer++ = sha2_hex_digits[*d & 0x0f]; 103878064Sume d++; 103978064Sume } 104078064Sume *buffer = (char)0; 104178064Sume } else { 1042119890Sphk bzero(context, sizeof(*context)); 104378064Sume } 104478064Sume bzero(digest, SHA384_DIGEST_LENGTH); 104578064Sume return buffer; 104678064Sume} 104778064Sume 104878064Sumechar* SHA384_Data(const sha2_byte* data, size_t len, char digest[SHA384_DIGEST_STRING_LENGTH]) { 104978064Sume SHA384_CTX context; 105078064Sume 105178064Sume SHA384_Init(&context); 105278064Sume SHA384_Update(&context, data, len); 105378064Sume return SHA384_End(&context, digest); 105478064Sume} 1055