svn commit: r328866 - in stable/11/sys: boot/efi/boot1 boot/efi/loader boot/i386/boot2 boot/i386/gptboot boot/i386/gptzfsboot boot/i386/zfsboot boot/userboot/ficl boot/userboot/userboot boot/userbo...

Kyle Evans kevans at FreeBSD.org
Mon Feb 5 04:01:02 UTC 2018


Author: kevans
Date: Mon Feb  5 04:00:59 2018
New Revision: 328866
URL: https://svnweb.freebsd.org/changeset/base/328866

Log:
  MFC r304321,304753,304754,306751,316077,316110:
  SHA512, skein, large block support for loader zfs
  
  MFC r304321: Add SHA512, skein, large blocks support for loader zfs.
  MFC r304753: loader: zio_checksum_verify() must test spa for NULL pointer
  MFC r304754: r304321 broken bhyve zvol VM bhyveload hang 100% WCPU
  MFC r306751: Disable loop unrolling in skein for sys/boot
  MFC r316077: Unbreak compilation with gcc 4.2.1
  MFC r316110: Use `-Wno-missing-declarations` with CWARNFLAGS for skein.c

Added:
  stable/11/sys/cddl/boot/zfs/skein_zfs.c
     - copied unchanged from r304321, head/sys/cddl/boot/zfs/skein_zfs.c
Modified:
  stable/11/sys/boot/efi/boot1/Makefile
  stable/11/sys/boot/efi/loader/Makefile
  stable/11/sys/boot/i386/boot2/Makefile
  stable/11/sys/boot/i386/gptboot/Makefile
  stable/11/sys/boot/i386/gptboot/gptldr.S
  stable/11/sys/boot/i386/gptzfsboot/Makefile
  stable/11/sys/boot/i386/zfsboot/Makefile
  stable/11/sys/boot/i386/zfsboot/zfsboot.c
  stable/11/sys/boot/i386/zfsboot/zfsldr.S
  stable/11/sys/boot/userboot/ficl/Makefile
  stable/11/sys/boot/userboot/userboot/Makefile
  stable/11/sys/boot/userboot/userboot/main.c
  stable/11/sys/boot/userboot/zfs/Makefile
  stable/11/sys/boot/zfs/Makefile
  stable/11/sys/boot/zfs/zfsimpl.c
  stable/11/sys/cddl/boot/zfs/fletcher.c
  stable/11/sys/cddl/boot/zfs/sha256.c
  stable/11/sys/cddl/boot/zfs/zfsimpl.h
  stable/11/sys/cddl/boot/zfs/zfssubr.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/boot/efi/boot1/Makefile
==============================================================================
--- stable/11/sys/boot/efi/boot1/Makefile	Mon Feb  5 00:18:21 2018	(r328865)
+++ stable/11/sys/boot/efi/boot1/Makefile	Mon Feb  5 04:00:59 2018	(r328866)
@@ -19,12 +19,22 @@ CWARNFLAGS.zfs_module.c += -Wno-missing-prototypes
 CWARNFLAGS.zfs_module.c += -Wno-sign-compare
 CWARNFLAGS.zfs_module.c += -Wno-unused-parameter
 CWARNFLAGS.zfs_module.c += -Wno-unused-function
+CWARNFLAGS.skein.c += -Wno-cast-align
+.if ${COMPILER_TYPE} == "clang"
+CWARNFLAGS.skein.c += -Wno-missing-variable-declarations
+.else if ${COMPILER_TYPE} == "gcc"
+CWARNFLAGS.skein.c += -Wno-missing-declarations
 .endif
+.endif
 
 # architecture-specific loader code
 SRCS=	boot1.c self_reloc.c start.S ufs_module.c
 .if ${MK_ZFS} != "no"
 SRCS+=		zfs_module.c
+SRCS+=		skein.c skein_block.c
+# Do not unroll skein loops, reduce code size
+CFLAGS+=	-DSKEIN_LOOP=111
+.PATH:		${.CURDIR}/../../../crypto/skein
 .endif
 
 .if ${COMPILER_TYPE} == "gcc" && ${COMPILER_VERSION} > 40201
@@ -44,6 +54,7 @@ CFLAGS+=	-DEFI_DEBUG
 .if ${MK_ZFS} != "no"
 CFLAGS+=	-I${.CURDIR}/../../zfs/
 CFLAGS+=	-I${.CURDIR}/../../../cddl/boot/zfs/
+CFLAGS+=	-I${.CURDIR}/../../../crypto/skein
 CFLAGS+=	-DEFI_ZFS_BOOT
 .endif
 

Modified: stable/11/sys/boot/efi/loader/Makefile
==============================================================================
--- stable/11/sys/boot/efi/loader/Makefile	Mon Feb  5 00:18:21 2018	(r328865)
+++ stable/11/sys/boot/efi/loader/Makefile	Mon Feb  5 04:00:59 2018	(r328866)
@@ -24,6 +24,10 @@ SRCS=	autoload.c \
 .if ${MK_ZFS} != "no"
 SRCS+=		zfs.c
 .PATH:		${.CURDIR}/../../zfs
+SRCS+=		skein.c skein_block.c
+# Do not unroll skein loops, reduce code size
+CFLAGS+=	-DSKEIN_LOOP=111
+.PATH:		${.CURDIR}/../../../crypto/skein
 
 # Disable warnings that are currently incompatible with the zfs boot code
 CWARNFLAGS.zfs.c+=	-Wno-sign-compare
@@ -57,6 +61,7 @@ CFLAGS+=	-I${.CURDIR}/../../i386/libi386
 .if ${MK_ZFS} != "no"
 CFLAGS+=	-I${.CURDIR}/../../zfs
 CFLAGS+=	-I${.CURDIR}/../../../cddl/boot/zfs
+CFLAGS+=	-I${.CURDIR}/../../../crypto/skein
 CFLAGS+=	-DEFI_ZFS_BOOT
 .endif
 CFLAGS+=	-DNO_PCI -DEFI

Modified: stable/11/sys/boot/i386/boot2/Makefile
==============================================================================
--- stable/11/sys/boot/i386/boot2/Makefile	Mon Feb  5 00:18:21 2018	(r328865)
+++ stable/11/sys/boot/i386/boot2/Makefile	Mon Feb  5 04:00:59 2018	(r328866)
@@ -33,7 +33,7 @@ CFLAGS=	-fomit-frame-pointer \
 	-DSIOSPD=${BOOT_COMCONSOLE_SPEED} \
 	-I${.CURDIR}/../../common \
 	-I${.CURDIR}/../btx/lib -I. \
-	-Wall -Waggregate-return -Wbad-function-cast -Wcast-align \
+	-Wall -Waggregate-return -Wbad-function-cast -Wno-cast-align \
 	-Wmissing-declarations -Wmissing-prototypes -Wnested-externs \
 	-Wpointer-arith -Wshadow -Wstrict-prototypes -Wwrite-strings \
 	-Winline

Modified: stable/11/sys/boot/i386/gptboot/Makefile
==============================================================================
--- stable/11/sys/boot/i386/gptboot/Makefile	Mon Feb  5 00:18:21 2018	(r328865)
+++ stable/11/sys/boot/i386/gptboot/Makefile	Mon Feb  5 04:00:59 2018	(r328866)
@@ -32,10 +32,10 @@ CFLAGS=	-DBOOTPROG=\"gptboot\" \
 	-I${.CURDIR}/../btx/lib -I. \
 	-I${.CURDIR}/../boot2 \
 	-I${.CURDIR}/../../.. \
-	-Wall -Waggregate-return -Wbad-function-cast -Wcast-align \
+	-Wall -Waggregate-return -Wbad-function-cast -Wno-cast-align \
 	-Wmissing-declarations -Wmissing-prototypes -Wnested-externs \
 	-Wpointer-arith -Wshadow -Wstrict-prototypes -Wwrite-strings \
-	-Winline
+	-Winline -Wno-pointer-sign
 
 CFLAGS.gcc+=	--param max-inline-insns-single=100
 

Modified: stable/11/sys/boot/i386/gptboot/gptldr.S
==============================================================================
--- stable/11/sys/boot/i386/gptboot/gptldr.S	Mon Feb  5 00:18:21 2018	(r328865)
+++ stable/11/sys/boot/i386/gptboot/gptldr.S	Mon Feb  5 04:00:59 2018	(r328866)
@@ -45,7 +45,7 @@
 /* Misc. Constants */
 		.set SIZ_PAG,0x1000		# Page size
 		.set SIZ_SEC,0x200		# Sector size
-		.set COPY_BLKS,0x4		# Number of blocks
+		.set COPY_BLKS,0x8		# Number of blocks
 						# to copy for boot2
 		.set COPY_BLK_SZ,0x8000		# Copy in 32k blocks; must be
 						# a multiple of 16 bytes

Modified: stable/11/sys/boot/i386/gptzfsboot/Makefile
==============================================================================
--- stable/11/sys/boot/i386/gptzfsboot/Makefile	Mon Feb  5 00:18:21 2018	(r328865)
+++ stable/11/sys/boot/i386/gptzfsboot/Makefile	Mon Feb  5 04:00:59 2018	(r328866)
@@ -1,8 +1,10 @@
 # $FreeBSD$
 
+.include <bsd.own.mk>
+
 .PATH:		${.CURDIR}/../boot2 ${.CURDIR}/../gptboot \
 		${.CURDIR}/../zfsboot ${.CURDIR}/../common \
-		${.CURDIR}/../../common
+		${.CURDIR}/../../common ${.CURDIR}/../../../crypto/skein
 
 FILES=		gptzfsboot
 MAN=		gptzfsboot.8
@@ -27,14 +29,23 @@ CFLAGS=	-DBOOTPROG=\"gptzfsboot\" \
 	-I${.CURDIR}/../common \
 	-I${.CURDIR}/../../zfs \
 	-I${.CURDIR}/../../../cddl/boot/zfs \
+	-I${.CURDIR}/../../../crypto/skein \
 	-I${.CURDIR}/../btx/lib -I. \
 	-I${.CURDIR}/../boot2 \
 	-I${.CURDIR}/../../.. \
-	-Wall -Waggregate-return -Wbad-function-cast -Wcast-align \
+	-Wall -Waggregate-return -Wbad-function-cast -Wno-cast-align \
 	-Wmissing-declarations -Wmissing-prototypes -Wnested-externs \
 	-Wpointer-arith -Wshadow -Wstrict-prototypes -Wwrite-strings \
-	-Winline
+	-Winline -Wno-pointer-sign
 
+.if ${COMPILER_TYPE} == "clang" || \
+    (${COMPILER_TYPE} == "gcc" && ${COMPILER_VERSION} > 40201)
+CFLAGS+=	-Wno-tentative-definition-incomplete-type
+.endif
+
+# Do not unroll skein loops, reduce code size
+CFLAGS+=	-DSKEIN_LOOP=111
+
 .if !defined(LOADER_NO_GELI_SUPPORT)
 CFLAGS+=	-DLOADER_GELI_SUPPORT
 CFLAGS+=	-I${.CURDIR}/../../geli
@@ -67,12 +78,13 @@ gptldr.out: gptldr.o
 	${LD} ${LD_FLAGS} -e start -Ttext ${ORG1} -o ${.TARGET} gptldr.o
 
 CLEANFILES+=	gptzfsboot.bin gptzfsboot.out zfsboot.o sio.o cons.o \
-		drv.o gpt.o util.o ${OPENCRYPTO_XTS}
+		drv.o gpt.o util.o skein.o skein_block.o ${OPENCRYPTO_XTS}
 
 gptzfsboot.bin: gptzfsboot.out
 	${OBJCOPY} -S -O binary gptzfsboot.out ${.TARGET}
 
-gptzfsboot.out: ${BTXCRT} zfsboot.o sio.o gpt.o drv.o cons.o util.o ${OPENCRYPTO_XTS}
+gptzfsboot.out: ${BTXCRT} zfsboot.o sio.o gpt.o drv.o cons.o util.o \
+	skein.o skein_block.o ${OPENCRYPTO_XTS}
 	${LD} ${LD_FLAGS} -Ttext ${ORG2} -o ${.TARGET} ${.ALLSRC} ${LIBSTAND} ${LIBGELIBOOT}
 
 zfsboot.o: ${.CURDIR}/../../zfs/zfsimpl.c

Modified: stable/11/sys/boot/i386/zfsboot/Makefile
==============================================================================
--- stable/11/sys/boot/i386/zfsboot/Makefile	Mon Feb  5 00:18:21 2018	(r328865)
+++ stable/11/sys/boot/i386/zfsboot/Makefile	Mon Feb  5 04:00:59 2018	(r328866)
@@ -1,6 +1,7 @@
 # $FreeBSD$
 
-.PATH:		${.CURDIR}/../boot2 ${.CURDIR}/../common ${.CURDIR}/../../common
+.PATH:		${.CURDIR}/../boot2 ${.CURDIR}/../common \
+		${.CURDIR}/../../common ${.CURDIR}/../../../crypto/skein
 
 FILES=		zfsboot
 MAN=		zfsboot.8
@@ -25,14 +26,17 @@ CFLAGS=	-DBOOTPROG=\"zfsboot\" \
 	-I${.CURDIR}/../common \
 	-I${.CURDIR}/../../zfs \
 	-I${.CURDIR}/../../../cddl/boot/zfs \
+	-I${.CURDIR}/../../../crypto/skein \
 	-I${.CURDIR}/../btx/lib -I. \
 	-I${.CURDIR}/../boot2 \
-	-Wall -Waggregate-return -Wbad-function-cast -Wcast-align \
+	-Wall -Waggregate-return -Wbad-function-cast -Wno-cast-align \
 	-Wmissing-declarations -Wmissing-prototypes -Wnested-externs \
 	-Wpointer-arith -Wshadow -Wstrict-prototypes -Wwrite-strings \
 	-Winline
 
 CFLAGS.gcc+=	--param max-inline-insns-single=100
+# Do not unroll skein loops, reduce code size
+CFLAGS+=	-DSKEIN_LOOP=111
 
 LD_FLAGS=-static -N --gc-sections
 
@@ -55,12 +59,13 @@ zfsldr.out: zfsldr.o
 	${LD} ${LD_FLAGS} -e start -Ttext ${ORG1} -o ${.TARGET} zfsldr.o
 
 CLEANFILES+=	zfsboot2 zfsboot.ld zfsboot.ldr zfsboot.bin zfsboot.out \
-		zfsboot.o zfsboot.s zfsboot.s.tmp sio.o cons.o drv.o util.o
+		zfsboot.o zfsboot.s zfsboot.s.tmp sio.o cons.o drv.o util.o \
+		skein.o skein_block.o
 
-# We currently allow 65536 bytes for zfsboot - in practice it could be
+# We currently allow 128k bytes for zfsboot - in practice it could be
 # any size up to 3.5Mb but keeping it fixed size simplifies zfsldr.
 # 
-BOOT2SIZE=	65536
+BOOT2SIZE=	131072
 
 zfsboot2: zfsboot.ld
 	@set -- `ls -l ${.ALLSRC}`; x=$$((${BOOT2SIZE}-$$5)); \
@@ -77,7 +82,7 @@ zfsboot.ldr:
 zfsboot.bin: zfsboot.out
 	${OBJCOPY} -S -O binary zfsboot.out ${.TARGET}
 
-zfsboot.out: ${BTXCRT} zfsboot.o sio.o drv.o cons.o util.o
+zfsboot.out: ${BTXCRT} zfsboot.o sio.o drv.o cons.o util.o skein.o skein_block.o
 	${LD} ${LD_FLAGS} -Ttext ${ORG2} -o ${.TARGET} ${.ALLSRC} ${LIBSTAND}
 
 SRCS=	zfsboot.c

Modified: stable/11/sys/boot/i386/zfsboot/zfsboot.c
==============================================================================
--- stable/11/sys/boot/i386/zfsboot/zfsboot.c	Mon Feb  5 00:18:21 2018	(r328865)
+++ stable/11/sys/boot/i386/zfsboot/zfsboot.c	Mon Feb  5 04:00:59 2018	(r328866)
@@ -105,7 +105,7 @@ static struct bios_smap smap;
 /*
  * The minimum amount of memory to reserve in bios_extmem for the heap.
  */
-#define	HEAP_MIN		(3 * 1024 * 1024)
+#define	HEAP_MIN		(64 * 1024 * 1024)
 
 static char *heap_next;
 static char *heap_end;

Modified: stable/11/sys/boot/i386/zfsboot/zfsldr.S
==============================================================================
--- stable/11/sys/boot/i386/zfsboot/zfsldr.S	Mon Feb  5 00:18:21 2018	(r328865)
+++ stable/11/sys/boot/i386/zfsboot/zfsldr.S	Mon Feb  5 04:00:59 2018	(r328866)
@@ -32,8 +32,11 @@
 /* Misc. Constants */
 		.set SIZ_PAG,0x1000		# Page size
 		.set SIZ_SEC,0x200		# Sector size
-
-		.set NSECT,0x80
+		.set COPY_BLKS,0x8		# Number of blocks
+						# to copy for boot2
+		.set COPY_BLK_SZ,0x8000		# Copy in 32k blocks; must be
+						# a multiple of 16 bytes
+		.set NSECT,(COPY_BLK_SZ / SIZ_SEC * COPY_BLKS)
 		.globl start
 		.code16
 
@@ -88,12 +91,12 @@ main.3: 	add $0x10,%si	 		# Next entry
 /*
  * Ok, we have a slice and drive in %dx now, so use that to locate and
  * load boot2.  %si references the start of the slice we are looking
- * for, so go ahead and load up the 128 sectors starting at sector 1024
- * (i.e. after the two vdev labels).  We don't have do anything fancy
- * here to allow for an extra copy of boot1 and a partition table
- * (compare to this section of the UFS bootstrap) so we just load it
- * all at 0x9000. The first part of boot2 is BTX, which wants to run
- * at 0x9000. The boot2.bin binary starts right after the end of BTX,
+ * for, so go ahead and load up the COPY_BLKS*COPY_BLK_SZ/SIZ_SEC sectors
+ * starting at sector 1024 (i.e. after the two vdev labels).  We don't
+ * have do anything fancy here to allow for an extra copy of boot1 and
+ * a partition table (compare to this section of the UFS bootstrap) so we
+ * just load it all at 0x9000. The first part of boot2 is BTX, which wants
+ * to run at 0x9000. The boot2.bin binary starts right after the end of BTX,
  * so we have to figure out where the start of it is and then move the
  * binary to 0xc000.  Normally, BTX clients start at MEM_USR, or 0xa000,
  * but when we use btxld to create zfsboot2, we use an entry point of
@@ -116,23 +119,37 @@ main.6:		pushal				# Save params
 		incl %eax			# Advance to
 		add $SIZ_SEC,%ebx		#  next sector
 		loop main.6			# If not last, read another
-		mov MEM_BTX+0xa,%bx		# Get BTX length
-		mov $NSECT*SIZ_SEC-1,%di	# Size of load area (less one)
-		mov %di,%si			# End of load area, 0x9000 rel
-		sub %bx,%di			# End of client, 0xc000 rel
-		mov %di,%cx			# Size of
-		inc %cx				#  client
-		mov $(MEM_BTX)>>4,%dx		# Segment
-		mov %dx,%ds			#   addressing 0x9000
-		mov $(MEM_USR+2*SIZ_PAG)>>4,%dx	# Segment
-		mov %dx,%es			#   addressing 0xc000
-		std				# Move with decrement
-		rep				# Relocate
-		movsb				#  client
+
+		mov $MEM_BTX,%bx		# BTX
+		mov 0xa(%bx),%si		# Get BTX length and set
+		add %bx,%si			#  %si to start of boot2
+		dec %si				# Set %ds:%si to point at the
+		mov %si,%ax			# last byte we want to copy
+		shr $4,%ax			# from boot2, with %si made as
+		add $(COPY_BLKS*COPY_BLK_SZ/16),%ax	# small as possible.
+		and $0xf,%si			#
+		mov %ax,%ds			#
+		mov $(MEM_USR+2*SIZ_PAG)/16,%ax # Set %es:(-1) to point at
+		add $(COPY_BLKS*COPY_BLK_SZ/16),%ax	# the last byte we
+		mov %ax,%es			# want to copy boot2 into.
+		mov $COPY_BLKS,%bx		# Copy COPY_BLKS 32k blocks
+copyloop:
+		add $COPY_BLK_SZ,%si		# Adjust %ds:%si to point at
+		mov %ds,%ax			# the end of the next 32k to
+		sub $COPY_BLK_SZ/16,%ax		# copy from boot2
+		mov %ax,%ds
+		mov $COPY_BLK_SZ-1,%di		# Adjust %es:%di to point at
+		mov %es,%ax			# the end of the next 32k into
+		sub $COPY_BLK_SZ/16,%ax		# which we want boot2 copied
+		mov %ax,%es
+		mov $COPY_BLK_SZ,%cx		# Copy 32k
+		std
+		rep movsb
+		dec %bx
+		jnz copyloop
+		mov %cx,%ds			# Reset %ds and %es
+		mov %cx,%es
 		cld				# Back to increment
-		xor %dx,%dx			# Back
-		mov %ds,%dx			#  to zero
-		mov %dx,%es			#  segment
 
 /*
  * Enable A20 so we can access memory above 1 meg.

Modified: stable/11/sys/boot/userboot/ficl/Makefile
==============================================================================
--- stable/11/sys/boot/userboot/ficl/Makefile	Mon Feb  5 00:18:21 2018	(r328865)
+++ stable/11/sys/boot/userboot/ficl/Makefile	Mon Feb  5 04:00:59 2018	(r328866)
@@ -10,6 +10,9 @@ BASE_SRCS=	dict.c ficl.c fileaccess.c float.c loader.c
 
 SRCS=		${BASE_SRCS} sysdep.c softcore.c
 CLEANFILES=	softcore.c testmain testmain.o
+
+CWARNFLAGS.loader.c.c += -Wno-implicit-function-declaration
+
 .if HAVE_PNP
 CFLAGS+=	-DHAVE_PNP
 .endif

Modified: stable/11/sys/boot/userboot/userboot/Makefile
==============================================================================
--- stable/11/sys/boot/userboot/userboot/Makefile	Mon Feb  5 00:18:21 2018	(r328865)
+++ stable/11/sys/boot/userboot/userboot/Makefile	Mon Feb  5 04:00:59 2018	(r328866)
@@ -35,6 +35,8 @@ CFLAGS+=	-I${.CURDIR}/../../..
 CFLAGS+=	-I${.CURDIR}/../../../../lib/libstand
 CFLAGS+=	-ffreestanding -I.
 
+CWARNFLAGS.main.c += -Wno-implicit-function-declaration
+
 LDFLAGS+=	-nostdlib -Wl,-Bsymbolic
 
 NEWVERSWHAT=	"User boot" ${MACHINE_CPUARCH}

Modified: stable/11/sys/boot/userboot/userboot/main.c
==============================================================================
--- stable/11/sys/boot/userboot/userboot/main.c	Mon Feb  5 00:18:21 2018	(r328865)
+++ stable/11/sys/boot/userboot/userboot/main.c	Mon Feb  5 04:00:59 2018	(r328866)
@@ -46,7 +46,7 @@ static int userboot_zfs_found;
 /* Minimum version required */
 #define	USERBOOT_VERSION	USERBOOT_VERSION_3
 
-#define	MALLOCSZ		(10*1024*1024)
+#define	MALLOCSZ		(64*1024*1024)
 
 struct loader_callbacks *callbacks;
 void *callbacks_arg;

Modified: stable/11/sys/boot/userboot/zfs/Makefile
==============================================================================
--- stable/11/sys/boot/userboot/zfs/Makefile	Mon Feb  5 00:18:21 2018	(r328865)
+++ stable/11/sys/boot/userboot/zfs/Makefile	Mon Feb  5 04:00:59 2018	(r328866)
@@ -2,15 +2,19 @@
 
 S=		${.CURDIR}/../../zfs
 
-.PATH:		${S}
+.PATH:		${S} ${.CURDIR}/../../../crypto/skein
 LIB=		zfsboot
 INTERNALLIB=
 
-SRCS+=		zfs.c
+SRCS+=		zfs.c skein.c skein_block.c
 
+# Do not unroll skein loops, reduce code size
+CFLAGS+=	-DSKEIN_LOOP=111
+
 CFLAGS+=	-I${.CURDIR}/../../common -I${.CURDIR}/../../.. -I.
 CFLAGS+=	-I${.CURDIR}/../../../../lib/libstand
 CFLAGS+=	-I${.CURDIR}/../../../cddl/boot/zfs
+CFLAGS+=	-I${.CURDIR}/../../../crypto/skein
 
 CFLAGS+=	-ffreestanding -fPIC
 CFLAGS+=	-Wformat -Wall

Modified: stable/11/sys/boot/zfs/Makefile
==============================================================================
--- stable/11/sys/boot/zfs/Makefile	Mon Feb  5 00:18:21 2018	(r328865)
+++ stable/11/sys/boot/zfs/Makefile	Mon Feb  5 04:00:59 2018	(r328866)
@@ -5,10 +5,16 @@ INTERNALLIB=
 
 SRCS+=		zfs.c
 
+SRCS+=		skein.c skein_block.c
+# Do not unroll skein loops, reduce code size
+CFLAGS+=	-DSKEIN_LOOP=111
+.PATH:		${.CURDIR}/../../crypto/skein
+
 CFLAGS+=	-DBOOTPROG=\"zfsloader\"
 CFLAGS+=	-I${.CURDIR}/../common -I${.CURDIR}/../.. -I.
 CFLAGS+=	-I${.CURDIR}/../../../lib/libstand
 CFLAGS+=	-I${.CURDIR}/../../cddl/boot/zfs
+CFLAGS+=	-I${.CURDIR}/../../crypto/skein
 
 .if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64"
 CFLAGS+=	-march=i386

Modified: stable/11/sys/boot/zfs/zfsimpl.c
==============================================================================
--- stable/11/sys/boot/zfs/zfsimpl.c	Mon Feb  5 00:18:21 2018	(r328865)
+++ stable/11/sys/boot/zfs/zfsimpl.c	Mon Feb  5 04:00:59 2018	(r328866)
@@ -58,6 +58,8 @@ static const char *features_for_read[] = {
 	"com.delphix:extensible_dataset",
 	"com.delphix:embedded_data",
 	"org.open-zfs:large_blocks",
+	"org.illumos:sha512",
+	"org.illumos:skein",
 	NULL
 };
 
@@ -77,6 +79,9 @@ static char *zfs_temp_buf, *zfs_temp_end, *zfs_temp_pt
 static int zio_read(const spa_t *spa, const blkptr_t *bp, void *buf);
 static int zfs_get_root(const spa_t *spa, uint64_t *objid);
 static int zfs_rlookup(const spa_t *spa, uint64_t objnum, char *result);
+static int zap_lookup(const spa_t *spa, const dnode_phys_t *dnode,
+    const char *name, uint64_t integer_size, uint64_t num_integers,
+    void *value);
 
 static void
 zfs_init(void)
@@ -419,7 +424,7 @@ vdev_read_phys(vdev_t *vdev, const blkptr_t *bp, void 
 	rc = vdev->v_phys_read(vdev, vdev->v_read_priv, offset, buf, psize);
 	if (rc)
 		return (rc);
-	if (bp && zio_checksum_verify(bp, buf))
+	if (bp && zio_checksum_verify(vdev->spa, bp, buf))
 		return (EIO);
 
 	return (0);
@@ -1073,6 +1078,7 @@ vdev_probe(vdev_phys_read_t *_read, void *read_priv, s
 	}
 	zfs_free(upbuf, VDEV_UBERBLOCK_SIZE(vdev));
 
+	vdev->spa = spa;
 	if (spap)
 		*spap = spa;
 	return (0);
@@ -1121,7 +1127,7 @@ zio_read_gang(const spa_t *spa, const blkptr_t *bp, vo
 		pbuf += BP_GET_PSIZE(gbp);
 	}
 
-	if (zio_checksum_verify(bp, buf))
+	if (zio_checksum_verify(spa, bp, buf))
 		return (EIO);
 	return (0);
 }
@@ -1223,7 +1229,8 @@ dnode_read(const spa_t *spa, const dnode_phys_t *dnode
 	int i, rc;
 
 	if (bsize > SPA_MAXBLOCKSIZE) {
-		printf("ZFS: I/O error - blocks larger than 128K are not supported\n");
+		printf("ZFS: I/O error - blocks larger than %llu are not "
+		    "supported\n", SPA_MAXBLOCKSIZE);
 		return (EIO);
 	}
 
@@ -1363,12 +1370,73 @@ fzap_leaf_value(const zap_leaf_t *zl, const zap_leaf_c
 	return value;
 }
 
+static void
+stv(int len, void *addr, uint64_t value)
+{
+	switch (len) {
+	case 1:
+		*(uint8_t *)addr = value;
+		return;
+	case 2:
+		*(uint16_t *)addr = value;
+		return;
+	case 4:
+		*(uint32_t *)addr = value;
+		return;
+	case 8:
+		*(uint64_t *)addr = value;
+		return;
+	}
+}
+
 /*
+ * Extract a array from a zap leaf entry.
+ */
+static void
+fzap_leaf_array(const zap_leaf_t *zl, const zap_leaf_chunk_t *zc,
+    uint64_t integer_size, uint64_t num_integers, void *buf)
+{
+	uint64_t array_int_len = zc->l_entry.le_value_intlen;
+	uint64_t value = 0;
+	uint64_t *u64 = buf;
+	char *p = buf;
+	int len = MIN(zc->l_entry.le_value_numints, num_integers);
+	int chunk = zc->l_entry.le_value_chunk;
+	int byten = 0;
+
+	if (integer_size == 8 && len == 1) {
+		*u64 = fzap_leaf_value(zl, zc);
+		return;
+	}
+
+	while (len > 0) {
+		struct zap_leaf_array *la = &ZAP_LEAF_CHUNK(zl, chunk).l_array;
+		int i;
+
+		ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS(zl));
+		for (i = 0; i < ZAP_LEAF_ARRAY_BYTES && len > 0; i++) {
+			value = (value << 8) | la->la_array[i];
+			byten++;
+			if (byten == array_int_len) {
+				stv(integer_size, p, value);
+				byten = 0;
+				len--;
+				if (len == 0)
+					return;
+				p += integer_size;
+			}
+		}
+		chunk = la->la_next;
+	}
+}
+
+/*
  * Lookup a value in a fatzap directory. Assumes that the zap scratch
  * buffer contains the directory header.
  */
 static int
-fzap_lookup(const spa_t *spa, const dnode_phys_t *dnode, const char *name, uint64_t *value)
+fzap_lookup(const spa_t *spa, const dnode_phys_t *dnode, const char *name,
+    uint64_t integer_size, uint64_t num_integers, void *value)
 {
 	int bsize = dnode->dn_datablkszsec << SPA_MINBLOCKSHIFT;
 	zap_phys_t zh = *(zap_phys_t *) zap_scratch;
@@ -1435,9 +1503,10 @@ fzap_lookup(const spa_t *spa, const dnode_phys_t *dnod
 		zc = &ZAP_LEAF_CHUNK(&zl, zc->l_entry.le_next);
 	}
 	if (fzap_name_equal(&zl, zc, name)) {
-		if (zc->l_entry.le_value_intlen * zc->l_entry.le_value_numints > 8)
+		if (zc->l_entry.le_value_intlen * zc->l_entry.le_value_numints >
+		    integer_size * num_integers)
 			return (E2BIG);
-		*value = fzap_leaf_value(&zl, zc);
+		fzap_leaf_array(&zl, zc, integer_size, num_integers, value);
 		return (0);
 	}
 
@@ -1448,7 +1517,8 @@ fzap_lookup(const spa_t *spa, const dnode_phys_t *dnod
  * Lookup a name in a zap object and return its value as a uint64_t.
  */
 static int
-zap_lookup(const spa_t *spa, const dnode_phys_t *dnode, const char *name, uint64_t *value)
+zap_lookup(const spa_t *spa, const dnode_phys_t *dnode, const char *name,
+    uint64_t integer_size, uint64_t num_integers, void *value)
 {
 	int rc;
 	uint64_t zap_type;
@@ -1461,8 +1531,10 @@ zap_lookup(const spa_t *spa, const dnode_phys_t *dnode
 	zap_type = *(uint64_t *) zap_scratch;
 	if (zap_type == ZBT_MICRO)
 		return mzap_lookup(dnode, name, value);
-	else if (zap_type == ZBT_HEADER)
-		return fzap_lookup(spa, dnode, name, value);
+	else if (zap_type == ZBT_HEADER) {
+		return fzap_lookup(spa, dnode, name, integer_size,
+		    num_integers, value);
+	}
 	printf("ZFS: invalid zap_type=%d\n", (int)zap_type);
 	return (EIO);
 }
@@ -1801,7 +1873,8 @@ zfs_lookup_dataset(const spa_t *spa, const char *name,
 
 	if (objset_get_dnode(spa, &spa->spa_mos, DMU_POOL_DIRECTORY_OBJECT, &dir))
 		return (EIO);
-	if (zap_lookup(spa, &dir, DMU_POOL_ROOT_DATASET, &dir_obj))
+	if (zap_lookup(spa, &dir, DMU_POOL_ROOT_DATASET, sizeof (dir_obj),
+	    1, &dir_obj))
 		return (EIO);
 
 	p = name;
@@ -1831,7 +1904,8 @@ zfs_lookup_dataset(const spa_t *spa, const char *name,
 			return (EIO);
 
 		/* Actual loop condition #2. */
-		if (zap_lookup(spa, &child_dir_zap, element, &dir_obj) != 0)
+		if (zap_lookup(spa, &child_dir_zap, element, sizeof (dir_obj),
+		    1, &dir_obj) != 0)
 			return (ENOENT);
 	}
 
@@ -1961,9 +2035,9 @@ zfs_get_root(const spa_t *spa, uint64_t *objid)
 	/*
 	 * Lookup the pool_props and see if we can find a bootfs.
 	 */
-	if (zap_lookup(spa, &dir, DMU_POOL_PROPS, &props) == 0
+	if (zap_lookup(spa, &dir, DMU_POOL_PROPS, sizeof (props), 1, &props) == 0
 	     && objset_get_dnode(spa, &spa->spa_mos, props, &propdir) == 0
-	     && zap_lookup(spa, &propdir, "bootfs", &bootfs) == 0
+	     && zap_lookup(spa, &propdir, "bootfs", sizeof (bootfs), 1, &bootfs) == 0
 	     && bootfs != 0)
 	{
 		*objid = bootfs;
@@ -1972,7 +2046,7 @@ zfs_get_root(const spa_t *spa, uint64_t *objid)
 	/*
 	 * Lookup the root dataset directory
 	 */
-	if (zap_lookup(spa, &dir, DMU_POOL_ROOT_DATASET, &root)
+	if (zap_lookup(spa, &dir, DMU_POOL_ROOT_DATASET, sizeof (root), 1, &root)
 	    || objset_get_dnode(spa, &spa->spa_mos, root, &dir)) {
 		printf("ZFS: can't find root dsl_dir\n");
 		return (EIO);
@@ -2046,7 +2120,8 @@ check_mos_features(const spa_t *spa)
 	if ((rc = objset_get_dnode(spa, &spa->spa_mos, DMU_OT_OBJECT_DIRECTORY,
 	    &dir)) != 0)
 		return (rc);
-	if ((rc = zap_lookup(spa, &dir, DMU_POOL_FEATURES_FOR_READ, &objnum)) != 0) {
+	if ((rc = zap_lookup(spa, &dir, DMU_POOL_FEATURES_FOR_READ,
+	    sizeof (objnum), 1, &objnum)) != 0) {
 		/*
 		 * It is older pool without features. As we have already
 		 * tested the label, just return without raising the error.
@@ -2076,6 +2151,7 @@ check_mos_features(const spa_t *spa)
 static int
 zfs_spa_init(spa_t *spa)
 {
+	dnode_phys_t dir;
 	int rc;
 
 	if (zio_read(spa, &spa->spa_uberblock.ub_rootbp, &spa->spa_mos)) {
@@ -2087,6 +2163,17 @@ zfs_spa_init(spa_t *spa)
 		return (EIO);
 	}
 
+	if (objset_get_dnode(spa, &spa->spa_mos, DMU_POOL_DIRECTORY_OBJECT,
+	    &dir)) {
+		printf("ZFS: failed to read pool %s directory object\n",
+		    spa->spa_name);
+		return (EIO);
+	}
+	/* this is allowed to fail, older pools do not have salt */
+	rc = zap_lookup(spa, &dir, DMU_POOL_CHECKSUM_SALT, 1,
+	    sizeof (spa->spa_cksum_salt.zcs_bytes),
+	    spa->spa_cksum_salt.zcs_bytes);
+
 	rc = check_mos_features(spa);
 	if (rc != 0) {
 		printf("ZFS: pool %s is not supported\n", spa->spa_name);
@@ -2239,7 +2326,7 @@ zfs_lookup(const struct zfsmount *mount, const char *u
 		return (rc);
 	}
 
-	rc = zap_lookup(spa, &dn, ZFS_ROOT_OBJ, &objnum);
+	rc = zap_lookup(spa, &dn, ZFS_ROOT_OBJ, sizeof (objnum), 1, &objnum);
 	if (rc) {
 		free(entry);
 		return (rc);
@@ -2299,7 +2386,7 @@ zfs_lookup(const struct zfsmount *mount, const char *u
 			goto done;
 		}
 
-		rc = zap_lookup(spa, &dn, element, &objnum);
+		rc = zap_lookup(spa, &dn, element, sizeof (objnum), 1, &objnum);
 		if (rc)
 			goto done;
 		objnum = ZFS_DIRENT_OBJ(objnum);

Modified: stable/11/sys/cddl/boot/zfs/fletcher.c
==============================================================================
--- stable/11/sys/cddl/boot/zfs/fletcher.c	Mon Feb  5 00:18:21 2018	(r328865)
+++ stable/11/sys/cddl/boot/zfs/fletcher.c	Mon Feb  5 04:00:59 2018	(r328866)
@@ -23,10 +23,9 @@
  * Use is subject to license terms.
  */
 
-/*#pragma ident	"%Z%%M%	%I%	%E% SMI"*/
-
 static void
-fletcher_2_native(const void *buf, uint64_t size, zio_cksum_t *zcp)
+fletcher_2_native(const void *buf, uint64_t size,
+    const void *ctx_template __unused, zio_cksum_t *zcp)
 {
 	const uint64_t *ip = buf;
 	const uint64_t *ipend = ip + (size / sizeof (uint64_t));
@@ -43,7 +42,8 @@ fletcher_2_native(const void *buf, uint64_t size, zio_
 }
 
 static void
-fletcher_2_byteswap(const void *buf, uint64_t size, zio_cksum_t *zcp)
+fletcher_2_byteswap(const void *buf, uint64_t size,
+    const void *ctx_template __unused, zio_cksum_t *zcp)
 {
 	const uint64_t *ip = buf;
 	const uint64_t *ipend = ip + (size / sizeof (uint64_t));
@@ -60,7 +60,8 @@ fletcher_2_byteswap(const void *buf, uint64_t size, zi
 }
 
 static void
-fletcher_4_native(const void *buf, uint64_t size, zio_cksum_t *zcp)
+fletcher_4_native(const void *buf, uint64_t size,
+    const void *ctx_template __unused, zio_cksum_t *zcp)
 {
 	const uint32_t *ip = buf;
 	const uint32_t *ipend = ip + (size / sizeof (uint32_t));
@@ -77,7 +78,8 @@ fletcher_4_native(const void *buf, uint64_t size, zio_
 }
 
 static void
-fletcher_4_byteswap(const void *buf, uint64_t size, zio_cksum_t *zcp)
+fletcher_4_byteswap(const void *buf, uint64_t size,
+    const void *ctx_template __unused, zio_cksum_t *zcp)
 {
 	const uint32_t *ip = buf;
 	const uint32_t *ipend = ip + (size / sizeof (uint32_t));

Modified: stable/11/sys/cddl/boot/zfs/sha256.c
==============================================================================
--- stable/11/sys/cddl/boot/zfs/sha256.c	Mon Feb  5 00:18:21 2018	(r328865)
+++ stable/11/sys/cddl/boot/zfs/sha256.c	Mon Feb  5 04:00:59 2018	(r328866)
@@ -23,19 +23,21 @@
  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
+/*
+ * Copyright 2013 Saso Kiselkov.  All rights reserved.
+ * Copyright 2015 Toomas Soome <tsoome at me.com>
+ */
 
-/*#pragma ident	"%Z%%M%	%I%	%E% SMI"*/
-
 /*
- * SHA-256 checksum, as specified in FIPS 180-2, available at:
+ * SHA-256 and SHA-512/256 hashes, as specified in FIPS 180-4, available at:
  * http://csrc.nist.gov/cryptval
  *
- * This is a very compact implementation of SHA-256.
+ * This is a very compact implementation of SHA-256 and SHA-512/256.
  * It is designed to be simple and portable, not to be fast.
  */
 
 /*
- * The literal definitions according to FIPS180-2 would be:
+ * The literal definitions according to FIPS180-4 would be:
  *
  * 	Ch(x, y, z)     (((x) & (y)) ^ ((~(x)) & (z)))
  * 	Maj(x, y, z)    (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
@@ -44,12 +46,21 @@
  */
 #define	Ch(x, y, z)	((z) ^ ((x) & ((y) ^ (z))))
 #define	Maj(x, y, z)	(((x) & (y)) ^ ((z) & ((x) ^ (y))))
-#define	Rot32(x, s)	(((x) >> s) | ((x) << (32 - s)))
-#define	SIGMA0(x)	(Rot32(x, 2) ^ Rot32(x, 13) ^ Rot32(x, 22))
-#define	SIGMA1(x)	(Rot32(x, 6) ^ Rot32(x, 11) ^ Rot32(x, 25))
-#define	sigma0(x)	(Rot32(x, 7) ^ Rot32(x, 18) ^ ((x) >> 3))
-#define	sigma1(x)	(Rot32(x, 17) ^ Rot32(x, 19) ^ ((x) >> 10))
+#define	ROTR(x, n)	(((x) >> (n)) | ((x) << ((sizeof (x) * NBBY)-(n))))
 
+/* SHA-224/256 operations */
+#define	BIGSIGMA0_256(x)	(ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
+#define	BIGSIGMA1_256(x)	(ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
+#define	SIGMA0_256(x)		(ROTR(x, 7) ^ ROTR(x, 18) ^ ((x) >> 3))
+#define	SIGMA1_256(x)		(ROTR(x, 17) ^ ROTR(x, 19) ^ ((x) >> 10))
+
+/* SHA-384/512 operations */
+#define	BIGSIGMA0_512(x)	(ROTR((x), 28) ^ ROTR((x), 34) ^ ROTR((x), 39))
+#define	BIGSIGMA1_512(x)	(ROTR((x), 14) ^ ROTR((x), 18) ^ ROTR((x), 41))
+#define	SIGMA0_512(x)		(ROTR((x), 1) ^ ROTR((x), 8) ^ ((x) >> 7))
+#define	SIGMA1_512(x)		(ROTR((x), 19) ^ ROTR((x), 61) ^ ((x) >> 6))
+
+/* SHA-256 round constants */
 static const uint32_t SHA256_K[64] = {
 	0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
 	0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
@@ -69,46 +80,134 @@ static const uint32_t SHA256_K[64] = {
 	0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
 };
 
+/* SHA-512 round constants */
+static const uint64_t SHA512_K[80] = {
+	0x428A2F98D728AE22ULL, 0x7137449123EF65CDULL,
+	0xB5C0FBCFEC4D3B2FULL, 0xE9B5DBA58189DBBCULL,
+	0x3956C25BF348B538ULL, 0x59F111F1B605D019ULL,
+	0x923F82A4AF194F9BULL, 0xAB1C5ED5DA6D8118ULL,
+	0xD807AA98A3030242ULL, 0x12835B0145706FBEULL,
+	0x243185BE4EE4B28CULL, 0x550C7DC3D5FFB4E2ULL,
+	0x72BE5D74F27B896FULL, 0x80DEB1FE3B1696B1ULL,
+	0x9BDC06A725C71235ULL, 0xC19BF174CF692694ULL,
+	0xE49B69C19EF14AD2ULL, 0xEFBE4786384F25E3ULL,
+	0x0FC19DC68B8CD5B5ULL, 0x240CA1CC77AC9C65ULL,
+	0x2DE92C6F592B0275ULL, 0x4A7484AA6EA6E483ULL,
+	0x5CB0A9DCBD41FBD4ULL, 0x76F988DA831153B5ULL,
+	0x983E5152EE66DFABULL, 0xA831C66D2DB43210ULL,
+	0xB00327C898FB213FULL, 0xBF597FC7BEEF0EE4ULL,
+	0xC6E00BF33DA88FC2ULL, 0xD5A79147930AA725ULL,
+	0x06CA6351E003826FULL, 0x142929670A0E6E70ULL,
+	0x27B70A8546D22FFCULL, 0x2E1B21385C26C926ULL,
+	0x4D2C6DFC5AC42AEDULL, 0x53380D139D95B3DFULL,
+	0x650A73548BAF63DEULL, 0x766A0ABB3C77B2A8ULL,
+	0x81C2C92E47EDAEE6ULL, 0x92722C851482353BULL,
+	0xA2BFE8A14CF10364ULL, 0xA81A664BBC423001ULL,
+	0xC24B8B70D0F89791ULL, 0xC76C51A30654BE30ULL,
+	0xD192E819D6EF5218ULL, 0xD69906245565A910ULL,
+	0xF40E35855771202AULL, 0x106AA07032BBD1B8ULL,
+	0x19A4C116B8D2D0C8ULL, 0x1E376C085141AB53ULL,
+	0x2748774CDF8EEB99ULL, 0x34B0BCB5E19B48A8ULL,
+	0x391C0CB3C5C95A63ULL, 0x4ED8AA4AE3418ACBULL,
+	0x5B9CCA4F7763E373ULL, 0x682E6FF3D6B2B8A3ULL,
+	0x748F82EE5DEFB2FCULL, 0x78A5636F43172F60ULL,
+	0x84C87814A1F0AB72ULL, 0x8CC702081A6439ECULL,
+	0x90BEFFFA23631E28ULL, 0xA4506CEBDE82BDE9ULL,
+	0xBEF9A3F7B2C67915ULL, 0xC67178F2E372532BULL,
+	0xCA273ECEEA26619CULL, 0xD186B8C721C0C207ULL,
+	0xEADA7DD6CDE0EB1EULL, 0xF57D4F7FEE6ED178ULL,
+	0x06F067AA72176FBAULL, 0x0A637DC5A2C898A6ULL,
+	0x113F9804BEF90DAEULL, 0x1B710B35131C471BULL,
+	0x28DB77F523047D84ULL, 0x32CAAB7B40C72493ULL,
+	0x3C9EBE0A15C9BEBCULL, 0x431D67C49C100D4CULL,
+	0x4CC5D4BECB3E42B6ULL, 0x597F299CFC657E2AULL,
+	0x5FCB6FAB3AD6FAECULL, 0x6C44198C4A475817ULL
+};
+
 static void
 SHA256Transform(uint32_t *H, const uint8_t *cp)
 {
 	uint32_t a, b, c, d, e, f, g, h, t, T1, T2, W[64];
 
-	for (t = 0; t < 16; t++, cp += 4)
+	/* copy chunk into the first 16 words of the message schedule */
+	for (t = 0; t < 16; t++, cp += sizeof (uint32_t))
 		W[t] = (cp[0] << 24) | (cp[1] << 16) | (cp[2] << 8) | cp[3];
 
+	/* extend the first 16 words into the remaining 48 words */
 	for (t = 16; t < 64; t++)
-		W[t] = sigma1(W[t - 2]) + W[t - 7] +
-		    sigma0(W[t - 15]) + W[t - 16];
+		W[t] = SIGMA1_256(W[t - 2]) + W[t - 7] +
+		    SIGMA0_256(W[t - 15]) + W[t - 16];
 
+	/* init working variables to the current hash value */
 	a = H[0]; b = H[1]; c = H[2]; d = H[3];
 	e = H[4]; f = H[5]; g = H[6]; h = H[7];
 
+	/* iterate the compression function for all rounds of the hash */
 	for (t = 0; t < 64; t++) {
-		T1 = h + SIGMA1(e) + Ch(e, f, g) + SHA256_K[t] + W[t];
-		T2 = SIGMA0(a) + Maj(a, b, c);
+		T1 = h + BIGSIGMA1_256(e) + Ch(e, f, g) + SHA256_K[t] + W[t];
+		T2 = BIGSIGMA0_256(a) + Maj(a, b, c);
 		h = g; g = f; f = e; e = d + T1;
 		d = c; c = b; b = a; a = T1 + T2;
 	}
 
+	/* add the compressed chunk to the current hash value */
 	H[0] += a; H[1] += b; H[2] += c; H[3] += d;
 	H[4] += e; H[5] += f; H[6] += g; H[7] += h;
 }
 
 static void
-zio_checksum_SHA256(const void *buf, uint64_t size, zio_cksum_t *zcp)
+SHA512Transform(uint64_t *H, const uint8_t *cp)
 {
-	uint32_t H[8] = { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
-	    0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 };
+	uint64_t a, b, c, d, e, f, g, h, t, T1, T2, W[80];
+
+	/* copy chunk into the first 16 words of the message schedule */
+	for (t = 0; t < 16; t++, cp += sizeof (uint64_t))
+		W[t] = ((uint64_t)cp[0] << 56) | ((uint64_t)cp[1] << 48) |
+		    ((uint64_t)cp[2] << 40) | ((uint64_t)cp[3] << 32) |
+		    ((uint64_t)cp[4] << 24) | ((uint64_t)cp[5] << 16) |
+		    ((uint64_t)cp[6] << 8) | (uint64_t)cp[7];
+
+	/* extend the first 16 words into the remaining 64 words */
+	for (t = 16; t < 80; t++)
+		W[t] = SIGMA1_512(W[t - 2]) + W[t - 7] +
+		    SIGMA0_512(W[t - 15]) + W[t - 16];
+
+	/* init working variables to the current hash value */
+	a = H[0]; b = H[1]; c = H[2]; d = H[3];
+	e = H[4]; f = H[5]; g = H[6]; h = H[7];
+
+	/* iterate the compression function for all rounds of the hash */
+	for (t = 0; t < 80; t++) {
+		T1 = h + BIGSIGMA1_512(e) + Ch(e, f, g) + SHA512_K[t] + W[t];
+		T2 = BIGSIGMA0_512(a) + Maj(a, b, c);
+		h = g; g = f; f = e; e = d + T1;
+		d = c; c = b; b = a; a = T1 + T2;
+	}
+
+	/* add the compressed chunk to the current hash value */
+	H[0] += a; H[1] += b; H[2] += c; H[3] += d;
+	H[4] += e; H[5] += f; H[6] += g; H[7] += h;
+}
+
+/*
+ * Implements the SHA-224 and SHA-256 hash algos - to select between them
+ * pass the appropriate initial values of 'H' and truncate the last 32 bits
+ * in case of SHA-224.
+ */
+static void
+SHA256(uint32_t *H, const void *buf, uint64_t size, zio_cksum_t *zcp)
+{
 	uint8_t pad[128];
-	int padsize = size & 63;
-	int i;
+	unsigned padsize = size & 63;
+	unsigned i, k;
 
+	/* process all blocks up to the last one */
 	for (i = 0; i < size - padsize; i += 64)
 		SHA256Transform(H, (uint8_t *)buf + i);
 
-	for (i = 0; i < padsize; i++)
-		pad[i] = ((uint8_t *)buf)[i];
+	/* process the last block and padding */
+	for (k = 0; k < padsize; k++)
+		pad[k] = ((uint8_t *)buf)[k+i];
 
 	for (pad[padsize++] = 0x80; (padsize & 63) != 56; padsize++)
 		pad[padsize] = 0;
@@ -124,4 +223,103 @@ zio_checksum_SHA256(const void *buf, uint64_t size, zi
 	    (uint64_t)H[2] << 32 | H[3],
 	    (uint64_t)H[4] << 32 | H[5],
 	    (uint64_t)H[6] << 32 | H[7]);
+}
+
+/*
+ * encode 64bit data in big-endian format.
+ */
+static void
+Encode64(uint8_t *output, uint64_t *input, size_t len)
+{
+	size_t i, j;
+	for (i = 0, j = 0; j < len; i++, j += 8) {
+		output[j]	= (input[i] >> 56) & 0xff;
+		output[j + 1]	= (input[i] >> 48) & 0xff;
+		output[j + 2]	= (input[i] >> 40) & 0xff;
+		output[j + 3]	= (input[i] >> 32) & 0xff;
+		output[j + 4]	= (input[i] >> 24) & 0xff;
+		output[j + 5]	= (input[i] >> 16) & 0xff;
+		output[j + 6]	= (input[i] >>  8) & 0xff;
+		output[j + 7]	= input[i] & 0xff;
+	}
+}
+
+/*
+ * Implements the SHA-384, SHA-512 and SHA-512/t hash algos - to select
+ * between them pass the appropriate initial values for 'H'. The output
+ * of this function is truncated to the first 256 bits that fit into 'zcp'.
+ */
+static void
+SHA512(uint64_t *H, const void *buf, uint64_t size, zio_cksum_t *zcp)
+{
+	uint64_t	c64[2];
+	uint8_t		pad[256];
+	unsigned	padsize = size & 127;
+	unsigned	i, k;
+
+	/* process all blocks up to the last one */
+	for (i = 0; i < size - padsize; i += 128)
+		SHA512Transform(H, (uint8_t *)buf + i);
+
+	/* process the last block and padding */
+	for (k = 0; k < padsize; k++)
+		pad[k] = ((uint8_t *)buf)[k+i];
+
+	if (padsize < 112) {
+		for (pad[padsize++] = 0x80; padsize < 112; padsize++)
+			pad[padsize] = 0;
+	} else {
+		for (pad[padsize++] = 0x80; padsize < 240; padsize++)
+			pad[padsize] = 0;
+	}
+
+	c64[0] = 0;
+	c64[1] = size << 3;
+	Encode64(pad+padsize, c64, sizeof (c64));
+	padsize += sizeof (c64);
+
+	for (i = 0; i < padsize; i += 128)
+		SHA512Transform(H, pad + i);
+
+	/* truncate the output to the first 256 bits which fit into 'zcp' */
+	Encode64((uint8_t *)zcp, H, sizeof (uint64_t) * 4);
+}
+
+static void
+zio_checksum_SHA256(const void *buf, uint64_t size,
+    const void *ctx_template __unused, zio_cksum_t *zcp)
+{
+	/* SHA-256 as per FIPS 180-4. */
+	uint32_t	H[] = {
+		0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
+		0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
+	};
+	SHA256(H, buf, size, zcp);
+}
+
+static void
+zio_checksum_SHA512_native(const void *buf, uint64_t size,
+    const void *ctx_template __unused, zio_cksum_t *zcp)
+{
+	/* SHA-512/256 as per FIPS 180-4. */
+	uint64_t	H[] = {
+		0x22312194FC2BF72CULL, 0x9F555FA3C84C64C2ULL,
+		0x2393B86B6F53B151ULL, 0x963877195940EABDULL,
+		0x96283EE2A88EFFE3ULL, 0xBE5E1E2553863992ULL,
+		0x2B0199FC2C85B8AAULL, 0x0EB72DDC81C52CA2ULL
+	};
+	SHA512(H, buf, size, zcp);
+}
+
+static void
+zio_checksum_SHA512_byteswap(const void *buf, uint64_t size,
+    const void *ctx_template, zio_cksum_t *zcp)
+{
+	zio_cksum_t	tmp;
+
+	zio_checksum_SHA512_native(buf, size, ctx_template, &tmp);
+	zcp->zc_word[0] = BSWAP_64(tmp.zc_word[0]);
+	zcp->zc_word[1] = BSWAP_64(tmp.zc_word[1]);
+	zcp->zc_word[2] = BSWAP_64(tmp.zc_word[2]);
+	zcp->zc_word[3] = BSWAP_64(tmp.zc_word[3]);
 }

Copied: stable/11/sys/cddl/boot/zfs/skein_zfs.c (from r304321, head/sys/cddl/boot/zfs/skein_zfs.c)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/11/sys/cddl/boot/zfs/skein_zfs.c	Mon Feb  5 04:00:59 2018	(r328866, copy of r304321, head/sys/cddl/boot/zfs/skein_zfs.c)
@@ -0,0 +1,92 @@
+/*
+ * CDDL HEADER START

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-all mailing list