comparison libpurple/cipher.c @ 17008:34d9037a228c

RC4 support to libpurple's cipher.c. applied changes from 16cddf101af9bec7aa7546f67d791389bb82a8c5 through eb65d87cbe206ce460c3647f24e6cc06bb1e83fe Patch from Nathan Peterson to add RC4 support. applied changes from eb65d87cbe206ce460c3647f24e6cc06bb1e83fe through c27d5698b3cb75df5ec296031e29e46440ac2303 Add rc4_get_key_size.
author Jeffrey Connelly <jaconnel@calpoly.edu>
date Thu, 10 May 2007 02:58:35 +0000
parents 07cf49a0f404
children ba8de77ec9b8
comparison
equal deleted inserted replaced
16975:9ded461750a9 17008:34d9037a228c
1273 NULL, 1273 NULL,
1274 NULL 1274 NULL
1275 }; 1275 };
1276 1276
1277 /******************************************************************************* 1277 /*******************************************************************************
1278 * RC4
1279 ******************************************************************************/
1280
1281 struct RC4Context {
1282 guchar state[256];
1283 guchar x;
1284 guchar y;
1285 gint key_len;
1286 };
1287
1288 static void
1289 rc4_init(PurpleCipherContext *context, void *extra) {
1290 struct RC4Context *rc4_ctx;
1291 rc4_ctx = g_new0(struct RC4Context, 1);
1292 purple_cipher_context_set_data(context, rc4_ctx);
1293 purple_cipher_context_reset(context, extra);
1294 }
1295
1296
1297 static void
1298 rc4_reset(PurpleCipherContext *context, void *extra) {
1299 struct RC4Context *rc4_ctx;
1300 guint i;
1301
1302 rc4_ctx = purple_cipher_context_get_data(context);
1303
1304 g_return_if_fail(rc4_ctx);
1305
1306 for(i = 0; i < 256; i++)
1307 rc4_ctx->state[i] = i;
1308 rc4_ctx->x = 0;
1309 rc4_ctx->y = 0;
1310
1311 /* default is 5 bytes (40bit key) */
1312 rc4_ctx->key_len = 5;
1313
1314 }
1315
1316 static void
1317 rc4_uninit(PurpleCipherContext *context) {
1318 struct RC4Context *rc4_ctx;
1319
1320 rc4_ctx = purple_cipher_context_get_data(context);
1321 memset(rc4_ctx, 0, sizeof(rc4_ctx));
1322
1323 g_free(rc4_ctx);
1324 rc4_ctx = NULL;
1325 }
1326
1327
1328
1329 static void
1330 rc4_set_key (PurpleCipherContext *context, const guchar * key) {
1331 struct RC4Context *ctx;
1332 guchar *state;
1333 guchar temp_swap;
1334 guchar x, y;
1335 guint i;
1336
1337 ctx = purple_cipher_context_get_data(context);
1338
1339 x = 0;
1340 y = 0;
1341 state = &ctx->state[0];
1342 for(i = 0; i < 256; i++)
1343 {
1344 y = (key[x] + state[i] + y) % 256;
1345 temp_swap = state[i];
1346 state[i] = state[y];
1347 state[y] = temp_swap;
1348 x = (x + 1) % ctx->key_len;
1349 }
1350 }
1351
1352 static void
1353 rc4_set_opt(PurpleCipherContext *context, const gchar *name, void *value) {
1354 struct RC4Context *ctx;
1355
1356 ctx = purple_cipher_context_get_data(context);
1357
1358 if(!strcmp(name, "key_len")) {
1359 ctx->key_len = GPOINTER_TO_INT(value);
1360 }
1361 }
1362
1363 static size_t
1364 rc4_get_key_size (PurpleCipherContext *context)
1365 {
1366 struct RC4Context *ctx;
1367
1368 g_return_val_if_fail(context, -1);
1369
1370 ctx = purple_cipher_context_get_data(context);
1371
1372 g_return_val_if_fail(ctx, -1);
1373
1374 return ctx->key_len;
1375 }
1376
1377 static void *
1378 rc4_get_opt(PurpleCipherContext *context, const gchar *name) {
1379 struct RC4Context *ctx;
1380
1381 ctx = purple_cipher_context_get_data(context);
1382
1383 if(!strcmp(name, "key_len")) {
1384 return GINT_TO_POINTER(ctx->key_len);
1385 }
1386
1387 return NULL;
1388 }
1389
1390 static gint
1391 rc4_encrypt(PurpleCipherContext *context, const guchar data[],
1392 size_t len, guchar output[], size_t *outlen) {
1393 struct RC4Context *ctx;
1394 guchar temp_swap;
1395 guchar x, y, z;
1396 guchar *state;
1397 guint i;
1398
1399 ctx = purple_cipher_context_get_data(context);
1400
1401 x = ctx->x;
1402 y = ctx->y;
1403 state = &ctx->state[0];
1404
1405 for(i = 0; i < len; i++)
1406 {
1407 x = (x + 1) % 256;
1408 y = (state[x] + y) % 256;
1409 temp_swap = state[x];
1410 state[x] = state[y];
1411 state[y] = temp_swap;
1412 z = state[x] + (state[y]) % 256;
1413 output[i] = data[i] ^ state[z];
1414 }
1415 ctx->x = x;
1416 ctx->y = y;
1417 if(outlen)
1418 *outlen = len;
1419
1420 return 0;
1421 }
1422
1423 static PurpleCipherOps RC4Ops = {
1424 rc4_set_opt, /* Set Option */
1425 rc4_get_opt, /* Get Option */
1426 rc4_init, /* init */
1427 rc4_reset, /* reset */
1428 rc4_uninit, /* uninit */
1429 NULL, /* set iv */
1430 NULL, /* append */
1431 NULL, /* digest */
1432 rc4_encrypt, /* encrypt */
1433 NULL, /* decrypt */
1434 NULL, /* set salt */
1435 NULL, /* get salt size */
1436 rc4_set_key, /* set key */
1437 rc4_get_key_size/* get key size */
1438 };
1439
1440 /*******************************************************************************
1278 * Structs 1441 * Structs
1279 ******************************************************************************/ 1442 ******************************************************************************/
1280 struct _PurpleCipher { 1443 struct _PurpleCipher {
1281 gchar *name; 1444 gchar *name;
1282 PurpleCipherOps *ops; 1445 PurpleCipherOps *ops;
1466 1629
1467 purple_ciphers_register_cipher("md5", &MD5Ops); 1630 purple_ciphers_register_cipher("md5", &MD5Ops);
1468 purple_ciphers_register_cipher("sha1", &SHA1Ops); 1631 purple_ciphers_register_cipher("sha1", &SHA1Ops);
1469 purple_ciphers_register_cipher("md4", &MD4Ops); 1632 purple_ciphers_register_cipher("md4", &MD4Ops);
1470 purple_ciphers_register_cipher("des", &DESOps); 1633 purple_ciphers_register_cipher("des", &DESOps);
1634 purple_ciphers_register_cipher("rc4", &RC4Ops);
1471 } 1635 }
1472 1636
1473 void 1637 void
1474 purple_ciphers_uninit() { 1638 purple_ciphers_uninit() {
1475 PurpleCipher *cipher; 1639 PurpleCipher *cipher;