xref: /openbsd/lib/libcrypto/sha/sha512.c (revision 9cb04522)
1 /* $OpenBSD: sha512.c,v 1.42 2024/06/01 07:36:16 tb Exp $ */
2 /* ====================================================================
3  * Copyright (c) 1998-2011 The OpenSSL Project.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in
14  *    the documentation and/or other materials provided with the
15  *    distribution.
16  *
17  * 3. All advertising materials mentioning features or use of this
18  *    software must display the following acknowledgment:
19  *    "This product includes software developed by the OpenSSL Project
20  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
21  *
22  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23  *    endorse or promote products derived from this software without
24  *    prior written permission. For written permission, please contact
25  *    openssl-core@openssl.org.
26  *
27  * 5. Products derived from this software may not be called "OpenSSL"
28  *    nor may "OpenSSL" appear in their names without prior written
29  *    permission of the OpenSSL Project.
30  *
31  * 6. Redistributions of any form whatsoever must retain the following
32  *    acknowledgment:
33  *    "This product includes software developed by the OpenSSL Project
34  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
35  *
36  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47  * OF THE POSSIBILITY OF SUCH DAMAGE.
48  * ====================================================================
49  *
50  * This product includes cryptographic software written by Eric Young
51  * (eay@cryptsoft.com).  This product includes software written by Tim
52  * Hudson (tjh@cryptsoft.com).
53  */
54 
55 #include <endian.h>
56 #include <stdlib.h>
57 #include <string.h>
58 
59 #include <openssl/opensslconf.h>
60 
61 #include <openssl/crypto.h>
62 #include <openssl/sha.h>
63 
64 #include "crypto_internal.h"
65 #include "sha_internal.h"
66 
67 #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA512)
68 
69 /* Ensure that SHA_LONG64 and uint64_t are equivalent. */
70 CTASSERT(sizeof(SHA_LONG64) == sizeof(uint64_t));
71 
72 #ifdef SHA512_ASM
73 void sha512_block_data_order(SHA512_CTX *ctx, const void *in, size_t num);
74 #endif
75 
76 #ifndef SHA512_ASM
77 static const SHA_LONG64 K512[80] = {
78 	U64(0x428a2f98d728ae22), U64(0x7137449123ef65cd),
79 	U64(0xb5c0fbcfec4d3b2f), U64(0xe9b5dba58189dbbc),
80 	U64(0x3956c25bf348b538), U64(0x59f111f1b605d019),
81 	U64(0x923f82a4af194f9b), U64(0xab1c5ed5da6d8118),
82 	U64(0xd807aa98a3030242), U64(0x12835b0145706fbe),
83 	U64(0x243185be4ee4b28c), U64(0x550c7dc3d5ffb4e2),
84 	U64(0x72be5d74f27b896f), U64(0x80deb1fe3b1696b1),
85 	U64(0x9bdc06a725c71235), U64(0xc19bf174cf692694),
86 	U64(0xe49b69c19ef14ad2), U64(0xefbe4786384f25e3),
87 	U64(0x0fc19dc68b8cd5b5), U64(0x240ca1cc77ac9c65),
88 	U64(0x2de92c6f592b0275), U64(0x4a7484aa6ea6e483),
89 	U64(0x5cb0a9dcbd41fbd4), U64(0x76f988da831153b5),
90 	U64(0x983e5152ee66dfab), U64(0xa831c66d2db43210),
91 	U64(0xb00327c898fb213f), U64(0xbf597fc7beef0ee4),
92 	U64(0xc6e00bf33da88fc2), U64(0xd5a79147930aa725),
93 	U64(0x06ca6351e003826f), U64(0x142929670a0e6e70),
94 	U64(0x27b70a8546d22ffc), U64(0x2e1b21385c26c926),
95 	U64(0x4d2c6dfc5ac42aed), U64(0x53380d139d95b3df),
96 	U64(0x650a73548baf63de), U64(0x766a0abb3c77b2a8),
97 	U64(0x81c2c92e47edaee6), U64(0x92722c851482353b),
98 	U64(0xa2bfe8a14cf10364), U64(0xa81a664bbc423001),
99 	U64(0xc24b8b70d0f89791), U64(0xc76c51a30654be30),
100 	U64(0xd192e819d6ef5218), U64(0xd69906245565a910),
101 	U64(0xf40e35855771202a), U64(0x106aa07032bbd1b8),
102 	U64(0x19a4c116b8d2d0c8), U64(0x1e376c085141ab53),
103 	U64(0x2748774cdf8eeb99), U64(0x34b0bcb5e19b48a8),
104 	U64(0x391c0cb3c5c95a63), U64(0x4ed8aa4ae3418acb),
105 	U64(0x5b9cca4f7763e373), U64(0x682e6ff3d6b2b8a3),
106 	U64(0x748f82ee5defb2fc), U64(0x78a5636f43172f60),
107 	U64(0x84c87814a1f0ab72), U64(0x8cc702081a6439ec),
108 	U64(0x90befffa23631e28), U64(0xa4506cebde82bde9),
109 	U64(0xbef9a3f7b2c67915), U64(0xc67178f2e372532b),
110 	U64(0xca273eceea26619c), U64(0xd186b8c721c0c207),
111 	U64(0xeada7dd6cde0eb1e), U64(0xf57d4f7fee6ed178),
112 	U64(0x06f067aa72176fba), U64(0x0a637dc5a2c898a6),
113 	U64(0x113f9804bef90dae), U64(0x1b710b35131c471b),
114 	U64(0x28db77f523047d84), U64(0x32caab7b40c72493),
115 	U64(0x3c9ebe0a15c9bebc), U64(0x431d67c49c100d4c),
116 	U64(0x4cc5d4becb3e42b6), U64(0x597f299cfc657e2a),
117 	U64(0x5fcb6fab3ad6faec), U64(0x6c44198c4a475817),
118 };
119 
120 static inline SHA_LONG64
Sigma0(SHA_LONG64 x)121 Sigma0(SHA_LONG64 x)
122 {
123 	return crypto_ror_u64(x, 28) ^ crypto_ror_u64(x, 34) ^
124 	    crypto_ror_u64(x, 39);
125 }
126 
127 static inline SHA_LONG64
Sigma1(SHA_LONG64 x)128 Sigma1(SHA_LONG64 x)
129 {
130 	return crypto_ror_u64(x, 14) ^ crypto_ror_u64(x, 18) ^
131 	    crypto_ror_u64(x, 41);
132 }
133 
134 static inline SHA_LONG64
sigma0(SHA_LONG64 x)135 sigma0(SHA_LONG64 x)
136 {
137 	return crypto_ror_u64(x, 1) ^ crypto_ror_u64(x, 8) ^ (x >> 7);
138 }
139 
140 static inline SHA_LONG64
sigma1(SHA_LONG64 x)141 sigma1(SHA_LONG64 x)
142 {
143 	return crypto_ror_u64(x, 19) ^ crypto_ror_u64(x, 61) ^ (x >> 6);
144 }
145 
146 static inline SHA_LONG64
Ch(SHA_LONG64 x,SHA_LONG64 y,SHA_LONG64 z)147 Ch(SHA_LONG64 x, SHA_LONG64 y, SHA_LONG64 z)
148 {
149 	return (x & y) ^ (~x & z);
150 }
151 
152 static inline SHA_LONG64
Maj(SHA_LONG64 x,SHA_LONG64 y,SHA_LONG64 z)153 Maj(SHA_LONG64 x, SHA_LONG64 y, SHA_LONG64 z)
154 {
155 	return (x & y) ^ (x & z) ^ (y & z);
156 }
157 
158 static inline void
sha512_msg_schedule_update(SHA_LONG64 * W0,SHA_LONG64 W1,SHA_LONG64 W9,SHA_LONG64 W14)159 sha512_msg_schedule_update(SHA_LONG64 *W0, SHA_LONG64 W1,
160     SHA_LONG64 W9, SHA_LONG64 W14)
161 {
162 	*W0 = sigma1(W14) + W9 + sigma0(W1) + *W0;
163 }
164 
165 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)166 sha512_round(SHA_LONG64 *a, SHA_LONG64 *b, SHA_LONG64 *c, SHA_LONG64 *d,
167     SHA_LONG64 *e, SHA_LONG64 *f, SHA_LONG64 *g, SHA_LONG64 *h,
168     SHA_LONG64 Kt, SHA_LONG64 Wt)
169 {
170 	SHA_LONG64 T1, T2;
171 
172 	T1 = *h + Sigma1(*e) + Ch(*e, *f, *g) + Kt + Wt;
173 	T2 = Sigma0(*a) + Maj(*a, *b, *c);
174 
175 	*h = *g;
176 	*g = *f;
177 	*f = *e;
178 	*e = *d + T1;
179 	*d = *c;
180 	*c = *b;
181 	*b = *a;
182 	*a = T1 + T2;
183 }
184 
185 static void
sha512_block_data_order(SHA512_CTX * ctx,const void * _in,size_t num)186 sha512_block_data_order(SHA512_CTX *ctx, const void *_in, size_t num)
187 {
188 	const uint8_t *in = _in;
189 	const SHA_LONG64 *in64;
190 	SHA_LONG64 a, b, c, d, e, f, g, h;
191 	SHA_LONG64 X[16];
192 	int i;
193 
194 	while (num--) {
195 		a = ctx->h[0];
196 		b = ctx->h[1];
197 		c = ctx->h[2];
198 		d = ctx->h[3];
199 		e = ctx->h[4];
200 		f = ctx->h[5];
201 		g = ctx->h[6];
202 		h = ctx->h[7];
203 
204 		if ((size_t)in % sizeof(SHA_LONG64) == 0) {
205 			/* Input is 64 bit aligned. */
206 			in64 = (const SHA_LONG64 *)in;
207 			X[0] = be64toh(in64[0]);
208 			X[1] = be64toh(in64[1]);
209 			X[2] = be64toh(in64[2]);
210 			X[3] = be64toh(in64[3]);
211 			X[4] = be64toh(in64[4]);
212 			X[5] = be64toh(in64[5]);
213 			X[6] = be64toh(in64[6]);
214 			X[7] = be64toh(in64[7]);
215 			X[8] = be64toh(in64[8]);
216 			X[9] = be64toh(in64[9]);
217 			X[10] = be64toh(in64[10]);
218 			X[11] = be64toh(in64[11]);
219 			X[12] = be64toh(in64[12]);
220 			X[13] = be64toh(in64[13]);
221 			X[14] = be64toh(in64[14]);
222 			X[15] = be64toh(in64[15]);
223 		} else {
224 			/* Input is not 64 bit aligned. */
225 			X[0] = crypto_load_be64toh(&in[0 * 8]);
226 			X[1] = crypto_load_be64toh(&in[1 * 8]);
227 			X[2] = crypto_load_be64toh(&in[2 * 8]);
228 			X[3] = crypto_load_be64toh(&in[3 * 8]);
229 			X[4] = crypto_load_be64toh(&in[4 * 8]);
230 			X[5] = crypto_load_be64toh(&in[5 * 8]);
231 			X[6] = crypto_load_be64toh(&in[6 * 8]);
232 			X[7] = crypto_load_be64toh(&in[7 * 8]);
233 			X[8] = crypto_load_be64toh(&in[8 * 8]);
234 			X[9] = crypto_load_be64toh(&in[9 * 8]);
235 			X[10] = crypto_load_be64toh(&in[10 * 8]);
236 			X[11] = crypto_load_be64toh(&in[11 * 8]);
237 			X[12] = crypto_load_be64toh(&in[12 * 8]);
238 			X[13] = crypto_load_be64toh(&in[13 * 8]);
239 			X[14] = crypto_load_be64toh(&in[14 * 8]);
240 			X[15] = crypto_load_be64toh(&in[15 * 8]);
241 		}
242 		in += SHA512_CBLOCK;
243 
244 		sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[0], X[0]);
245 		sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[1], X[1]);
246 		sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[2], X[2]);
247 		sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[3], X[3]);
248 		sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[4], X[4]);
249 		sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[5], X[5]);
250 		sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[6], X[6]);
251 		sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[7], X[7]);
252 		sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[8], X[8]);
253 		sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[9], X[9]);
254 		sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[10], X[10]);
255 		sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[11], X[11]);
256 		sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[12], X[12]);
257 		sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[13], X[13]);
258 		sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[14], X[14]);
259 		sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[15], X[15]);
260 
261 		for (i = 16; i < 80; i += 16) {
262 			sha512_msg_schedule_update(&X[0], X[1], X[9], X[14]);
263 			sha512_msg_schedule_update(&X[1], X[2], X[10], X[15]);
264 			sha512_msg_schedule_update(&X[2], X[3], X[11], X[0]);
265 			sha512_msg_schedule_update(&X[3], X[4], X[12], X[1]);
266 			sha512_msg_schedule_update(&X[4], X[5], X[13], X[2]);
267 			sha512_msg_schedule_update(&X[5], X[6], X[14], X[3]);
268 			sha512_msg_schedule_update(&X[6], X[7], X[15], X[4]);
269 			sha512_msg_schedule_update(&X[7], X[8], X[0], X[5]);
270 			sha512_msg_schedule_update(&X[8], X[9], X[1], X[6]);
271 			sha512_msg_schedule_update(&X[9], X[10], X[2], X[7]);
272 			sha512_msg_schedule_update(&X[10], X[11], X[3], X[8]);
273 			sha512_msg_schedule_update(&X[11], X[12], X[4], X[9]);
274 			sha512_msg_schedule_update(&X[12], X[13], X[5], X[10]);
275 			sha512_msg_schedule_update(&X[13], X[14], X[6], X[11]);
276 			sha512_msg_schedule_update(&X[14], X[15], X[7], X[12]);
277 			sha512_msg_schedule_update(&X[15], X[0], X[8], X[13]);
278 
279 			sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 0], X[0]);
280 			sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 1], X[1]);
281 			sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 2], X[2]);
282 			sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 3], X[3]);
283 			sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 4], X[4]);
284 			sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 5], X[5]);
285 			sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 6], X[6]);
286 			sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 7], X[7]);
287 			sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 8], X[8]);
288 			sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 9], X[9]);
289 			sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 10], X[10]);
290 			sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 11], X[11]);
291 			sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 12], X[12]);
292 			sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 13], X[13]);
293 			sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 14], X[14]);
294 			sha512_round(&a, &b, &c, &d, &e, &f, &g, &h, K512[i + 15], X[15]);
295 		}
296 
297 		ctx->h[0] += a;
298 		ctx->h[1] += b;
299 		ctx->h[2] += c;
300 		ctx->h[3] += d;
301 		ctx->h[4] += e;
302 		ctx->h[5] += f;
303 		ctx->h[6] += g;
304 		ctx->h[7] += h;
305 	}
306 }
307 
308 #endif /* SHA512_ASM */
309 
310 int
SHA384_Init(SHA512_CTX * c)311 SHA384_Init(SHA512_CTX *c)
312 {
313 	memset(c, 0, sizeof(*c));
314 
315 	c->h[0] = U64(0xcbbb9d5dc1059ed8);
316 	c->h[1] = U64(0x629a292a367cd507);
317 	c->h[2] = U64(0x9159015a3070dd17);
318 	c->h[3] = U64(0x152fecd8f70e5939);
319 	c->h[4] = U64(0x67332667ffc00b31);
320 	c->h[5] = U64(0x8eb44a8768581511);
321 	c->h[6] = U64(0xdb0c2e0d64f98fa7);
322 	c->h[7] = U64(0x47b5481dbefa4fa4);
323 
324 	c->md_len = SHA384_DIGEST_LENGTH;
325 
326 	return 1;
327 }
328 LCRYPTO_ALIAS(SHA384_Init);
329 
330 int
SHA384_Update(SHA512_CTX * c,const void * data,size_t len)331 SHA384_Update(SHA512_CTX *c, const void *data, size_t len)
332 {
333 	return SHA512_Update(c, data, len);
334 }
335 LCRYPTO_ALIAS(SHA384_Update);
336 
337 int
SHA384_Final(unsigned char * md,SHA512_CTX * c)338 SHA384_Final(unsigned char *md, SHA512_CTX *c)
339 {
340 	return SHA512_Final(md, c);
341 }
342 LCRYPTO_ALIAS(SHA384_Final);
343 
344 unsigned char *
SHA384(const unsigned char * d,size_t n,unsigned char * md)345 SHA384(const unsigned char *d, size_t n, unsigned char *md)
346 {
347 	SHA512_CTX c;
348 
349 	SHA384_Init(&c);
350 	SHA512_Update(&c, d, n);
351 	SHA512_Final(md, &c);
352 
353 	explicit_bzero(&c, sizeof(c));
354 
355 	return (md);
356 }
357 LCRYPTO_ALIAS(SHA384);
358 
359 int
SHA512_Init(SHA512_CTX * c)360 SHA512_Init(SHA512_CTX *c)
361 {
362 	memset(c, 0, sizeof(*c));
363 
364 	c->h[0] = U64(0x6a09e667f3bcc908);
365 	c->h[1] = U64(0xbb67ae8584caa73b);
366 	c->h[2] = U64(0x3c6ef372fe94f82b);
367 	c->h[3] = U64(0xa54ff53a5f1d36f1);
368 	c->h[4] = U64(0x510e527fade682d1);
369 	c->h[5] = U64(0x9b05688c2b3e6c1f);
370 	c->h[6] = U64(0x1f83d9abfb41bd6b);
371 	c->h[7] = U64(0x5be0cd19137e2179);
372 
373 	c->md_len = SHA512_DIGEST_LENGTH;
374 
375 	return 1;
376 }
377 LCRYPTO_ALIAS(SHA512_Init);
378 
379 void
SHA512_Transform(SHA512_CTX * c,const unsigned char * data)380 SHA512_Transform(SHA512_CTX *c, const unsigned char *data)
381 {
382 	sha512_block_data_order(c, data, 1);
383 }
384 LCRYPTO_ALIAS(SHA512_Transform);
385 
386 int
SHA512_Update(SHA512_CTX * c,const void * _data,size_t len)387 SHA512_Update(SHA512_CTX *c, const void *_data, size_t len)
388 {
389 	const unsigned char *data = _data;
390 	unsigned char *p = c->u.p;
391 	SHA_LONG64 l;
392 
393 	if (len == 0)
394 		return 1;
395 
396 	l = (c->Nl + (((SHA_LONG64)len) << 3))&U64(0xffffffffffffffff);
397 	if (l < c->Nl)
398 		c->Nh++;
399 	if (sizeof(len) >= 8)
400 		c->Nh += (((SHA_LONG64)len) >> 61);
401 	c->Nl = l;
402 
403 	if (c->num != 0) {
404 		size_t n = sizeof(c->u) - c->num;
405 
406 		if (len < n) {
407 			memcpy(p + c->num, data, len);
408 			c->num += (unsigned int)len;
409 			return 1;
410 		} else{
411 			memcpy(p + c->num, data, n);
412 			c->num = 0;
413 			len -= n;
414 			data += n;
415 			sha512_block_data_order(c, p, 1);
416 		}
417 	}
418 
419 	if (len >= sizeof(c->u)) {
420 		sha512_block_data_order(c, data, len/sizeof(c->u));
421 		data += len;
422 		len %= sizeof(c->u);
423 		data -= len;
424 	}
425 
426 	if (len != 0) {
427 		memcpy(p, data, len);
428 		c->num = (int)len;
429 	}
430 
431 	return 1;
432 }
433 LCRYPTO_ALIAS(SHA512_Update);
434 
435 int
SHA512_Final(unsigned char * md,SHA512_CTX * c)436 SHA512_Final(unsigned char *md, SHA512_CTX *c)
437 {
438 	unsigned char *p = (unsigned char *)c->u.p;
439 	size_t n = c->num;
440 
441 	p[n]=0x80;	/* There always is a room for one */
442 	n++;
443 	if (n > (sizeof(c->u) - 16)) {
444 		memset(p + n, 0, sizeof(c->u) - n);
445 		n = 0;
446 		sha512_block_data_order(c, p, 1);
447 	}
448 
449 	memset(p + n, 0, sizeof(c->u) - 16 - n);
450 	c->u.d[SHA_LBLOCK - 2] = htobe64(c->Nh);
451 	c->u.d[SHA_LBLOCK - 1] = htobe64(c->Nl);
452 
453 	sha512_block_data_order(c, p, 1);
454 
455 	if (md == NULL)
456 		return 0;
457 
458 	/* Let compiler decide if it's appropriate to unroll... */
459 	switch (c->md_len) {
460 	case SHA512_224_DIGEST_LENGTH:
461 		for (n = 0; n < SHA512_224_DIGEST_LENGTH/8; n++) {
462 			crypto_store_htobe64(md, c->h[n]);
463 			md += 8;
464 		}
465 		crypto_store_htobe32(md, c->h[n] >> 32);
466 		break;
467 	case SHA512_256_DIGEST_LENGTH:
468 		for (n = 0; n < SHA512_256_DIGEST_LENGTH/8; n++) {
469 			crypto_store_htobe64(md, c->h[n]);
470 			md += 8;
471 		}
472 		break;
473 	case SHA384_DIGEST_LENGTH:
474 		for (n = 0; n < SHA384_DIGEST_LENGTH/8; n++) {
475 			crypto_store_htobe64(md, c->h[n]);
476 			md += 8;
477 		}
478 		break;
479 	case SHA512_DIGEST_LENGTH:
480 		for (n = 0; n < SHA512_DIGEST_LENGTH/8; n++) {
481 			crypto_store_htobe64(md, c->h[n]);
482 			md += 8;
483 		}
484 		break;
485 	default:
486 		return 0;
487 	}
488 
489 	return 1;
490 }
491 LCRYPTO_ALIAS(SHA512_Final);
492 
493 unsigned char *
SHA512(const unsigned char * d,size_t n,unsigned char * md)494 SHA512(const unsigned char *d, size_t n, unsigned char *md)
495 {
496 	SHA512_CTX c;
497 
498 	SHA512_Init(&c);
499 	SHA512_Update(&c, d, n);
500 	SHA512_Final(md, &c);
501 
502 	explicit_bzero(&c, sizeof(c));
503 
504 	return (md);
505 }
506 LCRYPTO_ALIAS(SHA512);
507 
508 int
SHA512_224_Init(SHA512_CTX * c)509 SHA512_224_Init(SHA512_CTX *c)
510 {
511 	memset(c, 0, sizeof(*c));
512 
513 	/* FIPS 180-4 section 5.3.6.1. */
514 	c->h[0] = U64(0x8c3d37c819544da2);
515 	c->h[1] = U64(0x73e1996689dcd4d6);
516 	c->h[2] = U64(0x1dfab7ae32ff9c82);
517 	c->h[3] = U64(0x679dd514582f9fcf);
518 	c->h[4] = U64(0x0f6d2b697bd44da8);
519 	c->h[5] = U64(0x77e36f7304c48942);
520 	c->h[6] = U64(0x3f9d85a86a1d36c8);
521 	c->h[7] = U64(0x1112e6ad91d692a1);
522 
523 	c->md_len = SHA512_224_DIGEST_LENGTH;
524 
525 	return 1;
526 }
527 
528 int
SHA512_224_Update(SHA512_CTX * c,const void * data,size_t len)529 SHA512_224_Update(SHA512_CTX *c, const void *data, size_t len)
530 {
531 	return SHA512_Update(c, data, len);
532 }
533 
534 int
SHA512_224_Final(unsigned char * md,SHA512_CTX * c)535 SHA512_224_Final(unsigned char *md, SHA512_CTX *c)
536 {
537 	return SHA512_Final(md, c);
538 }
539 
540 int
SHA512_256_Init(SHA512_CTX * c)541 SHA512_256_Init(SHA512_CTX *c)
542 {
543 	memset(c, 0, sizeof(*c));
544 
545 	/* FIPS 180-4 section 5.3.6.2. */
546 	c->h[0] = U64(0x22312194fc2bf72c);
547 	c->h[1] = U64(0x9f555fa3c84c64c2);
548 	c->h[2] = U64(0x2393b86b6f53b151);
549 	c->h[3] = U64(0x963877195940eabd);
550 	c->h[4] = U64(0x96283ee2a88effe3);
551 	c->h[5] = U64(0xbe5e1e2553863992);
552 	c->h[6] = U64(0x2b0199fc2c85b8aa);
553 	c->h[7] = U64(0x0eb72ddc81c52ca2);
554 
555 	c->md_len = SHA512_256_DIGEST_LENGTH;
556 
557 	return 1;
558 }
559 
560 int
SHA512_256_Update(SHA512_CTX * c,const void * data,size_t len)561 SHA512_256_Update(SHA512_CTX *c, const void *data, size_t len)
562 {
563 	return SHA512_Update(c, data, len);
564 }
565 
566 int
SHA512_256_Final(unsigned char * md,SHA512_CTX * c)567 SHA512_256_Final(unsigned char *md, SHA512_CTX *c)
568 {
569 	return SHA512_Final(md, c);
570 }
571 
572 #endif /* !OPENSSL_NO_SHA512 */
573