Mercurial > pidgin
comparison libpurple/cipher.c @ 17270:fa6eaf499f22
Remove duplicate RC4 from cipher.c (third try; still getting used to MTN)
author | Jeffrey Connelly <jaconnel@calpoly.edu> |
---|---|
date | Fri, 01 Jun 2007 04:08:21 +0000 |
parents | 8a7238fb7905 |
children | cdfa6cd0b70d |
comparison
equal
deleted
inserted
replaced
17265:253155592cd5 | 17270:fa6eaf499f22 |
---|---|
1442 NULL, | 1442 NULL, |
1443 NULL | 1443 NULL |
1444 }; | 1444 }; |
1445 | 1445 |
1446 /******************************************************************************* | 1446 /******************************************************************************* |
1447 * RC4 | |
1448 ******************************************************************************/ | |
1449 | |
1450 struct RC4Context { | |
1451 guchar state[256]; | |
1452 guchar x; | |
1453 guchar y; | |
1454 gint key_len; | |
1455 }; | |
1456 | |
1457 static void | |
1458 rc4_init(PurpleCipherContext *context, void *extra) { | |
1459 struct RC4Context *rc4_ctx; | |
1460 rc4_ctx = g_new0(struct RC4Context, 1); | |
1461 purple_cipher_context_set_data(context, rc4_ctx); | |
1462 purple_cipher_context_reset(context, extra); | |
1463 } | |
1464 | |
1465 | |
1466 static void | |
1467 rc4_reset(PurpleCipherContext *context, void *extra) { | |
1468 struct RC4Context *rc4_ctx; | |
1469 guint i; | |
1470 | |
1471 rc4_ctx = purple_cipher_context_get_data(context); | |
1472 | |
1473 g_return_if_fail(rc4_ctx); | |
1474 | |
1475 for(i = 0; i < 256; i++) | |
1476 rc4_ctx->state[i] = i; | |
1477 rc4_ctx->x = 0; | |
1478 rc4_ctx->y = 0; | |
1479 | |
1480 /* default is 5 bytes (40bit key) */ | |
1481 rc4_ctx->key_len = 5; | |
1482 | |
1483 } | |
1484 | |
1485 static void | |
1486 rc4_uninit(PurpleCipherContext *context) { | |
1487 struct RC4Context *rc4_ctx; | |
1488 | |
1489 rc4_ctx = purple_cipher_context_get_data(context); | |
1490 memset(rc4_ctx, 0, sizeof(rc4_ctx)); | |
1491 | |
1492 g_free(rc4_ctx); | |
1493 rc4_ctx = NULL; | |
1494 } | |
1495 | |
1496 | |
1497 | |
1498 static void | |
1499 rc4_set_key (PurpleCipherContext *context, const guchar * key) { | |
1500 struct RC4Context *ctx; | |
1501 guchar *state; | |
1502 guchar temp_swap; | |
1503 guchar x, y; | |
1504 guint i; | |
1505 | |
1506 ctx = purple_cipher_context_get_data(context); | |
1507 | |
1508 x = 0; | |
1509 y = 0; | |
1510 state = &ctx->state[0]; | |
1511 for(i = 0; i < 256; i++) | |
1512 { | |
1513 y = (key[x] + state[i] + y) % 256; | |
1514 temp_swap = state[i]; | |
1515 state[i] = state[y]; | |
1516 state[y] = temp_swap; | |
1517 x = (x + 1) % ctx->key_len; | |
1518 } | |
1519 } | |
1520 | |
1521 static void | |
1522 rc4_set_opt(PurpleCipherContext *context, const gchar *name, void *value) { | |
1523 struct RC4Context *ctx; | |
1524 | |
1525 ctx = purple_cipher_context_get_data(context); | |
1526 | |
1527 if(!strcmp(name, "key_len")) { | |
1528 ctx->key_len = GPOINTER_TO_INT(value); | |
1529 } | |
1530 } | |
1531 | |
1532 static size_t | |
1533 rc4_get_key_size (PurpleCipherContext *context) | |
1534 { | |
1535 struct RC4Context *ctx; | |
1536 | |
1537 g_return_val_if_fail(context, -1); | |
1538 | |
1539 ctx = purple_cipher_context_get_data(context); | |
1540 | |
1541 g_return_val_if_fail(ctx, -1); | |
1542 | |
1543 return ctx->key_len; | |
1544 } | |
1545 | |
1546 static void * | |
1547 rc4_get_opt(PurpleCipherContext *context, const gchar *name) { | |
1548 struct RC4Context *ctx; | |
1549 | |
1550 ctx = purple_cipher_context_get_data(context); | |
1551 | |
1552 if(!strcmp(name, "key_len")) { | |
1553 return GINT_TO_POINTER(ctx->key_len); | |
1554 } | |
1555 | |
1556 return NULL; | |
1557 } | |
1558 | |
1559 static gint | |
1560 rc4_encrypt(PurpleCipherContext *context, const guchar data[], | |
1561 size_t len, guchar output[], size_t *outlen) { | |
1562 struct RC4Context *ctx; | |
1563 guchar temp_swap; | |
1564 guchar x, y, z; | |
1565 guchar *state; | |
1566 guint i; | |
1567 | |
1568 ctx = purple_cipher_context_get_data(context); | |
1569 | |
1570 x = ctx->x; | |
1571 y = ctx->y; | |
1572 state = &ctx->state[0]; | |
1573 | |
1574 for(i = 0; i < len; i++) | |
1575 { | |
1576 x = (x + 1) % 256; | |
1577 y = (state[x] + y) % 256; | |
1578 temp_swap = state[x]; | |
1579 state[x] = state[y]; | |
1580 state[y] = temp_swap; | |
1581 z = state[x] + (state[y]) % 256; | |
1582 output[i] = data[i] ^ state[z]; | |
1583 } | |
1584 ctx->x = x; | |
1585 ctx->y = y; | |
1586 if(outlen) | |
1587 *outlen = len; | |
1588 | |
1589 return 0; | |
1590 } | |
1591 | |
1592 static PurpleCipherOps RC4Ops = { | |
1593 rc4_set_opt, /* Set Option */ | |
1594 rc4_get_opt, /* Get Option */ | |
1595 rc4_init, /* init */ | |
1596 rc4_reset, /* reset */ | |
1597 rc4_uninit, /* uninit */ | |
1598 NULL, /* set iv */ | |
1599 NULL, /* append */ | |
1600 NULL, /* digest */ | |
1601 rc4_encrypt, /* encrypt */ | |
1602 NULL, /* decrypt */ | |
1603 NULL, /* set salt */ | |
1604 NULL, /* get salt size */ | |
1605 rc4_set_key, /* set key */ | |
1606 rc4_get_key_size/* get key size */ | |
1607 }; | |
1608 | |
1609 /******************************************************************************* | |
1610 * Structs | 1447 * Structs |
1611 ******************************************************************************/ | 1448 ******************************************************************************/ |
1612 struct _PurpleCipher { | 1449 struct _PurpleCipher { |
1613 gchar *name; | 1450 gchar *name; |
1614 PurpleCipherOps *ops; | 1451 PurpleCipherOps *ops; |