11ba4a712SPawel Jakub Dawidek /* 21ba4a712SPawel Jakub Dawidek * CDDL HEADER START 31ba4a712SPawel Jakub Dawidek * 41ba4a712SPawel Jakub Dawidek * The contents of this file are subject to the terms of the 51ba4a712SPawel Jakub Dawidek * Common Development and Distribution License, Version 1.0 only 61ba4a712SPawel Jakub Dawidek * (the "License"). You may not use this file except in compliance 71ba4a712SPawel Jakub Dawidek * with the License. 81ba4a712SPawel Jakub Dawidek * 91ba4a712SPawel Jakub Dawidek * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 101ba4a712SPawel Jakub Dawidek * or http://www.opensolaris.org/os/licensing. 111ba4a712SPawel Jakub Dawidek * See the License for the specific language governing permissions 121ba4a712SPawel Jakub Dawidek * and limitations under the License. 131ba4a712SPawel Jakub Dawidek * 141ba4a712SPawel Jakub Dawidek * When distributing Covered Code, include this CDDL HEADER in each 151ba4a712SPawel Jakub Dawidek * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 161ba4a712SPawel Jakub Dawidek * If applicable, add the following below this CDDL HEADER, with the 171ba4a712SPawel Jakub Dawidek * fields enclosed by brackets "[]" replaced with your own identifying 181ba4a712SPawel Jakub Dawidek * information: Portions Copyright [yyyy] [name of copyright owner] 191ba4a712SPawel Jakub Dawidek * 201ba4a712SPawel Jakub Dawidek * CDDL HEADER END 211ba4a712SPawel Jakub Dawidek */ 221ba4a712SPawel Jakub Dawidek /* 231ba4a712SPawel Jakub Dawidek * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 241ba4a712SPawel Jakub Dawidek * Use is subject to license terms. 251ba4a712SPawel Jakub Dawidek */ 261ba4a712SPawel Jakub Dawidek 271ba4a712SPawel Jakub Dawidek /*#pragma ident "%Z%%M% %I% %E% SMI"*/ 281ba4a712SPawel Jakub Dawidek 291ba4a712SPawel Jakub Dawidek /* 301ba4a712SPawel Jakub Dawidek * SHA-256 checksum, as specified in FIPS 180-2, available at: 311ba4a712SPawel Jakub Dawidek * http://csrc.nist.gov/cryptval 321ba4a712SPawel Jakub Dawidek * 331ba4a712SPawel Jakub Dawidek * This is a very compact implementation of SHA-256. 341ba4a712SPawel Jakub Dawidek * It is designed to be simple and portable, not to be fast. 351ba4a712SPawel Jakub Dawidek */ 361ba4a712SPawel Jakub Dawidek 371ba4a712SPawel Jakub Dawidek /* 381ba4a712SPawel Jakub Dawidek * The literal definitions according to FIPS180-2 would be: 391ba4a712SPawel Jakub Dawidek * 401ba4a712SPawel Jakub Dawidek * Ch(x, y, z) (((x) & (y)) ^ ((~(x)) & (z))) 411ba4a712SPawel Jakub Dawidek * Maj(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) 421ba4a712SPawel Jakub Dawidek * 431ba4a712SPawel Jakub Dawidek * We use logical equivalents which require one less op. 441ba4a712SPawel Jakub Dawidek */ 451ba4a712SPawel Jakub Dawidek #define Ch(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) 461ba4a712SPawel Jakub Dawidek #define Maj(x, y, z) (((x) & (y)) ^ ((z) & ((x) ^ (y)))) 471ba4a712SPawel Jakub Dawidek #define Rot32(x, s) (((x) >> s) | ((x) << (32 - s))) 481ba4a712SPawel Jakub Dawidek #define SIGMA0(x) (Rot32(x, 2) ^ Rot32(x, 13) ^ Rot32(x, 22)) 491ba4a712SPawel Jakub Dawidek #define SIGMA1(x) (Rot32(x, 6) ^ Rot32(x, 11) ^ Rot32(x, 25)) 501ba4a712SPawel Jakub Dawidek #define sigma0(x) (Rot32(x, 7) ^ Rot32(x, 18) ^ ((x) >> 3)) 511ba4a712SPawel Jakub Dawidek #define sigma1(x) (Rot32(x, 17) ^ Rot32(x, 19) ^ ((x) >> 10)) 521ba4a712SPawel Jakub Dawidek 531ba4a712SPawel Jakub Dawidek static const uint32_t SHA256_K[64] = { 541ba4a712SPawel Jakub Dawidek 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 551ba4a712SPawel Jakub Dawidek 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 561ba4a712SPawel Jakub Dawidek 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 571ba4a712SPawel Jakub Dawidek 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 581ba4a712SPawel Jakub Dawidek 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 591ba4a712SPawel Jakub Dawidek 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 601ba4a712SPawel Jakub Dawidek 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 611ba4a712SPawel Jakub Dawidek 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 621ba4a712SPawel Jakub Dawidek 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 631ba4a712SPawel Jakub Dawidek 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 641ba4a712SPawel Jakub Dawidek 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 651ba4a712SPawel Jakub Dawidek 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 661ba4a712SPawel Jakub Dawidek 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 671ba4a712SPawel Jakub Dawidek 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 681ba4a712SPawel Jakub Dawidek 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 691ba4a712SPawel Jakub Dawidek 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 701ba4a712SPawel Jakub Dawidek }; 711ba4a712SPawel Jakub Dawidek 721ba4a712SPawel Jakub Dawidek static void 731ba4a712SPawel Jakub Dawidek SHA256Transform(uint32_t *H, const uint8_t *cp) 741ba4a712SPawel Jakub Dawidek { 751ba4a712SPawel Jakub Dawidek uint32_t a, b, c, d, e, f, g, h, t, T1, T2, W[64]; 761ba4a712SPawel Jakub Dawidek 771ba4a712SPawel Jakub Dawidek for (t = 0; t < 16; t++, cp += 4) 781ba4a712SPawel Jakub Dawidek W[t] = (cp[0] << 24) | (cp[1] << 16) | (cp[2] << 8) | cp[3]; 791ba4a712SPawel Jakub Dawidek 801ba4a712SPawel Jakub Dawidek for (t = 16; t < 64; t++) 811ba4a712SPawel Jakub Dawidek W[t] = sigma1(W[t - 2]) + W[t - 7] + 821ba4a712SPawel Jakub Dawidek sigma0(W[t - 15]) + W[t - 16]; 831ba4a712SPawel Jakub Dawidek 841ba4a712SPawel Jakub Dawidek a = H[0]; b = H[1]; c = H[2]; d = H[3]; 851ba4a712SPawel Jakub Dawidek e = H[4]; f = H[5]; g = H[6]; h = H[7]; 861ba4a712SPawel Jakub Dawidek 871ba4a712SPawel Jakub Dawidek for (t = 0; t < 64; t++) { 881ba4a712SPawel Jakub Dawidek T1 = h + SIGMA1(e) + Ch(e, f, g) + SHA256_K[t] + W[t]; 891ba4a712SPawel Jakub Dawidek T2 = SIGMA0(a) + Maj(a, b, c); 901ba4a712SPawel Jakub Dawidek h = g; g = f; f = e; e = d + T1; 911ba4a712SPawel Jakub Dawidek d = c; c = b; b = a; a = T1 + T2; 921ba4a712SPawel Jakub Dawidek } 931ba4a712SPawel Jakub Dawidek 941ba4a712SPawel Jakub Dawidek H[0] += a; H[1] += b; H[2] += c; H[3] += d; 951ba4a712SPawel Jakub Dawidek H[4] += e; H[5] += f; H[6] += g; H[7] += h; 961ba4a712SPawel Jakub Dawidek } 971ba4a712SPawel Jakub Dawidek 981ba4a712SPawel Jakub Dawidek static void 991ba4a712SPawel Jakub Dawidek zio_checksum_SHA256(const void *buf, uint64_t size, zio_cksum_t *zcp) 1001ba4a712SPawel Jakub Dawidek { 1011ba4a712SPawel Jakub Dawidek uint32_t H[8] = { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 1021ba4a712SPawel Jakub Dawidek 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 }; 1031ba4a712SPawel Jakub Dawidek uint8_t pad[128]; 1041ba4a712SPawel Jakub Dawidek int padsize = size & 63; 1051ba4a712SPawel Jakub Dawidek int i; 1061ba4a712SPawel Jakub Dawidek 1071ba4a712SPawel Jakub Dawidek for (i = 0; i < size - padsize; i += 64) 1081ba4a712SPawel Jakub Dawidek SHA256Transform(H, (uint8_t *)buf + i); 1091ba4a712SPawel Jakub Dawidek 1101ba4a712SPawel Jakub Dawidek for (i = 0; i < padsize; i++) 1111ba4a712SPawel Jakub Dawidek pad[i] = ((uint8_t *)buf)[i]; 1121ba4a712SPawel Jakub Dawidek 1131ba4a712SPawel Jakub Dawidek for (pad[padsize++] = 0x80; (padsize & 63) != 56; padsize++) 1141ba4a712SPawel Jakub Dawidek pad[padsize] = 0; 1151ba4a712SPawel Jakub Dawidek 1161ba4a712SPawel Jakub Dawidek for (i = 0; i < 8; i++) 1171ba4a712SPawel Jakub Dawidek pad[padsize++] = (size << 3) >> (56 - 8 * i); 1181ba4a712SPawel Jakub Dawidek 1191ba4a712SPawel Jakub Dawidek for (i = 0; i < padsize; i += 64) 1201ba4a712SPawel Jakub Dawidek SHA256Transform(H, pad + i); 1211ba4a712SPawel Jakub Dawidek 1221ba4a712SPawel Jakub Dawidek ZIO_SET_CHECKSUM(zcp, 1231ba4a712SPawel Jakub Dawidek (uint64_t)H[0] << 32 | H[1], 1241ba4a712SPawel Jakub Dawidek (uint64_t)H[2] << 32 | H[3], 1251ba4a712SPawel Jakub Dawidek (uint64_t)H[4] << 32 | H[5], 1261ba4a712SPawel Jakub Dawidek (uint64_t)H[6] << 32 | H[7]); 1271ba4a712SPawel Jakub Dawidek } 128