about summary refs log tree commit diff
path: root/debian
diff options
context:
space:
mode:
Diffstat (limited to 'debian')
-rw-r--r--debian/changelog2
-rw-r--r--debian/control3
-rw-r--r--debian/patches/crypto-only-use-gnutls-crypto-API-remove-libgcrypt-d.patch576
-rw-r--r--debian/patches/series1
4 files changed, 580 insertions, 2 deletions
diff --git a/debian/changelog b/debian/changelog
index 8b8e1b9e..6401c6b9 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -6,6 +6,8 @@ network-manager (1.0.6-1) UNRELEASED; urgency=medium
   * Drop debian/patches/Mark-virtual-ethernet-interfaces-as-unmanaged.patch,
     this patch is obsolete, since upstream provides a udev rules based
     mechanism now to mark virtual interfaces as unmanaged. (Closes: #794083)
+  * Use GnuTLS crypto API instead of gcrypt. Patch cherry-picked from upstream
+    Git. (Closes: #748675)
 
  -- Michael Biebl <biebl@debian.org>  Fri, 28 Aug 2015 01:14:04 +0200
 
diff --git a/debian/control b/debian/control
index a80320d3..5c1e5a8f 100644
--- a/debian/control
+++ b/debian/control
@@ -18,8 +18,7 @@ Build-Depends: debhelper (>= 9),
                ppp-dev (>= 2.4.6),
                libpolkit-gobject-1-dev,
                libpolkit-agent-1-dev (>= 0.97),
-               libgnutls28-dev,
-               libgcrypt11-dev,
+               libgnutls28-dev (>= 2.12),
                uuid-dev,
                systemd (>= 185),
                libsystemd-dev (>= 209),
diff --git a/debian/patches/crypto-only-use-gnutls-crypto-API-remove-libgcrypt-d.patch b/debian/patches/crypto-only-use-gnutls-crypto-API-remove-libgcrypt-d.patch
new file mode 100644
index 00000000..13a8d9f5
--- /dev/null
+++ b/debian/patches/crypto-only-use-gnutls-crypto-API-remove-libgcrypt-d.patch
@@ -0,0 +1,576 @@
+From: =?utf-8?q?Ji=C5=99=C3=AD_Klime=C5=A1?= <jklimes@redhat.com>
+Date: Sat, 28 Mar 2015 00:20:55 +0100
+Subject: crypto: only use gnutls crypto API,
+ remove libgcrypt dependency (bgo #730294)
+
+We don't need libgcrypt, because gnutls provides an API for encryption and
+hashing. (Anyway gnutls itself now uses nettle instead of libgcrypt).
+
+https://bugzilla.gnome.org/show_bug.cgi?id=730294
+
+(cherry-picked from commit b6f5f030331cc680edbe19ae322e894494d63687)
+---
+ configure.ac               |  17 ++----
+ libnm-core/Makefile.am     |   4 +-
+ libnm-core/crypto_gnutls.c | 105 +++++++++++++--------------------
+ libnm-util/Makefile.am     |   6 +-
+ libnm-util/crypto_gnutls.c | 142 ++++++++++++++++++++-------------------------
+ 5 files changed, 112 insertions(+), 162 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index bb1ff6c..d46f1b8 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -566,18 +566,11 @@ if test x"$ac_crypto" = xnss; then
+   AC_DEFINE(HAVE_NSS, 1, [Define if you have NSS])
+   with_nss=yes
+ elif test x"$ac_crypto" = xgnutls; then
+-  PKG_CHECK_MODULES(GNUTLS, [gnutls >= 1.2])
+-  AC_PATH_PROG(LIBGCRYPT_CONFIG, libgcrypt-config, no)
+-  if test x"$LIBGCRYPT_CONFIG" = xno; then
+-    AC_MSG_ERROR([gnutls explicitly requested but gcrypt not found on system])
+-  else
+-    AC_DEFINE(HAVE_GNUTLS, 1, [Define if you have libgnutls])
+-    LIBGCRYPT_CFLAGS=`$LIBGCRYPT_CONFIG --cflags`
+-    LIBGCRYPT_LIBS=`$LIBGCRYPT_CONFIG --libs`
+-    AC_SUBST(LIBGCRYPT_CFLAGS)
+-    AC_SUBST(LIBGCRYPT_LIBS)
+-    with_gnutls=yes
+-  fi
++  PKG_CHECK_MODULES(GNUTLS, [gnutls >= 2.12])
++  AC_DEFINE(HAVE_GNUTLS, 1, [Define if you have libgnutls])
++  AC_SUBST(GNUTLS_CFLAGS)
++  AC_SUBST(GNUTLS_LIBS)
++  with_gnutls=yes
+ else
+   AC_MSG_ERROR([Please choose either 'nss' or 'gnutls' for certificate and crypto operations])
+ fi
+diff --git a/libnm-core/Makefile.am b/libnm-core/Makefile.am
+index 8fab84b..73c5eac 100644
+--- a/libnm-core/Makefile.am
++++ b/libnm-core/Makefile.am
+@@ -33,9 +33,9 @@ libnm_core_la_LIBADD =			\
+ 	$(UUID_LIBS)
+ 
+ if WITH_GNUTLS
+-AM_CPPFLAGS += $(LIBGCRYPT_CFLAGS) $(GNUTLS_CFLAGS)
++AM_CPPFLAGS += $(GNUTLS_CFLAGS)
+ libnm_core_la_SOURCES += crypto_gnutls.c
+-libnm_core_la_LIBADD += $(LIBGCRYPT_LIBS) $(GNUTLS_LIBS)
++libnm_core_la_LIBADD += $(GNUTLS_LIBS)
+ endif
+ 
+ if WITH_NSS
+diff --git a/libnm-core/crypto_gnutls.c b/libnm-core/crypto_gnutls.c
+index 96dddb9..01291f0 100644
+--- a/libnm-core/crypto_gnutls.c
++++ b/libnm-core/crypto_gnutls.c
+@@ -18,7 +18,7 @@
+  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  * Boston, MA 02110-1301 USA.
+  *
+- * Copyright 2007 - 2009 Red Hat, Inc.
++ * Copyright 2007 - 2015 Red Hat, Inc.
+  */
+ 
+ #include "config.h"
+@@ -26,8 +26,8 @@
+ #include <glib.h>
+ #include <glib/gi18n-lib.h>
+ 
+-#include <gcrypt.h>
+ #include <gnutls/gnutls.h>
++#include <gnutls/crypto.h>
+ #include <gnutls/x509.h>
+ #include <gnutls/pkcs12.h>
+ 
+@@ -68,8 +68,9 @@ crypto_decrypt (const char *cipher,
+                 gsize *out_len,
+                 GError **error)
+ {
+-	gcry_cipher_hd_t ctx;
+-	gcry_error_t err;
++	gnutls_cipher_hd_t ctx;
++	gnutls_datum_t key_dt, iv_dt;
++	int err;
+ 	int cipher_mech, i;
+ 	char *output = NULL;
+ 	gboolean success = FALSE;
+@@ -79,13 +80,13 @@ crypto_decrypt (const char *cipher,
+ 		return NULL;
+ 
+ 	if (!strcmp (cipher, CIPHER_DES_EDE3_CBC)) {
+-		cipher_mech = GCRY_CIPHER_3DES;
++		cipher_mech = GNUTLS_CIPHER_3DES_CBC;
+ 		real_iv_len = SALT_LEN;
+ 	} else if (!strcmp (cipher, CIPHER_DES_CBC)) {
+-		cipher_mech = GCRY_CIPHER_DES;
++		cipher_mech = GNUTLS_CIPHER_DES_CBC;
+ 		real_iv_len = SALT_LEN;
+ 	} else if (!strcmp (cipher, CIPHER_AES_CBC)) {
+-		cipher_mech = GCRY_CIPHER_AES;
++		cipher_mech = GNUTLS_CIPHER_AES_128_CBC;
+ 		real_iv_len = 16;
+ 	} else {
+ 		g_set_error (error, NM_CRYPTO_ERROR,
+@@ -105,39 +106,26 @@ crypto_decrypt (const char *cipher,
+ 
+ 	output = g_malloc0 (data_len);
+ 
+-	err = gcry_cipher_open (&ctx, cipher_mech, GCRY_CIPHER_MODE_CBC, 0);
+-	if (err) {
+-		g_set_error (error, NM_CRYPTO_ERROR,
+-		             NM_CRYPTO_ERROR_DECRYPTION_FAILED,
+-		             _("Failed to initialize the decryption cipher context: %s / %s."),
+-		             gcry_strsource (err), gcry_strerror (err));
+-		goto out;
+-	}
+-
+-	err = gcry_cipher_setkey (ctx, key, key_len);
+-	if (err) {
+-		g_set_error (error, NM_CRYPTO_ERROR,
+-		             NM_CRYPTO_ERROR_DECRYPTION_FAILED,
+-		             _("Failed to set symmetric key for decryption: %s / %s."),
+-		             gcry_strsource (err), gcry_strerror (err));
+-		goto out;
+-	}
++	key_dt.data = (unsigned char *) key;
++	key_dt.size = key_len;
++	iv_dt.data = (unsigned char *) iv;
++	iv_dt.size = iv_len;
+ 
+-	err = gcry_cipher_setiv (ctx, iv, iv_len);
+-	if (err) {
++	err = gnutls_cipher_init (&ctx, cipher_mech, &key_dt, &iv_dt);
++	if (err < 0) {
+ 		g_set_error (error, NM_CRYPTO_ERROR,
+ 		             NM_CRYPTO_ERROR_DECRYPTION_FAILED,
+-		             _("Failed to set IV for decryption: %s / %s."),
+-		             gcry_strsource (err), gcry_strerror (err));
++		             _("Failed to initialize the decryption cipher context: %s (%s)"),
++		             gnutls_strerror_name (err), gnutls_strerror (err));
+ 		goto out;
+ 	}
+ 
+-	err = gcry_cipher_decrypt (ctx, output, data_len, data, data_len);
+-	if (err) {
++	err = gnutls_cipher_decrypt2 (ctx, data, data_len, output, data_len);
++	if (err < 0) {
+ 		g_set_error (error, NM_CRYPTO_ERROR,
+ 		             NM_CRYPTO_ERROR_DECRYPTION_FAILED,
+-		             _("Failed to decrypt the private key: %s / %s."),
+-		             gcry_strsource (err), gcry_strerror (err));
++		             _("Failed to decrypt the private key: %s (%s)"),
++		             gnutls_strerror_name (err), gnutls_strerror (err));
+ 		goto out;
+ 	}
+ 	pad_len = output[data_len - 1];
+@@ -174,7 +162,7 @@ out:
+ 			output = NULL;
+ 		}
+ 	}
+-	gcry_cipher_close (ctx);
++	gnutls_cipher_deinit (ctx);
+ 	return output;
+ }
+ 
+@@ -189,8 +177,9 @@ crypto_encrypt (const char *cipher,
+                 gsize *out_len,
+                 GError **error)
+ {
+-	gcry_cipher_hd_t ctx;
+-	gcry_error_t err;
++	gnutls_cipher_hd_t ctx;
++	gnutls_datum_t key_dt, iv_dt;
++	int err;
+ 	int cipher_mech;
+ 	char *output = NULL;
+ 	gboolean success = FALSE;
+@@ -203,10 +192,10 @@ crypto_encrypt (const char *cipher,
+ 		return NULL;
+ 
+ 	if (!strcmp (cipher, CIPHER_DES_EDE3_CBC)) {
+-		cipher_mech = GCRY_CIPHER_3DES;
++		cipher_mech = GNUTLS_CIPHER_3DES_CBC;
+ 		salt_len = SALT_LEN;
+ 	} else if (!strcmp (cipher, CIPHER_AES_CBC)) {
+-		cipher_mech = GCRY_CIPHER_AES;
++		cipher_mech = GNUTLS_CIPHER_AES_128_CBC;
+ 		salt_len = iv_len;
+ 	} else {
+ 		g_set_error (error, NM_CRYPTO_ERROR,
+@@ -229,40 +218,26 @@ crypto_encrypt (const char *cipher,
+ 
+ 	output = g_malloc0 (output_len);
+ 
+-	err = gcry_cipher_open (&ctx, cipher_mech, GCRY_CIPHER_MODE_CBC, 0);
+-	if (err) {
+-		g_set_error (error, NM_CRYPTO_ERROR,
+-		             NM_CRYPTO_ERROR_ENCRYPTION_FAILED,
+-		             _("Failed to initialize the encryption cipher context: %s / %s."),
+-		             gcry_strsource (err), gcry_strerror (err));
+-		goto out;
+-	}
+-
+-	err = gcry_cipher_setkey (ctx, key, key_len);
+-	if (err) {
+-		g_set_error (error, NM_CRYPTO_ERROR,
+-		             NM_CRYPTO_ERROR_ENCRYPTION_FAILED,
+-		             _("Failed to set symmetric key for encryption: %s / %s."),
+-		             gcry_strsource (err), gcry_strerror (err));
+-		goto out;
+-	}
++	key_dt.data = (unsigned char *) key;
++	key_dt.size = key_len;
++	iv_dt.data = (unsigned char *) iv;
++	iv_dt.size = iv_len;
+ 
+-	/* gcrypt only wants 8 bytes of the IV (same as the DES block length) */
+-	err = gcry_cipher_setiv (ctx, iv, salt_len);
+-	if (err) {
++	err = gnutls_cipher_init (&ctx, cipher_mech, &key_dt, &iv_dt);
++	if (err < 0) {
+ 		g_set_error (error, NM_CRYPTO_ERROR,
+ 		             NM_CRYPTO_ERROR_ENCRYPTION_FAILED,
+-		             _("Failed to set IV for encryption: %s / %s."),
+-		             gcry_strsource (err), gcry_strerror (err));
++		             _("Failed to initialize the encryption cipher context: %s (%s)"),
++		             gnutls_strerror_name (err), gnutls_strerror (err));
+ 		goto out;
+ 	}
+ 
+-	err = gcry_cipher_encrypt (ctx, output, output_len, padded_buf, padded_buf_len);
+-	if (err) {
++	err = gnutls_cipher_encrypt2 (ctx, padded_buf, padded_buf_len, output, output_len);
++	if (err < 0) {
+ 		g_set_error (error, NM_CRYPTO_ERROR,
+ 		             NM_CRYPTO_ERROR_ENCRYPTION_FAILED,
+-		             _("Failed to encrypt the data: %s / %s."),
+-		             gcry_strsource (err), gcry_strerror (err));
++		             _("Failed to encrypt the data: %s (%s)"),
++		             gnutls_strerror_name (err), gnutls_strerror (err));
+ 		goto out;
+ 	}
+ 
+@@ -284,7 +259,7 @@ out:
+ 			output = NULL;
+ 		}
+ 	}
+-	gcry_cipher_close (ctx);
++	gnutls_cipher_deinit (ctx);
+ 	return output;
+ }
+ 
+@@ -449,6 +424,6 @@ crypto_randomize (void *buffer, gsize buffer_len, GError **error)
+ 	if (!crypto_init (error))
+ 		return FALSE;
+ 
+-	gcry_randomize (buffer, buffer_len, GCRY_STRONG_RANDOM);
++	gnutls_rnd (GNUTLS_RND_RANDOM, buffer, buffer_len);
+ 	return TRUE;
+ }
+diff --git a/libnm-util/Makefile.am b/libnm-util/Makefile.am
+index fbf8c0b..f508494 100644
+--- a/libnm-util/Makefile.am
++++ b/libnm-util/Makefile.am
+@@ -13,7 +13,7 @@ AM_CPPFLAGS = \
+ 	$(UUID_CFLAGS)
+ 
+ if WITH_GNUTLS
+-AM_CPPFLAGS += $(LIBGCRYPT_CFLAGS) $(GNUTLS_CFLAGS)
++AM_CPPFLAGS += $(GNUTLS_CFLAGS)
+ endif
+ 
+ if WITH_NSS
+@@ -119,7 +119,7 @@ libnm_util_la_LDFLAGS = -Wl,--version-script=$(SYMBOL_VIS_FILE) \
+ 
+ if WITH_GNUTLS
+ libnm_util_la_SOURCES += crypto_gnutls.c
+-libnm_util_la_LIBADD += $(LIBGCRYPT_LIBS) $(GNUTLS_LIBS)
++libnm_util_la_LIBADD += $(GNUTLS_LIBS)
+ endif
+ 
+ if WITH_NSS
+@@ -143,7 +143,7 @@ libtest_crypto_la_LIBADD = \
+ 
+ if WITH_GNUTLS
+ libtest_crypto_la_SOURCES += crypto_gnutls.c
+-libtest_crypto_la_LIBADD += $(LIBGCRYPT_LIBS) $(GNUTLS_LIBS)
++libtest_crypto_la_LIBADD += $(GNUTLS_LIBS)
+ endif
+ 
+ if WITH_NSS
+diff --git a/libnm-util/crypto_gnutls.c b/libnm-util/crypto_gnutls.c
+index 3bec24a..f61ad86 100644
+--- a/libnm-util/crypto_gnutls.c
++++ b/libnm-util/crypto_gnutls.c
+@@ -18,7 +18,7 @@
+  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  * Boston, MA 02110-1301 USA.
+  *
+- * Copyright 2007 - 2009 Red Hat, Inc.
++ * Copyright 2007 - 2015 Red Hat, Inc.
+  */
+ 
+ #include "config.h"
+@@ -26,8 +26,8 @@
+ #include <glib.h>
+ #include <glib/gi18n-lib.h>
+ 
+-#include <gcrypt.h>
+ #include <gnutls/gnutls.h>
++#include <gnutls/crypto.h>
+ #include <gnutls/x509.h>
+ #include <gnutls/pkcs12.h>
+ 
+@@ -65,8 +65,8 @@ crypto_md5_hash (const char *salt,
+                  gsize buflen,
+                  GError **error)
+ {
+-	gcry_md_hd_t ctx;
+-	gcry_error_t err;
++	gnutls_hash_hd_t ctx;
++	int err;
+ 	int nkey = buflen;
+ 	const gsize digest_len = 16;
+ 	int count = 0;
+@@ -81,26 +81,27 @@ crypto_md5_hash (const char *salt,
+ 	g_return_val_if_fail (buffer != NULL, FALSE);
+ 	g_return_val_if_fail (buflen > 0, FALSE);
+ 
+-	err = gcry_md_open (&ctx, GCRY_MD_MD5, 0);
+-	if (err) {
++	if (gnutls_hash_get_len (GNUTLS_DIG_MD5) > MD5_HASH_LEN) {
+ 		g_set_error (error, NM_CRYPTO_ERROR,
+ 		             NM_CRYPTO_ERR_MD5_INIT_FAILED,
+-		             _("Failed to initialize the MD5 engine: %s / %s."),
+-		             gcry_strsource (err), gcry_strerror (err));
++		             _("Hash length too long (%d > %d)."),
++		             gnutls_hash_get_len (GNUTLS_DIG_MD5), MD5_HASH_LEN);
+ 		return FALSE;
+ 	}
+ 
+ 	while (nkey > 0) {
+ 		int i = 0;
+ 
++		err = gnutls_hash_init (&ctx, GNUTLS_DIG_MD5);
++		if (err < 0)
++			goto error;
++
+ 		if (count++)
+-			gcry_md_write (ctx, digest, digest_len);
+-		gcry_md_write (ctx, password, password_len);
++			gnutls_hash (ctx, digest, digest_len);
++		gnutls_hash (ctx, password, password_len);
+ 		if (salt)
+-			gcry_md_write (ctx, salt, SALT_LEN); /* Only use 8 bytes of salt */
+-		gcry_md_final (ctx);
+-		memcpy (digest, gcry_md_read (ctx, 0), digest_len);
+-		gcry_md_reset (ctx);
++			gnutls_hash (ctx, salt, SALT_LEN); /* Only use 8 bytes of salt */
++		gnutls_hash_deinit (ctx, digest);
+ 
+ 		while (nkey && (i < digest_len)) {
+ 			*(p++) = digest[i++];
+@@ -109,8 +110,14 @@ crypto_md5_hash (const char *salt,
+ 	}
+ 
+ 	memset (digest, 0, sizeof (digest));
+-	gcry_md_close (ctx);
+ 	return TRUE;
++error:
++	memset (digest, 0, sizeof (digest));
++	g_set_error (error, NM_CRYPTO_ERROR,
++	             NM_CRYPTO_ERR_MD5_INIT_FAILED,
++	             _("Failed to initialize the MD5 engine: %s (%s)"),
++	             gnutls_strerror_name (err), gnutls_strerror (err));
++	return FALSE;
+ }
+ 
+ char *
+@@ -124,21 +131,22 @@ crypto_decrypt (const char *cipher,
+                 gsize *out_len,
+                 GError **error)
+ {
+-	gcry_cipher_hd_t ctx;
+-	gcry_error_t err;
++	gnutls_cipher_hd_t ctx;
++	gnutls_datum_t key_dt, iv_dt;
++	int err;
+ 	int cipher_mech, i;
+ 	char *output = NULL;
+ 	gboolean success = FALSE;
+ 	gsize pad_len, real_iv_len;
+ 
+ 	if (!strcmp (cipher, CIPHER_DES_EDE3_CBC)) {
+-		cipher_mech = GCRY_CIPHER_3DES;
++		cipher_mech = GNUTLS_CIPHER_3DES_CBC;
+ 		real_iv_len = SALT_LEN;
+ 	} else if (!strcmp (cipher, CIPHER_DES_CBC)) {
+-		cipher_mech = GCRY_CIPHER_DES;
++		cipher_mech = GNUTLS_CIPHER_DES_CBC;
+ 		real_iv_len = SALT_LEN;
+ 	} else if (!strcmp (cipher, CIPHER_AES_CBC)) {
+-		cipher_mech = GCRY_CIPHER_AES;
++		cipher_mech = GNUTLS_CIPHER_AES_128_CBC;
+ 		real_iv_len = 16;
+ 	} else {
+ 		g_set_error (error, NM_CRYPTO_ERROR,
+@@ -158,39 +166,26 @@ crypto_decrypt (const char *cipher,
+ 
+ 	output = g_malloc0 (data->len);
+ 
+-	err = gcry_cipher_open (&ctx, cipher_mech, GCRY_CIPHER_MODE_CBC, 0);
+-	if (err) {
+-		g_set_error (error, NM_CRYPTO_ERROR,
+-		             NM_CRYPTO_ERR_CIPHER_INIT_FAILED,
+-		             _("Failed to initialize the decryption cipher context: %s / %s."),
+-		             gcry_strsource (err), gcry_strerror (err));
+-		goto out;
+-	}
+-
+-	err = gcry_cipher_setkey (ctx, key, key_len);
+-	if (err) {
+-		g_set_error (error, NM_CRYPTO_ERROR,
+-		             NM_CRYPTO_ERR_CIPHER_SET_KEY_FAILED,
+-		             _("Failed to set symmetric key for decryption: %s / %s."),
+-		             gcry_strsource (err), gcry_strerror (err));
+-		goto out;
+-	}
++	key_dt.data = (unsigned char *) key;
++	key_dt.size = key_len;
++	iv_dt.data = (unsigned char *) iv;
++	iv_dt.size = iv_len;
+ 
+-	err = gcry_cipher_setiv (ctx, iv, iv_len);
+-	if (err) {
++	err = gnutls_cipher_init (&ctx, cipher_mech, &key_dt, &iv_dt);
++	if (err < 0) {
+ 		g_set_error (error, NM_CRYPTO_ERROR,
+-		             NM_CRYPTO_ERR_CIPHER_SET_IV_FAILED,
+-		             _("Failed to set IV for decryption: %s / %s."),
+-		             gcry_strsource (err), gcry_strerror (err));
++		             NM_CRYPTO_ERR_CIPHER_INIT_FAILED,
++		             _("Failed to initialize the decryption cipher context: %s (%s)"),
++		             gnutls_strerror_name (err), gnutls_strerror (err));
+ 		goto out;
+ 	}
+ 
+-	err = gcry_cipher_decrypt (ctx, output, data->len, data->data, data->len);
+-	if (err) {
++	err = gnutls_cipher_decrypt2 (ctx, data->data, data->len, output, data->len);
++	if (err < 0) {
+ 		g_set_error (error, NM_CRYPTO_ERROR,
+ 		             NM_CRYPTO_ERR_CIPHER_DECRYPT_FAILED,
+-		             _("Failed to decrypt the private key: %s / %s."),
+-		             gcry_strsource (err), gcry_strerror (err));
++		             _("Failed to decrypt the private key: %s (%s)"),
++		             gnutls_strerror_name (err), gnutls_strerror (err));
+ 		goto out;
+ 	}
+ 	pad_len = output[data->len - 1];
+@@ -227,7 +222,7 @@ out:
+ 			output = NULL;
+ 		}
+ 	}
+-	gcry_cipher_close (ctx);
++	gnutls_cipher_deinit (ctx);
+ 	return output;
+ }
+ 
+@@ -241,8 +236,9 @@ crypto_encrypt (const char *cipher,
+                 gsize *out_len,
+                 GError **error)
+ {
+-	gcry_cipher_hd_t ctx;
+-	gcry_error_t err;
++	gnutls_cipher_hd_t ctx;
++	gnutls_datum_t key_dt, iv_dt;
++	int err;
+ 	int cipher_mech;
+ 	char *output = NULL;
+ 	gboolean success = FALSE;
+@@ -252,10 +248,10 @@ crypto_encrypt (const char *cipher,
+ 	gsize salt_len;
+ 
+ 	if (!strcmp (cipher, CIPHER_DES_EDE3_CBC)) {
+-		cipher_mech = GCRY_CIPHER_3DES;
++		cipher_mech = GNUTLS_CIPHER_3DES_CBC;
+ 		salt_len = SALT_LEN;
+ 	} else if (!strcmp (cipher, CIPHER_AES_CBC)) {
+-		cipher_mech = GCRY_CIPHER_AES;
++		cipher_mech = GNUTLS_CIPHER_AES_128_CBC;
+ 		salt_len = iv_len;
+ 	} else {
+ 		g_set_error (error, NM_CRYPTO_ERROR,
+@@ -278,40 +274,26 @@ crypto_encrypt (const char *cipher,
+ 
+ 	output = g_malloc0 (output_len);
+ 
+-	err = gcry_cipher_open (&ctx, cipher_mech, GCRY_CIPHER_MODE_CBC, 0);
+-	if (err) {
+-		g_set_error (error, NM_CRYPTO_ERROR,
+-		             NM_CRYPTO_ERR_CIPHER_INIT_FAILED,
+-		             _("Failed to initialize the encryption cipher context: %s / %s."),
+-		             gcry_strsource (err), gcry_strerror (err));
+-		goto out;
+-	}
+-
+-	err = gcry_cipher_setkey (ctx, key, key_len);
+-	if (err) {
+-		g_set_error (error, NM_CRYPTO_ERROR,
+-		             NM_CRYPTO_ERR_CIPHER_SET_KEY_FAILED,
+-		             _("Failed to set symmetric key for encryption: %s / %s."),
+-		             gcry_strsource (err), gcry_strerror (err));
+-		goto out;
+-	}
++	key_dt.data = (unsigned char *) key;
++	key_dt.size = key_len;
++	iv_dt.data = (unsigned char *) iv;
++	iv_dt.size = iv_len;
+ 
+-	/* gcrypt only wants 8 bytes of the IV (same as the DES block length) */
+-	err = gcry_cipher_setiv (ctx, iv, salt_len);
+-	if (err) {
++	err = gnutls_cipher_init (&ctx, cipher_mech, &key_dt, &iv_dt);
++	if (err < 0) {
+ 		g_set_error (error, NM_CRYPTO_ERROR,
+-		             NM_CRYPTO_ERR_CIPHER_SET_IV_FAILED,
+-		             _("Failed to set IV for encryption: %s / %s."),
+-		             gcry_strsource (err), gcry_strerror (err));
++		             NM_CRYPTO_ERR_CIPHER_INIT_FAILED,
++		             _("Failed to initialize the encryption cipher context: %s (%s)"),
++		             gnutls_strerror_name (err), gnutls_strerror (err));
+ 		goto out;
+ 	}
+ 
+-	err = gcry_cipher_encrypt (ctx, output, output_len, padded_buf, padded_buf_len);
+-	if (err) {
++	err = gnutls_cipher_encrypt2 (ctx, padded_buf, padded_buf_len, output, output_len);
++	if (err < 0) {
+ 		g_set_error (error, NM_CRYPTO_ERROR,
+ 		             NM_CRYPTO_ERR_CIPHER_DECRYPT_FAILED,
+-		             _("Failed to encrypt the data: %s / %s."),
+-		             gcry_strsource (err), gcry_strerror (err));
++		             _("Failed to encrypt the data: %s (%s)"),
++		             gnutls_strerror_name (err), gnutls_strerror (err));
+ 		goto out;
+ 	}
+ 
+@@ -333,7 +315,7 @@ out:
+ 			output = NULL;
+ 		}
+ 	}
+-	gcry_cipher_close (ctx);
++	gnutls_cipher_deinit (ctx);
+ 	return output;
+ }
+ 
+@@ -484,6 +466,6 @@ crypto_verify_pkcs8 (const GByteArray *data,
+ gboolean
+ crypto_randomize (void *buffer, gsize buffer_len, GError **error)
+ {
+-	gcry_randomize (buffer, buffer_len, GCRY_STRONG_RANDOM);
++	gnutls_rnd (GNUTLS_RND_RANDOM, buffer, buffer_len);
+ 	return TRUE;
+ }
diff --git a/debian/patches/series b/debian/patches/series
index fe7351d9..df1d3cc3 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -9,3 +9,4 @@ build-install-nm-settings-ifcfg-rh.5-man-page-condit.patch
 Don-t-make-NetworkManager-D-Bus-activatable.patch
 Don-t-block-network.target-on-NetworkManager-wait-on.patch
 Fix-iscsiadm-path.patch
+crypto-only-use-gnutls-crypto-API-remove-libgcrypt-d.patch