comparison libpurple/cipher.c @ 21909:6648cfa72842

merge of '72df99671f84834d934f83b25ce492f289d77063' and 'c00604416a0d01f2fbf75b5cc6b6d4f9371e7a67'
author Sadrul Habib Chowdhury <imadil@gmail.com>
date Fri, 21 Dec 2007 09:33:45 +0000
parents f786e478e08b
children 76e0463db3aa
comparison
equal deleted inserted replaced
21897:a64a7bc69f42 21909:6648cfa72842
62 #include "value.h" 62 #include "value.h"
63 63
64 /******************************************************************************* 64 /*******************************************************************************
65 * MD5 65 * MD5
66 ******************************************************************************/ 66 ******************************************************************************/
67 #define MD5_HMAC_BLOCK_SIZE 64
68
67 struct MD5Context { 69 struct MD5Context {
68 guint32 total[2]; 70 guint32 total[2];
69 guint32 state[4]; 71 guint32 state[4];
70 guchar buffer[64]; 72 guchar buffer[64];
71 }; 73 };
323 *out_len = 16; 325 *out_len = 16;
324 326
325 return TRUE; 327 return TRUE;
326 } 328 }
327 329
330 static size_t
331 md5_get_block_size(PurpleCipherContext *context)
332 {
333 /* This does not change (in this case) */
334 return MD5_HMAC_BLOCK_SIZE;
335 }
336
328 static PurpleCipherOps MD5Ops = { 337 static PurpleCipherOps MD5Ops = {
329 NULL, /* Set option */ 338 NULL, /* Set option */
330 NULL, /* Get option */ 339 NULL, /* Get option */
331 md5_init, /* init */ 340 md5_init, /* init */
332 md5_reset, /* reset */ 341 md5_reset, /* reset */
338 NULL, /* decrypt */ 347 NULL, /* decrypt */
339 NULL, /* set salt */ 348 NULL, /* set salt */
340 NULL, /* get salt size */ 349 NULL, /* get salt size */
341 NULL, /* set key */ 350 NULL, /* set key */
342 NULL, /* get key size */ 351 NULL, /* get key size */
343 352 NULL, /* set batch mode */
344 /* padding */ 353 NULL, /* get batch mode */
345 NULL, 354 md5_get_block_size, /* get block size */
346 NULL, 355 NULL /* set key with len */
347 NULL,
348 NULL
349 }; 356 };
350 357
351 /******************************************************************************* 358 /*******************************************************************************
352 * MD4 359 * MD4
353 ******************************************************************************/ 360 ******************************************************************************/
578 585
579 g_free(md4_context); 586 g_free(md4_context);
580 md4_context = NULL; 587 md4_context = NULL;
581 } 588 }
582 589
590 static size_t
591 md4_get_block_size(PurpleCipherContext *context)
592 {
593 /* This does not change (in this case) */
594 return MD4_HMAC_BLOCK_SIZE;
595 }
596
583 static PurpleCipherOps MD4Ops = { 597 static PurpleCipherOps MD4Ops = {
584 NULL, /* Set option */ 598 NULL, /* Set option */
585 NULL, /* Get option */ 599 NULL, /* Get option */
586 md4_init, /* init */ 600 md4_init, /* init */
587 md4_reset, /* reset */ 601 md4_reset, /* reset */
593 NULL, /* decrypt */ 607 NULL, /* decrypt */
594 NULL, /* set salt */ 608 NULL, /* set salt */
595 NULL, /* get salt size */ 609 NULL, /* get salt size */
596 NULL, /* set key */ 610 NULL, /* set key */
597 NULL, /* get key size */ 611 NULL, /* get key size */
598 612 NULL, /* set batch mode */
599 /* padding */ 613 NULL, /* get batch mode */
600 NULL, 614 md4_get_block_size, /* get block size */
601 NULL, 615 NULL /* set key with len */
602 NULL, 616 };
603 NULL 617
618 /*******************************************************************************
619 * HMAC
620 ******************************************************************************/
621
622 struct HMAC_Context {
623 PurpleCipherContext *hash;
624 char *name;
625 int blocksize;
626 guchar *opad;
627 };
628
629 static void
630 hmac_init(PurpleCipherContext *context, gpointer extra)
631 {
632 struct HMAC_Context *hctx;
633 hctx = g_new0(struct HMAC_Context, 1);
634 purple_cipher_context_set_data(context, hctx);
635 purple_cipher_context_reset(context, extra);
636 }
637
638 static void
639 hmac_reset(PurpleCipherContext *context, gpointer extra)
640 {
641 struct HMAC_Context *hctx;
642
643 hctx = purple_cipher_context_get_data(context);
644
645 g_free(hctx->name);
646 hctx->name = NULL;
647 if (hctx->hash)
648 purple_cipher_context_destroy(hctx->hash);
649 hctx->hash = NULL;
650 hctx->blocksize = 0;
651 g_free(hctx->opad);
652 hctx->opad = NULL;
653 }
654
655 static void
656 hmac_set_opt(PurpleCipherContext *context, const gchar *name, void *value)
657 {
658 struct HMAC_Context *hctx;
659
660 hctx = purple_cipher_context_get_data(context);
661
662 if (!strcmp(name, "hash")) {
663 g_free(hctx->name);
664 if (hctx->hash)
665 purple_cipher_context_destroy(hctx->hash);
666 hctx->name = g_strdup((char*)value);
667 hctx->hash = purple_cipher_context_new_by_name((char *)value, NULL);
668 hctx->blocksize = purple_cipher_context_get_block_size(hctx->hash);
669 }
670 }
671
672 static void *
673 hmac_get_opt(PurpleCipherContext *context, const gchar *name)
674 {
675 struct HMAC_Context *hctx;
676
677 hctx = purple_cipher_context_get_data(context);
678
679 if (!strcmp(name, "hash")) {
680 return hctx->name;
681 }
682
683 return NULL;
684 }
685
686 static void
687 hmac_append(PurpleCipherContext *context, const guchar *data, size_t len)
688 {
689 struct HMAC_Context *hctx = purple_cipher_context_get_data(context);
690
691 g_return_if_fail(hctx->hash != NULL);
692
693 purple_cipher_context_append(hctx->hash, data, len);
694 }
695
696 static gboolean
697 hmac_digest(PurpleCipherContext *context, size_t in_len, guchar *out, size_t *out_len)
698 {
699 struct HMAC_Context *hctx = purple_cipher_context_get_data(context);
700 PurpleCipherContext *hash = hctx->hash;
701 guchar *inner_hash;
702 size_t hash_len;
703 gboolean result;
704
705 g_return_val_if_fail(hash != NULL, FALSE);
706
707 inner_hash = g_malloc(100); /* TODO: Should be enough for now... */
708 result = purple_cipher_context_digest(hash, 100, inner_hash, &hash_len);
709
710 purple_cipher_context_reset(hash, NULL);
711
712 purple_cipher_context_append(hash, hctx->opad, hctx->blocksize);
713 purple_cipher_context_append(hash, inner_hash, hash_len);
714
715 g_free(inner_hash);
716
717 result = result && purple_cipher_context_digest(hash, in_len, out, out_len);
718
719 return result;
720 }
721
722 static void
723 hmac_uninit(PurpleCipherContext *context)
724 {
725 struct HMAC_Context *hctx;
726
727 purple_cipher_context_reset(context, NULL);
728
729 hctx = purple_cipher_context_get_data(context);
730
731 g_free(hctx);
732 }
733
734 static void
735 hmac_set_key_with_len(PurpleCipherContext *context, const guchar * key, size_t key_len)
736 {
737 struct HMAC_Context *hctx = purple_cipher_context_get_data(context);
738 int blocksize, i;
739 guchar *ipad;
740 guchar *full_key;
741
742 g_return_if_fail(hctx->hash != NULL);
743
744 g_free(hctx->opad);
745
746 blocksize = hctx->blocksize;
747 ipad = g_malloc(blocksize);
748 hctx->opad = g_malloc(blocksize);
749
750 if (key_len > blocksize) {
751 purple_cipher_context_reset(hctx->hash, NULL);
752 purple_cipher_context_append(hctx->hash, key, key_len);
753 full_key = g_malloc(100); /* TODO: Should be enough for now... */
754 purple_cipher_context_digest(hctx->hash, 100, full_key, &key_len);
755 } else
756 full_key = g_memdup(key, key_len);
757
758 if (key_len < blocksize) {
759 full_key = g_realloc(full_key, blocksize);
760 memset(full_key + key_len, 0, blocksize - key_len);
761 }
762
763 for(i = 0; i < blocksize; i++) {
764 ipad[i] = 0x36 ^ full_key[i];
765 hctx->opad[i] = 0x5c ^ full_key[i];
766 }
767
768 g_free(full_key);
769
770 purple_cipher_context_reset(hctx->hash, NULL);
771 purple_cipher_context_append(hctx->hash, ipad, blocksize);
772 g_free(ipad);
773 }
774
775 static void
776 hmac_set_key(PurpleCipherContext *context, const guchar * key)
777 {
778 hmac_set_key_with_len(context, key, strlen(key));
779 }
780
781 static size_t
782 hmac_get_block_size(PurpleCipherContext *context)
783 {
784 struct HMAC_Context *hctx = purple_cipher_context_get_data(context);
785
786 return hctx->blocksize;
787 }
788
789 static PurpleCipherOps HMACOps = {
790 hmac_set_opt, /* Set option */
791 hmac_get_opt, /* Get option */
792 hmac_init, /* init */
793 hmac_reset, /* reset */
794 hmac_uninit, /* uninit */
795 NULL, /* set iv */
796 hmac_append, /* append */
797 hmac_digest, /* digest */
798 NULL, /* encrypt */
799 NULL, /* decrypt */
800 NULL, /* set salt */
801 NULL, /* get salt size */
802 hmac_set_key, /* set key */
803 NULL, /* get key size */
804 NULL, /* set batch mode */
805 NULL, /* get batch mode */
806 hmac_get_block_size, /* get block size */
807 hmac_set_key_with_len /* set key with len */
604 }; 808 };
605 809
606 /****************************************************************************** 810 /******************************************************************************
607 * DES 811 * DES
608 *****************************************************************************/ 812 *****************************************************************************/
984 0); 1188 0);
985 } 1189 }
986 return 0; 1190 return 0;
987 } 1191 }
988 1192
1193 static gint
1194 des_decrypt(PurpleCipherContext *context, const guchar data[],
1195 size_t len, guchar output[], size_t *outlen) {
1196 int offset = 0;
1197 int i = 0;
1198 int tmp;
1199 guint8 buf[8] = {0,0,0,0,0,0,0,0};
1200 while(offset+8<=len) {
1201 des_ecb_crypt(purple_cipher_context_get_data(context),
1202 data+offset,
1203 output+offset,
1204 1);
1205 offset+=8;
1206 }
1207 *outlen = len;
1208 if(offset<len) {
1209 *outlen += len - offset;
1210 tmp = offset;
1211 while(tmp<len) {
1212 buf[i++] = data[tmp];
1213 tmp++;
1214 }
1215 des_ecb_crypt(purple_cipher_context_get_data(context),
1216 buf,
1217 output+offset,
1218 1);
1219 }
1220 return 0;
1221 }
1222
989 static void 1223 static void
990 des_init(PurpleCipherContext *context, gpointer extra) { 1224 des_init(PurpleCipherContext *context, gpointer extra) {
991 struct _des_ctx *mctx; 1225 struct _des_ctx *mctx;
992 mctx = g_new0(struct _des_ctx, 1); 1226 mctx = g_new0(struct _des_ctx, 1);
993 purple_cipher_context_set_data(context, mctx); 1227 purple_cipher_context_set_data(context, mctx);
1003 g_free(des_context); 1237 g_free(des_context);
1004 des_context = NULL; 1238 des_context = NULL;
1005 } 1239 }
1006 1240
1007 static PurpleCipherOps DESOps = { 1241 static PurpleCipherOps DESOps = {
1008 NULL, /* Set option */ 1242 NULL, /* Set option */
1009 NULL, /* Get option */ 1243 NULL, /* Get option */
1010 des_init, /* init */ 1244 des_init, /* init */
1245 NULL, /* reset */
1246 des_uninit, /* uninit */
1247 NULL, /* set iv */
1248 NULL, /* append */
1249 NULL, /* digest */
1250 des_encrypt, /* encrypt */
1251 des_decrypt, /* decrypt */
1252 NULL, /* set salt */
1253 NULL, /* get salt size */
1254 des_set_key, /* set key */
1255 NULL, /* get key size */
1256 NULL, /* set batch mode */
1257 NULL, /* get batch mode */
1258 NULL, /* get block size */
1259 NULL /* set key with len */
1260 };
1261
1262 /******************************************************************************
1263 * Triple-DES
1264 *****************************************************************************/
1265
1266 typedef struct _des3_ctx
1267 {
1268 PurpleCipherBatchMode mode;
1269 guchar iv[8];
1270 /* First key for encryption */
1271 struct _des_ctx key1;
1272 /* Second key for decryption */
1273 struct _des_ctx key2;
1274 /* Third key for encryption */
1275 struct _des_ctx key3;
1276 } des3_ctx[1];
1277
1278 /*
1279 * Fill a DES3 context with subkeys calculated from 3 64bit key.
1280 * Does not check parity bits, but simply ignore them.
1281 * Does not check for weak keys.
1282 **/
1283 static void
1284 des3_set_key(PurpleCipherContext *context, const guchar * key)
1285 {
1286 struct _des3_ctx *ctx = purple_cipher_context_get_data(context);
1287 int i;
1288
1289 des_key_schedule (key + 0, ctx->key1.encrypt_subkeys);
1290 des_key_schedule (key + 8, ctx->key2.encrypt_subkeys);
1291 des_key_schedule (key + 16, ctx->key3.encrypt_subkeys);
1292
1293 for (i = 0; i < 32; i += 2)
1294 {
1295 ctx->key1.decrypt_subkeys[i] = ctx->key1.encrypt_subkeys[30-i];
1296 ctx->key1.decrypt_subkeys[i+1] = ctx->key1.encrypt_subkeys[31-i];
1297 ctx->key2.decrypt_subkeys[i] = ctx->key2.encrypt_subkeys[30-i];
1298 ctx->key2.decrypt_subkeys[i+1] = ctx->key2.encrypt_subkeys[31-i];
1299 ctx->key3.decrypt_subkeys[i] = ctx->key3.encrypt_subkeys[30-i];
1300 ctx->key3.decrypt_subkeys[i+1] = ctx->key3.encrypt_subkeys[31-i];
1301 }
1302 }
1303
1304 static gint
1305 des3_ecb_encrypt(struct _des3_ctx *ctx, const guchar data[],
1306 size_t len, guchar output[], size_t *outlen)
1307 {
1308 int offset = 0;
1309 int i = 0;
1310 int tmp;
1311 guint8 buf[8] = {0,0,0,0,0,0,0,0};
1312 while (offset + 8 <= len) {
1313 des_ecb_crypt(&ctx->key1,
1314 data+offset,
1315 output+offset,
1316 0);
1317 des_ecb_crypt(&ctx->key2,
1318 output+offset,
1319 buf,
1320 1);
1321 des_ecb_crypt(&ctx->key3,
1322 buf,
1323 output+offset,
1324 0);
1325 offset += 8;
1326 }
1327 *outlen = len;
1328 if (offset < len) {
1329 *outlen += len - offset;
1330 tmp = offset;
1331 memset(buf, 0, 8);
1332 while (tmp < len) {
1333 buf[i++] = data[tmp];
1334 tmp++;
1335 }
1336 des_ecb_crypt(&ctx->key1,
1337 buf,
1338 output+offset,
1339 0);
1340 des_ecb_crypt(&ctx->key2,
1341 output+offset,
1342 buf,
1343 1);
1344 des_ecb_crypt(&ctx->key3,
1345 buf,
1346 output+offset,
1347 0);
1348 }
1349 return 0;
1350 }
1351
1352 static gint
1353 des3_cbc_encrypt(struct _des3_ctx *ctx, const guchar data[],
1354 size_t len, guchar output[], size_t *outlen)
1355 {
1356 int offset = 0;
1357 int i = 0;
1358 int tmp;
1359 guint8 buf[8];
1360 memcpy(buf, ctx->iv, 8);
1361 while (offset + 8 <= len) {
1362 for (i = 0; i < 8; i++)
1363 buf[i] ^= data[offset + i];
1364 des_ecb_crypt(&ctx->key1,
1365 buf,
1366 output+offset,
1367 0);
1368 des_ecb_crypt(&ctx->key2,
1369 output+offset,
1370 buf,
1371 1);
1372 des_ecb_crypt(&ctx->key3,
1373 buf,
1374 output+offset,
1375 0);
1376 memcpy(buf, output+offset, 8);
1377 offset += 8;
1378 }
1379 *outlen = len;
1380 if (offset < len) {
1381 *outlen += len - offset;
1382 tmp = offset;
1383 i = 0;
1384 while (tmp < len) {
1385 buf[i++] ^= data[tmp];
1386 tmp++;
1387 }
1388 des_ecb_crypt(&ctx->key1,
1389 buf,
1390 output+offset,
1391 0);
1392 des_ecb_crypt(&ctx->key2,
1393 output+offset,
1394 buf,
1395 1);
1396 des_ecb_crypt(&ctx->key3,
1397 buf,
1398 output+offset,
1399 0);
1400 }
1401 return 0;
1402 }
1403
1404 static gint
1405 des3_encrypt(PurpleCipherContext *context, const guchar data[],
1406 size_t len, guchar output[], size_t *outlen)
1407 {
1408 struct _des3_ctx *ctx = purple_cipher_context_get_data(context);
1409
1410 if (ctx->mode == PURPLE_CIPHER_BATCH_MODE_ECB) {
1411 return des3_ecb_encrypt(ctx, data, len, output, outlen);
1412 } else if (ctx->mode == PURPLE_CIPHER_BATCH_MODE_CBC) {
1413 return des3_cbc_encrypt(ctx, data, len, output, outlen);
1414 } else {
1415 g_return_val_if_reached(0);
1416 }
1417
1418 return 0;
1419 }
1420
1421 static gint
1422 des3_ecb_decrypt(struct _des3_ctx *ctx, const guchar data[],
1423 size_t len, guchar output[], size_t *outlen)
1424 {
1425 int offset = 0;
1426 int i = 0;
1427 int tmp;
1428 guint8 buf[8] = {0,0,0,0,0,0,0,0};
1429 while (offset + 8 <= len) {
1430 /* NOTE: Apply key in reverse */
1431 des_ecb_crypt(&ctx->key3,
1432 data+offset,
1433 output+offset,
1434 1);
1435 des_ecb_crypt(&ctx->key2,
1436 output+offset,
1437 buf,
1438 0);
1439 des_ecb_crypt(&ctx->key1,
1440 buf,
1441 output+offset,
1442 1);
1443 offset+=8;
1444 }
1445 *outlen = len;
1446 if (offset < len) {
1447 *outlen += len - offset;
1448 tmp = offset;
1449 memset(buf, 0, 8);
1450 while (tmp < len) {
1451 buf[i++] = data[tmp];
1452 tmp++;
1453 }
1454 des_ecb_crypt(&ctx->key3,
1455 buf,
1456 output+offset,
1457 1);
1458 des_ecb_crypt(&ctx->key2,
1459 output+offset,
1460 buf,
1461 0);
1462 des_ecb_crypt(&ctx->key1,
1463 buf,
1464 output+offset,
1465 1);
1466 }
1467 return 0;
1468 }
1469
1470 static gint
1471 des3_cbc_decrypt(struct _des3_ctx *ctx, const guchar data[],
1472 size_t len, guchar output[], size_t *outlen)
1473 {
1474 int offset = 0;
1475 int i = 0;
1476 int tmp;
1477 guint8 buf[8] = {0,0,0,0,0,0,0,0};
1478 guint8 link[8];
1479 memcpy(link, ctx->iv, 8);
1480 while (offset + 8 <= len) {
1481 des_ecb_crypt(&ctx->key3,
1482 data+offset,
1483 output+offset,
1484 1);
1485 des_ecb_crypt(&ctx->key2,
1486 output+offset,
1487 buf,
1488 0);
1489 des_ecb_crypt(&ctx->key1,
1490 buf,
1491 output+offset,
1492 1);
1493 for (i = 0; i < 8; i++)
1494 output[offset + i] ^= link[i];
1495 memcpy(link, data + offset, 8);
1496 offset+=8;
1497 }
1498 *outlen = len;
1499 if(offset<len) {
1500 *outlen += len - offset;
1501 tmp = offset;
1502 memset(buf, 0, 8);
1503 i = 0;
1504 while(tmp<len) {
1505 buf[i++] = data[tmp];
1506 tmp++;
1507 }
1508 des_ecb_crypt(&ctx->key3,
1509 buf,
1510 output+offset,
1511 1);
1512 des_ecb_crypt(&ctx->key2,
1513 output+offset,
1514 buf,
1515 0);
1516 des_ecb_crypt(&ctx->key1,
1517 buf,
1518 output+offset,
1519 1);
1520 for (i = 0; i < 8; i++)
1521 output[offset + i] ^= link[i];
1522 }
1523 return 0;
1524 }
1525
1526 static gint
1527 des3_decrypt(PurpleCipherContext *context, const guchar data[],
1528 size_t len, guchar output[], size_t *outlen)
1529 {
1530 struct _des3_ctx *ctx = purple_cipher_context_get_data(context);
1531
1532 if (ctx->mode == PURPLE_CIPHER_BATCH_MODE_ECB) {
1533 return des3_ecb_decrypt(ctx, data, len, output, outlen);
1534 } else if (ctx->mode == PURPLE_CIPHER_BATCH_MODE_CBC) {
1535 return des3_cbc_decrypt(ctx, data, len, output, outlen);
1536 } else {
1537 g_return_val_if_reached(0);
1538 }
1539
1540 return 0;
1541 }
1542
1543 static void
1544 des3_set_batch(PurpleCipherContext *context, PurpleCipherBatchMode mode)
1545 {
1546 struct _des3_ctx *ctx = purple_cipher_context_get_data(context);
1547
1548 ctx->mode = mode;
1549 }
1550
1551 static PurpleCipherBatchMode
1552 des3_get_batch(PurpleCipherContext *context)
1553 {
1554 struct _des3_ctx *ctx = purple_cipher_context_get_data(context);
1555
1556 return ctx->mode;
1557 }
1558
1559 static void
1560 des3_set_iv(PurpleCipherContext *context, guchar *iv, size_t len)
1561 {
1562 struct _des3_ctx *ctx;
1563
1564 g_return_if_fail(len == 8);
1565
1566 ctx = purple_cipher_context_get_data(context);
1567
1568 memcpy(ctx->iv, iv, len);
1569 }
1570
1571 static void
1572 des3_init(PurpleCipherContext *context, gpointer extra)
1573 {
1574 struct _des3_ctx *mctx;
1575 mctx = g_new0(struct _des3_ctx, 1);
1576 purple_cipher_context_set_data(context, mctx);
1577 }
1578
1579 static void
1580 des3_uninit(PurpleCipherContext *context)
1581 {
1582 struct _des3_ctx *des3_context;
1583
1584 des3_context = purple_cipher_context_get_data(context);
1585 memset(des3_context, 0, sizeof(des3_context));
1586
1587 g_free(des3_context);
1588 des3_context = NULL;
1589 }
1590
1591 static PurpleCipherOps DES3Ops = {
1592 NULL, /* Set option */
1593 NULL, /* Get option */
1594 des3_init, /* init */
1011 NULL, /* reset */ 1595 NULL, /* reset */
1012 des_uninit, /* uninit */ 1596 des3_uninit, /* uninit */
1013 NULL, /* set iv */ 1597 des3_set_iv, /* set iv */
1014 NULL, /* append */ 1598 NULL, /* append */
1015 NULL, /* digest */ 1599 NULL, /* digest */
1016 des_encrypt, /* encrypt */ 1600 des3_encrypt, /* encrypt */
1017 NULL, /* decrypt */ 1601 des3_decrypt, /* decrypt */
1018 NULL, /* set salt */ 1602 NULL, /* set salt */
1019 NULL, /* get salt size */ 1603 NULL, /* get salt size */
1020 des_set_key, /* set key */ 1604 des3_set_key, /* set key */
1021 NULL, /* get key size */ 1605 NULL, /* get key size */
1022 1606 des3_set_batch, /* set batch mode */
1023 /* padding */ 1607 des3_get_batch, /* get batch mode */
1024 NULL, 1608 NULL, /* get block size */
1025 NULL, 1609 NULL /* set key with len */
1026 NULL,
1027 NULL
1028 }; 1610 };
1029
1030 1611
1031 /******************************************************************************* 1612 /*******************************************************************************
1032 * SHA-1 1613 * SHA-1
1033 ******************************************************************************/ 1614 ******************************************************************************/
1615 #define SHA1_HMAC_BLOCK_SIZE 64
1034 #define SHA1_ROTL(X,n) ((((X) << (n)) | ((X) >> (32-(n)))) & 0xFFFFFFFF) 1616 #define SHA1_ROTL(X,n) ((((X) << (n)) | ((X) >> (32-(n)))) & 0xFFFFFFFF)
1035 1617
1036 struct SHA1Context { 1618 struct SHA1Context {
1037 guint32 H[5]; 1619 guint32 H[5];
1038 guint32 W[80]; 1620 guint32 W[80];
1247 1829
1248 if(out_len) 1830 if(out_len)
1249 *out_len = 20; 1831 *out_len = 20;
1250 1832
1251 return TRUE; 1833 return TRUE;
1834 }
1835
1836 static size_t
1837 sha1_get_block_size(PurpleCipherContext *context)
1838 {
1839 /* This does not change (in this case) */
1840 return SHA1_HMAC_BLOCK_SIZE;
1252 } 1841 }
1253 1842
1254 static PurpleCipherOps SHA1Ops = { 1843 static PurpleCipherOps SHA1Ops = {
1255 sha1_set_opt, /* Set Option */ 1844 sha1_set_opt, /* Set Option */
1256 sha1_get_opt, /* Get Option */ 1845 sha1_get_opt, /* Get Option */
1264 NULL, /* decrypt */ 1853 NULL, /* decrypt */
1265 NULL, /* set salt */ 1854 NULL, /* set salt */
1266 NULL, /* get salt size */ 1855 NULL, /* get salt size */
1267 NULL, /* set key */ 1856 NULL, /* set key */
1268 NULL, /* get key size */ 1857 NULL, /* get key size */
1269 1858 NULL, /* set batch mode */
1270 /* padding */ 1859 NULL, /* get batch mode */
1271 NULL, 1860 sha1_get_block_size, /* get block size */
1272 NULL, 1861 NULL /* set key with len */
1273 NULL,
1274 NULL
1275 }; 1862 };
1276 1863
1277 /******************************************************************************* 1864 /*******************************************************************************
1278 * RC4 1865 * RC4
1279 ******************************************************************************/ 1866 ******************************************************************************/
1433 NULL, /* decrypt */ 2020 NULL, /* decrypt */
1434 NULL, /* set salt */ 2021 NULL, /* set salt */
1435 NULL, /* get salt size */ 2022 NULL, /* get salt size */
1436 rc4_set_key, /* set key */ 2023 rc4_set_key, /* set key */
1437 rc4_get_key_size, /* get key size */ 2024 rc4_get_key_size, /* get key size */
1438 2025 NULL, /* set batch mode */
1439 /* padding */ 2026 NULL, /* get batch mode */
1440 NULL, 2027 NULL, /* get block size */
1441 NULL, 2028 NULL /* set key with len */
1442 NULL,
1443 NULL
1444 }; 2029 };
1445 2030
1446 /******************************************************************************* 2031 /*******************************************************************************
1447 * Structs 2032 * Structs
1448 ******************************************************************************/ 2033 ******************************************************************************/
1508 caps |= PURPLE_CIPHER_CAPS_GET_SALT_SIZE; 2093 caps |= PURPLE_CIPHER_CAPS_GET_SALT_SIZE;
1509 if(ops->set_key) 2094 if(ops->set_key)
1510 caps |= PURPLE_CIPHER_CAPS_SET_KEY; 2095 caps |= PURPLE_CIPHER_CAPS_SET_KEY;
1511 if(ops->get_key_size) 2096 if(ops->get_key_size)
1512 caps |= PURPLE_CIPHER_CAPS_GET_KEY_SIZE; 2097 caps |= PURPLE_CIPHER_CAPS_GET_KEY_SIZE;
2098 if(ops->set_batch_mode)
2099 caps |= PURPLE_CIPHER_CAPS_SET_BATCH_MODE;
2100 if(ops->get_batch_mode)
2101 caps |= PURPLE_CIPHER_CAPS_GET_BATCH_MODE;
2102 if(ops->get_block_size)
2103 caps |= PURPLE_CIPHER_CAPS_GET_BLOCK_SIZE;
2104 if(ops->set_key_with_len)
2105 caps |= PURPLE_CIPHER_CAPS_SET_KEY_WITH_LEN;
1513 2106
1514 return caps; 2107 return caps;
1515 } 2108 }
1516 2109
1517 gboolean 2110 gboolean
1634 PURPLE_SUBTYPE_CIPHER)); 2227 PURPLE_SUBTYPE_CIPHER));
1635 2228
1636 purple_ciphers_register_cipher("md5", &MD5Ops); 2229 purple_ciphers_register_cipher("md5", &MD5Ops);
1637 purple_ciphers_register_cipher("sha1", &SHA1Ops); 2230 purple_ciphers_register_cipher("sha1", &SHA1Ops);
1638 purple_ciphers_register_cipher("md4", &MD4Ops); 2231 purple_ciphers_register_cipher("md4", &MD4Ops);
2232 purple_ciphers_register_cipher("hmac", &HMACOps);
1639 purple_ciphers_register_cipher("des", &DESOps); 2233 purple_ciphers_register_cipher("des", &DESOps);
2234 purple_ciphers_register_cipher("des3", &DES3Ops);
1640 purple_ciphers_register_cipher("rc4", &RC4Ops); 2235 purple_ciphers_register_cipher("rc4", &RC4Ops);
1641 } 2236 }
1642 2237
1643 void 2238 void
1644 purple_ciphers_uninit() { 2239 purple_ciphers_uninit() {
1962 purple_debug_info("cipher", "the %s cipher does not support the " 2557 purple_debug_info("cipher", "the %s cipher does not support the "
1963 "get_key_size operation\n", cipher->name); 2558 "get_key_size operation\n", cipher->name);
1964 2559
1965 return -1; 2560 return -1;
1966 } 2561 }
2562 }
2563
2564 void
2565 purple_cipher_context_set_batch_mode(PurpleCipherContext *context,
2566 PurpleCipherBatchMode mode)
2567 {
2568 PurpleCipher *cipher = NULL;
2569
2570 g_return_if_fail(context);
2571
2572 cipher = context->cipher;
2573 g_return_if_fail(cipher);
2574
2575 if(cipher->ops && cipher->ops->set_batch_mode)
2576 cipher->ops->set_batch_mode(context, mode);
2577 else
2578 purple_debug_info("cipher", "The %s cipher does not support the "
2579 "set_batch_mode operation\n", cipher->name);
2580 }
2581
2582 PurpleCipherBatchMode
2583 purple_cipher_context_get_batch_mode(PurpleCipherContext *context)
2584 {
2585 PurpleCipher *cipher = NULL;
2586
2587 g_return_val_if_fail(context, -1);
2588
2589 cipher = context->cipher;
2590 g_return_val_if_fail(cipher, -1);
2591
2592 if(cipher->ops && cipher->ops->get_batch_mode)
2593 return cipher->ops->get_batch_mode(context);
2594 else {
2595 purple_debug_info("cipher", "The %s cipher does not support the "
2596 "get_batch_mode operation\n", cipher->name);
2597 return -1;
2598 }
2599 }
2600
2601 size_t
2602 purple_cipher_context_get_block_size(PurpleCipherContext *context)
2603 {
2604 PurpleCipher *cipher = NULL;
2605
2606 g_return_val_if_fail(context, -1);
2607
2608 cipher = context->cipher;
2609 g_return_val_if_fail(cipher, -1);
2610
2611 if(cipher->ops && cipher->ops->get_block_size)
2612 return cipher->ops->get_block_size(context);
2613 else {
2614 purple_debug_info("cipher", "The %s cipher does not support the "
2615 "get_block_size operation\n", cipher->name);
2616 return -1;
2617 }
2618 }
2619
2620 void
2621 purple_cipher_context_set_key_with_len(PurpleCipherContext *context,
2622 const guchar *key, size_t len)
2623 {
2624 PurpleCipher *cipher = NULL;
2625
2626 g_return_if_fail(context);
2627
2628 cipher = context->cipher;
2629 g_return_if_fail(cipher);
2630
2631 if(cipher->ops && cipher->ops->set_key_with_len)
2632 cipher->ops->set_key_with_len(context, key, len);
2633 else
2634 purple_debug_info("cipher", "The %s cipher does not support the "
2635 "set_key_with_len operation\n", cipher->name);
1967 } 2636 }
1968 2637
1969 void 2638 void
1970 purple_cipher_context_set_data(PurpleCipherContext *context, gpointer data) { 2639 purple_cipher_context_set_data(PurpleCipherContext *context, gpointer data) {
1971 g_return_if_fail(context); 2640 g_return_if_fail(context);