199767f8919635c4928607450d9e0abb932109ceToomas Soome/*
199767f8919635c4928607450d9e0abb932109ceToomas Soome * CDDL HEADER START
199767f8919635c4928607450d9e0abb932109ceToomas Soome *
199767f8919635c4928607450d9e0abb932109ceToomas Soome * The contents of this file are subject to the terms of the
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Common Development and Distribution License, Version 1.0 only
199767f8919635c4928607450d9e0abb932109ceToomas Soome * (the "License"). You may not use this file except in compliance
199767f8919635c4928607450d9e0abb932109ceToomas Soome * with the License.
199767f8919635c4928607450d9e0abb932109ceToomas Soome *
199767f8919635c4928607450d9e0abb932109ceToomas Soome * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
199767f8919635c4928607450d9e0abb932109ceToomas Soome * or http://www.opensolaris.org/os/licensing.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * See the License for the specific language governing permissions
199767f8919635c4928607450d9e0abb932109ceToomas Soome * and limitations under the License.
199767f8919635c4928607450d9e0abb932109ceToomas Soome *
199767f8919635c4928607450d9e0abb932109ceToomas Soome * When distributing Covered Code, include this CDDL HEADER in each
199767f8919635c4928607450d9e0abb932109ceToomas Soome * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * If applicable, add the following below this CDDL HEADER, with the
199767f8919635c4928607450d9e0abb932109ceToomas Soome * fields enclosed by brackets "[]" replaced with your own identifying
199767f8919635c4928607450d9e0abb932109ceToomas Soome * information: Portions Copyright [yyyy] [name of copyright owner]
199767f8919635c4928607450d9e0abb932109ceToomas Soome *
199767f8919635c4928607450d9e0abb932109ceToomas Soome * CDDL HEADER END
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soome/*
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Use is subject to license terms.
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soome/*
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Copyright 2013 Saso Kiselkov. All rights reserved.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Copyright 2015 Toomas Soome <tsoome@me.com>
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/*
199767f8919635c4928607450d9e0abb932109ceToomas Soome * SHA-256 and SHA-512/256 hashes, as specified in FIPS 180-4, available at:
199767f8919635c4928607450d9e0abb932109ceToomas Soome * http://csrc.nist.gov/cryptval
199767f8919635c4928607450d9e0abb932109ceToomas Soome *
199767f8919635c4928607450d9e0abb932109ceToomas Soome * This is a very compact implementation of SHA-256 and SHA-512/256.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * It is designed to be simple and portable, not to be fast.
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/*
199767f8919635c4928607450d9e0abb932109ceToomas Soome * The literal definitions according to FIPS180-4 would be:
199767f8919635c4928607450d9e0abb932109ceToomas Soome *
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Ch(x, y, z) (((x) & (y)) ^ ((~(x)) & (z)))
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Maj(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
199767f8919635c4928607450d9e0abb932109ceToomas Soome *
199767f8919635c4928607450d9e0abb932109ceToomas Soome * We use logical equivalents which require one less op.
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soome#define Ch(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
199767f8919635c4928607450d9e0abb932109ceToomas Soome#define Maj(x, y, z) (((x) & (y)) ^ ((z) & ((x) ^ (y))))
199767f8919635c4928607450d9e0abb932109ceToomas Soome#define ROTR(x, n) (((x) >> (n)) | ((x) << ((sizeof (x) * NBBY)-(n))))
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* SHA-224/256 operations */
199767f8919635c4928607450d9e0abb932109ceToomas Soome#define BIGSIGMA0_256(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
199767f8919635c4928607450d9e0abb932109ceToomas Soome#define BIGSIGMA1_256(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
199767f8919635c4928607450d9e0abb932109ceToomas Soome#define SIGMA0_256(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ ((x) >> 3))
199767f8919635c4928607450d9e0abb932109ceToomas Soome#define SIGMA1_256(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ ((x) >> 10))
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* SHA-384/512 operations */
199767f8919635c4928607450d9e0abb932109ceToomas Soome#define BIGSIGMA0_512(x) (ROTR((x), 28) ^ ROTR((x), 34) ^ ROTR((x), 39))
199767f8919635c4928607450d9e0abb932109ceToomas Soome#define BIGSIGMA1_512(x) (ROTR((x), 14) ^ ROTR((x), 18) ^ ROTR((x), 41))
199767f8919635c4928607450d9e0abb932109ceToomas Soome#define SIGMA0_512(x) (ROTR((x), 1) ^ ROTR((x), 8) ^ ((x) >> 7))
199767f8919635c4928607450d9e0abb932109ceToomas Soome#define SIGMA1_512(x) (ROTR((x), 19) ^ ROTR((x), 61) ^ ((x) >> 6))
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* SHA-256 round constants */
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic const uint32_t SHA256_K[64] = {
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
199767f8919635c4928607450d9e0abb932109ceToomas Soome};
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* SHA-512 round constants */
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic const uint64_t SHA512_K[80] = {
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x428A2F98D728AE22ULL, 0x7137449123EF65CDULL,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0xB5C0FBCFEC4D3B2FULL, 0xE9B5DBA58189DBBCULL,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x3956C25BF348B538ULL, 0x59F111F1B605D019ULL,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x923F82A4AF194F9BULL, 0xAB1C5ED5DA6D8118ULL,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0xD807AA98A3030242ULL, 0x12835B0145706FBEULL,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x243185BE4EE4B28CULL, 0x550C7DC3D5FFB4E2ULL,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x72BE5D74F27B896FULL, 0x80DEB1FE3B1696B1ULL,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x9BDC06A725C71235ULL, 0xC19BF174CF692694ULL,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0xE49B69C19EF14AD2ULL, 0xEFBE4786384F25E3ULL,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x0FC19DC68B8CD5B5ULL, 0x240CA1CC77AC9C65ULL,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x2DE92C6F592B0275ULL, 0x4A7484AA6EA6E483ULL,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x5CB0A9DCBD41FBD4ULL, 0x76F988DA831153B5ULL,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x983E5152EE66DFABULL, 0xA831C66D2DB43210ULL,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0xB00327C898FB213FULL, 0xBF597FC7BEEF0EE4ULL,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0xC6E00BF33DA88FC2ULL, 0xD5A79147930AA725ULL,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x06CA6351E003826FULL, 0x142929670A0E6E70ULL,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x27B70A8546D22FFCULL, 0x2E1B21385C26C926ULL,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x4D2C6DFC5AC42AEDULL, 0x53380D139D95B3DFULL,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x650A73548BAF63DEULL, 0x766A0ABB3C77B2A8ULL,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x81C2C92E47EDAEE6ULL, 0x92722C851482353BULL,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0xA2BFE8A14CF10364ULL, 0xA81A664BBC423001ULL,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0xC24B8B70D0F89791ULL, 0xC76C51A30654BE30ULL,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0xD192E819D6EF5218ULL, 0xD69906245565A910ULL,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0xF40E35855771202AULL, 0x106AA07032BBD1B8ULL,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x19A4C116B8D2D0C8ULL, 0x1E376C085141AB53ULL,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x2748774CDF8EEB99ULL, 0x34B0BCB5E19B48A8ULL,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x391C0CB3C5C95A63ULL, 0x4ED8AA4AE3418ACBULL,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x5B9CCA4F7763E373ULL, 0x682E6FF3D6B2B8A3ULL,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x748F82EE5DEFB2FCULL, 0x78A5636F43172F60ULL,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x84C87814A1F0AB72ULL, 0x8CC702081A6439ECULL,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x90BEFFFA23631E28ULL, 0xA4506CEBDE82BDE9ULL,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0xBEF9A3F7B2C67915ULL, 0xC67178F2E372532BULL,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0xCA273ECEEA26619CULL, 0xD186B8C721C0C207ULL,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0xEADA7DD6CDE0EB1EULL, 0xF57D4F7FEE6ED178ULL,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x06F067AA72176FBAULL, 0x0A637DC5A2C898A6ULL,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x113F9804BEF90DAEULL, 0x1B710B35131C471BULL,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x28DB77F523047D84ULL, 0x32CAAB7B40C72493ULL,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x3C9EBE0A15C9BEBCULL, 0x431D67C49C100D4CULL,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x4CC5D4BECB3E42B6ULL, 0x597F299CFC657E2AULL,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x5FCB6FAB3AD6FAECULL, 0x6C44198C4A475817ULL
199767f8919635c4928607450d9e0abb932109ceToomas Soome};
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic void
199767f8919635c4928607450d9e0abb932109ceToomas SoomeSHA256Transform(uint32_t *H, const uint8_t *cp)
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome uint32_t a, b, c, d, e, f, g, h, t, T1, T2, W[64];
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* copy chunk into the first 16 words of the message schedule */
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (t = 0; t < 16; t++, cp += sizeof (uint32_t))
199767f8919635c4928607450d9e0abb932109ceToomas Soome W[t] = (cp[0] << 24) | (cp[1] << 16) | (cp[2] << 8) | cp[3];
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* extend the first 16 words into the remaining 48 words */
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (t = 16; t < 64; t++)
199767f8919635c4928607450d9e0abb932109ceToomas Soome W[t] = SIGMA1_256(W[t - 2]) + W[t - 7] +
199767f8919635c4928607450d9e0abb932109ceToomas Soome SIGMA0_256(W[t - 15]) + W[t - 16];
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* init working variables to the current hash value */
199767f8919635c4928607450d9e0abb932109ceToomas Soome a = H[0]; b = H[1]; c = H[2]; d = H[3];
199767f8919635c4928607450d9e0abb932109ceToomas Soome e = H[4]; f = H[5]; g = H[6]; h = H[7];
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* iterate the compression function for all rounds of the hash */
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (t = 0; t < 64; t++) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome T1 = h + BIGSIGMA1_256(e) + Ch(e, f, g) + SHA256_K[t] + W[t];
199767f8919635c4928607450d9e0abb932109ceToomas Soome T2 = BIGSIGMA0_256(a) + Maj(a, b, c);
199767f8919635c4928607450d9e0abb932109ceToomas Soome h = g; g = f; f = e; e = d + T1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome d = c; c = b; b = a; a = T1 + T2;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* add the compressed chunk to the current hash value */
199767f8919635c4928607450d9e0abb932109ceToomas Soome H[0] += a; H[1] += b; H[2] += c; H[3] += d;
199767f8919635c4928607450d9e0abb932109ceToomas Soome H[4] += e; H[5] += f; H[6] += g; H[7] += h;
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic void
199767f8919635c4928607450d9e0abb932109ceToomas SoomeSHA512Transform(uint64_t *H, const uint8_t *cp)
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome uint64_t a, b, c, d, e, f, g, h, t, T1, T2, W[80];
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* copy chunk into the first 16 words of the message schedule */
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (t = 0; t < 16; t++, cp += sizeof (uint64_t))
199767f8919635c4928607450d9e0abb932109ceToomas Soome W[t] = ((uint64_t)cp[0] << 56) | ((uint64_t)cp[1] << 48) |
199767f8919635c4928607450d9e0abb932109ceToomas Soome ((uint64_t)cp[2] << 40) | ((uint64_t)cp[3] << 32) |
199767f8919635c4928607450d9e0abb932109ceToomas Soome ((uint64_t)cp[4] << 24) | ((uint64_t)cp[5] << 16) |
199767f8919635c4928607450d9e0abb932109ceToomas Soome ((uint64_t)cp[6] << 8) | (uint64_t)cp[7];
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* extend the first 16 words into the remaining 64 words */
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (t = 16; t < 80; t++)
199767f8919635c4928607450d9e0abb932109ceToomas Soome W[t] = SIGMA1_512(W[t - 2]) + W[t - 7] +
199767f8919635c4928607450d9e0abb932109ceToomas Soome SIGMA0_512(W[t - 15]) + W[t - 16];
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* init working variables to the current hash value */
199767f8919635c4928607450d9e0abb932109ceToomas Soome a = H[0]; b = H[1]; c = H[2]; d = H[3];
199767f8919635c4928607450d9e0abb932109ceToomas Soome e = H[4]; f = H[5]; g = H[6]; h = H[7];
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* iterate the compression function for all rounds of the hash */
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (t = 0; t < 80; t++) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome T1 = h + BIGSIGMA1_512(e) + Ch(e, f, g) + SHA512_K[t] + W[t];
199767f8919635c4928607450d9e0abb932109ceToomas Soome T2 = BIGSIGMA0_512(a) + Maj(a, b, c);
199767f8919635c4928607450d9e0abb932109ceToomas Soome h = g; g = f; f = e; e = d + T1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome d = c; c = b; b = a; a = T1 + T2;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* add the compressed chunk to the current hash value */
199767f8919635c4928607450d9e0abb932109ceToomas Soome H[0] += a; H[1] += b; H[2] += c; H[3] += d;
199767f8919635c4928607450d9e0abb932109ceToomas Soome H[4] += e; H[5] += f; H[6] += g; H[7] += h;
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/*
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Implements the SHA-224 and SHA-256 hash algos - to select between them
199767f8919635c4928607450d9e0abb932109ceToomas Soome * pass the appropriate initial values of 'H' and truncate the last 32 bits
199767f8919635c4928607450d9e0abb932109ceToomas Soome * in case of SHA-224.
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic void
199767f8919635c4928607450d9e0abb932109ceToomas SoomeSHA256(uint32_t *H, const void *buf, uint64_t size, zio_cksum_t *zcp)
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome uint8_t pad[128];
199767f8919635c4928607450d9e0abb932109ceToomas Soome unsigned padsize = size & 63;
199767f8919635c4928607450d9e0abb932109ceToomas Soome unsigned i, k;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* process all blocks up to the last one */
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (i = 0; i < size - padsize; i += 64)
199767f8919635c4928607450d9e0abb932109ceToomas Soome SHA256Transform(H, (uint8_t *)buf + i);
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* process the last block and padding */
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (k = 0; k < padsize; k++)
199767f8919635c4928607450d9e0abb932109ceToomas Soome pad[k] = ((uint8_t *)buf)[k+i];
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (pad[padsize++] = 0x80; (padsize & 63) != 56; padsize++)
199767f8919635c4928607450d9e0abb932109ceToomas Soome pad[padsize] = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (i = 0; i < 8; i++)
199767f8919635c4928607450d9e0abb932109ceToomas Soome pad[padsize++] = (size << 3) >> (56 - 8 * i);
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (i = 0; i < padsize; i += 64)
199767f8919635c4928607450d9e0abb932109ceToomas Soome SHA256Transform(H, pad + i);
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome ZIO_SET_CHECKSUM(zcp,
199767f8919635c4928607450d9e0abb932109ceToomas Soome (uint64_t)H[0] << 32 | H[1],
199767f8919635c4928607450d9e0abb932109ceToomas Soome (uint64_t)H[2] << 32 | H[3],
199767f8919635c4928607450d9e0abb932109ceToomas Soome (uint64_t)H[4] << 32 | H[5],
199767f8919635c4928607450d9e0abb932109ceToomas Soome (uint64_t)H[6] << 32 | H[7]);
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/*
199767f8919635c4928607450d9e0abb932109ceToomas Soome * encode 64bit data in big-endian format.
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic void
199767f8919635c4928607450d9e0abb932109ceToomas SoomeEncode64(uint8_t *output, uint64_t *input, size_t len)
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome size_t i, j;
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (i = 0, j = 0; j < len; i++, j += 8) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome output[j] = (input[i] >> 56) & 0xff;
199767f8919635c4928607450d9e0abb932109ceToomas Soome output[j + 1] = (input[i] >> 48) & 0xff;
199767f8919635c4928607450d9e0abb932109ceToomas Soome output[j + 2] = (input[i] >> 40) & 0xff;
199767f8919635c4928607450d9e0abb932109ceToomas Soome output[j + 3] = (input[i] >> 32) & 0xff;
199767f8919635c4928607450d9e0abb932109ceToomas Soome output[j + 4] = (input[i] >> 24) & 0xff;
199767f8919635c4928607450d9e0abb932109ceToomas Soome output[j + 5] = (input[i] >> 16) & 0xff;
199767f8919635c4928607450d9e0abb932109ceToomas Soome output[j + 6] = (input[i] >> 8) & 0xff;
199767f8919635c4928607450d9e0abb932109ceToomas Soome output[j + 7] = input[i] & 0xff;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/*
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Implements the SHA-384, SHA-512 and SHA-512/t hash algos - to select
199767f8919635c4928607450d9e0abb932109ceToomas Soome * between them pass the appropriate initial values for 'H'. The output
199767f8919635c4928607450d9e0abb932109ceToomas Soome * of this function is truncated to the first 256 bits that fit into 'zcp'.
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic void
199767f8919635c4928607450d9e0abb932109ceToomas SoomeSHA512(uint64_t *H, const void *buf, uint64_t size, zio_cksum_t *zcp)
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome uint64_t c64[2];
199767f8919635c4928607450d9e0abb932109ceToomas Soome uint8_t pad[256];
199767f8919635c4928607450d9e0abb932109ceToomas Soome unsigned padsize = size & 127;
199767f8919635c4928607450d9e0abb932109ceToomas Soome unsigned i, k;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* process all blocks up to the last one */
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (i = 0; i < size - padsize; i += 128)
199767f8919635c4928607450d9e0abb932109ceToomas Soome SHA512Transform(H, (uint8_t *)buf + i);
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* process the last block and padding */
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (k = 0; k < padsize; k++)
199767f8919635c4928607450d9e0abb932109ceToomas Soome pad[k] = ((uint8_t *)buf)[k+i];
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (padsize < 112) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (pad[padsize++] = 0x80; padsize < 112; padsize++)
199767f8919635c4928607450d9e0abb932109ceToomas Soome pad[padsize] = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome } else {
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (pad[padsize++] = 0x80; padsize < 240; padsize++)
199767f8919635c4928607450d9e0abb932109ceToomas Soome pad[padsize] = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome c64[0] = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome c64[1] = size << 3;
199767f8919635c4928607450d9e0abb932109ceToomas Soome Encode64(pad+padsize, c64, sizeof (c64));
199767f8919635c4928607450d9e0abb932109ceToomas Soome padsize += sizeof (c64);
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (i = 0; i < padsize; i += 128)
199767f8919635c4928607450d9e0abb932109ceToomas Soome SHA512Transform(H, pad + i);
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* truncate the output to the first 256 bits which fit into 'zcp' */
199767f8919635c4928607450d9e0abb932109ceToomas Soome Encode64((uint8_t *)zcp, H, sizeof (uint64_t) * 4);
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic void
199767f8919635c4928607450d9e0abb932109ceToomas Soomezio_checksum_SHA256(const void *buf, uint64_t size,
199767f8919635c4928607450d9e0abb932109ceToomas Soome const void *ctx_template, zio_cksum_t *zcp)
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* SHA-256 as per FIPS 180-4. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome uint32_t H[] = {
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
199767f8919635c4928607450d9e0abb932109ceToomas Soome };
199767f8919635c4928607450d9e0abb932109ceToomas Soome SHA256(H, buf, size, zcp);
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic void
199767f8919635c4928607450d9e0abb932109ceToomas Soomezio_checksum_SHA512_native(const void *buf, uint64_t size,
199767f8919635c4928607450d9e0abb932109ceToomas Soome const void *ctx_template, zio_cksum_t *zcp)
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* SHA-512/256 as per FIPS 180-4. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome uint64_t H[] = {
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x22312194FC2BF72CULL, 0x9F555FA3C84C64C2ULL,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x2393B86B6F53B151ULL, 0x963877195940EABDULL,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x96283EE2A88EFFE3ULL, 0xBE5E1E2553863992ULL,
199767f8919635c4928607450d9e0abb932109ceToomas Soome 0x2B0199FC2C85B8AAULL, 0x0EB72DDC81C52CA2ULL
199767f8919635c4928607450d9e0abb932109ceToomas Soome };
199767f8919635c4928607450d9e0abb932109ceToomas Soome SHA512(H, buf, size, zcp);
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic void
199767f8919635c4928607450d9e0abb932109ceToomas Soomezio_checksum_SHA512_byteswap(const void *buf, uint64_t size,
199767f8919635c4928607450d9e0abb932109ceToomas Soome const void *ctx_template, zio_cksum_t *zcp)
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome zio_cksum_t tmp;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome zio_checksum_SHA512_native(buf, size, ctx_template, &tmp);
199767f8919635c4928607450d9e0abb932109ceToomas Soome zcp->zc_word[0] = BSWAP_64(tmp.zc_word[0]);
199767f8919635c4928607450d9e0abb932109ceToomas Soome zcp->zc_word[1] = BSWAP_64(tmp.zc_word[1]);
199767f8919635c4928607450d9e0abb932109ceToomas Soome zcp->zc_word[2] = BSWAP_64(tmp.zc_word[2]);
199767f8919635c4928607450d9e0abb932109ceToomas Soome zcp->zc_word[3] = BSWAP_64(tmp.zc_word[3]);
199767f8919635c4928607450d9e0abb932109ceToomas Soome}