You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
scrub/SOURCES/scrub-2.6.1-openssl-instead...

212 lines
6.1 KiB

From 8775096e070a5dc033248f1068b0bc37d5244265 Mon Sep 17 00:00:00 2001
From: Sergio Correia <scorreia@redhat.com>
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 <scorreia@redhat.com>
---
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 <gcrypt.h>
-#else
+#if !defined(HAVE_LIBGCRYPT) && !defined(HAVE_OPENSSL)
#include "aes.h"
-#endif /* HAVE_LIBGCRYPT. */
+#elif defined(HAVE_LIBGCRYPT)
+#include <gcrypt.h>
+#elif defined(HAVE_OPENSSL)
+#include <openssl/rand.h>
+#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