Skip to content

Commit

Permalink
btrfs-progs: add more hash implementation providers
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
kdave committed May 4, 2020
1 parent b29b3e6 commit 82464a0
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 6 deletions.
7 changes: 7 additions & 0 deletions INSTALL
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
15 changes: 12 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ CFLAGS = $(SUBST_CFLAGS) \
-fPIC \
-I$(TOPDIR) \
-I$(TOPDIR)/libbtrfsutil \
$(CRYPTO_CFLAGS) \
$(DISABLE_WARNING_FLAGS) \
$(ENABLE_WARNING_FLAGS) \
$(EXTRAWARN_CFLAGS) \
Expand All @@ -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
Expand Down Expand Up @@ -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 \
Expand Down Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions Makefile.inc.in
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,16 @@ 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@

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@

Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
29 changes: 29 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
])
5 changes: 3 additions & 2 deletions crypto/hash-speedtest.c
Original file line number Diff line number Diff line change
Expand Up @@ -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++) {
Expand Down
46 changes: 46 additions & 0 deletions crypto/hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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

0 comments on commit 82464a0

Please sign in to comment.