xref: /freebsd/sys/crypto/sha2/sha512c.c (revision 571ebf7685f6f4c14d29d3efba04a558def65bd4)
17a3f5d11SAllan Jude /*-
27a3f5d11SAllan Jude  * Copyright 2005 Colin Percival
37a3f5d11SAllan Jude  * All rights reserved.
47a3f5d11SAllan Jude  *
57a3f5d11SAllan Jude  * Redistribution and use in source and binary forms, with or without
67a3f5d11SAllan Jude  * modification, are permitted provided that the following conditions
77a3f5d11SAllan Jude  * are met:
87a3f5d11SAllan Jude  * 1. Redistributions of source code must retain the above copyright
97a3f5d11SAllan Jude  *    notice, this list of conditions and the following disclaimer.
107a3f5d11SAllan Jude  * 2. Redistributions in binary form must reproduce the above copyright
117a3f5d11SAllan Jude  *    notice, this list of conditions and the following disclaimer in the
127a3f5d11SAllan Jude  *    documentation and/or other materials provided with the distribution.
137a3f5d11SAllan Jude  *
147a3f5d11SAllan Jude  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
157a3f5d11SAllan Jude  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
167a3f5d11SAllan Jude  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
177a3f5d11SAllan Jude  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
187a3f5d11SAllan Jude  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
197a3f5d11SAllan Jude  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
207a3f5d11SAllan Jude  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
217a3f5d11SAllan Jude  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
227a3f5d11SAllan Jude  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
237a3f5d11SAllan Jude  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
247a3f5d11SAllan Jude  * SUCH DAMAGE.
257a3f5d11SAllan Jude  */
267a3f5d11SAllan Jude 
277a3f5d11SAllan Jude #include <sys/cdefs.h>
287a3f5d11SAllan Jude __FBSDID("$FreeBSD$");
297a3f5d11SAllan Jude 
307a3f5d11SAllan Jude #include <sys/endian.h>
317a3f5d11SAllan Jude #include <sys/types.h>
327a3f5d11SAllan Jude 
337a3f5d11SAllan Jude #ifdef _KERNEL
347a3f5d11SAllan Jude #include <sys/systm.h>
357a3f5d11SAllan Jude #else
367a3f5d11SAllan Jude #include <string.h>
377a3f5d11SAllan Jude #endif
387a3f5d11SAllan Jude 
397a3f5d11SAllan Jude #include "sha512.h"
407a3f5d11SAllan Jude #include "sha384.h"
417a3f5d11SAllan Jude 
427a3f5d11SAllan Jude #if BYTE_ORDER == BIG_ENDIAN
437a3f5d11SAllan Jude 
447a3f5d11SAllan Jude /* Copy a vector of big-endian uint64_t into a vector of bytes */
457a3f5d11SAllan Jude #define be64enc_vect(dst, src, len)	\
467a3f5d11SAllan Jude 	memcpy((void *)dst, (const void *)src, (size_t)len)
477a3f5d11SAllan Jude 
487a3f5d11SAllan Jude /* Copy a vector of bytes into a vector of big-endian uint64_t */
497a3f5d11SAllan Jude #define be64dec_vect(dst, src, len)	\
507a3f5d11SAllan Jude 	memcpy((void *)dst, (const void *)src, (size_t)len)
517a3f5d11SAllan Jude 
527a3f5d11SAllan Jude #else /* BYTE_ORDER != BIG_ENDIAN */
537a3f5d11SAllan Jude 
547a3f5d11SAllan Jude /*
557a3f5d11SAllan Jude  * Encode a length len/4 vector of (uint64_t) into a length len vector of
567a3f5d11SAllan Jude  * (unsigned char) in big-endian form.  Assumes len is a multiple of 8.
577a3f5d11SAllan Jude  */
587a3f5d11SAllan Jude static void
597a3f5d11SAllan Jude be64enc_vect(unsigned char *dst, const uint64_t *src, size_t len)
607a3f5d11SAllan Jude {
617a3f5d11SAllan Jude 	size_t i;
627a3f5d11SAllan Jude 
637a3f5d11SAllan Jude 	for (i = 0; i < len / 8; i++)
647a3f5d11SAllan Jude 		be64enc(dst + i * 8, src[i]);
657a3f5d11SAllan Jude }
667a3f5d11SAllan Jude 
677a3f5d11SAllan Jude /*
687a3f5d11SAllan Jude  * Decode a big-endian length len vector of (unsigned char) into a length
697a3f5d11SAllan Jude  * len/4 vector of (uint64_t).  Assumes len is a multiple of 8.
707a3f5d11SAllan Jude  */
717a3f5d11SAllan Jude static void
727a3f5d11SAllan Jude be64dec_vect(uint64_t *dst, const unsigned char *src, size_t len)
737a3f5d11SAllan Jude {
747a3f5d11SAllan Jude 	size_t i;
757a3f5d11SAllan Jude 
767a3f5d11SAllan Jude 	for (i = 0; i < len / 8; i++)
777a3f5d11SAllan Jude 		dst[i] = be64dec(src + i * 8);
787a3f5d11SAllan Jude }
797a3f5d11SAllan Jude 
807a3f5d11SAllan Jude #endif /* BYTE_ORDER != BIG_ENDIAN */
817a3f5d11SAllan Jude 
827a3f5d11SAllan Jude /* Elementary functions used by SHA512 */
837a3f5d11SAllan Jude #define Ch(x, y, z)	((x & (y ^ z)) ^ z)
847a3f5d11SAllan Jude #define Maj(x, y, z)	((x & (y | z)) | (y & z))
857a3f5d11SAllan Jude #define SHR(x, n)	(x >> n)
867a3f5d11SAllan Jude #define ROTR(x, n)	((x >> n) | (x << (64 - n)))
877a3f5d11SAllan Jude #define S0(x)		(ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
887a3f5d11SAllan Jude #define S1(x)		(ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
897a3f5d11SAllan Jude #define s0(x)		(ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
907a3f5d11SAllan Jude #define s1(x)		(ROTR(x, 19) ^ ROTR(x, 61) ^ SHR(x, 6))
917a3f5d11SAllan Jude 
927a3f5d11SAllan Jude /* SHA512 round function */
937a3f5d11SAllan Jude #define RND(a, b, c, d, e, f, g, h, k)			\
947a3f5d11SAllan Jude 	t0 = h + S1(e) + Ch(e, f, g) + k;		\
957a3f5d11SAllan Jude 	t1 = S0(a) + Maj(a, b, c);			\
967a3f5d11SAllan Jude 	d += t0;					\
977a3f5d11SAllan Jude 	h  = t0 + t1;
987a3f5d11SAllan Jude 
997a3f5d11SAllan Jude /* Adjusted round function for rotating state */
1007a3f5d11SAllan Jude #define RNDr(S, W, i, k)			\
1017a3f5d11SAllan Jude 	RND(S[(80 - i) % 8], S[(81 - i) % 8],	\
1027a3f5d11SAllan Jude 	    S[(82 - i) % 8], S[(83 - i) % 8],	\
1037a3f5d11SAllan Jude 	    S[(84 - i) % 8], S[(85 - i) % 8],	\
1047a3f5d11SAllan Jude 	    S[(86 - i) % 8], S[(87 - i) % 8],	\
1057a3f5d11SAllan Jude 	    W[i] + k)
1067a3f5d11SAllan Jude 
1077a3f5d11SAllan Jude /*
1087a3f5d11SAllan Jude  * SHA512 block compression function.  The 512-bit state is transformed via
1097a3f5d11SAllan Jude  * the 512-bit input block to produce a new state.
1107a3f5d11SAllan Jude  */
1117a3f5d11SAllan Jude static void
1127a3f5d11SAllan Jude SHA512_Transform(uint64_t * state, const unsigned char block[SHA512_BLOCK_LENGTH])
1137a3f5d11SAllan Jude {
1147a3f5d11SAllan Jude 	uint64_t W[80];
1157a3f5d11SAllan Jude 	uint64_t S[8];
1167a3f5d11SAllan Jude 	uint64_t t0, t1;
1177a3f5d11SAllan Jude 	int i;
1187a3f5d11SAllan Jude 
1197a3f5d11SAllan Jude 	/* 1. Prepare message schedule W. */
1207a3f5d11SAllan Jude 	be64dec_vect(W, block, SHA512_BLOCK_LENGTH);
1217a3f5d11SAllan Jude 	for (i = 16; i < 80; i++)
1227a3f5d11SAllan Jude 		W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16];
1237a3f5d11SAllan Jude 
1247a3f5d11SAllan Jude 	/* 2. Initialize working variables. */
1257a3f5d11SAllan Jude 	memcpy(S, state, SHA512_DIGEST_LENGTH);
1267a3f5d11SAllan Jude 
1277a3f5d11SAllan Jude 	/* 3. Mix. */
1287a3f5d11SAllan Jude 	RNDr(S, W, 0, 0x428a2f98d728ae22ULL);
1297a3f5d11SAllan Jude 	RNDr(S, W, 1, 0x7137449123ef65cdULL);
1307a3f5d11SAllan Jude 	RNDr(S, W, 2, 0xb5c0fbcfec4d3b2fULL);
1317a3f5d11SAllan Jude 	RNDr(S, W, 3, 0xe9b5dba58189dbbcULL);
1327a3f5d11SAllan Jude 	RNDr(S, W, 4, 0x3956c25bf348b538ULL);
1337a3f5d11SAllan Jude 	RNDr(S, W, 5, 0x59f111f1b605d019ULL);
1347a3f5d11SAllan Jude 	RNDr(S, W, 6, 0x923f82a4af194f9bULL);
1357a3f5d11SAllan Jude 	RNDr(S, W, 7, 0xab1c5ed5da6d8118ULL);
1367a3f5d11SAllan Jude 	RNDr(S, W, 8, 0xd807aa98a3030242ULL);
1377a3f5d11SAllan Jude 	RNDr(S, W, 9, 0x12835b0145706fbeULL);
1387a3f5d11SAllan Jude 	RNDr(S, W, 10, 0x243185be4ee4b28cULL);
1397a3f5d11SAllan Jude 	RNDr(S, W, 11, 0x550c7dc3d5ffb4e2ULL);
1407a3f5d11SAllan Jude 	RNDr(S, W, 12, 0x72be5d74f27b896fULL);
1417a3f5d11SAllan Jude 	RNDr(S, W, 13, 0x80deb1fe3b1696b1ULL);
1427a3f5d11SAllan Jude 	RNDr(S, W, 14, 0x9bdc06a725c71235ULL);
1437a3f5d11SAllan Jude 	RNDr(S, W, 15, 0xc19bf174cf692694ULL);
1447a3f5d11SAllan Jude 	RNDr(S, W, 16, 0xe49b69c19ef14ad2ULL);
1457a3f5d11SAllan Jude 	RNDr(S, W, 17, 0xefbe4786384f25e3ULL);
1467a3f5d11SAllan Jude 	RNDr(S, W, 18, 0x0fc19dc68b8cd5b5ULL);
1477a3f5d11SAllan Jude 	RNDr(S, W, 19, 0x240ca1cc77ac9c65ULL);
1487a3f5d11SAllan Jude 	RNDr(S, W, 20, 0x2de92c6f592b0275ULL);
1497a3f5d11SAllan Jude 	RNDr(S, W, 21, 0x4a7484aa6ea6e483ULL);
1507a3f5d11SAllan Jude 	RNDr(S, W, 22, 0x5cb0a9dcbd41fbd4ULL);
1517a3f5d11SAllan Jude 	RNDr(S, W, 23, 0x76f988da831153b5ULL);
1527a3f5d11SAllan Jude 	RNDr(S, W, 24, 0x983e5152ee66dfabULL);
1537a3f5d11SAllan Jude 	RNDr(S, W, 25, 0xa831c66d2db43210ULL);
1547a3f5d11SAllan Jude 	RNDr(S, W, 26, 0xb00327c898fb213fULL);
1557a3f5d11SAllan Jude 	RNDr(S, W, 27, 0xbf597fc7beef0ee4ULL);
1567a3f5d11SAllan Jude 	RNDr(S, W, 28, 0xc6e00bf33da88fc2ULL);
1577a3f5d11SAllan Jude 	RNDr(S, W, 29, 0xd5a79147930aa725ULL);
1587a3f5d11SAllan Jude 	RNDr(S, W, 30, 0x06ca6351e003826fULL);
1597a3f5d11SAllan Jude 	RNDr(S, W, 31, 0x142929670a0e6e70ULL);
1607a3f5d11SAllan Jude 	RNDr(S, W, 32, 0x27b70a8546d22ffcULL);
1617a3f5d11SAllan Jude 	RNDr(S, W, 33, 0x2e1b21385c26c926ULL);
1627a3f5d11SAllan Jude 	RNDr(S, W, 34, 0x4d2c6dfc5ac42aedULL);
1637a3f5d11SAllan Jude 	RNDr(S, W, 35, 0x53380d139d95b3dfULL);
1647a3f5d11SAllan Jude 	RNDr(S, W, 36, 0x650a73548baf63deULL);
1657a3f5d11SAllan Jude 	RNDr(S, W, 37, 0x766a0abb3c77b2a8ULL);
1667a3f5d11SAllan Jude 	RNDr(S, W, 38, 0x81c2c92e47edaee6ULL);
1677a3f5d11SAllan Jude 	RNDr(S, W, 39, 0x92722c851482353bULL);
1687a3f5d11SAllan Jude 	RNDr(S, W, 40, 0xa2bfe8a14cf10364ULL);
1697a3f5d11SAllan Jude 	RNDr(S, W, 41, 0xa81a664bbc423001ULL);
1707a3f5d11SAllan Jude 	RNDr(S, W, 42, 0xc24b8b70d0f89791ULL);
1717a3f5d11SAllan Jude 	RNDr(S, W, 43, 0xc76c51a30654be30ULL);
1727a3f5d11SAllan Jude 	RNDr(S, W, 44, 0xd192e819d6ef5218ULL);
1737a3f5d11SAllan Jude 	RNDr(S, W, 45, 0xd69906245565a910ULL);
1747a3f5d11SAllan Jude 	RNDr(S, W, 46, 0xf40e35855771202aULL);
1757a3f5d11SAllan Jude 	RNDr(S, W, 47, 0x106aa07032bbd1b8ULL);
1767a3f5d11SAllan Jude 	RNDr(S, W, 48, 0x19a4c116b8d2d0c8ULL);
1777a3f5d11SAllan Jude 	RNDr(S, W, 49, 0x1e376c085141ab53ULL);
1787a3f5d11SAllan Jude 	RNDr(S, W, 50, 0x2748774cdf8eeb99ULL);
1797a3f5d11SAllan Jude 	RNDr(S, W, 51, 0x34b0bcb5e19b48a8ULL);
1807a3f5d11SAllan Jude 	RNDr(S, W, 52, 0x391c0cb3c5c95a63ULL);
1817a3f5d11SAllan Jude 	RNDr(S, W, 53, 0x4ed8aa4ae3418acbULL);
1827a3f5d11SAllan Jude 	RNDr(S, W, 54, 0x5b9cca4f7763e373ULL);
1837a3f5d11SAllan Jude 	RNDr(S, W, 55, 0x682e6ff3d6b2b8a3ULL);
1847a3f5d11SAllan Jude 	RNDr(S, W, 56, 0x748f82ee5defb2fcULL);
1857a3f5d11SAllan Jude 	RNDr(S, W, 57, 0x78a5636f43172f60ULL);
1867a3f5d11SAllan Jude 	RNDr(S, W, 58, 0x84c87814a1f0ab72ULL);
1877a3f5d11SAllan Jude 	RNDr(S, W, 59, 0x8cc702081a6439ecULL);
1887a3f5d11SAllan Jude 	RNDr(S, W, 60, 0x90befffa23631e28ULL);
1897a3f5d11SAllan Jude 	RNDr(S, W, 61, 0xa4506cebde82bde9ULL);
1907a3f5d11SAllan Jude 	RNDr(S, W, 62, 0xbef9a3f7b2c67915ULL);
1917a3f5d11SAllan Jude 	RNDr(S, W, 63, 0xc67178f2e372532bULL);
1927a3f5d11SAllan Jude 	RNDr(S, W, 64, 0xca273eceea26619cULL);
1937a3f5d11SAllan Jude 	RNDr(S, W, 65, 0xd186b8c721c0c207ULL);
1947a3f5d11SAllan Jude 	RNDr(S, W, 66, 0xeada7dd6cde0eb1eULL);
1957a3f5d11SAllan Jude 	RNDr(S, W, 67, 0xf57d4f7fee6ed178ULL);
1967a3f5d11SAllan Jude 	RNDr(S, W, 68, 0x06f067aa72176fbaULL);
1977a3f5d11SAllan Jude 	RNDr(S, W, 69, 0x0a637dc5a2c898a6ULL);
1987a3f5d11SAllan Jude 	RNDr(S, W, 70, 0x113f9804bef90daeULL);
1997a3f5d11SAllan Jude 	RNDr(S, W, 71, 0x1b710b35131c471bULL);
2007a3f5d11SAllan Jude 	RNDr(S, W, 72, 0x28db77f523047d84ULL);
2017a3f5d11SAllan Jude 	RNDr(S, W, 73, 0x32caab7b40c72493ULL);
2027a3f5d11SAllan Jude 	RNDr(S, W, 74, 0x3c9ebe0a15c9bebcULL);
2037a3f5d11SAllan Jude 	RNDr(S, W, 75, 0x431d67c49c100d4cULL);
2047a3f5d11SAllan Jude 	RNDr(S, W, 76, 0x4cc5d4becb3e42b6ULL);
2057a3f5d11SAllan Jude 	RNDr(S, W, 77, 0x597f299cfc657e2aULL);
2067a3f5d11SAllan Jude 	RNDr(S, W, 78, 0x5fcb6fab3ad6faecULL);
2077a3f5d11SAllan Jude 	RNDr(S, W, 79, 0x6c44198c4a475817ULL);
2087a3f5d11SAllan Jude 
2097a3f5d11SAllan Jude 	/* 4. Mix local working variables into global state */
2107a3f5d11SAllan Jude 	for (i = 0; i < 8; i++)
2117a3f5d11SAllan Jude 		state[i] += S[i];
2127a3f5d11SAllan Jude }
2137a3f5d11SAllan Jude 
2147a3f5d11SAllan Jude static unsigned char PAD[SHA512_BLOCK_LENGTH] = {
2157a3f5d11SAllan Jude 	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2167a3f5d11SAllan Jude 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2177a3f5d11SAllan Jude 	0, 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 };
2247a3f5d11SAllan Jude 
2257a3f5d11SAllan Jude /* Add padding and terminating bit-count. */
2267a3f5d11SAllan Jude static void
2277a3f5d11SAllan Jude SHA512_Pad(SHA512_CTX * ctx)
2287a3f5d11SAllan Jude {
2297a3f5d11SAllan Jude 	unsigned char len[16];
2307a3f5d11SAllan Jude 	uint64_t r, plen;
2317a3f5d11SAllan Jude 
2327a3f5d11SAllan Jude 	/*
2337a3f5d11SAllan Jude 	 * Convert length to a vector of bytes -- we do this now rather
2347a3f5d11SAllan Jude 	 * than later because the length will change after we pad.
2357a3f5d11SAllan Jude 	 */
2367a3f5d11SAllan Jude 	be64enc_vect(len, ctx->count, 16);
2377a3f5d11SAllan Jude 
2387a3f5d11SAllan Jude 	/* Add 1--128 bytes so that the resulting length is 112 mod 128 */
2397a3f5d11SAllan Jude 	r = (ctx->count[1] >> 3) & 0x7f;
2407a3f5d11SAllan Jude 	plen = (r < 112) ? (112 - r) : (240 - r);
2417a3f5d11SAllan Jude 	SHA512_Update(ctx, PAD, (size_t)plen);
2427a3f5d11SAllan Jude 
2437a3f5d11SAllan Jude 	/* Add the terminating bit-count */
2447a3f5d11SAllan Jude 	SHA512_Update(ctx, len, 16);
2457a3f5d11SAllan Jude }
2467a3f5d11SAllan Jude 
2477a3f5d11SAllan Jude /* SHA-512 initialization.  Begins a SHA-512 operation. */
2487a3f5d11SAllan Jude void
2497a3f5d11SAllan Jude SHA512_Init(SHA512_CTX * ctx)
2507a3f5d11SAllan Jude {
2517a3f5d11SAllan Jude 
2527a3f5d11SAllan Jude 	/* Zero bits processed so far */
2537a3f5d11SAllan Jude 	ctx->count[0] = ctx->count[1] = 0;
2547a3f5d11SAllan Jude 
2557a3f5d11SAllan Jude 	/* Magic initialization constants */
2567a3f5d11SAllan Jude 	ctx->state[0] = 0x6a09e667f3bcc908ULL;
2577a3f5d11SAllan Jude 	ctx->state[1] = 0xbb67ae8584caa73bULL;
2587a3f5d11SAllan Jude 	ctx->state[2] = 0x3c6ef372fe94f82bULL;
2597a3f5d11SAllan Jude 	ctx->state[3] = 0xa54ff53a5f1d36f1ULL;
2607a3f5d11SAllan Jude 	ctx->state[4] = 0x510e527fade682d1ULL;
2617a3f5d11SAllan Jude 	ctx->state[5] = 0x9b05688c2b3e6c1fULL;
2627a3f5d11SAllan Jude 	ctx->state[6] = 0x1f83d9abfb41bd6bULL;
2637a3f5d11SAllan Jude 	ctx->state[7] = 0x5be0cd19137e2179ULL;
2647a3f5d11SAllan Jude }
2657a3f5d11SAllan Jude 
2667a3f5d11SAllan Jude /* Add bytes into the hash */
2677a3f5d11SAllan Jude void
2687a3f5d11SAllan Jude SHA512_Update(SHA512_CTX * ctx, const void *in, size_t len)
2697a3f5d11SAllan Jude {
2707a3f5d11SAllan Jude 	uint64_t bitlen[2];
2717a3f5d11SAllan Jude 	uint64_t r;
2727a3f5d11SAllan Jude 	const unsigned char *src = in;
2737a3f5d11SAllan Jude 
2747a3f5d11SAllan Jude 	/* Number of bytes left in the buffer from previous updates */
2757a3f5d11SAllan Jude 	r = (ctx->count[1] >> 3) & 0x7f;
2767a3f5d11SAllan Jude 
2777a3f5d11SAllan Jude 	/* Convert the length into a number of bits */
2787a3f5d11SAllan Jude 	bitlen[1] = ((uint64_t)len) << 3;
2797a3f5d11SAllan Jude 	bitlen[0] = ((uint64_t)len) >> 61;
2807a3f5d11SAllan Jude 
2817a3f5d11SAllan Jude 	/* Update number of bits */
2827a3f5d11SAllan Jude 	if ((ctx->count[1] += bitlen[1]) < bitlen[1])
2837a3f5d11SAllan Jude 		ctx->count[0]++;
2847a3f5d11SAllan Jude 	ctx->count[0] += bitlen[0];
2857a3f5d11SAllan Jude 
2867a3f5d11SAllan Jude 	/* Handle the case where we don't need to perform any transforms */
2877a3f5d11SAllan Jude 	if (len < SHA512_BLOCK_LENGTH - r) {
2887a3f5d11SAllan Jude 		memcpy(&ctx->buf[r], src, len);
2897a3f5d11SAllan Jude 		return;
2907a3f5d11SAllan Jude 	}
2917a3f5d11SAllan Jude 
2927a3f5d11SAllan Jude 	/* Finish the current block */
2937a3f5d11SAllan Jude 	memcpy(&ctx->buf[r], src, SHA512_BLOCK_LENGTH - r);
2947a3f5d11SAllan Jude 	SHA512_Transform(ctx->state, ctx->buf);
2957a3f5d11SAllan Jude 	src += SHA512_BLOCK_LENGTH - r;
2967a3f5d11SAllan Jude 	len -= SHA512_BLOCK_LENGTH - r;
2977a3f5d11SAllan Jude 
2987a3f5d11SAllan Jude 	/* Perform complete blocks */
2997a3f5d11SAllan Jude 	while (len >= SHA512_BLOCK_LENGTH) {
3007a3f5d11SAllan Jude 		SHA512_Transform(ctx->state, src);
3017a3f5d11SAllan Jude 		src += SHA512_BLOCK_LENGTH;
3027a3f5d11SAllan Jude 		len -= SHA512_BLOCK_LENGTH;
3037a3f5d11SAllan Jude 	}
3047a3f5d11SAllan Jude 
3057a3f5d11SAllan Jude 	/* Copy left over data into buffer */
3067a3f5d11SAllan Jude 	memcpy(ctx->buf, src, len);
3077a3f5d11SAllan Jude }
3087a3f5d11SAllan Jude 
3097a3f5d11SAllan Jude /*
3107a3f5d11SAllan Jude  * SHA-512 finalization.  Pads the input data, exports the hash value,
3117a3f5d11SAllan Jude  * and clears the context state.
3127a3f5d11SAllan Jude  */
3137a3f5d11SAllan Jude void
314*571ebf76SConrad Meyer SHA512_Final(unsigned char digest[static SHA512_DIGEST_LENGTH], SHA512_CTX *ctx)
3157a3f5d11SAllan Jude {
3167a3f5d11SAllan Jude 
3177a3f5d11SAllan Jude 	/* Add padding */
3187a3f5d11SAllan Jude 	SHA512_Pad(ctx);
3197a3f5d11SAllan Jude 
3207a3f5d11SAllan Jude 	/* Write the hash */
3217a3f5d11SAllan Jude 	be64enc_vect(digest, ctx->state, SHA512_DIGEST_LENGTH);
3227a3f5d11SAllan Jude 
3237a3f5d11SAllan Jude 	/* Clear the context state */
324*571ebf76SConrad Meyer 	memset(ctx, 0, sizeof(*ctx));
3257a3f5d11SAllan Jude }
3267a3f5d11SAllan Jude 
3277a3f5d11SAllan Jude /*** SHA-384: *********************************************************/
3287a3f5d11SAllan Jude /*
3297a3f5d11SAllan Jude  * the SHA384 and SHA512 transforms are identical, so SHA384 is skipped
3307a3f5d11SAllan Jude  */
3317a3f5d11SAllan Jude 
3327a3f5d11SAllan Jude /* SHA-384 initialization.  Begins a SHA-384 operation. */
3337a3f5d11SAllan Jude void
3347a3f5d11SAllan Jude SHA384_Init(SHA384_CTX * ctx)
3357a3f5d11SAllan Jude {
3367a3f5d11SAllan Jude 
3377a3f5d11SAllan Jude 	/* Zero bits processed so far */
3387a3f5d11SAllan Jude 	ctx->count[0] = ctx->count[1] = 0;
3397a3f5d11SAllan Jude 
3407a3f5d11SAllan Jude 	/* Magic initialization constants */
3417a3f5d11SAllan Jude 	ctx->state[0] = 0xcbbb9d5dc1059ed8ULL;
3427a3f5d11SAllan Jude 	ctx->state[1] = 0x629a292a367cd507ULL;
3437a3f5d11SAllan Jude 	ctx->state[2] = 0x9159015a3070dd17ULL;
3447a3f5d11SAllan Jude 	ctx->state[3] = 0x152fecd8f70e5939ULL;
3457a3f5d11SAllan Jude 	ctx->state[4] = 0x67332667ffc00b31ULL;
3467a3f5d11SAllan Jude 	ctx->state[5] = 0x8eb44a8768581511ULL;
3477a3f5d11SAllan Jude 	ctx->state[6] = 0xdb0c2e0d64f98fa7ULL;
3487a3f5d11SAllan Jude 	ctx->state[7] = 0x47b5481dbefa4fa4ULL;
3497a3f5d11SAllan Jude }
3507a3f5d11SAllan Jude 
3517a3f5d11SAllan Jude /* Add bytes into the SHA-384 hash */
3527a3f5d11SAllan Jude void
3537a3f5d11SAllan Jude SHA384_Update(SHA384_CTX * ctx, const void *in, size_t len)
3547a3f5d11SAllan Jude {
3557a3f5d11SAllan Jude 
3567a3f5d11SAllan Jude 	SHA512_Update((SHA512_CTX *)ctx, in, len);
3577a3f5d11SAllan Jude }
3587a3f5d11SAllan Jude 
3597a3f5d11SAllan Jude /*
3607a3f5d11SAllan Jude  * SHA-384 finalization.  Pads the input data, exports the hash value,
3617a3f5d11SAllan Jude  * and clears the context state.
3627a3f5d11SAllan Jude  */
3637a3f5d11SAllan Jude void
364*571ebf76SConrad Meyer SHA384_Final(unsigned char digest[static SHA384_DIGEST_LENGTH], SHA384_CTX *ctx)
3657a3f5d11SAllan Jude {
3667a3f5d11SAllan Jude 
3677a3f5d11SAllan Jude 	/* Add padding */
3687a3f5d11SAllan Jude 	SHA512_Pad((SHA512_CTX *)ctx);
3697a3f5d11SAllan Jude 
3707a3f5d11SAllan Jude 	/* Write the hash */
3717a3f5d11SAllan Jude 	be64enc_vect(digest, ctx->state, SHA384_DIGEST_LENGTH);
3727a3f5d11SAllan Jude 
3737a3f5d11SAllan Jude 	/* Clear the context state */
374*571ebf76SConrad Meyer 	memset(ctx, 0, sizeof(*ctx));
3757a3f5d11SAllan Jude }
3767a3f5d11SAllan Jude 
3777a3f5d11SAllan Jude #ifdef WEAK_REFS
3787a3f5d11SAllan Jude /* When building libmd, provide weak references. Note: this is not
3797a3f5d11SAllan Jude    activated in the context of compiling these sources for internal
3807a3f5d11SAllan Jude    use in libcrypt.
3817a3f5d11SAllan Jude  */
3827a3f5d11SAllan Jude #undef SHA512_Init
3837a3f5d11SAllan Jude __weak_reference(_libmd_SHA512_Init, SHA512_Init);
3847a3f5d11SAllan Jude #undef SHA512_Update
3857a3f5d11SAllan Jude __weak_reference(_libmd_SHA512_Update, SHA512_Update);
3867a3f5d11SAllan Jude #undef SHA512_Final
3877a3f5d11SAllan Jude __weak_reference(_libmd_SHA512_Final, SHA512_Final);
3887a3f5d11SAllan Jude #undef SHA512_Transform
3897a3f5d11SAllan Jude __weak_reference(_libmd_SHA512_Transform, SHA512_Transform);
3907a3f5d11SAllan Jude 
3917a3f5d11SAllan Jude #undef SHA384_Init
3927a3f5d11SAllan Jude __weak_reference(_libmd_SHA384_Init, SHA384_Init);
3937a3f5d11SAllan Jude #undef SHA384_Update
3947a3f5d11SAllan Jude __weak_reference(_libmd_SHA384_Update, SHA384_Update);
3957a3f5d11SAllan Jude #undef SHA384_Final
3967a3f5d11SAllan Jude __weak_reference(_libmd_SHA384_Final, SHA384_Final);
3977a3f5d11SAllan Jude #endif
398