1185029Spjd/*
2185029Spjd * CDDL HEADER START
3185029Spjd *
4185029Spjd * The contents of this file are subject to the terms of the
5185029Spjd * Common Development and Distribution License, Version 1.0 only
6185029Spjd * (the "License").  You may not use this file except in compliance
7185029Spjd * with the License.
8185029Spjd *
9185029Spjd * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10185029Spjd * or http://www.opensolaris.org/os/licensing.
11185029Spjd * See the License for the specific language governing permissions
12185029Spjd * and limitations under the License.
13185029Spjd *
14185029Spjd * When distributing Covered Code, include this CDDL HEADER in each
15185029Spjd * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16185029Spjd * If applicable, add the following below this CDDL HEADER, with the
17185029Spjd * fields enclosed by brackets "[]" replaced with your own identifying
18185029Spjd * information: Portions Copyright [yyyy] [name of copyright owner]
19185029Spjd *
20185029Spjd * CDDL HEADER END
21185029Spjd */
22185029Spjd/*
23185029Spjd * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24185029Spjd * Use is subject to license terms.
25185029Spjd */
26185029Spjd
27185029Spjd/*#pragma ident	"%Z%%M%	%I%	%E% SMI"*/
28185029Spjd
29185029Spjd/*
30185029Spjd * SHA-256 checksum, as specified in FIPS 180-2, available at:
31185029Spjd * http://csrc.nist.gov/cryptval
32185029Spjd *
33185029Spjd * This is a very compact implementation of SHA-256.
34185029Spjd * It is designed to be simple and portable, not to be fast.
35185029Spjd */
36185029Spjd
37185029Spjd/*
38185029Spjd * The literal definitions according to FIPS180-2 would be:
39185029Spjd *
40185029Spjd * 	Ch(x, y, z)     (((x) & (y)) ^ ((~(x)) & (z)))
41185029Spjd * 	Maj(x, y, z)    (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
42185029Spjd *
43185029Spjd * We use logical equivalents which require one less op.
44185029Spjd */
45185029Spjd#define	Ch(x, y, z)	((z) ^ ((x) & ((y) ^ (z))))
46185029Spjd#define	Maj(x, y, z)	(((x) & (y)) ^ ((z) & ((x) ^ (y))))
47185029Spjd#define	Rot32(x, s)	(((x) >> s) | ((x) << (32 - s)))
48185029Spjd#define	SIGMA0(x)	(Rot32(x, 2) ^ Rot32(x, 13) ^ Rot32(x, 22))
49185029Spjd#define	SIGMA1(x)	(Rot32(x, 6) ^ Rot32(x, 11) ^ Rot32(x, 25))
50185029Spjd#define	sigma0(x)	(Rot32(x, 7) ^ Rot32(x, 18) ^ ((x) >> 3))
51185029Spjd#define	sigma1(x)	(Rot32(x, 17) ^ Rot32(x, 19) ^ ((x) >> 10))
52185029Spjd
53185029Spjdstatic const uint32_t SHA256_K[64] = {
54185029Spjd	0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
55185029Spjd	0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
56185029Spjd	0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
57185029Spjd	0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
58185029Spjd	0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
59185029Spjd	0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
60185029Spjd	0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
61185029Spjd	0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
62185029Spjd	0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
63185029Spjd	0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
64185029Spjd	0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
65185029Spjd	0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
66185029Spjd	0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
67185029Spjd	0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
68185029Spjd	0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
69185029Spjd	0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
70185029Spjd};
71185029Spjd
72185029Spjdstatic void
73185029SpjdSHA256Transform(uint32_t *H, const uint8_t *cp)
74185029Spjd{
75185029Spjd	uint32_t a, b, c, d, e, f, g, h, t, T1, T2, W[64];
76185029Spjd
77185029Spjd	for (t = 0; t < 16; t++, cp += 4)
78185029Spjd		W[t] = (cp[0] << 24) | (cp[1] << 16) | (cp[2] << 8) | cp[3];
79185029Spjd
80185029Spjd	for (t = 16; t < 64; t++)
81185029Spjd		W[t] = sigma1(W[t - 2]) + W[t - 7] +
82185029Spjd		    sigma0(W[t - 15]) + W[t - 16];
83185029Spjd
84185029Spjd	a = H[0]; b = H[1]; c = H[2]; d = H[3];
85185029Spjd	e = H[4]; f = H[5]; g = H[6]; h = H[7];
86185029Spjd
87185029Spjd	for (t = 0; t < 64; t++) {
88185029Spjd		T1 = h + SIGMA1(e) + Ch(e, f, g) + SHA256_K[t] + W[t];
89185029Spjd		T2 = SIGMA0(a) + Maj(a, b, c);
90185029Spjd		h = g; g = f; f = e; e = d + T1;
91185029Spjd		d = c; c = b; b = a; a = T1 + T2;
92185029Spjd	}
93185029Spjd
94185029Spjd	H[0] += a; H[1] += b; H[2] += c; H[3] += d;
95185029Spjd	H[4] += e; H[5] += f; H[6] += g; H[7] += h;
96185029Spjd}
97185029Spjd
98185029Spjdstatic void
99185029Spjdzio_checksum_SHA256(const void *buf, uint64_t size, zio_cksum_t *zcp)
100185029Spjd{
101185029Spjd	uint32_t H[8] = { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
102185029Spjd	    0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 };
103185029Spjd	uint8_t pad[128];
104185029Spjd	int padsize = size & 63;
105185029Spjd	int i;
106185029Spjd
107185029Spjd	for (i = 0; i < size - padsize; i += 64)
108185029Spjd		SHA256Transform(H, (uint8_t *)buf + i);
109185029Spjd
110185029Spjd	for (i = 0; i < padsize; i++)
111185029Spjd		pad[i] = ((uint8_t *)buf)[i];
112185029Spjd
113185029Spjd	for (pad[padsize++] = 0x80; (padsize & 63) != 56; padsize++)
114185029Spjd		pad[padsize] = 0;
115185029Spjd
116185029Spjd	for (i = 0; i < 8; i++)
117185029Spjd		pad[padsize++] = (size << 3) >> (56 - 8 * i);
118185029Spjd
119185029Spjd	for (i = 0; i < padsize; i += 64)
120185029Spjd		SHA256Transform(H, pad + i);
121185029Spjd
122185029Spjd	ZIO_SET_CHECKSUM(zcp,
123185029Spjd	    (uint64_t)H[0] << 32 | H[1],
124185029Spjd	    (uint64_t)H[2] << 32 | H[3],
125185029Spjd	    (uint64_t)H[4] << 32 | H[5],
126185029Spjd	    (uint64_t)H[6] << 32 | H[7]);
127185029Spjd}
128