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 <tso...@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 ***
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to