Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F131803262
D7418.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
46 KB
Referenced Files
None
Subscribers
None
D7418.diff
View Options
Index: head/sys/boot/efi/boot1/Makefile
===================================================================
--- head/sys/boot/efi/boot1/Makefile
+++ head/sys/boot/efi/boot1/Makefile
@@ -19,12 +19,16 @@
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
+CWARNFLAGS.skein.c += -Wno-missing-variable-declarations
.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
+.PATH: ${.CURDIR}/../../../crypto/skein
.endif
CFLAGS+= -I.
@@ -40,6 +44,7 @@
.if ${MK_ZFS} != "no"
CFLAGS+= -I${.CURDIR}/../../zfs/
CFLAGS+= -I${.CURDIR}/../../../cddl/boot/zfs/
+CFLAGS+= -I${.CURDIR}/../../../crypto/skein
CFLAGS+= -DEFI_ZFS_BOOT
.endif
Index: head/sys/boot/efi/loader/Makefile
===================================================================
--- head/sys/boot/efi/loader/Makefile
+++ head/sys/boot/efi/loader/Makefile
@@ -24,6 +24,8 @@
.if ${MK_ZFS} != "no"
SRCS+= zfs.c
.PATH: ${.CURDIR}/../../zfs
+SRCS+= skein.c skein_block.c
+.PATH: ${.CURDIR}/../../../crypto/skein
# Disable warnings that are currently incompatible with the zfs boot code
CWARNFLAGS.zfs.c+= -Wno-sign-compare
@@ -53,6 +55,7 @@
.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
Index: head/sys/boot/i386/boot2/Makefile
===================================================================
--- head/sys/boot/i386/boot2/Makefile
+++ head/sys/boot/i386/boot2/Makefile
@@ -33,7 +33,7 @@
-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
Index: head/sys/boot/i386/gptboot/Makefile
===================================================================
--- head/sys/boot/i386/gptboot/Makefile
+++ head/sys/boot/i386/gptboot/Makefile
@@ -32,10 +32,10 @@
-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
Index: head/sys/boot/i386/gptboot/gptldr.S
===================================================================
--- head/sys/boot/i386/gptboot/gptldr.S
+++ head/sys/boot/i386/gptboot/gptldr.S
@@ -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
Index: head/sys/boot/i386/gptzfsboot/Makefile
===================================================================
--- head/sys/boot/i386/gptzfsboot/Makefile
+++ head/sys/boot/i386/gptzfsboot/Makefile
@@ -2,7 +2,7 @@
.PATH: ${.CURDIR}/../boot2 ${.CURDIR}/../gptboot \
${.CURDIR}/../zfsboot ${.CURDIR}/../common \
- ${.CURDIR}/../../common
+ ${.CURDIR}/../../common ${.CURDIR}/../../../crypto/skein
FILES= gptzfsboot
MAN= gptzfsboot.8
@@ -27,13 +27,14 @@
-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-tentative-definition-incomplete-type -Wno-pointer-sign
.if !defined(LOADER_NO_GELI_SUPPORT)
CFLAGS+= -DLOADER_GELI_SUPPORT
@@ -67,12 +68,13 @@
${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
Index: head/sys/boot/i386/zfsboot/Makefile
===================================================================
--- head/sys/boot/i386/zfsboot/Makefile
+++ head/sys/boot/i386/zfsboot/Makefile
@@ -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,9 +26,10 @@
-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
@@ -55,12 +57,13 @@
${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 zfsboot.ld`; x=$$((${BOOT2SIZE}-$$5)); \
@@ -77,7 +80,7 @@
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
Index: head/sys/boot/i386/zfsboot/zfsboot.c
===================================================================
--- head/sys/boot/i386/zfsboot/zfsboot.c
+++ head/sys/boot/i386/zfsboot/zfsboot.c
@@ -105,7 +105,7 @@
/*
* 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;
Index: head/sys/boot/i386/zfsboot/zfsldr.S
===================================================================
--- head/sys/boot/i386/zfsboot/zfsldr.S
+++ head/sys/boot/i386/zfsboot/zfsldr.S
@@ -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 @@
/*
* 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 @@
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.
Index: head/sys/boot/userboot/ficl/Makefile
===================================================================
--- head/sys/boot/userboot/ficl/Makefile
+++ head/sys/boot/userboot/ficl/Makefile
@@ -10,6 +10,9 @@
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
Index: head/sys/boot/userboot/userboot/Makefile
===================================================================
--- head/sys/boot/userboot/userboot/Makefile
+++ head/sys/boot/userboot/userboot/Makefile
@@ -35,6 +35,8 @@
CFLAGS+= -I${.CURDIR}/../../../../lib/libstand
CFLAGS+= -ffreestanding -I.
+CWARNFLAGS.main.c += -Wno-implicit-function-declaration
+
LDFLAGS+= -nostdlib -Wl,-Bsymbolic
NEWVERSWHAT= "User boot" ${MACHINE_CPUARCH}
Index: head/sys/boot/userboot/zfs/Makefile
===================================================================
--- head/sys/boot/userboot/zfs/Makefile
+++ head/sys/boot/userboot/zfs/Makefile
@@ -2,15 +2,16 @@
S= ${.CURDIR}/../../zfs
-.PATH: ${S}
+.PATH: ${S} ${.CURDIR}/../../../crypto/skein
LIB= zfsboot
INTERNALLIB=
-SRCS+= zfs.c
+SRCS+= zfs.c skein.c skein_block.c
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
Index: head/sys/boot/zfs/Makefile
===================================================================
--- head/sys/boot/zfs/Makefile
+++ head/sys/boot/zfs/Makefile
@@ -5,10 +5,14 @@
SRCS+= zfs.c
+SRCS+= skein.c skein_block.c
+.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
Index: head/sys/boot/zfs/zfsimpl.c
===================================================================
--- head/sys/boot/zfs/zfsimpl.c
+++ head/sys/boot/zfs/zfsimpl.c
@@ -58,6 +58,8 @@
"com.delphix:extensible_dataset",
"com.delphix:embedded_data",
"org.open-zfs:large_blocks",
+ "org.illumos:sha512",
+ "org.illumos:skein",
NULL
};
@@ -78,6 +80,9 @@
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)
@@ -420,7 +425,7 @@
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);
@@ -1074,6 +1079,7 @@
}
zfs_free(upbuf, VDEV_UBERBLOCK_SIZE(vdev));
+ vdev->spa = spa;
if (spap)
*spap = spa;
return (0);
@@ -1122,7 +1128,7 @@
pbuf += BP_GET_PSIZE(gbp);
}
- if (zio_checksum_verify(bp, buf))
+ if (zio_checksum_verify(spa, bp, buf))
return (EIO);
return (0);
}
@@ -1224,7 +1230,8 @@
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);
}
@@ -1364,12 +1371,73 @@
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;
@@ -1436,9 +1504,10 @@
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);
}
@@ -1449,7 +1518,8 @@
* 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;
@@ -1462,8 +1532,10 @@
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);
}
@@ -1802,7 +1874,8 @@
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;
@@ -1832,7 +1905,8 @@
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);
}
@@ -1962,9 +2036,9 @@
/*
* 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;
@@ -1973,7 +2047,7 @@
/*
* 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);
@@ -2047,7 +2121,8 @@
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)
return (rc);
if ((rc = objset_get_dnode(spa, &spa->spa_mos, objnum, &dir)) != 0)
@@ -2072,6 +2147,7 @@
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)) {
@@ -2083,6 +2159,17 @@
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);
@@ -2173,7 +2260,7 @@
if (rc)
return (rc);
- rc = zap_lookup(spa, &dn, ZFS_ROOT_OBJ, &rootnum);
+ rc = zap_lookup(spa, &dn, ZFS_ROOT_OBJ, sizeof (rootnum), 1, &rootnum);
if (rc)
return (rc);
@@ -2205,7 +2292,7 @@
return (ENOTDIR);
parentnum = objnum;
- rc = zap_lookup(spa, &dn, element, &objnum);
+ rc = zap_lookup(spa, &dn, element, sizeof (objnum), 1, &objnum);
if (rc)
return (rc);
objnum = ZFS_DIRENT_OBJ(objnum);
Index: head/sys/cddl/boot/zfs/fletcher.c
===================================================================
--- head/sys/cddl/boot/zfs/fletcher.c
+++ head/sys/cddl/boot/zfs/fletcher.c
@@ -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 @@
}
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 @@
}
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 @@
}
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));
Index: head/sys/cddl/boot/zfs/sha256.c
===================================================================
--- head/sys/cddl/boot/zfs/sha256.c
+++ head/sys/cddl/boot/zfs/sha256.c
@@ -23,19 +23,21 @@
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-
-/*#pragma ident "%Z%%M% %I% %E% SMI"*/
+/*
+ * Copyright 2013 Saso Kiselkov. All rights reserved.
+ * Copyright 2015 Toomas Soome <tsoome@me.com>
+ */
/*
- * 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 @@
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)
+{
+ 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)
{
- uint32_t H[8] = { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
- 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 };
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;
@@ -125,3 +224,102 @@
(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]);
+}
Index: head/sys/cddl/boot/zfs/skein_zfs.c
===================================================================
--- head/sys/cddl/boot/zfs/skein_zfs.c
+++ head/sys/cddl/boot/zfs/skein_zfs.c
@@ -0,0 +1,92 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://opensource.org/licenses/CDDL-1.0.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ * $FreeBSD$
+ */
+/*
+ * Copyright 2013 Saso Kiselkov. All rights reserved.
+ */
+#include <skein.h>
+
+/*
+ * Computes a native 256-bit skein MAC checksum. Please note that this
+ * function requires the presence of a ctx_template that should be allocated
+ * using zio_checksum_skein_tmpl_init.
+ */
+/*ARGSUSED*/
+static void
+zio_checksum_skein_native(const void *buf, uint64_t size,
+ const void *ctx_template, zio_cksum_t *zcp)
+{
+ Skein_512_Ctxt_t ctx;
+
+ ASSERT(ctx_template != NULL);
+ bcopy(ctx_template, &ctx, sizeof (ctx));
+ (void) Skein_512_Update(&ctx, buf, size);
+ (void) Skein_512_Final(&ctx, (uint8_t *)zcp);
+ bzero(&ctx, sizeof (ctx));
+}
+
+/*
+ * Byteswapped version of zio_checksum_skein_native. This just invokes
+ * the native checksum function and byteswaps the resulting checksum (since
+ * skein is internally endian-insensitive).
+ */
+static void
+zio_checksum_skein_byteswap(const void *buf, uint64_t size,
+ const void *ctx_template, zio_cksum_t *zcp)
+{
+ zio_cksum_t tmp;
+
+ zio_checksum_skein_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]);
+}
+
+/*
+ * Allocates a skein MAC template suitable for using in skein MAC checksum
+ * computations and returns a pointer to it.
+ */
+static void *
+zio_checksum_skein_tmpl_init(const zio_cksum_salt_t *salt)
+{
+ Skein_512_Ctxt_t *ctx;
+
+ ctx = malloc(sizeof (*ctx));
+ bzero(ctx, sizeof (*ctx));
+ (void) Skein_512_InitExt(ctx, sizeof (zio_cksum_t) * 8, 0,
+ salt->zcs_bytes, sizeof (salt->zcs_bytes));
+ return (ctx);
+}
+
+/*
+ * Frees a skein context template previously allocated using
+ * zio_checksum_skein_tmpl_init.
+ */
+static void
+zio_checksum_skein_tmpl_free(void *ctx_template)
+{
+ Skein_512_Ctxt_t *ctx = ctx_template;
+
+ bzero(ctx, sizeof (*ctx));
+ free(ctx);
+}
Index: head/sys/cddl/boot/zfs/zfsimpl.h
===================================================================
--- head/sys/cddl/boot/zfs/zfsimpl.h
+++ head/sys/cddl/boot/zfs/zfsimpl.h
@@ -114,13 +114,11 @@
#define BSWAP_32(x) ((BSWAP_16(x) << 16) | BSWAP_16((x) >> 16))
#define BSWAP_64(x) ((BSWAP_32(x) << 32) | BSWAP_32((x) >> 32))
-/*
- * Note: the boot loader can't actually read blocks larger than 128KB,
- * due to lack of memory. Therefore its SPA_MAXBLOCKSIZE is still 128KB.
- */
#define SPA_MINBLOCKSHIFT 9
-#define SPA_MAXBLOCKSHIFT 17
+#define SPA_OLDMAXBLOCKSHIFT 17
+#define SPA_MAXBLOCKSHIFT 24
#define SPA_MINBLOCKSIZE (1ULL << SPA_MINBLOCKSHIFT)
+#define SPA_OLDMAXBLOCKSIZE (1ULL << SPA_OLDMAXBLOCKSHIFT)
#define SPA_MAXBLOCKSIZE (1ULL << SPA_MAXBLOCKSHIFT)
/*
@@ -150,6 +148,14 @@
} zio_cksum_t;
/*
+ * Some checksums/hashes need a 256-bit initialization salt. This salt is kept
+ * secret and is suitable for use in MAC algorithms as the key.
+ */
+typedef struct zio_cksum_salt {
+ uint8_t zcs_bytes[32];
+} zio_cksum_salt_t;
+
+/*
* Each block is described by its DVAs, time of birth, checksum, etc.
* The word-by-word, bit-by-bit layout of the blkptr is as follows:
*
@@ -528,6 +534,10 @@
ZIO_CHECKSUM_FLETCHER_4,
ZIO_CHECKSUM_SHA256,
ZIO_CHECKSUM_ZILOG2,
+ ZIO_CHECKSUM_NOPARITY,
+ ZIO_CHECKSUM_SHA512,
+ ZIO_CHECKSUM_SKEIN,
+ ZIO_CHECKSUM_EDONR,
ZIO_CHECKSUM_FUNCTIONS
};
@@ -1157,6 +1167,7 @@
#define DMU_POOL_DEFLATE "deflate"
#define DMU_POOL_HISTORY "history"
#define DMU_POOL_PROPS "pool_props"
+#define DMU_POOL_CHECKSUM_SALT "org.illumos:checksum_salt"
#define ZAP_MAGIC 0x2F52AB2ABULL
@@ -1462,6 +1473,7 @@
* In-core vdev representation.
*/
struct vdev;
+struct spa;
typedef int vdev_phys_read_t(struct vdev *vdev, void *priv,
off_t offset, void *buf, size_t bytes);
typedef int vdev_read_t(struct vdev *vdev, const blkptr_t *bp,
@@ -1484,6 +1496,7 @@
vdev_phys_read_t *v_phys_read; /* read from raw leaf vdev */
vdev_read_t *v_read; /* read from vdev */
void *v_read_priv; /* private data for read function */
+ struct spa *spa; /* link to spa */
} vdev_t;
/*
@@ -1499,6 +1512,8 @@
struct uberblock spa_uberblock; /* best uberblock so far */
vdev_list_t spa_vdevs; /* list of all toplevel vdevs */
objset_phys_t spa_mos; /* MOS for this pool */
+ zio_cksum_salt_t spa_cksum_salt; /* secret salt for cksum */
+ void *spa_cksum_tmpls[ZIO_CHECKSUM_FUNCTIONS];
int spa_inited; /* initialized */
} spa_t;
Index: head/sys/cddl/boot/zfs/zfssubr.c
===================================================================
--- head/sys/cddl/boot/zfs/zfssubr.c
+++ head/sys/cddl/boot/zfs/zfssubr.c
@@ -63,7 +63,8 @@
}
static void
-zio_checksum_off(const void *buf, uint64_t size, zio_cksum_t *zcp)
+zio_checksum_off(const void *buf, uint64_t size,
+ const void *ctx_template, zio_cksum_t *zcp)
{
ZIO_SET_CHECKSUM(zcp, 0, 0, 0, 0);
}
@@ -71,38 +72,75 @@
/*
* Signature for checksum functions.
*/
-typedef void zio_checksum_t(const void *data, uint64_t size, zio_cksum_t *zcp);
+typedef void zio_checksum_t(const void *data, uint64_t size,
+ const void *ctx_template, zio_cksum_t *zcp);
+typedef void *zio_checksum_tmpl_init_t(const zio_cksum_salt_t *salt);
+typedef void zio_checksum_tmpl_free_t(void *ctx_template);
+
+typedef enum zio_checksum_flags {
+ /* Strong enough for metadata? */
+ ZCHECKSUM_FLAG_METADATA = (1 << 1),
+ /* ZIO embedded checksum */
+ ZCHECKSUM_FLAG_EMBEDDED = (1 << 2),
+ /* Strong enough for dedup (without verification)? */
+ ZCHECKSUM_FLAG_DEDUP = (1 << 3),
+ /* Uses salt value */
+ ZCHECKSUM_FLAG_SALTED = (1 << 4),
+ /* Strong enough for nopwrite? */
+ ZCHECKSUM_FLAG_NOPWRITE = (1 << 5)
+} zio_checksum_flags_t;
/*
* Information about each checksum function.
*/
typedef struct zio_checksum_info {
- zio_checksum_t *ci_func[2]; /* checksum function for each byteorder */
- int ci_correctable; /* number of correctable bits */
- int ci_eck; /* uses zio embedded checksum? */
- int ci_dedup; /* strong enough for dedup? */
- const char *ci_name; /* descriptive name */
+ /* checksum function for each byteorder */
+ zio_checksum_t *ci_func[2];
+ zio_checksum_tmpl_init_t *ci_tmpl_init;
+ zio_checksum_tmpl_free_t *ci_tmpl_free;
+ zio_checksum_flags_t ci_flags;
+ const char *ci_name; /* descriptive name */
} zio_checksum_info_t;
#include "blkptr.c"
#include "fletcher.c"
#include "sha256.c"
+#include "skein_zfs.c"
static zio_checksum_info_t zio_checksum_table[ZIO_CHECKSUM_FUNCTIONS] = {
- {{NULL, NULL}, 0, 0, 0, "inherit"},
- {{NULL, NULL}, 0, 0, 0, "on"},
- {{zio_checksum_off, zio_checksum_off}, 0, 0, 0, "off"},
- {{zio_checksum_SHA256, zio_checksum_SHA256}, 1, 1, 0, "label"},
- {{zio_checksum_SHA256, zio_checksum_SHA256}, 1, 1, 0, "gang_header"},
- {{fletcher_2_native, fletcher_2_byteswap}, 0, 1, 0, "zilog"},
- {{fletcher_2_native, fletcher_2_byteswap}, 0, 0, 0, "fletcher2"},
- {{fletcher_4_native, fletcher_4_byteswap}, 1, 0, 0, "fletcher4"},
- {{zio_checksum_SHA256, zio_checksum_SHA256}, 1, 0, 1, "SHA256"},
- {{fletcher_4_native, fletcher_4_byteswap}, 0, 1, 0, "zillog2"},
+ {{NULL, NULL}, NULL, NULL, 0, "inherit"},
+ {{NULL, NULL}, NULL, NULL, 0, "on"},
+ {{zio_checksum_off, zio_checksum_off}, NULL, NULL, 0, "off"},
+ {{zio_checksum_SHA256, zio_checksum_SHA256}, NULL, NULL,
+ ZCHECKSUM_FLAG_METADATA | ZCHECKSUM_FLAG_EMBEDDED, "label"},
+ {{zio_checksum_SHA256, zio_checksum_SHA256}, NULL, NULL,
+ ZCHECKSUM_FLAG_METADATA | ZCHECKSUM_FLAG_EMBEDDED, "gang_header"},
+ {{fletcher_2_native, fletcher_2_byteswap}, NULL, NULL,
+ ZCHECKSUM_FLAG_EMBEDDED, "zilog"},
+ {{fletcher_2_native, fletcher_2_byteswap}, NULL, NULL,
+ 0, "fletcher2"},
+ {{fletcher_4_native, fletcher_4_byteswap}, NULL, NULL,
+ ZCHECKSUM_FLAG_METADATA, "fletcher4"},
+ {{zio_checksum_SHA256, zio_checksum_SHA256}, NULL, NULL,
+ ZCHECKSUM_FLAG_METADATA | ZCHECKSUM_FLAG_DEDUP |
+ ZCHECKSUM_FLAG_NOPWRITE, "SHA256"},
+ {{fletcher_4_native, fletcher_4_byteswap}, NULL, NULL,
+ ZCHECKSUM_FLAG_EMBEDDED, "zillog2"},
+ {{zio_checksum_off, zio_checksum_off}, NULL, NULL,
+ 0, "noparity"},
+ {{zio_checksum_SHA512_native, zio_checksum_SHA512_byteswap},
+ NULL, NULL, ZCHECKSUM_FLAG_METADATA | ZCHECKSUM_FLAG_DEDUP |
+ ZCHECKSUM_FLAG_NOPWRITE, "SHA512"},
+ {{zio_checksum_skein_native, zio_checksum_skein_byteswap},
+ zio_checksum_skein_tmpl_init, zio_checksum_skein_tmpl_free,
+ ZCHECKSUM_FLAG_METADATA | ZCHECKSUM_FLAG_DEDUP |
+ ZCHECKSUM_FLAG_SALTED | ZCHECKSUM_FLAG_NOPWRITE, "skein"},
+ /* no edonr for now */
+ {{NULL, NULL}, NULL, NULL, ZCHECKSUM_FLAG_METADATA |
+ ZCHECKSUM_FLAG_SALTED | ZCHECKSUM_FLAG_NOPWRITE, "edonr"}
};
-
/*
* Common signature for all zio compress/decompress functions.
*/
@@ -186,8 +224,48 @@
ZIO_SET_CHECKSUM(zcp, offset, 0, 0, 0);
}
+/*
+ * Calls the template init function of a checksum which supports context
+ * templates and installs the template into the spa_t.
+ */
+static void
+zio_checksum_template_init(enum zio_checksum checksum, spa_t *spa)
+{
+ zio_checksum_info_t *ci = &zio_checksum_table[checksum];
+
+ if (ci->ci_tmpl_init == NULL)
+ return;
+
+ if (spa->spa_cksum_tmpls[checksum] != NULL)
+ return;
+
+ if (spa->spa_cksum_tmpls[checksum] == NULL) {
+ spa->spa_cksum_tmpls[checksum] =
+ ci->ci_tmpl_init(&spa->spa_cksum_salt);
+ }
+}
+
+/*
+ * Called by a spa_t that's about to be deallocated. This steps through
+ * all of the checksum context templates and deallocates any that were
+ * initialized using the algorithm-specific template init function.
+ */
+void
+zio_checksum_templates_free(spa_t *spa)
+{
+ for (enum zio_checksum checksum = 0;
+ checksum < ZIO_CHECKSUM_FUNCTIONS; checksum++) {
+ if (spa->spa_cksum_tmpls[checksum] != NULL) {
+ zio_checksum_info_t *ci = &zio_checksum_table[checksum];
+
+ ci->ci_tmpl_free(spa->spa_cksum_tmpls[checksum]);
+ spa->spa_cksum_tmpls[checksum] = NULL;
+ }
+ }
+}
+
static int
-zio_checksum_verify(const blkptr_t *bp, void *data)
+zio_checksum_verify(const spa_t *spa, const blkptr_t *bp, void *data)
{
uint64_t size;
unsigned int checksum;
@@ -204,7 +282,8 @@
if (ci->ci_func[0] == NULL || ci->ci_func[1] == NULL)
return (EINVAL);
- if (ci->ci_eck) {
+ zio_checksum_template_init(checksum, (spa_t *) spa);
+ if (ci->ci_flags & ZCHECKSUM_FLAG_EMBEDDED) {
zio_eck_t *eck;
ASSERT(checksum == ZIO_CHECKSUM_GANG_HEADER ||
@@ -227,7 +306,8 @@
expected_cksum = eck->zec_cksum;
eck->zec_cksum = verifier;
- ci->ci_func[byteswap](data, size, &actual_cksum);
+ ci->ci_func[byteswap](data, size,
+ spa->spa_cksum_tmpls[checksum], &actual_cksum);
eck->zec_cksum = expected_cksum;
if (byteswap)
@@ -235,11 +315,12 @@
sizeof (zio_cksum_t));
} else {
expected_cksum = bp->blk_cksum;
- ci->ci_func[0](data, size, &actual_cksum);
+ ci->ci_func[0](data, size, spa->spa_cksum_tmpls[checksum],
+ &actual_cksum);
}
if (!ZIO_CHECKSUM_EQUAL(actual_cksum, expected_cksum)) {
- /*printf("ZFS: read checksum failed\n");*/
+ /*printf("ZFS: read checksum %s failed\n", ci->ci_name);*/
return (EIO);
}
@@ -1249,10 +1330,10 @@
* any ereports we generate can note it.
*/
static int
-raidz_checksum_verify(const blkptr_t *bp, void *data, uint64_t size)
+raidz_checksum_verify(const spa_t *spa, const blkptr_t *bp, void *data,
+ uint64_t size)
{
-
- return (zio_checksum_verify(bp, data));
+ return (zio_checksum_verify(spa, bp, data));
}
/*
@@ -1301,8 +1382,8 @@
* cases we'd only use parity information in column 0.
*/
static int
-vdev_raidz_combrec(raidz_map_t *rm, const blkptr_t *bp, void *data,
- off_t offset, uint64_t bytes, int total_errors, int data_errors)
+vdev_raidz_combrec(const spa_t *spa, raidz_map_t *rm, const blkptr_t *bp,
+ void *data, off_t offset, uint64_t bytes, int total_errors, int data_errors)
{
raidz_col_t *rc;
void *orig[VDEV_RAIDZ_MAXPARITY];
@@ -1381,7 +1462,7 @@
* success.
*/
code = vdev_raidz_reconstruct(rm, tgts, n);
- if (raidz_checksum_verify(bp, data, bytes) == 0) {
+ if (raidz_checksum_verify(spa, bp, data, bytes) == 0) {
for (i = 0; i < n; i++) {
c = tgts[i];
rc = &rm->rm_col[c];
@@ -1552,7 +1633,7 @@
*/
if (total_errors <= rm->rm_firstdatacol - parity_untried) {
if (data_errors == 0) {
- if (raidz_checksum_verify(bp, data, bytes) == 0) {
+ if (raidz_checksum_verify(vd->spa, bp, data, bytes) == 0) {
/*
* If we read parity information (unnecessarily
* as it happens since no reconstruction was
@@ -1597,7 +1678,7 @@
code = vdev_raidz_reconstruct(rm, tgts, n);
- if (raidz_checksum_verify(bp, data, bytes) == 0) {
+ if (raidz_checksum_verify(vd->spa, bp, data, bytes) == 0) {
/*
* If we read more parity disks than were used
* for reconstruction, confirm that the other
@@ -1671,7 +1752,7 @@
if (total_errors > rm->rm_firstdatacol) {
error = EIO;
} else if (total_errors < rm->rm_firstdatacol &&
- (code = vdev_raidz_combrec(rm, bp, data, offset, bytes,
+ (code = vdev_raidz_combrec(vd->spa, rm, bp, data, offset, bytes,
total_errors, data_errors)) != 0) {
/*
* If we didn't use all the available parity for the
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Oct 12, 7:16 AM (16 h, 31 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
23613953
Default Alt Text
D7418.diff (46 KB)
Attached To
Mode
D7418: Add SHA512, skein, large blocks support for loader zfs.
Attached
Detach File
Event Timeline
Log In to Comment