xref: /openbsd/lib/libcrypto/sha/sha512.c (revision 9cb04522)
1*9cb04522Stb /* $OpenBSD: sha512.c,v 1.42 2024/06/01 07:36:16 tb Exp $ */
25650a0e1Sdjm /* ====================================================================
3770e2486Sjsing  * Copyright (c) 1998-2011 The OpenSSL Project.  All rights reserved.
4770e2486Sjsing  *
5770e2486Sjsing  * Redistribution and use in source and binary forms, with or without
6770e2486Sjsing  * modification, are permitted provided that the following conditions
7770e2486Sjsing  * are met:
8770e2486Sjsing  *
9770e2486Sjsing  * 1. Redistributions of source code must retain the above copyright
10770e2486Sjsing  *    notice, this list of conditions and the following disclaimer.
11770e2486Sjsing  *
12770e2486Sjsing  * 2. Redistributions in binary form must reproduce the above copyright
13770e2486Sjsing  *    notice, this list of conditions and the following disclaimer in
14770e2486Sjsing  *    the documentation and/or other materials provided with the
15770e2486Sjsing  *    distribution.
16770e2486Sjsing  *
17770e2486Sjsing  * 3. All advertising materials mentioning features or use of this
18770e2486Sjsing  *    software must display the following acknowledgment:
19770e2486Sjsing  *    "This product includes software developed by the OpenSSL Project
20770e2486Sjsing  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
21770e2486Sjsing  *
22770e2486Sjsing  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23770e2486Sjsing  *    endorse or promote products derived from this software without
24770e2486Sjsing  *    prior written permission. For written permission, please contact
25770e2486Sjsing  *    openssl-core@openssl.org.
26770e2486Sjsing  *
27770e2486Sjsing  * 5. Products derived from this software may not be called "OpenSSL"
28770e2486Sjsing  *    nor may "OpenSSL" appear in their names without prior written
29770e2486Sjsing  *    permission of the OpenSSL Project.
30770e2486Sjsing  *
31770e2486Sjsing  * 6. Redistributions of any form whatsoever must retain the following
32770e2486Sjsing  *    acknowledgment:
33770e2486Sjsing  *    "This product includes software developed by the OpenSSL Project
34770e2486Sjsing  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
35770e2486Sjsing  *
36770e2486Sjsing  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37770e2486Sjsing  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38770e2486Sjsing  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39770e2486Sjsing  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
40770e2486Sjsing  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41770e2486Sjsing  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42770e2486Sjsing  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43770e2486Sjsing  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44770e2486Sjsing  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45770e2486Sjsing  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46770e2486Sjsing  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47770e2486Sjsing  * OF THE POSSIBILITY OF SUCH DAMAGE.
485650a0e1Sdjm  * ====================================================================
49770e2486Sjsing  *
50770e2486Sjsing  * This product includes cryptographic software written by Eric Young
51770e2486Sjsing  * (eay@cryptsoft.com).  This product includes software written by Tim
52770e2486Sjsing  * Hudson (tjh@cryptsoft.com).
535650a0e1Sdjm  */
548cf4d6a6Sjsing 
55b6c209beSbcook #include <endian.h>
568cf4d6a6Sjsing #include <stdlib.h>
578cf4d6a6Sjsing #include <string.h>
588cf4d6a6Sjsing 
595650a0e1Sdjm #include <openssl/opensslconf.h>
608cf4d6a6Sjsing 
61978a915aSjsing #include <openssl/crypto.h>
62978a915aSjsing #include <openssl/sha.h>
63978a915aSjsing 
64e1ee69a9Sjsing #include "crypto_internal.h"
658e9acae6Sjsing #include "sha_internal.h"
66e1ee69a9Sjsing 
675650a0e1Sdjm #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA512)
685650a0e1Sdjm 
69a255a78fSjsing /* Ensure that SHA_LONG64 and uint64_t are equivalent. */
70825d9bb4Sjsing CTASSERT(sizeof(SHA_LONG64) == sizeof(uint64_t));
715650a0e1Sdjm 
72802c7807Sjsing #ifdef SHA512_ASM
735650a0e1Sdjm void sha512_block_data_order(SHA512_CTX *ctx, const void *in, size_t num);
74802c7807Sjsing #endif
755650a0e1Sdjm 
765650a0e1Sdjm #ifndef SHA512_ASM
775650a0e1Sdjm static const SHA_LONG64 K512[80] = {
785650a0e1Sdjm 	U64(0x428a2f98d728ae22), U64(0x7137449123ef65cd),
795650a0e1Sdjm 	U64(0xb5c0fbcfec4d3b2f), U64(0xe9b5dba58189dbbc),
805650a0e1Sdjm 	U64(0x3956c25bf348b538), U64(0x59f111f1b605d019),
815650a0e1Sdjm 	U64(0x923f82a4af194f9b), U64(0xab1c5ed5da6d8118),
825650a0e1Sdjm 	U64(0xd807aa98a3030242), U64(0x12835b0145706fbe),
835650a0e1Sdjm 	U64(0x243185be4ee4b28c), U64(0x550c7dc3d5ffb4e2),
845650a0e1Sdjm 	U64(0x72be5d74f27b896f), U64(0x80deb1fe3b1696b1),
855650a0e1Sdjm 	U64(0x9bdc06a725c71235), U64(0xc19bf174cf692694),
865650a0e1Sdjm 	U64(0xe49b69c19ef14ad2), U64(0xefbe4786384f25e3),
875650a0e1Sdjm 	U64(0x0fc19dc68b8cd5b5), U64(0x240ca1cc77ac9c65),
885650a0e1Sdjm 	U64(0x2de92c6f592b0275), U64(0x4a7484aa6ea6e483),
895650a0e1Sdjm 	U64(0x5cb0a9dcbd41fbd4), U64(0x76f988da831153b5),
905650a0e1Sdjm 	U64(0x983e5152ee66dfab), U64(0xa831c66d2db43210),
915650a0e1Sdjm 	U64(0xb00327c898fb213f), U64(0xbf597fc7beef0ee4),
925650a0e1Sdjm 	U64(0xc6e00bf33da88fc2), U64(0xd5a79147930aa725),
935650a0e1Sdjm 	U64(0x06ca6351e003826f), U64(0x142929670a0e6e70),
945650a0e1Sdjm 	U64(0x27b70a8546d22ffc), U64(0x2e1b21385c26c926),
955650a0e1Sdjm 	U64(0x4d2c6dfc5ac42aed), U64(0x53380d139d95b3df),
965650a0e1Sdjm 	U64(0x650a73548baf63de), U64(0x766a0abb3c77b2a8),
975650a0e1Sdjm 	U64(0x81c2c92e47edaee6), U64(0x92722c851482353b),
985650a0e1Sdjm 	U64(0xa2bfe8a14cf10364), U64(0xa81a664bbc423001),
995650a0e1Sdjm 	U64(0xc24b8b70d0f89791), U64(0xc76c51a30654be30),
1005650a0e1Sdjm 	U64(0xd192e819d6ef5218), U64(0xd69906245565a910),
1015650a0e1Sdjm 	U64(0xf40e35855771202a), U64(0x106aa07032bbd1b8),
1025650a0e1Sdjm 	U64(0x19a4c116b8d2d0c8), U64(0x1e376c085141ab53),
1035650a0e1Sdjm 	U64(0x2748774cdf8eeb99), U64(0x34b0bcb5e19b48a8),
1045650a0e1Sdjm 	U64(0x391c0cb3c5c95a63), U64(0x4ed8aa4ae3418acb),
1055650a0e1Sdjm 	U64(0x5b9cca4f7763e373), U64(0x682e6ff3d6b2b8a3),
1065650a0e1Sdjm 	U64(0x748f82ee5defb2fc), U64(0x78a5636f43172f60),
1075650a0e1Sdjm 	U64(0x84c87814a1f0ab72), U64(0x8cc702081a6439ec),
1085650a0e1Sdjm 	U64(0x90befffa23631e28), U64(0xa4506cebde82bde9),
1095650a0e1Sdjm 	U64(0xbef9a3f7b2c67915), U64(0xc67178f2e372532b),
1105650a0e1Sdjm 	U64(0xca273eceea26619c), U64(0xd186b8c721c0c207),
1115650a0e1Sdjm 	U64(0xeada7dd6cde0eb1e), U64(0xf57d4f7fee6ed178),
1125650a0e1Sdjm 	U64(0x06f067aa72176fba), U64(0x0a637dc5a2c898a6),
1135650a0e1Sdjm 	U64(0x113f9804bef90dae), U64(0x1b710b35131c471b),
1145650a0e1Sdjm 	U64(0x28db77f523047d84), U64(0x32caab7b40c72493),
1155650a0e1Sdjm 	U64(0x3c9ebe0a15c9bebc), U64(0x431d67c49c100d4c),
1165650a0e1Sdjm 	U64(0x4cc5d4becb3e42b6), U64(0x597f299cfc657e2a),
11799570d72Sjsing 	U64(0x5fcb6fab3ad6faec), U64(0x6c44198c4a475817),
11899570d72Sjsing };
1195650a0e1Sdjm 
120a255a78fSjsing static inline SHA_LONG64
Sigma0(SHA_LONG64 x)121a255a78fSjsing Sigma0(SHA_LONG64 x)
122a255a78fSjsing {
123a255a78fSjsing 	return crypto_ror_u64(x, 28) ^ crypto_ror_u64(x, 34) ^
124a255a78fSjsing 	    crypto_ror_u64(x, 39);
125a255a78fSjsing }
1265650a0e1Sdjm 
127a255a78fSjsing static inline SHA_LONG64
Sigma1(SHA_LONG64 x)128a255a78fSjsing Sigma1(SHA_LONG64 x)
129a255a78fSjsing {
130a255a78fSjsing 	return crypto_ror_u64(x, 14) ^ crypto_ror_u64(x, 18) ^
131a255a78fSjsing 	    crypto_ror_u64(x, 41);
132a255a78fSjsing }
1335650a0e1Sdjm 
134a255a78fSjsing static inline SHA_LONG64
sigma0(SHA_LONG64 x)135a255a78fSjsing sigma0(SHA_LONG64 x)
136a255a78fSjsing {
137a255a78fSjsing 	return crypto_ror_u64(x, 1) ^ crypto_ror_u64(x, 8) ^ (x >> 7);
138a255a78fSjsing }
1395650a0e1Sdjm 
140a255a78fSjsing static inline SHA_LONG64
sigma1(SHA_LONG64 x)141a255a78fSjsing sigma1(SHA_LONG64 x)
142a255a78fSjsing {
143a255a78fSjsing 	return crypto_ror_u64(x, 19) ^ crypto_ror_u64(x, 61) ^ (x >> 6);
144a255a78fSjsing }
1455650a0e1Sdjm 
146a255a78fSjsing static inline SHA_LONG64
Ch(SHA_LONG64 x,SHA_LONG64 y,SHA_LONG64 z)147a255a78fSjsing Ch(SHA_LONG64 x, SHA_LONG64 y, SHA_LONG64 z)
148a255a78fSjsing {
149a255a78fSjsing 	return (x & y) ^ (~x & z);
150a255a78fSjsing }
151a255a78fSjsing 
152a255a78fSjsing static inline SHA_LONG64
Maj(SHA_LONG64 x,SHA_LONG64 y,SHA_LONG64 z)153a255a78fSjsing Maj(SHA_LONG64 x, SHA_LONG64 y, SHA_LONG64 z)
154a255a78fSjsing {
155a255a78fSjsing 	return (x & y) ^ (x & z) ^ (y & z);
156a255a78fSjsing }
157a255a78fSjsing 
158a255a78fSjsing static inline void
sha512_msg_schedule_update(SHA_LONG64 * W0,SHA_LONG64 W1,SHA_LONG64 W9,SHA_LONG64 W14)159a255a78fSjsing sha512_msg_schedule_update(SHA_LONG64 *W0, SHA_LONG64 W1,
160a255a78fSjsing     SHA_LONG64 W9, SHA_LONG64 W14)
161a255a78fSjsing {
162a255a78fSjsing 	*W0 = sigma1(W14) + W9 + sigma0(W1) + *W0;
163a255a78fSjsing }
164a255a78fSjsing 
165a255a78fSjsing static inline void
sha512_round(SHA_LONG64 * a,SHA_LONG64 * b,SHA_LONG64 * c,SHA_LONG64 * d,SHA_LONG64 * e,SHA_LONG64 * f,SHA_LONG64 * g,SHA_LONG64 * h,SHA_LONG64 Kt,SHA_LONG64 Wt)166a255a78fSjsing sha512_round(SHA_LONG64 *a, SHA_LONG64 *b, SHA_LONG64 *c, SHA_LONG64 *d,
167a255a78fSjsing     SHA_LONG64 *e, SHA_LONG64 *f, SHA_LONG64 *g, SHA_LONG64 *h,
168a255a78fSjsing     SHA_LONG64 Kt, SHA_LONG64 Wt)
169a255a78fSjsing {
170a255a78fSjsing 	SHA_LONG64 T1, T2;
171a255a78fSjsing 
172a255a78fSjsing 	T1 = *h + Sigma1(*e) + Ch(*e, *f, *g) + Kt + Wt;
173a255a78fSjsing 	T2 = Sigma0(*a) + Maj(*a, *b, *c);
174a255a78fSjsing 
175a255a78fSjsing 	*h = *g;
176a255a78fSjsing 	*g = *f;
177a255a78fSjsing 	*f = *e;
178a255a78fSjsing 	*e = *d + T1;
179a255a78fSjsing 	*d = *c;
180a255a78fSjsing 	*c = *b;
181a255a78fSjsing 	*b = *a;
182a255a78fSjsing 	*a = T1 + T2;
183a255a78fSjsing }
1845650a0e1Sdjm 
18599570d72Sjsing static void
sha512_block_data_order(SHA512_CTX * ctx,const void * _in,size_t num)186c7cae210Sjsing sha512_block_data_order(SHA512_CTX *ctx, const void *_in, size_t num)
1875650a0e1Sdjm {
188825d9bb4Sjsing 	const uint8_t *in = _in;
189825d9bb4Sjsing 	const SHA_LONG64 *in64;
190a255a78fSjsing 	SHA_LONG64 a, b, c, d, e, f, g, h;
1915650a0e1Sdjm 	SHA_LONG64 X[16];
1925650a0e1Sdjm 	int i;
1935650a0e1Sdjm 
1945650a0e1Sdjm 	while (num--) {
19599570d72Sjsing 		a = ctx->h[0];
19699570d72Sjsing 		b = ctx->h[1];
19799570d72Sjsing 		c = ctx->h[2];
19899570d72Sjsing 		d = ctx->h[3];
19999570d72Sjsing 		e = ctx->h[4];
20099570d72Sjsing 		f = ctx->h[5];
20199570d72Sjsing 		g = ctx->h[6];
20299570d72Sjsing 		h = ctx->h[7];
2035650a0e1Sdjm 
204825d9bb4Sjsing 		if ((size_t)in % sizeof(SHA_LONG64) == 0) {
205825d9bb4Sjsing 			/* Input is 64 bit aligned. */
206825d9bb4Sjsing 			in64 = (const SHA_LONG64 *)in;
207825d9bb4Sjsing 			X[0] = be64toh(in64[0]);
208825d9bb4Sjsing 			X[1] = be64toh(in64[1]);
209825d9bb4Sjsing 			X[2] = be64toh(in64[2]);
210825d9bb4Sjsing 			X[3] = be64toh(in64[3]);
211825d9bb4Sjsing 			X[4] = be64toh(in64[4]);
212825d9bb4Sjsing 			X[5] = be64toh(in64[5]);
213825d9bb4Sjsing 			X[6] = be64toh(in64[6]);
214825d9bb4Sjsing 			X[7] = be64toh(in64[7]);
215825d9bb4Sjsing 			X[8] = be64toh(in64[8]);
216825d9bb4Sjsing 			X[9] = be64toh(in64[9]);
217825d9bb4Sjsing 			X[10] = be64toh(in64[10]);
218825d9bb4Sjsing 			X[11] = be64toh(in64[11]);
219825d9bb4Sjsing 			X[12] = be64toh(in64[12]);
220825d9bb4Sjsing 			X[13] = be64toh(in64[13]);
221825d9bb4Sjsing 			X[14] = be64toh(in64[14]);
222825d9bb4Sjsing 			X[15] = be64toh(in64[15]);
223825d9bb4Sjsing 		} else {
224825d9bb4Sjsing 			/* Input is not 64 bit aligned. */
225825d9bb4Sjsing 			X[0] = crypto_load_be64toh(&in[0 * 8]);
226825d9bb4Sjsing 			X[1] = crypto_load_be64toh(&in[1 * 8]);
227825d9bb4Sjsing 			X[2] = crypto_load_be64toh(&in[2 * 8]);
228825d9bb4Sjsing 			X[3] = crypto_load_be64toh(&in[3 * 8]);
229825d9bb4Sjsing 			X[4] = crypto_load_be64toh(&in[4 * 8]);
230825d9bb4Sjsing 			X[5] = crypto_load_be64toh(&in[5 * 8]);
231825d9bb4Sjsing 			X[6] = crypto_load_be64toh(&in[6 * 8]);
232825d9bb4Sjsing 			X[7] = crypto_load_be64toh(&in[7 * 8]);
233825d9bb4Sjsing 			X[8] = crypto_load_be64toh(&in[8 * 8]);
234825d9bb4Sjsing 			X[9] = crypto_load_be64toh(&in[9 * 8]);
235825d9bb4Sjsing 			X[10] = crypto_load_be64toh(&in[10 * 8]);
236825d9bb4Sjsing 			X[11] = crypto_load_be64toh(&in[11 * 8]);
237825d9bb4Sjsing 			X[12] = crypto_load_be64toh(&in[12 * 8]);
238825d9bb4Sjsing 			X[13] = crypto_load_be64toh(&in[13 * 8]);
239825d9bb4Sjsing 			X[14] = crypto_load_be64toh(&in[14 * 8]);
240825d9bb4Sjsing 			X[15] = crypto_load_be64toh(&in[15 * 8]);
241825d9bb4Sjsing 		}
242825d9bb4Sjsing 		in += SHA512_CBLOCK;
243825d9bb4Sjsing 
244a255a78fSjsing 		sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[0], X[0]);
245a255a78fSjsing 		sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[1], X[1]);
246a255a78fSjsing 		sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[2], X[2]);
247a255a78fSjsing 		sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[3], X[3]);
248a255a78fSjsing 		sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[4], X[4]);
249a255a78fSjsing 		sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[5], X[5]);
250a255a78fSjsing 		sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[6], X[6]);
251a255a78fSjsing 		sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[7], X[7]);
252a255a78fSjsing 		sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[8], X[8]);
253a255a78fSjsing 		sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[9], X[9]);
254a255a78fSjsing 		sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[10], X[10]);
255a255a78fSjsing 		sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[11], X[11]);
256a255a78fSjsing 		sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[12], X[12]);
257a255a78fSjsing 		sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[13], X[13]);
258a255a78fSjsing 		sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[14], X[14]);
259a255a78fSjsing 		sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[15], X[15]);
2605650a0e1Sdjm 
26199570d72Sjsing 		for (i = 16; i < 80; i += 16) {
262a255a78fSjsing 			sha512_msg_schedule_update(&X[0], X[1], X[9], X[14]);
263a255a78fSjsing 			sha512_msg_schedule_update(&X[1], X[2], X[10], X[15]);
264a255a78fSjsing 			sha512_msg_schedule_update(&X[2], X[3], X[11], X[0]);
265a255a78fSjsing 			sha512_msg_schedule_update(&X[3], X[4], X[12], X[1]);
266a255a78fSjsing 			sha512_msg_schedule_update(&X[4], X[5], X[13], X[2]);
267a255a78fSjsing 			sha512_msg_schedule_update(&X[5], X[6], X[14], X[3]);
268a255a78fSjsing 			sha512_msg_schedule_update(&X[6], X[7], X[15], X[4]);
269a255a78fSjsing 			sha512_msg_schedule_update(&X[7], X[8], X[0], X[5]);
270a255a78fSjsing 			sha512_msg_schedule_update(&X[8], X[9], X[1], X[6]);
271a255a78fSjsing 			sha512_msg_schedule_update(&X[9], X[10], X[2], X[7]);
272a255a78fSjsing 			sha512_msg_schedule_update(&X[10], X[11], X[3], X[8]);
273a255a78fSjsing 			sha512_msg_schedule_update(&X[11], X[12], X[4], X[9]);
274a255a78fSjsing 			sha512_msg_schedule_update(&X[12], X[13], X[5], X[10]);
275a255a78fSjsing 			sha512_msg_schedule_update(&X[13], X[14], X[6], X[11]);
276a255a78fSjsing 			sha512_msg_schedule_update(&X[14], X[15], X[7], X[12]);
277a255a78fSjsing 			sha512_msg_schedule_update(&X[15], X[0], X[8], X[13]);
278a255a78fSjsing 
279a255a78fSjsing 			sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 0], X[0]);
280a255a78fSjsing 			sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 1], X[1]);
281a255a78fSjsing 			sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 2], X[2]);
282a255a78fSjsing 			sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 3], X[3]);
283a255a78fSjsing 			sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 4], X[4]);
284a255a78fSjsing 			sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 5], X[5]);
285a255a78fSjsing 			sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 6], X[6]);
286a255a78fSjsing 			sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 7], X[7]);
287a255a78fSjsing 			sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 8], X[8]);
288a255a78fSjsing 			sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 9], X[9]);
289a255a78fSjsing 			sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 10], X[10]);
290a255a78fSjsing 			sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 11], X[11]);
291a255a78fSjsing 			sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 12], X[12]);
292a255a78fSjsing 			sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 13], X[13]);
293a255a78fSjsing 			sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 14], X[14]);
294a255a78fSjsing 			sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 15], X[15]);
2955650a0e1Sdjm 		}
2965650a0e1Sdjm 
29799570d72Sjsing 		ctx->h[0] += a;
29899570d72Sjsing 		ctx->h[1] += b;
29999570d72Sjsing 		ctx->h[2] += c;
30099570d72Sjsing 		ctx->h[3] += d;
30199570d72Sjsing 		ctx->h[4] += e;
30299570d72Sjsing 		ctx->h[5] += f;
30399570d72Sjsing 		ctx->h[6] += g;
30499570d72Sjsing 		ctx->h[7] += h;
3055650a0e1Sdjm 	}
3065650a0e1Sdjm }
3075650a0e1Sdjm 
3085650a0e1Sdjm #endif /* SHA512_ASM */
3095650a0e1Sdjm 
3108f831773Sjsing int
SHA384_Init(SHA512_CTX * c)3118f831773Sjsing SHA384_Init(SHA512_CTX *c)
3128f831773Sjsing {
313e9f61643Sjsing 	memset(c, 0, sizeof(*c));
314e9f61643Sjsing 
3158f831773Sjsing 	c->h[0] = U64(0xcbbb9d5dc1059ed8);
3168f831773Sjsing 	c->h[1] = U64(0x629a292a367cd507);
3178f831773Sjsing 	c->h[2] = U64(0x9159015a3070dd17);
3188f831773Sjsing 	c->h[3] = U64(0x152fecd8f70e5939);
3198f831773Sjsing 	c->h[4] = U64(0x67332667ffc00b31);
3208f831773Sjsing 	c->h[5] = U64(0x8eb44a8768581511);
3218f831773Sjsing 	c->h[6] = U64(0xdb0c2e0d64f98fa7);
3228f831773Sjsing 	c->h[7] = U64(0x47b5481dbefa4fa4);
3238f831773Sjsing 
3248f831773Sjsing 	c->md_len = SHA384_DIGEST_LENGTH;
325e9f61643Sjsing 
3268f831773Sjsing 	return 1;
3278f831773Sjsing }
32865be244dSbeck LCRYPTO_ALIAS(SHA384_Init);
3298f831773Sjsing 
3308f831773Sjsing int
SHA384_Update(SHA512_CTX * c,const void * data,size_t len)3318f831773Sjsing SHA384_Update(SHA512_CTX *c, const void *data, size_t len)
3328f831773Sjsing {
3338f831773Sjsing 	return SHA512_Update(c, data, len);
3348f831773Sjsing }
33565be244dSbeck LCRYPTO_ALIAS(SHA384_Update);
3368f831773Sjsing 
3378f831773Sjsing int
SHA384_Final(unsigned char * md,SHA512_CTX * c)3388f831773Sjsing SHA384_Final(unsigned char *md, SHA512_CTX *c)
3398f831773Sjsing {
3408f831773Sjsing 	return SHA512_Final(md, c);
3418f831773Sjsing }
34265be244dSbeck LCRYPTO_ALIAS(SHA384_Final);
3438f831773Sjsing 
3448f831773Sjsing unsigned char *
SHA384(const unsigned char * d,size_t n,unsigned char * md)3458f831773Sjsing SHA384(const unsigned char *d, size_t n, unsigned char *md)
3468f831773Sjsing {
3478f831773Sjsing 	SHA512_CTX c;
3488f831773Sjsing 
3498f831773Sjsing 	SHA384_Init(&c);
3508f831773Sjsing 	SHA512_Update(&c, d, n);
3518f831773Sjsing 	SHA512_Final(md, &c);
3528f831773Sjsing 
3538f831773Sjsing 	explicit_bzero(&c, sizeof(c));
3548f831773Sjsing 
3558f831773Sjsing 	return (md);
3568f831773Sjsing }
35765be244dSbeck LCRYPTO_ALIAS(SHA384);
3588f831773Sjsing 
3598f831773Sjsing int
SHA512_Init(SHA512_CTX * c)3608f831773Sjsing SHA512_Init(SHA512_CTX *c)
3618f831773Sjsing {
362e9f61643Sjsing 	memset(c, 0, sizeof(*c));
363e9f61643Sjsing 
3648f831773Sjsing 	c->h[0] = U64(0x6a09e667f3bcc908);
3658f831773Sjsing 	c->h[1] = U64(0xbb67ae8584caa73b);
3668f831773Sjsing 	c->h[2] = U64(0x3c6ef372fe94f82b);
3678f831773Sjsing 	c->h[3] = U64(0xa54ff53a5f1d36f1);
3688f831773Sjsing 	c->h[4] = U64(0x510e527fade682d1);
3698f831773Sjsing 	c->h[5] = U64(0x9b05688c2b3e6c1f);
3708f831773Sjsing 	c->h[6] = U64(0x1f83d9abfb41bd6b);
3718f831773Sjsing 	c->h[7] = U64(0x5be0cd19137e2179);
3728f831773Sjsing 
3738f831773Sjsing 	c->md_len = SHA512_DIGEST_LENGTH;
374e9f61643Sjsing 
3758f831773Sjsing 	return 1;
3768f831773Sjsing }
37765be244dSbeck LCRYPTO_ALIAS(SHA512_Init);
3788f831773Sjsing 
3798f831773Sjsing void
SHA512_Transform(SHA512_CTX * c,const unsigned char * data)3808f831773Sjsing SHA512_Transform(SHA512_CTX *c, const unsigned char *data)
3818f831773Sjsing {
3828f831773Sjsing 	sha512_block_data_order(c, data, 1);
3838f831773Sjsing }
38465be244dSbeck LCRYPTO_ALIAS(SHA512_Transform);
3858f831773Sjsing 
3868f831773Sjsing int
SHA512_Update(SHA512_CTX * c,const void * _data,size_t len)3878f831773Sjsing SHA512_Update(SHA512_CTX *c, const void *_data, size_t len)
3888f831773Sjsing {
389825d9bb4Sjsing 	const unsigned char *data = _data;
3903c6df8cfSderaadt 	unsigned char *p = c->u.p;
391825d9bb4Sjsing 	SHA_LONG64 l;
3928f831773Sjsing 
3938f831773Sjsing 	if (len == 0)
3948f831773Sjsing 		return 1;
3958f831773Sjsing 
3968f831773Sjsing 	l = (c->Nl + (((SHA_LONG64)len) << 3))&U64(0xffffffffffffffff);
3978f831773Sjsing 	if (l < c->Nl)
3988f831773Sjsing 		c->Nh++;
3998f831773Sjsing 	if (sizeof(len) >= 8)
4008f831773Sjsing 		c->Nh += (((SHA_LONG64)len) >> 61);
4018f831773Sjsing 	c->Nl = l;
4028f831773Sjsing 
4038f831773Sjsing 	if (c->num != 0) {
4048f831773Sjsing 		size_t n = sizeof(c->u) - c->num;
4058f831773Sjsing 
4068f831773Sjsing 		if (len < n) {
4078f831773Sjsing 			memcpy(p + c->num, data, len);
4088f831773Sjsing 			c->num += (unsigned int)len;
4098f831773Sjsing 			return 1;
4108f831773Sjsing 		} else{
4118f831773Sjsing 			memcpy(p + c->num, data, n);
4128f831773Sjsing 			c->num = 0;
4138f831773Sjsing 			len -= n;
4148f831773Sjsing 			data += n;
4158f831773Sjsing 			sha512_block_data_order(c, p, 1);
4168f831773Sjsing 		}
4178f831773Sjsing 	}
4188f831773Sjsing 
4198f831773Sjsing 	if (len >= sizeof(c->u)) {
4208f831773Sjsing 		sha512_block_data_order(c, data, len/sizeof(c->u));
4218f831773Sjsing 		data += len;
4228f831773Sjsing 		len %= sizeof(c->u);
4238f831773Sjsing 		data -= len;
4248f831773Sjsing 	}
4258f831773Sjsing 
4268f831773Sjsing 	if (len != 0) {
4278f831773Sjsing 		memcpy(p, data, len);
4288f831773Sjsing 		c->num = (int)len;
4298f831773Sjsing 	}
4308f831773Sjsing 
4318f831773Sjsing 	return 1;
4328f831773Sjsing }
43365be244dSbeck LCRYPTO_ALIAS(SHA512_Update);
4348f831773Sjsing 
4358f831773Sjsing int
SHA512_Final(unsigned char * md,SHA512_CTX * c)4368f831773Sjsing SHA512_Final(unsigned char *md, SHA512_CTX *c)
4378f831773Sjsing {
4388f831773Sjsing 	unsigned char *p = (unsigned char *)c->u.p;
4398f831773Sjsing 	size_t n = c->num;
4408f831773Sjsing 
4418f831773Sjsing 	p[n]=0x80;	/* There always is a room for one */
4428f831773Sjsing 	n++;
4438f831773Sjsing 	if (n > (sizeof(c->u) - 16)) {
4448f831773Sjsing 		memset(p + n, 0, sizeof(c->u) - n);
4458f831773Sjsing 		n = 0;
4468f831773Sjsing 		sha512_block_data_order(c, p, 1);
4478f831773Sjsing 	}
4488f831773Sjsing 
4498f831773Sjsing 	memset(p + n, 0, sizeof(c->u) - 16 - n);
450bfe1061bStb 	c->u.d[SHA_LBLOCK - 2] = htobe64(c->Nh);
451bfe1061bStb 	c->u.d[SHA_LBLOCK - 1] = htobe64(c->Nl);
4528f831773Sjsing 
4538f831773Sjsing 	sha512_block_data_order(c, p, 1);
4548f831773Sjsing 
455e1ee69a9Sjsing 	if (md == NULL)
4568f831773Sjsing 		return 0;
4578f831773Sjsing 
4588f831773Sjsing 	/* Let compiler decide if it's appropriate to unroll... */
459e1ee69a9Sjsing 	switch (c->md_len) {
4608e9acae6Sjsing 	case SHA512_224_DIGEST_LENGTH:
4618e9acae6Sjsing 		for (n = 0; n < SHA512_224_DIGEST_LENGTH/8; n++) {
4628e9acae6Sjsing 			crypto_store_htobe64(md, c->h[n]);
4638e9acae6Sjsing 			md += 8;
4648e9acae6Sjsing 		}
4658e9acae6Sjsing 		crypto_store_htobe32(md, c->h[n] >> 32);
4668e9acae6Sjsing 		break;
4678e9acae6Sjsing 	case SHA512_256_DIGEST_LENGTH:
4688e9acae6Sjsing 		for (n = 0; n < SHA512_256_DIGEST_LENGTH/8; n++) {
4698e9acae6Sjsing 			crypto_store_htobe64(md, c->h[n]);
4708e9acae6Sjsing 			md += 8;
4718e9acae6Sjsing 		}
4728e9acae6Sjsing 		break;
4738f831773Sjsing 	case SHA384_DIGEST_LENGTH:
4748f831773Sjsing 		for (n = 0; n < SHA384_DIGEST_LENGTH/8; n++) {
475e1ee69a9Sjsing 			crypto_store_htobe64(md, c->h[n]);
476e1ee69a9Sjsing 			md += 8;
4778f831773Sjsing 		}
4788f831773Sjsing 		break;
4798f831773Sjsing 	case SHA512_DIGEST_LENGTH:
4808f831773Sjsing 		for (n = 0; n < SHA512_DIGEST_LENGTH/8; n++) {
481e1ee69a9Sjsing 			crypto_store_htobe64(md, c->h[n]);
482e1ee69a9Sjsing 			md += 8;
4838f831773Sjsing 		}
4848f831773Sjsing 		break;
4858f831773Sjsing 	default:
4868f831773Sjsing 		return 0;
4878f831773Sjsing 	}
4888f831773Sjsing 
4898f831773Sjsing 	return 1;
4908f831773Sjsing }
49165be244dSbeck LCRYPTO_ALIAS(SHA512_Final);
4928f831773Sjsing 
4938f831773Sjsing unsigned char *
SHA512(const unsigned char * d,size_t n,unsigned char * md)4948f831773Sjsing SHA512(const unsigned char *d, size_t n, unsigned char *md)
4958f831773Sjsing {
4968f831773Sjsing 	SHA512_CTX c;
4978f831773Sjsing 
4988f831773Sjsing 	SHA512_Init(&c);
4998f831773Sjsing 	SHA512_Update(&c, d, n);
5008f831773Sjsing 	SHA512_Final(md, &c);
5018f831773Sjsing 
5028f831773Sjsing 	explicit_bzero(&c, sizeof(c));
5038f831773Sjsing 
5048f831773Sjsing 	return (md);
5058f831773Sjsing }
50665be244dSbeck LCRYPTO_ALIAS(SHA512);
5078f831773Sjsing 
5088e9acae6Sjsing int
SHA512_224_Init(SHA512_CTX * c)5098e9acae6Sjsing SHA512_224_Init(SHA512_CTX *c)
5108e9acae6Sjsing {
5118e9acae6Sjsing 	memset(c, 0, sizeof(*c));
5128e9acae6Sjsing 
5138e9acae6Sjsing 	/* FIPS 180-4 section 5.3.6.1. */
5148e9acae6Sjsing 	c->h[0] = U64(0x8c3d37c819544da2);
5158e9acae6Sjsing 	c->h[1] = U64(0x73e1996689dcd4d6);
5168e9acae6Sjsing 	c->h[2] = U64(0x1dfab7ae32ff9c82);
5178e9acae6Sjsing 	c->h[3] = U64(0x679dd514582f9fcf);
5188e9acae6Sjsing 	c->h[4] = U64(0x0f6d2b697bd44da8);
5198e9acae6Sjsing 	c->h[5] = U64(0x77e36f7304c48942);
5208e9acae6Sjsing 	c->h[6] = U64(0x3f9d85a86a1d36c8);
5218e9acae6Sjsing 	c->h[7] = U64(0x1112e6ad91d692a1);
5228e9acae6Sjsing 
5238e9acae6Sjsing 	c->md_len = SHA512_224_DIGEST_LENGTH;
5248e9acae6Sjsing 
5258e9acae6Sjsing 	return 1;
5268e9acae6Sjsing }
5278e9acae6Sjsing 
5288e9acae6Sjsing int
SHA512_224_Update(SHA512_CTX * c,const void * data,size_t len)5298e9acae6Sjsing SHA512_224_Update(SHA512_CTX *c, const void *data, size_t len)
5308e9acae6Sjsing {
5318e9acae6Sjsing 	return SHA512_Update(c, data, len);
5328e9acae6Sjsing }
5338e9acae6Sjsing 
5348e9acae6Sjsing int
SHA512_224_Final(unsigned char * md,SHA512_CTX * c)5358e9acae6Sjsing SHA512_224_Final(unsigned char *md, SHA512_CTX *c)
5368e9acae6Sjsing {
5378e9acae6Sjsing 	return SHA512_Final(md, c);
5388e9acae6Sjsing }
5398e9acae6Sjsing 
5408e9acae6Sjsing int
SHA512_256_Init(SHA512_CTX * c)5418e9acae6Sjsing SHA512_256_Init(SHA512_CTX *c)
5428e9acae6Sjsing {
5438e9acae6Sjsing 	memset(c, 0, sizeof(*c));
5448e9acae6Sjsing 
5458e9acae6Sjsing 	/* FIPS 180-4 section 5.3.6.2. */
5468e9acae6Sjsing 	c->h[0] = U64(0x22312194fc2bf72c);
5478e9acae6Sjsing 	c->h[1] = U64(0x9f555fa3c84c64c2);
5488e9acae6Sjsing 	c->h[2] = U64(0x2393b86b6f53b151);
5498e9acae6Sjsing 	c->h[3] = U64(0x963877195940eabd);
5508e9acae6Sjsing 	c->h[4] = U64(0x96283ee2a88effe3);
5518e9acae6Sjsing 	c->h[5] = U64(0xbe5e1e2553863992);
5528e9acae6Sjsing 	c->h[6] = U64(0x2b0199fc2c85b8aa);
5538e9acae6Sjsing 	c->h[7] = U64(0x0eb72ddc81c52ca2);
5548e9acae6Sjsing 
5558e9acae6Sjsing 	c->md_len = SHA512_256_DIGEST_LENGTH;
5568e9acae6Sjsing 
5578e9acae6Sjsing 	return 1;
5588e9acae6Sjsing }
5598e9acae6Sjsing 
5608e9acae6Sjsing int
SHA512_256_Update(SHA512_CTX * c,const void * data,size_t len)5618e9acae6Sjsing SHA512_256_Update(SHA512_CTX *c, const void *data, size_t len)
5628e9acae6Sjsing {
5638e9acae6Sjsing 	return SHA512_Update(c, data, len);
5648e9acae6Sjsing }
5658e9acae6Sjsing 
5668e9acae6Sjsing int
SHA512_256_Final(unsigned char * md,SHA512_CTX * c)5678e9acae6Sjsing SHA512_256_Final(unsigned char *md, SHA512_CTX *c)
5688e9acae6Sjsing {
5698e9acae6Sjsing 	return SHA512_Final(md, c);
5708e9acae6Sjsing }
5718e9acae6Sjsing 
572f1535dc8Sdjm #endif /* !OPENSSL_NO_SHA512 */
573