xref: /illumos-gate/usr/src/grub/grub-0.97/stage2/zfs_sha256.c (revision 9ce6e318fecae800270f382ed76162508c5d525b)
1 /*
2  *  GRUB  --  GRand Unified Bootloader
3  *  Copyright (C) 1999,2000,2001,2002,2003,2004  Free Software Foundation, Inc.
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program; if not, write to the Free Software
17  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19 /*
20  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
21  * Use is subject to license terms.
22  */
23 /*
24  * Copyright 2013 Saso Kiselkov.  All rights reserved.
25  * Copyright 2015 Toomas Soome <tsoome@me.com>
26  */
27 
28 #include "fsys_zfs.h"
29 
30 /*
31  * SHA-256 and SHA-512/256 hashes, as specified in FIPS 180-4, available at:
32  * http://csrc.nist.gov/cryptval
33  *
34  * This is a very compact implementation of SHA-256 and SHA-512/256.
35  * It is designed to be simple and portable, not to be fast.
36  */
37 
38 /*
39  * The literal definitions according to FIPS180-4 would be:
40  *
41  * 	Ch(x, y, z)     (((x) & (y)) ^ ((~(x)) & (z)))
42  * 	Maj(x, y, z)    (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
43  *
44  * We use logical equivalents which require one less op.
45  */
46 #define	Ch(x, y, z)	((z) ^ ((x) & ((y) ^ (z))))
47 #define	Maj(x, y, z)	(((x) & (y)) ^ ((z) & ((x) ^ (y))))
48 #define	ROTR(x, n)	(((x) >> (n)) | ((x) << ((sizeof (x) * NBBY)-(n))))
49 
50 /* SHA-224/256 operations */
51 #define	BIGSIGMA0_256(x)	(ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
52 #define	BIGSIGMA1_256(x)	(ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
53 #define	SIGMA0_256(x)		(ROTR(x, 7) ^ ROTR(x, 18) ^ ((x) >> 3))
54 #define	SIGMA1_256(x)		(ROTR(x, 17) ^ ROTR(x, 19) ^ ((x) >> 10))
55 
56 /* SHA-384/512 operations */
57 #define	BIGSIGMA0_512(x)	(ROTR((x), 28) ^ ROTR((x), 34) ^ ROTR((x), 39))
58 #define	BIGSIGMA1_512(x)	(ROTR((x), 14) ^ ROTR((x), 18) ^ ROTR((x), 41))
59 #define	SIGMA0_512(x)		(ROTR((x), 1) ^ ROTR((x), 8) ^ ((x) >> 7))
60 #define	SIGMA1_512(x)		(ROTR((x), 19) ^ ROTR((x), 61) ^ ((x) >> 6))
61 
62 /* SHA-256 round constants */
63 static const uint32_t SHA256_K[64] = {
64 	0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
65 	0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
66 	0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
67 	0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
68 	0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
69 	0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
70 	0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
71 	0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
72 	0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
73 	0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
74 	0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
75 	0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
76 	0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
77 	0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
78 	0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
79 	0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
80 };
81 
82 /* SHA-512 round constants */
83 static const uint64_t SHA512_K[80] = {
84 	0x428A2F98D728AE22ULL, 0x7137449123EF65CDULL,
85 	0xB5C0FBCFEC4D3B2FULL, 0xE9B5DBA58189DBBCULL,
86 	0x3956C25BF348B538ULL, 0x59F111F1B605D019ULL,
87 	0x923F82A4AF194F9BULL, 0xAB1C5ED5DA6D8118ULL,
88 	0xD807AA98A3030242ULL, 0x12835B0145706FBEULL,
89 	0x243185BE4EE4B28CULL, 0x550C7DC3D5FFB4E2ULL,
90 	0x72BE5D74F27B896FULL, 0x80DEB1FE3B1696B1ULL,
91 	0x9BDC06A725C71235ULL, 0xC19BF174CF692694ULL,
92 	0xE49B69C19EF14AD2ULL, 0xEFBE4786384F25E3ULL,
93 	0x0FC19DC68B8CD5B5ULL, 0x240CA1CC77AC9C65ULL,
94 	0x2DE92C6F592B0275ULL, 0x4A7484AA6EA6E483ULL,
95 	0x5CB0A9DCBD41FBD4ULL, 0x76F988DA831153B5ULL,
96 	0x983E5152EE66DFABULL, 0xA831C66D2DB43210ULL,
97 	0xB00327C898FB213FULL, 0xBF597FC7BEEF0EE4ULL,
98 	0xC6E00BF33DA88FC2ULL, 0xD5A79147930AA725ULL,
99 	0x06CA6351E003826FULL, 0x142929670A0E6E70ULL,
100 	0x27B70A8546D22FFCULL, 0x2E1B21385C26C926ULL,
101 	0x4D2C6DFC5AC42AEDULL, 0x53380D139D95B3DFULL,
102 	0x650A73548BAF63DEULL, 0x766A0ABB3C77B2A8ULL,
103 	0x81C2C92E47EDAEE6ULL, 0x92722C851482353BULL,
104 	0xA2BFE8A14CF10364ULL, 0xA81A664BBC423001ULL,
105 	0xC24B8B70D0F89791ULL, 0xC76C51A30654BE30ULL,
106 	0xD192E819D6EF5218ULL, 0xD69906245565A910ULL,
107 	0xF40E35855771202AULL, 0x106AA07032BBD1B8ULL,
108 	0x19A4C116B8D2D0C8ULL, 0x1E376C085141AB53ULL,
109 	0x2748774CDF8EEB99ULL, 0x34B0BCB5E19B48A8ULL,
110 	0x391C0CB3C5C95A63ULL, 0x4ED8AA4AE3418ACBULL,
111 	0x5B9CCA4F7763E373ULL, 0x682E6FF3D6B2B8A3ULL,
112 	0x748F82EE5DEFB2FCULL, 0x78A5636F43172F60ULL,
113 	0x84C87814A1F0AB72ULL, 0x8CC702081A6439ECULL,
114 	0x90BEFFFA23631E28ULL, 0xA4506CEBDE82BDE9ULL,
115 	0xBEF9A3F7B2C67915ULL, 0xC67178F2E372532BULL,
116 	0xCA273ECEEA26619CULL, 0xD186B8C721C0C207ULL,
117 	0xEADA7DD6CDE0EB1EULL, 0xF57D4F7FEE6ED178ULL,
118 	0x06F067AA72176FBAULL, 0x0A637DC5A2C898A6ULL,
119 	0x113F9804BEF90DAEULL, 0x1B710B35131C471BULL,
120 	0x28DB77F523047D84ULL, 0x32CAAB7B40C72493ULL,
121 	0x3C9EBE0A15C9BEBCULL, 0x431D67C49C100D4CULL,
122 	0x4CC5D4BECB3E42B6ULL, 0x597F299CFC657E2AULL,
123 	0x5FCB6FAB3AD6FAECULL, 0x6C44198C4A475817ULL
124 };
125 
126 static void
SHA256Transform(uint32_t * H,const uint8_t * cp)127 SHA256Transform(uint32_t *H, const uint8_t *cp)
128 {
129 	uint32_t a, b, c, d, e, f, g, h, t, T1, T2, W[64];
130 
131 	/* copy chunk into the first 16 words of the message schedule */
132 	for (t = 0; t < 16; t++, cp +=  sizeof (uint32_t))
133 		W[t] = (cp[0] << 24) | (cp[1] << 16) | (cp[2] << 8) | cp[3];
134 
135 	/* extend the first 16 words into the remaining 48 words */
136 	for (t = 16; t < 64; t++)
137 		W[t] = SIGMA1_256(W[t - 2]) + W[t - 7] +
138 		    SIGMA0_256(W[t - 15]) + W[t - 16];
139 
140 	/* init working variables to the current hash value */
141 	a = H[0]; b = H[1]; c = H[2]; d = H[3];
142 	e = H[4]; f = H[5]; g = H[6]; h = H[7];
143 
144 	/* iterate the compression function for all rounds of the hash */
145 	for (t = 0; t < 64; t++) {
146 		T1 = h + BIGSIGMA1_256(e) + Ch(e, f, g) + SHA256_K[t] + W[t];
147 		T2 = BIGSIGMA0_256(a) + Maj(a, b, c);
148 		h = g; g = f; f = e; e = d + T1;
149 		d = c; c = b; b = a; a = T1 + T2;
150 	}
151 
152 	/* add the compressed chunk to the current hash value */
153 	H[0] += a; H[1] += b; H[2] += c; H[3] += d;
154 	H[4] += e; H[5] += f; H[6] += g; H[7] += h;
155 }
156 
157 static void
SHA512Transform(uint64_t * H,const uint8_t * cp)158 SHA512Transform(uint64_t *H, const uint8_t *cp)
159 {
160 	uint64_t a, b, c, d, e, f, g, h, t, T1, T2, W[80];
161 
162 	/* copy chunk into the first 16 words of the message schedule */
163 	for (t = 0; t < 16; t++, cp += sizeof (uint64_t))
164 		W[t] = ((uint64_t)cp[0] << 56) | ((uint64_t)cp[1] << 48) |
165 		    ((uint64_t)cp[2] << 40) | ((uint64_t)cp[3] << 32) |
166 		    ((uint64_t)cp[4] << 24) | ((uint64_t)cp[5] << 16) |
167 		    ((uint64_t)cp[6] << 8) | (uint64_t)cp[7];
168 
169 	/* extend the first 16 words into the remaining 64 words */
170 	for (t = 16; t < 80; t++)
171 		W[t] = SIGMA1_512(W[t - 2]) + W[t - 7] +
172 		    SIGMA0_512(W[t - 15]) + W[t - 16];
173 
174 	/* init working variables to the current hash value */
175 	a = H[0]; b = H[1]; c = H[2]; d = H[3];
176 	e = H[4]; f = H[5]; g = H[6]; h = H[7];
177 
178 	/* iterate the compression function for all rounds of the hash */
179 	for (t = 0; t < 80; t++) {
180 		T1 = h + BIGSIGMA1_512(e) + Ch(e, f, g) + SHA512_K[t] + W[t];
181 		T2 = BIGSIGMA0_512(a) + Maj(a, b, c);
182 		h = g; g = f; f = e; e = d + T1;
183 		d = c; c = b; b = a; a = T1 + T2;
184 	}
185 
186 	/* add the compressed chunk to the current hash value */
187 	H[0] += a; H[1] += b; H[2] += c; H[3] += d;
188 	H[4] += e; H[5] += f; H[6] += g; H[7] += h;
189 }
190 
191 /*
192  * Implements the SHA-224 and SHA-256 hash algos - to select between them
193  * pass the appropriate initial values of 'H' and truncate the last 32 bits
194  * in case of SHA-224.
195  */
196 static void
SHA256(uint32_t * H,const void * buf,uint64_t size,zio_cksum_t * zcp)197 SHA256(uint32_t *H, const void *buf, uint64_t size, zio_cksum_t *zcp)
198 {
199 	uint8_t		pad[128];
200 	unsigned	padsize = size & 63;
201 	unsigned	i;
202 
203 	/* process all blocks up to the last one */
204 	for (i = 0; i < size - padsize; i += 64)
205 		SHA256Transform(H, (uint8_t *)buf + i);
206 
207 	/* process the last block and padding */
208 	for (i = 0; i < padsize; i++)
209 		pad[i] = ((uint8_t *)buf)[i];
210 
211 	for (pad[padsize++] = 0x80; (padsize & 63) != 56; padsize++)
212 		pad[padsize] = 0;
213 
214 	for (i = 0; i < 8; i++)
215 		pad[padsize++] = (size << 3) >> (56 - 8 * i);
216 
217 	for (i = 0; i < padsize; i += 64)
218 		SHA256Transform(H, pad + i);
219 
220 	ZIO_SET_CHECKSUM(zcp,
221 	    (uint64_t)H[0] << 32 | H[1],
222 	    (uint64_t)H[2] << 32 | H[3],
223 	    (uint64_t)H[4] << 32 | H[5],
224 	    (uint64_t)H[6] << 32 | H[7]);
225 }
226 
227 /*
228  * encode 64bit data in big-endian format.
229  */
230 static void
Encode64(uint8_t * output,uint64_t * input,size_t len)231 Encode64(uint8_t *output, uint64_t *input, size_t len)
232 {
233 	size_t i, j;
234 	for (i = 0, j = 0; j < len; i++, j += 8) {
235 		output[j]	= (input[i] >> 56) & 0xff;
236 		output[j + 1]	= (input[i] >> 48) & 0xff;
237 		output[j + 2]	= (input[i] >> 40) & 0xff;
238 		output[j + 3]	= (input[i] >> 32) & 0xff;
239 		output[j + 4]	= (input[i] >> 24) & 0xff;
240 		output[j + 5]	= (input[i] >> 16) & 0xff;
241 		output[j + 6]	= (input[i] >>  8) & 0xff;
242 		output[j + 7]	= input[i] & 0xff;
243 	}
244 }
245 
246 /*
247  * Implements the SHA-384, SHA-512 and SHA-512/t hash algos - to select
248  * between them pass the appropriate initial values for 'H'. The output
249  * of this function is truncated to the first 256 bits that fit into 'zcp'.
250  */
251 static void
SHA512(uint64_t * H,const void * buf,uint64_t size,zio_cksum_t * zcp)252 SHA512(uint64_t *H, const void *buf, uint64_t size, zio_cksum_t *zcp)
253 {
254 	uint64_t	c64[2];
255 	uint8_t		pad[256];
256 	unsigned	padsize = size & 127;
257 	unsigned	i, k;
258 
259 	/* process all blocks up to the last one */
260 	for (i = 0; i < size - padsize; i += 128)
261 		SHA512Transform(H, (uint8_t *)buf + i);
262 
263 	/* process the last block and padding */
264 	for (k = 0; k < padsize; k++)
265 		pad[k] = ((uint8_t *)buf)[k+i];
266 
267 	if (padsize < 112) {
268 		for (pad[padsize++] = 0x80; padsize < 112; padsize++)
269 			pad[padsize] = 0;
270 	} else {
271 		for (pad[padsize++] = 0x80; padsize < 240; padsize++)
272 			pad[padsize] = 0;
273 	}
274 
275 	c64[0] = 0;
276 	c64[1] = size << 3;
277 	Encode64(pad+padsize, c64, sizeof (c64));
278 	padsize += sizeof (c64);
279 
280 	for (i = 0; i < padsize; i += 128)
281 		SHA512Transform(H, pad + i);
282 
283 	/* truncate the output to the first 256 bits which fit into 'zcp' */
284 	Encode64((uint8_t *)zcp, H, sizeof (uint64_t) * 4);
285 }
286 
287 void
zio_checksum_SHA256(const void * buf,uint64_t size,zio_cksum_t * zcp)288 zio_checksum_SHA256(const void *buf, uint64_t size, zio_cksum_t *zcp)
289 {
290 	/* SHA-256 as per FIPS 180-4. */
291 	uint32_t	H[] = {
292 		0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
293 		0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
294 	};
295 	SHA256(H, buf, size, zcp);
296 }
297 
298 void
zio_checksum_SHA512(const void * buf,uint64_t size,zio_cksum_t * zcp)299 zio_checksum_SHA512(const void *buf, uint64_t size, zio_cksum_t *zcp)
300 {
301 	/* SHA-512/256 as per FIPS 180-4. */
302 	uint64_t	H[] = {
303 		0x22312194FC2BF72CULL, 0x9F555FA3C84C64C2ULL,
304 		0x2393B86B6F53B151ULL, 0x963877195940EABDULL,
305 		0x96283EE2A88EFFE3ULL, 0xBE5E1E2553863992ULL,
306 		0x2B0199FC2C85B8AAULL, 0x0EB72DDC81C52CA2ULL
307 	};
308 	SHA512(H, buf, size, zcp);
309 }
310