4 * Purple is the legal property of its developers, whose names are too numerous
5 * to list here. Please refer to the COPYRIGHT file distributed with this
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
33 rc4_init(PurpleCipherContext
*context
, void *extra
) {
34 struct RC4Context
*rc4_ctx
;
35 rc4_ctx
= g_new0(struct RC4Context
, 1);
36 purple_cipher_context_set_data(context
, rc4_ctx
);
37 purple_cipher_context_reset(context
, extra
);
42 rc4_reset(PurpleCipherContext
*context
, void *extra
) {
43 struct RC4Context
*rc4_ctx
;
46 rc4_ctx
= purple_cipher_context_get_data(context
);
48 g_return_if_fail(rc4_ctx
);
50 for(i
= 0; i
< 256; i
++)
51 rc4_ctx
->state
[i
] = i
;
55 /* default is 5 bytes (40bit key) */
61 rc4_uninit(PurpleCipherContext
*context
) {
62 struct RC4Context
*rc4_ctx
;
64 rc4_ctx
= purple_cipher_context_get_data(context
);
65 memset(rc4_ctx
, 0, sizeof(*rc4_ctx
));
74 rc4_set_key (PurpleCipherContext
*context
, const guchar
* key
) {
75 struct RC4Context
*ctx
;
81 ctx
= purple_cipher_context_get_data(context
);
85 state
= &ctx
->state
[0];
86 for(i
= 0; i
< 256; i
++)
88 y
= (key
[x
] + state
[i
] + y
) % 256;
92 x
= (x
+ 1) % ctx
->key_len
;
97 rc4_set_opt(PurpleCipherContext
*context
, const gchar
*name
, void *value
) {
98 struct RC4Context
*ctx
;
100 ctx
= purple_cipher_context_get_data(context
);
102 if(purple_strequal(name
, "key_len")) {
103 ctx
->key_len
= GPOINTER_TO_INT(value
);
108 rc4_get_key_size (PurpleCipherContext
*context
)
110 struct RC4Context
*ctx
;
112 g_return_val_if_fail(context
, -1);
114 ctx
= purple_cipher_context_get_data(context
);
116 g_return_val_if_fail(ctx
, -1);
122 rc4_get_opt(PurpleCipherContext
*context
, const gchar
*name
) {
123 struct RC4Context
*ctx
;
125 ctx
= purple_cipher_context_get_data(context
);
127 if(purple_strequal(name
, "key_len")) {
128 return GINT_TO_POINTER(ctx
->key_len
);
135 rc4_encrypt(PurpleCipherContext
*context
, const guchar data
[],
136 size_t len
, guchar output
[], size_t *outlen
) {
137 struct RC4Context
*ctx
;
143 ctx
= purple_cipher_context_get_data(context
);
147 state
= &ctx
->state
[0];
149 for(i
= 0; i
< len
; i
++)
152 y
= (state
[x
] + y
) % 256;
153 temp_swap
= state
[x
];
155 state
[y
] = temp_swap
;
156 z
= state
[x
] + (state
[y
]) % 256;
157 output
[i
] = data
[i
] ^ state
[z
];
167 static PurpleCipherOps RC4Ops
= {
168 rc4_set_opt
, /* Set Option */
169 rc4_get_opt
, /* Get Option */
171 rc4_reset
, /* reset */
172 rc4_uninit
, /* uninit */
176 rc4_encrypt
, /* encrypt */
179 NULL
, /* get salt size */
180 rc4_set_key
, /* set key */
181 rc4_get_key_size
, /* get key size */
182 NULL
, /* set batch mode */
183 NULL
, /* get batch mode */
184 NULL
, /* get block size */
185 NULL
/* set key with len */
189 purple_rc4_cipher_get_ops(void) {