1b1b8ab34Slling /*
2b1b8ab34Slling  *  GRUB  --  GRand Unified Bootloader
3b1b8ab34Slling  *  Copyright (C) 1999,2000,2001,2002,2003,2004  Free Software Foundation, Inc.
4b1b8ab34Slling  *
5b1b8ab34Slling  *  This program is free software; you can redistribute it and/or modify
6b1b8ab34Slling  *  it under the terms of the GNU General Public License as published by
7b1b8ab34Slling  *  the Free Software Foundation; either version 2 of the License, or
8b1b8ab34Slling  *  (at your option) any later version.
9b1b8ab34Slling  *
10b1b8ab34Slling  *  This program is distributed in the hope that it will be useful,
11b1b8ab34Slling  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12b1b8ab34Slling  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13b1b8ab34Slling  *  GNU General Public License for more details.
14b1b8ab34Slling  *
15b1b8ab34Slling  *  You should have received a copy of the GNU General Public License
16b1b8ab34Slling  *  along with this program; if not, write to the Free Software
17b1b8ab34Slling  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18b1b8ab34Slling  */
19b1b8ab34Slling /*
20b1b8ab34Slling  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
21b1b8ab34Slling  * Use is subject to license terms.
22b1b8ab34Slling  */
2345818ee1SMatthew Ahrens /*
2445818ee1SMatthew Ahrens  * Copyright 2013 Saso Kiselkov.  All rights reserved.
25*9ce6e318SToomas Soome  * Copyright 2015 Toomas Soome <tsoome@me.com>
2645818ee1SMatthew Ahrens  */
27b1b8ab34Slling 
28b1b8ab34Slling #include "fsys_zfs.h"
29b1b8ab34Slling 
30b1b8ab34Slling /*
3145818ee1SMatthew Ahrens  * SHA-256 and SHA-512/256 hashes, as specified in FIPS 180-4, available at:
32b1b8ab34Slling  * http://csrc.nist.gov/cryptval
33b1b8ab34Slling  *
3445818ee1SMatthew Ahrens  * This is a very compact implementation of SHA-256 and SHA-512/256.
35b1b8ab34Slling  * It is designed to be simple and portable, not to be fast.
36b1b8ab34Slling  */
37b1b8ab34Slling 
38b1b8ab34Slling /*
3945818ee1SMatthew Ahrens  * The literal definitions according to FIPS180-4 would be:
40b1b8ab34Slling  *
41b1b8ab34Slling  * 	Ch(x, y, z)     (((x) & (y)) ^ ((~(x)) & (z)))
42b1b8ab34Slling  * 	Maj(x, y, z)    (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
43b1b8ab34Slling  *
44b1b8ab34Slling  * We use logical equivalents which require one less op.
45b1b8ab34Slling  */
46b1b8ab34Slling #define	Ch(x, y, z)	((z) ^ ((x) & ((y) ^ (z))))
47b1b8ab34Slling #define	Maj(x, y, z)	(((x) & (y)) ^ ((z) & ((x) ^ (y))))
4845818ee1SMatthew Ahrens #define	ROTR(x, n)	(((x) >> (n)) | ((x) << ((sizeof (x) * NBBY)-(n))))
4945818ee1SMatthew Ahrens 
5045818ee1SMatthew Ahrens /* SHA-224/256 operations */
5145818ee1SMatthew Ahrens #define	BIGSIGMA0_256(x)	(ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
5245818ee1SMatthew Ahrens #define	BIGSIGMA1_256(x)	(ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
5345818ee1SMatthew Ahrens #define	SIGMA0_256(x)		(ROTR(x, 7) ^ ROTR(x, 18) ^ ((x) >> 3))
5445818ee1SMatthew Ahrens #define	SIGMA1_256(x)		(ROTR(x, 17) ^ ROTR(x, 19) ^ ((x) >> 10))
55b1b8ab34Slling 
5645818ee1SMatthew Ahrens /* SHA-384/512 operations */
5745818ee1SMatthew Ahrens #define	BIGSIGMA0_512(x)	(ROTR((x), 28) ^ ROTR((x), 34) ^ ROTR((x), 39))
5845818ee1SMatthew Ahrens #define	BIGSIGMA1_512(x)	(ROTR((x), 14) ^ ROTR((x), 18) ^ ROTR((x), 41))
5945818ee1SMatthew Ahrens #define	SIGMA0_512(x)		(ROTR((x), 1) ^ ROTR((x), 8) ^ ((x) >> 7))
6045818ee1SMatthew Ahrens #define	SIGMA1_512(x)		(ROTR((x), 19) ^ ROTR((x), 61) ^ ((x) >> 6))
6145818ee1SMatthew Ahrens 
6245818ee1SMatthew Ahrens /* SHA-256 round constants */
63b1b8ab34Slling static const uint32_t SHA256_K[64] = {
64b1b8ab34Slling 	0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
65b1b8ab34Slling 	0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
66b1b8ab34Slling 	0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
67b1b8ab34Slling 	0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
68b1b8ab34Slling 	0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
69b1b8ab34Slling 	0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
70b1b8ab34Slling 	0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
71b1b8ab34Slling 	0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
72b1b8ab34Slling 	0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
73b1b8ab34Slling 	0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
74b1b8ab34Slling 	0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
75b1b8ab34Slling 	0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
76b1b8ab34Slling 	0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
77b1b8ab34Slling 	0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
78b1b8ab34Slling 	0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
79b1b8ab34Slling 	0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
80b1b8ab34Slling };
81b1b8ab34Slling 
8245818ee1SMatthew Ahrens /* SHA-512 round constants */
8345818ee1SMatthew Ahrens static const uint64_t SHA512_K[80] = {
8445818ee1SMatthew Ahrens 	0x428A2F98D728AE22ULL, 0x7137449123EF65CDULL,
8545818ee1SMatthew Ahrens 	0xB5C0FBCFEC4D3B2FULL, 0xE9B5DBA58189DBBCULL,
8645818ee1SMatthew Ahrens 	0x3956C25BF348B538ULL, 0x59F111F1B605D019ULL,
8745818ee1SMatthew Ahrens 	0x923F82A4AF194F9BULL, 0xAB1C5ED5DA6D8118ULL,
8845818ee1SMatthew Ahrens 	0xD807AA98A3030242ULL, 0x12835B0145706FBEULL,
8945818ee1SMatthew Ahrens 	0x243185BE4EE4B28CULL, 0x550C7DC3D5FFB4E2ULL,
9045818ee1SMatthew Ahrens 	0x72BE5D74F27B896FULL, 0x80DEB1FE3B1696B1ULL,
9145818ee1SMatthew Ahrens 	0x9BDC06A725C71235ULL, 0xC19BF174CF692694ULL,
9245818ee1SMatthew Ahrens 	0xE49B69C19EF14AD2ULL, 0xEFBE4786384F25E3ULL,
9345818ee1SMatthew Ahrens 	0x0FC19DC68B8CD5B5ULL, 0x240CA1CC77AC9C65ULL,
9445818ee1SMatthew Ahrens 	0x2DE92C6F592B0275ULL, 0x4A7484AA6EA6E483ULL,
9545818ee1SMatthew Ahrens 	0x5CB0A9DCBD41FBD4ULL, 0x76F988DA831153B5ULL,
9645818ee1SMatthew Ahrens 	0x983E5152EE66DFABULL, 0xA831C66D2DB43210ULL,
9745818ee1SMatthew Ahrens 	0xB00327C898FB213FULL, 0xBF597FC7BEEF0EE4ULL,
9845818ee1SMatthew Ahrens 	0xC6E00BF33DA88FC2ULL, 0xD5A79147930AA725ULL,
9945818ee1SMatthew Ahrens 	0x06CA6351E003826FULL, 0x142929670A0E6E70ULL,
10045818ee1SMatthew Ahrens 	0x27B70A8546D22FFCULL, 0x2E1B21385C26C926ULL,
10145818ee1SMatthew Ahrens 	0x4D2C6DFC5AC42AEDULL, 0x53380D139D95B3DFULL,
10245818ee1SMatthew Ahrens 	0x650A73548BAF63DEULL, 0x766A0ABB3C77B2A8ULL,
10345818ee1SMatthew Ahrens 	0x81C2C92E47EDAEE6ULL, 0x92722C851482353BULL,
10445818ee1SMatthew Ahrens 	0xA2BFE8A14CF10364ULL, 0xA81A664BBC423001ULL,
10545818ee1SMatthew Ahrens 	0xC24B8B70D0F89791ULL, 0xC76C51A30654BE30ULL,
10645818ee1SMatthew Ahrens 	0xD192E819D6EF5218ULL, 0xD69906245565A910ULL,
10745818ee1SMatthew Ahrens 	0xF40E35855771202AULL, 0x106AA07032BBD1B8ULL,
10845818ee1SMatthew Ahrens 	0x19A4C116B8D2D0C8ULL, 0x1E376C085141AB53ULL,
10945818ee1SMatthew Ahrens 	0x2748774CDF8EEB99ULL, 0x34B0BCB5E19B48A8ULL,
11045818ee1SMatthew Ahrens 	0x391C0CB3C5C95A63ULL, 0x4ED8AA4AE3418ACBULL,
11145818ee1SMatthew Ahrens 	0x5B9CCA4F7763E373ULL, 0x682E6FF3D6B2B8A3ULL,
11245818ee1SMatthew Ahrens 	0x748F82EE5DEFB2FCULL, 0x78A5636F43172F60ULL,
11345818ee1SMatthew Ahrens 	0x84C87814A1F0AB72ULL, 0x8CC702081A6439ECULL,
11445818ee1SMatthew Ahrens 	0x90BEFFFA23631E28ULL, 0xA4506CEBDE82BDE9ULL,
11545818ee1SMatthew Ahrens 	0xBEF9A3F7B2C67915ULL, 0xC67178F2E372532BULL,
11645818ee1SMatthew Ahrens 	0xCA273ECEEA26619CULL, 0xD186B8C721C0C207ULL,
11745818ee1SMatthew Ahrens 	0xEADA7DD6CDE0EB1EULL, 0xF57D4F7FEE6ED178ULL,
11845818ee1SMatthew Ahrens 	0x06F067AA72176FBAULL, 0x0A637DC5A2C898A6ULL,
11945818ee1SMatthew Ahrens 	0x113F9804BEF90DAEULL, 0x1B710B35131C471BULL,
12045818ee1SMatthew Ahrens 	0x28DB77F523047D84ULL, 0x32CAAB7B40C72493ULL,
12145818ee1SMatthew Ahrens 	0x3C9EBE0A15C9BEBCULL, 0x431D67C49C100D4CULL,
12245818ee1SMatthew Ahrens 	0x4CC5D4BECB3E42B6ULL, 0x597F299CFC657E2AULL,
12345818ee1SMatthew Ahrens 	0x5FCB6FAB3AD6FAECULL, 0x6C44198C4A475817ULL
12445818ee1SMatthew Ahrens };
12545818ee1SMatthew Ahrens 
126b1b8ab34Slling static void
SHA256Transform(uint32_t * H,const uint8_t * cp)127b1b8ab34Slling SHA256Transform(uint32_t *H, const uint8_t *cp)
128b1b8ab34Slling {
129b1b8ab34Slling 	uint32_t a, b, c, d, e, f, g, h, t, T1, T2, W[64];
130b1b8ab34Slling 
13145818ee1SMatthew Ahrens 	/* copy chunk into the first 16 words of the message schedule */
13245818ee1SMatthew Ahrens 	for (t = 0; t < 16; t++, cp +=  sizeof (uint32_t))
133b1b8ab34Slling 		W[t] = (cp[0] << 24) | (cp[1] << 16) | (cp[2] << 8) | cp[3];
134b1b8ab34Slling 
13545818ee1SMatthew Ahrens 	/* extend the first 16 words into the remaining 48 words */
136b1b8ab34Slling 	for (t = 16; t < 64; t++)
13745818ee1SMatthew Ahrens 		W[t] = SIGMA1_256(W[t - 2]) + W[t - 7] +
13845818ee1SMatthew Ahrens 		    SIGMA0_256(W[t - 15]) + W[t - 16];
139b1b8ab34Slling 
14045818ee1SMatthew Ahrens 	/* init working variables to the current hash value */
141b1b8ab34Slling 	a = H[0]; b = H[1]; c = H[2]; d = H[3];
142b1b8ab34Slling 	e = H[4]; f = H[5]; g = H[6]; h = H[7];
143b1b8ab34Slling 
14445818ee1SMatthew Ahrens 	/* iterate the compression function for all rounds of the hash */
145b1b8ab34Slling 	for (t = 0; t < 64; t++) {
14645818ee1SMatthew Ahrens 		T1 = h + BIGSIGMA1_256(e) + Ch(e, f, g) + SHA256_K[t] + W[t];
14745818ee1SMatthew Ahrens 		T2 = BIGSIGMA0_256(a) + Maj(a, b, c);
148b1b8ab34Slling 		h = g; g = f; f = e; e = d + T1;
149b1b8ab34Slling 		d = c; c = b; b = a; a = T1 + T2;
150b1b8ab34Slling 	}
151b1b8ab34Slling 
15245818ee1SMatthew Ahrens 	/* add the compressed chunk to the current hash value */
153b1b8ab34Slling 	H[0] += a; H[1] += b; H[2] += c; H[3] += d;
154b1b8ab34Slling 	H[4] += e; H[5] += f; H[6] += g; H[7] += h;
155b1b8ab34Slling }
156b1b8ab34Slling 
15745818ee1SMatthew Ahrens static void
SHA512Transform(uint64_t * H,const uint8_t * cp)15845818ee1SMatthew Ahrens SHA512Transform(uint64_t *H, const uint8_t *cp)
159b1b8ab34Slling {
16045818ee1SMatthew Ahrens 	uint64_t a, b, c, d, e, f, g, h, t, T1, T2, W[80];
16145818ee1SMatthew Ahrens 
16245818ee1SMatthew Ahrens 	/* copy chunk into the first 16 words of the message schedule */
16345818ee1SMatthew Ahrens 	for (t = 0; t < 16; t++, cp += sizeof (uint64_t))
16445818ee1SMatthew Ahrens 		W[t] = ((uint64_t)cp[0] << 56) | ((uint64_t)cp[1] << 48) |
16545818ee1SMatthew Ahrens 		    ((uint64_t)cp[2] << 40) | ((uint64_t)cp[3] << 32) |
166*9ce6e318SToomas Soome 		    ((uint64_t)cp[4] << 24) | ((uint64_t)cp[5] << 16) |
167*9ce6e318SToomas Soome 		    ((uint64_t)cp[6] << 8) | (uint64_t)cp[7];
168b1b8ab34Slling 
16945818ee1SMatthew Ahrens 	/* extend the first 16 words into the remaining 64 words */
17045818ee1SMatthew Ahrens 	for (t = 16; t < 80; t++)
17145818ee1SMatthew Ahrens 		W[t] = SIGMA1_512(W[t - 2]) + W[t - 7] +
17245818ee1SMatthew Ahrens 		    SIGMA0_512(W[t - 15]) + W[t - 16];
17345818ee1SMatthew Ahrens 
17445818ee1SMatthew Ahrens 	/* init working variables to the current hash value */
17545818ee1SMatthew Ahrens 	a = H[0]; b = H[1]; c = H[2]; d = H[3];
17645818ee1SMatthew Ahrens 	e = H[4]; f = H[5]; g = H[6]; h = H[7];
17745818ee1SMatthew Ahrens 
17845818ee1SMatthew Ahrens 	/* iterate the compression function for all rounds of the hash */
17945818ee1SMatthew Ahrens 	for (t = 0; t < 80; t++) {
18045818ee1SMatthew Ahrens 		T1 = h + BIGSIGMA1_512(e) + Ch(e, f, g) + SHA512_K[t] + W[t];
18145818ee1SMatthew Ahrens 		T2 = BIGSIGMA0_512(a) + Maj(a, b, c);
18245818ee1SMatthew Ahrens 		h = g; g = f; f = e; e = d + T1;
18345818ee1SMatthew Ahrens 		d = c; c = b; b = a; a = T1 + T2;
18445818ee1SMatthew Ahrens 	}
18545818ee1SMatthew Ahrens 
18645818ee1SMatthew Ahrens 	/* add the compressed chunk to the current hash value */
18745818ee1SMatthew Ahrens 	H[0] += a; H[1] += b; H[2] += c; H[3] += d;
18845818ee1SMatthew Ahrens 	H[4] += e; H[5] += f; H[6] += g; H[7] += h;
18945818ee1SMatthew Ahrens }
19045818ee1SMatthew Ahrens 
19145818ee1SMatthew Ahrens /*
19245818ee1SMatthew Ahrens  * Implements the SHA-224 and SHA-256 hash algos - to select between them
19345818ee1SMatthew Ahrens  * pass the appropriate initial values of 'H' and truncate the last 32 bits
19445818ee1SMatthew Ahrens  * in case of SHA-224.
19545818ee1SMatthew Ahrens  */
19645818ee1SMatthew Ahrens static void
SHA256(uint32_t * H,const void * buf,uint64_t size,zio_cksum_t * zcp)19745818ee1SMatthew Ahrens SHA256(uint32_t *H, const void *buf, uint64_t size, zio_cksum_t *zcp)
19845818ee1SMatthew Ahrens {
19945818ee1SMatthew Ahrens 	uint8_t		pad[128];
20045818ee1SMatthew Ahrens 	unsigned	padsize = size & 63;
20145818ee1SMatthew Ahrens 	unsigned	i;
20245818ee1SMatthew Ahrens 
20345818ee1SMatthew Ahrens 	/* process all blocks up to the last one */
204b1b8ab34Slling 	for (i = 0; i < size - padsize; i += 64)
205b1b8ab34Slling 		SHA256Transform(H, (uint8_t *)buf + i);
206b1b8ab34Slling 
20745818ee1SMatthew Ahrens 	/* process the last block and padding */
208b1b8ab34Slling 	for (i = 0; i < padsize; i++)
209b1b8ab34Slling 		pad[i] = ((uint8_t *)buf)[i];
210b1b8ab34Slling 
211b1b8ab34Slling 	for (pad[padsize++] = 0x80; (padsize & 63) != 56; padsize++)
212b1b8ab34Slling 		pad[padsize] = 0;
213b1b8ab34Slling 
214b1b8ab34Slling 	for (i = 0; i < 8; i++)
215b1b8ab34Slling 		pad[padsize++] = (size << 3) >> (56 - 8 * i);
216b1b8ab34Slling 
217b1b8ab34Slling 	for (i = 0; i < padsize; i += 64)
218b1b8ab34Slling 		SHA256Transform(H, pad + i);
219b1b8ab34Slling 
220b1b8ab34Slling 	ZIO_SET_CHECKSUM(zcp,
221b1b8ab34Slling 	    (uint64_t)H[0] << 32 | H[1],
222b1b8ab34Slling 	    (uint64_t)H[2] << 32 | H[3],
223b1b8ab34Slling 	    (uint64_t)H[4] << 32 | H[5],
224b1b8ab34Slling 	    (uint64_t)H[6] << 32 | H[7]);
225b1b8ab34Slling }
22645818ee1SMatthew Ahrens 
227*9ce6e318SToomas Soome /*
228*9ce6e318SToomas Soome  * encode 64bit data in big-endian format.
229*9ce6e318SToomas Soome  */
230*9ce6e318SToomas Soome static void
Encode64(uint8_t * output,uint64_t * input,size_t len)231*9ce6e318SToomas Soome Encode64(uint8_t *output, uint64_t *input, size_t len)
232*9ce6e318SToomas Soome {
233*9ce6e318SToomas Soome 	size_t i, j;
234*9ce6e318SToomas Soome 	for (i = 0, j = 0; j < len; i++, j += 8) {
235*9ce6e318SToomas Soome 		output[j]	= (input[i] >> 56) & 0xff;
236*9ce6e318SToomas Soome 		output[j + 1]	= (input[i] >> 48) & 0xff;
237*9ce6e318SToomas Soome 		output[j + 2]	= (input[i] >> 40) & 0xff;
238*9ce6e318SToomas Soome 		output[j + 3]	= (input[i] >> 32) & 0xff;
239*9ce6e318SToomas Soome 		output[j + 4]	= (input[i] >> 24) & 0xff;
240*9ce6e318SToomas Soome 		output[j + 5]	= (input[i] >> 16) & 0xff;
241*9ce6e318SToomas Soome 		output[j + 6]	= (input[i] >>  8) & 0xff;
242*9ce6e318SToomas Soome 		output[j + 7]	= input[i] & 0xff;
243*9ce6e318SToomas Soome 	}
244*9ce6e318SToomas Soome }
245*9ce6e318SToomas Soome 
24645818ee1SMatthew Ahrens /*
24745818ee1SMatthew Ahrens  * Implements the SHA-384, SHA-512 and SHA-512/t hash algos - to select
24845818ee1SMatthew Ahrens  * between them pass the appropriate initial values for 'H'. The output
24945818ee1SMatthew Ahrens  * of this function is truncated to the first 256 bits that fit into 'zcp'.
25045818ee1SMatthew Ahrens  */
25145818ee1SMatthew Ahrens static void
SHA512(uint64_t * H,const void * buf,uint64_t size,zio_cksum_t * zcp)25245818ee1SMatthew Ahrens SHA512(uint64_t *H, const void *buf, uint64_t size, zio_cksum_t *zcp)
25345818ee1SMatthew Ahrens {
254*9ce6e318SToomas Soome 	uint64_t	c64[2];
25545818ee1SMatthew Ahrens 	uint8_t		pad[256];
25645818ee1SMatthew Ahrens 	unsigned	padsize = size & 127;
257*9ce6e318SToomas Soome 	unsigned	i, k;
25845818ee1SMatthew Ahrens 
25945818ee1SMatthew Ahrens 	/* process all blocks up to the last one */
26045818ee1SMatthew Ahrens 	for (i = 0; i < size - padsize; i += 128)
26145818ee1SMatthew Ahrens 		SHA512Transform(H, (uint8_t *)buf + i);
26245818ee1SMatthew Ahrens 
26345818ee1SMatthew Ahrens 	/* process the last block and padding */
264*9ce6e318SToomas Soome 	for (k = 0; k < padsize; k++)
265*9ce6e318SToomas Soome 		pad[k] = ((uint8_t *)buf)[k+i];
266*9ce6e318SToomas Soome 
267*9ce6e318SToomas Soome 	if (padsize < 112) {
268*9ce6e318SToomas Soome 		for (pad[padsize++] = 0x80; padsize < 112; padsize++)
269*9ce6e318SToomas Soome 			pad[padsize] = 0;
270*9ce6e318SToomas Soome 	} else {
271*9ce6e318SToomas Soome 		for (pad[padsize++] = 0x80; padsize < 240; padsize++)
272*9ce6e318SToomas Soome 			pad[padsize] = 0;
273*9ce6e318SToomas Soome 	}
27445818ee1SMatthew Ahrens 
275*9ce6e318SToomas Soome 	c64[0] = 0;
276*9ce6e318SToomas Soome 	c64[1] = size << 3;
277*9ce6e318SToomas Soome 	Encode64(pad+padsize, c64, sizeof (c64));
278*9ce6e318SToomas Soome 	padsize += sizeof (c64);
27945818ee1SMatthew Ahrens 
28045818ee1SMatthew Ahrens 	for (i = 0; i < padsize; i += 128)
28145818ee1SMatthew Ahrens 		SHA512Transform(H, pad + i);
28245818ee1SMatthew Ahrens 
28345818ee1SMatthew Ahrens 	/* truncate the output to the first 256 bits which fit into 'zcp' */
284*9ce6e318SToomas Soome 	Encode64((uint8_t *)zcp, H, sizeof (uint64_t) * 4);
28545818ee1SMatthew Ahrens }
28645818ee1SMatthew Ahrens 
28745818ee1SMatthew Ahrens void
zio_checksum_SHA256(const void * buf,uint64_t size,zio_cksum_t * zcp)28845818ee1SMatthew Ahrens zio_checksum_SHA256(const void *buf, uint64_t size, zio_cksum_t *zcp)
28945818ee1SMatthew Ahrens {
29045818ee1SMatthew Ahrens 	/* SHA-256 as per FIPS 180-4. */
29145818ee1SMatthew Ahrens 	uint32_t	H[] = {
29245818ee1SMatthew Ahrens 		0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
29345818ee1SMatthew Ahrens 		0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
29445818ee1SMatthew Ahrens 	};
29545818ee1SMatthew Ahrens 	SHA256(H, buf, size, zcp);
29645818ee1SMatthew Ahrens }
29745818ee1SMatthew Ahrens 
29845818ee1SMatthew Ahrens void
zio_checksum_SHA512(const void * buf,uint64_t size,zio_cksum_t * zcp)29945818ee1SMatthew Ahrens zio_checksum_SHA512(const void *buf, uint64_t size, zio_cksum_t *zcp)
30045818ee1SMatthew Ahrens {
30145818ee1SMatthew Ahrens 	/* SHA-512/256 as per FIPS 180-4. */
30245818ee1SMatthew Ahrens 	uint64_t	H[] = {
30345818ee1SMatthew Ahrens 		0x22312194FC2BF72CULL, 0x9F555FA3C84C64C2ULL,
30445818ee1SMatthew Ahrens 		0x2393B86B6F53B151ULL, 0x963877195940EABDULL,
30545818ee1SMatthew Ahrens 		0x96283EE2A88EFFE3ULL, 0xBE5E1E2553863992ULL,
30645818ee1SMatthew Ahrens 		0x2B0199FC2C85B8AAULL, 0x0EB72DDC81C52CA2ULL
30745818ee1SMatthew Ahrens 	};
30845818ee1SMatthew Ahrens 	SHA512(H, buf, size, zcp);
30945818ee1SMatthew Ahrens }
310