Blame egg/egg-openssl.c

Packit Service f02b19
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
Packit Service f02b19
/* egg-openssl.c - OpenSSL compatibility functionality
Packit Service f02b19
Packit Service f02b19
   Copyright (C) 2007 Stefan Walter
Packit Service f02b19
Packit Service f02b19
   The Gnome Keyring Library is free software; you can redistribute it and/or
Packit Service f02b19
   modify it under the terms of the GNU Library General Public License as
Packit Service f02b19
   published by the Free Software Foundation; either version 2 of the
Packit Service f02b19
   License, or (at your option) any later version.
Packit Service f02b19
Packit Service f02b19
   The Gnome Keyring Library is distributed in the hope that it will be useful,
Packit Service f02b19
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service f02b19
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service f02b19
   Library General Public License for more details.
Packit Service f02b19
Packit Service f02b19
   You should have received a copy of the GNU Library General Public
Packit Service f02b19
   License along with the Gnome Library; see the file COPYING.LIB.  If not,
Packit Service f02b19
   see <http://www.gnu.org/licenses/>.
Packit Service f02b19
Packit Service f02b19
   Author: Stef Walter <stef@memberwebs.com>
Packit Service f02b19
*/
Packit Service f02b19
Packit Service f02b19
#include "config.h"
Packit Service f02b19
Packit Service f02b19
#include "egg-hex.h"
Packit Service f02b19
#include "egg-openssl.h"
Packit Service f02b19
#include "egg-secure-memory.h"
Packit Service f02b19
#include "egg-symkey.h"
Packit Service f02b19
Packit Service f02b19
#include <gcrypt.h>
Packit Service f02b19
Packit Service f02b19
#include <glib.h>
Packit Service f02b19
Packit Service f02b19
#include <ctype.h>
Packit Service f02b19
#include <string.h>
Packit Service f02b19
Packit Service f02b19
EGG_SECURE_DECLARE (openssl);
Packit Service f02b19
Packit Service f02b19
static const struct {
Packit Service f02b19
	const gchar *desc;
Packit Service f02b19
	int algo;
Packit Service f02b19
	int mode;
Packit Service f02b19
} openssl_algos[] = {
Packit Service f02b19
	{ "DES-ECB", GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB },
Packit Service f02b19
	{ "DES-CFB64", GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CFB },
Packit Service f02b19
	{ "DES-CFB", GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CFB },
Packit Service f02b19
	/* DES-CFB1 */
Packit Service f02b19
	/* DES-CFB8 */
Packit Service f02b19
	/* DESX-CBC */
Packit Service f02b19
	/* DES-EDE */
Packit Service f02b19
	/* DES-EDE-CBC */
Packit Service f02b19
	/* DES-EDE-ECB */
Packit Service f02b19
	/* DES-EDE-CFB64 DES-EDE-CFB */
Packit Service f02b19
	/* DES-EDE-CFB1 */
Packit Service f02b19
	/* DES-EDE-CFB8 */
Packit Service f02b19
	/* DES-EDE-OFB */
Packit Service f02b19
	/* DES-EDE3 */
Packit Service f02b19
	{ "DES-EDE3-ECB", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_ECB },
Packit Service f02b19
	{ "DES-EDE3-CFB64", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CFB },
Packit Service f02b19
	{ "DES-EDE3-CFB", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CFB },
Packit Service f02b19
	/* DES-EDE3-CFB1 */
Packit Service f02b19
	/* DES-EDE3-CFB8 */
Packit Service f02b19
	{ "DES-OFB", GCRY_CIPHER_DES, GCRY_CIPHER_MODE_OFB },
Packit Service f02b19
	{ "DES-EDE3-OFB", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_OFB },
Packit Service f02b19
	{ "DES-CBC", GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC },
Packit Service f02b19
	{ "DES-EDE3-CBC", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC },
Packit Service f02b19
	/* RC2-ECB */
Packit Service f02b19
	/* RC2-CBC */
Packit Service f02b19
	/* RC2-40-CBC */
Packit Service f02b19
	/* RC2-64-CBC */
Packit Service f02b19
	/* RC2-CFB64    RC2-CFB */
Packit Service f02b19
	/* RC2-OFB */
Packit Service f02b19
	{ "RC4", GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM },
Packit Service f02b19
	{ "RC4-40", GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM },
Packit Service f02b19
	{ "IDEA-ECB", GCRY_CIPHER_IDEA, GCRY_CIPHER_MODE_ECB },
Packit Service f02b19
	{ "IDEA-CFB64", GCRY_CIPHER_IDEA, GCRY_CIPHER_MODE_CFB },
Packit Service f02b19
	{ "IDEA-OFB", GCRY_CIPHER_IDEA, GCRY_CIPHER_MODE_OFB },
Packit Service f02b19
	{ "IDEA-CBC", GCRY_CIPHER_IDEA, GCRY_CIPHER_MODE_CBC },
Packit Service f02b19
	{ "BF-ECB", GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_ECB },
Packit Service f02b19
	{ "BF-CBC", GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CBC },
Packit Service f02b19
	{ "BF-CFB64", GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CFB },
Packit Service f02b19
	{ "BF-CFB", GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CFB },
Packit Service f02b19
	{ "BF-OFB", GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_OFB },
Packit Service f02b19
	{ "CAST5-ECB", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_ECB },
Packit Service f02b19
	{ "CAST5-CBC", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CBC },
Packit Service f02b19
	{ "CAST5-CFB64", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CFB },
Packit Service f02b19
	{ "CAST5-CFB", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CFB },
Packit Service f02b19
	{ "CAST5-OFB", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_OFB },
Packit Service f02b19
	/* RC5-32-12-16-CBC */
Packit Service f02b19
	/* RC5-32-12-16-ECB */
Packit Service f02b19
	/* RC5-32-12-16-CFB64  RC5-32-12-16-CFB */
Packit Service f02b19
	/* RC5-32-12-16-OFB */
Packit Service f02b19
	{ "AES-128-ECB", GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_ECB },
Packit Service f02b19
	{ "AES-128-CBC", GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC },
Packit Service f02b19
	/* AES-128-CFB1 */
Packit Service f02b19
	/* AES-128-CFB8	*/
Packit Service f02b19
	{ "AES-128-CFB128", GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CFB },
Packit Service f02b19
	{ "AES-128-CFB", GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CFB },
Packit Service f02b19
	{ "AES-128-OFB", GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_OFB },
Packit Service f02b19
	{ "AES-128-CTR", GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CTR },
Packit Service f02b19
	{ "AES-192-ECB", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_ECB },
Packit Service f02b19
	{ "AES-192-CBC", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC },
Packit Service f02b19
	/* AES-192-CFB1 */
Packit Service f02b19
	/* AES-192-CFB8 */
Packit Service f02b19
	{ "AES-192-CFB128", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CFB },
Packit Service f02b19
	{ "AES-192-CFB", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CFB },
Packit Service f02b19
	{ "AES-192-OFB", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_OFB },
Packit Service f02b19
	{ "AES-192-CTR", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CTR },
Packit Service f02b19
	{ "AES-256-ECB", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_ECB },
Packit Service f02b19
	{ "AES-256-CBC", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC },
Packit Service f02b19
	/* AES-256-CFB1 */
Packit Service f02b19
	/* AES-256-CFB8 */
Packit Service f02b19
	{ "AES-256-CFB128", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CFB },
Packit Service f02b19
	{ "AES-256-CFB", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CFB },
Packit Service f02b19
	{ "AES-256-OFB", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_OFB },
Packit Service f02b19
	{ "AES-256-CTR", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CTR },
Packit Service f02b19
	/* CAMELLIA-128-ECB */
Packit Service f02b19
	/* CAMELLIA-128-CBC */
Packit Service f02b19
	/* CAMELLIA-128-CFB1 */
Packit Service f02b19
	/* CAMELLIA-128-CFB8 */
Packit Service f02b19
	/* CAMELLIA-128-CFB128   CAMELLIA-128-CFB */
Packit Service f02b19
	/* CAMELLIA-128-OFB */
Packit Service f02b19
	/* CAMELLIA-192-ECB */
Packit Service f02b19
	/* CAMELLIA-192-CBC */
Packit Service f02b19
	/* CAMELLIA-192-CFB1 */
Packit Service f02b19
	/* CAMELLIA-192-CFB8 */
Packit Service f02b19
	/* CAMELLIA-192-CFB128   CAMELLIA-192-CFB */
Packit Service f02b19
	/* CAMELLIA-192_OFB */
Packit Service f02b19
	/* CAMELLIA-256-ECB */
Packit Service f02b19
	/* CAMELLIA-256-CBC */
Packit Service f02b19
	/* CAMELLIA-256-CFB1 */
Packit Service f02b19
	/* CAMELLIA-256-CFB8 */
Packit Service f02b19
	/* CAMELLIA-256-CFB128   CAMELLIA-256-CFB */
Packit Service f02b19
	/* CAMELLIA-256-OFB */
Packit Service f02b19
};
Packit Service f02b19
Packit Service f02b19
/* ------------------------------------------------------------------------- */
Packit Service f02b19
Packit Service f02b19
int
Packit Service f02b19
egg_openssl_parse_algo (const char *name, int *mode)
Packit Service f02b19
{
Packit Service f02b19
	static GQuark openssl_quarks[G_N_ELEMENTS(openssl_algos)] = { 0, };
Packit Service f02b19
	static gsize openssl_quarks_inited = 0;
Packit Service f02b19
	GQuark q;
Packit Service f02b19
	int i;
Packit Service f02b19
Packit Service f02b19
	if (g_once_init_enter (&openssl_quarks_inited)) {
Packit Service f02b19
		for (i = 0; i < G_N_ELEMENTS(openssl_algos); ++i)
Packit Service f02b19
			openssl_quarks[i] = g_quark_from_static_string (openssl_algos[i].desc);
Packit Service f02b19
		g_once_init_leave (&openssl_quarks_inited, 1);
Packit Service f02b19
	}
Packit Service f02b19
Packit Service f02b19
	q = g_quark_try_string (name);
Packit Service f02b19
	if (q) {
Packit Service f02b19
		for (i = 0; i < G_N_ELEMENTS(openssl_algos); ++i) {
Packit Service f02b19
			if (q == openssl_quarks[i]) {
Packit Service f02b19
				*mode = openssl_algos[i].mode;
Packit Service f02b19
				return openssl_algos[i].algo;
Packit Service f02b19
			}
Packit Service f02b19
		}
Packit Service f02b19
	}
Packit Service f02b19
Packit Service f02b19
	return 0;
Packit Service f02b19
}
Packit Service f02b19
Packit Service f02b19
static gboolean
Packit Service f02b19
parse_dekinfo (const gchar *dek, int *algo, int *mode, guchar **iv)
Packit Service f02b19
{
Packit Service f02b19
	gboolean success = FALSE;
Packit Service f02b19
	gchar **parts = NULL;
Packit Service f02b19
	gcry_error_t gcry;
Packit Service f02b19
	gsize ivlen, len;
Packit Service f02b19
Packit Service f02b19
	parts = g_strsplit (dek, ",", 2);
Packit Service f02b19
	if (!parts || !parts[0] || !parts[1])
Packit Service f02b19
		goto done;
Packit Service f02b19
Packit Service f02b19
	/* Parse the algorithm name */
Packit Service f02b19
	*algo = egg_openssl_parse_algo (parts[0], mode);
Packit Service f02b19
	if (!*algo)
Packit Service f02b19
		goto done;
Packit Service f02b19
Packit Service f02b19
	/* Make sure this is usable */
Packit Service f02b19
	gcry = gcry_cipher_test_algo (*algo);
Packit Service f02b19
	if (gcry)
Packit Service f02b19
		goto done;
Packit Service f02b19
Packit Service f02b19
	/* Parse the IV */
Packit Service f02b19
	ivlen = gcry_cipher_get_algo_blklen (*algo);
Packit Service f02b19
Packit Service f02b19
	*iv = egg_hex_decode (parts[1], strlen(parts[1]), &len;;
Packit Service f02b19
	if (!*iv || ivlen != len) {
Packit Service f02b19
		g_free (*iv);
Packit Service f02b19
		goto done;
Packit Service f02b19
	}
Packit Service f02b19
Packit Service f02b19
	success = TRUE;
Packit Service f02b19
Packit Service f02b19
done:
Packit Service f02b19
	g_strfreev (parts);
Packit Service f02b19
	return success;
Packit Service f02b19
}
Packit Service f02b19
Packit Service f02b19
guchar *
Packit Service f02b19
egg_openssl_decrypt_block (const gchar *dekinfo,
Packit Service f02b19
                           const gchar *password,
Packit Service f02b19
                           gssize n_password,
Packit Service f02b19
                           GBytes *data,
Packit Service f02b19
                           gsize *n_decrypted)
Packit Service f02b19
{
Packit Service f02b19
	gcry_cipher_hd_t ch;
Packit Service f02b19
	guchar *key = NULL;
Packit Service f02b19
	guchar *iv = NULL;
Packit Service f02b19
	int gcry, ivlen;
Packit Service f02b19
	int algo = 0;
Packit Service f02b19
	int mode = 0;
Packit Service f02b19
	guchar *decrypted;
Packit Service f02b19
Packit Service f02b19
	if (!parse_dekinfo (dekinfo, &algo, &mode, &iv))
Packit Service f02b19
		return FALSE;
Packit Service f02b19
Packit Service f02b19
	ivlen = gcry_cipher_get_algo_blklen (algo);
Packit Service f02b19
Packit Service f02b19
	/* We assume the iv is at least as long as at 8 byte salt */
Packit Service f02b19
	g_return_val_if_fail (ivlen >= 8, FALSE);
Packit Service f02b19
Packit Service f02b19
	/* IV is already set from the DEK info */
Packit Service f02b19
	if (!egg_symkey_generate_simple (algo, GCRY_MD_MD5, password,
Packit Service f02b19
	                                 n_password, iv, 8, 1, &key, NULL)) {
Packit Service f02b19
		g_free (iv);
Packit Service f02b19
		return NULL;
Packit Service f02b19
	}
Packit Service f02b19
Packit Service f02b19
	gcry = gcry_cipher_open (&ch, algo, mode, 0);
Packit Service f02b19
	g_return_val_if_fail (!gcry, NULL);
Packit Service f02b19
Packit Service f02b19
	gcry = gcry_cipher_setkey (ch, key, gcry_cipher_get_algo_keylen (algo));
Packit Service f02b19
	g_return_val_if_fail (!gcry, NULL);
Packit Service f02b19
	egg_secure_free (key);
Packit Service f02b19
Packit Service f02b19
	/* 16 = 128 bits */
Packit Service f02b19
	gcry = gcry_cipher_setiv (ch, iv, ivlen);
Packit Service f02b19
	g_return_val_if_fail (!gcry, NULL);
Packit Service f02b19
	g_free (iv);
Packit Service f02b19
Packit Service f02b19
	/* Allocate output area */
Packit Service f02b19
	*n_decrypted = g_bytes_get_size (data);
Packit Service f02b19
	decrypted = egg_secure_alloc (*n_decrypted);
Packit Service f02b19
Packit Service f02b19
	gcry = gcry_cipher_decrypt (ch, decrypted, *n_decrypted,
Packit Service f02b19
	                            g_bytes_get_data (data, NULL),
Packit Service f02b19
	                            g_bytes_get_size (data));
Packit Service f02b19
	if (gcry) {
Packit Service f02b19
		egg_secure_free (decrypted);
Packit Service f02b19
		g_return_val_if_reached (NULL);
Packit Service f02b19
	}
Packit Service f02b19
Packit Service f02b19
	gcry_cipher_close (ch);
Packit Service f02b19
Packit Service f02b19
	return decrypted;
Packit Service f02b19
}
Packit Service f02b19
Packit Service f02b19
guchar *
Packit Service f02b19
egg_openssl_encrypt_block (const gchar *dekinfo,
Packit Service f02b19
                           const gchar *password,
Packit Service f02b19
                           gssize n_password,
Packit Service f02b19
                           GBytes *data,
Packit Service f02b19
                           gsize *n_encrypted)
Packit Service f02b19
{
Packit Service f02b19
	gsize n_overflow, n_batch, n_padding;
Packit Service f02b19
	gcry_cipher_hd_t ch;
Packit Service f02b19
	guchar *key = NULL;
Packit Service f02b19
	guchar *iv = NULL;
Packit Service f02b19
	guchar *padded = NULL;
Packit Service f02b19
	int gcry, ivlen;
Packit Service f02b19
	int algo = 0;
Packit Service f02b19
	int mode = 0;
Packit Service f02b19
	gsize n_data;
Packit Service f02b19
	guchar *encrypted;
Packit Service f02b19
	const guchar *dat;
Packit Service f02b19
Packit Service f02b19
	if (!parse_dekinfo (dekinfo, &algo, &mode, &iv))
Packit Service f02b19
		g_return_val_if_reached (NULL);
Packit Service f02b19
Packit Service f02b19
	ivlen = gcry_cipher_get_algo_blklen (algo);
Packit Service f02b19
Packit Service f02b19
	/* We assume the iv is at least as long as at 8 byte salt */
Packit Service f02b19
	g_return_val_if_fail (ivlen >= 8, NULL);
Packit Service f02b19
Packit Service f02b19
	/* IV is already set from the DEK info */
Packit Service f02b19
	if (!egg_symkey_generate_simple (algo, GCRY_MD_MD5, password,
Packit Service f02b19
	                                        n_password, iv, 8, 1, &key, NULL))
Packit Service f02b19
		g_return_val_if_reached (NULL);
Packit Service f02b19
Packit Service f02b19
	gcry = gcry_cipher_open (&ch, algo, mode, 0);
Packit Service f02b19
	g_return_val_if_fail (!gcry, NULL);
Packit Service f02b19
Packit Service f02b19
	gcry = gcry_cipher_setkey (ch, key, gcry_cipher_get_algo_keylen (algo));
Packit Service f02b19
	g_return_val_if_fail (!gcry, NULL);
Packit Service f02b19
	egg_secure_free (key);
Packit Service f02b19
Packit Service f02b19
	/* 16 = 128 bits */
Packit Service f02b19
	gcry = gcry_cipher_setiv (ch, iv, ivlen);
Packit Service f02b19
	g_return_val_if_fail (!gcry, NULL);
Packit Service f02b19
	g_free (iv);
Packit Service f02b19
Packit Service f02b19
	dat = g_bytes_get_data (data, &n_data);
Packit Service f02b19
Packit Service f02b19
	/* Allocate output area */
Packit Service f02b19
	n_overflow = (n_data % ivlen);
Packit Service f02b19
	n_padding = n_overflow ? (ivlen - n_overflow) : 0;
Packit Service f02b19
	n_batch = n_data - n_overflow;
Packit Service f02b19
	*n_encrypted = n_data + n_padding;
Packit Service f02b19
	encrypted = g_malloc0 (*n_encrypted);
Packit Service f02b19
Packit Service f02b19
	g_assert (*n_encrypted % ivlen == 0);
Packit Service f02b19
	g_assert (*n_encrypted >= n_data);
Packit Service f02b19
	g_assert (*n_encrypted == n_batch + n_overflow + n_padding);
Packit Service f02b19
Packit Service f02b19
	/* Encrypt everything but the last bit */
Packit Service f02b19
	gcry = gcry_cipher_encrypt (ch, encrypted, n_batch, dat, n_batch);
Packit Service f02b19
	if (gcry) {
Packit Service f02b19
		g_free (encrypted);
Packit Service f02b19
		g_return_val_if_reached (NULL);
Packit Service f02b19
	}
Packit Service f02b19
Packit Service f02b19
	/* Encrypt the padded block */
Packit Service f02b19
	if (n_overflow) {
Packit Service f02b19
		padded = egg_secure_alloc (ivlen);
Packit Service f02b19
		memset (padded, 0, ivlen);
Packit Service f02b19
		memcpy (padded, dat + n_batch, n_overflow);
Packit Service f02b19
		gcry = gcry_cipher_encrypt (ch, encrypted + n_batch, ivlen, padded, ivlen);
Packit Service f02b19
		egg_secure_free (padded);
Packit Service f02b19
		if (gcry) {
Packit Service f02b19
			g_free (encrypted);
Packit Service f02b19
			g_return_val_if_reached (NULL);
Packit Service f02b19
		}
Packit Service f02b19
	}
Packit Service f02b19
Packit Service f02b19
	gcry_cipher_close (ch);
Packit Service f02b19
	return encrypted;
Packit Service f02b19
}
Packit Service f02b19
Packit Service f02b19
const gchar*
Packit Service f02b19
egg_openssl_get_dekinfo (GHashTable *headers)
Packit Service f02b19
{
Packit Service f02b19
	const gchar *val;
Packit Service f02b19
	if (!headers)
Packit Service f02b19
		return NULL;
Packit Service f02b19
	val = g_hash_table_lookup (headers, "Proc-Type");
Packit Service f02b19
	if (!val || strcmp (val, "4,ENCRYPTED") != 0)
Packit Service f02b19
		return NULL;
Packit Service f02b19
	val = g_hash_table_lookup (headers, "DEK-Info");
Packit Service f02b19
	g_return_val_if_fail (val, NULL);
Packit Service f02b19
	return val;
Packit Service f02b19
}
Packit Service f02b19
Packit Service f02b19
const gchar*
Packit Service f02b19
egg_openssl_prep_dekinfo (GHashTable *headers)
Packit Service f02b19
{
Packit Service f02b19
	gchar *dekinfo, *hex;
Packit Service f02b19
	gsize ivlen;
Packit Service f02b19
	guchar *iv;
Packit Service f02b19
Packit Service f02b19
	/* Create the iv */
Packit Service f02b19
	ivlen = gcry_cipher_get_algo_blklen (GCRY_CIPHER_3DES);
Packit Service f02b19
	g_return_val_if_fail (ivlen, NULL);
Packit Service f02b19
	iv = g_malloc (ivlen);
Packit Service f02b19
	gcry_create_nonce (iv, ivlen);
Packit Service f02b19
Packit Service f02b19
	/* And encode it into the string */
Packit Service f02b19
	hex = egg_hex_encode (iv, ivlen);
Packit Service f02b19
	g_return_val_if_fail (hex, NULL);
Packit Service f02b19
	dekinfo = g_strdup_printf ("DES-EDE3-CBC,%s", hex);
Packit Service f02b19
	g_free (hex);
Packit Service f02b19
	g_free (iv);
Packit Service f02b19
Packit Service f02b19
	g_hash_table_insert (headers, g_strdup ("DEK-Info"), (void*)dekinfo);
Packit Service f02b19
	g_hash_table_insert (headers, g_strdup ("Proc-Type"), g_strdup ("4,ENCRYPTED"));
Packit Service f02b19
Packit Service f02b19
	return dekinfo;
Packit Service f02b19
}