xref: /illumos-gate/usr/src/boot/sys/cddl/boot/zfs/sha256.c (revision 8eef2ab6)
1199767f8SToomas Soome /*
2199767f8SToomas Soome  * CDDL HEADER START
3199767f8SToomas Soome  *
4199767f8SToomas Soome  * The contents of this file are subject to the terms of the
5199767f8SToomas Soome  * Common Development and Distribution License, Version 1.0 only
6199767f8SToomas Soome  * (the "License").  You may not use this file except in compliance
7199767f8SToomas Soome  * with the License.
8199767f8SToomas Soome  *
9199767f8SToomas Soome  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10199767f8SToomas Soome  * or http://www.opensolaris.org/os/licensing.
11199767f8SToomas Soome  * See the License for the specific language governing permissions
12199767f8SToomas Soome  * and limitations under the License.
13199767f8SToomas Soome  *
14199767f8SToomas Soome  * When distributing Covered Code, include this CDDL HEADER in each
15199767f8SToomas Soome  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16199767f8SToomas Soome  * If applicable, add the following below this CDDL HEADER, with the
17199767f8SToomas Soome  * fields enclosed by brackets "[]" replaced with your own identifying
18199767f8SToomas Soome  * information: Portions Copyright [yyyy] [name of copyright owner]
19199767f8SToomas Soome  *
20199767f8SToomas Soome  * CDDL HEADER END
21199767f8SToomas Soome  */
22199767f8SToomas Soome /*
23199767f8SToomas Soome  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24199767f8SToomas Soome  * Use is subject to license terms.
25199767f8SToomas Soome  */
26199767f8SToomas Soome /*
27199767f8SToomas Soome  * Copyright 2013 Saso Kiselkov.  All rights reserved.
28199767f8SToomas Soome  * Copyright 2015 Toomas Soome <tsoome@me.com>
29199767f8SToomas Soome  */
30199767f8SToomas Soome 
31199767f8SToomas Soome /*
32199767f8SToomas Soome  * SHA-256 and SHA-512/256 hashes, as specified in FIPS 180-4, available at:
33199767f8SToomas Soome  * http://csrc.nist.gov/cryptval
34199767f8SToomas Soome  *
35199767f8SToomas Soome  * This is a very compact implementation of SHA-256 and SHA-512/256.
36199767f8SToomas Soome  * It is designed to be simple and portable, not to be fast.
37199767f8SToomas Soome  */
38199767f8SToomas Soome 
39199767f8SToomas Soome /*
40199767f8SToomas Soome  * The literal definitions according to FIPS180-4 would be:
41199767f8SToomas Soome  *
42199767f8SToomas Soome  * 	Ch(x, y, z)     (((x) & (y)) ^ ((~(x)) & (z)))
43199767f8SToomas Soome  * 	Maj(x, y, z)    (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
44199767f8SToomas Soome  *
45199767f8SToomas Soome  * We use logical equivalents which require one less op.
46199767f8SToomas Soome  */
47199767f8SToomas Soome #define	Ch(x, y, z)	((z) ^ ((x) & ((y) ^ (z))))
48199767f8SToomas Soome #define	Maj(x, y, z)	(((x) & (y)) ^ ((z) & ((x) ^ (y))))
49199767f8SToomas Soome #define	ROTR(x, n)	(((x) >> (n)) | ((x) << ((sizeof (x) * NBBY)-(n))))
50199767f8SToomas Soome 
51199767f8SToomas Soome /* SHA-224/256 operations */
52199767f8SToomas Soome #define	BIGSIGMA0_256(x)	(ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
53199767f8SToomas Soome #define	BIGSIGMA1_256(x)	(ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
54199767f8SToomas Soome #define	SIGMA0_256(x)		(ROTR(x, 7) ^ ROTR(x, 18) ^ ((x) >> 3))
55199767f8SToomas Soome #define	SIGMA1_256(x)		(ROTR(x, 17) ^ ROTR(x, 19) ^ ((x) >> 10))
56199767f8SToomas Soome 
57199767f8SToomas Soome /* SHA-384/512 operations */
58199767f8SToomas Soome #define	BIGSIGMA0_512(x)	(ROTR((x), 28) ^ ROTR((x), 34) ^ ROTR((x), 39))
59199767f8SToomas Soome #define	BIGSIGMA1_512(x)	(ROTR((x), 14) ^ ROTR((x), 18) ^ ROTR((x), 41))
60199767f8SToomas Soome #define	SIGMA0_512(x)		(ROTR((x), 1) ^ ROTR((x), 8) ^ ((x) >> 7))
61199767f8SToomas Soome #define	SIGMA1_512(x)		(ROTR((x), 19) ^ ROTR((x), 61) ^ ((x) >> 6))
62199767f8SToomas Soome 
63199767f8SToomas Soome /* SHA-256 round constants */
64199767f8SToomas Soome static const uint32_t SHA256_K[64] = {
65199767f8SToomas Soome 	0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
66199767f8SToomas Soome 	0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
67199767f8SToomas Soome 	0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
68199767f8SToomas Soome 	0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
69199767f8SToomas Soome 	0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
70199767f8SToomas Soome 	0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
71199767f8SToomas Soome 	0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
72199767f8SToomas Soome 	0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
73199767f8SToomas Soome 	0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
74199767f8SToomas Soome 	0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
75199767f8SToomas Soome 	0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
76199767f8SToomas Soome 	0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
77199767f8SToomas Soome 	0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
78199767f8SToomas Soome 	0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
79199767f8SToomas Soome 	0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
80199767f8SToomas Soome 	0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
81199767f8SToomas Soome };
82199767f8SToomas Soome 
83199767f8SToomas Soome /* SHA-512 round constants */
84199767f8SToomas Soome static const uint64_t SHA512_K[80] = {
85199767f8SToomas Soome 	0x428A2F98D728AE22ULL, 0x7137449123EF65CDULL,
86199767f8SToomas Soome 	0xB5C0FBCFEC4D3B2FULL, 0xE9B5DBA58189DBBCULL,
87199767f8SToomas Soome 	0x3956C25BF348B538ULL, 0x59F111F1B605D019ULL,
88199767f8SToomas Soome 	0x923F82A4AF194F9BULL, 0xAB1C5ED5DA6D8118ULL,
89199767f8SToomas Soome 	0xD807AA98A3030242ULL, 0x12835B0145706FBEULL,
90199767f8SToomas Soome 	0x243185BE4EE4B28CULL, 0x550C7DC3D5FFB4E2ULL,
91199767f8SToomas Soome 	0x72BE5D74F27B896FULL, 0x80DEB1FE3B1696B1ULL,
92199767f8SToomas Soome 	0x9BDC06A725C71235ULL, 0xC19BF174CF692694ULL,
93199767f8SToomas Soome 	0xE49B69C19EF14AD2ULL, 0xEFBE4786384F25E3ULL,
94199767f8SToomas Soome 	0x0FC19DC68B8CD5B5ULL, 0x240CA1CC77AC9C65ULL,
95199767f8SToomas Soome 	0x2DE92C6F592B0275ULL, 0x4A7484AA6EA6E483ULL,
96199767f8SToomas Soome 	0x5CB0A9DCBD41FBD4ULL, 0x76F988DA831153B5ULL,
97199767f8SToomas Soome 	0x983E5152EE66DFABULL, 0xA831C66D2DB43210ULL,
98199767f8SToomas Soome 	0xB00327C898FB213FULL, 0xBF597FC7BEEF0EE4ULL,
99199767f8SToomas Soome 	0xC6E00BF33DA88FC2ULL, 0xD5A79147930AA725ULL,
100199767f8SToomas Soome 	0x06CA6351E003826FULL, 0x142929670A0E6E70ULL,
101199767f8SToomas Soome 	0x27B70A8546D22FFCULL, 0x2E1B21385C26C926ULL,
102199767f8SToomas Soome 	0x4D2C6DFC5AC42AEDULL, 0x53380D139D95B3DFULL,
103199767f8SToomas Soome 	0x650A73548BAF63DEULL, 0x766A0ABB3C77B2A8ULL,
104199767f8SToomas Soome 	0x81C2C92E47EDAEE6ULL, 0x92722C851482353BULL,
105199767f8SToomas Soome 	0xA2BFE8A14CF10364ULL, 0xA81A664BBC423001ULL,
106199767f8SToomas Soome 	0xC24B8B70D0F89791ULL, 0xC76C51A30654BE30ULL,
107199767f8SToomas Soome 	0xD192E819D6EF5218ULL, 0xD69906245565A910ULL,
108199767f8SToomas Soome 	0xF40E35855771202AULL, 0x106AA07032BBD1B8ULL,
109199767f8SToomas Soome 	0x19A4C116B8D2D0C8ULL, 0x1E376C085141AB53ULL,
110199767f8SToomas Soome 	0x2748774CDF8EEB99ULL, 0x34B0BCB5E19B48A8ULL,
111199767f8SToomas Soome 	0x391C0CB3C5C95A63ULL, 0x4ED8AA4AE3418ACBULL,
112199767f8SToomas Soome 	0x5B9CCA4F7763E373ULL, 0x682E6FF3D6B2B8A3ULL,
113199767f8SToomas Soome 	0x748F82EE5DEFB2FCULL, 0x78A5636F43172F60ULL,
114199767f8SToomas Soome 	0x84C87814A1F0AB72ULL, 0x8CC702081A6439ECULL,
115199767f8SToomas Soome 	0x90BEFFFA23631E28ULL, 0xA4506CEBDE82BDE9ULL,
116199767f8SToomas Soome 	0xBEF9A3F7B2C67915ULL, 0xC67178F2E372532BULL,
117199767f8SToomas Soome 	0xCA273ECEEA26619CULL, 0xD186B8C721C0C207ULL,
118199767f8SToomas Soome 	0xEADA7DD6CDE0EB1EULL, 0xF57D4F7FEE6ED178ULL,
119199767f8SToomas Soome 	0x06F067AA72176FBAULL, 0x0A637DC5A2C898A6ULL,
120199767f8SToomas Soome 	0x113F9804BEF90DAEULL, 0x1B710B35131C471BULL,
121199767f8SToomas Soome 	0x28DB77F523047D84ULL, 0x32CAAB7B40C72493ULL,
122199767f8SToomas Soome 	0x3C9EBE0A15C9BEBCULL, 0x431D67C49C100D4CULL,
123199767f8SToomas Soome 	0x4CC5D4BECB3E42B6ULL, 0x597F299CFC657E2AULL,
124199767f8SToomas Soome 	0x5FCB6FAB3AD6FAECULL, 0x6C44198C4A475817ULL
125199767f8SToomas Soome };
126199767f8SToomas Soome 
127199767f8SToomas Soome static void
SHA256Transform(uint32_t * H,const uint8_t * cp)128199767f8SToomas Soome SHA256Transform(uint32_t *H, const uint8_t *cp)
129199767f8SToomas Soome {
130199767f8SToomas Soome 	uint32_t a, b, c, d, e, f, g, h, t, T1, T2, W[64];
131199767f8SToomas Soome 
132199767f8SToomas Soome 	/* copy chunk into the first 16 words of the message schedule */
133199767f8SToomas Soome 	for (t = 0; t < 16; t++, cp += sizeof (uint32_t))
134199767f8SToomas Soome 		W[t] = (cp[0] << 24) | (cp[1] << 16) | (cp[2] << 8) | cp[3];
135199767f8SToomas Soome 
136199767f8SToomas Soome 	/* extend the first 16 words into the remaining 48 words */
137199767f8SToomas Soome 	for (t = 16; t < 64; t++)
138199767f8SToomas Soome 		W[t] = SIGMA1_256(W[t - 2]) + W[t - 7] +
139199767f8SToomas Soome 		    SIGMA0_256(W[t - 15]) + W[t - 16];
140199767f8SToomas Soome 
141199767f8SToomas Soome 	/* init working variables to the current hash value */
142199767f8SToomas Soome 	a = H[0]; b = H[1]; c = H[2]; d = H[3];
143199767f8SToomas Soome 	e = H[4]; f = H[5]; g = H[6]; h = H[7];
144199767f8SToomas Soome 
145199767f8SToomas Soome 	/* iterate the compression function for all rounds of the hash */
146199767f8SToomas Soome 	for (t = 0; t < 64; t++) {
147199767f8SToomas Soome 		T1 = h + BIGSIGMA1_256(e) + Ch(e, f, g) + SHA256_K[t] + W[t];
148199767f8SToomas Soome 		T2 = BIGSIGMA0_256(a) + Maj(a, b, c);
149199767f8SToomas Soome 		h = g; g = f; f = e; e = d + T1;
150199767f8SToomas Soome 		d = c; c = b; b = a; a = T1 + T2;
151199767f8SToomas Soome 	}
152199767f8SToomas Soome 
153199767f8SToomas Soome 	/* add the compressed chunk to the current hash value */
154199767f8SToomas Soome 	H[0] += a; H[1] += b; H[2] += c; H[3] += d;
155199767f8SToomas Soome 	H[4] += e; H[5] += f; H[6] += g; H[7] += h;
156199767f8SToomas Soome }
157199767f8SToomas Soome 
158199767f8SToomas Soome static void
SHA512Transform(uint64_t * H,const uint8_t * cp)159199767f8SToomas Soome SHA512Transform(uint64_t *H, const uint8_t *cp)
160199767f8SToomas Soome {
161199767f8SToomas Soome 	uint64_t a, b, c, d, e, f, g, h, t, T1, T2, W[80];
162199767f8SToomas Soome 
163199767f8SToomas Soome 	/* copy chunk into the first 16 words of the message schedule */
164199767f8SToomas Soome 	for (t = 0; t < 16; t++, cp += sizeof (uint64_t))
165199767f8SToomas Soome 		W[t] = ((uint64_t)cp[0] << 56) | ((uint64_t)cp[1] << 48) |
166199767f8SToomas Soome 		    ((uint64_t)cp[2] << 40) | ((uint64_t)cp[3] << 32) |
167199767f8SToomas Soome 		    ((uint64_t)cp[4] << 24) | ((uint64_t)cp[5] << 16) |
168199767f8SToomas Soome 		    ((uint64_t)cp[6] << 8) | (uint64_t)cp[7];
169199767f8SToomas Soome 
170199767f8SToomas Soome 	/* extend the first 16 words into the remaining 64 words */
171199767f8SToomas Soome 	for (t = 16; t < 80; t++)
172199767f8SToomas Soome 		W[t] = SIGMA1_512(W[t - 2]) + W[t - 7] +
173199767f8SToomas Soome 		    SIGMA0_512(W[t - 15]) + W[t - 16];
174199767f8SToomas Soome 
175199767f8SToomas Soome 	/* init working variables to the current hash value */
176199767f8SToomas Soome 	a = H[0]; b = H[1]; c = H[2]; d = H[3];
177199767f8SToomas Soome 	e = H[4]; f = H[5]; g = H[6]; h = H[7];
178199767f8SToomas Soome 
179199767f8SToomas Soome 	/* iterate the compression function for all rounds of the hash */
180199767f8SToomas Soome 	for (t = 0; t < 80; t++) {
181199767f8SToomas Soome 		T1 = h + BIGSIGMA1_512(e) + Ch(e, f, g) + SHA512_K[t] + W[t];
182199767f8SToomas Soome 		T2 = BIGSIGMA0_512(a) + Maj(a, b, c);
183199767f8SToomas Soome 		h = g; g = f; f = e; e = d + T1;
184199767f8SToomas Soome 		d = c; c = b; b = a; a = T1 + T2;
185199767f8SToomas Soome 	}
186199767f8SToomas Soome 
187199767f8SToomas Soome 	/* add the compressed chunk to the current hash value */
188199767f8SToomas Soome 	H[0] += a; H[1] += b; H[2] += c; H[3] += d;
189199767f8SToomas Soome 	H[4] += e; H[5] += f; H[6] += g; H[7] += h;
190199767f8SToomas Soome }
191199767f8SToomas Soome 
192199767f8SToomas Soome /*
193199767f8SToomas Soome  * Implements the SHA-224 and SHA-256 hash algos - to select between them
194199767f8SToomas Soome  * pass the appropriate initial values of 'H' and truncate the last 32 bits
195199767f8SToomas Soome  * in case of SHA-224.
196199767f8SToomas Soome  */
197199767f8SToomas Soome static void
SHA256(uint32_t * H,const void * buf,uint64_t size,zio_cksum_t * zcp)198199767f8SToomas Soome SHA256(uint32_t *H, const void *buf, uint64_t size, zio_cksum_t *zcp)
199199767f8SToomas Soome {
200199767f8SToomas Soome 	uint8_t pad[128];
201199767f8SToomas Soome 	unsigned padsize = size & 63;
202199767f8SToomas Soome 	unsigned i, k;
203199767f8SToomas Soome 
204199767f8SToomas Soome 	/* process all blocks up to the last one */
205199767f8SToomas Soome 	for (i = 0; i < size - padsize; i += 64)
206199767f8SToomas Soome 		SHA256Transform(H, (uint8_t *)buf + i);
207199767f8SToomas Soome 
208199767f8SToomas Soome 	/* process the last block and padding */
209199767f8SToomas Soome 	for (k = 0; k < padsize; k++)
210199767f8SToomas Soome 		pad[k] = ((uint8_t *)buf)[k+i];
211199767f8SToomas Soome 
212199767f8SToomas Soome 	for (pad[padsize++] = 0x80; (padsize & 63) != 56; padsize++)
213199767f8SToomas Soome 		pad[padsize] = 0;
214199767f8SToomas Soome 
215199767f8SToomas Soome 	for (i = 0; i < 8; i++)
216199767f8SToomas Soome 		pad[padsize++] = (size << 3) >> (56 - 8 * i);
217199767f8SToomas Soome 
218199767f8SToomas Soome 	for (i = 0; i < padsize; i += 64)
219199767f8SToomas Soome 		SHA256Transform(H, pad + i);
220199767f8SToomas Soome 
221199767f8SToomas Soome 	ZIO_SET_CHECKSUM(zcp,
222199767f8SToomas Soome 	    (uint64_t)H[0] << 32 | H[1],
223199767f8SToomas Soome 	    (uint64_t)H[2] << 32 | H[3],
224199767f8SToomas Soome 	    (uint64_t)H[4] << 32 | H[5],
225199767f8SToomas Soome 	    (uint64_t)H[6] << 32 | H[7]);
226199767f8SToomas Soome }
227199767f8SToomas Soome 
228199767f8SToomas Soome /*
229199767f8SToomas Soome  * encode 64bit data in big-endian format.
230199767f8SToomas Soome  */
231199767f8SToomas Soome static void
Encode64(uint8_t * output,uint64_t * input,size_t len)232199767f8SToomas Soome Encode64(uint8_t *output, uint64_t *input, size_t len)
233199767f8SToomas Soome {
234199767f8SToomas Soome 	size_t i, j;
235199767f8SToomas Soome 	for (i = 0, j = 0; j < len; i++, j += 8) {
236199767f8SToomas Soome 		output[j]	= (input[i] >> 56) & 0xff;
237199767f8SToomas Soome 		output[j + 1]	= (input[i] >> 48) & 0xff;
238199767f8SToomas Soome 		output[j + 2]	= (input[i] >> 40) & 0xff;
239199767f8SToomas Soome 		output[j + 3]	= (input[i] >> 32) & 0xff;
240199767f8SToomas Soome 		output[j + 4]	= (input[i] >> 24) & 0xff;
241199767f8SToomas Soome 		output[j + 5]	= (input[i] >> 16) & 0xff;
242199767f8SToomas Soome 		output[j + 6]	= (input[i] >>  8) & 0xff;
243199767f8SToomas Soome 		output[j + 7]	= input[i] & 0xff;
244199767f8SToomas Soome 	}
245199767f8SToomas Soome }
246199767f8SToomas Soome 
247199767f8SToomas Soome /*
248199767f8SToomas Soome  * Implements the SHA-384, SHA-512 and SHA-512/t hash algos - to select
249199767f8SToomas Soome  * between them pass the appropriate initial values for 'H'. The output
250199767f8SToomas Soome  * of this function is truncated to the first 256 bits that fit into 'zcp'.
251199767f8SToomas Soome  */
252199767f8SToomas Soome static void
SHA512(uint64_t * H,const void * buf,uint64_t size,zio_cksum_t * zcp)253199767f8SToomas Soome SHA512(uint64_t *H, const void *buf, uint64_t size, zio_cksum_t *zcp)
254199767f8SToomas Soome {
255199767f8SToomas Soome 	uint64_t	c64[2];
256199767f8SToomas Soome 	uint8_t		pad[256];
257199767f8SToomas Soome 	unsigned	padsize = size & 127;
258199767f8SToomas Soome 	unsigned	i, k;
259199767f8SToomas Soome 
260199767f8SToomas Soome 	/* process all blocks up to the last one */
261199767f8SToomas Soome 	for (i = 0; i < size - padsize; i += 128)
262199767f8SToomas Soome 		SHA512Transform(H, (uint8_t *)buf + i);
263199767f8SToomas Soome 
264199767f8SToomas Soome 	/* process the last block and padding */
265199767f8SToomas Soome 	for (k = 0; k < padsize; k++)
266199767f8SToomas Soome 		pad[k] = ((uint8_t *)buf)[k+i];
267199767f8SToomas Soome 
268199767f8SToomas Soome 	if (padsize < 112) {
269199767f8SToomas Soome 		for (pad[padsize++] = 0x80; padsize < 112; padsize++)
270199767f8SToomas Soome 			pad[padsize] = 0;
271199767f8SToomas Soome 	} else {
272199767f8SToomas Soome 		for (pad[padsize++] = 0x80; padsize < 240; padsize++)
273199767f8SToomas Soome 			pad[padsize] = 0;
274199767f8SToomas Soome 	}
275199767f8SToomas Soome 
276199767f8SToomas Soome 	c64[0] = 0;
277199767f8SToomas Soome 	c64[1] = size << 3;
278199767f8SToomas Soome 	Encode64(pad+padsize, c64, sizeof (c64));
279199767f8SToomas Soome 	padsize += sizeof (c64);
280199767f8SToomas Soome 
281199767f8SToomas Soome 	for (i = 0; i < padsize; i += 128)
282199767f8SToomas Soome 		SHA512Transform(H, pad + i);
283199767f8SToomas Soome 
284199767f8SToomas Soome 	/* truncate the output to the first 256 bits which fit into 'zcp' */
285199767f8SToomas Soome 	Encode64((uint8_t *)zcp, H, sizeof (uint64_t) * 4);
286199767f8SToomas Soome }
287199767f8SToomas Soome 
288199767f8SToomas Soome static void
zio_checksum_SHA256(const void * buf,uint64_t size,const void * ctx_template __unused,zio_cksum_t * zcp)289199767f8SToomas Soome zio_checksum_SHA256(const void *buf, uint64_t size,
290*8eef2ab6SToomas Soome     const void *ctx_template __unused, zio_cksum_t *zcp)
291199767f8SToomas Soome {
292199767f8SToomas Soome 	/* SHA-256 as per FIPS 180-4. */
293199767f8SToomas Soome 	uint32_t	H[] = {
294199767f8SToomas Soome 		0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
295199767f8SToomas Soome 		0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
296199767f8SToomas Soome 	};
297199767f8SToomas Soome 	SHA256(H, buf, size, zcp);
298199767f8SToomas Soome }
299199767f8SToomas Soome 
300199767f8SToomas Soome static void
zio_checksum_SHA512_native(const void * buf,uint64_t size,const void * ctx_template __unused,zio_cksum_t * zcp)301199767f8SToomas Soome zio_checksum_SHA512_native(const void *buf, uint64_t size,
302*8eef2ab6SToomas Soome     const void *ctx_template __unused, zio_cksum_t *zcp)
303199767f8SToomas Soome {
304199767f8SToomas Soome 	/* SHA-512/256 as per FIPS 180-4. */
305199767f8SToomas Soome 	uint64_t	H[] = {
306199767f8SToomas Soome 		0x22312194FC2BF72CULL, 0x9F555FA3C84C64C2ULL,
307199767f8SToomas Soome 		0x2393B86B6F53B151ULL, 0x963877195940EABDULL,
308199767f8SToomas Soome 		0x96283EE2A88EFFE3ULL, 0xBE5E1E2553863992ULL,
309199767f8SToomas Soome 		0x2B0199FC2C85B8AAULL, 0x0EB72DDC81C52CA2ULL
310199767f8SToomas Soome 	};
311199767f8SToomas Soome 	SHA512(H, buf, size, zcp);
312199767f8SToomas Soome }
313199767f8SToomas Soome 
314199767f8SToomas Soome static void
zio_checksum_SHA512_byteswap(const void * buf,uint64_t size,const void * ctx_template,zio_cksum_t * zcp)315199767f8SToomas Soome zio_checksum_SHA512_byteswap(const void *buf, uint64_t size,
316199767f8SToomas Soome     const void *ctx_template, zio_cksum_t *zcp)
317199767f8SToomas Soome {
318199767f8SToomas Soome 	zio_cksum_t	tmp;
319199767f8SToomas Soome 
320199767f8SToomas Soome 	zio_checksum_SHA512_native(buf, size, ctx_template, &tmp);
321199767f8SToomas Soome 	zcp->zc_word[0] = BSWAP_64(tmp.zc_word[0]);
322199767f8SToomas Soome 	zcp->zc_word[1] = BSWAP_64(tmp.zc_word[1]);
323199767f8SToomas Soome 	zcp->zc_word[2] = BSWAP_64(tmp.zc_word[2]);
324199767f8SToomas Soome 	zcp->zc_word[3] = BSWAP_64(tmp.zc_word[3]);
325199767f8SToomas Soome }
326