Add linux-sha2 topic branch for portability
The upstream ZFS code has correctly moved to a faster native sha2 implementation. Unfortunately, under Linux that's going to be a little problematic so we revert the code to the more portable version contained in earlier ZFS releases. Using the native sha2 implementation in Linux is possible but the API is slightly different in kernel version user space depending on which libraries are used. Ideally, we need a fast implementation of SHA256 which builds as part of ZFS this shouldn't be that hard to do but it will take some effort.
This commit is contained in:
parent
b41c7ff877
commit
14d073e298
24
.topmsg
24
.topmsg
|
@ -1,19 +1,13 @@
|
||||||
From: Brian Behlendorf <behlendorf1@llnl.gov>
|
From: Brian Behlendorf <behlendorf1@llnl.gov>
|
||||||
Subject: [PATCH] zfs branch
|
Subject: [PATCH] linux-sha2
|
||||||
|
|
||||||
Merged result of all changes which are relevant to both Solaris
|
The upstream ZFS code has correctly moved to a faster native sha2
|
||||||
and Linux builds of the ZFS code. These are changes where there
|
implementation. Unfortunately, under Linux that's going to be a little
|
||||||
is a reasonable chance they will be accepted upstream.
|
problematic so we revert the code to the more portable version contained
|
||||||
|
in earlier ZFS releases. Using the native sha2 implementation in Linux
|
||||||
Additionally, since this is effectively the root of the linux
|
is possible but the API is slightly different in kernel version user
|
||||||
ZFS tree the core linux build system is added here. This
|
space depending on which libraries are used. Ideally, we need a fast
|
||||||
includes autogen.sh, configure.ac, m4 macros, some scripts/*,
|
implementation of SHA256 which builds as part of ZFS this shouldn't be
|
||||||
and makefiles for all the core ZFS components. Linux-only
|
that hard to do but it will take some effort.
|
||||||
features which require tweaks to the build system should appear
|
|
||||||
on the relevant topic branches. All autotools products which
|
|
||||||
result from autogen.sh are commited to the linux-configure-branch.
|
|
||||||
|
|
||||||
This branch also contains the META, ChangeLog, AUTHORS, TODO,
|
|
||||||
and README, files.
|
|
||||||
|
|
||||||
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
|
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
|
||||||
|
|
|
@ -43,7 +43,6 @@
|
||||||
#include "zfs_prop.h"
|
#include "zfs_prop.h"
|
||||||
#include "zfs_fletcher.h"
|
#include "zfs_fletcher.h"
|
||||||
#include "libzfs_impl.h"
|
#include "libzfs_impl.h"
|
||||||
#include <sha2.h>
|
|
||||||
#include <sys/zio_checksum.h>
|
#include <sys/zio_checksum.h>
|
||||||
#include <sys/ddt.h>
|
#include <sys/ddt.h>
|
||||||
|
|
||||||
|
@ -336,12 +335,11 @@ cksummer(void *arg)
|
||||||
if (ZIO_CHECKSUM_EQUAL(drrw->drr_key.ddk_cksum,
|
if (ZIO_CHECKSUM_EQUAL(drrw->drr_key.ddk_cksum,
|
||||||
zero_cksum) ||
|
zero_cksum) ||
|
||||||
!DRR_IS_DEDUP_CAPABLE(drrw->drr_checksumflags)) {
|
!DRR_IS_DEDUP_CAPABLE(drrw->drr_checksumflags)) {
|
||||||
SHA256_CTX ctx;
|
zio_cksum_t tmpsha256;
|
||||||
zio_cksum_t tmpsha256;
|
|
||||||
|
zio_checksum_SHA256(buf,
|
||||||
|
drrw->drr_length, &tmpsha256);
|
||||||
|
|
||||||
SHA256Init(&ctx);
|
|
||||||
SHA256Update(&ctx, buf, drrw->drr_length);
|
|
||||||
SHA256Final(&tmpsha256, &ctx);
|
|
||||||
drrw->drr_key.ddk_cksum.zc_word[0] =
|
drrw->drr_key.ddk_cksum.zc_word[0] =
|
||||||
BE_64(tmpsha256.zc_word[0]);
|
BE_64(tmpsha256.zc_word[0]);
|
||||||
drrw->drr_key.ddk_cksum.zc_word[1] =
|
drrw->drr_key.ddk_cksum.zc_word[1] =
|
||||||
|
|
|
@ -19,32 +19,109 @@
|
||||||
* CDDL HEADER END
|
* CDDL HEADER END
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
|
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
|
||||||
* Use is subject to license terms.
|
* Use is subject to license terms.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/zfs_context.h>
|
#include <sys/zfs_context.h>
|
||||||
#include <sys/zio.h>
|
#include <sys/zio.h>
|
||||||
#include <sys/sha2.h>
|
#include <sys/zio_checksum.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SHA-256 checksum, as specified in FIPS 180-3, available at:
|
||||||
|
* http://csrc.nist.gov/publications/PubsFIPS.html
|
||||||
|
*
|
||||||
|
* This is a very compact implementation of SHA-256.
|
||||||
|
* It is designed to be simple and portable, not to be fast.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The literal definitions of Ch() and Maj() according to FIPS 180-3 are:
|
||||||
|
*
|
||||||
|
* Ch(x, y, z) (x & y) ^ (~x & z)
|
||||||
|
* Maj(x, y, z) (x & y) ^ (x & z) ^ (y & z)
|
||||||
|
*
|
||||||
|
* We use equivalent logical reductions here that require one less op.
|
||||||
|
*/
|
||||||
|
#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))
|
||||||
|
|
||||||
|
static const uint32_t SHA256_K[64] = {
|
||||||
|
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
|
||||||
|
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||||||
|
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
|
||||||
|
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
||||||
|
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
|
||||||
|
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||||||
|
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
|
||||||
|
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
||||||
|
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
|
||||||
|
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
||||||
|
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
|
||||||
|
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
||||||
|
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
|
||||||
|
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
||||||
|
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
|
||||||
|
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
||||||
|
};
|
||||||
|
|
||||||
|
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)
|
||||||
|
W[t] = (cp[0] << 24) | (cp[1] << 16) | (cp[2] << 8) | cp[3];
|
||||||
|
|
||||||
|
for (t = 16; t < 64; t++)
|
||||||
|
W[t] = sigma1(W[t - 2]) + W[t - 7] +
|
||||||
|
sigma0(W[t - 15]) + W[t - 16];
|
||||||
|
|
||||||
|
a = H[0]; b = H[1]; c = H[2]; d = H[3];
|
||||||
|
e = H[4]; f = H[5]; g = H[6]; h = H[7];
|
||||||
|
|
||||||
|
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);
|
||||||
|
h = g; g = f; f = e; e = d + T1;
|
||||||
|
d = c; c = b; b = a; a = T1 + T2;
|
||||||
|
}
|
||||||
|
|
||||||
|
H[0] += a; H[1] += b; H[2] += c; H[3] += d;
|
||||||
|
H[4] += e; H[5] += f; H[6] += g; H[7] += h;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
zio_checksum_SHA256(const void *buf, uint64_t size, zio_cksum_t *zcp)
|
zio_checksum_SHA256(const void *buf, uint64_t size, zio_cksum_t *zcp)
|
||||||
{
|
{
|
||||||
SHA2_CTX ctx;
|
uint32_t H[8] = { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
|
||||||
zio_cksum_t tmp;
|
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 };
|
||||||
|
uint8_t pad[128];
|
||||||
|
int i, padsize;
|
||||||
|
|
||||||
SHA2Init(SHA256, &ctx);
|
for (i = 0; i < (size & ~63ULL); i += 64)
|
||||||
SHA2Update(&ctx, buf, size);
|
SHA256Transform(H, (uint8_t *)buf + i);
|
||||||
SHA2Final(&tmp, &ctx);
|
|
||||||
|
|
||||||
/*
|
for (padsize = 0; i < size; i++)
|
||||||
* A prior implementation of this function had a
|
pad[padsize++] = *((uint8_t *)buf + i);
|
||||||
* private SHA256 implementation always wrote things out in
|
|
||||||
* Big Endian and there wasn't a byteswap variant of it.
|
for (pad[padsize++] = 0x80; (padsize & 63) != 56; padsize++)
|
||||||
* To preseve on disk compatibility we need to force that
|
pad[padsize] = 0;
|
||||||
* behaviour.
|
|
||||||
*/
|
for (i = 56; i >= 0; i -= 8)
|
||||||
zcp->zc_word[0] = BE_64(tmp.zc_word[0]);
|
pad[padsize++] = (size << 3) >> i;
|
||||||
zcp->zc_word[1] = BE_64(tmp.zc_word[1]);
|
|
||||||
zcp->zc_word[2] = BE_64(tmp.zc_word[2]);
|
for (i = 0; i < padsize; i += 64)
|
||||||
zcp->zc_word[3] = BE_64(tmp.zc_word[3]);
|
SHA256Transform(H, pad + i);
|
||||||
|
|
||||||
|
ZIO_SET_CHECKSUM(zcp,
|
||||||
|
(uint64_t)H[0] << 32 | H[1],
|
||||||
|
(uint64_t)H[2] << 32 | H[3],
|
||||||
|
(uint64_t)H[4] << 32 | H[5],
|
||||||
|
(uint64_t)H[6] << 32 | H[7]);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue