diff options
author | Daniel P. Berrange <berrange@redhat.com> | 2015-07-01 18:10:33 +0100 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2015-07-08 13:11:01 +0200 |
commit | 62893b67cd82bbd48b013c1cec25f0d863612c80 (patch) | |
tree | fdcded03d2afd85f14e082d1264808ac8b0e4abb /crypto/init.c | |
parent | ca38a4cc9e36647437b837b346a41981fb8880cd (diff) | |
download | qemu-62893b67cd82bbd48b013c1cec25f0d863612c80.zip qemu-62893b67cd82bbd48b013c1cec25f0d863612c80.tar.gz qemu-62893b67cd82bbd48b013c1cec25f0d863612c80.tar.bz2 |
crypto: add a gcrypt cipher implementation
If we are linking to gnutls already and gnutls is built against
gcrypt, then we should use gcrypt as a cipher backend in
preference to our built-in backend.
This will be used when linking against GNUTLS 1.x and many
GNUTLS 2.x versions.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Message-Id: <1435770638-25715-6-git-send-email-berrange@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'crypto/init.c')
-rw-r--r-- | crypto/init.c | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/crypto/init.c b/crypto/init.c index 40f3d6e..7447882 100644 --- a/crypto/init.c +++ b/crypto/init.c @@ -19,13 +19,48 @@ */ #include "crypto/init.h" +#include "qemu/thread.h" #ifdef CONFIG_GNUTLS #include <gnutls/gnutls.h> #include <gnutls/crypto.h> +#ifdef CONFIG_GNUTLS_GCRYPT +#include <gcrypt.h> +#endif + /* #define DEBUG_GNUTLS */ +/* + * If GNUTLS is built against GCrypt then + * + * - 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 + * + * But.... + * + * When gcrypt >= 1.6.0 we must not initialize gcrypt threading + * because gcrypt will do that itself. + * + * So we need to init gcrypt threading if + * + * - gcrypt < 1.6.0 + * AND + * - gnutls < 2.12 + * + */ + +#if (defined(CONFIG_GNUTLS_GCRYPT) && \ + (!defined(GNUTLS_VERSION_NUMBER) || \ + (GNUTLS_VERSION_NUMBER < 0x020c00)) && \ + (!defined(GCRYPT_VERSION_NUMBER) || \ + (GCRYPT_VERSION_NUMBER < 0x010600))) +#define QCRYPTO_INIT_GCRYPT_THREADS +#else +#undef QCRYPTO_INIT_GCRYPT_THREADS +#endif + #ifdef DEBUG_GNUTLS static void qcrypto_gnutls_log(int level, const char *str) { @@ -33,6 +68,49 @@ static void qcrypto_gnutls_log(int level, const char *str) } #endif +#ifdef QCRYPTO_INIT_GCRYPT_THREADS +static int qcrypto_gcrypt_mutex_init(void **priv) +{ \ + QemuMutex *lock = NULL; + lock = g_new0(QemuMutex, 1); + qemu_mutex_init(lock); + *priv = lock; + return 0; +} + +static int qcrypto_gcrypt_mutex_destroy(void **priv) +{ + QemuMutex *lock = *priv; + qemu_mutex_destroy(lock); + g_free(lock); + return 0; +} + +static int qcrypto_gcrypt_mutex_lock(void **priv) +{ + QemuMutex *lock = *priv; + qemu_mutex_lock(lock); + return 0; +} + +static int qcrypto_gcrypt_mutex_unlock(void **priv) +{ + QemuMutex *lock = *priv; + qemu_mutex_unlock(lock); + return 0; +} + +static struct gcry_thread_cbs qcrypto_gcrypt_thread_impl = { + (GCRY_THREAD_OPTION_PTHREAD | (GCRY_THREAD_OPTION_VERSION << 8)), + NULL, + qcrypto_gcrypt_mutex_init, + qcrypto_gcrypt_mutex_destroy, + qcrypto_gcrypt_mutex_lock, + qcrypto_gcrypt_mutex_unlock, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; +#endif /* QCRYPTO_INIT_GCRYPT */ + int qcrypto_init(Error **errp) { int ret; @@ -47,6 +125,18 @@ int qcrypto_init(Error **errp) gnutls_global_set_log_level(10); gnutls_global_set_log_function(qcrypto_gnutls_log); #endif + +#ifdef CONFIG_GNUTLS_GCRYPT + if (!gcry_check_version(GCRYPT_VERSION)) { + error_setg(errp, "Unable to initialize gcrypt"); + return -1; + } +#ifdef QCRYPTO_INIT_GCRYPT_THREADS + gcry_control(GCRYCTL_SET_THREAD_CBS, &qcrypto_gcrypt_thread_impl); +#endif /* QCRYPTO_INIT_GCRYPT_THREADS */ + gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0); +#endif + return 0; } |