xref: /netbsd-src/crypto/external/bsd/netpgp/dist/src/netpgpverify/sha2.c (revision f8570f8a97f412a33574ec77d412b16dbe332965)
1*f8570f8aSmrg /* $NetBSD: sha2.c,v 1.5 2023/08/01 07:04:14 mrg Exp $ */
225f78d91Sagc /*	$KAME: sha2.c,v 1.9 2003/07/20 00:28:38 itojun Exp $	*/
325f78d91Sagc 
425f78d91Sagc /*
525f78d91Sagc  * sha2.c
625f78d91Sagc  *
725f78d91Sagc  * Version 1.0.0beta1
825f78d91Sagc  *
925f78d91Sagc  * Written by Aaron D. Gifford <me@aarongifford.com>
1025f78d91Sagc  *
1125f78d91Sagc  * Copyright 2000 Aaron D. Gifford.  All rights reserved.
1225f78d91Sagc  *
1325f78d91Sagc  * Redistribution and use in source and binary forms, with or without
1425f78d91Sagc  * modification, are permitted provided that the following conditions
1525f78d91Sagc  * are met:
1625f78d91Sagc  * 1. Redistributions of source code must retain the above copyright
1725f78d91Sagc  *    notice, this list of conditions and the following disclaimer.
1825f78d91Sagc  * 2. Redistributions in binary form must reproduce the above copyright
1925f78d91Sagc  *    notice, this list of conditions and the following disclaimer in the
2025f78d91Sagc  *    documentation and/or other materials provided with the distribution.
2125f78d91Sagc  * 3. Neither the name of the copyright holder nor the names of contributors
2225f78d91Sagc  *    may be used to endorse or promote products derived from this software
2325f78d91Sagc  *    without specific prior written permission.
2425f78d91Sagc  *
2525f78d91Sagc  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTOR(S) ``AS IS'' AND
2625f78d91Sagc  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2725f78d91Sagc  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2825f78d91Sagc  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE
2925f78d91Sagc  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3025f78d91Sagc  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3125f78d91Sagc  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3225f78d91Sagc  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3325f78d91Sagc  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3425f78d91Sagc  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3525f78d91Sagc  * SUCH DAMAGE.
3625f78d91Sagc  *
3725f78d91Sagc  */
3825f78d91Sagc 
3925f78d91Sagc #include <sys/types.h>
4025f78d91Sagc 
4125f78d91Sagc #include <inttypes.h>
4225f78d91Sagc #include <string.h>
4325f78d91Sagc 
4425f78d91Sagc #include "sha2.h"
4525f78d91Sagc 
4625f78d91Sagc #   undef htobe32
4725f78d91Sagc #   undef htobe64
4825f78d91Sagc #   undef be32toh
4925f78d91Sagc #   undef be64toh
5025f78d91Sagc 
51fd2346d6Schristos #ifndef __CAST
5225f78d91Sagc #define __CAST(__dt, __st)      ((__dt)(__st)) /* srsly? */
53fd2346d6Schristos #endif
5425f78d91Sagc 
5525f78d91Sagc static __inline void
be32encode(void * buf,uint32_t u)5625f78d91Sagc be32encode(void *buf, uint32_t u)
5725f78d91Sagc {
5825f78d91Sagc         uint8_t *p = __CAST(uint8_t *, buf);
5925f78d91Sagc 
6025f78d91Sagc         p[0] = __CAST(uint8_t, ((u >> 24) & 0xff));
6125f78d91Sagc         p[1] = __CAST(uint8_t, ((u >> 16) & 0xff));
6225f78d91Sagc         p[2] = __CAST(uint8_t, ((u >> 8) & 0xff));
6325f78d91Sagc         p[3] = __CAST(uint8_t, (u & 0xff));
6425f78d91Sagc }
6525f78d91Sagc 
6625f78d91Sagc static __inline void
be64encode(void * buf,uint64_t u)6725f78d91Sagc be64encode(void *buf, uint64_t u)
6825f78d91Sagc {
6925f78d91Sagc         uint8_t *p = __CAST(uint8_t *, buf);
7025f78d91Sagc 
7125f78d91Sagc         be32encode(p, __CAST(uint32_t, (u >> 32)));
7225f78d91Sagc         be32encode(p + 4, __CAST(uint32_t, (u & 0xffffffffULL)));
7325f78d91Sagc }
7425f78d91Sagc 
7525f78d91Sagc static uint32_t
htobe32(uint32_t x)7625f78d91Sagc htobe32(uint32_t x)
7725f78d91Sagc {
7825f78d91Sagc 	uint8_t p[4];
7925f78d91Sagc 	memcpy(p, &x, 4);
8025f78d91Sagc 
81f57bc4a2Skamil 	return (((uint32_t)p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
8225f78d91Sagc }
8325f78d91Sagc 
8425f78d91Sagc static uint64_t
htobe64(uint64_t x)8525f78d91Sagc htobe64(uint64_t x)
8625f78d91Sagc {
8725f78d91Sagc 	uint8_t p[8];
8825f78d91Sagc 	uint32_t u, v;
8925f78d91Sagc 	memcpy(p, &x, 8);
9025f78d91Sagc 
91f57bc4a2Skamil 	u = (((uint32_t)p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
92f57bc4a2Skamil 	v = (((uint32_t)p[4] << 24) | (p[5] << 16) | (p[6] << 8) | p[7]);
9325f78d91Sagc 
9425f78d91Sagc 	return ((((uint64_t)u) << 32) | v);
9525f78d91Sagc }
9625f78d91Sagc 
9725f78d91Sagc static uint32_t
be32toh(uint32_t x)9825f78d91Sagc be32toh(uint32_t x)
9925f78d91Sagc {
10025f78d91Sagc 	return htobe32(x);
10125f78d91Sagc }
10225f78d91Sagc 
10325f78d91Sagc static uint64_t
be64toh(uint64_t x)10425f78d91Sagc be64toh(uint64_t x)
10525f78d91Sagc {
10625f78d91Sagc 	return htobe64(x);
10725f78d91Sagc }
10825f78d91Sagc 
10925f78d91Sagc /*** SHA-256/384/512 Various Length Definitions ***********************/
11025f78d91Sagc /* NOTE: Most of these are in sha2.h */
11125f78d91Sagc #define SHA256_SHORT_BLOCK_LENGTH	(SHA256_BLOCK_LENGTH - 8)
11225f78d91Sagc #define SHA384_SHORT_BLOCK_LENGTH	(SHA384_BLOCK_LENGTH - 16)
11325f78d91Sagc #define SHA512_SHORT_BLOCK_LENGTH	(SHA512_BLOCK_LENGTH - 16)
11425f78d91Sagc 
11525f78d91Sagc /*
11625f78d91Sagc  * Macro for incrementally adding the unsigned 64-bit integer n to the
11725f78d91Sagc  * unsigned 128-bit integer (represented using a two-element array of
11825f78d91Sagc  * 64-bit words):
11925f78d91Sagc  */
12025f78d91Sagc #define ADDINC128(w,n)	{ \
12125f78d91Sagc 	(w)[0] += (uint64_t)(n); \
12225f78d91Sagc 	if ((w)[0] < (n)) { \
12325f78d91Sagc 		(w)[1]++; \
12425f78d91Sagc 	} \
12525f78d91Sagc }
12625f78d91Sagc 
12725f78d91Sagc /*** THE SIX LOGICAL FUNCTIONS ****************************************/
12825f78d91Sagc /*
12925f78d91Sagc  * Bit shifting and rotation (used by the six SHA-XYZ logical functions:
13025f78d91Sagc  *
13125f78d91Sagc  *   NOTE:  The naming of R and S appears backwards here (R is a SHIFT and
13225f78d91Sagc  *   S is a ROTATION) because the SHA-256/384/512 description document
13325f78d91Sagc  *   (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this
13425f78d91Sagc  *   same "backwards" definition.
13525f78d91Sagc  */
13625f78d91Sagc /* Shift-right (used in SHA-256, SHA-384, and SHA-512): */
13725f78d91Sagc #define R(b,x) 		((x) >> (b))
13825f78d91Sagc /* 32-bit Rotate-right (used in SHA-256): */
13925f78d91Sagc #define S32(b,x)	(((x) >> (b)) | ((x) << (32 - (b))))
14025f78d91Sagc /* 64-bit Rotate-right (used in SHA-384 and SHA-512): */
14125f78d91Sagc #define S64(b,x)	(((x) >> (b)) | ((x) << (64 - (b))))
14225f78d91Sagc 
14325f78d91Sagc /* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */
14425f78d91Sagc #define Ch(x,y,z)	(((x) & (y)) ^ ((~(x)) & (z)))
14525f78d91Sagc #define Maj(x,y,z)	(((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
14625f78d91Sagc 
14725f78d91Sagc /* Four of six logical functions used in SHA-256: */
14825f78d91Sagc #define Sigma0_256(x)	(S32(2,  (x)) ^ S32(13, (x)) ^ S32(22, (x)))
14925f78d91Sagc #define Sigma1_256(x)	(S32(6,  (x)) ^ S32(11, (x)) ^ S32(25, (x)))
15025f78d91Sagc #define sigma0_256(x)	(S32(7,  (x)) ^ S32(18, (x)) ^ R(3 ,   (x)))
15125f78d91Sagc #define sigma1_256(x)	(S32(17, (x)) ^ S32(19, (x)) ^ R(10,   (x)))
15225f78d91Sagc 
15325f78d91Sagc /* Four of six logical functions used in SHA-384 and SHA-512: */
15425f78d91Sagc #define Sigma0_512(x)	(S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x)))
15525f78d91Sagc #define Sigma1_512(x)	(S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x)))
15625f78d91Sagc #define sigma0_512(x)	(S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7,   (x)))
15725f78d91Sagc #define sigma1_512(x)	(S64(19, (x)) ^ S64(61, (x)) ^ R( 6,   (x)))
15825f78d91Sagc 
15925f78d91Sagc /*** INTERNAL FUNCTION PROTOTYPES *************************************/
16025f78d91Sagc /* NOTE: These should not be accessed directly from outside this
16125f78d91Sagc  * library -- they are intended for private internal visibility/use
16225f78d91Sagc  * only.
16325f78d91Sagc  */
164dd98b26dSagc static void netpgpv_SHA512_Last(NETPGPV_SHA512_CTX *);
165dd98b26dSagc void netpgpv_SHA224_Transform(NETPGPV_SHA224_CTX *, const uint32_t*);
166dd98b26dSagc void netpgpv_SHA256_Transform(NETPGPV_SHA256_CTX *, const uint32_t*);
167dd98b26dSagc void netpgpv_SHA384_Transform(NETPGPV_SHA384_CTX *, const uint64_t*);
168dd98b26dSagc void netpgpv_SHA512_Transform(NETPGPV_SHA512_CTX *, const uint64_t*);
16925f78d91Sagc 
17025f78d91Sagc 
17125f78d91Sagc /*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/
17225f78d91Sagc /* Hash constant words K for SHA-256: */
17325f78d91Sagc static const uint32_t K256[64] = {
17425f78d91Sagc 	0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
17525f78d91Sagc 	0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
17625f78d91Sagc 	0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
17725f78d91Sagc 	0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
17825f78d91Sagc 	0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
17925f78d91Sagc 	0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
18025f78d91Sagc 	0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
18125f78d91Sagc 	0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
18225f78d91Sagc 	0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
18325f78d91Sagc 	0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
18425f78d91Sagc 	0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
18525f78d91Sagc 	0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
18625f78d91Sagc 	0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
18725f78d91Sagc 	0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
18825f78d91Sagc 	0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
18925f78d91Sagc 	0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
19025f78d91Sagc };
19125f78d91Sagc 
19225f78d91Sagc /* Initial hash value H for SHA-224: */
19325f78d91Sagc static const uint32_t sha224_initial_hash_value[8] = {
19425f78d91Sagc 	0xc1059ed8UL,
19525f78d91Sagc 	0x367cd507UL,
19625f78d91Sagc 	0x3070dd17UL,
19725f78d91Sagc 	0xf70e5939UL,
19825f78d91Sagc 	0xffc00b31UL,
19925f78d91Sagc 	0x68581511UL,
20025f78d91Sagc 	0x64f98fa7UL,
20125f78d91Sagc 	0xbefa4fa4UL
20225f78d91Sagc };
20325f78d91Sagc 
20425f78d91Sagc /* Initial hash value H for SHA-256: */
20525f78d91Sagc static const uint32_t sha256_initial_hash_value[8] = {
20625f78d91Sagc 	0x6a09e667UL,
20725f78d91Sagc 	0xbb67ae85UL,
20825f78d91Sagc 	0x3c6ef372UL,
20925f78d91Sagc 	0xa54ff53aUL,
21025f78d91Sagc 	0x510e527fUL,
21125f78d91Sagc 	0x9b05688cUL,
21225f78d91Sagc 	0x1f83d9abUL,
21325f78d91Sagc 	0x5be0cd19UL
21425f78d91Sagc };
21525f78d91Sagc 
21625f78d91Sagc /* Hash constant words K for SHA-384 and SHA-512: */
21725f78d91Sagc static const uint64_t K512[80] = {
21825f78d91Sagc 	0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
21925f78d91Sagc 	0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
22025f78d91Sagc 	0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
22125f78d91Sagc 	0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
22225f78d91Sagc 	0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
22325f78d91Sagc 	0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
22425f78d91Sagc 	0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
22525f78d91Sagc 	0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
22625f78d91Sagc 	0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
22725f78d91Sagc 	0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
22825f78d91Sagc 	0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
22925f78d91Sagc 	0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
23025f78d91Sagc 	0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
23125f78d91Sagc 	0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
23225f78d91Sagc 	0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
23325f78d91Sagc 	0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
23425f78d91Sagc 	0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
23525f78d91Sagc 	0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
23625f78d91Sagc 	0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
23725f78d91Sagc 	0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
23825f78d91Sagc 	0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
23925f78d91Sagc 	0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
24025f78d91Sagc 	0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
24125f78d91Sagc 	0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
24225f78d91Sagc 	0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
24325f78d91Sagc 	0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
24425f78d91Sagc 	0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
24525f78d91Sagc 	0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
24625f78d91Sagc 	0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
24725f78d91Sagc 	0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
24825f78d91Sagc 	0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
24925f78d91Sagc 	0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
25025f78d91Sagc 	0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
25125f78d91Sagc 	0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
25225f78d91Sagc 	0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
25325f78d91Sagc 	0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
25425f78d91Sagc 	0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
25525f78d91Sagc 	0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
25625f78d91Sagc 	0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
25725f78d91Sagc 	0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
25825f78d91Sagc };
25925f78d91Sagc 
26025f78d91Sagc /* Initial hash value H for SHA-384 */
26125f78d91Sagc static const uint64_t sha384_initial_hash_value[8] = {
26225f78d91Sagc 	0xcbbb9d5dc1059ed8ULL,
26325f78d91Sagc 	0x629a292a367cd507ULL,
26425f78d91Sagc 	0x9159015a3070dd17ULL,
26525f78d91Sagc 	0x152fecd8f70e5939ULL,
26625f78d91Sagc 	0x67332667ffc00b31ULL,
26725f78d91Sagc 	0x8eb44a8768581511ULL,
26825f78d91Sagc 	0xdb0c2e0d64f98fa7ULL,
26925f78d91Sagc 	0x47b5481dbefa4fa4ULL
27025f78d91Sagc };
27125f78d91Sagc 
27225f78d91Sagc /* Initial hash value H for SHA-512 */
27325f78d91Sagc static const uint64_t sha512_initial_hash_value[8] = {
27425f78d91Sagc 	0x6a09e667f3bcc908ULL,
27525f78d91Sagc 	0xbb67ae8584caa73bULL,
27625f78d91Sagc 	0x3c6ef372fe94f82bULL,
27725f78d91Sagc 	0xa54ff53a5f1d36f1ULL,
27825f78d91Sagc 	0x510e527fade682d1ULL,
27925f78d91Sagc 	0x9b05688c2b3e6c1fULL,
28025f78d91Sagc 	0x1f83d9abfb41bd6bULL,
28125f78d91Sagc 	0x5be0cd19137e2179ULL
28225f78d91Sagc };
28325f78d91Sagc 
28425f78d91Sagc /*** SHA-256: *********************************************************/
28525f78d91Sagc int
netpgpv_SHA256_Init(NETPGPV_SHA256_CTX * context)286dd98b26dSagc netpgpv_SHA256_Init(NETPGPV_SHA256_CTX *context)
28725f78d91Sagc {
28825f78d91Sagc 	if (context == NULL)
28925f78d91Sagc 		return 1;
29025f78d91Sagc 
29125f78d91Sagc 	memcpy(context->state, sha256_initial_hash_value,
29225f78d91Sagc 	    (size_t)(SHA256_DIGEST_LENGTH));
29325f78d91Sagc 	memset(context->buffer, 0, (size_t)(SHA256_BLOCK_LENGTH));
29425f78d91Sagc 	context->bitcount = 0;
29525f78d91Sagc 
29625f78d91Sagc 	return 1;
29725f78d91Sagc }
29825f78d91Sagc 
29925f78d91Sagc #ifdef SHA2_UNROLL_TRANSFORM
30025f78d91Sagc 
30125f78d91Sagc /* Unrolled SHA-256 round macros: */
30225f78d91Sagc 
30325f78d91Sagc #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h)	\
30425f78d91Sagc 	W256[j] = be32toh(*data);		\
30525f78d91Sagc 	++data;					\
30625f78d91Sagc 	T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
30725f78d91Sagc              K256[j] + W256[j]; \
30825f78d91Sagc 	(d) += T1; \
30925f78d91Sagc 	(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
31025f78d91Sagc 	j++
31125f78d91Sagc 
31225f78d91Sagc #define ROUND256(a,b,c,d,e,f,g,h)	\
31325f78d91Sagc 	s0 = W256[(j+1)&0x0f]; \
31425f78d91Sagc 	s0 = sigma0_256(s0); \
31525f78d91Sagc 	s1 = W256[(j+14)&0x0f]; \
31625f78d91Sagc 	s1 = sigma1_256(s1); \
31725f78d91Sagc 	T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \
31825f78d91Sagc 	     (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \
31925f78d91Sagc 	(d) += T1; \
32025f78d91Sagc 	(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
32125f78d91Sagc 	j++
32225f78d91Sagc 
32325f78d91Sagc void
netpgpv_SHA256_Transform(NETPGPV_SHA256_CTX * context,const uint32_t * data)324dd98b26dSagc netpgpv_SHA256_Transform(NETPGPV_SHA256_CTX *context, const uint32_t *data)
32525f78d91Sagc {
32625f78d91Sagc 	uint32_t	a, b, c, d, e, f, g, h, s0, s1;
32725f78d91Sagc 	uint32_t	T1, *W256;
32825f78d91Sagc 	int		j;
32925f78d91Sagc 
33025f78d91Sagc 	W256 = (uint32_t *)context->buffer;
33125f78d91Sagc 
33225f78d91Sagc 	/* Initialize registers with the prev. intermediate value */
33325f78d91Sagc 	a = context->state[0];
33425f78d91Sagc 	b = context->state[1];
33525f78d91Sagc 	c = context->state[2];
33625f78d91Sagc 	d = context->state[3];
33725f78d91Sagc 	e = context->state[4];
33825f78d91Sagc 	f = context->state[5];
33925f78d91Sagc 	g = context->state[6];
34025f78d91Sagc 	h = context->state[7];
34125f78d91Sagc 
34225f78d91Sagc 	j = 0;
34325f78d91Sagc 	do {
34425f78d91Sagc 		/* Rounds 0 to 15 (unrolled): */
34525f78d91Sagc 		ROUND256_0_TO_15(a,b,c,d,e,f,g,h);
34625f78d91Sagc 		ROUND256_0_TO_15(h,a,b,c,d,e,f,g);
34725f78d91Sagc 		ROUND256_0_TO_15(g,h,a,b,c,d,e,f);
34825f78d91Sagc 		ROUND256_0_TO_15(f,g,h,a,b,c,d,e);
34925f78d91Sagc 		ROUND256_0_TO_15(e,f,g,h,a,b,c,d);
35025f78d91Sagc 		ROUND256_0_TO_15(d,e,f,g,h,a,b,c);
35125f78d91Sagc 		ROUND256_0_TO_15(c,d,e,f,g,h,a,b);
35225f78d91Sagc 		ROUND256_0_TO_15(b,c,d,e,f,g,h,a);
35325f78d91Sagc 	} while (j < 16);
35425f78d91Sagc 
35525f78d91Sagc 	/* Now for the remaining rounds to 64: */
35625f78d91Sagc 	do {
35725f78d91Sagc 		ROUND256(a,b,c,d,e,f,g,h);
35825f78d91Sagc 		ROUND256(h,a,b,c,d,e,f,g);
35925f78d91Sagc 		ROUND256(g,h,a,b,c,d,e,f);
36025f78d91Sagc 		ROUND256(f,g,h,a,b,c,d,e);
36125f78d91Sagc 		ROUND256(e,f,g,h,a,b,c,d);
36225f78d91Sagc 		ROUND256(d,e,f,g,h,a,b,c);
36325f78d91Sagc 		ROUND256(c,d,e,f,g,h,a,b);
36425f78d91Sagc 		ROUND256(b,c,d,e,f,g,h,a);
36525f78d91Sagc 	} while (j < 64);
36625f78d91Sagc 
36725f78d91Sagc 	/* Compute the current intermediate hash value */
36825f78d91Sagc 	context->state[0] += a;
36925f78d91Sagc 	context->state[1] += b;
37025f78d91Sagc 	context->state[2] += c;
37125f78d91Sagc 	context->state[3] += d;
37225f78d91Sagc 	context->state[4] += e;
37325f78d91Sagc 	context->state[5] += f;
37425f78d91Sagc 	context->state[6] += g;
37525f78d91Sagc 	context->state[7] += h;
37625f78d91Sagc 
37725f78d91Sagc 	/* Clean up */
37825f78d91Sagc 	a = b = c = d = e = f = g = h = T1 = 0;
37925f78d91Sagc }
38025f78d91Sagc 
38125f78d91Sagc #else /* SHA2_UNROLL_TRANSFORM */
38225f78d91Sagc 
38325f78d91Sagc void
netpgpv_SHA256_Transform(NETPGPV_SHA256_CTX * context,const uint32_t * data)384dd98b26dSagc netpgpv_SHA256_Transform(NETPGPV_SHA256_CTX *context, const uint32_t *data)
38525f78d91Sagc {
38625f78d91Sagc 	uint32_t	a, b, c, d, e, f, g, h, s0, s1;
38725f78d91Sagc 	uint32_t	T1, T2, *W256;
38825f78d91Sagc 	int		j;
38925f78d91Sagc 
39025f78d91Sagc 	W256 = (uint32_t *)(void *)context->buffer;
39125f78d91Sagc 
39225f78d91Sagc 	/* Initialize registers with the prev. intermediate value */
39325f78d91Sagc 	a = context->state[0];
39425f78d91Sagc 	b = context->state[1];
39525f78d91Sagc 	c = context->state[2];
39625f78d91Sagc 	d = context->state[3];
39725f78d91Sagc 	e = context->state[4];
39825f78d91Sagc 	f = context->state[5];
39925f78d91Sagc 	g = context->state[6];
40025f78d91Sagc 	h = context->state[7];
40125f78d91Sagc 
40225f78d91Sagc 	j = 0;
40325f78d91Sagc 	do {
40425f78d91Sagc 		W256[j] = be32toh(*data);
40525f78d91Sagc 		++data;
40625f78d91Sagc 		/* Apply the SHA-256 compression function to update a..h */
40725f78d91Sagc 		T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];
40825f78d91Sagc 		T2 = Sigma0_256(a) + Maj(a, b, c);
40925f78d91Sagc 		h = g;
41025f78d91Sagc 		g = f;
41125f78d91Sagc 		f = e;
41225f78d91Sagc 		e = d + T1;
41325f78d91Sagc 		d = c;
41425f78d91Sagc 		c = b;
41525f78d91Sagc 		b = a;
41625f78d91Sagc 		a = T1 + T2;
41725f78d91Sagc 
41825f78d91Sagc 		j++;
41925f78d91Sagc 	} while (j < 16);
42025f78d91Sagc 
42125f78d91Sagc 	do {
42225f78d91Sagc 		/* Part of the message block expansion: */
42325f78d91Sagc 		s0 = W256[(j+1)&0x0f];
42425f78d91Sagc 		s0 = sigma0_256(s0);
42525f78d91Sagc 		s1 = W256[(j+14)&0x0f];
42625f78d91Sagc 		s1 = sigma1_256(s1);
42725f78d91Sagc 
42825f78d91Sagc 		/* Apply the SHA-256 compression function to update a..h */
42925f78d91Sagc 		T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] +
43025f78d91Sagc 		     (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0);
43125f78d91Sagc 		T2 = Sigma0_256(a) + Maj(a, b, c);
43225f78d91Sagc 		h = g;
43325f78d91Sagc 		g = f;
43425f78d91Sagc 		f = e;
43525f78d91Sagc 		e = d + T1;
43625f78d91Sagc 		d = c;
43725f78d91Sagc 		c = b;
43825f78d91Sagc 		b = a;
43925f78d91Sagc 		a = T1 + T2;
44025f78d91Sagc 
44125f78d91Sagc 		j++;
44225f78d91Sagc 	} while (j < 64);
44325f78d91Sagc 
44425f78d91Sagc 	/* Compute the current intermediate hash value */
44525f78d91Sagc 	context->state[0] += a;
44625f78d91Sagc 	context->state[1] += b;
44725f78d91Sagc 	context->state[2] += c;
44825f78d91Sagc 	context->state[3] += d;
44925f78d91Sagc 	context->state[4] += e;
45025f78d91Sagc 	context->state[5] += f;
45125f78d91Sagc 	context->state[6] += g;
45225f78d91Sagc 	context->state[7] += h;
45325f78d91Sagc 
45425f78d91Sagc 	/* Clean up */
45525f78d91Sagc 	a = b = c = d = e = f = g = h = T1 = T2 = 0;
45625f78d91Sagc }
45725f78d91Sagc 
45825f78d91Sagc #endif /* SHA2_UNROLL_TRANSFORM */
45925f78d91Sagc 
46025f78d91Sagc int
netpgpv_SHA256_Update(NETPGPV_SHA256_CTX * context,const uint8_t * data,size_t len)461dd98b26dSagc netpgpv_SHA256_Update(NETPGPV_SHA256_CTX *context, const uint8_t *data, size_t len)
46225f78d91Sagc {
46325f78d91Sagc 	unsigned int	freespace, usedspace;
46425f78d91Sagc 
46525f78d91Sagc 	if (len == 0) {
46625f78d91Sagc 		/* Calling with no data is valid - we do nothing */
46725f78d91Sagc 		return 1;
46825f78d91Sagc 	}
46925f78d91Sagc 
47025f78d91Sagc 	usedspace = (unsigned int)((context->bitcount >> 3) %
47125f78d91Sagc 				    SHA256_BLOCK_LENGTH);
47225f78d91Sagc 	if (usedspace > 0) {
47325f78d91Sagc 		/* Calculate how much free space is available in the buffer */
47425f78d91Sagc 		freespace = SHA256_BLOCK_LENGTH - usedspace;
47525f78d91Sagc 
47625f78d91Sagc 		if (len >= freespace) {
47725f78d91Sagc 			/* Fill the buffer completely and process it */
47825f78d91Sagc 			memcpy(&context->buffer[usedspace], data,
47925f78d91Sagc 			    (size_t)(freespace));
48025f78d91Sagc 			context->bitcount += freespace << 3;
48125f78d91Sagc 			len -= freespace;
48225f78d91Sagc 			data += freespace;
483dd98b26dSagc 			netpgpv_SHA256_Transform(context,
48425f78d91Sagc 			    (uint32_t *)(void *)context->buffer);
48525f78d91Sagc 		} else {
48625f78d91Sagc 			/* The buffer is not yet full */
48725f78d91Sagc 			memcpy(&context->buffer[usedspace], data, len);
48825f78d91Sagc 			context->bitcount += len << 3;
48925f78d91Sagc 			/* Clean up: */
49025f78d91Sagc 			usedspace = freespace = 0;
49125f78d91Sagc 			return 1;
49225f78d91Sagc 		}
49325f78d91Sagc 	}
49425f78d91Sagc 	/*
49525f78d91Sagc 	 * Process as many complete blocks as possible.
49625f78d91Sagc 	 *
49725f78d91Sagc 	 * Check alignment of the data pointer. If it is 32bit aligned,
49825f78d91Sagc 	 * SHA256_Transform can be called directly on the data stream,
49925f78d91Sagc 	 * otherwise enforce the alignment by copy into the buffer.
50025f78d91Sagc 	 */
50125f78d91Sagc 	if ((uintptr_t)data % 4 == 0) {
50225f78d91Sagc 		while (len >= SHA256_BLOCK_LENGTH) {
503dd98b26dSagc 			netpgpv_SHA256_Transform(context,
50425f78d91Sagc 			    (const uint32_t *)(const void *)data);
50525f78d91Sagc 			context->bitcount += SHA256_BLOCK_LENGTH << 3;
50625f78d91Sagc 			len -= SHA256_BLOCK_LENGTH;
50725f78d91Sagc 			data += SHA256_BLOCK_LENGTH;
50825f78d91Sagc 		}
50925f78d91Sagc 	} else {
51025f78d91Sagc 		while (len >= SHA256_BLOCK_LENGTH) {
51125f78d91Sagc 			memcpy(context->buffer, data, SHA256_BLOCK_LENGTH);
512dd98b26dSagc 			netpgpv_SHA256_Transform(context,
51325f78d91Sagc 			    (const uint32_t *)(const void *)context->buffer);
51425f78d91Sagc 			context->bitcount += SHA256_BLOCK_LENGTH << 3;
51525f78d91Sagc 			len -= SHA256_BLOCK_LENGTH;
51625f78d91Sagc 			data += SHA256_BLOCK_LENGTH;
51725f78d91Sagc 		}
51825f78d91Sagc 	}
51925f78d91Sagc 	if (len > 0) {
52025f78d91Sagc 		/* There's left-overs, so save 'em */
52125f78d91Sagc 		memcpy(context->buffer, data, len);
52225f78d91Sagc 		context->bitcount += len << 3;
52325f78d91Sagc 	}
52425f78d91Sagc 	/* Clean up: */
52525f78d91Sagc 	usedspace = freespace = 0;
52625f78d91Sagc 
52725f78d91Sagc 	return 1;
52825f78d91Sagc }
52925f78d91Sagc 
53025f78d91Sagc static int
netpgpv_SHA224_256_Final(uint8_t digest[],NETPGPV_SHA256_CTX * context,size_t len)531dd98b26dSagc netpgpv_SHA224_256_Final(uint8_t digest[], NETPGPV_SHA256_CTX *context, size_t len)
53225f78d91Sagc {
53325f78d91Sagc 	unsigned int	usedspace;
53425f78d91Sagc 	size_t i;
53525f78d91Sagc 
53625f78d91Sagc 	/* If no digest buffer is passed, we don't bother doing this: */
53725f78d91Sagc 	if (digest != NULL) {
53825f78d91Sagc 		usedspace = (unsigned int)((context->bitcount >> 3) %
53925f78d91Sagc 		    SHA256_BLOCK_LENGTH);
54025f78d91Sagc 		context->bitcount = htobe64(context->bitcount);
54125f78d91Sagc 		if (usedspace > 0) {
54225f78d91Sagc 			/* Begin padding with a 1 bit: */
54325f78d91Sagc 			context->buffer[usedspace++] = 0x80;
54425f78d91Sagc 
54525f78d91Sagc 			if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) {
54625f78d91Sagc 				/* Set-up for the last transform: */
54725f78d91Sagc 				memset(&context->buffer[usedspace], 0,
54825f78d91Sagc 				    (size_t)(SHA256_SHORT_BLOCK_LENGTH -
54925f78d91Sagc 				    usedspace));
55025f78d91Sagc 			} else {
55125f78d91Sagc 				if (usedspace < SHA256_BLOCK_LENGTH) {
55225f78d91Sagc 					memset(&context->buffer[usedspace], 0,
55325f78d91Sagc 					    (size_t)(SHA256_BLOCK_LENGTH -
55425f78d91Sagc 					    usedspace));
55525f78d91Sagc 				}
55625f78d91Sagc 				/* Do second-to-last transform: */
557dd98b26dSagc 				netpgpv_SHA256_Transform(context,
55825f78d91Sagc 				    (uint32_t *)(void *)context->buffer);
55925f78d91Sagc 
56025f78d91Sagc 				/* And set-up for the last transform: */
56125f78d91Sagc 				memset(context->buffer, 0,
56225f78d91Sagc 				    (size_t)(SHA256_SHORT_BLOCK_LENGTH));
56325f78d91Sagc 			}
56425f78d91Sagc 		} else {
56525f78d91Sagc 			/* Set-up for the last transform: */
56625f78d91Sagc 			memset(context->buffer, 0,
56725f78d91Sagc 			    (size_t)(SHA256_SHORT_BLOCK_LENGTH));
56825f78d91Sagc 
56925f78d91Sagc 			/* Begin padding with a 1 bit: */
57025f78d91Sagc 			*context->buffer = 0x80;
57125f78d91Sagc 		}
57225f78d91Sagc 		/* Set the bit count: */
57325f78d91Sagc 		memcpy(&context->buffer[SHA256_SHORT_BLOCK_LENGTH],
57425f78d91Sagc 		    &context->bitcount, sizeof(context->bitcount));
57525f78d91Sagc 
57625f78d91Sagc 		/* Final transform: */
577dd98b26dSagc 		netpgpv_SHA256_Transform(context, (uint32_t *)(void *)context->buffer);
57825f78d91Sagc 
57925f78d91Sagc 		for (i = 0; i < len / 4; i++)
58025f78d91Sagc 			be32encode(digest + 4 * i, context->state[i]);
58125f78d91Sagc 	}
58225f78d91Sagc 
58325f78d91Sagc 	/* Clean up state data: */
58425f78d91Sagc 	memset(context, 0, sizeof(*context));
58525f78d91Sagc 	usedspace = 0;
58625f78d91Sagc 
58725f78d91Sagc 	return 1;
58825f78d91Sagc }
58925f78d91Sagc 
59025f78d91Sagc int
netpgpv_SHA256_Final(uint8_t digest[32],NETPGPV_SHA256_CTX * context)591*f8570f8aSmrg netpgpv_SHA256_Final(uint8_t digest[32], NETPGPV_SHA256_CTX *context)
59225f78d91Sagc {
593dd98b26dSagc 	return netpgpv_SHA224_256_Final(digest, context, SHA256_DIGEST_LENGTH);
59425f78d91Sagc }
59525f78d91Sagc 
59625f78d91Sagc /*** SHA-224: *********************************************************/
59725f78d91Sagc int
netpgpv_SHA224_Init(NETPGPV_SHA224_CTX * context)598dd98b26dSagc netpgpv_SHA224_Init(NETPGPV_SHA224_CTX *context)
59925f78d91Sagc {
60025f78d91Sagc 	if (context == NULL)
60125f78d91Sagc 		return 1;
60225f78d91Sagc 
60325f78d91Sagc 	/* The state and buffer size are driven by SHA256, not by SHA224. */
60425f78d91Sagc 	memcpy(context->state, sha224_initial_hash_value,
60525f78d91Sagc 	    (size_t)(SHA256_DIGEST_LENGTH));
60625f78d91Sagc 	memset(context->buffer, 0, (size_t)(SHA256_BLOCK_LENGTH));
60725f78d91Sagc 	context->bitcount = 0;
60825f78d91Sagc 
60925f78d91Sagc 	return 1;
61025f78d91Sagc }
61125f78d91Sagc 
61225f78d91Sagc int
netpgpv_SHA224_Update(NETPGPV_SHA224_CTX * context,const uint8_t * data,size_t len)613dd98b26dSagc netpgpv_SHA224_Update(NETPGPV_SHA224_CTX *context, const uint8_t *data, size_t len)
61425f78d91Sagc {
615dd98b26dSagc 	return netpgpv_SHA256_Update((NETPGPV_SHA256_CTX *)context, data, len);
61625f78d91Sagc }
61725f78d91Sagc 
61825f78d91Sagc void
netpgpv_SHA224_Transform(NETPGPV_SHA224_CTX * context,const uint32_t * data)619dd98b26dSagc netpgpv_SHA224_Transform(NETPGPV_SHA224_CTX *context, const uint32_t *data)
62025f78d91Sagc {
621dd98b26dSagc 	netpgpv_SHA256_Transform((NETPGPV_SHA256_CTX *)context, data);
62225f78d91Sagc }
62325f78d91Sagc 
62425f78d91Sagc int
netpgpv_SHA224_Final(uint8_t digest[28],NETPGPV_SHA224_CTX * context)625*f8570f8aSmrg netpgpv_SHA224_Final(uint8_t digest[28], NETPGPV_SHA224_CTX *context)
62625f78d91Sagc {
627dd98b26dSagc 	return netpgpv_SHA224_256_Final(digest, (NETPGPV_SHA256_CTX *)context,
62825f78d91Sagc 	    SHA224_DIGEST_LENGTH);
62925f78d91Sagc }
63025f78d91Sagc 
63125f78d91Sagc /*** SHA-512: *********************************************************/
63225f78d91Sagc int
netpgpv_SHA512_Init(NETPGPV_SHA512_CTX * context)633dd98b26dSagc netpgpv_SHA512_Init(NETPGPV_SHA512_CTX *context)
63425f78d91Sagc {
63525f78d91Sagc 	if (context == NULL)
63625f78d91Sagc 		return 1;
63725f78d91Sagc 
63825f78d91Sagc 	memcpy(context->state, sha512_initial_hash_value,
63925f78d91Sagc 	    (size_t)(SHA512_DIGEST_LENGTH));
64025f78d91Sagc 	memset(context->buffer, 0, (size_t)(SHA512_BLOCK_LENGTH));
64125f78d91Sagc 	context->bitcount[0] = context->bitcount[1] =  0;
64225f78d91Sagc 
64325f78d91Sagc 	return 1;
64425f78d91Sagc }
64525f78d91Sagc 
64625f78d91Sagc #ifdef SHA2_UNROLL_TRANSFORM
64725f78d91Sagc 
64825f78d91Sagc /* Unrolled SHA-512 round macros: */
64925f78d91Sagc #define ROUND512_0_TO_15(a,b,c,d,e,f,g,h)	\
65025f78d91Sagc 	W512[j] = be64toh(*data);		\
65125f78d91Sagc 	++data;					\
65225f78d91Sagc 	T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
65325f78d91Sagc              K512[j] + W512[j]; \
65425f78d91Sagc 	(d) += T1, \
65525f78d91Sagc 	(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \
65625f78d91Sagc 	j++
65725f78d91Sagc 
65825f78d91Sagc #define ROUND512(a,b,c,d,e,f,g,h)	\
65925f78d91Sagc 	s0 = W512[(j+1)&0x0f]; \
66025f78d91Sagc 	s0 = sigma0_512(s0); \
66125f78d91Sagc 	s1 = W512[(j+14)&0x0f]; \
66225f78d91Sagc 	s1 = sigma1_512(s1); \
66325f78d91Sagc 	T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \
66425f78d91Sagc              (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \
66525f78d91Sagc 	(d) += T1; \
66625f78d91Sagc 	(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
66725f78d91Sagc 	j++
66825f78d91Sagc 
66925f78d91Sagc void
netpgpv_SHA512_Transform(NETPGPV_SHA512_CTX * context,const uint64_t * data)670dd98b26dSagc netpgpv_SHA512_Transform(NETPGPV_SHA512_CTX *context, const uint64_t *data)
67125f78d91Sagc {
67225f78d91Sagc 	uint64_t	a, b, c, d, e, f, g, h, s0, s1;
67325f78d91Sagc 	uint64_t	T1, *W512 = (uint64_t *)context->buffer;
67425f78d91Sagc 	int		j;
67525f78d91Sagc 
67625f78d91Sagc 	/* Initialize registers with the prev. intermediate value */
67725f78d91Sagc 	a = context->state[0];
67825f78d91Sagc 	b = context->state[1];
67925f78d91Sagc 	c = context->state[2];
68025f78d91Sagc 	d = context->state[3];
68125f78d91Sagc 	e = context->state[4];
68225f78d91Sagc 	f = context->state[5];
68325f78d91Sagc 	g = context->state[6];
68425f78d91Sagc 	h = context->state[7];
68525f78d91Sagc 
68625f78d91Sagc 	j = 0;
68725f78d91Sagc 	do {
68825f78d91Sagc 		ROUND512_0_TO_15(a,b,c,d,e,f,g,h);
68925f78d91Sagc 		ROUND512_0_TO_15(h,a,b,c,d,e,f,g);
69025f78d91Sagc 		ROUND512_0_TO_15(g,h,a,b,c,d,e,f);
69125f78d91Sagc 		ROUND512_0_TO_15(f,g,h,a,b,c,d,e);
69225f78d91Sagc 		ROUND512_0_TO_15(e,f,g,h,a,b,c,d);
69325f78d91Sagc 		ROUND512_0_TO_15(d,e,f,g,h,a,b,c);
69425f78d91Sagc 		ROUND512_0_TO_15(c,d,e,f,g,h,a,b);
69525f78d91Sagc 		ROUND512_0_TO_15(b,c,d,e,f,g,h,a);
69625f78d91Sagc 	} while (j < 16);
69725f78d91Sagc 
69825f78d91Sagc 	/* Now for the remaining rounds up to 79: */
69925f78d91Sagc 	do {
70025f78d91Sagc 		ROUND512(a,b,c,d,e,f,g,h);
70125f78d91Sagc 		ROUND512(h,a,b,c,d,e,f,g);
70225f78d91Sagc 		ROUND512(g,h,a,b,c,d,e,f);
70325f78d91Sagc 		ROUND512(f,g,h,a,b,c,d,e);
70425f78d91Sagc 		ROUND512(e,f,g,h,a,b,c,d);
70525f78d91Sagc 		ROUND512(d,e,f,g,h,a,b,c);
70625f78d91Sagc 		ROUND512(c,d,e,f,g,h,a,b);
70725f78d91Sagc 		ROUND512(b,c,d,e,f,g,h,a);
70825f78d91Sagc 	} while (j < 80);
70925f78d91Sagc 
71025f78d91Sagc 	/* Compute the current intermediate hash value */
71125f78d91Sagc 	context->state[0] += a;
71225f78d91Sagc 	context->state[1] += b;
71325f78d91Sagc 	context->state[2] += c;
71425f78d91Sagc 	context->state[3] += d;
71525f78d91Sagc 	context->state[4] += e;
71625f78d91Sagc 	context->state[5] += f;
71725f78d91Sagc 	context->state[6] += g;
71825f78d91Sagc 	context->state[7] += h;
71925f78d91Sagc 
72025f78d91Sagc 	/* Clean up */
72125f78d91Sagc 	a = b = c = d = e = f = g = h = T1 = 0;
72225f78d91Sagc }
72325f78d91Sagc 
72425f78d91Sagc #else /* SHA2_UNROLL_TRANSFORM */
72525f78d91Sagc 
72625f78d91Sagc void
netpgpv_SHA512_Transform(NETPGPV_SHA512_CTX * context,const uint64_t * data)727dd98b26dSagc netpgpv_SHA512_Transform(NETPGPV_SHA512_CTX *context, const uint64_t *data)
72825f78d91Sagc {
72925f78d91Sagc 	uint64_t	a, b, c, d, e, f, g, h, s0, s1;
73025f78d91Sagc 	uint64_t	T1, T2, *W512 = (void *)context->buffer;
73125f78d91Sagc 	int		j;
73225f78d91Sagc 
73325f78d91Sagc 	/* Initialize registers with the prev. intermediate value */
73425f78d91Sagc 	a = context->state[0];
73525f78d91Sagc 	b = context->state[1];
73625f78d91Sagc 	c = context->state[2];
73725f78d91Sagc 	d = context->state[3];
73825f78d91Sagc 	e = context->state[4];
73925f78d91Sagc 	f = context->state[5];
74025f78d91Sagc 	g = context->state[6];
74125f78d91Sagc 	h = context->state[7];
74225f78d91Sagc 
74325f78d91Sagc 	j = 0;
74425f78d91Sagc 	do {
74525f78d91Sagc 		W512[j] = be64toh(*data);
74625f78d91Sagc 		++data;
74725f78d91Sagc 		/* Apply the SHA-512 compression function to update a..h */
74825f78d91Sagc 		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j];
74925f78d91Sagc 		T2 = Sigma0_512(a) + Maj(a, b, c);
75025f78d91Sagc 		h = g;
75125f78d91Sagc 		g = f;
75225f78d91Sagc 		f = e;
75325f78d91Sagc 		e = d + T1;
75425f78d91Sagc 		d = c;
75525f78d91Sagc 		c = b;
75625f78d91Sagc 		b = a;
75725f78d91Sagc 		a = T1 + T2;
75825f78d91Sagc 
75925f78d91Sagc 		j++;
76025f78d91Sagc 	} while (j < 16);
76125f78d91Sagc 
76225f78d91Sagc 	do {
76325f78d91Sagc 		/* Part of the message block expansion: */
76425f78d91Sagc 		s0 = W512[(j+1)&0x0f];
76525f78d91Sagc 		s0 = sigma0_512(s0);
76625f78d91Sagc 		s1 = W512[(j+14)&0x0f];
76725f78d91Sagc 		s1 =  sigma1_512(s1);
76825f78d91Sagc 
76925f78d91Sagc 		/* Apply the SHA-512 compression function to update a..h */
77025f78d91Sagc 		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] +
77125f78d91Sagc 		     (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0);
77225f78d91Sagc 		T2 = Sigma0_512(a) + Maj(a, b, c);
77325f78d91Sagc 		h = g;
77425f78d91Sagc 		g = f;
77525f78d91Sagc 		f = e;
77625f78d91Sagc 		e = d + T1;
77725f78d91Sagc 		d = c;
77825f78d91Sagc 		c = b;
77925f78d91Sagc 		b = a;
78025f78d91Sagc 		a = T1 + T2;
78125f78d91Sagc 
78225f78d91Sagc 		j++;
78325f78d91Sagc 	} while (j < 80);
78425f78d91Sagc 
78525f78d91Sagc 	/* Compute the current intermediate hash value */
78625f78d91Sagc 	context->state[0] += a;
78725f78d91Sagc 	context->state[1] += b;
78825f78d91Sagc 	context->state[2] += c;
78925f78d91Sagc 	context->state[3] += d;
79025f78d91Sagc 	context->state[4] += e;
79125f78d91Sagc 	context->state[5] += f;
79225f78d91Sagc 	context->state[6] += g;
79325f78d91Sagc 	context->state[7] += h;
79425f78d91Sagc 
79525f78d91Sagc 	/* Clean up */
79625f78d91Sagc 	a = b = c = d = e = f = g = h = T1 = T2 = 0;
79725f78d91Sagc }
79825f78d91Sagc 
79925f78d91Sagc #endif /* SHA2_UNROLL_TRANSFORM */
80025f78d91Sagc 
80125f78d91Sagc int
netpgpv_SHA512_Update(NETPGPV_SHA512_CTX * context,const uint8_t * data,size_t len)802dd98b26dSagc netpgpv_SHA512_Update(NETPGPV_SHA512_CTX *context, const uint8_t *data, size_t len)
80325f78d91Sagc {
80425f78d91Sagc 	unsigned int	freespace, usedspace;
80525f78d91Sagc 
80625f78d91Sagc 	if (len == 0) {
80725f78d91Sagc 		/* Calling with no data is valid - we do nothing */
80825f78d91Sagc 		return 1;
80925f78d91Sagc 	}
81025f78d91Sagc 
81125f78d91Sagc 	usedspace = (unsigned int)((context->bitcount[0] >> 3) %
81225f78d91Sagc 	    SHA512_BLOCK_LENGTH);
81325f78d91Sagc 	if (usedspace > 0) {
81425f78d91Sagc 		/* Calculate how much free space is available in the buffer */
81525f78d91Sagc 		freespace = SHA512_BLOCK_LENGTH - usedspace;
81625f78d91Sagc 
81725f78d91Sagc 		if (len >= freespace) {
81825f78d91Sagc 			/* Fill the buffer completely and process it */
81925f78d91Sagc 			memcpy(&context->buffer[usedspace], data,
82025f78d91Sagc 			    (size_t)(freespace));
82125f78d91Sagc 			ADDINC128(context->bitcount, freespace << 3);
82225f78d91Sagc 			len -= freespace;
82325f78d91Sagc 			data += freespace;
824dd98b26dSagc 			netpgpv_SHA512_Transform(context,
82525f78d91Sagc 			    (uint64_t *)(void *)context->buffer);
82625f78d91Sagc 		} else {
82725f78d91Sagc 			/* The buffer is not yet full */
82825f78d91Sagc 			memcpy(&context->buffer[usedspace], data, len);
82925f78d91Sagc 			ADDINC128(context->bitcount, len << 3);
83025f78d91Sagc 			/* Clean up: */
83125f78d91Sagc 			usedspace = freespace = 0;
83225f78d91Sagc 			return 1;
83325f78d91Sagc 		}
83425f78d91Sagc 	}
83525f78d91Sagc 	/*
83625f78d91Sagc 	 * Process as many complete blocks as possible.
83725f78d91Sagc 	 *
83825f78d91Sagc 	 * Check alignment of the data pointer. If it is 64bit aligned,
83925f78d91Sagc 	 * SHA512_Transform can be called directly on the data stream,
84025f78d91Sagc 	 * otherwise enforce the alignment by copy into the buffer.
84125f78d91Sagc 	 */
84225f78d91Sagc 	if ((uintptr_t)data % 8 == 0) {
84325f78d91Sagc 		while (len >= SHA512_BLOCK_LENGTH) {
844dd98b26dSagc 			netpgpv_SHA512_Transform(context,
84525f78d91Sagc 			    (const uint64_t*)(const void *)data);
84625f78d91Sagc 			ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3);
84725f78d91Sagc 			len -= SHA512_BLOCK_LENGTH;
84825f78d91Sagc 			data += SHA512_BLOCK_LENGTH;
84925f78d91Sagc 		}
85025f78d91Sagc 	} else {
85125f78d91Sagc 		while (len >= SHA512_BLOCK_LENGTH) {
85225f78d91Sagc 			memcpy(context->buffer, data, SHA512_BLOCK_LENGTH);
853dd98b26dSagc 			netpgpv_SHA512_Transform(context,
85425f78d91Sagc 			    (const void *)context->buffer);
85525f78d91Sagc 			ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3);
85625f78d91Sagc 			len -= SHA512_BLOCK_LENGTH;
85725f78d91Sagc 			data += SHA512_BLOCK_LENGTH;
85825f78d91Sagc 		}
85925f78d91Sagc 	}
86025f78d91Sagc 	if (len > 0) {
86125f78d91Sagc 		/* There's left-overs, so save 'em */
86225f78d91Sagc 		memcpy(context->buffer, data, len);
86325f78d91Sagc 		ADDINC128(context->bitcount, len << 3);
86425f78d91Sagc 	}
86525f78d91Sagc 	/* Clean up: */
86625f78d91Sagc 	usedspace = freespace = 0;
86725f78d91Sagc 
86825f78d91Sagc 	return 1;
86925f78d91Sagc }
87025f78d91Sagc 
87125f78d91Sagc static void
netpgpv_SHA512_Last(NETPGPV_SHA512_CTX * context)872dd98b26dSagc netpgpv_SHA512_Last(NETPGPV_SHA512_CTX *context)
87325f78d91Sagc {
87425f78d91Sagc 	unsigned int	usedspace;
87525f78d91Sagc 
87625f78d91Sagc 	usedspace = (unsigned int)((context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH);
87725f78d91Sagc 	context->bitcount[0] = htobe64(context->bitcount[0]);
87825f78d91Sagc 	context->bitcount[1] = htobe64(context->bitcount[1]);
87925f78d91Sagc 	if (usedspace > 0) {
88025f78d91Sagc 		/* Begin padding with a 1 bit: */
88125f78d91Sagc 		context->buffer[usedspace++] = 0x80;
88225f78d91Sagc 
88325f78d91Sagc 		if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) {
88425f78d91Sagc 			/* Set-up for the last transform: */
88525f78d91Sagc 			memset(&context->buffer[usedspace], 0,
88625f78d91Sagc 			    (size_t)(SHA512_SHORT_BLOCK_LENGTH - usedspace));
88725f78d91Sagc 		} else {
88825f78d91Sagc 			if (usedspace < SHA512_BLOCK_LENGTH) {
88925f78d91Sagc 				memset(&context->buffer[usedspace], 0,
89025f78d91Sagc 				    (size_t)(SHA512_BLOCK_LENGTH - usedspace));
89125f78d91Sagc 			}
89225f78d91Sagc 			/* Do second-to-last transform: */
893dd98b26dSagc 			netpgpv_SHA512_Transform(context,
89425f78d91Sagc 			    (uint64_t *)(void *)context->buffer);
89525f78d91Sagc 
89625f78d91Sagc 			/* And set-up for the last transform: */
89725f78d91Sagc 			memset(context->buffer, 0,
89825f78d91Sagc 			    (size_t)(SHA512_BLOCK_LENGTH - 2));
89925f78d91Sagc 		}
90025f78d91Sagc 	} else {
90125f78d91Sagc 		/* Prepare for final transform: */
90225f78d91Sagc 		memset(context->buffer, 0, (size_t)(SHA512_SHORT_BLOCK_LENGTH));
90325f78d91Sagc 
90425f78d91Sagc 		/* Begin padding with a 1 bit: */
90525f78d91Sagc 		*context->buffer = 0x80;
90625f78d91Sagc 	}
90725f78d91Sagc 	/* Store the length of input data (in bits): */
90825f78d91Sagc 	memcpy(&context->buffer[SHA512_SHORT_BLOCK_LENGTH],
90925f78d91Sagc 	    &context->bitcount[1], sizeof(context->bitcount[1]));
91025f78d91Sagc 	memcpy(&context->buffer[SHA512_SHORT_BLOCK_LENGTH + 8],
91125f78d91Sagc 	    &context->bitcount[0], sizeof(context->bitcount[0]));
91225f78d91Sagc 
91325f78d91Sagc 	/* Final transform: */
914dd98b26dSagc 	netpgpv_SHA512_Transform(context, (uint64_t *)(void *)context->buffer);
91525f78d91Sagc }
91625f78d91Sagc 
91725f78d91Sagc int
netpgpv_SHA512_Final(uint8_t digest[64],NETPGPV_SHA512_CTX * context)918*f8570f8aSmrg netpgpv_SHA512_Final(uint8_t digest[64], NETPGPV_SHA512_CTX *context)
91925f78d91Sagc {
92025f78d91Sagc 	size_t i;
92125f78d91Sagc 
92225f78d91Sagc 	/* If no digest buffer is passed, we don't bother doing this: */
92325f78d91Sagc 	if (digest != NULL) {
924dd98b26dSagc 		netpgpv_SHA512_Last(context);
92525f78d91Sagc 
92625f78d91Sagc 		/* Save the hash data for output: */
92725f78d91Sagc 		for (i = 0; i < 8; ++i)
92825f78d91Sagc 			be64encode(digest + 8 * i, context->state[i]);
92925f78d91Sagc 	}
93025f78d91Sagc 
93125f78d91Sagc 	/* Zero out state data */
93225f78d91Sagc 	memset(context, 0, sizeof(*context));
93325f78d91Sagc 
93425f78d91Sagc 	return 1;
93525f78d91Sagc }
93625f78d91Sagc 
93725f78d91Sagc /*** SHA-384: *********************************************************/
93825f78d91Sagc int
netpgpv_SHA384_Init(NETPGPV_SHA384_CTX * context)939dd98b26dSagc netpgpv_SHA384_Init(NETPGPV_SHA384_CTX *context)
94025f78d91Sagc {
94125f78d91Sagc 	if (context == NULL)
94225f78d91Sagc 		return 1;
94325f78d91Sagc 
94425f78d91Sagc 	memcpy(context->state, sha384_initial_hash_value,
94525f78d91Sagc 	    (size_t)(SHA512_DIGEST_LENGTH));
94625f78d91Sagc 	memset(context->buffer, 0, (size_t)(SHA384_BLOCK_LENGTH));
94725f78d91Sagc 	context->bitcount[0] = context->bitcount[1] = 0;
94825f78d91Sagc 
94925f78d91Sagc 	return 1;
95025f78d91Sagc }
95125f78d91Sagc 
95225f78d91Sagc int
netpgpv_SHA384_Update(NETPGPV_SHA384_CTX * context,const uint8_t * data,size_t len)953dd98b26dSagc netpgpv_SHA384_Update(NETPGPV_SHA384_CTX *context, const uint8_t *data, size_t len)
95425f78d91Sagc {
955dd98b26dSagc 	return netpgpv_SHA512_Update((NETPGPV_SHA512_CTX *)context, data, len);
95625f78d91Sagc }
95725f78d91Sagc 
95825f78d91Sagc void
netpgpv_SHA384_Transform(NETPGPV_SHA512_CTX * context,const uint64_t * data)959dd98b26dSagc netpgpv_SHA384_Transform(NETPGPV_SHA512_CTX *context, const uint64_t *data)
96025f78d91Sagc {
961dd98b26dSagc 	netpgpv_SHA512_Transform((NETPGPV_SHA512_CTX *)context, data);
96225f78d91Sagc }
96325f78d91Sagc 
96425f78d91Sagc int
netpgpv_SHA384_Final(uint8_t digest[48],NETPGPV_SHA384_CTX * context)965*f8570f8aSmrg netpgpv_SHA384_Final(uint8_t digest[48], NETPGPV_SHA384_CTX *context)
96625f78d91Sagc {
96725f78d91Sagc 	size_t i;
96825f78d91Sagc 
96925f78d91Sagc 	/* If no digest buffer is passed, we don't bother doing this: */
97025f78d91Sagc 	if (digest != NULL) {
971dd98b26dSagc 		netpgpv_SHA512_Last((NETPGPV_SHA512_CTX *)context);
97225f78d91Sagc 
97325f78d91Sagc 		/* Save the hash data for output: */
97425f78d91Sagc 		for (i = 0; i < 6; ++i)
97525f78d91Sagc 			be64encode(digest + 8 * i, context->state[i]);
97625f78d91Sagc 	}
97725f78d91Sagc 
97825f78d91Sagc 	/* Zero out state data */
97925f78d91Sagc 	memset(context, 0, sizeof(*context));
98025f78d91Sagc 
98125f78d91Sagc 	return 1;
98225f78d91Sagc }
983