xref: /freebsd/sys/crypto/sha2/sha512c.c (revision 1780e407158ada85e454b24960b83a4f8e35cc25)
17a3f5d11SAllan Jude /*-
27a3f5d11SAllan Jude  * Copyright 2005 Colin Percival
3*1780e407SAllan Jude  * Copyright (c) 2015 Allan Jude <allanjude@FreeBSD.org>
47a3f5d11SAllan Jude  * All rights reserved.
57a3f5d11SAllan Jude  *
67a3f5d11SAllan Jude  * Redistribution and use in source and binary forms, with or without
77a3f5d11SAllan Jude  * modification, are permitted provided that the following conditions
87a3f5d11SAllan Jude  * are met:
97a3f5d11SAllan Jude  * 1. Redistributions of source code must retain the above copyright
107a3f5d11SAllan Jude  *    notice, this list of conditions and the following disclaimer.
117a3f5d11SAllan Jude  * 2. Redistributions in binary form must reproduce the above copyright
127a3f5d11SAllan Jude  *    notice, this list of conditions and the following disclaimer in the
137a3f5d11SAllan Jude  *    documentation and/or other materials provided with the distribution.
147a3f5d11SAllan Jude  *
157a3f5d11SAllan Jude  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
167a3f5d11SAllan Jude  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
177a3f5d11SAllan Jude  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
187a3f5d11SAllan Jude  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
197a3f5d11SAllan Jude  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
207a3f5d11SAllan Jude  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
217a3f5d11SAllan Jude  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
227a3f5d11SAllan Jude  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
237a3f5d11SAllan Jude  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
247a3f5d11SAllan Jude  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
257a3f5d11SAllan Jude  * SUCH DAMAGE.
267a3f5d11SAllan Jude  */
277a3f5d11SAllan Jude 
287a3f5d11SAllan Jude #include <sys/cdefs.h>
297a3f5d11SAllan Jude __FBSDID("$FreeBSD$");
307a3f5d11SAllan Jude 
317a3f5d11SAllan Jude #include <sys/endian.h>
327a3f5d11SAllan Jude #include <sys/types.h>
337a3f5d11SAllan Jude 
347a3f5d11SAllan Jude #ifdef _KERNEL
357a3f5d11SAllan Jude #include <sys/systm.h>
367a3f5d11SAllan Jude #else
377a3f5d11SAllan Jude #include <string.h>
387a3f5d11SAllan Jude #endif
397a3f5d11SAllan Jude 
407a3f5d11SAllan Jude #include "sha512.h"
41*1780e407SAllan Jude #include "sha512t.h"
427a3f5d11SAllan Jude #include "sha384.h"
437a3f5d11SAllan Jude 
447a3f5d11SAllan Jude #if BYTE_ORDER == BIG_ENDIAN
457a3f5d11SAllan Jude 
467a3f5d11SAllan Jude /* Copy a vector of big-endian uint64_t into a vector of bytes */
477a3f5d11SAllan Jude #define be64enc_vect(dst, src, len)	\
487a3f5d11SAllan Jude 	memcpy((void *)dst, (const void *)src, (size_t)len)
497a3f5d11SAllan Jude 
507a3f5d11SAllan Jude /* Copy a vector of bytes into a vector of big-endian uint64_t */
517a3f5d11SAllan Jude #define be64dec_vect(dst, src, len)	\
527a3f5d11SAllan Jude 	memcpy((void *)dst, (const void *)src, (size_t)len)
537a3f5d11SAllan Jude 
547a3f5d11SAllan Jude #else /* BYTE_ORDER != BIG_ENDIAN */
557a3f5d11SAllan Jude 
567a3f5d11SAllan Jude /*
577a3f5d11SAllan Jude  * Encode a length len/4 vector of (uint64_t) into a length len vector of
587a3f5d11SAllan Jude  * (unsigned char) in big-endian form.  Assumes len is a multiple of 8.
597a3f5d11SAllan Jude  */
607a3f5d11SAllan Jude static void
617a3f5d11SAllan Jude be64enc_vect(unsigned char *dst, const uint64_t *src, size_t len)
627a3f5d11SAllan Jude {
637a3f5d11SAllan Jude 	size_t i;
647a3f5d11SAllan Jude 
657a3f5d11SAllan Jude 	for (i = 0; i < len / 8; i++)
667a3f5d11SAllan Jude 		be64enc(dst + i * 8, src[i]);
677a3f5d11SAllan Jude }
687a3f5d11SAllan Jude 
697a3f5d11SAllan Jude /*
707a3f5d11SAllan Jude  * Decode a big-endian length len vector of (unsigned char) into a length
717a3f5d11SAllan Jude  * len/4 vector of (uint64_t).  Assumes len is a multiple of 8.
727a3f5d11SAllan Jude  */
737a3f5d11SAllan Jude static void
747a3f5d11SAllan Jude be64dec_vect(uint64_t *dst, const unsigned char *src, size_t len)
757a3f5d11SAllan Jude {
767a3f5d11SAllan Jude 	size_t i;
777a3f5d11SAllan Jude 
787a3f5d11SAllan Jude 	for (i = 0; i < len / 8; i++)
797a3f5d11SAllan Jude 		dst[i] = be64dec(src + i * 8);
807a3f5d11SAllan Jude }
817a3f5d11SAllan Jude 
827a3f5d11SAllan Jude #endif /* BYTE_ORDER != BIG_ENDIAN */
837a3f5d11SAllan Jude 
847a3f5d11SAllan Jude /* Elementary functions used by SHA512 */
857a3f5d11SAllan Jude #define Ch(x, y, z)	((x & (y ^ z)) ^ z)
867a3f5d11SAllan Jude #define Maj(x, y, z)	((x & (y | z)) | (y & z))
877a3f5d11SAllan Jude #define SHR(x, n)	(x >> n)
887a3f5d11SAllan Jude #define ROTR(x, n)	((x >> n) | (x << (64 - n)))
897a3f5d11SAllan Jude #define S0(x)		(ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
907a3f5d11SAllan Jude #define S1(x)		(ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
917a3f5d11SAllan Jude #define s0(x)		(ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
927a3f5d11SAllan Jude #define s1(x)		(ROTR(x, 19) ^ ROTR(x, 61) ^ SHR(x, 6))
937a3f5d11SAllan Jude 
947a3f5d11SAllan Jude /* SHA512 round function */
957a3f5d11SAllan Jude #define RND(a, b, c, d, e, f, g, h, k)			\
967a3f5d11SAllan Jude 	t0 = h + S1(e) + Ch(e, f, g) + k;		\
977a3f5d11SAllan Jude 	t1 = S0(a) + Maj(a, b, c);			\
987a3f5d11SAllan Jude 	d += t0;					\
997a3f5d11SAllan Jude 	h  = t0 + t1;
1007a3f5d11SAllan Jude 
1017a3f5d11SAllan Jude /* Adjusted round function for rotating state */
1027a3f5d11SAllan Jude #define RNDr(S, W, i, k)			\
1037a3f5d11SAllan Jude 	RND(S[(80 - i) % 8], S[(81 - i) % 8],	\
1047a3f5d11SAllan Jude 	    S[(82 - i) % 8], S[(83 - i) % 8],	\
1057a3f5d11SAllan Jude 	    S[(84 - i) % 8], S[(85 - i) % 8],	\
1067a3f5d11SAllan Jude 	    S[(86 - i) % 8], S[(87 - i) % 8],	\
1077a3f5d11SAllan Jude 	    W[i] + k)
1087a3f5d11SAllan Jude 
1097a3f5d11SAllan Jude /*
1107a3f5d11SAllan Jude  * SHA512 block compression function.  The 512-bit state is transformed via
1117a3f5d11SAllan Jude  * the 512-bit input block to produce a new state.
1127a3f5d11SAllan Jude  */
1137a3f5d11SAllan Jude static void
1147a3f5d11SAllan Jude SHA512_Transform(uint64_t * state, const unsigned char block[SHA512_BLOCK_LENGTH])
1157a3f5d11SAllan Jude {
1167a3f5d11SAllan Jude 	uint64_t W[80];
1177a3f5d11SAllan Jude 	uint64_t S[8];
1187a3f5d11SAllan Jude 	uint64_t t0, t1;
1197a3f5d11SAllan Jude 	int i;
1207a3f5d11SAllan Jude 
1217a3f5d11SAllan Jude 	/* 1. Prepare message schedule W. */
1227a3f5d11SAllan Jude 	be64dec_vect(W, block, SHA512_BLOCK_LENGTH);
1237a3f5d11SAllan Jude 	for (i = 16; i < 80; i++)
1247a3f5d11SAllan Jude 		W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16];
1257a3f5d11SAllan Jude 
1267a3f5d11SAllan Jude 	/* 2. Initialize working variables. */
1277a3f5d11SAllan Jude 	memcpy(S, state, SHA512_DIGEST_LENGTH);
1287a3f5d11SAllan Jude 
1297a3f5d11SAllan Jude 	/* 3. Mix. */
1307a3f5d11SAllan Jude 	RNDr(S, W, 0, 0x428a2f98d728ae22ULL);
1317a3f5d11SAllan Jude 	RNDr(S, W, 1, 0x7137449123ef65cdULL);
1327a3f5d11SAllan Jude 	RNDr(S, W, 2, 0xb5c0fbcfec4d3b2fULL);
1337a3f5d11SAllan Jude 	RNDr(S, W, 3, 0xe9b5dba58189dbbcULL);
1347a3f5d11SAllan Jude 	RNDr(S, W, 4, 0x3956c25bf348b538ULL);
1357a3f5d11SAllan Jude 	RNDr(S, W, 5, 0x59f111f1b605d019ULL);
1367a3f5d11SAllan Jude 	RNDr(S, W, 6, 0x923f82a4af194f9bULL);
1377a3f5d11SAllan Jude 	RNDr(S, W, 7, 0xab1c5ed5da6d8118ULL);
1387a3f5d11SAllan Jude 	RNDr(S, W, 8, 0xd807aa98a3030242ULL);
1397a3f5d11SAllan Jude 	RNDr(S, W, 9, 0x12835b0145706fbeULL);
1407a3f5d11SAllan Jude 	RNDr(S, W, 10, 0x243185be4ee4b28cULL);
1417a3f5d11SAllan Jude 	RNDr(S, W, 11, 0x550c7dc3d5ffb4e2ULL);
1427a3f5d11SAllan Jude 	RNDr(S, W, 12, 0x72be5d74f27b896fULL);
1437a3f5d11SAllan Jude 	RNDr(S, W, 13, 0x80deb1fe3b1696b1ULL);
1447a3f5d11SAllan Jude 	RNDr(S, W, 14, 0x9bdc06a725c71235ULL);
1457a3f5d11SAllan Jude 	RNDr(S, W, 15, 0xc19bf174cf692694ULL);
1467a3f5d11SAllan Jude 	RNDr(S, W, 16, 0xe49b69c19ef14ad2ULL);
1477a3f5d11SAllan Jude 	RNDr(S, W, 17, 0xefbe4786384f25e3ULL);
1487a3f5d11SAllan Jude 	RNDr(S, W, 18, 0x0fc19dc68b8cd5b5ULL);
1497a3f5d11SAllan Jude 	RNDr(S, W, 19, 0x240ca1cc77ac9c65ULL);
1507a3f5d11SAllan Jude 	RNDr(S, W, 20, 0x2de92c6f592b0275ULL);
1517a3f5d11SAllan Jude 	RNDr(S, W, 21, 0x4a7484aa6ea6e483ULL);
1527a3f5d11SAllan Jude 	RNDr(S, W, 22, 0x5cb0a9dcbd41fbd4ULL);
1537a3f5d11SAllan Jude 	RNDr(S, W, 23, 0x76f988da831153b5ULL);
1547a3f5d11SAllan Jude 	RNDr(S, W, 24, 0x983e5152ee66dfabULL);
1557a3f5d11SAllan Jude 	RNDr(S, W, 25, 0xa831c66d2db43210ULL);
1567a3f5d11SAllan Jude 	RNDr(S, W, 26, 0xb00327c898fb213fULL);
1577a3f5d11SAllan Jude 	RNDr(S, W, 27, 0xbf597fc7beef0ee4ULL);
1587a3f5d11SAllan Jude 	RNDr(S, W, 28, 0xc6e00bf33da88fc2ULL);
1597a3f5d11SAllan Jude 	RNDr(S, W, 29, 0xd5a79147930aa725ULL);
1607a3f5d11SAllan Jude 	RNDr(S, W, 30, 0x06ca6351e003826fULL);
1617a3f5d11SAllan Jude 	RNDr(S, W, 31, 0x142929670a0e6e70ULL);
1627a3f5d11SAllan Jude 	RNDr(S, W, 32, 0x27b70a8546d22ffcULL);
1637a3f5d11SAllan Jude 	RNDr(S, W, 33, 0x2e1b21385c26c926ULL);
1647a3f5d11SAllan Jude 	RNDr(S, W, 34, 0x4d2c6dfc5ac42aedULL);
1657a3f5d11SAllan Jude 	RNDr(S, W, 35, 0x53380d139d95b3dfULL);
1667a3f5d11SAllan Jude 	RNDr(S, W, 36, 0x650a73548baf63deULL);
1677a3f5d11SAllan Jude 	RNDr(S, W, 37, 0x766a0abb3c77b2a8ULL);
1687a3f5d11SAllan Jude 	RNDr(S, W, 38, 0x81c2c92e47edaee6ULL);
1697a3f5d11SAllan Jude 	RNDr(S, W, 39, 0x92722c851482353bULL);
1707a3f5d11SAllan Jude 	RNDr(S, W, 40, 0xa2bfe8a14cf10364ULL);
1717a3f5d11SAllan Jude 	RNDr(S, W, 41, 0xa81a664bbc423001ULL);
1727a3f5d11SAllan Jude 	RNDr(S, W, 42, 0xc24b8b70d0f89791ULL);
1737a3f5d11SAllan Jude 	RNDr(S, W, 43, 0xc76c51a30654be30ULL);
1747a3f5d11SAllan Jude 	RNDr(S, W, 44, 0xd192e819d6ef5218ULL);
1757a3f5d11SAllan Jude 	RNDr(S, W, 45, 0xd69906245565a910ULL);
1767a3f5d11SAllan Jude 	RNDr(S, W, 46, 0xf40e35855771202aULL);
1777a3f5d11SAllan Jude 	RNDr(S, W, 47, 0x106aa07032bbd1b8ULL);
1787a3f5d11SAllan Jude 	RNDr(S, W, 48, 0x19a4c116b8d2d0c8ULL);
1797a3f5d11SAllan Jude 	RNDr(S, W, 49, 0x1e376c085141ab53ULL);
1807a3f5d11SAllan Jude 	RNDr(S, W, 50, 0x2748774cdf8eeb99ULL);
1817a3f5d11SAllan Jude 	RNDr(S, W, 51, 0x34b0bcb5e19b48a8ULL);
1827a3f5d11SAllan Jude 	RNDr(S, W, 52, 0x391c0cb3c5c95a63ULL);
1837a3f5d11SAllan Jude 	RNDr(S, W, 53, 0x4ed8aa4ae3418acbULL);
1847a3f5d11SAllan Jude 	RNDr(S, W, 54, 0x5b9cca4f7763e373ULL);
1857a3f5d11SAllan Jude 	RNDr(S, W, 55, 0x682e6ff3d6b2b8a3ULL);
1867a3f5d11SAllan Jude 	RNDr(S, W, 56, 0x748f82ee5defb2fcULL);
1877a3f5d11SAllan Jude 	RNDr(S, W, 57, 0x78a5636f43172f60ULL);
1887a3f5d11SAllan Jude 	RNDr(S, W, 58, 0x84c87814a1f0ab72ULL);
1897a3f5d11SAllan Jude 	RNDr(S, W, 59, 0x8cc702081a6439ecULL);
1907a3f5d11SAllan Jude 	RNDr(S, W, 60, 0x90befffa23631e28ULL);
1917a3f5d11SAllan Jude 	RNDr(S, W, 61, 0xa4506cebde82bde9ULL);
1927a3f5d11SAllan Jude 	RNDr(S, W, 62, 0xbef9a3f7b2c67915ULL);
1937a3f5d11SAllan Jude 	RNDr(S, W, 63, 0xc67178f2e372532bULL);
1947a3f5d11SAllan Jude 	RNDr(S, W, 64, 0xca273eceea26619cULL);
1957a3f5d11SAllan Jude 	RNDr(S, W, 65, 0xd186b8c721c0c207ULL);
1967a3f5d11SAllan Jude 	RNDr(S, W, 66, 0xeada7dd6cde0eb1eULL);
1977a3f5d11SAllan Jude 	RNDr(S, W, 67, 0xf57d4f7fee6ed178ULL);
1987a3f5d11SAllan Jude 	RNDr(S, W, 68, 0x06f067aa72176fbaULL);
1997a3f5d11SAllan Jude 	RNDr(S, W, 69, 0x0a637dc5a2c898a6ULL);
2007a3f5d11SAllan Jude 	RNDr(S, W, 70, 0x113f9804bef90daeULL);
2017a3f5d11SAllan Jude 	RNDr(S, W, 71, 0x1b710b35131c471bULL);
2027a3f5d11SAllan Jude 	RNDr(S, W, 72, 0x28db77f523047d84ULL);
2037a3f5d11SAllan Jude 	RNDr(S, W, 73, 0x32caab7b40c72493ULL);
2047a3f5d11SAllan Jude 	RNDr(S, W, 74, 0x3c9ebe0a15c9bebcULL);
2057a3f5d11SAllan Jude 	RNDr(S, W, 75, 0x431d67c49c100d4cULL);
2067a3f5d11SAllan Jude 	RNDr(S, W, 76, 0x4cc5d4becb3e42b6ULL);
2077a3f5d11SAllan Jude 	RNDr(S, W, 77, 0x597f299cfc657e2aULL);
2087a3f5d11SAllan Jude 	RNDr(S, W, 78, 0x5fcb6fab3ad6faecULL);
2097a3f5d11SAllan Jude 	RNDr(S, W, 79, 0x6c44198c4a475817ULL);
2107a3f5d11SAllan Jude 
2117a3f5d11SAllan Jude 	/* 4. Mix local working variables into global state */
2127a3f5d11SAllan Jude 	for (i = 0; i < 8; i++)
2137a3f5d11SAllan Jude 		state[i] += S[i];
2147a3f5d11SAllan Jude }
2157a3f5d11SAllan Jude 
2167a3f5d11SAllan Jude static unsigned char PAD[SHA512_BLOCK_LENGTH] = {
2177a3f5d11SAllan Jude 	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2187a3f5d11SAllan Jude 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2197a3f5d11SAllan Jude 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2207a3f5d11SAllan Jude 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2217a3f5d11SAllan Jude 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2227a3f5d11SAllan Jude 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2237a3f5d11SAllan Jude 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2247a3f5d11SAllan Jude 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2257a3f5d11SAllan Jude };
2267a3f5d11SAllan Jude 
2277a3f5d11SAllan Jude /* Add padding and terminating bit-count. */
2287a3f5d11SAllan Jude static void
2297a3f5d11SAllan Jude SHA512_Pad(SHA512_CTX * ctx)
2307a3f5d11SAllan Jude {
2317a3f5d11SAllan Jude 	unsigned char len[16];
2327a3f5d11SAllan Jude 	uint64_t r, plen;
2337a3f5d11SAllan Jude 
2347a3f5d11SAllan Jude 	/*
2357a3f5d11SAllan Jude 	 * Convert length to a vector of bytes -- we do this now rather
2367a3f5d11SAllan Jude 	 * than later because the length will change after we pad.
2377a3f5d11SAllan Jude 	 */
2387a3f5d11SAllan Jude 	be64enc_vect(len, ctx->count, 16);
2397a3f5d11SAllan Jude 
2407a3f5d11SAllan Jude 	/* Add 1--128 bytes so that the resulting length is 112 mod 128 */
2417a3f5d11SAllan Jude 	r = (ctx->count[1] >> 3) & 0x7f;
2427a3f5d11SAllan Jude 	plen = (r < 112) ? (112 - r) : (240 - r);
2437a3f5d11SAllan Jude 	SHA512_Update(ctx, PAD, (size_t)plen);
2447a3f5d11SAllan Jude 
2457a3f5d11SAllan Jude 	/* Add the terminating bit-count */
2467a3f5d11SAllan Jude 	SHA512_Update(ctx, len, 16);
2477a3f5d11SAllan Jude }
2487a3f5d11SAllan Jude 
2497a3f5d11SAllan Jude /* SHA-512 initialization.  Begins a SHA-512 operation. */
2507a3f5d11SAllan Jude void
2517a3f5d11SAllan Jude SHA512_Init(SHA512_CTX * ctx)
2527a3f5d11SAllan Jude {
2537a3f5d11SAllan Jude 
2547a3f5d11SAllan Jude 	/* Zero bits processed so far */
2557a3f5d11SAllan Jude 	ctx->count[0] = ctx->count[1] = 0;
2567a3f5d11SAllan Jude 
2577a3f5d11SAllan Jude 	/* Magic initialization constants */
2587a3f5d11SAllan Jude 	ctx->state[0] = 0x6a09e667f3bcc908ULL;
2597a3f5d11SAllan Jude 	ctx->state[1] = 0xbb67ae8584caa73bULL;
2607a3f5d11SAllan Jude 	ctx->state[2] = 0x3c6ef372fe94f82bULL;
2617a3f5d11SAllan Jude 	ctx->state[3] = 0xa54ff53a5f1d36f1ULL;
2627a3f5d11SAllan Jude 	ctx->state[4] = 0x510e527fade682d1ULL;
2637a3f5d11SAllan Jude 	ctx->state[5] = 0x9b05688c2b3e6c1fULL;
2647a3f5d11SAllan Jude 	ctx->state[6] = 0x1f83d9abfb41bd6bULL;
2657a3f5d11SAllan Jude 	ctx->state[7] = 0x5be0cd19137e2179ULL;
2667a3f5d11SAllan Jude }
2677a3f5d11SAllan Jude 
2687a3f5d11SAllan Jude /* Add bytes into the hash */
2697a3f5d11SAllan Jude void
2707a3f5d11SAllan Jude SHA512_Update(SHA512_CTX * ctx, const void *in, size_t len)
2717a3f5d11SAllan Jude {
2727a3f5d11SAllan Jude 	uint64_t bitlen[2];
2737a3f5d11SAllan Jude 	uint64_t r;
2747a3f5d11SAllan Jude 	const unsigned char *src = in;
2757a3f5d11SAllan Jude 
2767a3f5d11SAllan Jude 	/* Number of bytes left in the buffer from previous updates */
2777a3f5d11SAllan Jude 	r = (ctx->count[1] >> 3) & 0x7f;
2787a3f5d11SAllan Jude 
2797a3f5d11SAllan Jude 	/* Convert the length into a number of bits */
2807a3f5d11SAllan Jude 	bitlen[1] = ((uint64_t)len) << 3;
2817a3f5d11SAllan Jude 	bitlen[0] = ((uint64_t)len) >> 61;
2827a3f5d11SAllan Jude 
2837a3f5d11SAllan Jude 	/* Update number of bits */
2847a3f5d11SAllan Jude 	if ((ctx->count[1] += bitlen[1]) < bitlen[1])
2857a3f5d11SAllan Jude 		ctx->count[0]++;
2867a3f5d11SAllan Jude 	ctx->count[0] += bitlen[0];
2877a3f5d11SAllan Jude 
2887a3f5d11SAllan Jude 	/* Handle the case where we don't need to perform any transforms */
2897a3f5d11SAllan Jude 	if (len < SHA512_BLOCK_LENGTH - r) {
2907a3f5d11SAllan Jude 		memcpy(&ctx->buf[r], src, len);
2917a3f5d11SAllan Jude 		return;
2927a3f5d11SAllan Jude 	}
2937a3f5d11SAllan Jude 
2947a3f5d11SAllan Jude 	/* Finish the current block */
2957a3f5d11SAllan Jude 	memcpy(&ctx->buf[r], src, SHA512_BLOCK_LENGTH - r);
2967a3f5d11SAllan Jude 	SHA512_Transform(ctx->state, ctx->buf);
2977a3f5d11SAllan Jude 	src += SHA512_BLOCK_LENGTH - r;
2987a3f5d11SAllan Jude 	len -= SHA512_BLOCK_LENGTH - r;
2997a3f5d11SAllan Jude 
3007a3f5d11SAllan Jude 	/* Perform complete blocks */
3017a3f5d11SAllan Jude 	while (len >= SHA512_BLOCK_LENGTH) {
3027a3f5d11SAllan Jude 		SHA512_Transform(ctx->state, src);
3037a3f5d11SAllan Jude 		src += SHA512_BLOCK_LENGTH;
3047a3f5d11SAllan Jude 		len -= SHA512_BLOCK_LENGTH;
3057a3f5d11SAllan Jude 	}
3067a3f5d11SAllan Jude 
3077a3f5d11SAllan Jude 	/* Copy left over data into buffer */
3087a3f5d11SAllan Jude 	memcpy(ctx->buf, src, len);
3097a3f5d11SAllan Jude }
3107a3f5d11SAllan Jude 
3117a3f5d11SAllan Jude /*
3127a3f5d11SAllan Jude  * SHA-512 finalization.  Pads the input data, exports the hash value,
3137a3f5d11SAllan Jude  * and clears the context state.
3147a3f5d11SAllan Jude  */
3157a3f5d11SAllan Jude void
316571ebf76SConrad Meyer SHA512_Final(unsigned char digest[static SHA512_DIGEST_LENGTH], SHA512_CTX *ctx)
3177a3f5d11SAllan Jude {
3187a3f5d11SAllan Jude 
3197a3f5d11SAllan Jude 	/* Add padding */
3207a3f5d11SAllan Jude 	SHA512_Pad(ctx);
3217a3f5d11SAllan Jude 
3227a3f5d11SAllan Jude 	/* Write the hash */
3237a3f5d11SAllan Jude 	be64enc_vect(digest, ctx->state, SHA512_DIGEST_LENGTH);
3247a3f5d11SAllan Jude 
3257a3f5d11SAllan Jude 	/* Clear the context state */
326571ebf76SConrad Meyer 	memset(ctx, 0, sizeof(*ctx));
3277a3f5d11SAllan Jude }
3287a3f5d11SAllan Jude 
329*1780e407SAllan Jude /*** SHA-512t: *********************************************************/
330*1780e407SAllan Jude /*
331*1780e407SAllan Jude  * the SHA512t transforms are identical to SHA512 so reuse the existing function
332*1780e407SAllan Jude  */
333*1780e407SAllan Jude void
334*1780e407SAllan Jude SHA512_224_Init(SHA512_CTX * ctx)
335*1780e407SAllan Jude {
336*1780e407SAllan Jude 
337*1780e407SAllan Jude 	/* Zero bits processed so far */
338*1780e407SAllan Jude 	ctx->count[0] = ctx->count[1] = 0;
339*1780e407SAllan Jude 
340*1780e407SAllan Jude 	/* Magic initialization constants */
341*1780e407SAllan Jude 	ctx->state[0] = 0x8c3d37c819544da2ULL;
342*1780e407SAllan Jude 	ctx->state[1] = 0x73e1996689dcd4d6ULL;
343*1780e407SAllan Jude 	ctx->state[2] = 0x1dfab7ae32ff9c82ULL;
344*1780e407SAllan Jude 	ctx->state[3] = 0x679dd514582f9fcfULL;
345*1780e407SAllan Jude 	ctx->state[4] = 0x0f6d2b697bd44da8ULL;
346*1780e407SAllan Jude 	ctx->state[5] = 0x77e36f7304c48942ULL;
347*1780e407SAllan Jude 	ctx->state[6] = 0x3f9d85a86a1d36c8ULL;
348*1780e407SAllan Jude 	ctx->state[7] = 0x1112e6ad91d692a1ULL;
349*1780e407SAllan Jude }
350*1780e407SAllan Jude 
351*1780e407SAllan Jude void
352*1780e407SAllan Jude SHA512_224_Update(SHA512_CTX * ctx, const void *in, size_t len)
353*1780e407SAllan Jude {
354*1780e407SAllan Jude 
355*1780e407SAllan Jude 	SHA512_Update(ctx, in, len);
356*1780e407SAllan Jude }
357*1780e407SAllan Jude 
358*1780e407SAllan Jude void
359*1780e407SAllan Jude SHA512_224_Final(unsigned char digest[static SHA512_224_DIGEST_LENGTH], SHA512_CTX * ctx)
360*1780e407SAllan Jude {
361*1780e407SAllan Jude 
362*1780e407SAllan Jude 	/* Add padding */
363*1780e407SAllan Jude 	SHA512_Pad(ctx);
364*1780e407SAllan Jude 
365*1780e407SAllan Jude 	/* Write the hash */
366*1780e407SAllan Jude 	be64enc_vect(digest, ctx->state, SHA512_224_DIGEST_LENGTH);
367*1780e407SAllan Jude 
368*1780e407SAllan Jude 	/* Clear the context state */
369*1780e407SAllan Jude 	memset(ctx, 0, sizeof(*ctx));
370*1780e407SAllan Jude }
371*1780e407SAllan Jude 
372*1780e407SAllan Jude void
373*1780e407SAllan Jude SHA512_256_Init(SHA512_CTX * ctx)
374*1780e407SAllan Jude {
375*1780e407SAllan Jude 
376*1780e407SAllan Jude 	/* Zero bits processed so far */
377*1780e407SAllan Jude 	ctx->count[0] = ctx->count[1] = 0;
378*1780e407SAllan Jude 
379*1780e407SAllan Jude 	/* Magic initialization constants */
380*1780e407SAllan Jude 	ctx->state[0] = 0x22312194fc2bf72cULL;
381*1780e407SAllan Jude 	ctx->state[1] = 0x9f555fa3c84c64c2ULL;
382*1780e407SAllan Jude 	ctx->state[2] = 0x2393b86b6f53b151ULL;
383*1780e407SAllan Jude 	ctx->state[3] = 0x963877195940eabdULL;
384*1780e407SAllan Jude 	ctx->state[4] = 0x96283ee2a88effe3ULL;
385*1780e407SAllan Jude 	ctx->state[5] = 0xbe5e1e2553863992ULL;
386*1780e407SAllan Jude 	ctx->state[6] = 0x2b0199fc2c85b8aaULL;
387*1780e407SAllan Jude 	ctx->state[7] = 0x0eb72ddc81c52ca2ULL;
388*1780e407SAllan Jude }
389*1780e407SAllan Jude 
390*1780e407SAllan Jude void
391*1780e407SAllan Jude SHA512_256_Update(SHA512_CTX * ctx, const void *in, size_t len)
392*1780e407SAllan Jude {
393*1780e407SAllan Jude 
394*1780e407SAllan Jude 	SHA512_Update(ctx, in, len);
395*1780e407SAllan Jude }
396*1780e407SAllan Jude 
397*1780e407SAllan Jude void
398*1780e407SAllan Jude SHA512_256_Final(unsigned char digest[static SHA512_256_DIGEST_LENGTH], SHA512_CTX * ctx)
399*1780e407SAllan Jude {
400*1780e407SAllan Jude 
401*1780e407SAllan Jude 	/* Add padding */
402*1780e407SAllan Jude 	SHA512_Pad(ctx);
403*1780e407SAllan Jude 
404*1780e407SAllan Jude 	/* Write the hash */
405*1780e407SAllan Jude 	be64enc_vect(digest, ctx->state, SHA512_256_DIGEST_LENGTH);
406*1780e407SAllan Jude 
407*1780e407SAllan Jude 	/* Clear the context state */
408*1780e407SAllan Jude 	memset(ctx, 0, sizeof(*ctx));
409*1780e407SAllan Jude }
410*1780e407SAllan Jude 
4117a3f5d11SAllan Jude /*** SHA-384: *********************************************************/
4127a3f5d11SAllan Jude /*
4137a3f5d11SAllan Jude  * the SHA384 and SHA512 transforms are identical, so SHA384 is skipped
4147a3f5d11SAllan Jude  */
4157a3f5d11SAllan Jude 
4167a3f5d11SAllan Jude /* SHA-384 initialization.  Begins a SHA-384 operation. */
4177a3f5d11SAllan Jude void
4187a3f5d11SAllan Jude SHA384_Init(SHA384_CTX * ctx)
4197a3f5d11SAllan Jude {
4207a3f5d11SAllan Jude 
4217a3f5d11SAllan Jude 	/* Zero bits processed so far */
4227a3f5d11SAllan Jude 	ctx->count[0] = ctx->count[1] = 0;
4237a3f5d11SAllan Jude 
4247a3f5d11SAllan Jude 	/* Magic initialization constants */
4257a3f5d11SAllan Jude 	ctx->state[0] = 0xcbbb9d5dc1059ed8ULL;
4267a3f5d11SAllan Jude 	ctx->state[1] = 0x629a292a367cd507ULL;
4277a3f5d11SAllan Jude 	ctx->state[2] = 0x9159015a3070dd17ULL;
4287a3f5d11SAllan Jude 	ctx->state[3] = 0x152fecd8f70e5939ULL;
4297a3f5d11SAllan Jude 	ctx->state[4] = 0x67332667ffc00b31ULL;
4307a3f5d11SAllan Jude 	ctx->state[5] = 0x8eb44a8768581511ULL;
4317a3f5d11SAllan Jude 	ctx->state[6] = 0xdb0c2e0d64f98fa7ULL;
4327a3f5d11SAllan Jude 	ctx->state[7] = 0x47b5481dbefa4fa4ULL;
4337a3f5d11SAllan Jude }
4347a3f5d11SAllan Jude 
4357a3f5d11SAllan Jude /* Add bytes into the SHA-384 hash */
4367a3f5d11SAllan Jude void
4377a3f5d11SAllan Jude SHA384_Update(SHA384_CTX * ctx, const void *in, size_t len)
4387a3f5d11SAllan Jude {
4397a3f5d11SAllan Jude 
4407a3f5d11SAllan Jude 	SHA512_Update((SHA512_CTX *)ctx, in, len);
4417a3f5d11SAllan Jude }
4427a3f5d11SAllan Jude 
4437a3f5d11SAllan Jude /*
4447a3f5d11SAllan Jude  * SHA-384 finalization.  Pads the input data, exports the hash value,
4457a3f5d11SAllan Jude  * and clears the context state.
4467a3f5d11SAllan Jude  */
4477a3f5d11SAllan Jude void
448571ebf76SConrad Meyer SHA384_Final(unsigned char digest[static SHA384_DIGEST_LENGTH], SHA384_CTX *ctx)
4497a3f5d11SAllan Jude {
4507a3f5d11SAllan Jude 
4517a3f5d11SAllan Jude 	/* Add padding */
4527a3f5d11SAllan Jude 	SHA512_Pad((SHA512_CTX *)ctx);
4537a3f5d11SAllan Jude 
4547a3f5d11SAllan Jude 	/* Write the hash */
4557a3f5d11SAllan Jude 	be64enc_vect(digest, ctx->state, SHA384_DIGEST_LENGTH);
4567a3f5d11SAllan Jude 
4577a3f5d11SAllan Jude 	/* Clear the context state */
458571ebf76SConrad Meyer 	memset(ctx, 0, sizeof(*ctx));
4597a3f5d11SAllan Jude }
4607a3f5d11SAllan Jude 
4617a3f5d11SAllan Jude #ifdef WEAK_REFS
4627a3f5d11SAllan Jude /* When building libmd, provide weak references. Note: this is not
4637a3f5d11SAllan Jude    activated in the context of compiling these sources for internal
4647a3f5d11SAllan Jude    use in libcrypt.
4657a3f5d11SAllan Jude  */
4667a3f5d11SAllan Jude #undef SHA512_Init
4677a3f5d11SAllan Jude __weak_reference(_libmd_SHA512_Init, SHA512_Init);
4687a3f5d11SAllan Jude #undef SHA512_Update
4697a3f5d11SAllan Jude __weak_reference(_libmd_SHA512_Update, SHA512_Update);
4707a3f5d11SAllan Jude #undef SHA512_Final
4717a3f5d11SAllan Jude __weak_reference(_libmd_SHA512_Final, SHA512_Final);
4727a3f5d11SAllan Jude #undef SHA512_Transform
4737a3f5d11SAllan Jude __weak_reference(_libmd_SHA512_Transform, SHA512_Transform);
4747a3f5d11SAllan Jude 
475*1780e407SAllan Jude #undef SHA512_224_Init
476*1780e407SAllan Jude __weak_reference(_libmd_SHA512_224_Init, SHA512_224_Init);
477*1780e407SAllan Jude #undef SHA512_224_Update
478*1780e407SAllan Jude __weak_reference(_libmd_SHA512_224_Update, SHA512_224_Update);
479*1780e407SAllan Jude #undef SHA512_224_Final
480*1780e407SAllan Jude __weak_reference(_libmd_SHA512_224_Final, SHA512_224_Final);
481*1780e407SAllan Jude 
482*1780e407SAllan Jude #undef SHA512_256_Init
483*1780e407SAllan Jude __weak_reference(_libmd_SHA512_256_Init, SHA512_256_Init);
484*1780e407SAllan Jude #undef SHA512_256_Update
485*1780e407SAllan Jude __weak_reference(_libmd_SHA512_256_Update, SHA512_256_Update);
486*1780e407SAllan Jude #undef SHA512_256_Final
487*1780e407SAllan Jude __weak_reference(_libmd_SHA512_256_Final, SHA512_256_Final);
488*1780e407SAllan Jude 
4897a3f5d11SAllan Jude #undef SHA384_Init
4907a3f5d11SAllan Jude __weak_reference(_libmd_SHA384_Init, SHA384_Init);
4917a3f5d11SAllan Jude #undef SHA384_Update
4927a3f5d11SAllan Jude __weak_reference(_libmd_SHA384_Update, SHA384_Update);
4937a3f5d11SAllan Jude #undef SHA384_Final
4947a3f5d11SAllan Jude __weak_reference(_libmd_SHA384_Final, SHA384_Final);
4957a3f5d11SAllan Jude #endif
496