From 8775096e070a5dc033248f1068b0bc37d5244265 Mon Sep 17 00:00:00 2001 From: Sergio Correia Date: Mon, 19 Aug 2024 14:45:08 +0100 Subject: [PATCH] Add OpenSSL as an alternative to libgcrypt If OpenSSL is not explicitly required (ie.g with --with-openssl), the default keeps being: 1. try to use a HW random generator 2. attempt to use libgcrypt 3. fall back to custom AES implementation, if libgcrypt is not available If OpenSSL is explictly required, step #2 replaces libgcrypt with openssl. Signed-off-by: Sergio Correia --- configure.ac | 42 +++++++++++++++++++++++++++++++++++------- src/genrand.c | 34 +++++++++++++++++++--------------- src/scrub.c | 4 ++-- 3 files changed, 56 insertions(+), 24 deletions(-) diff --git a/configure.ac b/configure.ac index 504051f..c1a087d 100644 --- a/configure.ac +++ b/configure.ac @@ -69,19 +69,47 @@ AC_CHECK_FUNCS( \ ) X_AC_CHECK_PTHREADS + +# Sanity check; we cannot have both --with-libgcrypt AND --with-openssl +# together. +AS_IF([test "x$with_openssl" = "xyes"], [ + AS_IF([test "x$with_libgcrypt" = "xyes"], + [AC_MSG_ERROR([You can use either --with-openssl or --with-libgcrypt, not both at once])] + ) +]) + +## +# OpenSSL libcrypto library +## +have_openssl=no +AC_ARG_WITH(openssl, AS_HELP_STRING([--with-openssl], [build with OpenSSL libcrypto])) + +if test "x$with_openssl" = "xyes"; then + AC_SEARCH_LIBS([RAND_bytes], [crypto], + [AC_DEFINE([HAVE_OPENSSL], [1], [OpenSSL libcrypto available]) + have_openssl=yes + ], [AC_MSG_ERROR([OpenSSL libcrypto required])] + ) +fi + ## # gcrypt library ## have_libgcrypt=no AC_ARG_WITH(libgcrypt, AS_HELP_STRING([--without-libgcrypt], [build without libgcrypt; fallback to custom AES implementation])) -AS_IF([test "x$with_libgcrypt" != "xno"], - [AM_PATH_LIBGCRYPT([1.5.0], - [AC_DEFINE([HAVE_LIBGCRYPT], [1], [libgcrypt API available]) - gcrypt_CFLAGS="$LIBGCRYPT_CFLAGS" - gcrypt_LIBS="$LIBGCRYPT_LIBS" - have_libgcrypt=yes - ] + +# Technically there is no need for testing this again, as we already +# error'ed out early if both options were enabled at once. +AS_IF([test "x$with_openssl" != "xyes"], [ + AS_IF([test "x$with_libgcrypt" != "xno"], [ + AM_PATH_LIBGCRYPT([1.5.0], + [AC_DEFINE([HAVE_LIBGCRYPT], [1], [libgcrypt API available]) + gcrypt_CFLAGS="$LIBGCRYPT_CFLAGS" + gcrypt_LIBS="$LIBGCRYPT_LIBS" + have_libgcrypt=yes + ] + )] )] ) AM_CONDITIONAL([LIBGCRYPT], [test "$have_libgcrypt" = "yes"]) diff --git a/src/genrand.c b/src/genrand.c index f9ac610..d37daa8 100644 --- a/src/genrand.c +++ b/src/genrand.c @@ -41,18 +41,20 @@ #include "genrand.h" #include "hwrand.h" -#ifdef HAVE_LIBGCRYPT -#include -#else +#if !defined(HAVE_LIBGCRYPT) && !defined(HAVE_OPENSSL) #include "aes.h" -#endif /* HAVE_LIBGCRYPT. */ +#elif defined(HAVE_LIBGCRYPT) +#include +#elif defined(HAVE_OPENSSL) +#include +#endif /* !defined(HAVE_LIBGCRYPT) && !defined(HAVE_OPENSSL) */ extern char *prog; static bool no_hwrand = false; static hwrand_t gen_hwrand; -#ifndef HAVE_LIBGCRYPT +#if !defined(HAVE_LIBGCRYPT) && !defined(HAVE_OPENSSL) #define PATH_URANDOM "/dev/urandom" #define PAYLOAD_SZ 16 @@ -146,26 +148,26 @@ churnrand(void) error: return -1; } -#endif /* HAVE_LIBGCRYPT. */ +#endif /* !defined(HAVE_LIBGCRYPT) && !defined(HAVE_OPENSSL) */ /* Initialize the module. */ int initrand(void) { -#ifndef HAVE_LIBGCRYPT +#if !defined(HAVE_LIBGCRYPT) && !defined(HAVE_OPENSSL) struct timeval tv; -#else +#elif defined(HAVE_LIBCRYPT) if (!gcry_check_version(GCRYPT_VERSION)) { goto error; } gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0); -#endif /* HAVE_LIBGCRYPT */ +#endif /* !defined(HAVE_LIBGCRYPT) && !defined(HAVE_OPENSSL) */ if (!no_hwrand) gen_hwrand = init_hwrand(); -#ifndef HAVE_LIBGCRYPT +#if !defined(HAVE_LIBGCRYPT) && !defined(HAVE_OPENSSL) /* Always initialize the software random number generator as backup */ if (gettimeofday(&tv, NULL) < 0) @@ -178,7 +180,7 @@ initrand(void) #endif if (churnrand() < 0) goto error; -#endif /* HAVE_LIBGCRYPT. */ +#endif /* !defined(HAVE_LIBGCRYPT) && !defined(HAVE_OPENSSL) */ return 0; error: return -1; @@ -189,11 +191,11 @@ error: void genrand(unsigned char *buf, int buflen) { -#ifndef HAVE_LIBGCRYPT +#if !defined(HAVE_LIBGCRYPT) && !defined(HAVE_OPENSSL) int i; unsigned char out[PAYLOAD_SZ]; int cpylen = PAYLOAD_SZ; -#endif /* HAVE_LIBGCRYPT. */ +#endif if (gen_hwrand) { bool hwok = gen_hwrand(buf, buflen); @@ -201,7 +203,7 @@ genrand(unsigned char *buf, int buflen) return; } -#ifndef HAVE_LIBGCRYPT +#if !defined(HAVE_LIBGCRYPT) && !defined(HAVE_OPENSSL) for (i = 0; i < buflen; i += cpylen) { aes_encrypt(&ctx, ctr, out); incr128(ctr); @@ -210,8 +212,10 @@ genrand(unsigned char *buf, int buflen) memcpy(&buf[i], out, cpylen); } assert(i == buflen); -#else +#elif defined(HAVE_LIBGCRYPT) gcry_randomize(buf, buflen, GCRY_STRONG_RANDOM); +#elif defined(HAVE_OPENSSL) + assert(RAND_bytes(buf, buflen) == 1); #endif /* HAVE_LIBGCRYPT. */ } diff --git a/src/scrub.c b/src/scrub.c index 55abf72..f76a2b2 100644 --- a/src/scrub.c +++ b/src/scrub.c @@ -465,13 +465,13 @@ scrub(char *path, off_t size, const sequence_t *seq, int bufsize, case PAT_RANDOM: printf("%s: %-8s", prog, "random"); progress_create(&p, pcol); -#ifndef HAVE_LIBGCRYPT +#if !defined(HAVE_LIBGCRYPT) && !defined(HAVE_OPENSSL) if (churnrand() < 0) { fprintf(stderr, "%s: churnrand: %s\n", prog, strerror(errno)); exit(1); } -#endif /* HAVE_LIBGCRYPT. */ +#endif /* !defined(HAVE_LIBGCRYPT) && !defined(HAVE_OPENSSL) */ written = fillfile(path, size, buf, bufsize, (progress_t)progress_update, p, (refill_t)genrand, sparse, enospc, extentonly); -- 2.44.0