mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-25 03:37:45 +03:00
OpenZFS 4185 - add new cryptographic checksums to ZFS: SHA-512, Skein, Edon-R
Reviewed by: George Wilson <george.wilson@delphix.com> Reviewed by: Prakash Surya <prakash.surya@delphix.com> Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com> Reviewed by: Richard Lowe <richlowe@richlowe.net> Approved by: Garrett D'Amore <garrett@damore.org> Ported by: Tony Hutter <hutter2@llnl.gov> OpenZFS-issue: https://www.illumos.org/issues/4185 OpenZFS-commit: https://github.com/openzfs/openzfs/commit/45818ee Porting Notes: This code is ported on top of the Illumos Crypto Framework code: https://github.com/zfsonlinux/zfs/pull/4329/commits/b5e030c8dbb9cd393d313571dee4756fbba8c22d The list of porting changes includes: - Copied module/icp/include/sha2/sha2.h directly from illumos - Removed from module/icp/algs/sha2/sha2.c: #pragma inline(SHA256Init, SHA384Init, SHA512Init) - Added 'ctx' to lib/libzfs/libzfs_sendrecv.c:zio_checksum_SHA256() since it now takes in an extra parameter. - Added CTASSERT() to assert.h from for module/zfs/edonr_zfs.c - Added skein & edonr to libicp/Makefile.am - Added sha512.S. It was generated from sha512-x86_64.pl in Illumos. - Updated ztest.c with new fletcher_4_*() args; used NULL for new CTX argument. - In icp/algs/edonr/edonr_byteorder.h, Removed the #if defined(__linux) section to not #include the non-existant endian.h. - In skein_test.c, renane NULL to 0 in "no test vector" array entries to get around a compiler warning. - Fixup test files: - Rename <sys/varargs.h> -> <varargs.h>, <strings.h> -> <string.h>, - Remove <note.h> and define NOTE() as NOP. - Define u_longlong_t - Rename "#!/usr/bin/ksh" -> "#!/bin/ksh -p" - Rename NULL to 0 in "no test vector" array entries to get around a compiler warning. - Remove "for isa in $($ISAINFO); do" stuff - Add/update Makefiles - Add some userspace headers like stdio.h/stdlib.h in places of sys/types.h. - EXPORT_SYMBOL *_Init/*_Update/*_Final... routines in ICP modules. - Update scripts/zfs2zol-patch.sed - include <sys/sha2.h> in sha2_impl.h - Add sha2.h to include/sys/Makefile.am - Add skein and edonr dirs to icp Makefile - Add new checksums to zpool_get.cfg - Move checksum switch block from zfs_secpolicy_setprop() to zfs_check_settable() - Fix -Wuninitialized error in edonr_byteorder.h on PPC - Fix stack frame size errors on ARM32 - Don't unroll loops in Skein on 32-bit to save stack space - Add memory barriers in sha2.c on 32-bit to save stack space - Add filetest_001_pos.ksh checksum sanity test - Add option to write psudorandom data in file_write utility
This commit is contained in:
+25
-12
@@ -979,7 +979,7 @@ zio_write_phys(zio_t *pio, vdev_t *vd, uint64_t offset, uint64_t size,
|
||||
|
||||
zio->io_prop.zp_checksum = checksum;
|
||||
|
||||
if (zio_checksum_table[checksum].ci_eck) {
|
||||
if (zio_checksum_table[checksum].ci_flags & ZCHECKSUM_FLAG_EMBEDDED) {
|
||||
/*
|
||||
* zec checksums are necessarily destructive -- they modify
|
||||
* the end of the write buffer to hold the verifier/checksum.
|
||||
@@ -1190,8 +1190,8 @@ zio_write_bp_init(zio_t *zio)
|
||||
if (BP_IS_HOLE(bp) || !zp->zp_dedup)
|
||||
return (ZIO_PIPELINE_CONTINUE);
|
||||
|
||||
ASSERT(zio_checksum_table[zp->zp_checksum].ci_dedup ||
|
||||
zp->zp_dedup_verify);
|
||||
ASSERT((zio_checksum_table[zp->zp_checksum].ci_flags &
|
||||
ZCHECKSUM_FLAG_DEDUP) || zp->zp_dedup_verify);
|
||||
|
||||
if (BP_GET_CHECKSUM(bp) == zp->zp_checksum) {
|
||||
BP_SET_DEDUP(bp, 1);
|
||||
@@ -2198,12 +2198,22 @@ zio_write_gang_block(zio_t *pio)
|
||||
}
|
||||
|
||||
/*
|
||||
* The zio_nop_write stage in the pipeline determines if allocating
|
||||
* a new bp is necessary. By leveraging a cryptographically secure checksum,
|
||||
* such as SHA256, we can compare the checksums of the new data and the old
|
||||
* to determine if allocating a new block is required. The nopwrite
|
||||
* feature can handle writes in either syncing or open context (i.e. zil
|
||||
* writes) and as a result is mutually exclusive with dedup.
|
||||
* The zio_nop_write stage in the pipeline determines if allocating a
|
||||
* new bp is necessary. The nopwrite feature can handle writes in
|
||||
* either syncing or open context (i.e. zil writes) and as a result is
|
||||
* mutually exclusive with dedup.
|
||||
*
|
||||
* By leveraging a cryptographically secure checksum, such as SHA256, we
|
||||
* can compare the checksums of the new data and the old to determine if
|
||||
* allocating a new block is required. Note that our requirements for
|
||||
* cryptographic strength are fairly weak: there can't be any accidental
|
||||
* hash collisions, but we don't need to be secure against intentional
|
||||
* (malicious) collisions. To trigger a nopwrite, you have to be able
|
||||
* to write the file to begin with, and triggering an incorrect (hash
|
||||
* collision) nopwrite is no worse than simply writing to the file.
|
||||
* That said, there are no known attacks against the checksum algorithms
|
||||
* used for nopwrite, assuming that the salt and the checksums
|
||||
* themselves remain secret.
|
||||
*/
|
||||
static int
|
||||
zio_nop_write(zio_t *zio)
|
||||
@@ -2226,7 +2236,8 @@ zio_nop_write(zio_t *zio)
|
||||
* allocate a new bp.
|
||||
*/
|
||||
if (BP_IS_HOLE(bp_orig) ||
|
||||
!zio_checksum_table[BP_GET_CHECKSUM(bp)].ci_dedup ||
|
||||
!(zio_checksum_table[BP_GET_CHECKSUM(bp)].ci_flags &
|
||||
ZCHECKSUM_FLAG_NOPWRITE) ||
|
||||
BP_GET_CHECKSUM(bp) != BP_GET_CHECKSUM(bp_orig) ||
|
||||
BP_GET_COMPRESS(bp) != BP_GET_COMPRESS(bp_orig) ||
|
||||
BP_GET_DEDUP(bp) != BP_GET_DEDUP(bp_orig) ||
|
||||
@@ -2238,7 +2249,8 @@ zio_nop_write(zio_t *zio)
|
||||
* avoid allocating a new bp and issuing any I/O.
|
||||
*/
|
||||
if (ZIO_CHECKSUM_EQUAL(bp->blk_cksum, bp_orig->blk_cksum)) {
|
||||
ASSERT(zio_checksum_table[zp->zp_checksum].ci_dedup);
|
||||
ASSERT(zio_checksum_table[zp->zp_checksum].ci_flags &
|
||||
ZCHECKSUM_FLAG_NOPWRITE);
|
||||
ASSERT3U(BP_GET_PSIZE(bp), ==, BP_GET_PSIZE(bp_orig));
|
||||
ASSERT3U(BP_GET_LSIZE(bp), ==, BP_GET_LSIZE(bp_orig));
|
||||
ASSERT(zp->zp_compress != ZIO_COMPRESS_OFF);
|
||||
@@ -2566,7 +2578,8 @@ zio_ddt_write(zio_t *zio)
|
||||
* we can't resolve it, so just convert to an ordinary write.
|
||||
* (And automatically e-mail a paper to Nature?)
|
||||
*/
|
||||
if (!zio_checksum_table[zp->zp_checksum].ci_dedup) {
|
||||
if (!(zio_checksum_table[zp->zp_checksum].ci_flags &
|
||||
ZCHECKSUM_FLAG_DEDUP)) {
|
||||
zp->zp_checksum = spa_dedup_checksum(spa);
|
||||
zio_pop_transforms(zio);
|
||||
zio->io_stage = ZIO_STAGE_OPEN;
|
||||
|
||||
Reference in New Issue
Block a user