1 /*
2 * purple
3 *
4 * Purple is the legal property of its developers, whose names are too numerous
5 * to list here. Please refer to the COPYRIGHT file distributed with this
6 * source distribution.
7 *
8 * Original des taken from gpg
9 *
10 * des.c - DES and Triple-DES encryption/decryption Algorithm
11 * Copyright (C) 1998 Free Software Foundation, Inc.
12 *
13 * Please see below for more legal information!
14 *
15 * According to the definition of DES in FIPS PUB 46-2 from December 1993.
16 * For a description of triple encryption, see:
17 * Bruce Schneier: Applied Cryptography. Second Edition.
18 * John Wiley & Sons, 1996. ISBN 0-471-12845-7. Pages 358 ff.
19 *
20 * This file is part of GnuPG.
21 *
22 * This program is free software; you can redistribute it and/or modify
23 * it under the terms of the GNU General Public License as published by
24 * the Free Software Foundation; either version 2 of the License, or
25 * (at your option) any later version.
26 *
27 * This program is distributed in the hope that it will be useful,
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 * GNU General Public License for more details.
31 *
32 * You should have received a copy of the GNU General Public License
33 * along with this program; if not, write to the Free Software
34 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
35 */
36 #include <cipher.h>
37
38 /******************************************************************************
39 * DES
40 *****************************************************************************/
41 typedef struct _des_ctx
42 {
43 guint32 encrypt_subkeys[32];
44 guint32 decrypt_subkeys[32];
45 } des_ctx[1];
46
47 /*
48 * The s-box values are permuted according to the 'primitive function P'
49 */
50 static const guint32 sbox1[64] =
51 {
52 0x00808200, 0x00000000, 0x00008000, 0x00808202, 0x00808002, 0x00008202, 0x00000002, 0x00008000,
53 0x00000200, 0x00808200, 0x00808202, 0x00000200, 0x00800202, 0x00808002, 0x00800000, 0x00000002,
54 0x00000202, 0x00800200, 0x00800200, 0x00008200, 0x00008200, 0x00808000, 0x00808000, 0x00800202,
55 0x00008002, 0x00800002, 0x00800002, 0x00008002, 0x00000000, 0x00000202, 0x00008202, 0x00800000,
56 0x00008000, 0x00808202, 0x00000002, 0x00808000, 0x00808200, 0x00800000, 0x00800000, 0x00000200,
57 0x00808002, 0x00008000, 0x00008200, 0x00800002, 0x00000200, 0x00000002, 0x00800202, 0x00008202,
58 0x00808202, 0x00008002, 0x00808000, 0x00800202, 0x00800002, 0x00000202, 0x00008202, 0x00808200,
59 0x00000202, 0x00800200, 0x00800200, 0x00000000, 0x00008002, 0x00008200, 0x00000000, 0x00808002
60 };
61
62 static const guint32 sbox2[64] =
63 {
64 0x40084010, 0x40004000, 0x00004000, 0x00084010, 0x00080000, 0x00000010, 0x40080010, 0x40004010,
65 0x40000010, 0x40084010, 0x40084000, 0x40000000, 0x40004000, 0x00080000, 0x00000010, 0x40080010,
66 0x00084000, 0x00080010, 0x40004010, 0x00000000, 0x40000000, 0x00004000, 0x00084010, 0x40080000,
67 0x00080010, 0x40000010, 0x00000000, 0x00084000, 0x00004010, 0x40084000, 0x40080000, 0x00004010,
68 0x00000000, 0x00084010, 0x40080010, 0x00080000, 0x40004010, 0x40080000, 0x40084000, 0x00004000,
69 0x40080000, 0x40004000, 0x00000010, 0x40084010, 0x00084010, 0x00000010, 0x00004000, 0x40000000,
70 0x00004010, 0x40084000, 0x00080000, 0x40000010, 0x00080010, 0x40004010, 0x40000010, 0x00080010,
71 0x00084000, 0x00000000, 0x40004000, 0x00004010, 0x40000000, 0x40080010, 0x40084010, 0x00084000
72 };
73
74 static const guint32 sbox3[64] =
75 {
76 0x00000104, 0x04010100, 0x00000000, 0x04010004, 0x04000100, 0x00000000, 0x00010104, 0x04000100,
77 0x00010004, 0x04000004, 0x04000004, 0x00010000, 0x04010104, 0x00010004, 0x04010000, 0x00000104,
78 0x04000000, 0x00000004, 0x04010100, 0x00000100, 0x00010100, 0x04010000, 0x04010004, 0x00010104,
79 0x04000104, 0x00010100, 0x00010000, 0x04000104, 0x00000004, 0x04010104, 0x00000100, 0x04000000,
80 0x04010100, 0x04000000, 0x00010004, 0x00000104, 0x00010000, 0x04010100, 0x04000100, 0x00000000,
81 0x00000100, 0x00010004, 0x04010104, 0x04000100, 0x04000004, 0x00000100, 0x00000000, 0x04010004,
82 0x04000104, 0x00010000, 0x04000000, 0x04010104, 0x00000004, 0x00010104, 0x00010100, 0x04000004,
83 0x04010000, 0x04000104, 0x00000104, 0x04010000, 0x00010104, 0x00000004, 0x04010004, 0x00010100
84 };
85
86 static const guint32 sbox4[64] =
87 {
88 0x80401000, 0x80001040, 0x80001040, 0x00000040, 0x00401040, 0x80400040, 0x80400000, 0x80001000,
89 0x00000000, 0x00401000, 0x00401000, 0x80401040, 0x80000040, 0x00000000, 0x00400040, 0x80400000,
90 0x80000000, 0x00001000, 0x00400000, 0x80401000, 0x00000040, 0x00400000, 0x80001000, 0x00001040,
91 0x80400040, 0x80000000, 0x00001040, 0x00400040, 0x00001000, 0x00401040, 0x80401040, 0x80000040,
92 0x00400040, 0x80400000, 0x00401000, 0x80401040, 0x80000040, 0x00000000, 0x00000000, 0x00401000,
93 0x00001040, 0x00400040, 0x80400040, 0x80000000, 0x80401000, 0x80001040, 0x80001040, 0x00000040,
94 0x80401040, 0x80000040, 0x80000000, 0x00001000, 0x80400000, 0x80001000, 0x00401040, 0x80400040,
95 0x80001000, 0x00001040, 0x00400000, 0x80401000, 0x00000040, 0x00400000, 0x00001000, 0x00401040
96 };
97
98 static const guint32 sbox5[64] =
99 {
100 0x00000080, 0x01040080, 0x01040000, 0x21000080, 0x00040000, 0x00000080, 0x20000000, 0x01040000,
101 0x20040080, 0x00040000, 0x01000080, 0x20040080, 0x21000080, 0x21040000, 0x00040080, 0x20000000,
102 0x01000000, 0x20040000, 0x20040000, 0x00000000, 0x20000080, 0x21040080, 0x21040080, 0x01000080,
103 0x21040000, 0x20000080, 0x00000000, 0x21000000, 0x01040080, 0x01000000, 0x21000000, 0x00040080,
104 0x00040000, 0x21000080, 0x00000080, 0x01000000, 0x20000000, 0x01040000, 0x21000080, 0x20040080,
105 0x01000080, 0x20000000, 0x21040000, 0x01040080, 0x20040080, 0x00000080, 0x01000000, 0x21040000,
106 0x21040080, 0x00040080, 0x21000000, 0x21040080, 0x01040000, 0x00000000, 0x20040000, 0x21000000,
107 0x00040080, 0x01000080, 0x20000080, 0x00040000, 0x00000000, 0x20040000, 0x01040080, 0x20000080
108 };
109
110 static const guint32 sbox6[64] =
111 {
112 0x10000008, 0x10200000, 0x00002000, 0x10202008, 0x10200000, 0x00000008, 0x10202008, 0x00200000,
113 0x10002000, 0x00202008, 0x00200000, 0x10000008, 0x00200008, 0x10002000, 0x10000000, 0x00002008,
114 0x00000000, 0x00200008, 0x10002008, 0x00002000, 0x00202000, 0x10002008, 0x00000008, 0x10200008,
115 0x10200008, 0x00000000, 0x00202008, 0x10202000, 0x00002008, 0x00202000, 0x10202000, 0x10000000,
116 0x10002000, 0x00000008, 0x10200008, 0x00202000, 0x10202008, 0x00200000, 0x00002008, 0x10000008,
117 0x00200000, 0x10002000, 0x10000000, 0x00002008, 0x10000008, 0x10202008, 0x00202000, 0x10200000,
118 0x00202008, 0x10202000, 0x00000000, 0x10200008, 0x00000008, 0x00002000, 0x10200000, 0x00202008,
119 0x00002000, 0x00200008, 0x10002008, 0x00000000, 0x10202000, 0x10000000, 0x00200008, 0x10002008
120 };
121
122 static const guint32 sbox7[64] =
123 {
124 0x00100000, 0x02100001, 0x02000401, 0x00000000, 0x00000400, 0x02000401, 0x00100401, 0x02100400,
125 0x02100401, 0x00100000, 0x00000000, 0x02000001, 0x00000001, 0x02000000, 0x02100001, 0x00000401,
126 0x02000400, 0x00100401, 0x00100001, 0x02000400, 0x02000001, 0x02100000, 0x02100400, 0x00100001,
127 0x02100000, 0x00000400, 0x00000401, 0x02100401, 0x00100400, 0x00000001, 0x02000000, 0x00100400,
128 0x02000000, 0x00100400, 0x00100000, 0x02000401, 0x02000401, 0x02100001, 0x02100001, 0x00000001,
129 0x00100001, 0x02000000, 0x02000400, 0x00100000, 0x02100400, 0x00000401, 0x00100401, 0x02100400,
130 0x00000401, 0x02000001, 0x02100401, 0x02100000, 0x00100400, 0x00000000, 0x00000001, 0x02100401,
131 0x00000000, 0x00100401, 0x02100000, 0x00000400, 0x02000001, 0x02000400, 0x00000400, 0x00100001
132 };
133
134 static const guint32 sbox8[64] =
135 {
136 0x08000820, 0x00000800, 0x00020000, 0x08020820, 0x08000000, 0x08000820, 0x00000020, 0x08000000,
137 0x00020020, 0x08020000, 0x08020820, 0x00020800, 0x08020800, 0x00020820, 0x00000800, 0x00000020,
138 0x08020000, 0x08000020, 0x08000800, 0x00000820, 0x00020800, 0x00020020, 0x08020020, 0x08020800,
139 0x00000820, 0x00000000, 0x00000000, 0x08020020, 0x08000020, 0x08000800, 0x00020820, 0x00020000,
140 0x00020820, 0x00020000, 0x08020800, 0x00000800, 0x00000020, 0x08020020, 0x00000800, 0x00020820,
141 0x08000800, 0x00000020, 0x08000020, 0x08020000, 0x08020020, 0x08000000, 0x00020000, 0x08000820,
142 0x00000000, 0x08020820, 0x00020020, 0x08000020, 0x08020000, 0x08000800, 0x08000820, 0x00000000,
143 0x08020820, 0x00020800, 0x00020800, 0x00000820, 0x00000820, 0x00020020, 0x08000000, 0x08020800
144 };
145
146
147 /*
148 * * These two tables are part of the 'permuted choice 1' function.
149 * * In this implementation several speed improvements are done.
150 * */
151 static const guint32 leftkey_swap[16] =
152 {
153 0x00000000, 0x00000001, 0x00000100, 0x00000101,
154 0x00010000, 0x00010001, 0x00010100, 0x00010101,
155 0x01000000, 0x01000001, 0x01000100, 0x01000101,
156 0x01010000, 0x01010001, 0x01010100, 0x01010101
157 };
158
159 static const guint32 rightkey_swap[16] =
160 {
161 0x00000000, 0x01000000, 0x00010000, 0x01010000,
162 0x00000100, 0x01000100, 0x00010100, 0x01010100,
163 0x00000001, 0x01000001, 0x00010001, 0x01010001,
164 0x00000101, 0x01000101, 0x00010101, 0x01010101,
165 };
166
167
168 /*
169 * Numbers of left shifts per round for encryption subkey schedule
170 * To calculate the decryption key scheduling we just reverse the
171 * ordering of the subkeys so we can omit the table for decryption
172 * subkey schedule.
173 */
174 static const guint8 encrypt_rotate_tab[16] =
175 {
176 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
177 };
178
179 /*
180 * Macro to swap bits across two words
181 **/
182 #define DO_PERMUTATION(a, temp, b, offset, mask) \
183 temp = ((a>>offset) ^ b) & mask; \
184 b ^= temp; \
185 a ^= temp<<offset;
186
187
188 /*
189 * This performs the 'initial permutation' for the data to be encrypted or decrypted
190 **/
191 #define INITIAL_PERMUTATION(left, temp, right) \
192 DO_PERMUTATION(left, temp, right, 4, 0x0f0f0f0f) \
193 DO_PERMUTATION(left, temp, right, 16, 0x0000ffff) \
194 DO_PERMUTATION(right, temp, left, 2, 0x33333333) \
195 DO_PERMUTATION(right, temp, left, 8, 0x00ff00ff) \
196 DO_PERMUTATION(left, temp, right, 1, 0x55555555)
197
198
199 /*
200 * The 'inverse initial permutation'
201 **/
202 #define FINAL_PERMUTATION(left, temp, right) \
203 DO_PERMUTATION(left, temp, right, 1, 0x55555555) \
204 DO_PERMUTATION(right, temp, left, 8, 0x00ff00ff) \
205 DO_PERMUTATION(right, temp, left, 2, 0x33333333) \
206 DO_PERMUTATION(left, temp, right, 16, 0x0000ffff) \
207 DO_PERMUTATION(left, temp, right, 4, 0x0f0f0f0f)
208
209
210 /*
211 * A full DES round including 'expansion function', 'sbox substitution'
212 * and 'primitive function P' but without swapping the left and right word.
213 **/
214 #define DES_ROUND(from, to, work, subkey) \
215 work = ((from<<1) | (from>>31)) ^ *subkey++; \
216 to ^= sbox8[ work & 0x3f ]; \
217 to ^= sbox6[ (work>>8) & 0x3f ]; \
218 to ^= sbox4[ (work>>16) & 0x3f ]; \
219 to ^= sbox2[ (work>>24) & 0x3f ]; \
220 work = ((from>>3) | (from<<29)) ^ *subkey++; \
221 to ^= sbox7[ work & 0x3f ]; \
222 to ^= sbox5[ (work>>8) & 0x3f ]; \
223 to ^= sbox3[ (work>>16) & 0x3f ]; \
224 to ^= sbox1[ (work>>24) & 0x3f ];
225
226
227 /*
228 * Macros to convert 8 bytes from/to 32bit words
229 **/
230 #define READ_64BIT_DATA(data, left, right) \
231 left = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; \
232 right = (data[4] << 24) | (data[5] << 16) | (data[6] << 8) | data[7];
233
234 #define WRITE_64BIT_DATA(data, left, right) \
235 data[0] = (left >> 24) &0xff; data[1] = (left >> 16) &0xff; \
236 data[2] = (left >> 8) &0xff; data[3] = left &0xff; \
237 data[4] = (right >> 24) &0xff; data[5] = (right >> 16) &0xff; \
238 data[6] = (right >> 8) &0xff; data[7] = right &0xff;
239
240
241 /*
242 * des_key_schedule(): Calculate 16 subkeys pairs (even/odd) for
243 * 16 encryption rounds.
244 * To calculate subkeys for decryption the caller
245 * have to reorder the generated subkeys.
246 *
247 * rawkey: 8 Bytes of key data
248 * subkey: Array of at least 32 guint32s. Will be filled
249 * with calculated subkeys.
250 *
251 **/
252 static void
des_key_schedule(const guint8 * rawkey,guint32 * subkey)253 des_key_schedule (const guint8 * rawkey, guint32 * subkey)
254 {
255 guint32 left, right, work;
256 int round;
257
258 READ_64BIT_DATA (rawkey, left, right)
259
260 DO_PERMUTATION (right, work, left, 4, 0x0f0f0f0f)
261 DO_PERMUTATION (right, work, left, 0, 0x10101010)
262
263 left = (leftkey_swap[(left >> 0) & 0xf] << 3) | (leftkey_swap[(left >> 8) & 0xf] << 2)
264 | (leftkey_swap[(left >> 16) & 0xf] << 1) | (leftkey_swap[(left >> 24) & 0xf])
265 | (leftkey_swap[(left >> 5) & 0xf] << 7) | (leftkey_swap[(left >> 13) & 0xf] << 6)
266 | (leftkey_swap[(left >> 21) & 0xf] << 5) | (leftkey_swap[(left >> 29) & 0xf] << 4);
267
268 left &= 0x0fffffff;
269
270 right = (rightkey_swap[(right >> 1) & 0xf] << 3) | (rightkey_swap[(right >> 9) & 0xf] << 2)
271 | (rightkey_swap[(right >> 17) & 0xf] << 1) | (rightkey_swap[(right >> 25) & 0xf])
272 | (rightkey_swap[(right >> 4) & 0xf] << 7) | (rightkey_swap[(right >> 12) & 0xf] << 6)
273 | (rightkey_swap[(right >> 20) & 0xf] << 5) | (rightkey_swap[(right >> 28) & 0xf] << 4);
274
275 right &= 0x0fffffff;
276
277 for (round = 0; round < 16; ++round)
278 {
279 left = ((left << encrypt_rotate_tab[round]) | (left >> (28 - encrypt_rotate_tab[round]))) & 0x0fffffff;
280 right = ((right << encrypt_rotate_tab[round]) | (right >> (28 - encrypt_rotate_tab[round]))) & 0x0fffffff;
281
282 *subkey++ = ((left << 4) & 0x24000000)
283 | ((left << 28) & 0x10000000)
284 | ((left << 14) & 0x08000000)
285 | ((left << 18) & 0x02080000)
286 | ((left << 6) & 0x01000000)
287 | ((left << 9) & 0x00200000)
288 | ((left >> 1) & 0x00100000)
289 | ((left << 10) & 0x00040000)
290 | ((left << 2) & 0x00020000)
291 | ((left >> 10) & 0x00010000)
292 | ((right >> 13) & 0x00002000)
293 | ((right >> 4) & 0x00001000)
294 | ((right << 6) & 0x00000800)
295 | ((right >> 1) & 0x00000400)
296 | ((right >> 14) & 0x00000200)
297 | (right & 0x00000100)
298 | ((right >> 5) & 0x00000020)
299 | ((right >> 10) & 0x00000010)
300 | ((right >> 3) & 0x00000008)
301 | ((right >> 18) & 0x00000004)
302 | ((right >> 26) & 0x00000002)
303 | ((right >> 24) & 0x00000001);
304
305 *subkey++ = ((left << 15) & 0x20000000)
306 | ((left << 17) & 0x10000000)
307 | ((left << 10) & 0x08000000)
308 | ((left << 22) & 0x04000000)
309 | ((left >> 2) & 0x02000000)
310 | ((left << 1) & 0x01000000)
311 | ((left << 16) & 0x00200000)
312 | ((left << 11) & 0x00100000)
313 | ((left << 3) & 0x00080000)
314 | ((left >> 6) & 0x00040000)
315 | ((left << 15) & 0x00020000)
316 | ((left >> 4) & 0x00010000)
317 | ((right >> 2) & 0x00002000)
318 | ((right << 8) & 0x00001000)
319 | ((right >> 14) & 0x00000808)
320 | ((right >> 9) & 0x00000400)
321 | ((right) & 0x00000200)
322 | ((right << 7) & 0x00000100)
323 | ((right >> 7) & 0x00000020)
324 | ((right >> 3) & 0x00000011)
325 | ((right << 2) & 0x00000004)
326 | ((right >> 21) & 0x00000002);
327 }
328 }
329
330
331 /*
332 * Fill a DES context with subkeys calculated from a 64bit key.
333 * Does not check parity bits, but simply ignore them.
334 * Does not check for weak keys.
335 **/
336 static void
des_set_key(PurpleCipherContext * context,const guchar * key)337 des_set_key (PurpleCipherContext *context, const guchar * key)
338 {
339 struct _des_ctx *ctx = purple_cipher_context_get_data(context);
340 int i;
341
342 des_key_schedule (key, ctx->encrypt_subkeys);
343
344 for(i=0; i<32; i+=2)
345 {
346 ctx->decrypt_subkeys[i] = ctx->encrypt_subkeys[30-i];
347 ctx->decrypt_subkeys[i+1] = ctx->encrypt_subkeys[31-i];
348 }
349 }
350
351
352 /*
353 * Electronic Codebook Mode DES encryption/decryption of data according
354 * to 'mode'.
355 **/
356 static int
des_ecb_crypt(struct _des_ctx * ctx,const guint8 * from,guint8 * to,int mode)357 des_ecb_crypt (struct _des_ctx *ctx, const guint8 * from, guint8 * to, int mode)
358 {
359 guint32 left, right, work;
360 guint32 *keys;
361
362 keys = mode ? ctx->decrypt_subkeys : ctx->encrypt_subkeys;
363
364 READ_64BIT_DATA (from, left, right)
365 INITIAL_PERMUTATION (left, work, right)
366
367 DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
368 DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
369 DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
370 DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
371 DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
372 DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
373 DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
374 DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
375
376 FINAL_PERMUTATION (right, work, left)
377 WRITE_64BIT_DATA (to, right, left)
378
379 return 0;
380 }
381
382 static gint
des_encrypt(PurpleCipherContext * context,const guchar data[],size_t len,guchar output[],size_t * outlen)383 des_encrypt(PurpleCipherContext *context, const guchar data[],
384 size_t len, guchar output[], size_t *outlen)
385 {
386 int offset = 0;
387 int i = 0;
388 int tmp;
389 guint8 buf[8] = {0,0,0,0,0,0,0,0};
390 while(offset+8<=len) {
391 des_ecb_crypt(purple_cipher_context_get_data(context),
392 data+offset,
393 output+offset,
394 0);
395 offset+=8;
396 }
397 *outlen = len;
398 if(offset<len) {
399 *outlen += len - offset;
400 tmp = offset;
401 while(tmp<len) {
402 buf[i++] = data[tmp];
403 tmp++;
404 }
405 des_ecb_crypt(purple_cipher_context_get_data(context),
406 buf,
407 output+offset,
408 0);
409 }
410 return 0;
411 }
412
413 static gint
des_decrypt(PurpleCipherContext * context,const guchar data[],size_t len,guchar output[],size_t * outlen)414 des_decrypt(PurpleCipherContext *context, const guchar data[],
415 size_t len, guchar output[], size_t *outlen)
416 {
417 int offset = 0;
418 int i = 0;
419 int tmp;
420 guint8 buf[8] = {0,0,0,0,0,0,0,0};
421 while(offset+8<=len) {
422 des_ecb_crypt(purple_cipher_context_get_data(context),
423 data+offset,
424 output+offset,
425 1);
426 offset+=8;
427 }
428 *outlen = len;
429 if(offset<len) {
430 *outlen += len - offset;
431 tmp = offset;
432 while(tmp<len) {
433 buf[i++] = data[tmp];
434 tmp++;
435 }
436 des_ecb_crypt(purple_cipher_context_get_data(context),
437 buf,
438 output+offset,
439 1);
440 }
441 return 0;
442 }
443
444 static void
des_init(PurpleCipherContext * context,gpointer extra)445 des_init(PurpleCipherContext *context, gpointer extra) {
446 struct _des_ctx *mctx;
447 mctx = g_new0(struct _des_ctx, 1);
448 purple_cipher_context_set_data(context, mctx);
449 }
450
451 static void
des_uninit(PurpleCipherContext * context)452 des_uninit(PurpleCipherContext *context) {
453 struct _des_ctx *des_context;
454
455 des_context = purple_cipher_context_get_data(context);
456 memset(des_context, 0, sizeof(*des_context));
457
458 g_free(des_context);
459 des_context = NULL;
460 }
461
462 static PurpleCipherOps DESOps = {
463 NULL, /* Set option */
464 NULL, /* Get option */
465 des_init, /* init */
466 NULL, /* reset */
467 des_uninit, /* uninit */
468 NULL, /* set iv */
469 NULL, /* append */
470 NULL, /* digest */
471 des_encrypt, /* encrypt */
472 des_decrypt, /* decrypt */
473 NULL, /* set salt */
474 NULL, /* get salt size */
475 des_set_key, /* set key */
476 NULL, /* get key size */
477 NULL, /* set batch mode */
478 NULL, /* get batch mode */
479 NULL, /* get block size */
480 NULL /* set key with len */
481 };
482
483 /******************************************************************************
484 * Triple-DES
485 *****************************************************************************/
486
487 typedef struct _des3_ctx
488 {
489 PurpleCipherBatchMode mode;
490 guchar iv[8];
491 /* First key for encryption */
492 struct _des_ctx key1;
493 /* Second key for decryption */
494 struct _des_ctx key2;
495 /* Third key for encryption */
496 struct _des_ctx key3;
497 } des3_ctx[1];
498
499 /*
500 * Fill a DES3 context with subkeys calculated from 3 64bit key.
501 * Does not check parity bits, but simply ignore them.
502 * Does not check for weak keys.
503 **/
504 static void
des3_set_key(PurpleCipherContext * context,const guchar * key)505 des3_set_key(PurpleCipherContext *context, const guchar * key)
506 {
507 struct _des3_ctx *ctx = purple_cipher_context_get_data(context);
508 int i;
509
510 des_key_schedule (key + 0, ctx->key1.encrypt_subkeys);
511 des_key_schedule (key + 8, ctx->key2.encrypt_subkeys);
512 des_key_schedule (key + 16, ctx->key3.encrypt_subkeys);
513
514 for (i = 0; i < 32; i += 2)
515 {
516 ctx->key1.decrypt_subkeys[i] = ctx->key1.encrypt_subkeys[30-i];
517 ctx->key1.decrypt_subkeys[i+1] = ctx->key1.encrypt_subkeys[31-i];
518 ctx->key2.decrypt_subkeys[i] = ctx->key2.encrypt_subkeys[30-i];
519 ctx->key2.decrypt_subkeys[i+1] = ctx->key2.encrypt_subkeys[31-i];
520 ctx->key3.decrypt_subkeys[i] = ctx->key3.encrypt_subkeys[30-i];
521 ctx->key3.decrypt_subkeys[i+1] = ctx->key3.encrypt_subkeys[31-i];
522 }
523 }
524
525 static gint
des3_ecb_encrypt(struct _des3_ctx * ctx,const guchar data[],size_t len,guchar output[],size_t * outlen)526 des3_ecb_encrypt(struct _des3_ctx *ctx, const guchar data[],
527 size_t len, guchar output[], size_t *outlen)
528 {
529 int offset = 0;
530 int i = 0;
531 int tmp;
532 guint8 buf[8] = {0,0,0,0,0,0,0,0};
533 while (offset + 8 <= len) {
534 des_ecb_crypt(&ctx->key1,
535 data+offset,
536 output+offset,
537 0);
538 des_ecb_crypt(&ctx->key2,
539 output+offset,
540 buf,
541 1);
542 des_ecb_crypt(&ctx->key3,
543 buf,
544 output+offset,
545 0);
546 offset += 8;
547 }
548 *outlen = len;
549 if (offset < len) {
550 *outlen += len - offset;
551 tmp = offset;
552 memset(buf, 0, 8);
553 while (tmp < len) {
554 buf[i++] = data[tmp];
555 tmp++;
556 }
557 des_ecb_crypt(&ctx->key1,
558 buf,
559 output+offset,
560 0);
561 des_ecb_crypt(&ctx->key2,
562 output+offset,
563 buf,
564 1);
565 des_ecb_crypt(&ctx->key3,
566 buf,
567 output+offset,
568 0);
569 }
570 return 0;
571 }
572
573 static gint
des3_cbc_encrypt(struct _des3_ctx * ctx,const guchar data[],size_t len,guchar output[],size_t * outlen)574 des3_cbc_encrypt(struct _des3_ctx *ctx, const guchar data[],
575 size_t len, guchar output[], size_t *outlen)
576 {
577 int offset = 0;
578 int i = 0;
579 int tmp;
580 guint8 buf[8];
581 memcpy(buf, ctx->iv, 8);
582 while (offset + 8 <= len) {
583 for (i = 0; i < 8; i++)
584 buf[i] ^= data[offset + i];
585
586 des_ecb_crypt(&ctx->key1,
587 buf,
588 output+offset,
589 0);
590 des_ecb_crypt(&ctx->key2,
591 output+offset,
592 buf,
593 1);
594 des_ecb_crypt(&ctx->key3,
595 buf,
596 output+offset,
597 0);
598 memcpy(buf, output+offset, 8);
599 offset += 8;
600 }
601 *outlen = len;
602 if (offset < len) {
603 *outlen += len - offset;
604 tmp = offset;
605 i = 0;
606 while (tmp < len) {
607 buf[i++] ^= data[tmp];
608 tmp++;
609 }
610 des_ecb_crypt(&ctx->key1,
611 buf,
612 output+offset,
613 0);
614 des_ecb_crypt(&ctx->key2,
615 output+offset,
616 buf,
617 1);
618 des_ecb_crypt(&ctx->key3,
619 buf,
620 output+offset,
621 0);
622 }
623 return 0;
624 }
625
626 static gint
des3_encrypt(PurpleCipherContext * context,const guchar data[],size_t len,guchar output[],size_t * outlen)627 des3_encrypt(PurpleCipherContext *context, const guchar data[],
628 size_t len, guchar output[], size_t *outlen)
629 {
630 struct _des3_ctx *ctx = purple_cipher_context_get_data(context);
631
632 if (ctx->mode == PURPLE_CIPHER_BATCH_MODE_ECB) {
633 return des3_ecb_encrypt(ctx, data, len, output, outlen);
634 } else if (ctx->mode == PURPLE_CIPHER_BATCH_MODE_CBC) {
635 return des3_cbc_encrypt(ctx, data, len, output, outlen);
636 } else {
637 g_return_val_if_reached(0);
638 }
639
640 return 0;
641 }
642
643 static gint
des3_ecb_decrypt(struct _des3_ctx * ctx,const guchar data[],size_t len,guchar output[],size_t * outlen)644 des3_ecb_decrypt(struct _des3_ctx *ctx, const guchar data[],
645 size_t len, guchar output[], size_t *outlen)
646 {
647 int offset = 0;
648 int i = 0;
649 int tmp;
650 guint8 buf[8] = {0,0,0,0,0,0,0,0};
651 while (offset + 8 <= len) {
652 /* NOTE: Apply key in reverse */
653 des_ecb_crypt(&ctx->key3,
654 data+offset,
655 output+offset,
656 1);
657 des_ecb_crypt(&ctx->key2,
658 output+offset,
659 buf,
660 0);
661 des_ecb_crypt(&ctx->key1,
662 buf,
663 output+offset,
664 1);
665 offset+=8;
666 }
667 *outlen = len;
668 if (offset < len) {
669 *outlen += len - offset;
670 tmp = offset;
671 memset(buf, 0, 8);
672 while (tmp < len) {
673 buf[i++] = data[tmp];
674 tmp++;
675 }
676 des_ecb_crypt(&ctx->key3,
677 buf,
678 output+offset,
679 1);
680 des_ecb_crypt(&ctx->key2,
681 output+offset,
682 buf,
683 0);
684 des_ecb_crypt(&ctx->key1,
685 buf,
686 output+offset,
687 1);
688 }
689 return 0;
690 }
691
692 static gint
des3_cbc_decrypt(struct _des3_ctx * ctx,const guchar data[],size_t len,guchar output[],size_t * outlen)693 des3_cbc_decrypt(struct _des3_ctx *ctx, const guchar data[],
694 size_t len, guchar output[], size_t *outlen)
695 {
696 int offset = 0;
697 int i = 0;
698 int tmp;
699 guint8 buf[8] = {0,0,0,0,0,0,0,0};
700 guint8 link[8];
701 memcpy(link, ctx->iv, 8);
702 while (offset + 8 <= len) {
703 des_ecb_crypt(&ctx->key3,
704 data+offset,
705 output+offset,
706 1);
707 des_ecb_crypt(&ctx->key2,
708 output+offset,
709 buf,
710 0);
711 des_ecb_crypt(&ctx->key1,
712 buf,
713 output+offset,
714 1);
715 for (i = 0; i < 8; i++)
716 output[offset + i] ^= link[i];
717 memcpy(link, data + offset, 8);
718 offset+=8;
719 }
720 *outlen = len;
721 if(offset<len) {
722 *outlen += len - offset;
723 tmp = offset;
724 memset(buf, 0, 8);
725 i = 0;
726 while(tmp<len) {
727 buf[i++] = data[tmp];
728 tmp++;
729 }
730 des_ecb_crypt(&ctx->key3,
731 buf,
732 output+offset,
733 1);
734 des_ecb_crypt(&ctx->key2,
735 output+offset,
736 buf,
737 0);
738 des_ecb_crypt(&ctx->key1,
739 buf,
740 output+offset,
741 1);
742 for (i = 0; i < 8; i++)
743 output[offset + i] ^= link[i];
744 }
745 return 0;
746 }
747
748 static gint
des3_decrypt(PurpleCipherContext * context,const guchar data[],size_t len,guchar output[],size_t * outlen)749 des3_decrypt(PurpleCipherContext *context, const guchar data[],
750 size_t len, guchar output[], size_t *outlen)
751 {
752 struct _des3_ctx *ctx = purple_cipher_context_get_data(context);
753
754 if (ctx->mode == PURPLE_CIPHER_BATCH_MODE_ECB) {
755 return des3_ecb_decrypt(ctx, data, len, output, outlen);
756 } else if (ctx->mode == PURPLE_CIPHER_BATCH_MODE_CBC) {
757 return des3_cbc_decrypt(ctx, data, len, output, outlen);
758 } else {
759 g_return_val_if_reached(0);
760 }
761
762 return 0;
763 }
764
765 static void
des3_set_batch(PurpleCipherContext * context,PurpleCipherBatchMode mode)766 des3_set_batch(PurpleCipherContext *context, PurpleCipherBatchMode mode)
767 {
768 struct _des3_ctx *ctx = purple_cipher_context_get_data(context);
769
770 ctx->mode = mode;
771 }
772
773 static PurpleCipherBatchMode
des3_get_batch(PurpleCipherContext * context)774 des3_get_batch(PurpleCipherContext *context)
775 {
776 struct _des3_ctx *ctx = purple_cipher_context_get_data(context);
777
778 return ctx->mode;
779 }
780
781 static void
des3_set_iv(PurpleCipherContext * context,guchar * iv,size_t len)782 des3_set_iv(PurpleCipherContext *context, guchar *iv, size_t len)
783 {
784 struct _des3_ctx *ctx;
785
786 g_return_if_fail(len == 8);
787
788 ctx = purple_cipher_context_get_data(context);
789
790 memcpy(ctx->iv, iv, len);
791 }
792
793 static void
des3_init(PurpleCipherContext * context,gpointer extra)794 des3_init(PurpleCipherContext *context, gpointer extra)
795 {
796 struct _des3_ctx *mctx;
797 mctx = g_new0(struct _des3_ctx, 1);
798 purple_cipher_context_set_data(context, mctx);
799 }
800
801 static void
des3_uninit(PurpleCipherContext * context)802 des3_uninit(PurpleCipherContext *context)
803 {
804 struct _des3_ctx *des3_context;
805
806 des3_context = purple_cipher_context_get_data(context);
807 memset(des3_context, 0, sizeof(*des3_context));
808
809 g_free(des3_context);
810 des3_context = NULL;
811 }
812
813 static PurpleCipherOps DES3Ops = {
814 NULL, /* Set option */
815 NULL, /* Get option */
816 des3_init, /* init */
817 NULL, /* reset */
818 des3_uninit, /* uninit */
819 des3_set_iv, /* set iv */
820 NULL, /* append */
821 NULL, /* digest */
822 des3_encrypt, /* encrypt */
823 des3_decrypt, /* decrypt */
824 NULL, /* set salt */
825 NULL, /* get salt size */
826 des3_set_key, /* set key */
827 NULL, /* get key size */
828 des3_set_batch, /* set batch mode */
829 des3_get_batch, /* get batch mode */
830 NULL, /* get block size */
831 NULL /* set key with len */
832 };
833
834 /******************************************************************************
835 * Registration
836 *****************************************************************************/
837 PurpleCipherOps *
purple_des_cipher_get_ops(void)838 purple_des_cipher_get_ops(void) {
839 return &DESOps;
840 }
841
842 PurpleCipherOps *
purple_des3_cipher_get_ops(void)843 purple_des3_cipher_get_ops(void) {
844 return &DES3Ops;
845 }
846
847