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