Mercurial > pidgin.yaz
comparison libpurple/cipher.c @ 21907:03463c52b9d7
Triple DES cipher support from Elliott Sales de Andrade
committer: Gary Kramlich <grim@reaperworld.com>
author | Elliott Sales de Andrade <qulogic@pidgin.im> |
---|---|
date | Thu, 20 Dec 2007 03:40:56 +0000 |
parents | 787b3897ba9f |
children | f786e478e08b |
comparison
equal
deleted
inserted
replaced
21906:47aabef7f802 | 21907:03463c52b9d7 |
---|---|
338 NULL, /* decrypt */ | 338 NULL, /* decrypt */ |
339 NULL, /* set salt */ | 339 NULL, /* set salt */ |
340 NULL, /* get salt size */ | 340 NULL, /* get salt size */ |
341 NULL, /* set key */ | 341 NULL, /* set key */ |
342 NULL, /* get key size */ | 342 NULL, /* get key size */ |
343 NULL, /* set batch mode */ | |
344 NULL, /* get batch mode */ | |
343 | 345 |
344 /* padding */ | 346 /* padding */ |
345 NULL, | |
346 NULL, | |
347 NULL, | 347 NULL, |
348 NULL | 348 NULL |
349 }; | 349 }; |
350 | 350 |
351 /******************************************************************************* | 351 /******************************************************************************* |
593 NULL, /* decrypt */ | 593 NULL, /* decrypt */ |
594 NULL, /* set salt */ | 594 NULL, /* set salt */ |
595 NULL, /* get salt size */ | 595 NULL, /* get salt size */ |
596 NULL, /* set key */ | 596 NULL, /* set key */ |
597 NULL, /* get key size */ | 597 NULL, /* get key size */ |
598 NULL, /* set batch mode */ | |
599 NULL, /* get batch mode */ | |
598 | 600 |
599 /* padding */ | 601 /* padding */ |
600 NULL, | |
601 NULL, | |
602 NULL, | 602 NULL, |
603 NULL | 603 NULL |
604 }; | 604 }; |
605 | 605 |
606 /****************************************************************************** | 606 /****************************************************************************** |
984 0); | 984 0); |
985 } | 985 } |
986 return 0; | 986 return 0; |
987 } | 987 } |
988 | 988 |
989 static gint | |
990 des_decrypt(PurpleCipherContext *context, const guchar data[], | |
991 size_t len, guchar output[], size_t *outlen) { | |
992 int offset = 0; | |
993 int i = 0; | |
994 int tmp; | |
995 guint8 buf[8] = {0,0,0,0,0,0,0,0}; | |
996 while(offset+8<=len) { | |
997 des_ecb_crypt(purple_cipher_context_get_data(context), | |
998 data+offset, | |
999 output+offset, | |
1000 1); | |
1001 offset+=8; | |
1002 } | |
1003 *outlen = len; | |
1004 if(offset<len) { | |
1005 *outlen += len - offset; | |
1006 tmp = offset; | |
1007 while(tmp<len) { | |
1008 buf[i++] = data[tmp]; | |
1009 tmp++; | |
1010 } | |
1011 des_ecb_crypt(purple_cipher_context_get_data(context), | |
1012 buf, | |
1013 output+offset, | |
1014 1); | |
1015 } | |
1016 return 0; | |
1017 } | |
1018 | |
989 static void | 1019 static void |
990 des_init(PurpleCipherContext *context, gpointer extra) { | 1020 des_init(PurpleCipherContext *context, gpointer extra) { |
991 struct _des_ctx *mctx; | 1021 struct _des_ctx *mctx; |
992 mctx = g_new0(struct _des_ctx, 1); | 1022 mctx = g_new0(struct _des_ctx, 1); |
993 purple_cipher_context_set_data(context, mctx); | 1023 purple_cipher_context_set_data(context, mctx); |
1003 g_free(des_context); | 1033 g_free(des_context); |
1004 des_context = NULL; | 1034 des_context = NULL; |
1005 } | 1035 } |
1006 | 1036 |
1007 static PurpleCipherOps DESOps = { | 1037 static PurpleCipherOps DESOps = { |
1008 NULL, /* Set option */ | 1038 NULL, /* Set option */ |
1009 NULL, /* Get option */ | 1039 NULL, /* Get option */ |
1010 des_init, /* init */ | 1040 des_init, /* init */ |
1011 NULL, /* reset */ | 1041 NULL, /* reset */ |
1012 des_uninit, /* uninit */ | 1042 des_uninit, /* uninit */ |
1013 NULL, /* set iv */ | 1043 NULL, /* set iv */ |
1014 NULL, /* append */ | 1044 NULL, /* append */ |
1015 NULL, /* digest */ | 1045 NULL, /* digest */ |
1016 des_encrypt, /* encrypt */ | 1046 des_encrypt, /* encrypt */ |
1017 NULL, /* decrypt */ | 1047 des_decrypt, /* decrypt */ |
1018 NULL, /* set salt */ | 1048 NULL, /* set salt */ |
1019 NULL, /* get salt size */ | 1049 NULL, /* get salt size */ |
1020 des_set_key, /* set key */ | 1050 des_set_key, /* set key */ |
1021 NULL, /* get key size */ | 1051 NULL, /* get key size */ |
1052 NULL, /* set batch mode */ | |
1053 NULL, /* get batch mode */ | |
1022 | 1054 |
1023 /* padding */ | 1055 /* padding */ |
1024 NULL, | |
1025 NULL, | |
1026 NULL, | 1056 NULL, |
1027 NULL | 1057 NULL |
1028 }; | 1058 }; |
1029 | 1059 |
1060 /****************************************************************************** | |
1061 * Triple-DES | |
1062 *****************************************************************************/ | |
1063 | |
1064 typedef struct _des3_ctx | |
1065 { | |
1066 PurpleCipherBatchMode mode; | |
1067 guchar iv[8]; | |
1068 /* First key for encryption */ | |
1069 struct _des_ctx key1; | |
1070 /* Second key for decryption */ | |
1071 struct _des_ctx key2; | |
1072 /* Third key for encryption */ | |
1073 struct _des_ctx key3; | |
1074 } des3_ctx[1]; | |
1075 | |
1076 /* | |
1077 * Fill a DES3 context with subkeys calculated from 3 64bit key. | |
1078 * Does not check parity bits, but simply ignore them. | |
1079 * Does not check for weak keys. | |
1080 **/ | |
1081 static void | |
1082 des3_set_key(PurpleCipherContext *context, const guchar * key) | |
1083 { | |
1084 struct _des3_ctx *ctx = purple_cipher_context_get_data(context); | |
1085 int i; | |
1086 | |
1087 des_key_schedule (key + 0, ctx->key1.encrypt_subkeys); | |
1088 des_key_schedule (key + 8, ctx->key2.encrypt_subkeys); | |
1089 des_key_schedule (key + 16, ctx->key3.encrypt_subkeys); | |
1090 | |
1091 for (i = 0; i < 32; i += 2) | |
1092 { | |
1093 ctx->key1.decrypt_subkeys[i] = ctx->key1.encrypt_subkeys[30-i]; | |
1094 ctx->key1.decrypt_subkeys[i+1] = ctx->key1.encrypt_subkeys[31-i]; | |
1095 ctx->key2.decrypt_subkeys[i] = ctx->key2.encrypt_subkeys[30-i]; | |
1096 ctx->key2.decrypt_subkeys[i+1] = ctx->key2.encrypt_subkeys[31-i]; | |
1097 ctx->key3.decrypt_subkeys[i] = ctx->key3.encrypt_subkeys[30-i]; | |
1098 ctx->key3.decrypt_subkeys[i+1] = ctx->key3.encrypt_subkeys[31-i]; | |
1099 } | |
1100 } | |
1101 | |
1102 static gint | |
1103 des3_ecb_encrypt(struct _des3_ctx *ctx, const guchar data[], | |
1104 size_t len, guchar output[], size_t *outlen) | |
1105 { | |
1106 int offset = 0; | |
1107 int i = 0; | |
1108 int tmp; | |
1109 guint8 buf[8] = {0,0,0,0,0,0,0,0}; | |
1110 while (offset + 8 <= len) { | |
1111 des_ecb_crypt(&ctx->key1, | |
1112 data+offset, | |
1113 output+offset, | |
1114 0); | |
1115 des_ecb_crypt(&ctx->key2, | |
1116 output+offset, | |
1117 buf, | |
1118 1); | |
1119 des_ecb_crypt(&ctx->key3, | |
1120 buf, | |
1121 output+offset, | |
1122 0); | |
1123 offset += 8; | |
1124 } | |
1125 *outlen = len; | |
1126 if (offset < len) { | |
1127 *outlen += len - offset; | |
1128 tmp = offset; | |
1129 memset(buf, 0, 8); | |
1130 while (tmp < len) { | |
1131 buf[i++] = data[tmp]; | |
1132 tmp++; | |
1133 } | |
1134 des_ecb_crypt(&ctx->key1, | |
1135 buf, | |
1136 output+offset, | |
1137 0); | |
1138 des_ecb_crypt(&ctx->key2, | |
1139 output+offset, | |
1140 buf, | |
1141 1); | |
1142 des_ecb_crypt(&ctx->key3, | |
1143 buf, | |
1144 output+offset, | |
1145 0); | |
1146 } | |
1147 return 0; | |
1148 } | |
1149 | |
1150 static gint | |
1151 des3_cbc_encrypt(struct _des3_ctx *ctx, const guchar data[], | |
1152 size_t len, guchar output[], size_t *outlen) | |
1153 { | |
1154 int offset = 0; | |
1155 int i = 0; | |
1156 int tmp; | |
1157 guint8 buf[8]; | |
1158 memcpy(buf, ctx->iv, 8); | |
1159 while (offset + 8 <= len) { | |
1160 for (i = 0; i < 8; i++) | |
1161 buf[i] ^= data[offset + i]; | |
1162 des_ecb_crypt(&ctx->key1, | |
1163 buf, | |
1164 output+offset, | |
1165 0); | |
1166 des_ecb_crypt(&ctx->key2, | |
1167 output+offset, | |
1168 buf, | |
1169 1); | |
1170 des_ecb_crypt(&ctx->key3, | |
1171 buf, | |
1172 output+offset, | |
1173 0); | |
1174 memcpy(buf, output+offset, 8); | |
1175 offset += 8; | |
1176 } | |
1177 *outlen = len; | |
1178 if (offset < len) { | |
1179 *outlen += len - offset; | |
1180 tmp = offset; | |
1181 i = 0; | |
1182 while (tmp < len) { | |
1183 buf[i++] ^= data[tmp]; | |
1184 tmp++; | |
1185 } | |
1186 des_ecb_crypt(&ctx->key1, | |
1187 buf, | |
1188 output+offset, | |
1189 0); | |
1190 des_ecb_crypt(&ctx->key2, | |
1191 output+offset, | |
1192 buf, | |
1193 1); | |
1194 des_ecb_crypt(&ctx->key3, | |
1195 buf, | |
1196 output+offset, | |
1197 0); | |
1198 } | |
1199 return 0; | |
1200 } | |
1201 | |
1202 static gint | |
1203 des3_encrypt(PurpleCipherContext *context, const guchar data[], | |
1204 size_t len, guchar output[], size_t *outlen) | |
1205 { | |
1206 struct _des3_ctx *ctx = purple_cipher_context_get_data(context); | |
1207 | |
1208 if (ctx->mode == PURPLE_CIPHER_BATCH_MODE_ECB) { | |
1209 return des3_ecb_encrypt(ctx, data, len, output, outlen); | |
1210 } else if (ctx->mode == PURPLE_CIPHER_BATCH_MODE_CBC) { | |
1211 return des3_cbc_encrypt(ctx, data, len, output, outlen); | |
1212 } else { | |
1213 g_return_val_if_reached(0); | |
1214 } | |
1215 | |
1216 return 0; | |
1217 } | |
1218 | |
1219 static gint | |
1220 des3_ecb_decrypt(struct _des3_ctx *ctx, const guchar data[], | |
1221 size_t len, guchar output[], size_t *outlen) | |
1222 { | |
1223 int offset = 0; | |
1224 int i = 0; | |
1225 int tmp; | |
1226 guint8 buf[8] = {0,0,0,0,0,0,0,0}; | |
1227 while (offset + 8 <= len) { | |
1228 /* NOTE: Apply key in reverse */ | |
1229 des_ecb_crypt(&ctx->key3, | |
1230 data+offset, | |
1231 output+offset, | |
1232 1); | |
1233 des_ecb_crypt(&ctx->key2, | |
1234 output+offset, | |
1235 buf, | |
1236 0); | |
1237 des_ecb_crypt(&ctx->key1, | |
1238 buf, | |
1239 output+offset, | |
1240 1); | |
1241 offset+=8; | |
1242 } | |
1243 *outlen = len; | |
1244 if (offset < len) { | |
1245 *outlen += len - offset; | |
1246 tmp = offset; | |
1247 memset(buf, 0, 8); | |
1248 while (tmp < len) { | |
1249 buf[i++] = data[tmp]; | |
1250 tmp++; | |
1251 } | |
1252 des_ecb_crypt(&ctx->key3, | |
1253 buf, | |
1254 output+offset, | |
1255 1); | |
1256 des_ecb_crypt(&ctx->key2, | |
1257 output+offset, | |
1258 buf, | |
1259 0); | |
1260 des_ecb_crypt(&ctx->key1, | |
1261 buf, | |
1262 output+offset, | |
1263 1); | |
1264 } | |
1265 return 0; | |
1266 } | |
1267 | |
1268 static gint | |
1269 des3_cbc_decrypt(struct _des3_ctx *ctx, const guchar data[], | |
1270 size_t len, guchar output[], size_t *outlen) | |
1271 { | |
1272 int offset = 0; | |
1273 int i = 0; | |
1274 int tmp; | |
1275 guint8 buf[8] = {0,0,0,0,0,0,0,0}; | |
1276 guint8 link[8]; | |
1277 memcpy(link, ctx->iv, 8); | |
1278 while (offset + 8 <= len) { | |
1279 des_ecb_crypt(&ctx->key3, | |
1280 data+offset, | |
1281 output+offset, | |
1282 1); | |
1283 des_ecb_crypt(&ctx->key2, | |
1284 output+offset, | |
1285 buf, | |
1286 0); | |
1287 des_ecb_crypt(&ctx->key1, | |
1288 buf, | |
1289 output+offset, | |
1290 1); | |
1291 for (i = 0; i < 8; i++) | |
1292 output[offset + i] ^= link[i]; | |
1293 memcpy(link, data + offset, 8); | |
1294 offset+=8; | |
1295 } | |
1296 *outlen = len; | |
1297 if(offset<len) { | |
1298 *outlen += len - offset; | |
1299 tmp = offset; | |
1300 memset(buf, 0, 8); | |
1301 i = 0; | |
1302 while(tmp<len) { | |
1303 buf[i++] = data[tmp]; | |
1304 tmp++; | |
1305 } | |
1306 des_ecb_crypt(&ctx->key3, | |
1307 buf, | |
1308 output+offset, | |
1309 1); | |
1310 des_ecb_crypt(&ctx->key2, | |
1311 output+offset, | |
1312 buf, | |
1313 0); | |
1314 des_ecb_crypt(&ctx->key1, | |
1315 buf, | |
1316 output+offset, | |
1317 1); | |
1318 for (i = 0; i < 8; i++) | |
1319 output[offset + i] ^= link[i]; | |
1320 } | |
1321 return 0; | |
1322 } | |
1323 | |
1324 static gint | |
1325 des3_decrypt(PurpleCipherContext *context, const guchar data[], | |
1326 size_t len, guchar output[], size_t *outlen) | |
1327 { | |
1328 struct _des3_ctx *ctx = purple_cipher_context_get_data(context); | |
1329 | |
1330 if (ctx->mode == PURPLE_CIPHER_BATCH_MODE_ECB) { | |
1331 return des3_ecb_decrypt(ctx, data, len, output, outlen); | |
1332 } else if (ctx->mode == PURPLE_CIPHER_BATCH_MODE_CBC) { | |
1333 return des3_cbc_decrypt(ctx, data, len, output, outlen); | |
1334 } else { | |
1335 g_return_val_if_reached(0); | |
1336 } | |
1337 | |
1338 return 0; | |
1339 } | |
1340 | |
1341 static void | |
1342 des3_set_batch(PurpleCipherContext *context, PurpleCipherBatchMode mode) | |
1343 { | |
1344 struct _des3_ctx *ctx = purple_cipher_context_get_data(context); | |
1345 | |
1346 ctx->mode = mode; | |
1347 } | |
1348 | |
1349 static PurpleCipherBatchMode | |
1350 des3_get_batch(PurpleCipherContext *context) | |
1351 { | |
1352 struct _des3_ctx *ctx = purple_cipher_context_get_data(context); | |
1353 | |
1354 return ctx->mode; | |
1355 } | |
1356 | |
1357 static void | |
1358 des3_set_iv(PurpleCipherContext *context, guchar *iv, size_t len) | |
1359 { | |
1360 struct _des3_ctx *ctx; | |
1361 | |
1362 g_return_if_fail(len == 8); | |
1363 | |
1364 ctx = purple_cipher_context_get_data(context); | |
1365 | |
1366 memcpy(ctx->iv, iv, len); | |
1367 } | |
1368 | |
1369 static void | |
1370 des3_init(PurpleCipherContext *context, gpointer extra) | |
1371 { | |
1372 struct _des3_ctx *mctx; | |
1373 mctx = g_new0(struct _des3_ctx, 1); | |
1374 purple_cipher_context_set_data(context, mctx); | |
1375 } | |
1376 | |
1377 static void | |
1378 des3_uninit(PurpleCipherContext *context) | |
1379 { | |
1380 struct _des3_ctx *des3_context; | |
1381 | |
1382 des3_context = purple_cipher_context_get_data(context); | |
1383 memset(des3_context, 0, sizeof(des3_context)); | |
1384 | |
1385 g_free(des3_context); | |
1386 des3_context = NULL; | |
1387 } | |
1388 | |
1389 static PurpleCipherOps DES3Ops = { | |
1390 NULL, /* Set option */ | |
1391 NULL, /* Get option */ | |
1392 des3_init, /* init */ | |
1393 NULL, /* reset */ | |
1394 des3_uninit, /* uninit */ | |
1395 des3_set_iv, /* set iv */ | |
1396 NULL, /* append */ | |
1397 NULL, /* digest */ | |
1398 des3_encrypt, /* encrypt */ | |
1399 des3_decrypt, /* decrypt */ | |
1400 NULL, /* set salt */ | |
1401 NULL, /* get salt size */ | |
1402 des3_set_key, /* set key */ | |
1403 NULL, /* get key size */ | |
1404 des3_set_batch, /* set batch mode */ | |
1405 des3_get_batch, /* get batch mode */ | |
1406 | |
1407 /* padding */ | |
1408 NULL, | |
1409 NULL | |
1410 }; | |
1030 | 1411 |
1031 /******************************************************************************* | 1412 /******************************************************************************* |
1032 * SHA-1 | 1413 * SHA-1 |
1033 ******************************************************************************/ | 1414 ******************************************************************************/ |
1034 #define SHA1_ROTL(X,n) ((((X) << (n)) | ((X) >> (32-(n)))) & 0xFFFFFFFF) | 1415 #define SHA1_ROTL(X,n) ((((X) << (n)) | ((X) >> (32-(n)))) & 0xFFFFFFFF) |
1264 NULL, /* decrypt */ | 1645 NULL, /* decrypt */ |
1265 NULL, /* set salt */ | 1646 NULL, /* set salt */ |
1266 NULL, /* get salt size */ | 1647 NULL, /* get salt size */ |
1267 NULL, /* set key */ | 1648 NULL, /* set key */ |
1268 NULL, /* get key size */ | 1649 NULL, /* get key size */ |
1650 NULL, /* set batch mode */ | |
1651 NULL, /* get batch mode */ | |
1269 | 1652 |
1270 /* padding */ | 1653 /* padding */ |
1271 NULL, | |
1272 NULL, | |
1273 NULL, | 1654 NULL, |
1274 NULL | 1655 NULL |
1275 }; | 1656 }; |
1276 | 1657 |
1277 /******************************************************************************* | 1658 /******************************************************************************* |
1433 NULL, /* decrypt */ | 1814 NULL, /* decrypt */ |
1434 NULL, /* set salt */ | 1815 NULL, /* set salt */ |
1435 NULL, /* get salt size */ | 1816 NULL, /* get salt size */ |
1436 rc4_set_key, /* set key */ | 1817 rc4_set_key, /* set key */ |
1437 rc4_get_key_size, /* get key size */ | 1818 rc4_get_key_size, /* get key size */ |
1819 NULL, /* set batch mode */ | |
1820 NULL, /* get batch mode */ | |
1438 | 1821 |
1439 /* padding */ | 1822 /* padding */ |
1440 NULL, | |
1441 NULL, | |
1442 NULL, | 1823 NULL, |
1443 NULL | 1824 NULL |
1444 }; | 1825 }; |
1445 | 1826 |
1446 /******************************************************************************* | 1827 /******************************************************************************* |
1508 caps |= PURPLE_CIPHER_CAPS_GET_SALT_SIZE; | 1889 caps |= PURPLE_CIPHER_CAPS_GET_SALT_SIZE; |
1509 if(ops->set_key) | 1890 if(ops->set_key) |
1510 caps |= PURPLE_CIPHER_CAPS_SET_KEY; | 1891 caps |= PURPLE_CIPHER_CAPS_SET_KEY; |
1511 if(ops->get_key_size) | 1892 if(ops->get_key_size) |
1512 caps |= PURPLE_CIPHER_CAPS_GET_KEY_SIZE; | 1893 caps |= PURPLE_CIPHER_CAPS_GET_KEY_SIZE; |
1894 if(ops->set_batch_mode) | |
1895 caps |= PURPLE_CIPHER_CAPS_SET_BATCH_MODE; | |
1896 if(ops->get_batch_mode) | |
1897 caps |= PURPLE_CIPHER_CAPS_GET_BATCH_MODE; | |
1513 | 1898 |
1514 return caps; | 1899 return caps; |
1515 } | 1900 } |
1516 | 1901 |
1517 gboolean | 1902 gboolean |
1635 | 2020 |
1636 purple_ciphers_register_cipher("md5", &MD5Ops); | 2021 purple_ciphers_register_cipher("md5", &MD5Ops); |
1637 purple_ciphers_register_cipher("sha1", &SHA1Ops); | 2022 purple_ciphers_register_cipher("sha1", &SHA1Ops); |
1638 purple_ciphers_register_cipher("md4", &MD4Ops); | 2023 purple_ciphers_register_cipher("md4", &MD4Ops); |
1639 purple_ciphers_register_cipher("des", &DESOps); | 2024 purple_ciphers_register_cipher("des", &DESOps); |
2025 purple_ciphers_register_cipher("des3", &DES3Ops); | |
1640 purple_ciphers_register_cipher("rc4", &RC4Ops); | 2026 purple_ciphers_register_cipher("rc4", &RC4Ops); |
1641 } | 2027 } |
1642 | 2028 |
1643 void | 2029 void |
1644 purple_ciphers_uninit() { | 2030 purple_ciphers_uninit() { |
1960 return cipher->ops->get_key_size(context); | 2346 return cipher->ops->get_key_size(context); |
1961 else { | 2347 else { |
1962 purple_debug_info("cipher", "the %s cipher does not support the " | 2348 purple_debug_info("cipher", "the %s cipher does not support the " |
1963 "get_key_size operation\n", cipher->name); | 2349 "get_key_size operation\n", cipher->name); |
1964 | 2350 |
2351 return -1; | |
2352 } | |
2353 } | |
2354 | |
2355 void | |
2356 purple_cipher_context_set_batch_mode(PurpleCipherContext *context, | |
2357 PurpleCipherBatchMode mode) | |
2358 { | |
2359 PurpleCipher *cipher = NULL; | |
2360 | |
2361 g_return_if_fail(context); | |
2362 | |
2363 cipher = context->cipher; | |
2364 g_return_if_fail(cipher); | |
2365 | |
2366 if(cipher->ops && cipher->ops->set_batch_mode) | |
2367 cipher->ops->set_batch_mode(context, mode); | |
2368 else | |
2369 purple_debug_info("cipher", "The %s cipher does not support the " | |
2370 "set_batch_mode operation\n", cipher->name); | |
2371 } | |
2372 | |
2373 PurpleCipherBatchMode | |
2374 purple_cipher_context_get_batch_mode(PurpleCipherContext *context) | |
2375 { | |
2376 PurpleCipher *cipher = NULL; | |
2377 | |
2378 g_return_val_if_fail(context, -1); | |
2379 | |
2380 cipher = context->cipher; | |
2381 g_return_val_if_fail(cipher, -1); | |
2382 | |
2383 if(cipher->ops && cipher->ops->get_batch_mode) | |
2384 return cipher->ops->get_batch_mode(context); | |
2385 else { | |
2386 purple_debug_info("cipher", "The %s cipher does not support the " | |
2387 "get_batch_mode operation\n", cipher->name); | |
1965 return -1; | 2388 return -1; |
1966 } | 2389 } |
1967 } | 2390 } |
1968 | 2391 |
1969 void | 2392 void |