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