Mercurial > pidgin
comparison libpurple/cipher.c @ 16721:ca69d4253246
explicit merge of '92e787fa231318dd21ddc9dd68f17b636033b13e'
and 'ea739f0c09468a0ca1e1761b05a4d5a453f402ec'
author | Jeffrey Connelly <jaconnel@calpoly.edu> |
---|---|
date | Tue, 01 May 2007 03:11:38 +0000 |
parents | 07cf49a0f404 18d766d252f3 |
children | 8a7238fb7905 |
comparison
equal
deleted
inserted
replaced
16700:79bc35a19de5 | 16721:ca69d4253246 |
---|---|
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; |