btrfs-progs: add more hash implementation providers

For environments that require certified implementations of cryptographic
primitives allow to select a library providing them. The requirements
are SHA256 and BLAKE2 (with the 2b variant and 256 bit digest).

For now there are two: libgrcrypt and libsodium (openssl does not
provide the BLAKE2b-256). Accellerated versions are typically provided
and automatically selected.

Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
David Sterba 2020-04-06 21:02:56 +02:00
parent b29b3e6b73
commit 82464a03e7
7 changed files with 102 additions and 6 deletions

View File

@ -14,6 +14,13 @@ For the btrfs-convert utility:
- e2fsprogs - ext2/ext3/ext4 file system libraries, or called e2fslibs
- libreiserfscore - reiserfs file system library version >= 3.6.27
Optionally, the checksums based on cryptographic hashes can be implemeted by
external libraries. Builtin implementations are provided in case the library
dependencies are not desired.
- libgcrypt
- libsodium
Generating documentation:
- asciidoc - text document format tool

View File

@ -95,6 +95,7 @@ CFLAGS = $(SUBST_CFLAGS) \
-fPIC \
-I$(TOPDIR) \
-I$(TOPDIR)/libbtrfsutil \
$(CRYPTO_CFLAGS) \
$(DISABLE_WARNING_FLAGS) \
$(ENABLE_WARNING_FLAGS) \
$(EXTRAWARN_CFLAGS) \
@ -121,8 +122,11 @@ LIBBTRFSUTIL_LDFLAGS = $(SUBST_LDFLAGS) \
$(DEBUG_LDFLAGS_INTERNAL) \
$(EXTRA_LDFLAGS)
LIBS = $(LIBS_BASE)
LIBBTRFS_LIBS = $(LIBS_BASE)
# Default implementation
CRYPTO_OBJECTS =
LIBS = $(LIBS_BASE) $(LIBS_CRYPTO)
LIBBTRFS_LIBS = $(LIBS_BASE) $(LIBS_CRYPTO)
# Static compilation flags
STATIC_CFLAGS = $(CFLAGS) -ffunction-sections -fdata-sections
@ -165,7 +169,7 @@ libbtrfs_objects = send-stream.o send-utils.o kernel-lib/rbtree.o btrfs-list.o \
kernel-lib/raid56.o kernel-lib/tables.o \
common/device-scan.o common/path-utils.o \
common/utils.o libbtrfsutil/subvolume.o libbtrfsutil/stubs.o \
crypto/hash.o crypto/xxhash.o crypto/sha224-256.o crypto/blake2b-ref.o
crypto/hash.o crypto/xxhash.o $(CRYPTO_OBJECTS)
libbtrfs_headers = send-stream.h send-utils.h send.h kernel-lib/rbtree.h btrfs-list.h \
crypto/crc32c.h kernel-lib/list.h kerncompat.h \
kernel-lib/radix-tree.h kernel-lib/sizes.h kernel-lib/raid56.h \
@ -290,6 +294,11 @@ btrfs_convert_cflags += -DBTRFSCONVERT_REISERFS=$(BTRFSCONVERT_REISERFS)
btrfs_fragments_libs = -lgd -lpng -ljpeg -lfreetype
cmds_restore_cflags = -DBTRFSRESTORE_ZSTD=$(BTRFSRESTORE_ZSTD)
ifeq ($(CRYPTOPROVIDER_BUILTIN),1)
CRYPTO_OBJECTS = crypto/sha224-256.o crypto/blake2b-ref.o
CRYPTO_CFLAGS = -DCRYPTOPROVIDER_BUILTIN=1
endif
CHECKER_FLAGS += $(btrfs_convert_cflags)
# collect values of the variables above

View File

@ -21,6 +21,8 @@ BTRFSRESTORE_ZSTD = @BTRFSRESTORE_ZSTD@
PYTHON_BINDINGS = @PYTHON_BINDINGS@
PYTHON = @PYTHON@
PYTHON_CFLAGS = @PYTHON_CFLAGS@
CRYPTOPROVIDER_BUILTIN = @CRYPTOPROVIDER_BUILTIN@
CRYPTO_CFLAGS = @GCRYPT_CFLAGS@ @SODIUM_CFLAGS@
SUBST_CFLAGS = @CFLAGS@
SUBST_LDFLAGS = @LDFLAGS@
@ -28,6 +30,7 @@ SUBST_LDFLAGS = @LDFLAGS@
LIBS_BASE = @UUID_LIBS@ @BLKID_LIBS@ -L. -pthread
LIBS_COMP = @ZLIB_LIBS@ @LZO2_LIBS@ @ZSTD_LIBS@
LIBS_PYTHON = @PYTHON_LIBS@
LIBS_CRYPTO = @GCRYPT_LIBS@ @SODIUM_LIBS@
STATIC_LIBS_BASE = @UUID_LIBS_STATIC@ @BLKID_LIBS_STATIC@ -L. -pthread
STATIC_LIBS_COMP = @ZLIB_LIBS_STATIC@ @LZO2_LIBS_STATIC@ @ZSTD_LIBS_STATIC@

View File

@ -98,7 +98,8 @@ Build dependencies are listed in [INSTALL](INSTALL). Implementation of checksum/
functions is provided by copies of the respective sources to avoid adding
dependencies that would make deployments in rescure or limited environments
harder. The implementations are portable and not optimized for speed nor
accelerated.
accelerated. Optionally it's possible to use libgcrypt or libsodium
implementations.
* CRC32C: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/
* XXHASH: https://github.com/Cyan4973/xxHash

View File

@ -195,6 +195,34 @@ if test "$DISABLE_BTRFSCONVERT" = 0 && test "x$convertfs" = "x"; then
AC_MSG_ERROR([no filesystems for convert, use --disable-convert instead])
fi
AC_ARG_WITH([crypto],
AS_HELP_STRING([[[]--with-crypto[[=builtin]]]], [provider of cryptographic primtives: builtin, libgcrypt, libsodium]),
[], [with_crypto=builtin]
)
cryptoprovider=
cryptoproviderversion=
CRYPTOPROVIDER_BUILTIN=0
if test "$with_crypto" = "builtin"; then
cryptoprovider="builtin"
CRYPTOPROVIDER_BUILTIN=1
AC_DEFINE([CRYPTOPROVIDER_BUILTIN],[1],[Use builtin implementation])
elif test "$with_crypto" = "libgcrypt"; then
cryptoprovider="libgcrypt"
PKG_CHECK_MODULES(GCRYPT, [libgcrypt >= 1.8.0])
AC_DEFINE([CRYPTOPROVIDER_LIBGCRYPT],[1],[Use libcrypt])
cryptoproviderversion=`pkg-config libgcrypt --version`
elif test "$with_crypto" = "libsodium"; then
cryptoprovider="libsodium"
PKG_CHECK_MODULES(SODIUM, [libsodium >= 1.0.4])
AC_DEFINE([CRYPTOPROVIDER_LIBSODIUM],[1],[Use libsodium])
cryptoproviderversion=`pkg-config libsodium --version`
else
AC_MSG_ERROR([unrecognized crypto provider: $with_crypto])
fi
AC_SUBST([CRYPTOPROVIDER_BUILTIN])
AC_DEFINE_UNQUOTED([CRYPTOPROVIDER],["$cryptoprovider"],[Crypto implementation source name])
HAVE_OWN_FIEMAP_EXTENT_SHARED_DEFINE=0
AX_CHECK_DEFINE([linux/fiemap.h], [FIEMAP_EXTENT_SHARED], [],
[HAVE_OWN_FIEMAP_EXTENT_SHARED_DEFINE=1
@ -307,6 +335,7 @@ AC_MSG_RESULT([
btrfs-restore zstd: ${enable_zstd}
Python bindings: ${enable_python}
Python interpreter: ${PYTHON}
crypto provider: ${cryptoprovider} ${cryptoproviderversion}
Type 'make' to compile.
])

View File

@ -75,8 +75,9 @@ int main(int argc, char **argv) {
crc32c_optimization_init();
memset(buf, 0, 4096);
printf("Block size: %d\n", blocksize);
printf("Iterations: %d\n", iterations);
printf("Block size: %d\n", blocksize);
printf("Iterations: %d\n", iterations);
printf("Implementaion: %s\n", CRYPTOPROVIDER);
printf("\n");
for (idx = 0; idx < ARRAY_SIZE(contestants); idx++) {

View File

@ -4,6 +4,9 @@
#include "crypto/sha.h"
#include "crypto/blake2.h"
/*
* Default builtin implementations
*/
int hash_crc32c(const u8* buf, size_t length, u8 *out)
{
u32 crc = ~0;
@ -24,6 +27,11 @@ int hash_xxhash(const u8 *buf, size_t length, u8 *out)
return 0;
}
/*
* Implementations of cryptographic primitives
*/
#if CRYPTOPROVIDER_BUILTIN == 1
int hash_sha256(const u8 *buf, size_t len, u8 *out)
{
SHA256Context context;
@ -45,3 +53,41 @@ int hash_blake2b(const u8 *buf, size_t len, u8 *out)
return 0;
}
#endif
#if CRYPTOPROVIDER_LIBGCRYPT == 1
#include <gcrypt.h>
int hash_sha256(const u8 *buf, size_t len, u8 *out)
{
gcry_md_hash_buffer(GCRY_MD_SHA256, out, buf, len);
return 0;
}
int hash_blake2b(const u8 *buf, size_t len, u8 *out)
{
gcry_md_hash_buffer(GCRY_MD_BLAKE2B_256, out, buf, len);
return 0;
}
#endif
#if CRYPTOPROVIDER_LIBSODIUM == 1
#include <sodium/crypto_hash_sha256.h>
#include <sodium/crypto_generichash_blake2b.h>
int hash_sha256(const u8 *buf, size_t len, u8 *out)
{
return crypto_hash_sha256(out, buf, len);
}
int hash_blake2b(const u8 *buf, size_t len, u8 *out)
{
return crypto_generichash_blake2b(out, CRYPTO_HASH_SIZE_MAX, buf, len,
NULL, 0);
}
#endif