comparison libpurple/cipher.c @ 31667:076d62344ede

broke des and des3 out to ciphers/des.c
author Gary Kramlich <grim@reaperworld.com>
date Mon, 14 Feb 2011 06:51:10 +0000
parents 3af51303d45c
children 2b041e31b825
comparison
equal deleted inserted replaced
31666:3af51303d45c 31667:076d62344ede
118 118
119 return TRUE; 119 return TRUE;
120 } 120 }
121 #endif 121 #endif
122 122
123 /******************************************************************************
124 * DES
125 *****************************************************************************/
126
127 typedef struct _des_ctx
128 {
129 guint32 encrypt_subkeys[32];
130 guint32 decrypt_subkeys[32];
131 } des_ctx[1];
132
133 /*
134 * The s-box values are permuted according to the 'primitive function P'
135 */
136 static const guint32 sbox1[64] =
137 {
138 0x00808200, 0x00000000, 0x00008000, 0x00808202, 0x00808002, 0x00008202, 0x00000002, 0x00008000,
139 0x00000200, 0x00808200, 0x00808202, 0x00000200, 0x00800202, 0x00808002, 0x00800000, 0x00000002,
140 0x00000202, 0x00800200, 0x00800200, 0x00008200, 0x00008200, 0x00808000, 0x00808000, 0x00800202,
141 0x00008002, 0x00800002, 0x00800002, 0x00008002, 0x00000000, 0x00000202, 0x00008202, 0x00800000,
142 0x00008000, 0x00808202, 0x00000002, 0x00808000, 0x00808200, 0x00800000, 0x00800000, 0x00000200,
143 0x00808002, 0x00008000, 0x00008200, 0x00800002, 0x00000200, 0x00000002, 0x00800202, 0x00008202,
144 0x00808202, 0x00008002, 0x00808000, 0x00800202, 0x00800002, 0x00000202, 0x00008202, 0x00808200,
145 0x00000202, 0x00800200, 0x00800200, 0x00000000, 0x00008002, 0x00008200, 0x00000000, 0x00808002
146 };
147
148 static const guint32 sbox2[64] =
149 {
150 0x40084010, 0x40004000, 0x00004000, 0x00084010, 0x00080000, 0x00000010, 0x40080010, 0x40004010,
151 0x40000010, 0x40084010, 0x40084000, 0x40000000, 0x40004000, 0x00080000, 0x00000010, 0x40080010,
152 0x00084000, 0x00080010, 0x40004010, 0x00000000, 0x40000000, 0x00004000, 0x00084010, 0x40080000,
153 0x00080010, 0x40000010, 0x00000000, 0x00084000, 0x00004010, 0x40084000, 0x40080000, 0x00004010,
154 0x00000000, 0x00084010, 0x40080010, 0x00080000, 0x40004010, 0x40080000, 0x40084000, 0x00004000,
155 0x40080000, 0x40004000, 0x00000010, 0x40084010, 0x00084010, 0x00000010, 0x00004000, 0x40000000,
156 0x00004010, 0x40084000, 0x00080000, 0x40000010, 0x00080010, 0x40004010, 0x40000010, 0x00080010,
157 0x00084000, 0x00000000, 0x40004000, 0x00004010, 0x40000000, 0x40080010, 0x40084010, 0x00084000
158 };
159
160 static const guint32 sbox3[64] =
161 {
162 0x00000104, 0x04010100, 0x00000000, 0x04010004, 0x04000100, 0x00000000, 0x00010104, 0x04000100,
163 0x00010004, 0x04000004, 0x04000004, 0x00010000, 0x04010104, 0x00010004, 0x04010000, 0x00000104,
164 0x04000000, 0x00000004, 0x04010100, 0x00000100, 0x00010100, 0x04010000, 0x04010004, 0x00010104,
165 0x04000104, 0x00010100, 0x00010000, 0x04000104, 0x00000004, 0x04010104, 0x00000100, 0x04000000,
166 0x04010100, 0x04000000, 0x00010004, 0x00000104, 0x00010000, 0x04010100, 0x04000100, 0x00000000,
167 0x00000100, 0x00010004, 0x04010104, 0x04000100, 0x04000004, 0x00000100, 0x00000000, 0x04010004,
168 0x04000104, 0x00010000, 0x04000000, 0x04010104, 0x00000004, 0x00010104, 0x00010100, 0x04000004,
169 0x04010000, 0x04000104, 0x00000104, 0x04010000, 0x00010104, 0x00000004, 0x04010004, 0x00010100
170 };
171
172 static const guint32 sbox4[64] =
173 {
174 0x80401000, 0x80001040, 0x80001040, 0x00000040, 0x00401040, 0x80400040, 0x80400000, 0x80001000,
175 0x00000000, 0x00401000, 0x00401000, 0x80401040, 0x80000040, 0x00000000, 0x00400040, 0x80400000,
176 0x80000000, 0x00001000, 0x00400000, 0x80401000, 0x00000040, 0x00400000, 0x80001000, 0x00001040,
177 0x80400040, 0x80000000, 0x00001040, 0x00400040, 0x00001000, 0x00401040, 0x80401040, 0x80000040,
178 0x00400040, 0x80400000, 0x00401000, 0x80401040, 0x80000040, 0x00000000, 0x00000000, 0x00401000,
179 0x00001040, 0x00400040, 0x80400040, 0x80000000, 0x80401000, 0x80001040, 0x80001040, 0x00000040,
180 0x80401040, 0x80000040, 0x80000000, 0x00001000, 0x80400000, 0x80001000, 0x00401040, 0x80400040,
181 0x80001000, 0x00001040, 0x00400000, 0x80401000, 0x00000040, 0x00400000, 0x00001000, 0x00401040
182 };
183
184 static const guint32 sbox5[64] =
185 {
186 0x00000080, 0x01040080, 0x01040000, 0x21000080, 0x00040000, 0x00000080, 0x20000000, 0x01040000,
187 0x20040080, 0x00040000, 0x01000080, 0x20040080, 0x21000080, 0x21040000, 0x00040080, 0x20000000,
188 0x01000000, 0x20040000, 0x20040000, 0x00000000, 0x20000080, 0x21040080, 0x21040080, 0x01000080,
189 0x21040000, 0x20000080, 0x00000000, 0x21000000, 0x01040080, 0x01000000, 0x21000000, 0x00040080,
190 0x00040000, 0x21000080, 0x00000080, 0x01000000, 0x20000000, 0x01040000, 0x21000080, 0x20040080,
191 0x01000080, 0x20000000, 0x21040000, 0x01040080, 0x20040080, 0x00000080, 0x01000000, 0x21040000,
192 0x21040080, 0x00040080, 0x21000000, 0x21040080, 0x01040000, 0x00000000, 0x20040000, 0x21000000,
193 0x00040080, 0x01000080, 0x20000080, 0x00040000, 0x00000000, 0x20040000, 0x01040080, 0x20000080
194 };
195
196 static const guint32 sbox6[64] =
197 {
198 0x10000008, 0x10200000, 0x00002000, 0x10202008, 0x10200000, 0x00000008, 0x10202008, 0x00200000,
199 0x10002000, 0x00202008, 0x00200000, 0x10000008, 0x00200008, 0x10002000, 0x10000000, 0x00002008,
200 0x00000000, 0x00200008, 0x10002008, 0x00002000, 0x00202000, 0x10002008, 0x00000008, 0x10200008,
201 0x10200008, 0x00000000, 0x00202008, 0x10202000, 0x00002008, 0x00202000, 0x10202000, 0x10000000,
202 0x10002000, 0x00000008, 0x10200008, 0x00202000, 0x10202008, 0x00200000, 0x00002008, 0x10000008,
203 0x00200000, 0x10002000, 0x10000000, 0x00002008, 0x10000008, 0x10202008, 0x00202000, 0x10200000,
204 0x00202008, 0x10202000, 0x00000000, 0x10200008, 0x00000008, 0x00002000, 0x10200000, 0x00202008,
205 0x00002000, 0x00200008, 0x10002008, 0x00000000, 0x10202000, 0x10000000, 0x00200008, 0x10002008
206 };
207
208 static const guint32 sbox7[64] =
209 {
210 0x00100000, 0x02100001, 0x02000401, 0x00000000, 0x00000400, 0x02000401, 0x00100401, 0x02100400,
211 0x02100401, 0x00100000, 0x00000000, 0x02000001, 0x00000001, 0x02000000, 0x02100001, 0x00000401,
212 0x02000400, 0x00100401, 0x00100001, 0x02000400, 0x02000001, 0x02100000, 0x02100400, 0x00100001,
213 0x02100000, 0x00000400, 0x00000401, 0x02100401, 0x00100400, 0x00000001, 0x02000000, 0x00100400,
214 0x02000000, 0x00100400, 0x00100000, 0x02000401, 0x02000401, 0x02100001, 0x02100001, 0x00000001,
215 0x00100001, 0x02000000, 0x02000400, 0x00100000, 0x02100400, 0x00000401, 0x00100401, 0x02100400,
216 0x00000401, 0x02000001, 0x02100401, 0x02100000, 0x00100400, 0x00000000, 0x00000001, 0x02100401,
217 0x00000000, 0x00100401, 0x02100000, 0x00000400, 0x02000001, 0x02000400, 0x00000400, 0x00100001
218 };
219
220 static const guint32 sbox8[64] =
221 {
222 0x08000820, 0x00000800, 0x00020000, 0x08020820, 0x08000000, 0x08000820, 0x00000020, 0x08000000,
223 0x00020020, 0x08020000, 0x08020820, 0x00020800, 0x08020800, 0x00020820, 0x00000800, 0x00000020,
224 0x08020000, 0x08000020, 0x08000800, 0x00000820, 0x00020800, 0x00020020, 0x08020020, 0x08020800,
225 0x00000820, 0x00000000, 0x00000000, 0x08020020, 0x08000020, 0x08000800, 0x00020820, 0x00020000,
226 0x00020820, 0x00020000, 0x08020800, 0x00000800, 0x00000020, 0x08020020, 0x00000800, 0x00020820,
227 0x08000800, 0x00000020, 0x08000020, 0x08020000, 0x08020020, 0x08000000, 0x00020000, 0x08000820,
228 0x00000000, 0x08020820, 0x00020020, 0x08000020, 0x08020000, 0x08000800, 0x08000820, 0x00000000,
229 0x08020820, 0x00020800, 0x00020800, 0x00000820, 0x00000820, 0x00020020, 0x08000000, 0x08020800
230 };
231
232
233
234 /*
235 * * These two tables are part of the 'permuted choice 1' function.
236 * * In this implementation several speed improvements are done.
237 * */
238 static const guint32 leftkey_swap[16] =
239 {
240 0x00000000, 0x00000001, 0x00000100, 0x00000101,
241 0x00010000, 0x00010001, 0x00010100, 0x00010101,
242 0x01000000, 0x01000001, 0x01000100, 0x01000101,
243 0x01010000, 0x01010001, 0x01010100, 0x01010101
244 };
245
246 static const guint32 rightkey_swap[16] =
247 {
248 0x00000000, 0x01000000, 0x00010000, 0x01010000,
249 0x00000100, 0x01000100, 0x00010100, 0x01010100,
250 0x00000001, 0x01000001, 0x00010001, 0x01010001,
251 0x00000101, 0x01000101, 0x00010101, 0x01010101,
252 };
253
254
255
256 /*
257 * Numbers of left shifts per round for encryption subkey schedule
258 * To calculate the decryption key scheduling we just reverse the
259 * ordering of the subkeys so we can omit the table for decryption
260 * subkey schedule.
261 */
262 static const guint8 encrypt_rotate_tab[16] =
263 {
264 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
265 };
266
267 /*
268 * Macro to swap bits across two words
269 **/
270 #define DO_PERMUTATION(a, temp, b, offset, mask) \
271 temp = ((a>>offset) ^ b) & mask; \
272 b ^= temp; \
273 a ^= temp<<offset;
274
275
276 /*
277 * This performs the 'initial permutation' for the data to be encrypted or decrypted
278 **/
279 #define INITIAL_PERMUTATION(left, temp, right) \
280 DO_PERMUTATION(left, temp, right, 4, 0x0f0f0f0f) \
281 DO_PERMUTATION(left, temp, right, 16, 0x0000ffff) \
282 DO_PERMUTATION(right, temp, left, 2, 0x33333333) \
283 DO_PERMUTATION(right, temp, left, 8, 0x00ff00ff) \
284 DO_PERMUTATION(left, temp, right, 1, 0x55555555)
285
286
287 /*
288 * The 'inverse initial permutation'
289 **/
290 #define FINAL_PERMUTATION(left, temp, right) \
291 DO_PERMUTATION(left, temp, right, 1, 0x55555555) \
292 DO_PERMUTATION(right, temp, left, 8, 0x00ff00ff) \
293 DO_PERMUTATION(right, temp, left, 2, 0x33333333) \
294 DO_PERMUTATION(left, temp, right, 16, 0x0000ffff) \
295 DO_PERMUTATION(left, temp, right, 4, 0x0f0f0f0f)
296
297
298 /*
299 * A full DES round including 'expansion function', 'sbox substitution'
300 * and 'primitive function P' but without swapping the left and right word.
301 **/
302 #define DES_ROUND(from, to, work, subkey) \
303 work = ((from<<1) | (from>>31)) ^ *subkey++; \
304 to ^= sbox8[ work & 0x3f ]; \
305 to ^= sbox6[ (work>>8) & 0x3f ]; \
306 to ^= sbox4[ (work>>16) & 0x3f ]; \
307 to ^= sbox2[ (work>>24) & 0x3f ]; \
308 work = ((from>>3) | (from<<29)) ^ *subkey++; \
309 to ^= sbox7[ work & 0x3f ]; \
310 to ^= sbox5[ (work>>8) & 0x3f ]; \
311 to ^= sbox3[ (work>>16) & 0x3f ]; \
312 to ^= sbox1[ (work>>24) & 0x3f ];
313
314
315 /*
316 * Macros to convert 8 bytes from/to 32bit words
317 **/
318 #define READ_64BIT_DATA(data, left, right) \
319 left = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; \
320 right = (data[4] << 24) | (data[5] << 16) | (data[6] << 8) | data[7];
321
322 #define WRITE_64BIT_DATA(data, left, right) \
323 data[0] = (left >> 24) &0xff; data[1] = (left >> 16) &0xff; \
324 data[2] = (left >> 8) &0xff; data[3] = left &0xff; \
325 data[4] = (right >> 24) &0xff; data[5] = (right >> 16) &0xff; \
326 data[6] = (right >> 8) &0xff; data[7] = right &0xff;
327
328
329
330
331
332
333 /*
334 * des_key_schedule(): Calculate 16 subkeys pairs (even/odd) for
335 * 16 encryption rounds.
336 * To calculate subkeys for decryption the caller
337 * have to reorder the generated subkeys.
338 *
339 * rawkey: 8 Bytes of key data
340 * subkey: Array of at least 32 guint32s. Will be filled
341 * with calculated subkeys.
342 *
343 **/
344 static void
345 des_key_schedule (const guint8 * rawkey, guint32 * subkey)
346 {
347 guint32 left, right, work;
348 int round;
349
350 READ_64BIT_DATA (rawkey, left, right)
351
352 DO_PERMUTATION (right, work, left, 4, 0x0f0f0f0f)
353 DO_PERMUTATION (right, work, left, 0, 0x10101010)
354
355 left = (leftkey_swap[(left >> 0) & 0xf] << 3) | (leftkey_swap[(left >> 8) & 0xf] << 2)
356 | (leftkey_swap[(left >> 16) & 0xf] << 1) | (leftkey_swap[(left >> 24) & 0xf])
357 | (leftkey_swap[(left >> 5) & 0xf] << 7) | (leftkey_swap[(left >> 13) & 0xf] << 6)
358 | (leftkey_swap[(left >> 21) & 0xf] << 5) | (leftkey_swap[(left >> 29) & 0xf] << 4);
359
360 left &= 0x0fffffff;
361
362 right = (rightkey_swap[(right >> 1) & 0xf] << 3) | (rightkey_swap[(right >> 9) & 0xf] << 2)
363 | (rightkey_swap[(right >> 17) & 0xf] << 1) | (rightkey_swap[(right >> 25) & 0xf])
364 | (rightkey_swap[(right >> 4) & 0xf] << 7) | (rightkey_swap[(right >> 12) & 0xf] << 6)
365 | (rightkey_swap[(right >> 20) & 0xf] << 5) | (rightkey_swap[(right >> 28) & 0xf] << 4);
366
367 right &= 0x0fffffff;
368
369 for (round = 0; round < 16; ++round)
370 {
371 left = ((left << encrypt_rotate_tab[round]) | (left >> (28 - encrypt_rotate_tab[round]))) & 0x0fffffff;
372 right = ((right << encrypt_rotate_tab[round]) | (right >> (28 - encrypt_rotate_tab[round]))) & 0x0fffffff;
373
374 *subkey++ = ((left << 4) & 0x24000000)
375 | ((left << 28) & 0x10000000)
376 | ((left << 14) & 0x08000000)
377 | ((left << 18) & 0x02080000)
378 | ((left << 6) & 0x01000000)
379 | ((left << 9) & 0x00200000)
380 | ((left >> 1) & 0x00100000)
381 | ((left << 10) & 0x00040000)
382 | ((left << 2) & 0x00020000)
383 | ((left >> 10) & 0x00010000)
384 | ((right >> 13) & 0x00002000)
385 | ((right >> 4) & 0x00001000)
386 | ((right << 6) & 0x00000800)
387 | ((right >> 1) & 0x00000400)
388 | ((right >> 14) & 0x00000200)
389 | (right & 0x00000100)
390 | ((right >> 5) & 0x00000020)
391 | ((right >> 10) & 0x00000010)
392 | ((right >> 3) & 0x00000008)
393 | ((right >> 18) & 0x00000004)
394 | ((right >> 26) & 0x00000002)
395 | ((right >> 24) & 0x00000001);
396
397 *subkey++ = ((left << 15) & 0x20000000)
398 | ((left << 17) & 0x10000000)
399 | ((left << 10) & 0x08000000)
400 | ((left << 22) & 0x04000000)
401 | ((left >> 2) & 0x02000000)
402 | ((left << 1) & 0x01000000)
403 | ((left << 16) & 0x00200000)
404 | ((left << 11) & 0x00100000)
405 | ((left << 3) & 0x00080000)
406 | ((left >> 6) & 0x00040000)
407 | ((left << 15) & 0x00020000)
408 | ((left >> 4) & 0x00010000)
409 | ((right >> 2) & 0x00002000)
410 | ((right << 8) & 0x00001000)
411 | ((right >> 14) & 0x00000808)
412 | ((right >> 9) & 0x00000400)
413 | ((right) & 0x00000200)
414 | ((right << 7) & 0x00000100)
415 | ((right >> 7) & 0x00000020)
416 | ((right >> 3) & 0x00000011)
417 | ((right << 2) & 0x00000004)
418 | ((right >> 21) & 0x00000002);
419 }
420 }
421
422
423
424 /*
425 * Fill a DES context with subkeys calculated from a 64bit key.
426 * Does not check parity bits, but simply ignore them.
427 * Does not check for weak keys.
428 **/
429 static void
430 des_set_key (PurpleCipherContext *context, const guchar * key)
431 {
432 struct _des_ctx *ctx = purple_cipher_context_get_data(context);
433 int i;
434
435 des_key_schedule (key, ctx->encrypt_subkeys);
436
437 for(i=0; i<32; i+=2)
438 {
439 ctx->decrypt_subkeys[i] = ctx->encrypt_subkeys[30-i];
440 ctx->decrypt_subkeys[i+1] = ctx->encrypt_subkeys[31-i];
441 }
442 }
443
444
445
446 /*
447 * Electronic Codebook Mode DES encryption/decryption of data according
448 * to 'mode'.
449 **/
450 static int
451 des_ecb_crypt (struct _des_ctx *ctx, const guint8 * from, guint8 * to, int mode)
452 {
453 guint32 left, right, work;
454 guint32 *keys;
455
456 keys = mode ? ctx->decrypt_subkeys : ctx->encrypt_subkeys;
457
458 READ_64BIT_DATA (from, left, right)
459 INITIAL_PERMUTATION (left, work, right)
460
461 DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
462 DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
463 DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
464 DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
465 DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
466 DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
467 DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
468 DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
469
470 FINAL_PERMUTATION (right, work, left)
471 WRITE_64BIT_DATA (to, right, left)
472
473 return 0;
474 }
475
476 static gint
477 des_encrypt(PurpleCipherContext *context, const guchar data[],
478 size_t len, guchar output[], size_t *outlen) {
479 int offset = 0;
480 int i = 0;
481 int tmp;
482 guint8 buf[8] = {0,0,0,0,0,0,0,0};
483 while(offset+8<=len) {
484 des_ecb_crypt(purple_cipher_context_get_data(context),
485 data+offset,
486 output+offset,
487 0);
488 offset+=8;
489 }
490 *outlen = len;
491 if(offset<len) {
492 *outlen += len - offset;
493 tmp = offset;
494 while(tmp<len) {
495 buf[i++] = data[tmp];
496 tmp++;
497 }
498 des_ecb_crypt(purple_cipher_context_get_data(context),
499 buf,
500 output+offset,
501 0);
502 }
503 return 0;
504 }
505
506 static gint
507 des_decrypt(PurpleCipherContext *context, const guchar data[],
508 size_t len, guchar output[], size_t *outlen) {
509 int offset = 0;
510 int i = 0;
511 int tmp;
512 guint8 buf[8] = {0,0,0,0,0,0,0,0};
513 while(offset+8<=len) {
514 des_ecb_crypt(purple_cipher_context_get_data(context),
515 data+offset,
516 output+offset,
517 1);
518 offset+=8;
519 }
520 *outlen = len;
521 if(offset<len) {
522 *outlen += len - offset;
523 tmp = offset;
524 while(tmp<len) {
525 buf[i++] = data[tmp];
526 tmp++;
527 }
528 des_ecb_crypt(purple_cipher_context_get_data(context),
529 buf,
530 output+offset,
531 1);
532 }
533 return 0;
534 }
535
536 static void
537 des_init(PurpleCipherContext *context, gpointer extra) {
538 struct _des_ctx *mctx;
539 mctx = g_new0(struct _des_ctx, 1);
540 purple_cipher_context_set_data(context, mctx);
541 }
542
543 static void
544 des_uninit(PurpleCipherContext *context) {
545 struct _des_ctx *des_context;
546
547 des_context = purple_cipher_context_get_data(context);
548 memset(des_context, 0, sizeof(*des_context));
549
550 g_free(des_context);
551 des_context = NULL;
552 }
553
554 static PurpleCipherOps DESOps = {
555 NULL, /* Set option */
556 NULL, /* Get option */
557 des_init, /* init */
558 NULL, /* reset */
559 des_uninit, /* uninit */
560 NULL, /* set iv */
561 NULL, /* append */
562 NULL, /* digest */
563 des_encrypt, /* encrypt */
564 des_decrypt, /* decrypt */
565 NULL, /* set salt */
566 NULL, /* get salt size */
567 des_set_key, /* set key */
568 NULL, /* get key size */
569 NULL, /* set batch mode */
570 NULL, /* get batch mode */
571 NULL, /* get block size */
572 NULL /* set key with len */
573 };
574
575 /******************************************************************************
576 * Triple-DES
577 *****************************************************************************/
578
579 typedef struct _des3_ctx
580 {
581 PurpleCipherBatchMode mode;
582 guchar iv[8];
583 /* First key for encryption */
584 struct _des_ctx key1;
585 /* Second key for decryption */
586 struct _des_ctx key2;
587 /* Third key for encryption */
588 struct _des_ctx key3;
589 } des3_ctx[1];
590
591 /*
592 * Fill a DES3 context with subkeys calculated from 3 64bit key.
593 * Does not check parity bits, but simply ignore them.
594 * Does not check for weak keys.
595 **/
596 static void
597 des3_set_key(PurpleCipherContext *context, const guchar * key)
598 {
599 struct _des3_ctx *ctx = purple_cipher_context_get_data(context);
600 int i;
601
602 des_key_schedule (key + 0, ctx->key1.encrypt_subkeys);
603 des_key_schedule (key + 8, ctx->key2.encrypt_subkeys);
604 des_key_schedule (key + 16, ctx->key3.encrypt_subkeys);
605
606 for (i = 0; i < 32; i += 2)
607 {
608 ctx->key1.decrypt_subkeys[i] = ctx->key1.encrypt_subkeys[30-i];
609 ctx->key1.decrypt_subkeys[i+1] = ctx->key1.encrypt_subkeys[31-i];
610 ctx->key2.decrypt_subkeys[i] = ctx->key2.encrypt_subkeys[30-i];
611 ctx->key2.decrypt_subkeys[i+1] = ctx->key2.encrypt_subkeys[31-i];
612 ctx->key3.decrypt_subkeys[i] = ctx->key3.encrypt_subkeys[30-i];
613 ctx->key3.decrypt_subkeys[i+1] = ctx->key3.encrypt_subkeys[31-i];
614 }
615 }
616
617 static gint
618 des3_ecb_encrypt(struct _des3_ctx *ctx, const guchar data[],
619 size_t len, guchar output[], size_t *outlen)
620 {
621 int offset = 0;
622 int i = 0;
623 int tmp;
624 guint8 buf[8] = {0,0,0,0,0,0,0,0};
625 while (offset + 8 <= len) {
626 des_ecb_crypt(&ctx->key1,
627 data+offset,
628 output+offset,
629 0);
630 des_ecb_crypt(&ctx->key2,
631 output+offset,
632 buf,
633 1);
634 des_ecb_crypt(&ctx->key3,
635 buf,
636 output+offset,
637 0);
638 offset += 8;
639 }
640 *outlen = len;
641 if (offset < len) {
642 *outlen += len - offset;
643 tmp = offset;
644 memset(buf, 0, 8);
645 while (tmp < len) {
646 buf[i++] = data[tmp];
647 tmp++;
648 }
649 des_ecb_crypt(&ctx->key1,
650 buf,
651 output+offset,
652 0);
653 des_ecb_crypt(&ctx->key2,
654 output+offset,
655 buf,
656 1);
657 des_ecb_crypt(&ctx->key3,
658 buf,
659 output+offset,
660 0);
661 }
662 return 0;
663 }
664
665 static gint
666 des3_cbc_encrypt(struct _des3_ctx *ctx, const guchar data[],
667 size_t len, guchar output[], size_t *outlen)
668 {
669 int offset = 0;
670 int i = 0;
671 int tmp;
672 guint8 buf[8];
673 memcpy(buf, ctx->iv, 8);
674 while (offset + 8 <= len) {
675 for (i = 0; i < 8; i++)
676 buf[i] ^= data[offset + i];
677 des_ecb_crypt(&ctx->key1,
678 buf,
679 output+offset,
680 0);
681 des_ecb_crypt(&ctx->key2,
682 output+offset,
683 buf,
684 1);
685 des_ecb_crypt(&ctx->key3,
686 buf,
687 output+offset,
688 0);
689 memcpy(buf, output+offset, 8);
690 offset += 8;
691 }
692 *outlen = len;
693 if (offset < len) {
694 *outlen += len - offset;
695 tmp = offset;
696 i = 0;
697 while (tmp < len) {
698 buf[i++] ^= data[tmp];
699 tmp++;
700 }
701 des_ecb_crypt(&ctx->key1,
702 buf,
703 output+offset,
704 0);
705 des_ecb_crypt(&ctx->key2,
706 output+offset,
707 buf,
708 1);
709 des_ecb_crypt(&ctx->key3,
710 buf,
711 output+offset,
712 0);
713 }
714 return 0;
715 }
716
717 static gint
718 des3_encrypt(PurpleCipherContext *context, const guchar data[],
719 size_t len, guchar output[], size_t *outlen)
720 {
721 struct _des3_ctx *ctx = purple_cipher_context_get_data(context);
722
723 if (ctx->mode == PURPLE_CIPHER_BATCH_MODE_ECB) {
724 return des3_ecb_encrypt(ctx, data, len, output, outlen);
725 } else if (ctx->mode == PURPLE_CIPHER_BATCH_MODE_CBC) {
726 return des3_cbc_encrypt(ctx, data, len, output, outlen);
727 } else {
728 g_return_val_if_reached(0);
729 }
730
731 return 0;
732 }
733
734 static gint
735 des3_ecb_decrypt(struct _des3_ctx *ctx, const guchar data[],
736 size_t len, guchar output[], size_t *outlen)
737 {
738 int offset = 0;
739 int i = 0;
740 int tmp;
741 guint8 buf[8] = {0,0,0,0,0,0,0,0};
742 while (offset + 8 <= len) {
743 /* NOTE: Apply key in reverse */
744 des_ecb_crypt(&ctx->key3,
745 data+offset,
746 output+offset,
747 1);
748 des_ecb_crypt(&ctx->key2,
749 output+offset,
750 buf,
751 0);
752 des_ecb_crypt(&ctx->key1,
753 buf,
754 output+offset,
755 1);
756 offset+=8;
757 }
758 *outlen = len;
759 if (offset < len) {
760 *outlen += len - offset;
761 tmp = offset;
762 memset(buf, 0, 8);
763 while (tmp < len) {
764 buf[i++] = data[tmp];
765 tmp++;
766 }
767 des_ecb_crypt(&ctx->key3,
768 buf,
769 output+offset,
770 1);
771 des_ecb_crypt(&ctx->key2,
772 output+offset,
773 buf,
774 0);
775 des_ecb_crypt(&ctx->key1,
776 buf,
777 output+offset,
778 1);
779 }
780 return 0;
781 }
782
783 static gint
784 des3_cbc_decrypt(struct _des3_ctx *ctx, const guchar data[],
785 size_t len, guchar output[], size_t *outlen)
786 {
787 int offset = 0;
788 int i = 0;
789 int tmp;
790 guint8 buf[8] = {0,0,0,0,0,0,0,0};
791 guint8 link[8];
792 memcpy(link, ctx->iv, 8);
793 while (offset + 8 <= len) {
794 des_ecb_crypt(&ctx->key3,
795 data+offset,
796 output+offset,
797 1);
798 des_ecb_crypt(&ctx->key2,
799 output+offset,
800 buf,
801 0);
802 des_ecb_crypt(&ctx->key1,
803 buf,
804 output+offset,
805 1);
806 for (i = 0; i < 8; i++)
807 output[offset + i] ^= link[i];
808 memcpy(link, data + offset, 8);
809 offset+=8;
810 }
811 *outlen = len;
812 if(offset<len) {
813 *outlen += len - offset;
814 tmp = offset;
815 memset(buf, 0, 8);
816 i = 0;
817 while(tmp<len) {
818 buf[i++] = data[tmp];
819 tmp++;
820 }
821 des_ecb_crypt(&ctx->key3,
822 buf,
823 output+offset,
824 1);
825 des_ecb_crypt(&ctx->key2,
826 output+offset,
827 buf,
828 0);
829 des_ecb_crypt(&ctx->key1,
830 buf,
831 output+offset,
832 1);
833 for (i = 0; i < 8; i++)
834 output[offset + i] ^= link[i];
835 }
836 return 0;
837 }
838
839 static gint
840 des3_decrypt(PurpleCipherContext *context, const guchar data[],
841 size_t len, guchar output[], size_t *outlen)
842 {
843 struct _des3_ctx *ctx = purple_cipher_context_get_data(context);
844
845 if (ctx->mode == PURPLE_CIPHER_BATCH_MODE_ECB) {
846 return des3_ecb_decrypt(ctx, data, len, output, outlen);
847 } else if (ctx->mode == PURPLE_CIPHER_BATCH_MODE_CBC) {
848 return des3_cbc_decrypt(ctx, data, len, output, outlen);
849 } else {
850 g_return_val_if_reached(0);
851 }
852
853 return 0;
854 }
855
856 static void
857 des3_set_batch(PurpleCipherContext *context, PurpleCipherBatchMode mode)
858 {
859 struct _des3_ctx *ctx = purple_cipher_context_get_data(context);
860
861 ctx->mode = mode;
862 }
863
864 static PurpleCipherBatchMode
865 des3_get_batch(PurpleCipherContext *context)
866 {
867 struct _des3_ctx *ctx = purple_cipher_context_get_data(context);
868
869 return ctx->mode;
870 }
871
872 static void
873 des3_set_iv(PurpleCipherContext *context, guchar *iv, size_t len)
874 {
875 struct _des3_ctx *ctx;
876
877 g_return_if_fail(len == 8);
878
879 ctx = purple_cipher_context_get_data(context);
880
881 memcpy(ctx->iv, iv, len);
882 }
883
884 static void
885 des3_init(PurpleCipherContext *context, gpointer extra)
886 {
887 struct _des3_ctx *mctx;
888 mctx = g_new0(struct _des3_ctx, 1);
889 purple_cipher_context_set_data(context, mctx);
890 }
891
892 static void
893 des3_uninit(PurpleCipherContext *context)
894 {
895 struct _des3_ctx *des3_context;
896
897 des3_context = purple_cipher_context_get_data(context);
898 memset(des3_context, 0, sizeof(*des3_context));
899
900 g_free(des3_context);
901 des3_context = NULL;
902 }
903
904 static PurpleCipherOps DES3Ops = {
905 NULL, /* Set option */
906 NULL, /* Get option */
907 des3_init, /* init */
908 NULL, /* reset */
909 des3_uninit, /* uninit */
910 des3_set_iv, /* set iv */
911 NULL, /* append */
912 NULL, /* digest */
913 des3_encrypt, /* encrypt */
914 des3_decrypt, /* decrypt */
915 NULL, /* set salt */
916 NULL, /* get salt size */
917 des3_set_key, /* set key */
918 NULL, /* get key size */
919 des3_set_batch, /* set batch mode */
920 des3_get_batch, /* get batch mode */
921 NULL, /* get block size */
922 NULL /* set key with len */
923 };
924
925 /******************************************************************************* 123 /*******************************************************************************
926 * Structs 124 * Structs
927 ******************************************************************************/ 125 ******************************************************************************/
928 struct _PurpleCipher { 126 struct _PurpleCipher {
929 gchar *name; /**< Internal name - used for searching */ 127 gchar *name; /**< Internal name - used for searching */
1108 /* This are implemented in the purple-ciphers sublibrary built in the ciphers 306 /* This are implemented in the purple-ciphers sublibrary built in the ciphers
1109 * directory. We could put a header file in there, but it's less hassle for 307 * directory. We could put a header file in there, but it's less hassle for
1110 * the developer to just add it here since they have to register it here as 308 * the developer to just add it here since they have to register it here as
1111 * well. 309 * well.
1112 */ 310 */
311 PurpleCipherOps *purple_des_cipher_get_ops();
312 PurpleCipherOps *purple_des3_cipher_get_ops();
1113 PurpleCipherOps *purple_hmac_cipher_get_ops(); 313 PurpleCipherOps *purple_hmac_cipher_get_ops();
1114 PurpleCipherOps *purple_md4_cipher_get_ops(); 314 PurpleCipherOps *purple_md4_cipher_get_ops();
1115 PurpleCipherOps *purple_md5_cipher_get_ops(); 315 PurpleCipherOps *purple_md5_cipher_get_ops();
1116 PurpleCipherOps *purple_rc4_cipher_get_ops(); 316 PurpleCipherOps *purple_rc4_cipher_get_ops();
1117 PurpleCipherOps *purple_sha1_cipher_get_ops(); 317 PurpleCipherOps *purple_sha1_cipher_get_ops();
1135 purple_ciphers_register_cipher("md5", purple_md5_cipher_get_ops()); 335 purple_ciphers_register_cipher("md5", purple_md5_cipher_get_ops());
1136 purple_ciphers_register_cipher("sha1", purple_sha1_cipher_get_ops()); 336 purple_ciphers_register_cipher("sha1", purple_sha1_cipher_get_ops());
1137 purple_ciphers_register_cipher("sha256", purple_sha256_cipher_get_ops()); 337 purple_ciphers_register_cipher("sha256", purple_sha256_cipher_get_ops());
1138 purple_ciphers_register_cipher("md4", purple_md4_cipher_get_ops()); 338 purple_ciphers_register_cipher("md4", purple_md4_cipher_get_ops());
1139 purple_ciphers_register_cipher("hmac", purple_hmac_cipher_get_ops()); 339 purple_ciphers_register_cipher("hmac", purple_hmac_cipher_get_ops());
1140 purple_ciphers_register_cipher("des", &DESOps); 340 purple_ciphers_register_cipher("des", purple_des_cipher_get_ops());
1141 purple_ciphers_register_cipher("des3", &DES3Ops); 341 purple_ciphers_register_cipher("des3", purple_des3_cipher_get_ops());
1142 purple_ciphers_register_cipher("rc4", purple_rc4_cipher_get_ops()); 342 purple_ciphers_register_cipher("rc4", purple_rc4_cipher_get_ops());
1143 } 343 }
1144 344
1145 void 345 void
1146 purple_ciphers_uninit() { 346 purple_ciphers_uninit() {