xref: /openbsd-src/lib/libcrypto/sha/sha512.c (revision ff0e7be1ebbcc809ea8ad2b6dafe215824da9e46)
1 /* $OpenBSD: sha512.c,v 1.39 2023/05/27 09:18:17 jsing 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 is 64 bits. */
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 #define ROTR(x, s)	crypto_ror_u64(x, s)
121 
122 #define Sigma0(x)	(ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39))
123 #define Sigma1(x)	(ROTR((x),14) ^ ROTR((x),18) ^ ROTR((x),41))
124 #define sigma0(x)	(ROTR((x),1)  ^ ROTR((x),8)  ^ ((x)>>7))
125 #define sigma1(x)	(ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6))
126 
127 #define Ch(x, y, z)	(((x) & (y)) ^ ((~(x)) & (z)))
128 #define Maj(x, y, z)	(((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
129 
130 #define	ROUND_00_15(i, a, b, c, d, e, f, g, h, Wt)		do {	\
131 	T1 = h + Sigma1(e) + Ch(e, f, g) + K512[i] + Wt;		\
132 	T2 = Sigma0(a) + Maj(a, b, c);					\
133 	d += T1;							\
134 	h = T1 + T2;							\
135 								} while (0)
136 
137 #define	ROUND_16_80(i, j, a, b, c, d, e, f, g, h, X)		do {	\
138 	s0 = sigma0(X[(j + 1) & 0x0f]);					\
139 	s1 = sigma1(X[(j + 14) & 0x0f]);				\
140 	X[(j) & 0x0f] += s0 + s1 + X[(j + 9) & 0x0f];			\
141 	ROUND_00_15(i + j, a, b, c, d, e, f, g, h, X[(j) & 0x0f]);	\
142 								} while (0)
143 
144 static void
145 sha512_block_data_order(SHA512_CTX *ctx, const void *_in, size_t num)
146 {
147 	const uint8_t *in = _in;
148 	const SHA_LONG64 *in64;
149 	SHA_LONG64 a, b, c, d, e, f, g, h, s0, s1, T1, T2;
150 	SHA_LONG64 X[16];
151 	int i;
152 
153 	while (num--) {
154 		a = ctx->h[0];
155 		b = ctx->h[1];
156 		c = ctx->h[2];
157 		d = ctx->h[3];
158 		e = ctx->h[4];
159 		f = ctx->h[5];
160 		g = ctx->h[6];
161 		h = ctx->h[7];
162 
163 		if ((size_t)in % sizeof(SHA_LONG64) == 0) {
164 			/* Input is 64 bit aligned. */
165 			in64 = (const SHA_LONG64 *)in;
166 			X[0] = be64toh(in64[0]);
167 			X[1] = be64toh(in64[1]);
168 			X[2] = be64toh(in64[2]);
169 			X[3] = be64toh(in64[3]);
170 			X[4] = be64toh(in64[4]);
171 			X[5] = be64toh(in64[5]);
172 			X[6] = be64toh(in64[6]);
173 			X[7] = be64toh(in64[7]);
174 			X[8] = be64toh(in64[8]);
175 			X[9] = be64toh(in64[9]);
176 			X[10] = be64toh(in64[10]);
177 			X[11] = be64toh(in64[11]);
178 			X[12] = be64toh(in64[12]);
179 			X[13] = be64toh(in64[13]);
180 			X[14] = be64toh(in64[14]);
181 			X[15] = be64toh(in64[15]);
182 		} else {
183 			/* Input is not 64 bit aligned. */
184 			X[0] = crypto_load_be64toh(&in[0 * 8]);
185 			X[1] = crypto_load_be64toh(&in[1 * 8]);
186 			X[2] = crypto_load_be64toh(&in[2 * 8]);
187 			X[3] = crypto_load_be64toh(&in[3 * 8]);
188 			X[4] = crypto_load_be64toh(&in[4 * 8]);
189 			X[5] = crypto_load_be64toh(&in[5 * 8]);
190 			X[6] = crypto_load_be64toh(&in[6 * 8]);
191 			X[7] = crypto_load_be64toh(&in[7 * 8]);
192 			X[8] = crypto_load_be64toh(&in[8 * 8]);
193 			X[9] = crypto_load_be64toh(&in[9 * 8]);
194 			X[10] = crypto_load_be64toh(&in[10 * 8]);
195 			X[11] = crypto_load_be64toh(&in[11 * 8]);
196 			X[12] = crypto_load_be64toh(&in[12 * 8]);
197 			X[13] = crypto_load_be64toh(&in[13 * 8]);
198 			X[14] = crypto_load_be64toh(&in[14 * 8]);
199 			X[15] = crypto_load_be64toh(&in[15 * 8]);
200 		}
201 		in += SHA512_CBLOCK;
202 
203 		ROUND_00_15(0, a, b, c, d, e, f, g, h, X[0]);
204 		ROUND_00_15(1, h, a, b, c, d, e, f, g, X[1]);
205 		ROUND_00_15(2, g, h, a, b, c, d, e, f, X[2]);
206 		ROUND_00_15(3, f, g, h, a, b, c, d, e, X[3]);
207 		ROUND_00_15(4, e, f, g, h, a, b, c, d, X[4]);
208 		ROUND_00_15(5, d, e, f, g, h, a, b, c, X[5]);
209 		ROUND_00_15(6, c, d, e, f, g, h, a, b, X[6]);
210 		ROUND_00_15(7, b, c, d, e, f, g, h, a, X[7]);
211 		ROUND_00_15(8, a, b, c, d, e, f, g, h, X[8]);
212 		ROUND_00_15(9, h, a, b, c, d, e, f, g, X[9]);
213 		ROUND_00_15(10, g, h, a, b, c, d, e, f, X[10]);
214 		ROUND_00_15(11, f, g, h, a, b, c, d, e, X[11]);
215 		ROUND_00_15(12, e, f, g, h, a, b, c, d, X[12]);
216 		ROUND_00_15(13, d, e, f, g, h, a, b, c, X[13]);
217 		ROUND_00_15(14, c, d, e, f, g, h, a, b, X[14]);
218 		ROUND_00_15(15, b, c, d, e, f, g, h, a, X[15]);
219 
220 		for (i = 16; i < 80; i += 16) {
221 			ROUND_16_80(i, 0, a, b, c, d, e, f, g, h, X);
222 			ROUND_16_80(i, 1, h, a, b, c, d, e, f, g, X);
223 			ROUND_16_80(i, 2, g, h, a, b, c, d, e, f, X);
224 			ROUND_16_80(i, 3, f, g, h, a, b, c, d, e, X);
225 			ROUND_16_80(i, 4, e, f, g, h, a, b, c, d, X);
226 			ROUND_16_80(i, 5, d, e, f, g, h, a, b, c, X);
227 			ROUND_16_80(i, 6, c, d, e, f, g, h, a, b, X);
228 			ROUND_16_80(i, 7, b, c, d, e, f, g, h, a, X);
229 			ROUND_16_80(i, 8, a, b, c, d, e, f, g, h, X);
230 			ROUND_16_80(i, 9, h, a, b, c, d, e, f, g, X);
231 			ROUND_16_80(i, 10, g, h, a, b, c, d, e, f, X);
232 			ROUND_16_80(i, 11, f, g, h, a, b, c, d, e, X);
233 			ROUND_16_80(i, 12, e, f, g, h, a, b, c, d, X);
234 			ROUND_16_80(i, 13, d, e, f, g, h, a, b, c, X);
235 			ROUND_16_80(i, 14, c, d, e, f, g, h, a, b, X);
236 			ROUND_16_80(i, 15, b, c, d, e, f, g, h, a, X);
237 		}
238 
239 		ctx->h[0] += a;
240 		ctx->h[1] += b;
241 		ctx->h[2] += c;
242 		ctx->h[3] += d;
243 		ctx->h[4] += e;
244 		ctx->h[5] += f;
245 		ctx->h[6] += g;
246 		ctx->h[7] += h;
247 	}
248 }
249 
250 #endif /* SHA512_ASM */
251 
252 int
253 SHA384_Init(SHA512_CTX *c)
254 {
255 	memset(c, 0, sizeof(*c));
256 
257 	c->h[0] = U64(0xcbbb9d5dc1059ed8);
258 	c->h[1] = U64(0x629a292a367cd507);
259 	c->h[2] = U64(0x9159015a3070dd17);
260 	c->h[3] = U64(0x152fecd8f70e5939);
261 	c->h[4] = U64(0x67332667ffc00b31);
262 	c->h[5] = U64(0x8eb44a8768581511);
263 	c->h[6] = U64(0xdb0c2e0d64f98fa7);
264 	c->h[7] = U64(0x47b5481dbefa4fa4);
265 
266 	c->md_len = SHA384_DIGEST_LENGTH;
267 
268 	return 1;
269 }
270 
271 int
272 SHA384_Update(SHA512_CTX *c, const void *data, size_t len)
273 {
274 	return SHA512_Update(c, data, len);
275 }
276 
277 int
278 SHA384_Final(unsigned char *md, SHA512_CTX *c)
279 {
280 	return SHA512_Final(md, c);
281 }
282 
283 unsigned char *
284 SHA384(const unsigned char *d, size_t n, unsigned char *md)
285 {
286 	SHA512_CTX c;
287 	static unsigned char m[SHA384_DIGEST_LENGTH];
288 
289 	if (md == NULL)
290 		md = m;
291 
292 	SHA384_Init(&c);
293 	SHA512_Update(&c, d, n);
294 	SHA512_Final(md, &c);
295 
296 	explicit_bzero(&c, sizeof(c));
297 
298 	return (md);
299 }
300 
301 int
302 SHA512_Init(SHA512_CTX *c)
303 {
304 	memset(c, 0, sizeof(*c));
305 
306 	c->h[0] = U64(0x6a09e667f3bcc908);
307 	c->h[1] = U64(0xbb67ae8584caa73b);
308 	c->h[2] = U64(0x3c6ef372fe94f82b);
309 	c->h[3] = U64(0xa54ff53a5f1d36f1);
310 	c->h[4] = U64(0x510e527fade682d1);
311 	c->h[5] = U64(0x9b05688c2b3e6c1f);
312 	c->h[6] = U64(0x1f83d9abfb41bd6b);
313 	c->h[7] = U64(0x5be0cd19137e2179);
314 
315 	c->md_len = SHA512_DIGEST_LENGTH;
316 
317 	return 1;
318 }
319 
320 void
321 SHA512_Transform(SHA512_CTX *c, const unsigned char *data)
322 {
323 	sha512_block_data_order(c, data, 1);
324 }
325 
326 int
327 SHA512_Update(SHA512_CTX *c, const void *_data, size_t len)
328 {
329 	const unsigned char *data = _data;
330 	unsigned char *p = c->u.p;
331 	SHA_LONG64 l;
332 
333 	if (len == 0)
334 		return 1;
335 
336 	l = (c->Nl + (((SHA_LONG64)len) << 3))&U64(0xffffffffffffffff);
337 	if (l < c->Nl)
338 		c->Nh++;
339 	if (sizeof(len) >= 8)
340 		c->Nh += (((SHA_LONG64)len) >> 61);
341 	c->Nl = l;
342 
343 	if (c->num != 0) {
344 		size_t n = sizeof(c->u) - c->num;
345 
346 		if (len < n) {
347 			memcpy(p + c->num, data, len);
348 			c->num += (unsigned int)len;
349 			return 1;
350 		} else{
351 			memcpy(p + c->num, data, n);
352 			c->num = 0;
353 			len -= n;
354 			data += n;
355 			sha512_block_data_order(c, p, 1);
356 		}
357 	}
358 
359 	if (len >= sizeof(c->u)) {
360 		sha512_block_data_order(c, data, len/sizeof(c->u));
361 		data += len;
362 		len %= sizeof(c->u);
363 		data -= len;
364 	}
365 
366 	if (len != 0) {
367 		memcpy(p, data, len);
368 		c->num = (int)len;
369 	}
370 
371 	return 1;
372 }
373 
374 int
375 SHA512_Final(unsigned char *md, SHA512_CTX *c)
376 {
377 	unsigned char *p = (unsigned char *)c->u.p;
378 	size_t n = c->num;
379 
380 	p[n]=0x80;	/* There always is a room for one */
381 	n++;
382 	if (n > (sizeof(c->u) - 16)) {
383 		memset(p + n, 0, sizeof(c->u) - n);
384 		n = 0;
385 		sha512_block_data_order(c, p, 1);
386 	}
387 
388 	memset(p + n, 0, sizeof(c->u) - 16 - n);
389 	c->u.d[SHA_LBLOCK - 2] = htobe64(c->Nh);
390 	c->u.d[SHA_LBLOCK - 1] = htobe64(c->Nl);
391 
392 	sha512_block_data_order(c, p, 1);
393 
394 	if (md == NULL)
395 		return 0;
396 
397 	/* Let compiler decide if it's appropriate to unroll... */
398 	switch (c->md_len) {
399 	case SHA512_224_DIGEST_LENGTH:
400 		for (n = 0; n < SHA512_224_DIGEST_LENGTH/8; n++) {
401 			crypto_store_htobe64(md, c->h[n]);
402 			md += 8;
403 		}
404 		crypto_store_htobe32(md, c->h[n] >> 32);
405 		break;
406 	case SHA512_256_DIGEST_LENGTH:
407 		for (n = 0; n < SHA512_256_DIGEST_LENGTH/8; n++) {
408 			crypto_store_htobe64(md, c->h[n]);
409 			md += 8;
410 		}
411 		break;
412 	case SHA384_DIGEST_LENGTH:
413 		for (n = 0; n < SHA384_DIGEST_LENGTH/8; n++) {
414 			crypto_store_htobe64(md, c->h[n]);
415 			md += 8;
416 		}
417 		break;
418 	case SHA512_DIGEST_LENGTH:
419 		for (n = 0; n < SHA512_DIGEST_LENGTH/8; n++) {
420 			crypto_store_htobe64(md, c->h[n]);
421 			md += 8;
422 		}
423 		break;
424 	default:
425 		return 0;
426 	}
427 
428 	return 1;
429 }
430 
431 unsigned char *
432 SHA512(const unsigned char *d, size_t n, unsigned char *md)
433 {
434 	SHA512_CTX c;
435 	static unsigned char m[SHA512_DIGEST_LENGTH];
436 
437 	if (md == NULL)
438 		md = m;
439 
440 	SHA512_Init(&c);
441 	SHA512_Update(&c, d, n);
442 	SHA512_Final(md, &c);
443 
444 	explicit_bzero(&c, sizeof(c));
445 
446 	return (md);
447 }
448 
449 int
450 SHA512_224_Init(SHA512_CTX *c)
451 {
452 	memset(c, 0, sizeof(*c));
453 
454 	/* FIPS 180-4 section 5.3.6.1. */
455 	c->h[0] = U64(0x8c3d37c819544da2);
456 	c->h[1] = U64(0x73e1996689dcd4d6);
457 	c->h[2] = U64(0x1dfab7ae32ff9c82);
458 	c->h[3] = U64(0x679dd514582f9fcf);
459 	c->h[4] = U64(0x0f6d2b697bd44da8);
460 	c->h[5] = U64(0x77e36f7304c48942);
461 	c->h[6] = U64(0x3f9d85a86a1d36c8);
462 	c->h[7] = U64(0x1112e6ad91d692a1);
463 
464 	c->md_len = SHA512_224_DIGEST_LENGTH;
465 
466 	return 1;
467 }
468 
469 int
470 SHA512_224_Update(SHA512_CTX *c, const void *data, size_t len)
471 {
472 	return SHA512_Update(c, data, len);
473 }
474 
475 int
476 SHA512_224_Final(unsigned char *md, SHA512_CTX *c)
477 {
478 	return SHA512_Final(md, c);
479 }
480 
481 int
482 SHA512_256_Init(SHA512_CTX *c)
483 {
484 	memset(c, 0, sizeof(*c));
485 
486 	/* FIPS 180-4 section 5.3.6.2. */
487 	c->h[0] = U64(0x22312194fc2bf72c);
488 	c->h[1] = U64(0x9f555fa3c84c64c2);
489 	c->h[2] = U64(0x2393b86b6f53b151);
490 	c->h[3] = U64(0x963877195940eabd);
491 	c->h[4] = U64(0x96283ee2a88effe3);
492 	c->h[5] = U64(0xbe5e1e2553863992);
493 	c->h[6] = U64(0x2b0199fc2c85b8aa);
494 	c->h[7] = U64(0x0eb72ddc81c52ca2);
495 
496 	c->md_len = SHA512_256_DIGEST_LENGTH;
497 
498 	return 1;
499 }
500 
501 int
502 SHA512_256_Update(SHA512_CTX *c, const void *data, size_t len)
503 {
504 	return SHA512_Update(c, data, len);
505 }
506 
507 int
508 SHA512_256_Final(unsigned char *md, SHA512_CTX *c)
509 {
510 	return SHA512_Final(md, c);
511 }
512 
513 #endif /* !OPENSSL_NO_SHA512 */
514