From 5221aedc00531fd746fa79fbf856233b73c01be5 Mon Sep 17 00:00:00 2001 From: David Sterba Date: Wed, 15 Nov 2023 19:02:15 +0100 Subject: [PATCH] btrfs-progs: crypto: add Botan as crypto provider https://botan.randombit.net/ Botan is a cryptography library with C bindings and provides what we need (sha256 and blake2b), among many others. Add it to the list of crypto backends if somebody wants to use it. Currently the version 2.19 is the latest one. Botan3 3.2.0 exists but does not seem to be widely available in distros yet. Configure with --with-crypto=botan. Signed-off-by: David Sterba --- .github/workflows/ci-build-test.yml | 7 +++ INSTALL | 1 + Makefile.inc.in | 4 +- README.md | 4 +- .../ci-openSUSE-tumbleweed-x86_64/Dockerfile | 3 +- configure.ac | 10 +++- crypto/hash-speedtest.c | 4 ++ crypto/hash-vectest.c | 16 ++++++ crypto/hash.c | 55 +++++++++++++++++++ tests/build-tests.sh | 3 + tests/hash-tests.sh | 1 + 11 files changed, 102 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci-build-test.yml b/.github/workflows/ci-build-test.yml index dcddfb66..5c558d04 100644 --- a/.github/workflows/ci-build-test.yml +++ b/.github/workflows/ci-build-test.yml @@ -80,3 +80,10 @@ jobs: - uses: actions/checkout@v3 - name: CI Tumbleweed (libkcapi) run: ci/ci-build-tumbleweed HEAD --with-crypto=libkcapi + check-tumbleweed-botan: + name: CI Tumbleweed (Botan) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: CI Tumbleweed (Botan) + run: ci/ci-build-tumbleweed HEAD --with-crypto=botan diff --git a/INSTALL b/INSTALL index 6ae89091..d7698abc 100644 --- a/INSTALL +++ b/INSTALL @@ -21,6 +21,7 @@ dependencies are not desired. - libgcrypt >= 1.8.0 - libsodium >= 1.0.4 - libkcapi >= 1.0.0 +- Botan >= 2.19.0 Optionally, multipath device detection requires libudev and running udev daemon, as it's the only source of the path information. Static build has a diff --git a/Makefile.inc.in b/Makefile.inc.in index 4a0003c2..b0988065 100644 --- a/Makefile.inc.in +++ b/Makefile.inc.in @@ -22,7 +22,7 @@ PYTHON_BINDINGS = @PYTHON_BINDINGS@ PYTHON = @PYTHON@ PYTHON_CFLAGS = @PYTHON_CFLAGS@ CRYPTOPROVIDER_BUILTIN = @CRYPTOPROVIDER_BUILTIN@ -CRYPTO_CFLAGS = @GCRYPT_CFLAGS@ @SODIUM_CFLAGS@ @KCAPI_CFLAGS@ +CRYPTO_CFLAGS = @GCRYPT_CFLAGS@ @SODIUM_CFLAGS@ @KCAPI_CFLAGS@ @BOTAN_CFLAGS@ HAVE_CFLAG_msse2 = @HAVE_CFLAG_msse2@ HAVE_CFLAG_msse41 = @HAVE_CFLAG_msse41@ @@ -37,7 +37,7 @@ SUBST_LDFLAGS = @LDFLAGS@ LIBS_BASE = @UUID_LIBS@ @BLKID_LIBS@ @LIBUDEV_LIBS@ -L. -pthread LIBS_COMP = @ZLIB_LIBS@ @LZO2_LIBS@ @ZSTD_LIBS@ LIBS_PYTHON = @PYTHON_LIBS@ -LIBS_CRYPTO = @GCRYPT_LIBS@ @SODIUM_LIBS@ @KCAPI_LIBS@ +LIBS_CRYPTO = @GCRYPT_LIBS@ @SODIUM_LIBS@ @KCAPI_LIBS@ @BOTAN_LIBS@ STATIC_LIBS_BASE = @UUID_LIBS_STATIC@ @BLKID_LIBS_STATIC@ -L. -pthread STATIC_LIBS_COMP = @ZLIB_LIBS_STATIC@ @LZO2_LIBS_STATIC@ @ZSTD_LIBS_STATIC@ diff --git a/README.md b/README.md index d6424c39..8e2a0ef8 100644 --- a/README.md +++ b/README.md @@ -123,8 +123,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 rescue or limited environments harder. The implementations are portable and there are optimized versions for -some architectures. Optionally it's possible to use libgcrypt, libsodium or -libkcapi implementations. +some architectures. Optionally it's possible to use libgcrypt, libsodium, +libkcapi or Botan implementations. * CRC32C: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/ * XXHASH: https://github.com/Cyan4973/xxHash diff --git a/ci/images/ci-openSUSE-tumbleweed-x86_64/Dockerfile b/ci/images/ci-openSUSE-tumbleweed-x86_64/Dockerfile index 52e6d7e1..dffd6cd2 100644 --- a/ci/images/ci-openSUSE-tumbleweed-x86_64/Dockerfile +++ b/ci/images/ci-openSUSE-tumbleweed-x86_64/Dockerfile @@ -26,7 +26,8 @@ RUN zypper install -y --no-recommends glibc-devel-static libblkid-devel-static \ libzstd-devel-static lzo-devel-static zlib-devel-static RUN zypper install -y --no-recommends gcc13 -RUN zypper install -y --no-recommends libgcrypt-devel libsodium-devel libkcapi-devel +RUN zypper install -y --no-recommends libgcrypt-devel libsodium-devel libkcapi-devel \ + libbotan-devel COPY ./test-build . COPY ./run-tests . diff --git a/configure.ac b/configure.ac index 3b2b7452..819f2226 100644 --- a/configure.ac +++ b/configure.ac @@ -236,7 +236,7 @@ if test "$DISABLE_BTRFSCONVERT" = 0 && test "x$convertfs" = "x"; then fi AC_ARG_WITH([crypto], - AS_HELP_STRING([[[]--with-crypto[[=builtin]]]], [provider of cryptographic primitives: builtin, libgcrypt, libsodium, libkcapi]), + AS_HELP_STRING([[[]--with-crypto[[=builtin]]]], [provider of cryptographic primitives: builtin, libgcrypt, libsodium, libkcapi, botan]), [], [with_crypto=builtin] ) @@ -246,6 +246,7 @@ CRYPTOPROVIDER_BUILTIN=0 CRYPTOPROVIDER_LIBGCRYPT=0 CRYPTOPROVIDER_LIBSODIUM=0 CRYPTOPROVIDER_LIBKCAPI=0 +CRYPTOPROVIDER_BOTAN=0 if test "$with_crypto" = "builtin"; then cryptoprovider="builtin" CRYPTOPROVIDER_BUILTIN=1 @@ -264,6 +265,11 @@ elif test "$with_crypto" = "libkcapi"; then PKG_CHECK_MODULES(KCAPI, [libkcapi >= 1.0.0]) CRYPTOPROVIDER_LIBKCAPI=1 cryptoproviderversion=`${PKG_CONFIG} libkcapi --modversion` +elif test "$with_crypto" = "botan"; then + cryptoprovider="botan" + PKG_CHECK_MODULES(BOTAN, [botan-2 >= 2.19.0]) + CRYPTOPROVIDER_BOTAN=1 + cryptoproviderversion=`${PKG_CONFIG} botan-2 --modversion` else AC_MSG_ERROR([unrecognized crypto provider: $with_crypto]) fi @@ -275,6 +281,8 @@ AC_SUBST([CRYPTOPROVIDER_LIBSODIUM]) AC_DEFINE_UNQUOTED([CRYPTOPROVIDER_LIBSODIUM],[$CRYPTOPROVIDER_LIBSODIUM],[Use libsodium]) AC_SUBST([CRYPTOPROVIDER_LIBKCAPI]) AC_DEFINE_UNQUOTED([CRYPTOPROVIDER_LIBKCAPI],[$CRYPTOPROVIDER_LIBKCAPI],[Use libkcapi]) +AC_SUBST([CRYPTOPROVIDER_BOTAN]) +AC_DEFINE_UNQUOTED([CRYPTOPROVIDER_BOTAN],[$CRYPTOPROVIDER_BOTAN],[Use Botan]) AC_DEFINE_UNQUOTED([CRYPTOPROVIDER],["$cryptoprovider"],[Crypto implementation source name]) AX_CHECK_DEFINE([linux/fiemap.h], [FIEMAP_EXTENT_SHARED], [], diff --git a/crypto/hash-speedtest.c b/crypto/hash-speedtest.c index 88f9c9b1..24418e3e 100644 --- a/crypto/hash-speedtest.c +++ b/crypto/hash-speedtest.c @@ -200,6 +200,8 @@ int main(int argc, char **argv) { .cpu_flag = CPU_FLAG_NONE, .backend = CRYPTOPROVIDER_LIBSODIUM + 1 }, { .name = "SHA256-kcapi", .digest = hash_sha256, .digest_size = 32, .cpu_flag = CPU_FLAG_NONE, .backend = CRYPTOPROVIDER_LIBKCAPI + 1 }, + { .name = "SHA256-botan", .digest = hash_sha256, .digest_size = 32, + .cpu_flag = CPU_FLAG_NONE, .backend = CRYPTOPROVIDER_BOTAN + 1 }, { .name = "SHA256-NI", .digest = hash_sha256, .digest_size = 32, .cpu_flag = CPU_FLAG_SHA, .backend = CRYPTOPROVIDER_BUILTIN + 1 }, { .name = "BLAKE2-ref", .digest = hash_blake2b, .digest_size = 32, @@ -210,6 +212,8 @@ int main(int argc, char **argv) { .cpu_flag = CPU_FLAG_NONE, .backend = CRYPTOPROVIDER_LIBSODIUM + 1 }, { .name = "BLAKE2-kcapi", .digest = hash_blake2b, .digest_size = 32, .cpu_flag = CPU_FLAG_NONE, .backend = CRYPTOPROVIDER_LIBKCAPI + 1 }, + { .name = "BLAKE2-botan", .digest = hash_blake2b, .digest_size = 32, + .cpu_flag = CPU_FLAG_NONE, .backend = CRYPTOPROVIDER_BOTAN + 1 }, { .name = "BLAKE2-SSE2", .digest = hash_blake2b, .digest_size = 32, .cpu_flag = CPU_FLAG_SSE2, .backend = CRYPTOPROVIDER_BUILTIN + 1 }, { .name = "BLAKE2-SSE41", .digest = hash_blake2b, .digest_size = 32, diff --git a/crypto/hash-vectest.c b/crypto/hash-vectest.c index 07a830fb..e0561e47 100644 --- a/crypto/hash-vectest.c +++ b/crypto/hash-vectest.c @@ -482,6 +482,14 @@ static const struct hash_testspec test_spec[] = { .cpu_flag = CPU_FLAG_NONE, .hash = hash_sha256, .backend = CRYPTOPROVIDER_LIBKCAPI + 1 + }, { + .name = "SHA256-botan", + .digest_size = 32, + .testvec = sha256_tv, + .count = ARRAY_SIZE(sha256_tv), + .cpu_flag = CPU_FLAG_NONE, + .hash = hash_sha256, + .backend = CRYPTOPROVIDER_BOTAN + 1 }, { .name = "SHA256-NI", .digest_size = 32, @@ -522,6 +530,14 @@ static const struct hash_testspec test_spec[] = { .cpu_flag = CPU_FLAG_NONE, .hash = hash_blake2b, .backend = CRYPTOPROVIDER_LIBKCAPI + 1 + }, { + .name = "BLAKE2-botan", + .digest_size = 32, + .testvec = blake2b_256_tv, + .count = ARRAY_SIZE(blake2b_256_tv), + .cpu_flag = CPU_FLAG_NONE, + .hash = hash_blake2b, + .backend = CRYPTOPROVIDER_BOTAN + 1 }, { .name = "BLAKE2-SSE2", .digest_size = 32, diff --git a/crypto/hash.c b/crypto/hash.c index f18dbcb6..61208f78 100644 --- a/crypto/hash.c +++ b/crypto/hash.c @@ -180,3 +180,58 @@ int hash_blake2b(const u8 *buf, size_t len, u8 *out) } #endif + +#if CRYPTOPROVIDER_BOTAN == 1 + +#include + +void hash_init_accel(void) +{ + crc32c_init_accel(); +} + +int hash_sha256(const u8 *buf, size_t len, u8 *out) +{ + botan_hash_t hash; + static bool initialized = false; + int ret; + + if (!initialized) { + ret = botan_hash_init(&hash, "SHA-256", 0); + if (ret < 0) { + fprintf(stderr, "HASH: cannot instantiate sha256, error %d\n", ret); + exit(1); + } + initialized = true; + } else { + botan_hash_clear(hash); + } + botan_hash_update(hash, buf, len); + botan_hash_final(hash, out); + /* botan_hash_destroy(hash); */ + return 0; +} + +int hash_blake2b(const u8 *buf, size_t len, u8 *out) +{ + botan_hash_t hash; + static bool initialized = false; + int ret; + + if (!initialized) { + ret = botan_hash_init(&hash, "BLAKE2b(256)", 0); + if (ret < 0) { + fprintf(stderr, "HASH: cannot instantiate sha256, error %d\n", ret); + exit(1); + } + initialized = true; + } else { + botan_hash_clear(hash); + } + botan_hash_update(hash, buf, len); + botan_hash_final(hash, out); + /* botan_hash_destroy(hash); */ + return 0; +} + +#endif diff --git a/tests/build-tests.sh b/tests/build-tests.sh index 80609908..8544f441 100755 --- a/tests/build-tests.sh +++ b/tests/build-tests.sh @@ -130,6 +130,9 @@ build_make_targets conf='--with-crypto=libkcapi' build_make_targets +conf='--with-crypto=botan' +build_make_targets + # Old architectures conf='--with-crypto=builtin' buildme_cflags '-march=core2' diff --git a/tests/hash-tests.sh b/tests/hash-tests.sh index d77270f5..b77ad181 100755 --- a/tests/hash-tests.sh +++ b/tests/hash-tests.sh @@ -36,6 +36,7 @@ buildme builtin buildme libgcrypt buildme libsodium buildme libkcapi +buildme botan echo "VERDICT:" echo "$verdict"