zfs_sha256.c revision 8044:b3af80bbf173
1238438Sdteske/* 2238438Sdteske * GRUB -- GRand Unified Bootloader 3238438Sdteske * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. 4245106Sdteske * 5238438Sdteske * This program is free software; you can redistribute it and/or modify 6238438Sdteske * it under the terms of the GNU General Public License as published by 7238438Sdteske * the Free Software Foundation; either version 2 of the License, or 8238438Sdteske * (at your option) any later version. 9238438Sdteske * 10238438Sdteske * This program is distributed in the hope that it will be useful, 11238438Sdteske * but WITHOUT ANY WARRANTY; without even the implied warranty of 12238438Sdteske * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13238438Sdteske * GNU General Public License for more details. 14238438Sdteske * 15238438Sdteske * You should have received a copy of the GNU General Public License 16238438Sdteske * along with this program; if not, write to the Free Software 17238438Sdteske * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18238438Sdteske */ 19238438Sdteske/* 20238438Sdteske * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 21238438Sdteske * Use is subject to license terms. 22238438Sdteske */ 23238438Sdteske 24238438Sdteske#pragma ident "%Z%%M% %I% %E% SMI" 25238438Sdteske 26238438Sdteske#include "fsys_zfs.h" 27238438Sdteske 28238438Sdteske/* 29238438Sdteske * SHA-256 checksum, as specified in FIPS 180-2, available at: 30238438Sdteske * http://csrc.nist.gov/cryptval 31238438Sdteske * 32251265Sdteske * This is a very compact implementation of SHA-256. 33251265Sdteske * It is designed to be simple and portable, not to be fast. 34251265Sdteske */ 35251265Sdteske 36251265Sdteske/* 37251265Sdteske * The literal definitions according to FIPS180-2 would be: 38251265Sdteske * 39251265Sdteske * Ch(x, y, z) (((x) & (y)) ^ ((~(x)) & (z))) 40251265Sdteske * Maj(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) 41251265Sdteske * 42251265Sdteske * We use logical equivalents which require one less op. 43251265Sdteske */ 44251265Sdteske#define Ch(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) 45251265Sdteske#define Maj(x, y, z) (((x) & (y)) ^ ((z) & ((x) ^ (y)))) 46251265Sdteske#define Rot32(x, s) (((x) >> s) | ((x) << (32 - s))) 47240684Sdteske#define SIGMA0(x) (Rot32(x, 2) ^ Rot32(x, 13) ^ Rot32(x, 22)) 48240684Sdteske#define SIGMA1(x) (Rot32(x, 6) ^ Rot32(x, 11) ^ Rot32(x, 25)) 49244675Sdteske#define sigma0(x) (Rot32(x, 7) ^ Rot32(x, 18) ^ ((x) >> 3)) 50240684Sdteske#define sigma1(x) (Rot32(x, 17) ^ Rot32(x, 19) ^ ((x) >> 10)) 51240684Sdteske 52240684Sdteskestatic const uint32_t SHA256_K[64] = { 53240684Sdteske 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 54238438Sdteske 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 55238438Sdteske 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 56238438Sdteske 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 57242107Sdteske 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 58242107Sdteske 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 59242107Sdteske 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 60238438Sdteske 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 61238438Sdteske 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 62238438Sdteske 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 63238438Sdteske 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 64238438Sdteske 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 65238438Sdteske 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 66238438Sdteske 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 67238438Sdteske 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 68251264Sdteske 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 69251264Sdteske}; 70238438Sdteske 71238438Sdteskestatic void 72249746SdteskeSHA256Transform(uint32_t *H, const uint8_t *cp) 73238438Sdteske{ 74238438Sdteske uint32_t a, b, c, d, e, f, g, h, t, T1, T2, W[64]; 75238438Sdteske 76238438Sdteske for (t = 0; t < 16; t++, cp += 4) 77238438Sdteske W[t] = (cp[0] << 24) | (cp[1] << 16) | (cp[2] << 8) | cp[3]; 78238438Sdteske 79238438Sdteske for (t = 16; t < 64; t++) 80238438Sdteske W[t] = sigma1(W[t - 2]) + W[t - 7] + 81238438Sdteske sigma0(W[t - 15]) + W[t - 16]; 82238438Sdteske 83238438Sdteske a = H[0]; b = H[1]; c = H[2]; d = H[3]; 84238438Sdteske e = H[4]; f = H[5]; g = H[6]; h = H[7]; 85238438Sdteske 86238438Sdteske for (t = 0; t < 64; t++) { 87238438Sdteske T1 = h + SIGMA1(e) + Ch(e, f, g) + SHA256_K[t] + W[t]; 88238438Sdteske T2 = SIGMA0(a) + Maj(a, b, c); 89238438Sdteske h = g; g = f; f = e; e = d + T1; 90238438Sdteske d = c; c = b; b = a; a = T1 + T2; 91244550Sdteske } 92238438Sdteske 93238438Sdteske H[0] += a; H[1] += b; H[2] += c; H[3] += d; 94238438Sdteske H[4] += e; H[5] += f; H[6] += g; H[7] += h; 95238438Sdteske} 96251270Sdteske 97238438Sdteskevoid 98251270Sdteskezio_checksum_SHA256(const void *buf, uint64_t size, zio_cksum_t *zcp) 99244550Sdteske{ 100238438Sdteske uint32_t H[8] = { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 101238438Sdteske 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 }; 102238438Sdteske uint8_t pad[128]; 103238438Sdteske int padsize = size & 63; 104238438Sdteske int i; 105238438Sdteske 106238438Sdteske for (i = 0; i < size - padsize; i += 64) 107238438Sdteske SHA256Transform(H, (uint8_t *)buf + i); 108238438Sdteske 109238438Sdteske for (i = 0; i < padsize; i++) 110238438Sdteske pad[i] = ((uint8_t *)buf)[i]; 111238438Sdteske 112244550Sdteske for (pad[padsize++] = 0x80; (padsize & 63) != 56; padsize++) 113238438Sdteske pad[padsize] = 0; 114238438Sdteske 115238438Sdteske for (i = 0; i < 8; i++) 116238438Sdteske pad[padsize++] = (size << 3) >> (56 - 8 * i); 117238438Sdteske 118238438Sdteske for (i = 0; i < padsize; i += 64) 119238438Sdteske SHA256Transform(H, pad + i); 120238438Sdteske 121238438Sdteske ZIO_SET_CHECKSUM(zcp, 122238438Sdteske (uint64_t)H[0] << 32 | H[1], 123238438Sdteske (uint64_t)H[2] << 32 | H[3], 124238438Sdteske (uint64_t)H[4] << 32 | H[5], 125238438Sdteske (uint64_t)H[6] << 32 | H[7]); 126238438Sdteske} 127238438Sdteske