libpurple/ciphers/aescipher.c

changeset 38889
5f88ba22172b
parent 38888
8bcae3a0b165
parent 38431
71898cf4d20f
child 38894
bde4fb15df80
child 38897
6db89a0010ae
--- a/libpurple/ciphers/aescipher.c	Thu Jun 15 10:48:26 2017 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,725 +0,0 @@
-/*
- * purple
- *
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here.  Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- *
- * Written by Tomek Wasilczyk <twasilczyk@pidgin.im>
- */
-
-#include "internal.h"
-#include "glibcompat.h"
-
-#include "aescipher.h"
-#include "debug.h"
-#include "enums.h"
-
-#include <string.h>
-
-#if defined(HAVE_GNUTLS)
-#  define PURPLE_AES_USE_GNUTLS 1
-#  include <gnutls/gnutls.h>
-#  include <gnutls/crypto.h>
-#elif defined(HAVE_NSS)
-#  define PURPLE_AES_USE_NSS 1
-#  include <nss.h>
-#  include <pk11pub.h>
-#  include <prerror.h>
-#else
-#  warning "No GnuTLS or NSS support"
-#endif
-
-/* 128bit */
-#define PURPLE_AES_BLOCK_SIZE 16
-
-/******************************************************************************
- * Structs
- *****************************************************************************/
-#define PURPLE_AES_CIPHER_GET_PRIVATE(obj) \
-	(G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_AES_CIPHER, PurpleAESCipherPrivate))
-
-typedef struct {
-	guchar iv[PURPLE_AES_BLOCK_SIZE];
-	guchar key[32];
-	guint key_size;
-	gboolean failure;
-	PurpleCipherBatchMode batch_mode;
-} PurpleAESCipherPrivate;
-
-/******************************************************************************
- * Enums
- *****************************************************************************/
-enum {
-	PROP_NONE,
-	PROP_BATCH_MODE,
-	PROP_IV,
-	PROP_KEY,
-	PROP_LAST,
-};
-
-/*******************************************************************************
- * Globals
- ******************************************************************************/
-static GParamSpec *properties[PROP_LAST];
-
-/******************************************************************************
- * Cipher Stuff
- *****************************************************************************/
-
-typedef gboolean (*purple_aes_cipher_crypt_func)(
-	const guchar *input, guchar *output, size_t len,
-	guchar iv[PURPLE_AES_BLOCK_SIZE], guchar key[32], guint key_size,
-	PurpleCipherBatchMode batch_mode);
-
-static void
-purple_aes_cipher_reset(PurpleCipher *cipher)
-{
-	PurpleAESCipherPrivate *priv = PURPLE_AES_CIPHER_GET_PRIVATE(cipher);
-
-	g_return_if_fail(priv != NULL);
-
-	memset(priv->iv, 0, sizeof(priv->iv));
-	memset(priv->key, 0, sizeof(priv->key));
-	priv->key_size = 32; /* 256bit */
-	priv->failure = FALSE;
-}
-
-static void
-purple_aes_cipher_set_iv(PurpleCipher *cipher, guchar *iv, size_t len)
-{
-	PurpleAESCipherPrivate *priv = PURPLE_AES_CIPHER_GET_PRIVATE(cipher);
-
-	if ((len > 0 && iv == NULL) ||
-		(len != 0 && len != sizeof(priv->iv))) {
-		purple_debug_error("cipher-aes", "invalid IV length\n");
-		priv->failure = TRUE;
-		return;
-	}
-
-	if (len == 0)
-		memset(priv->iv, 0, sizeof(priv->iv));
-	else
-		memcpy(priv->iv, iv, len);
-
-	g_object_notify_by_pspec(G_OBJECT(cipher), properties[PROP_IV]);
-}
-
-static void
-purple_aes_cipher_set_key(PurpleCipher *cipher, const guchar *key, size_t len)
-{
-	PurpleAESCipherPrivate *priv = PURPLE_AES_CIPHER_GET_PRIVATE(cipher);
-
-	if ((len > 0 && key == NULL) ||
-		(len != 0 && len != 16 && len != 24 && len != 32)) {
-		purple_debug_error("cipher-aes", "invalid key length\n");
-		priv->failure = TRUE;
-		return;
-	}
-
-	priv->key_size = len;
-	memset(priv->key, 0, sizeof(priv->key));
-	if (len > 0)
-		memcpy(priv->key, key, len);
-
-	g_object_notify_by_pspec(G_OBJECT(cipher), properties[PROP_KEY]);
-}
-
-static guchar *
-purple_aes_cipher_pad_pkcs7(const guchar input[], size_t in_len, size_t *out_len)
-{
-	int padding_len, total_len;
-	guchar *padded;
-
-	g_return_val_if_fail(input != NULL, NULL);
-	g_return_val_if_fail(out_len != NULL, NULL);
-
-	padding_len = PURPLE_AES_BLOCK_SIZE - (in_len % PURPLE_AES_BLOCK_SIZE);
-	total_len = in_len + padding_len;
-	g_assert((total_len % PURPLE_AES_BLOCK_SIZE) == 0);
-
-	padded = g_new(guchar, total_len);
-	*out_len = total_len;
-
-	memcpy(padded, input, in_len);
-	memset(padded + in_len, padding_len, padding_len);
-
-	return padded;
-}
-
-static ssize_t
-purple_aes_cipher_unpad_pkcs7(guchar input[], size_t in_len)
-{
-	guchar padding_len, i;
-	size_t out_len;
-
-	g_return_val_if_fail(input != NULL, -1);
-	g_return_val_if_fail(in_len > 0, -1);
-
-	padding_len = input[in_len - 1];
-	if (padding_len == 0 || padding_len > PURPLE_AES_BLOCK_SIZE ||
-		padding_len > in_len) {
-		purple_debug_warning("cipher-aes",
-			"Invalid padding length: %d (total %" G_GSIZE_FORMAT ") - "
-			"most probably, the key was invalid\n",
-			padding_len, in_len);
-		return -1;
-	}
-
-	out_len = in_len - padding_len;
-	for (i = 0; i < padding_len; i++) {
-		if (input[out_len + i] != padding_len) {
-			purple_debug_warning("cipher-aes",
-				"Padding doesn't match at pos %d (found %02x, "
-				"expected %02x) - "
-				"most probably, the key was invalid\n",
-				i, input[out_len + i], padding_len);
-			return -1;
-		}
-	}
-
-	memset(input + out_len, 0, padding_len);
-	return out_len;
-}
-
-#ifdef PURPLE_AES_USE_GNUTLS
-
-static gnutls_cipher_hd_t
-purple_aes_cipher_gnutls_crypt_init(guchar iv[PURPLE_AES_BLOCK_SIZE], guchar key[32],
-	guint key_size)
-{
-	gnutls_cipher_hd_t handle;
-	gnutls_cipher_algorithm_t algorithm;
-	gnutls_datum_t key_info, iv_info;
-	int ret;
-
-	if (key_size == 16)
-		algorithm = GNUTLS_CIPHER_AES_128_CBC;
-	else if (key_size == 24)
-		algorithm = GNUTLS_CIPHER_AES_192_CBC;
-	else if (key_size == 32)
-		algorithm = GNUTLS_CIPHER_AES_256_CBC;
-	else
-		g_return_val_if_reached(NULL);
-
-	key_info.data = key;
-	key_info.size = key_size;
-
-	iv_info.data = iv;
-	iv_info.size = PURPLE_AES_BLOCK_SIZE;
-
-	ret = gnutls_cipher_init(&handle, algorithm, &key_info, &iv_info);
-	if (ret != 0) {
-		purple_debug_error("cipher-aes",
-			"gnutls_cipher_init failed: %d\n", ret);
-		return NULL;
-	}
-
-	return handle;
-}
-
-static gboolean
-purple_aes_cipher_gnutls_encrypt(const guchar *input, guchar *output, size_t len,
-	guchar iv[PURPLE_AES_BLOCK_SIZE], guchar key[32], guint key_size,
-	PurpleCipherBatchMode batch_mode)
-{
-	gnutls_cipher_hd_t handle;
-	int ret;
-
-	/* We have to simulate ECB mode, which is not supported by GnuTLS. */
-	if (batch_mode == PURPLE_CIPHER_BATCH_MODE_ECB) {
-		size_t i;
-		for (i = 0; i < len / PURPLE_AES_BLOCK_SIZE; i++) {
-			int offset = i * PURPLE_AES_BLOCK_SIZE;
-			guchar iv_local[PURPLE_AES_BLOCK_SIZE];
-			gboolean succ;
-
-			memcpy(iv_local, iv, sizeof(iv_local));
-			succ = purple_aes_cipher_gnutls_encrypt(
-				input + offset, output + offset,
-				PURPLE_AES_BLOCK_SIZE,
-				iv_local, key, key_size,
-				PURPLE_CIPHER_BATCH_MODE_CBC);
-			if (!succ)
-				return FALSE;
-		}
-		return TRUE;
-	}
-
-	handle = purple_aes_cipher_gnutls_crypt_init(iv, key, key_size);
-	if (handle == NULL)
-		return FALSE;
-
-	ret = gnutls_cipher_encrypt2(handle, (guchar *)input, len, output, len);
-	gnutls_cipher_deinit(handle);
-
-	if (ret != 0) {
-		purple_debug_error("cipher-aes",
-			"gnutls_cipher_encrypt2 failed: %d\n", ret);
-		return FALSE;
-	}
-
-	return TRUE;
-}
-
-static gboolean
-purple_aes_cipher_gnutls_decrypt(const guchar *input, guchar *output, size_t len,
-	guchar iv[PURPLE_AES_BLOCK_SIZE], guchar key[32], guint key_size,
-	PurpleCipherBatchMode batch_mode)
-{
-	gnutls_cipher_hd_t handle;
-	int ret;
-
-	/* We have to simulate ECB mode, which is not supported by GnuTLS. */
-	if (batch_mode == PURPLE_CIPHER_BATCH_MODE_ECB) {
-		size_t i;
-		for (i = 0; i < len / PURPLE_AES_BLOCK_SIZE; i++) {
-			int offset = i * PURPLE_AES_BLOCK_SIZE;
-			guchar iv_local[PURPLE_AES_BLOCK_SIZE];
-			gboolean succ;
-
-			memcpy(iv_local, iv, sizeof(iv_local));
-			succ = purple_aes_cipher_gnutls_decrypt(
-				input + offset, output + offset,
-				PURPLE_AES_BLOCK_SIZE,
-				iv_local, key, key_size,
-				PURPLE_CIPHER_BATCH_MODE_CBC);
-			if (!succ)
-				return FALSE;
-		}
-		return TRUE;
-	}
-
-	handle = purple_aes_cipher_gnutls_crypt_init(iv, key, key_size);
-	if (handle == NULL)
-		return FALSE;
-
-	ret = gnutls_cipher_decrypt2(handle, input, len, output, len);
-	gnutls_cipher_deinit(handle);
-
-	if (ret != 0) {
-		purple_debug_error("cipher-aes",
-			"gnutls_cipher_decrypt2 failed: %d\n", ret);
-		return FALSE;
-	}
-
-	return TRUE;
-}
-
-#elif defined(PURPLE_AES_USE_NSS)
-
-typedef struct {
-	PK11SlotInfo *slot;
-	PK11SymKey *sym_key;
-	SECItem *sec_param;
-	PK11Context *enc_context;
-} PurpleAESCipherNSSContext;
-
-static void
-purple_aes_cipher_nss_cleanup(PurpleAESCipherNSSContext *context)
-{
-	g_return_if_fail(context != NULL);
-
-	if (context->enc_context != NULL)
-		PK11_DestroyContext(context->enc_context, TRUE);
-	if (context->sec_param != NULL)
-		SECITEM_FreeItem(context->sec_param, TRUE);
-	if (context->sym_key != NULL)
-		PK11_FreeSymKey(context->sym_key);
-	if (context->slot != NULL)
-		PK11_FreeSlot(context->slot);
-
-	memset(context, 0, sizeof(PurpleAESCipherNSSContext));
-}
-
-static gboolean
-purple_aes_cipher_nss_crypt(const guchar *input, guchar *output, size_t len,
-	guchar iv[PURPLE_AES_BLOCK_SIZE], guchar key[32], guint key_size,
-	CK_ATTRIBUTE_TYPE operation, CK_MECHANISM_TYPE cipher_mech)
-{
-	PurpleAESCipherNSSContext context;
-	SECItem key_item, iv_item;
-	SECStatus ret;
-	int outlen = 0;
-	unsigned int outlen_tmp = 0;
-
-	memset(&context, 0, sizeof(PurpleAESCipherNSSContext));
-
-	if (NSS_NoDB_Init(NULL) != SECSuccess) {
-		purple_debug_error("cipher-aes",
-			"NSS_NoDB_Init failed: %d\n", PR_GetError());
-		return FALSE;
-	}
-
-	context.slot = PK11_GetBestSlot(cipher_mech, NULL);
-	if (context.slot == NULL) {
-		purple_debug_error("cipher-aes",
-			"PK11_GetBestSlot failed: %d\n", PR_GetError());
-		return FALSE;
-	}
-
-	key_item.type = siBuffer;
-	key_item.data = key;
-	key_item.len = key_size;
-	context.sym_key = PK11_ImportSymKey(context.slot, cipher_mech,
-		PK11_OriginUnwrap, CKA_ENCRYPT, &key_item, NULL);
-	if (context.sym_key == NULL) {
-		purple_debug_error("cipher-aes",
-			"PK11_ImportSymKey failed: %d\n", PR_GetError());
-		purple_aes_cipher_nss_cleanup(&context);
-		return FALSE;
-	}
-
-	iv_item.type = siBuffer;
-	iv_item.data = iv;
-	iv_item.len = PURPLE_AES_BLOCK_SIZE;
-	context.sec_param = PK11_ParamFromIV(cipher_mech, &iv_item);
-	if (context.sec_param == NULL) {
-		purple_debug_error("cipher-aes",
-			"PK11_ParamFromIV failed: %d\n", PR_GetError());
-		purple_aes_cipher_nss_cleanup(&context);
-		return FALSE;
-	}
-
-	context.enc_context = PK11_CreateContextBySymKey(cipher_mech, operation,
-		context.sym_key, context.sec_param);
-	if (context.enc_context == NULL) {
-		purple_debug_error("cipher-aes",
-			"PK11_CreateContextBySymKey failed: %d\n",
-				PR_GetError());
-		purple_aes_cipher_nss_cleanup(&context);
-		return FALSE;
-	}
-
-	ret = PK11_CipherOp(context.enc_context, output, &outlen, len,
-			(guchar *)input, len);
-	if (ret != SECSuccess) {
-		purple_debug_error("cipher-aes",
-			"PK11_CipherOp failed: %d\n", PR_GetError());
-		purple_aes_cipher_nss_cleanup(&context);
-		return FALSE;
-	}
-
-	ret = PK11_DigestFinal(context.enc_context, output + outlen, &outlen_tmp,
-		len - outlen);
-	if (ret != SECSuccess) {
-		purple_debug_error("cipher-aes",
-			"PK11_DigestFinal failed: %d\n", PR_GetError());
-		purple_aes_cipher_nss_cleanup(&context);
-		return FALSE;
-	}
-
-	purple_aes_cipher_nss_cleanup(&context);
-
-	outlen += outlen_tmp;
-	if (outlen != (int)len) {
-		purple_debug_error("cipher-aes",
-			"resulting length doesn't match: %d (expected: %"
-			G_GSIZE_FORMAT ")\n", outlen, len);
-		return FALSE;
-	}
-
-	return TRUE;
-}
-
-static CK_MECHANISM_TYPE
-purple_aes_cipher_nss_batch_mode(PurpleCipherBatchMode batch_mode)
-{
-	switch (batch_mode) {
-		case PURPLE_CIPHER_BATCH_MODE_CBC:
-			return CKM_AES_CBC;
-		case PURPLE_CIPHER_BATCH_MODE_ECB:
-			return CKM_AES_ECB;
-	}
-
-	return CKM_AES_CBC;
-}
-
-static gboolean
-purple_aes_cipher_nss_encrypt(const guchar *input, guchar *output, size_t len,
-	guchar iv[PURPLE_AES_BLOCK_SIZE], guchar key[32], guint key_size,
-	PurpleCipherBatchMode batch_mode)
-{
-	return purple_aes_cipher_nss_crypt(input, output, len, iv, key, key_size,
-		CKA_ENCRYPT, purple_aes_cipher_nss_batch_mode(batch_mode));
-}
-
-static gboolean
-purple_aes_cipher_nss_decrypt(const guchar *input, guchar *output, size_t len,
-	guchar iv[PURPLE_AES_BLOCK_SIZE], guchar key[32], guint key_size,
-	PurpleCipherBatchMode batch_mode)
-{
-	return purple_aes_cipher_nss_crypt(input, output, len, iv, key, key_size,
-		CKA_DECRYPT, purple_aes_cipher_nss_batch_mode(batch_mode));
-}
-
-#endif /* PURPLE_AES_USE_NSS */
-
-static ssize_t
-purple_aes_cipher_encrypt(PurpleCipher *cipher, const guchar input[],
-	size_t in_len, guchar output[], size_t out_size)
-{
-	PurpleAESCipherPrivate *priv = PURPLE_AES_CIPHER_GET_PRIVATE(cipher);
-	purple_aes_cipher_crypt_func encrypt_func;
-	guchar *input_padded;
-	size_t out_len = 0;
-	gboolean succ;
-
-	if (priv->failure)
-		return -1;
-
-	input_padded = purple_aes_cipher_pad_pkcs7(input, in_len, &out_len);
-
-	if (out_len > out_size) {
-		purple_debug_error("cipher-aes", "Output buffer too small (%"
-			G_GSIZE_FORMAT " > %" G_GSIZE_FORMAT ")",
-			out_len, out_size);
-		memset(input_padded, 0, out_len);
-		g_free(input_padded);
-		return -1;
-	}
-
-#if defined(PURPLE_AES_USE_GNUTLS)
-	encrypt_func = purple_aes_cipher_gnutls_encrypt;
-#elif defined(PURPLE_AES_USE_NSS)
-	encrypt_func = purple_aes_cipher_nss_encrypt;
-#else
-	purple_debug_error("cipher-aes", "No matching encrypt_func\n");
-	return -1;
-#endif
-
-	succ = encrypt_func(input_padded, output, out_len, priv->iv,
-		priv->key, priv->key_size, priv->batch_mode);
-
-	memset(input_padded, 0, out_len);
-	g_free(input_padded);
-
-	if (!succ) {
-		memset(output, 0, out_len);
-		return -1;
-	}
-
-	return out_len;
-}
-
-static ssize_t
-purple_aes_cipher_decrypt(PurpleCipher *cipher, const guchar input[],
-	size_t in_len, guchar output[], size_t out_size)
-{
-	PurpleAESCipherPrivate *priv = PURPLE_AES_CIPHER_GET_PRIVATE(cipher);
-	purple_aes_cipher_crypt_func decrypt_func;
-	gboolean succ;
-	ssize_t out_len;
-
-	if (priv->failure)
-		return -1;
-
-	if (in_len > out_size) {
-		purple_debug_error("cipher-aes", "Output buffer too small\n");
-		return -1;
-	}
-
-	if ((in_len % PURPLE_AES_BLOCK_SIZE) != 0 || in_len == 0) {
-		purple_debug_error("cipher-aes", "Malformed data\n");
-		return -1;
-	}
-
-#if defined(PURPLE_AES_USE_GNUTLS)
-	decrypt_func = purple_aes_cipher_gnutls_decrypt;
-#elif defined(PURPLE_AES_USE_NSS)
-	decrypt_func = purple_aes_cipher_nss_decrypt;
-#else
-	purple_debug_error("cipher-aes", "No matching decrypt_func\n");
-	return -1;
-#endif
-
-	succ = decrypt_func(input, output, in_len, priv->iv, priv->key,
-		priv->key_size, priv->batch_mode);
-
-	if (!succ) {
-		memset(output, 0, in_len);
-		return -1;
-	}
-
-	out_len = purple_aes_cipher_unpad_pkcs7(output, in_len);
-	if (out_len < 0) {
-		memset(output, 0, in_len);
-		return -1;
-	}
-
-	return out_len;
-}
-
-static size_t
-purple_aes_cipher_get_key_size(PurpleCipher *cipher)
-{
-	PurpleAESCipherPrivate *priv = PURPLE_AES_CIPHER_GET_PRIVATE(cipher);
-
-	return priv->key_size;
-}
-
-static void
-purple_aes_cipher_set_batch_mode(PurpleCipher *cipher,
-	PurpleCipherBatchMode mode)
-{
-	PurpleAESCipherPrivate *priv = PURPLE_AES_CIPHER_GET_PRIVATE(cipher);
-
-	if (mode != PURPLE_CIPHER_BATCH_MODE_CBC &&
-		mode != PURPLE_CIPHER_BATCH_MODE_ECB)
-	{
-		purple_debug_error("cipher-aes", "unsupported batch mode\n");
-		priv->failure = TRUE;
-	}
-
-	priv->batch_mode = mode;
-
-	g_object_notify_by_pspec(G_OBJECT(cipher), properties[PROP_BATCH_MODE]);
-}
-
-static PurpleCipherBatchMode
-purple_aes_cipher_get_batch_mode(PurpleCipher *cipher)
-{
-	PurpleAESCipherPrivate *priv = PURPLE_AES_CIPHER_GET_PRIVATE(cipher);
-
-	return priv->batch_mode;
-}
-
-static size_t
-purple_aes_cipher_get_block_size(PurpleCipher *cipher)
-{
-	return PURPLE_AES_BLOCK_SIZE;
-}
-
-/******************************************************************************
- * Object Stuff
- *****************************************************************************/
-static void
-purple_aes_cipher_get_property(GObject *obj, guint param_id, GValue *value,
-								GParamSpec *pspec)
-{
-	PurpleCipher *cipher = PURPLE_CIPHER(obj);
-
-	switch(param_id) {
-		case PROP_BATCH_MODE:
-			g_value_set_enum(value,
-							 purple_cipher_get_batch_mode(cipher));
-			break;
-		default:
-			G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
-			break;
-	}
-}
-
-static void
-purple_aes_cipher_set_property(GObject *obj, guint param_id,
-								const GValue *value, GParamSpec *pspec)
-{
-	PurpleCipher *cipher = PURPLE_CIPHER(obj);
-
-	switch(param_id) {
-		case PROP_BATCH_MODE:
-			purple_cipher_set_batch_mode(cipher,
-										 g_value_get_enum(value));
-			break;
-		case PROP_IV:
-			{
-				guchar *iv = (guchar *)g_value_get_string(value);
-				purple_cipher_set_iv(cipher, iv, strlen((gchar*)iv));
-			}
-			break;
-		case PROP_KEY:
-			purple_cipher_set_key(cipher, (guchar *)g_value_get_string(value),
-				purple_aes_cipher_get_key_size(cipher));
-			break;
-		default:
-			G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
-			break;
-	}
-}
-
-static void
-purple_aes_cipher_class_init(PurpleAESCipherClass *klass) {
-	GObjectClass *obj_class = G_OBJECT_CLASS(klass);
-	PurpleCipherClass *cipher_class = PURPLE_CIPHER_CLASS(klass);
-
-	obj_class->get_property = purple_aes_cipher_get_property;
-	obj_class->set_property = purple_aes_cipher_set_property;
-
-	cipher_class->reset = purple_aes_cipher_reset;
-	cipher_class->set_iv = purple_aes_cipher_set_iv;
-	cipher_class->encrypt = purple_aes_cipher_encrypt;
-	cipher_class->decrypt = purple_aes_cipher_decrypt;
-	cipher_class->set_key = purple_aes_cipher_set_key;
-	cipher_class->get_key_size = purple_aes_cipher_get_key_size;
-	cipher_class->set_batch_mode = purple_aes_cipher_set_batch_mode;
-	cipher_class->get_batch_mode = purple_aes_cipher_get_batch_mode;
-	cipher_class->get_block_size = purple_aes_cipher_get_block_size;
-
-	g_type_class_add_private(klass, sizeof(PurpleAESCipherPrivate));
-
-	properties[PROP_BATCH_MODE] = g_param_spec_enum("batch-mode",
-		"batch-mode", "batch-mode", PURPLE_TYPE_CIPHER_BATCH_MODE,
-		PURPLE_CIPHER_BATCH_MODE_CBC,
-		G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
-
-	properties[PROP_IV] = g_param_spec_string("iv", "iv", "iv", NULL,
-								G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS);
-
-	properties[PROP_KEY] = g_param_spec_string("key", "key", "key", NULL,
-								G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS);
-
-	g_object_class_install_properties(obj_class, PROP_LAST, properties);
-}
-
-static void
-purple_aes_cipher_init(PurpleCipher *cipher) {
-	purple_cipher_reset(cipher);
-}
-
-/******************************************************************************
- * API
- *****************************************************************************/
-GType
-purple_aes_cipher_get_type(void) {
-	static GType type = 0;
-
-	if(type == 0) {
-		static const GTypeInfo info = {
-			sizeof(PurpleAESCipherClass),
-			NULL,
-			NULL,
-			(GClassInitFunc)purple_aes_cipher_class_init,
-			NULL,
-			NULL,
-			sizeof(PurpleAESCipher),
-			0,
-			(GInstanceInitFunc)purple_aes_cipher_init,
-			NULL
-		};
-
-		type = g_type_register_static(PURPLE_TYPE_CIPHER,
-									  "PurpleAESCipher",
-									  &info, 0);
-	}
-
-	return type;
-}
-
-PurpleCipher *
-purple_aes_cipher_new(void) {
-	return g_object_new(PURPLE_TYPE_AES_CIPHER, NULL);
-}

mercurial