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