changeset 31216:1bdc5f464802

Moved rc4 to the ciphers sublibrary
author Gary Kramlich <grim@reaperworld.com>
date Mon, 14 Feb 2011 06:10:49 +0000
parents 521febcb717a
children 3af51303d45c
files libpurple/cipher.c libpurple/ciphers/Makefile.am libpurple/ciphers/rc4.c
diffstat 3 files changed, 185 insertions(+), 169 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/cipher.c	Mon Feb 14 06:05:29 2011 +0000
+++ b/libpurple/cipher.c	Mon Feb 14 06:10:49 2011 +0000
@@ -1224,174 +1224,6 @@
 };
 
 #endif /* GLIB_CHECK_VERSION(2,16,0) */
-
-/*******************************************************************************
- * RC4
- ******************************************************************************/
-
-struct RC4Context {
-  guchar state[256];
-  guchar x;
-  guchar y;
-  gint key_len;
-};
-
-static void
-rc4_init(PurpleCipherContext *context, void *extra) {
-	struct RC4Context *rc4_ctx;
-	rc4_ctx = g_new0(struct RC4Context, 1);
-	purple_cipher_context_set_data(context, rc4_ctx);
-	purple_cipher_context_reset(context, extra);
-}
-
-
-static void
-rc4_reset(PurpleCipherContext *context, void *extra) {
-	struct RC4Context *rc4_ctx;
-	guint i;
-
-	rc4_ctx = purple_cipher_context_get_data(context);
-
-	g_return_if_fail(rc4_ctx);
-
-	for(i = 0; i < 256; i++)
-		rc4_ctx->state[i] = i;
-	rc4_ctx->x = 0;
-	rc4_ctx->y = 0;
-
-	/* default is 5 bytes (40bit key) */
-	rc4_ctx->key_len = 5;
-
-}
-
-static void
-rc4_uninit(PurpleCipherContext *context) {
-	struct RC4Context *rc4_ctx;
-
-	rc4_ctx = purple_cipher_context_get_data(context);
-	memset(rc4_ctx, 0, sizeof(*rc4_ctx));
-
-	g_free(rc4_ctx);
-	rc4_ctx = NULL;
-}
-
-
-
-static void
-rc4_set_key (PurpleCipherContext *context, const guchar * key) {
-	struct RC4Context *ctx;
-	guchar *state;
-	guchar temp_swap;
-	guchar x, y;
-	guint i;
-
-	ctx = purple_cipher_context_get_data(context);
-
-	x = 0;
-	y = 0;
-	state = &ctx->state[0];
-	for(i = 0; i < 256; i++)
-	{
-		y = (key[x] + state[i] + y) % 256;
-		temp_swap = state[i];
-		state[i] = state[y];
-		state[y] = temp_swap;
-		x = (x + 1) % ctx->key_len;
-	}
-}
-
-static void
-rc4_set_opt(PurpleCipherContext *context, const gchar *name, void *value) {
-	struct RC4Context *ctx;
-
-	ctx = purple_cipher_context_get_data(context);
-
-	if(purple_strequal(name, "key_len")) {
-		ctx->key_len = GPOINTER_TO_INT(value);
-	}
-}
-
-static size_t
-rc4_get_key_size (PurpleCipherContext *context)
-{
-	struct RC4Context *ctx;
-
-	g_return_val_if_fail(context, -1);
-
-	ctx = purple_cipher_context_get_data(context);
-
-	g_return_val_if_fail(ctx, -1);
-
-	return ctx->key_len;
-}
-
-static void *
-rc4_get_opt(PurpleCipherContext *context, const gchar *name) {
-	struct RC4Context *ctx;
-
-	ctx = purple_cipher_context_get_data(context);
-
-	if(purple_strequal(name, "key_len")) {
-		return GINT_TO_POINTER(ctx->key_len);
-	}
-
-	return NULL;
-}
-
-static gint
-rc4_encrypt(PurpleCipherContext *context, const guchar data[],
-	    size_t len, guchar output[], size_t *outlen) {
-	struct RC4Context *ctx;
-	guchar temp_swap;
-	guchar x, y, z;
-	guchar *state;
-	guint i;
-
-	ctx = purple_cipher_context_get_data(context);
-
-	x = ctx->x;
-	y = ctx->y;
-	state = &ctx->state[0];
-
-	for(i = 0; i < len; i++)
-	{
-		x = (x + 1) % 256;
-		y = (state[x] + y) % 256;
-		temp_swap = state[x];
-		state[x] = state[y];
-		state[y] = temp_swap;
-		z = state[x] + (state[y]) % 256;
-		output[i] = data[i] ^ state[z];
-	}
-	ctx->x = x;
-	ctx->y = y;
-	if(outlen)
-		*outlen = len;
-
-	return 0;
-}
-
-static PurpleCipherOps RC4Ops = {
-	rc4_set_opt,   /* Set Option    */
-	rc4_get_opt,   /* Get Option    */
-	rc4_init,      /* init          */
-	rc4_reset,     /* reset         */
-	rc4_uninit,    /* uninit        */
-	NULL,          /* set iv        */
-	NULL,          /* append        */
-	NULL,          /* digest        */
-	rc4_encrypt,   /* encrypt       */
-	NULL,          /* decrypt       */
-	NULL,          /* set salt      */
-	NULL,          /* get salt size */
-	rc4_set_key,   /* set key       */
-	rc4_get_key_size, /* get key size  */
-	NULL,          /* set batch mode */
-	NULL,          /* get batch mode */
-	NULL,          /* get block size */
-	NULL           /* set key with len */
-};
-
 /*******************************************************************************
  * Structs
  ******************************************************************************/
@@ -1578,6 +1410,7 @@
 PurpleCipherOps *purple_hmac_cipher_get_ops();
 PurpleCipherOps *purple_md4_cipher_get_ops();
 PurpleCipherOps *purple_md5_cipher_get_ops();
+PurpleCipherOps *purple_rc4_cipher_get_ops();
 PurpleCipherOps *purple_sha1_cipher_get_ops();
 
 void
@@ -1602,7 +1435,7 @@
 	purple_ciphers_register_cipher("hmac", purple_hmac_cipher_get_ops());
 	purple_ciphers_register_cipher("des", &DESOps);
 	purple_ciphers_register_cipher("des3", &DES3Ops);
-	purple_ciphers_register_cipher("rc4", &RC4Ops);
+	purple_ciphers_register_cipher("rc4", purple_rc4_cipher_get_ops());
 }
 
 void
--- a/libpurple/ciphers/Makefile.am	Mon Feb 14 06:05:29 2011 +0000
+++ b/libpurple/ciphers/Makefile.am	Mon Feb 14 06:10:49 2011 +0000
@@ -4,6 +4,7 @@
 	hmac.c \
 	md4.c \
 	md5.c \
+	rc4.c \
 	sha1.c
 
 INCLUDES = -I$(top_srcdir)/libpurple
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/ciphers/rc4.c	Mon Feb 14 06:10:49 2011 +0000
@@ -0,0 +1,182 @@
+/*
+ * 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
+ */
+#include <cipher.h>
+#include <string.h>
+
+struct RC4Context {
+	guchar state[256];
+	guchar x;
+	guchar y;
+	gint key_len;
+};
+
+static void
+rc4_init(PurpleCipherContext *context, void *extra) {
+	struct RC4Context *rc4_ctx;
+	rc4_ctx = g_new0(struct RC4Context, 1);
+	purple_cipher_context_set_data(context, rc4_ctx);
+	purple_cipher_context_reset(context, extra);
+}
+
+
+static void
+rc4_reset(PurpleCipherContext *context, void *extra) {
+	struct RC4Context *rc4_ctx;
+	guint i;
+
+	rc4_ctx = purple_cipher_context_get_data(context);
+
+	g_return_if_fail(rc4_ctx);
+
+	for(i = 0; i < 256; i++)
+		rc4_ctx->state[i] = i;
+	rc4_ctx->x = 0;
+	rc4_ctx->y = 0;
+
+	/* default is 5 bytes (40bit key) */
+	rc4_ctx->key_len = 5;
+
+}
+
+static void
+rc4_uninit(PurpleCipherContext *context) {
+	struct RC4Context *rc4_ctx;
+
+	rc4_ctx = purple_cipher_context_get_data(context);
+	memset(rc4_ctx, 0, sizeof(*rc4_ctx));
+
+	g_free(rc4_ctx);
+	rc4_ctx = NULL;
+}
+
+
+
+static void
+rc4_set_key (PurpleCipherContext *context, const guchar * key) {
+	struct RC4Context *ctx;
+	guchar *state;
+	guchar temp_swap;
+	guchar x, y;
+	guint i;
+
+	ctx = purple_cipher_context_get_data(context);
+
+	x = 0;
+	y = 0;
+	state = &ctx->state[0];
+	for(i = 0; i < 256; i++)
+	{
+		y = (key[x] + state[i] + y) % 256;
+		temp_swap = state[i];
+		state[i] = state[y];
+		state[y] = temp_swap;
+		x = (x + 1) % ctx->key_len;
+	}
+}
+
+static void
+rc4_set_opt(PurpleCipherContext *context, const gchar *name, void *value) {
+	struct RC4Context *ctx;
+
+	ctx = purple_cipher_context_get_data(context);
+
+	if(purple_strequal(name, "key_len")) {
+		ctx->key_len = GPOINTER_TO_INT(value);
+	}
+}
+
+	static size_t
+rc4_get_key_size (PurpleCipherContext *context)
+{
+	struct RC4Context *ctx;
+
+	g_return_val_if_fail(context, -1);
+
+	ctx = purple_cipher_context_get_data(context);
+
+	g_return_val_if_fail(ctx, -1);
+
+	return ctx->key_len;
+}
+
+static void *
+rc4_get_opt(PurpleCipherContext *context, const gchar *name) {
+	struct RC4Context *ctx;
+
+	ctx = purple_cipher_context_get_data(context);
+
+	if(purple_strequal(name, "key_len")) {
+		return GINT_TO_POINTER(ctx->key_len);
+	}
+
+	return NULL;
+}
+
+static gint
+rc4_encrypt(PurpleCipherContext *context, const guchar data[],
+		size_t len, guchar output[], size_t *outlen) {
+	struct RC4Context *ctx;
+	guchar temp_swap;
+	guchar x, y, z;
+	guchar *state;
+	guint i;
+
+	ctx = purple_cipher_context_get_data(context);
+
+	x = ctx->x;
+	y = ctx->y;
+	state = &ctx->state[0];
+
+	for(i = 0; i < len; i++)
+	{
+		x = (x + 1) % 256;
+		y = (state[x] + y) % 256;
+		temp_swap = state[x];
+		state[x] = state[y];
+		state[y] = temp_swap;
+		z = state[x] + (state[y]) % 256;
+		output[i] = data[i] ^ state[z];
+	}
+	ctx->x = x;
+	ctx->y = y;
+	if(outlen)
+		*outlen = len;
+
+	return 0;
+}
+
+static PurpleCipherOps RC4Ops = {
+	.set_option = rc4_set_opt,
+	.get_option = rc4_get_opt,
+	.init = rc4_init,
+	.reset = rc4_reset,
+	.uninit = rc4_uninit,
+	.encrypt = rc4_encrypt,
+	.set_key = rc4_set_key,
+	.get_key_size = rc4_get_key_size,
+};
+
+PurpleCipherOps *
+purple_rc4_cipher_get_ops(void) {
+	return &RC4Ops;
+}
+