Commit 91bfcdb0 authored by Daniel P. Berrangé's avatar Daniel P. Berrangé
Browse files

crypto: allow use of nettle/gcrypt to be selected explicitly



Currently the choice of whether to use nettle or gcrypt is
made based on what gnutls is linked to. There are times
when it is desirable to be able to force build against a
specific library. For example, if testing changes to QEMU's
crypto code all 3 possible backends need to be checked
regardless of what the local gnutls uses.

It is also desirable to be able to enable nettle/gcrypt
for cipher/hash algorithms, without enabling gnutls
for TLS support.

This gives two new configure flags, which allow the
following possibilities

Automatically determine nettle vs gcrypt from what
gnutls links to (recommended to minimize number of
crypto libraries linked to)

 ./configure

Automatically determine nettle vs gcrypt based on
which is installed

 ./configure --disable-gnutls

Force use of nettle

 ./configure --enable-nettle

Force use of gcrypt

 ./configure --enable-gcrypt

Force use of built-in AES & crippled-DES

 ./configure --disable-nettle --disable-gcrypt

Signed-off-by: default avatarDaniel P. Berrange <berrange@redhat.com>
parent ca3e40e2
Loading
Loading
Loading
Loading
+89 −11
Original line number Diff line number Diff line
@@ -331,6 +331,8 @@ gtkabi=""
gtk_gl="no"
gnutls=""
gnutls_hash=""
nettle=""
gcrypt=""
vte=""
virglrenderer=""
tpm="yes"
@@ -1114,6 +1116,14 @@ for opt do
  ;;
  --enable-gnutls) gnutls="yes"
  ;;
  --disable-nettle) nettle="no"
  ;;
  --enable-nettle) nettle="yes"
  ;;
  --disable-gcrypt) gcrypt="no"
  ;;
  --enable-gcrypt) gcrypt="yes"
  ;;
  --enable-rdma) rdma="yes"
  ;;
  --disable-rdma) rdma="no"
@@ -1324,6 +1334,8 @@ disabled with --disable-FEATURE, default is enabled if available:
  sparse          sparse checker

  gnutls          GNUTLS cryptography support
  nettle          nettle cryptography support
  gcrypt          libgcrypt cryptography support
  sdl             SDL UI
  --with-sdlabi     select preferred SDL ABI 1.2 or 2.0
  gtk             gtk UI
@@ -2254,20 +2266,76 @@ else
    gnutls_hash="no"
fi

if test "$gnutls_gcrypt" != "no"; then
    if has "libgcrypt-config"; then

# If user didn't give a --disable/enable-gcrypt flag,
# then mark as disabled if user requested nettle
# explicitly, or if gnutls links to nettle
if test -z "$gcrypt"
then
    if test "$nettle" = "yes" || test "$gnutls_nettle" = "yes"
    then
        gcrypt="no"
    fi
fi

# If user didn't give a --disable/enable-nettle flag,
# then mark as disabled if user requested gcrypt
# explicitly, or if gnutls links to gcrypt
if test -z "$nettle"
then
    if test "$gcrypt" = "yes" || test "$gnutls_gcrypt" = "yes"
    then
        nettle="no"
    fi
fi

has_libgcrypt_config() {
    if ! has "libgcrypt-config"
    then
	return 1
    fi

    if test -n "$cross_prefix"
    then
	host=`libgcrypt-config --host`
	if test "$host-" != $cross_prefix
	then
	    return 1
	fi
    fi

    return 0
}

if test "$gcrypt" != "no"; then
    if has_libgcrypt_config; then
        gcrypt_cflags=`libgcrypt-config --cflags`
        gcrypt_libs=`libgcrypt-config --libs`
        # Debian has remove -lgpg-error from libgcrypt-config
        # as it "spreads unnecessary dependencies" which in
        # turn breaks static builds...
        if test "$static" = "yes"
        then
            gcrypt_libs="$gcrypt_libs -lgpg-error"
        fi
        libs_softmmu="$gcrypt_libs $libs_softmmu"
        libs_tools="$gcrypt_libs $libs_tools"
        QEMU_CFLAGS="$QEMU_CFLAGS $gcrypt_cflags"
        gcrypt="yes"
        if test -z "$nettle"; then
           nettle="no"
        fi
    else
        if test "$gcrypt" = "yes"; then
            feature_not_found "gcrypt" "Install gcrypt devel"
        else
            gcrypt="no"
        fi
    fi
fi


if test "$gnutls_nettle" != "no"; then
if test "$nettle" != "no"; then
    if $pkg_config --exists "nettle"; then
        nettle_cflags=`$pkg_config --cflags nettle`
        nettle_libs=`$pkg_config --libs nettle`
@@ -2275,10 +2343,20 @@ if test "$gnutls_nettle" != "no"; then
        libs_softmmu="$nettle_libs $libs_softmmu"
        libs_tools="$nettle_libs $libs_tools"
        QEMU_CFLAGS="$QEMU_CFLAGS $nettle_cflags"
        nettle="yes"
    else
        if test "$nettle" = "yes"; then
            feature_not_found "nettle" "Install nettle devel"
        else
            nettle="no"
        fi
    fi
fi

if test "$gcrypt" = "yes" && test "$nettle" = "yes"
then
    error_exit "Only one of gcrypt & nettle can be enabled"
fi

##########################################
# libtasn1 - only for the TLS creds/session test suite
@@ -4621,8 +4699,8 @@ echo "GTK support $gtk"
echo "GTK GL support    $gtk_gl"
echo "GNUTLS support    $gnutls"
echo "GNUTLS hash       $gnutls_hash"
echo "GNUTLS gcrypt     $gnutls_gcrypt"
echo "GNUTLS nettle     $gnutls_nettle ${gnutls_nettle+($nettle_version)}"
echo "libgcrypt         $gcrypt"
echo "nettle            $nettle ${nettle+($nettle_version)}"
echo "libtasn1          $tasn1"
echo "VTE support       $vte"
echo "curses support    $curses"
@@ -4991,11 +5069,11 @@ fi
if test "$gnutls_hash" = "yes" ; then
  echo "CONFIG_GNUTLS_HASH=y" >> $config_host_mak
fi
if test "$gnutls_gcrypt" = "yes" ; then
  echo "CONFIG_GNUTLS_GCRYPT=y" >> $config_host_mak
if test "$gcrypt" = "yes" ; then
  echo "CONFIG_GCRYPT=y" >> $config_host_mak
fi
if test "$gnutls_nettle" = "yes" ; then
  echo "CONFIG_GNUTLS_NETTLE=y" >> $config_host_mak
if test "$nettle" = "yes" ; then
  echo "CONFIG_NETTLE=y" >> $config_host_mak
  echo "CONFIG_NETTLE_VERSION_MAJOR=${nettle_version%%.*}" >> $config_host_mak
fi
if test "$tasn1" = "yes" ; then
+4 −4
Original line number Diff line number Diff line
@@ -47,7 +47,7 @@ qcrypto_cipher_validate_key_length(QCryptoCipherAlgorithm alg,
    return true;
}

#if defined(CONFIG_GNUTLS_GCRYPT) || defined(CONFIG_GNUTLS_NETTLE)
#if defined(CONFIG_GCRYPT) || defined(CONFIG_NETTLE)
static uint8_t *
qcrypto_cipher_munge_des_rfb_key(const uint8_t *key,
                                 size_t nkey)
@@ -63,11 +63,11 @@ qcrypto_cipher_munge_des_rfb_key(const uint8_t *key,
    }
    return ret;
}
#endif /* CONFIG_GNUTLS_GCRYPT || CONFIG_GNUTLS_NETTLE */
#endif /* CONFIG_GCRYPT || CONFIG_NETTLE */

#ifdef CONFIG_GNUTLS_GCRYPT
#ifdef CONFIG_GCRYPT
#include "crypto/cipher-gcrypt.c"
#elif defined CONFIG_GNUTLS_NETTLE
#elif defined CONFIG_NETTLE
#include "crypto/cipher-nettle.c"
#else
#include "crypto/cipher-builtin.c"
+12 −14
Original line number Diff line number Diff line
@@ -24,8 +24,9 @@
#ifdef CONFIG_GNUTLS
#include <gnutls/gnutls.h>
#include <gnutls/crypto.h>
#endif

#ifdef CONFIG_GNUTLS_GCRYPT
#ifdef CONFIG_GCRYPT
#include <gcrypt.h>
#endif

@@ -37,6 +38,7 @@
 *  - When GNUTLS >= 2.12, we must not initialize gcrypt threading
 *    because GNUTLS will do that itself
 *  - When GNUTLS < 2.12 we must always initialize gcrypt threading
 *  - When GNUTLS is disabled we must always initialize gcrypt threading
 *
 * But....
 *
@@ -48,11 +50,14 @@
 *   - gcrypt < 1.6.0
 * AND
 *      - gnutls < 2.12
 *   OR
 *      - gnutls is disabled
 *
 */

#if (defined(CONFIG_GNUTLS_GCRYPT) &&           \
     (!defined(GNUTLS_VERSION_NUMBER) ||        \
#if (defined(CONFIG_GCRYPT) &&                  \
     (!defined(CONFIG_GNUTLS) ||                \
      !defined(GNUTLS_VERSION_NUMBER) ||       \
      (GNUTLS_VERSION_NUMBER < 0x020c00)) &&    \
     (!defined(GCRYPT_VERSION_NUMBER) ||        \
      (GCRYPT_VERSION_NUMBER < 0x010600)))
@@ -113,6 +118,7 @@ static struct gcry_thread_cbs qcrypto_gcrypt_thread_impl = {

int qcrypto_init(Error **errp)
{
#ifdef CONFIG_GNUTLS
    int ret;
    ret = gnutls_global_init();
    if (ret < 0) {
@@ -125,8 +131,9 @@ int qcrypto_init(Error **errp)
    gnutls_global_set_log_level(10);
    gnutls_global_set_log_function(qcrypto_gnutls_log);
#endif
#endif

#ifdef CONFIG_GNUTLS_GCRYPT
#ifdef CONFIG_GCRYPT
    if (!gcry_check_version(GCRYPT_VERSION)) {
        error_setg(errp, "Unable to initialize gcrypt");
        return -1;
@@ -139,12 +146,3 @@ int qcrypto_init(Error **errp)

    return 0;
}

#else /* ! CONFIG_GNUTLS */

int qcrypto_init(Error **errp G_GNUC_UNUSED)
{
    return 0;
}

#endif /* ! CONFIG_GNUTLS */