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 */
262c55d090SToomas Soome /*
272c55d090SToomas Soome * Copyright 2013 Saso Kiselkov. All rights reserved.
282c55d090SToomas Soome * Copyright 2015 Toomas Soome <tsoome@me.com>
292c55d090SToomas Soome */
301ba4a712SPawel Jakub Dawidek
311ba4a712SPawel Jakub Dawidek /*
322c55d090SToomas Soome * SHA-256 and SHA-512/256 hashes, as specified in FIPS 180-4, available at:
331ba4a712SPawel Jakub Dawidek * http://csrc.nist.gov/cryptval
341ba4a712SPawel Jakub Dawidek *
352c55d090SToomas Soome * This is a very compact implementation of SHA-256 and SHA-512/256.
361ba4a712SPawel Jakub Dawidek * It is designed to be simple and portable, not to be fast.
371ba4a712SPawel Jakub Dawidek */
381ba4a712SPawel Jakub Dawidek
391ba4a712SPawel Jakub Dawidek /*
402c55d090SToomas Soome * The literal definitions according to FIPS180-4 would be:
411ba4a712SPawel Jakub Dawidek *
421ba4a712SPawel Jakub Dawidek * Ch(x, y, z) (((x) & (y)) ^ ((~(x)) & (z)))
431ba4a712SPawel Jakub Dawidek * Maj(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
441ba4a712SPawel Jakub Dawidek *
451ba4a712SPawel Jakub Dawidek * We use logical equivalents which require one less op.
461ba4a712SPawel Jakub Dawidek */
471ba4a712SPawel Jakub Dawidek #define Ch(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
481ba4a712SPawel Jakub Dawidek #define Maj(x, y, z) (((x) & (y)) ^ ((z) & ((x) ^ (y))))
492c55d090SToomas Soome #define ROTR(x, n) (((x) >> (n)) | ((x) << ((sizeof (x) * NBBY)-(n))))
501ba4a712SPawel Jakub Dawidek
512c55d090SToomas Soome /* SHA-224/256 operations */
522c55d090SToomas Soome #define BIGSIGMA0_256(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
532c55d090SToomas Soome #define BIGSIGMA1_256(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
542c55d090SToomas Soome #define SIGMA0_256(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ ((x) >> 3))
552c55d090SToomas Soome #define SIGMA1_256(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ ((x) >> 10))
562c55d090SToomas Soome
572c55d090SToomas Soome /* SHA-384/512 operations */
582c55d090SToomas Soome #define BIGSIGMA0_512(x) (ROTR((x), 28) ^ ROTR((x), 34) ^ ROTR((x), 39))
592c55d090SToomas Soome #define BIGSIGMA1_512(x) (ROTR((x), 14) ^ ROTR((x), 18) ^ ROTR((x), 41))
602c55d090SToomas Soome #define SIGMA0_512(x) (ROTR((x), 1) ^ ROTR((x), 8) ^ ((x) >> 7))
612c55d090SToomas Soome #define SIGMA1_512(x) (ROTR((x), 19) ^ ROTR((x), 61) ^ ((x) >> 6))
622c55d090SToomas Soome
632c55d090SToomas Soome /* SHA-256 round constants */
641ba4a712SPawel Jakub Dawidek static const uint32_t SHA256_K[64] = {
651ba4a712SPawel Jakub Dawidek 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
661ba4a712SPawel Jakub Dawidek 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
671ba4a712SPawel Jakub Dawidek 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
681ba4a712SPawel Jakub Dawidek 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
691ba4a712SPawel Jakub Dawidek 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
701ba4a712SPawel Jakub Dawidek 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
711ba4a712SPawel Jakub Dawidek 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
721ba4a712SPawel Jakub Dawidek 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
731ba4a712SPawel Jakub Dawidek 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
741ba4a712SPawel Jakub Dawidek 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
751ba4a712SPawel Jakub Dawidek 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
761ba4a712SPawel Jakub Dawidek 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
771ba4a712SPawel Jakub Dawidek 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
781ba4a712SPawel Jakub Dawidek 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
791ba4a712SPawel Jakub Dawidek 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
801ba4a712SPawel Jakub Dawidek 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
811ba4a712SPawel Jakub Dawidek };
821ba4a712SPawel Jakub Dawidek
832c55d090SToomas Soome /* SHA-512 round constants */
842c55d090SToomas Soome static const uint64_t SHA512_K[80] = {
852c55d090SToomas Soome 0x428A2F98D728AE22ULL, 0x7137449123EF65CDULL,
862c55d090SToomas Soome 0xB5C0FBCFEC4D3B2FULL, 0xE9B5DBA58189DBBCULL,
872c55d090SToomas Soome 0x3956C25BF348B538ULL, 0x59F111F1B605D019ULL,
882c55d090SToomas Soome 0x923F82A4AF194F9BULL, 0xAB1C5ED5DA6D8118ULL,
892c55d090SToomas Soome 0xD807AA98A3030242ULL, 0x12835B0145706FBEULL,
902c55d090SToomas Soome 0x243185BE4EE4B28CULL, 0x550C7DC3D5FFB4E2ULL,
912c55d090SToomas Soome 0x72BE5D74F27B896FULL, 0x80DEB1FE3B1696B1ULL,
922c55d090SToomas Soome 0x9BDC06A725C71235ULL, 0xC19BF174CF692694ULL,
932c55d090SToomas Soome 0xE49B69C19EF14AD2ULL, 0xEFBE4786384F25E3ULL,
942c55d090SToomas Soome 0x0FC19DC68B8CD5B5ULL, 0x240CA1CC77AC9C65ULL,
952c55d090SToomas Soome 0x2DE92C6F592B0275ULL, 0x4A7484AA6EA6E483ULL,
962c55d090SToomas Soome 0x5CB0A9DCBD41FBD4ULL, 0x76F988DA831153B5ULL,
972c55d090SToomas Soome 0x983E5152EE66DFABULL, 0xA831C66D2DB43210ULL,
982c55d090SToomas Soome 0xB00327C898FB213FULL, 0xBF597FC7BEEF0EE4ULL,
992c55d090SToomas Soome 0xC6E00BF33DA88FC2ULL, 0xD5A79147930AA725ULL,
1002c55d090SToomas Soome 0x06CA6351E003826FULL, 0x142929670A0E6E70ULL,
1012c55d090SToomas Soome 0x27B70A8546D22FFCULL, 0x2E1B21385C26C926ULL,
1022c55d090SToomas Soome 0x4D2C6DFC5AC42AEDULL, 0x53380D139D95B3DFULL,
1032c55d090SToomas Soome 0x650A73548BAF63DEULL, 0x766A0ABB3C77B2A8ULL,
1042c55d090SToomas Soome 0x81C2C92E47EDAEE6ULL, 0x92722C851482353BULL,
1052c55d090SToomas Soome 0xA2BFE8A14CF10364ULL, 0xA81A664BBC423001ULL,
1062c55d090SToomas Soome 0xC24B8B70D0F89791ULL, 0xC76C51A30654BE30ULL,
1072c55d090SToomas Soome 0xD192E819D6EF5218ULL, 0xD69906245565A910ULL,
1082c55d090SToomas Soome 0xF40E35855771202AULL, 0x106AA07032BBD1B8ULL,
1092c55d090SToomas Soome 0x19A4C116B8D2D0C8ULL, 0x1E376C085141AB53ULL,
1102c55d090SToomas Soome 0x2748774CDF8EEB99ULL, 0x34B0BCB5E19B48A8ULL,
1112c55d090SToomas Soome 0x391C0CB3C5C95A63ULL, 0x4ED8AA4AE3418ACBULL,
1122c55d090SToomas Soome 0x5B9CCA4F7763E373ULL, 0x682E6FF3D6B2B8A3ULL,
1132c55d090SToomas Soome 0x748F82EE5DEFB2FCULL, 0x78A5636F43172F60ULL,
1142c55d090SToomas Soome 0x84C87814A1F0AB72ULL, 0x8CC702081A6439ECULL,
1152c55d090SToomas Soome 0x90BEFFFA23631E28ULL, 0xA4506CEBDE82BDE9ULL,
1162c55d090SToomas Soome 0xBEF9A3F7B2C67915ULL, 0xC67178F2E372532BULL,
1172c55d090SToomas Soome 0xCA273ECEEA26619CULL, 0xD186B8C721C0C207ULL,
1182c55d090SToomas Soome 0xEADA7DD6CDE0EB1EULL, 0xF57D4F7FEE6ED178ULL,
1192c55d090SToomas Soome 0x06F067AA72176FBAULL, 0x0A637DC5A2C898A6ULL,
1202c55d090SToomas Soome 0x113F9804BEF90DAEULL, 0x1B710B35131C471BULL,
1212c55d090SToomas Soome 0x28DB77F523047D84ULL, 0x32CAAB7B40C72493ULL,
1222c55d090SToomas Soome 0x3C9EBE0A15C9BEBCULL, 0x431D67C49C100D4CULL,
1232c55d090SToomas Soome 0x4CC5D4BECB3E42B6ULL, 0x597F299CFC657E2AULL,
1242c55d090SToomas Soome 0x5FCB6FAB3AD6FAECULL, 0x6C44198C4A475817ULL
1252c55d090SToomas Soome };
1262c55d090SToomas Soome
1271ba4a712SPawel Jakub Dawidek static void
SHA256Transform(uint32_t * H,const uint8_t * cp)1281ba4a712SPawel Jakub Dawidek SHA256Transform(uint32_t *H, const uint8_t *cp)
1291ba4a712SPawel Jakub Dawidek {
1301ba4a712SPawel Jakub Dawidek uint32_t a, b, c, d, e, f, g, h, t, T1, T2, W[64];
1311ba4a712SPawel Jakub Dawidek
1322c55d090SToomas Soome /* copy chunk into the first 16 words of the message schedule */
1332c55d090SToomas Soome for (t = 0; t < 16; t++, cp += sizeof (uint32_t))
1341ba4a712SPawel Jakub Dawidek W[t] = (cp[0] << 24) | (cp[1] << 16) | (cp[2] << 8) | cp[3];
1351ba4a712SPawel Jakub Dawidek
1362c55d090SToomas Soome /* extend the first 16 words into the remaining 48 words */
1371ba4a712SPawel Jakub Dawidek for (t = 16; t < 64; t++)
1382c55d090SToomas Soome W[t] = SIGMA1_256(W[t - 2]) + W[t - 7] +
1392c55d090SToomas Soome SIGMA0_256(W[t - 15]) + W[t - 16];
1401ba4a712SPawel Jakub Dawidek
1412c55d090SToomas Soome /* init working variables to the current hash value */
1421ba4a712SPawel Jakub Dawidek a = H[0]; b = H[1]; c = H[2]; d = H[3];
1431ba4a712SPawel Jakub Dawidek e = H[4]; f = H[5]; g = H[6]; h = H[7];
1441ba4a712SPawel Jakub Dawidek
1452c55d090SToomas Soome /* iterate the compression function for all rounds of the hash */
1461ba4a712SPawel Jakub Dawidek for (t = 0; t < 64; t++) {
1472c55d090SToomas Soome T1 = h + BIGSIGMA1_256(e) + Ch(e, f, g) + SHA256_K[t] + W[t];
1482c55d090SToomas Soome T2 = BIGSIGMA0_256(a) + Maj(a, b, c);
1491ba4a712SPawel Jakub Dawidek h = g; g = f; f = e; e = d + T1;
1501ba4a712SPawel Jakub Dawidek d = c; c = b; b = a; a = T1 + T2;
1511ba4a712SPawel Jakub Dawidek }
1521ba4a712SPawel Jakub Dawidek
1532c55d090SToomas Soome /* add the compressed chunk to the current hash value */
1541ba4a712SPawel Jakub Dawidek H[0] += a; H[1] += b; H[2] += c; H[3] += d;
1551ba4a712SPawel Jakub Dawidek H[4] += e; H[5] += f; H[6] += g; H[7] += h;
1561ba4a712SPawel Jakub Dawidek }
1571ba4a712SPawel Jakub Dawidek
1581ba4a712SPawel Jakub Dawidek static void
SHA512Transform(uint64_t * H,const uint8_t * cp)1592c55d090SToomas Soome SHA512Transform(uint64_t *H, const uint8_t *cp)
1601ba4a712SPawel Jakub Dawidek {
1612c55d090SToomas Soome uint64_t a, b, c, d, e, f, g, h, t, T1, T2, W[80];
1621ba4a712SPawel Jakub Dawidek
1632c55d090SToomas Soome /* copy chunk into the first 16 words of the message schedule */
1642c55d090SToomas Soome for (t = 0; t < 16; t++, cp += sizeof (uint64_t))
1652c55d090SToomas Soome W[t] = ((uint64_t)cp[0] << 56) | ((uint64_t)cp[1] << 48) |
1662c55d090SToomas Soome ((uint64_t)cp[2] << 40) | ((uint64_t)cp[3] << 32) |
1672c55d090SToomas Soome ((uint64_t)cp[4] << 24) | ((uint64_t)cp[5] << 16) |
1682c55d090SToomas Soome ((uint64_t)cp[6] << 8) | (uint64_t)cp[7];
1692c55d090SToomas Soome
1702c55d090SToomas Soome /* extend the first 16 words into the remaining 64 words */
1712c55d090SToomas Soome for (t = 16; t < 80; t++)
1722c55d090SToomas Soome W[t] = SIGMA1_512(W[t - 2]) + W[t - 7] +
1732c55d090SToomas Soome SIGMA0_512(W[t - 15]) + W[t - 16];
1742c55d090SToomas Soome
1752c55d090SToomas Soome /* init working variables to the current hash value */
1762c55d090SToomas Soome a = H[0]; b = H[1]; c = H[2]; d = H[3];
1772c55d090SToomas Soome e = H[4]; f = H[5]; g = H[6]; h = H[7];
1782c55d090SToomas Soome
1792c55d090SToomas Soome /* iterate the compression function for all rounds of the hash */
1802c55d090SToomas Soome for (t = 0; t < 80; t++) {
1812c55d090SToomas Soome T1 = h + BIGSIGMA1_512(e) + Ch(e, f, g) + SHA512_K[t] + W[t];
1822c55d090SToomas Soome T2 = BIGSIGMA0_512(a) + Maj(a, b, c);
1832c55d090SToomas Soome h = g; g = f; f = e; e = d + T1;
1842c55d090SToomas Soome d = c; c = b; b = a; a = T1 + T2;
1852c55d090SToomas Soome }
1862c55d090SToomas Soome
1872c55d090SToomas Soome /* add the compressed chunk to the current hash value */
1882c55d090SToomas Soome H[0] += a; H[1] += b; H[2] += c; H[3] += d;
1892c55d090SToomas Soome H[4] += e; H[5] += f; H[6] += g; H[7] += h;
1902c55d090SToomas Soome }
1912c55d090SToomas Soome
1922c55d090SToomas Soome /*
1932c55d090SToomas Soome * Implements the SHA-224 and SHA-256 hash algos - to select between them
1942c55d090SToomas Soome * pass the appropriate initial values of 'H' and truncate the last 32 bits
1952c55d090SToomas Soome * in case of SHA-224.
1962c55d090SToomas Soome */
1972c55d090SToomas Soome static void
SHA256(uint32_t * H,const void * buf,uint64_t size,zio_cksum_t * zcp)1982c55d090SToomas Soome SHA256(uint32_t *H, const void *buf, uint64_t size, zio_cksum_t *zcp)
1992c55d090SToomas Soome {
2002c55d090SToomas Soome uint8_t pad[128];
2012c55d090SToomas Soome unsigned padsize = size & 63;
2022c55d090SToomas Soome unsigned i, k;
2032c55d090SToomas Soome
2042c55d090SToomas Soome /* process all blocks up to the last one */
2051ba4a712SPawel Jakub Dawidek for (i = 0; i < size - padsize; i += 64)
206*8d20f156SMark Johnston SHA256Transform(H, (const uint8_t *)buf + i);
2071ba4a712SPawel Jakub Dawidek
2082c55d090SToomas Soome /* process the last block and padding */
2092c55d090SToomas Soome for (k = 0; k < padsize; k++)
210*8d20f156SMark Johnston pad[k] = ((const uint8_t *)buf)[k + i];
2111ba4a712SPawel Jakub Dawidek
2121ba4a712SPawel Jakub Dawidek for (pad[padsize++] = 0x80; (padsize & 63) != 56; padsize++)
2131ba4a712SPawel Jakub Dawidek pad[padsize] = 0;
2141ba4a712SPawel Jakub Dawidek
2151ba4a712SPawel Jakub Dawidek for (i = 0; i < 8; i++)
2161ba4a712SPawel Jakub Dawidek pad[padsize++] = (size << 3) >> (56 - 8 * i);
2171ba4a712SPawel Jakub Dawidek
2181ba4a712SPawel Jakub Dawidek for (i = 0; i < padsize; i += 64)
2191ba4a712SPawel Jakub Dawidek SHA256Transform(H, pad + i);
2201ba4a712SPawel Jakub Dawidek
2211ba4a712SPawel Jakub Dawidek ZIO_SET_CHECKSUM(zcp,
2221ba4a712SPawel Jakub Dawidek (uint64_t)H[0] << 32 | H[1],
2231ba4a712SPawel Jakub Dawidek (uint64_t)H[2] << 32 | H[3],
2241ba4a712SPawel Jakub Dawidek (uint64_t)H[4] << 32 | H[5],
2251ba4a712SPawel Jakub Dawidek (uint64_t)H[6] << 32 | H[7]);
2261ba4a712SPawel Jakub Dawidek }
2272c55d090SToomas Soome
2282c55d090SToomas Soome /*
2292c55d090SToomas Soome * encode 64bit data in big-endian format.
2302c55d090SToomas Soome */
2312c55d090SToomas Soome static void
Encode64(uint8_t * output,uint64_t * input,size_t len)2322c55d090SToomas Soome Encode64(uint8_t *output, uint64_t *input, size_t len)
2332c55d090SToomas Soome {
2342c55d090SToomas Soome size_t i, j;
2352c55d090SToomas Soome for (i = 0, j = 0; j < len; i++, j += 8) {
2362c55d090SToomas Soome output[j] = (input[i] >> 56) & 0xff;
2372c55d090SToomas Soome output[j + 1] = (input[i] >> 48) & 0xff;
2382c55d090SToomas Soome output[j + 2] = (input[i] >> 40) & 0xff;
2392c55d090SToomas Soome output[j + 3] = (input[i] >> 32) & 0xff;
2402c55d090SToomas Soome output[j + 4] = (input[i] >> 24) & 0xff;
2412c55d090SToomas Soome output[j + 5] = (input[i] >> 16) & 0xff;
2422c55d090SToomas Soome output[j + 6] = (input[i] >> 8) & 0xff;
2432c55d090SToomas Soome output[j + 7] = input[i] & 0xff;
2442c55d090SToomas Soome }
2452c55d090SToomas Soome }
2462c55d090SToomas Soome
2472c55d090SToomas Soome /*
2482c55d090SToomas Soome * Implements the SHA-384, SHA-512 and SHA-512/t hash algos - to select
2492c55d090SToomas Soome * between them pass the appropriate initial values for 'H'. The output
2502c55d090SToomas Soome * of this function is truncated to the first 256 bits that fit into 'zcp'.
2512c55d090SToomas Soome */
2522c55d090SToomas Soome static void
SHA512(uint64_t * H,const void * buf,uint64_t size,zio_cksum_t * zcp)2532c55d090SToomas Soome SHA512(uint64_t *H, const void *buf, uint64_t size, zio_cksum_t *zcp)
2542c55d090SToomas Soome {
2552c55d090SToomas Soome uint64_t c64[2];
2562c55d090SToomas Soome uint8_t pad[256];
2572c55d090SToomas Soome unsigned padsize = size & 127;
2582c55d090SToomas Soome unsigned i, k;
2592c55d090SToomas Soome
2602c55d090SToomas Soome /* process all blocks up to the last one */
2612c55d090SToomas Soome for (i = 0; i < size - padsize; i += 128)
262*8d20f156SMark Johnston SHA512Transform(H, (const uint8_t *)buf + i);
2632c55d090SToomas Soome
2642c55d090SToomas Soome /* process the last block and padding */
2652c55d090SToomas Soome for (k = 0; k < padsize; k++)
266*8d20f156SMark Johnston pad[k] = ((const uint8_t *)buf)[k + i];
2672c55d090SToomas Soome
2682c55d090SToomas Soome if (padsize < 112) {
2692c55d090SToomas Soome for (pad[padsize++] = 0x80; padsize < 112; padsize++)
2702c55d090SToomas Soome pad[padsize] = 0;
2712c55d090SToomas Soome } else {
2722c55d090SToomas Soome for (pad[padsize++] = 0x80; padsize < 240; padsize++)
2732c55d090SToomas Soome pad[padsize] = 0;
2742c55d090SToomas Soome }
2752c55d090SToomas Soome
2762c55d090SToomas Soome c64[0] = 0;
2772c55d090SToomas Soome c64[1] = size << 3;
2782c55d090SToomas Soome Encode64(pad+padsize, c64, sizeof (c64));
2792c55d090SToomas Soome padsize += sizeof (c64);
2802c55d090SToomas Soome
2812c55d090SToomas Soome for (i = 0; i < padsize; i += 128)
2822c55d090SToomas Soome SHA512Transform(H, pad + i);
2832c55d090SToomas Soome
2842c55d090SToomas Soome /* truncate the output to the first 256 bits which fit into 'zcp' */
2852c55d090SToomas Soome Encode64((uint8_t *)zcp, H, sizeof (uint64_t) * 4);
2862c55d090SToomas Soome }
2872c55d090SToomas Soome
2882c55d090SToomas Soome static void
zio_checksum_SHA256(const void * buf,uint64_t size,const void * ctx_template __unused,zio_cksum_t * zcp)2892c55d090SToomas Soome zio_checksum_SHA256(const void *buf, uint64_t size,
2902c55d090SToomas Soome const void *ctx_template __unused, zio_cksum_t *zcp)
2912c55d090SToomas Soome {
2922c55d090SToomas Soome /* SHA-256 as per FIPS 180-4. */
2932c55d090SToomas Soome uint32_t H[] = {
2942c55d090SToomas Soome 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
2952c55d090SToomas Soome 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
2962c55d090SToomas Soome };
2972c55d090SToomas Soome SHA256(H, buf, size, zcp);
2982c55d090SToomas Soome }
2992c55d090SToomas Soome
3002c55d090SToomas Soome static void
zio_checksum_SHA512_native(const void * buf,uint64_t size,const void * ctx_template __unused,zio_cksum_t * zcp)3012c55d090SToomas Soome zio_checksum_SHA512_native(const void *buf, uint64_t size,
3022c55d090SToomas Soome const void *ctx_template __unused, zio_cksum_t *zcp)
3032c55d090SToomas Soome {
3042c55d090SToomas Soome /* SHA-512/256 as per FIPS 180-4. */
3052c55d090SToomas Soome uint64_t H[] = {
3062c55d090SToomas Soome 0x22312194FC2BF72CULL, 0x9F555FA3C84C64C2ULL,
3072c55d090SToomas Soome 0x2393B86B6F53B151ULL, 0x963877195940EABDULL,
3082c55d090SToomas Soome 0x96283EE2A88EFFE3ULL, 0xBE5E1E2553863992ULL,
3092c55d090SToomas Soome 0x2B0199FC2C85B8AAULL, 0x0EB72DDC81C52CA2ULL
3102c55d090SToomas Soome };
3112c55d090SToomas Soome SHA512(H, buf, size, zcp);
3122c55d090SToomas Soome }
3132c55d090SToomas Soome
3142c55d090SToomas Soome static void
zio_checksum_SHA512_byteswap(const void * buf,uint64_t size,const void * ctx_template,zio_cksum_t * zcp)3152c55d090SToomas Soome zio_checksum_SHA512_byteswap(const void *buf, uint64_t size,
3162c55d090SToomas Soome const void *ctx_template, zio_cksum_t *zcp)
3172c55d090SToomas Soome {
3182c55d090SToomas Soome zio_cksum_t tmp;
3192c55d090SToomas Soome
3202c55d090SToomas Soome zio_checksum_SHA512_native(buf, size, ctx_template, &tmp);
3212c55d090SToomas Soome zcp->zc_word[0] = BSWAP_64(tmp.zc_word[0]);
3222c55d090SToomas Soome zcp->zc_word[1] = BSWAP_64(tmp.zc_word[1]);
3232c55d090SToomas Soome zcp->zc_word[2] = BSWAP_64(tmp.zc_word[2]);
3242c55d090SToomas Soome zcp->zc_word[3] = BSWAP_64(tmp.zc_word[3]);
3252c55d090SToomas Soome }
326