xref: /openbmc/u-boot/fs/zfs/zfs_sha256.c (revision 83d290c56fab2d38cd1ab4c4cc7099559c1d5046)
1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
24d3c95f5SJorgen Lundman /*
34d3c95f5SJorgen Lundman  *  GRUB  --  GRand Unified Bootloader
44d3c95f5SJorgen Lundman  *  Copyright (C) 1999,2000,2001,2002,2003,2004  Free Software Foundation, Inc.
54d3c95f5SJorgen Lundman  */
64d3c95f5SJorgen Lundman /*
74d3c95f5SJorgen Lundman  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
84d3c95f5SJorgen Lundman  * Use is subject to license terms.
94d3c95f5SJorgen Lundman  */
104d3c95f5SJorgen Lundman 
114d3c95f5SJorgen Lundman #include <common.h>
124d3c95f5SJorgen Lundman #include <malloc.h>
134d3c95f5SJorgen Lundman #include <linux/stat.h>
144d3c95f5SJorgen Lundman #include <linux/time.h>
154d3c95f5SJorgen Lundman #include <linux/ctype.h>
164d3c95f5SJorgen Lundman #include <asm/byteorder.h>
174d3c95f5SJorgen Lundman #include "zfs_common.h"
184d3c95f5SJorgen Lundman 
194d3c95f5SJorgen Lundman #include <zfs/zfs.h>
204d3c95f5SJorgen Lundman #include <zfs/zio.h>
214d3c95f5SJorgen Lundman #include <zfs/dnode.h>
224d3c95f5SJorgen Lundman #include <zfs/uberblock_impl.h>
234d3c95f5SJorgen Lundman #include <zfs/vdev_impl.h>
244d3c95f5SJorgen Lundman #include <zfs/zio_checksum.h>
254d3c95f5SJorgen Lundman #include <zfs/zap_impl.h>
264d3c95f5SJorgen Lundman #include <zfs/zap_leaf.h>
274d3c95f5SJorgen Lundman #include <zfs/zfs_znode.h>
284d3c95f5SJorgen Lundman #include <zfs/dmu.h>
294d3c95f5SJorgen Lundman #include <zfs/dmu_objset.h>
304d3c95f5SJorgen Lundman #include <zfs/dsl_dir.h>
314d3c95f5SJorgen Lundman #include <zfs/dsl_dataset.h>
324d3c95f5SJorgen Lundman 
334d3c95f5SJorgen Lundman /*
344d3c95f5SJorgen Lundman  * SHA-256 checksum, as specified in FIPS 180-2, available at:
354d3c95f5SJorgen Lundman  * http://csrc.nist.gov/cryptval
364d3c95f5SJorgen Lundman  *
374d3c95f5SJorgen Lundman  * This is a very compact implementation of SHA-256.
384d3c95f5SJorgen Lundman  * It is designed to be simple and portable, not to be fast.
394d3c95f5SJorgen Lundman  */
404d3c95f5SJorgen Lundman 
414d3c95f5SJorgen Lundman /*
424d3c95f5SJorgen Lundman  * The literal definitions according to FIPS180-2 would be:
434d3c95f5SJorgen Lundman  *
444d3c95f5SJorgen Lundman  *	Ch(x, y, z)		(((x) & (y)) ^ ((~(x)) & (z)))
454d3c95f5SJorgen Lundman  *	Maj(x, y, z)	(((x) & (y)) | ((x) & (z)) | ((y) & (z)))
464d3c95f5SJorgen Lundman  *
474d3c95f5SJorgen Lundman  * We use logical equivalents which require one less op.
484d3c95f5SJorgen Lundman  */
494d3c95f5SJorgen Lundman #define	Ch(x, y, z)	((z) ^ ((x) & ((y) ^ (z))))
504d3c95f5SJorgen Lundman #define	Maj(x, y, z)	(((x) & (y)) ^ ((z) & ((x) ^ (y))))
514d3c95f5SJorgen Lundman #define	Rot32(x, s)	(((x) >> s) | ((x) << (32 - s)))
524d3c95f5SJorgen Lundman #define	SIGMA0(x)	(Rot32(x, 2) ^ Rot32(x, 13) ^ Rot32(x, 22))
534d3c95f5SJorgen Lundman #define	SIGMA1(x)	(Rot32(x, 6) ^ Rot32(x, 11) ^ Rot32(x, 25))
544d3c95f5SJorgen Lundman #define	sigma0(x)	(Rot32(x, 7) ^ Rot32(x, 18) ^ ((x) >> 3))
554d3c95f5SJorgen Lundman #define	sigma1(x)	(Rot32(x, 17) ^ Rot32(x, 19) ^ ((x) >> 10))
564d3c95f5SJorgen Lundman 
574d3c95f5SJorgen Lundman static const uint32_t SHA256_K[64] = {
584d3c95f5SJorgen Lundman 	0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
594d3c95f5SJorgen Lundman 	0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
604d3c95f5SJorgen Lundman 	0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
614d3c95f5SJorgen Lundman 	0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
624d3c95f5SJorgen Lundman 	0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
634d3c95f5SJorgen Lundman 	0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
644d3c95f5SJorgen Lundman 	0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
654d3c95f5SJorgen Lundman 	0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
664d3c95f5SJorgen Lundman 	0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
674d3c95f5SJorgen Lundman 	0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
684d3c95f5SJorgen Lundman 	0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
694d3c95f5SJorgen Lundman 	0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
704d3c95f5SJorgen Lundman 	0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
714d3c95f5SJorgen Lundman 	0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
724d3c95f5SJorgen Lundman 	0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
734d3c95f5SJorgen Lundman 	0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
744d3c95f5SJorgen Lundman };
754d3c95f5SJorgen Lundman 
764d3c95f5SJorgen Lundman static void
SHA256Transform(uint32_t * H,const uint8_t * cp)774d3c95f5SJorgen Lundman SHA256Transform(uint32_t *H, const uint8_t *cp)
784d3c95f5SJorgen Lundman {
794d3c95f5SJorgen Lundman 	uint32_t a, b, c, d, e, f, g, h, t, T1, T2, W[64];
804d3c95f5SJorgen Lundman 
814d3c95f5SJorgen Lundman 	for (t = 0; t < 16; t++, cp += 4)
824d3c95f5SJorgen Lundman 		W[t] = (cp[0] << 24) | (cp[1] << 16) | (cp[2] << 8) | cp[3];
834d3c95f5SJorgen Lundman 
844d3c95f5SJorgen Lundman 	for (t = 16; t < 64; t++)
854d3c95f5SJorgen Lundman 		W[t] = sigma1(W[t - 2]) + W[t - 7] +
864d3c95f5SJorgen Lundman 			sigma0(W[t - 15]) + W[t - 16];
874d3c95f5SJorgen Lundman 
884d3c95f5SJorgen Lundman 	a = H[0]; b = H[1]; c = H[2]; d = H[3];
894d3c95f5SJorgen Lundman 	e = H[4]; f = H[5]; g = H[6]; h = H[7];
904d3c95f5SJorgen Lundman 
914d3c95f5SJorgen Lundman 	for (t = 0; t < 64; t++) {
924d3c95f5SJorgen Lundman 		T1 = h + SIGMA1(e) + Ch(e, f, g) + SHA256_K[t] + W[t];
934d3c95f5SJorgen Lundman 		T2 = SIGMA0(a) + Maj(a, b, c);
944d3c95f5SJorgen Lundman 		h = g; g = f; f = e; e = d + T1;
954d3c95f5SJorgen Lundman 		d = c; c = b; b = a; a = T1 + T2;
964d3c95f5SJorgen Lundman 	}
974d3c95f5SJorgen Lundman 
984d3c95f5SJorgen Lundman 	H[0] += a; H[1] += b; H[2] += c; H[3] += d;
994d3c95f5SJorgen Lundman 	H[4] += e; H[5] += f; H[6] += g; H[7] += h;
1004d3c95f5SJorgen Lundman }
1014d3c95f5SJorgen Lundman 
1024d3c95f5SJorgen Lundman void
zio_checksum_SHA256(const void * buf,uint64_t size,zfs_endian_t endian,zio_cksum_t * zcp)1034d3c95f5SJorgen Lundman zio_checksum_SHA256(const void *buf, uint64_t size,
1044d3c95f5SJorgen Lundman 					zfs_endian_t endian, zio_cksum_t *zcp)
1054d3c95f5SJorgen Lundman {
1064d3c95f5SJorgen Lundman 	uint32_t H[8] = { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
1074d3c95f5SJorgen Lundman 					  0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 };
1084d3c95f5SJorgen Lundman 	uint8_t pad[128];
1094d3c95f5SJorgen Lundman 	unsigned padsize = size & 63;
1104d3c95f5SJorgen Lundman 	unsigned i;
1114d3c95f5SJorgen Lundman 
1124d3c95f5SJorgen Lundman 	for (i = 0; i < size - padsize; i += 64)
1134d3c95f5SJorgen Lundman 		SHA256Transform(H, (uint8_t *)buf + i);
1144d3c95f5SJorgen Lundman 
1154d3c95f5SJorgen Lundman 	for (i = 0; i < padsize; i++)
1164d3c95f5SJorgen Lundman 		pad[i] = ((uint8_t *)buf)[i];
1174d3c95f5SJorgen Lundman 
1184d3c95f5SJorgen Lundman 	for (pad[padsize++] = 0x80; (padsize & 63) != 56; padsize++)
1194d3c95f5SJorgen Lundman 		pad[padsize] = 0;
1204d3c95f5SJorgen Lundman 
1214d3c95f5SJorgen Lundman 	for (i = 0; i < 8; i++)
1224d3c95f5SJorgen Lundman 		pad[padsize++] = (size << 3) >> (56 - 8 * i);
1234d3c95f5SJorgen Lundman 
1244d3c95f5SJorgen Lundman 	for (i = 0; i < padsize; i += 64)
1254d3c95f5SJorgen Lundman 		SHA256Transform(H, pad + i);
1264d3c95f5SJorgen Lundman 
1274d3c95f5SJorgen Lundman 	zcp->zc_word[0] = cpu_to_zfs64((uint64_t)H[0] << 32 | H[1],
1284d3c95f5SJorgen Lundman 										endian);
1294d3c95f5SJorgen Lundman 	zcp->zc_word[1] = cpu_to_zfs64((uint64_t)H[2] << 32 | H[3],
1304d3c95f5SJorgen Lundman 										endian);
1314d3c95f5SJorgen Lundman 	zcp->zc_word[2] = cpu_to_zfs64((uint64_t)H[4] << 32 | H[5],
1324d3c95f5SJorgen Lundman 										endian);
1334d3c95f5SJorgen Lundman 	zcp->zc_word[3] = cpu_to_zfs64((uint64_t)H[6] << 32 | H[7],
1344d3c95f5SJorgen Lundman 										endian);
1354d3c95f5SJorgen Lundman }
136