Scan media entities as well, not just url entities. This should expand more
[bitlbee.git] / lib / des.c
blob3b9cc8d57caa05ceb53459dba7e5f0d519411623
1 /*
2 * FIPS-46-3 compliant 3DES implementation
4 * Copyright (C) 2001-2003 Christophe Devine
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * Modified for BitlBee: Added a function compatible with the existing
23 * function in ssl_openssl.c, fairly specialised for MSN auth (since that's
24 * all this is used for at least for now).
26 * Added some consts to the tables at the top, and disabled some 64-bit
27 * and 128-bit key code that I don't need.
29 * *Many* thanks to Christophe for this compact and easy to import code.
32 #include <string.h>
33 #include <glib.h>
34 #include "des.h"
36 /* the eight DES S-boxes */
38 static const uint32_t SB1[64] =
40 0x01010400, 0x00000000, 0x00010000, 0x01010404,
41 0x01010004, 0x00010404, 0x00000004, 0x00010000,
42 0x00000400, 0x01010400, 0x01010404, 0x00000400,
43 0x01000404, 0x01010004, 0x01000000, 0x00000004,
44 0x00000404, 0x01000400, 0x01000400, 0x00010400,
45 0x00010400, 0x01010000, 0x01010000, 0x01000404,
46 0x00010004, 0x01000004, 0x01000004, 0x00010004,
47 0x00000000, 0x00000404, 0x00010404, 0x01000000,
48 0x00010000, 0x01010404, 0x00000004, 0x01010000,
49 0x01010400, 0x01000000, 0x01000000, 0x00000400,
50 0x01010004, 0x00010000, 0x00010400, 0x01000004,
51 0x00000400, 0x00000004, 0x01000404, 0x00010404,
52 0x01010404, 0x00010004, 0x01010000, 0x01000404,
53 0x01000004, 0x00000404, 0x00010404, 0x01010400,
54 0x00000404, 0x01000400, 0x01000400, 0x00000000,
55 0x00010004, 0x00010400, 0x00000000, 0x01010004
58 static const uint32_t SB2[64] =
60 0x80108020, 0x80008000, 0x00008000, 0x00108020,
61 0x00100000, 0x00000020, 0x80100020, 0x80008020,
62 0x80000020, 0x80108020, 0x80108000, 0x80000000,
63 0x80008000, 0x00100000, 0x00000020, 0x80100020,
64 0x00108000, 0x00100020, 0x80008020, 0x00000000,
65 0x80000000, 0x00008000, 0x00108020, 0x80100000,
66 0x00100020, 0x80000020, 0x00000000, 0x00108000,
67 0x00008020, 0x80108000, 0x80100000, 0x00008020,
68 0x00000000, 0x00108020, 0x80100020, 0x00100000,
69 0x80008020, 0x80100000, 0x80108000, 0x00008000,
70 0x80100000, 0x80008000, 0x00000020, 0x80108020,
71 0x00108020, 0x00000020, 0x00008000, 0x80000000,
72 0x00008020, 0x80108000, 0x00100000, 0x80000020,
73 0x00100020, 0x80008020, 0x80000020, 0x00100020,
74 0x00108000, 0x00000000, 0x80008000, 0x00008020,
75 0x80000000, 0x80100020, 0x80108020, 0x00108000
78 static const uint32_t SB3[64] =
80 0x00000208, 0x08020200, 0x00000000, 0x08020008,
81 0x08000200, 0x00000000, 0x00020208, 0x08000200,
82 0x00020008, 0x08000008, 0x08000008, 0x00020000,
83 0x08020208, 0x00020008, 0x08020000, 0x00000208,
84 0x08000000, 0x00000008, 0x08020200, 0x00000200,
85 0x00020200, 0x08020000, 0x08020008, 0x00020208,
86 0x08000208, 0x00020200, 0x00020000, 0x08000208,
87 0x00000008, 0x08020208, 0x00000200, 0x08000000,
88 0x08020200, 0x08000000, 0x00020008, 0x00000208,
89 0x00020000, 0x08020200, 0x08000200, 0x00000000,
90 0x00000200, 0x00020008, 0x08020208, 0x08000200,
91 0x08000008, 0x00000200, 0x00000000, 0x08020008,
92 0x08000208, 0x00020000, 0x08000000, 0x08020208,
93 0x00000008, 0x00020208, 0x00020200, 0x08000008,
94 0x08020000, 0x08000208, 0x00000208, 0x08020000,
95 0x00020208, 0x00000008, 0x08020008, 0x00020200
98 static const uint32_t SB4[64] =
100 0x00802001, 0x00002081, 0x00002081, 0x00000080,
101 0x00802080, 0x00800081, 0x00800001, 0x00002001,
102 0x00000000, 0x00802000, 0x00802000, 0x00802081,
103 0x00000081, 0x00000000, 0x00800080, 0x00800001,
104 0x00000001, 0x00002000, 0x00800000, 0x00802001,
105 0x00000080, 0x00800000, 0x00002001, 0x00002080,
106 0x00800081, 0x00000001, 0x00002080, 0x00800080,
107 0x00002000, 0x00802080, 0x00802081, 0x00000081,
108 0x00800080, 0x00800001, 0x00802000, 0x00802081,
109 0x00000081, 0x00000000, 0x00000000, 0x00802000,
110 0x00002080, 0x00800080, 0x00800081, 0x00000001,
111 0x00802001, 0x00002081, 0x00002081, 0x00000080,
112 0x00802081, 0x00000081, 0x00000001, 0x00002000,
113 0x00800001, 0x00002001, 0x00802080, 0x00800081,
114 0x00002001, 0x00002080, 0x00800000, 0x00802001,
115 0x00000080, 0x00800000, 0x00002000, 0x00802080
118 static const uint32_t SB5[64] =
120 0x00000100, 0x02080100, 0x02080000, 0x42000100,
121 0x00080000, 0x00000100, 0x40000000, 0x02080000,
122 0x40080100, 0x00080000, 0x02000100, 0x40080100,
123 0x42000100, 0x42080000, 0x00080100, 0x40000000,
124 0x02000000, 0x40080000, 0x40080000, 0x00000000,
125 0x40000100, 0x42080100, 0x42080100, 0x02000100,
126 0x42080000, 0x40000100, 0x00000000, 0x42000000,
127 0x02080100, 0x02000000, 0x42000000, 0x00080100,
128 0x00080000, 0x42000100, 0x00000100, 0x02000000,
129 0x40000000, 0x02080000, 0x42000100, 0x40080100,
130 0x02000100, 0x40000000, 0x42080000, 0x02080100,
131 0x40080100, 0x00000100, 0x02000000, 0x42080000,
132 0x42080100, 0x00080100, 0x42000000, 0x42080100,
133 0x02080000, 0x00000000, 0x40080000, 0x42000000,
134 0x00080100, 0x02000100, 0x40000100, 0x00080000,
135 0x00000000, 0x40080000, 0x02080100, 0x40000100
138 static const uint32_t SB6[64] =
140 0x20000010, 0x20400000, 0x00004000, 0x20404010,
141 0x20400000, 0x00000010, 0x20404010, 0x00400000,
142 0x20004000, 0x00404010, 0x00400000, 0x20000010,
143 0x00400010, 0x20004000, 0x20000000, 0x00004010,
144 0x00000000, 0x00400010, 0x20004010, 0x00004000,
145 0x00404000, 0x20004010, 0x00000010, 0x20400010,
146 0x20400010, 0x00000000, 0x00404010, 0x20404000,
147 0x00004010, 0x00404000, 0x20404000, 0x20000000,
148 0x20004000, 0x00000010, 0x20400010, 0x00404000,
149 0x20404010, 0x00400000, 0x00004010, 0x20000010,
150 0x00400000, 0x20004000, 0x20000000, 0x00004010,
151 0x20000010, 0x20404010, 0x00404000, 0x20400000,
152 0x00404010, 0x20404000, 0x00000000, 0x20400010,
153 0x00000010, 0x00004000, 0x20400000, 0x00404010,
154 0x00004000, 0x00400010, 0x20004010, 0x00000000,
155 0x20404000, 0x20000000, 0x00400010, 0x20004010
158 static const uint32_t SB7[64] =
160 0x00200000, 0x04200002, 0x04000802, 0x00000000,
161 0x00000800, 0x04000802, 0x00200802, 0x04200800,
162 0x04200802, 0x00200000, 0x00000000, 0x04000002,
163 0x00000002, 0x04000000, 0x04200002, 0x00000802,
164 0x04000800, 0x00200802, 0x00200002, 0x04000800,
165 0x04000002, 0x04200000, 0x04200800, 0x00200002,
166 0x04200000, 0x00000800, 0x00000802, 0x04200802,
167 0x00200800, 0x00000002, 0x04000000, 0x00200800,
168 0x04000000, 0x00200800, 0x00200000, 0x04000802,
169 0x04000802, 0x04200002, 0x04200002, 0x00000002,
170 0x00200002, 0x04000000, 0x04000800, 0x00200000,
171 0x04200800, 0x00000802, 0x00200802, 0x04200800,
172 0x00000802, 0x04000002, 0x04200802, 0x04200000,
173 0x00200800, 0x00000000, 0x00000002, 0x04200802,
174 0x00000000, 0x00200802, 0x04200000, 0x00000800,
175 0x04000002, 0x04000800, 0x00000800, 0x00200002
178 static const uint32_t SB8[64] =
180 0x10001040, 0x00001000, 0x00040000, 0x10041040,
181 0x10000000, 0x10001040, 0x00000040, 0x10000000,
182 0x00040040, 0x10040000, 0x10041040, 0x00041000,
183 0x10041000, 0x00041040, 0x00001000, 0x00000040,
184 0x10040000, 0x10000040, 0x10001000, 0x00001040,
185 0x00041000, 0x00040040, 0x10040040, 0x10041000,
186 0x00001040, 0x00000000, 0x00000000, 0x10040040,
187 0x10000040, 0x10001000, 0x00041040, 0x00040000,
188 0x00041040, 0x00040000, 0x10041000, 0x00001000,
189 0x00000040, 0x10040040, 0x00001000, 0x00041040,
190 0x10001000, 0x00000040, 0x10000040, 0x10040000,
191 0x10040040, 0x10000000, 0x00040000, 0x10001040,
192 0x00000000, 0x10041040, 0x00040040, 0x10000040,
193 0x10040000, 0x10001000, 0x10001040, 0x00000000,
194 0x10041040, 0x00041000, 0x00041000, 0x00001040,
195 0x00001040, 0x00040040, 0x10000000, 0x10041000
198 /* PC1: left and right halves bit-swap */
200 static const uint32_t LHs[16] =
202 0x00000000, 0x00000001, 0x00000100, 0x00000101,
203 0x00010000, 0x00010001, 0x00010100, 0x00010101,
204 0x01000000, 0x01000001, 0x01000100, 0x01000101,
205 0x01010000, 0x01010001, 0x01010100, 0x01010101
208 static const uint32_t RHs[16] =
210 0x00000000, 0x01000000, 0x00010000, 0x01010000,
211 0x00000100, 0x01000100, 0x00010100, 0x01010100,
212 0x00000001, 0x01000001, 0x00010001, 0x01010001,
213 0x00000101, 0x01000101, 0x00010101, 0x01010101,
216 /* platform-independant 32-bit integer manipulation macros */
218 #define GET_UINT32(n,b,i) \
220 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
221 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
222 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
223 | ( (uint32_t) (b)[(i) + 3] ); \
226 #define PUT_UINT32(n,b,i) \
228 (b)[(i) ] = (uint8_t) ( (n) >> 24 ); \
229 (b)[(i) + 1] = (uint8_t) ( (n) >> 16 ); \
230 (b)[(i) + 2] = (uint8_t) ( (n) >> 8 ); \
231 (b)[(i) + 3] = (uint8_t) ( (n) ); \
234 /* Initial Permutation macro */
236 #define DES_IP(X,Y) \
238 T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \
239 T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \
240 T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \
241 T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \
242 Y = ((Y << 1) | (Y >> 31)) & 0xFFFFFFFF; \
243 T = (X ^ Y) & 0xAAAAAAAA; Y ^= T; X ^= T; \
244 X = ((X << 1) | (X >> 31)) & 0xFFFFFFFF; \
247 /* Final Permutation macro */
249 #define DES_FP(X,Y) \
251 X = ((X << 31) | (X >> 1)) & 0xFFFFFFFF; \
252 T = (X ^ Y) & 0xAAAAAAAA; X ^= T; Y ^= T; \
253 Y = ((Y << 31) | (Y >> 1)) & 0xFFFFFFFF; \
254 T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \
255 T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \
256 T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \
257 T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \
260 /* DES round macro */
262 #define DES_ROUND(X,Y) \
264 T = *SK++ ^ X; \
265 Y ^= SB8[ (T ) & 0x3F ] ^ \
266 SB6[ (T >> 8) & 0x3F ] ^ \
267 SB4[ (T >> 16) & 0x3F ] ^ \
268 SB2[ (T >> 24) & 0x3F ]; \
270 T = *SK++ ^ ((X << 28) | (X >> 4)); \
271 Y ^= SB7[ (T ) & 0x3F ] ^ \
272 SB5[ (T >> 8) & 0x3F ] ^ \
273 SB3[ (T >> 16) & 0x3F ] ^ \
274 SB1[ (T >> 24) & 0x3F ]; \
277 /* DES key schedule */
279 int des_main_ks( uint32_t SK[32], const uint8_t key[8] )
281 int i;
282 uint32_t X, Y, T;
284 GET_UINT32( X, key, 0 );
285 GET_UINT32( Y, key, 4 );
287 /* Permuted Choice 1 */
289 T = ((Y >> 4) ^ X) & 0x0F0F0F0F; X ^= T; Y ^= (T << 4);
290 T = ((Y ) ^ X) & 0x10101010; X ^= T; Y ^= (T );
292 X = (LHs[ (X ) & 0xF] << 3) | (LHs[ (X >> 8) & 0xF ] << 2)
293 | (LHs[ (X >> 16) & 0xF] << 1) | (LHs[ (X >> 24) & 0xF ] )
294 | (LHs[ (X >> 5) & 0xF] << 7) | (LHs[ (X >> 13) & 0xF ] << 6)
295 | (LHs[ (X >> 21) & 0xF] << 5) | (LHs[ (X >> 29) & 0xF ] << 4);
297 Y = (RHs[ (Y >> 1) & 0xF] << 3) | (RHs[ (Y >> 9) & 0xF ] << 2)
298 | (RHs[ (Y >> 17) & 0xF] << 1) | (RHs[ (Y >> 25) & 0xF ] )
299 | (RHs[ (Y >> 4) & 0xF] << 7) | (RHs[ (Y >> 12) & 0xF ] << 6)
300 | (RHs[ (Y >> 20) & 0xF] << 5) | (RHs[ (Y >> 28) & 0xF ] << 4);
302 X &= 0x0FFFFFFF;
303 Y &= 0x0FFFFFFF;
305 /* calculate subkeys */
307 for( i = 0; i < 16; i++ )
309 if( i < 2 || i == 8 || i == 15 )
311 X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF;
312 Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF;
314 else
316 X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF;
317 Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF;
320 *SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000)
321 | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000)
322 | ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000)
323 | ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000)
324 | ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000)
325 | ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000)
326 | ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400)
327 | ((Y >> 14) & 0x00000200) | ((Y ) & 0x00000100)
328 | ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010)
329 | ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004)
330 | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001);
332 *SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000)
333 | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000)
334 | ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000)
335 | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000)
336 | ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000)
337 | ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000)
338 | ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000)
339 | ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400)
340 | ((Y ) & 0x00000200) | ((Y << 7) & 0x00000100)
341 | ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011)
342 | ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002);
345 return( 0 );
348 #if TEST
349 int des_set_key( des_context *ctx, uint8_t key[8] )
351 int i;
353 /* setup encryption subkeys */
355 des_main_ks( ctx->esk, key );
357 /* setup decryption subkeys */
359 for( i = 0; i < 32; i += 2 )
361 ctx->dsk[i ] = ctx->esk[30 - i];
362 ctx->dsk[i + 1] = ctx->esk[31 - i];
365 return( 0 );
368 /* DES 64-bit block encryption/decryption */
370 void des_crypt( uint32_t SK[32], uint8_t input[8], uint8_t output[8] )
372 uint32_t X, Y, T;
374 GET_UINT32( X, input, 0 );
375 GET_UINT32( Y, input, 4 );
377 DES_IP( X, Y );
379 DES_ROUND( Y, X ); DES_ROUND( X, Y );
380 DES_ROUND( Y, X ); DES_ROUND( X, Y );
381 DES_ROUND( Y, X ); DES_ROUND( X, Y );
382 DES_ROUND( Y, X ); DES_ROUND( X, Y );
383 DES_ROUND( Y, X ); DES_ROUND( X, Y );
384 DES_ROUND( Y, X ); DES_ROUND( X, Y );
385 DES_ROUND( Y, X ); DES_ROUND( X, Y );
386 DES_ROUND( Y, X ); DES_ROUND( X, Y );
388 DES_FP( Y, X );
390 PUT_UINT32( Y, output, 0 );
391 PUT_UINT32( X, output, 4 );
394 void des_encrypt( des_context *ctx, uint8_t input[8], uint8_t output[8] )
396 des_crypt( ctx->esk, input, output );
399 void des_decrypt( des_context *ctx, uint8_t input[8], uint8_t output[8] )
401 des_crypt( ctx->dsk, input, output );
404 /* Triple-DES key schedule */
406 int des3_set_2keys( des3_context *ctx, const uint8_t key1[8], const uint8_t key2[8] )
408 int i;
410 des_main_ks( ctx->esk , key1 );
411 des_main_ks( ctx->dsk + 32, key2 );
413 for( i = 0; i < 32; i += 2 )
415 ctx->dsk[i ] = ctx->esk[30 - i];
416 ctx->dsk[i + 1] = ctx->esk[31 - i];
418 ctx->esk[i + 32] = ctx->dsk[62 - i];
419 ctx->esk[i + 33] = ctx->dsk[63 - i];
421 ctx->esk[i + 64] = ctx->esk[ i];
422 ctx->esk[i + 65] = ctx->esk[ 1 + i];
424 ctx->dsk[i + 64] = ctx->dsk[ i];
425 ctx->dsk[i + 65] = ctx->dsk[ 1 + i];
428 return( 0 );
430 #endif
432 int des3_set_3keys( des3_context *ctx, const uint8_t key1[8], const uint8_t key2[8],
433 const uint8_t key3[8] )
435 int i;
437 des_main_ks( ctx->esk , key1 );
438 des_main_ks( ctx->dsk + 32, key2 );
439 des_main_ks( ctx->esk + 64, key3 );
441 for( i = 0; i < 32; i += 2 )
443 ctx->dsk[i ] = ctx->esk[94 - i];
444 ctx->dsk[i + 1] = ctx->esk[95 - i];
446 ctx->esk[i + 32] = ctx->dsk[62 - i];
447 ctx->esk[i + 33] = ctx->dsk[63 - i];
449 ctx->dsk[i + 64] = ctx->esk[30 - i];
450 ctx->dsk[i + 65] = ctx->esk[31 - i];
453 return( 0 );
456 /* Triple-DES 64-bit block encryption/decryption */
458 void des3_crypt( uint32_t SK[96], uint8_t input[8], uint8_t output[8] )
460 uint32_t X, Y, T;
462 GET_UINT32( X, input, 0 );
463 GET_UINT32( Y, input, 4 );
465 DES_IP( X, Y );
467 DES_ROUND( Y, X ); DES_ROUND( X, Y );
468 DES_ROUND( Y, X ); DES_ROUND( X, Y );
469 DES_ROUND( Y, X ); DES_ROUND( X, Y );
470 DES_ROUND( Y, X ); DES_ROUND( X, Y );
471 DES_ROUND( Y, X ); DES_ROUND( X, Y );
472 DES_ROUND( Y, X ); DES_ROUND( X, Y );
473 DES_ROUND( Y, X ); DES_ROUND( X, Y );
474 DES_ROUND( Y, X ); DES_ROUND( X, Y );
476 DES_ROUND( X, Y ); DES_ROUND( Y, X );
477 DES_ROUND( X, Y ); DES_ROUND( Y, X );
478 DES_ROUND( X, Y ); DES_ROUND( Y, X );
479 DES_ROUND( X, Y ); DES_ROUND( Y, X );
480 DES_ROUND( X, Y ); DES_ROUND( Y, X );
481 DES_ROUND( X, Y ); DES_ROUND( Y, X );
482 DES_ROUND( X, Y ); DES_ROUND( Y, X );
483 DES_ROUND( X, Y ); DES_ROUND( Y, X );
485 DES_ROUND( Y, X ); DES_ROUND( X, Y );
486 DES_ROUND( Y, X ); DES_ROUND( X, Y );
487 DES_ROUND( Y, X ); DES_ROUND( X, Y );
488 DES_ROUND( Y, X ); DES_ROUND( X, Y );
489 DES_ROUND( Y, X ); DES_ROUND( X, Y );
490 DES_ROUND( Y, X ); DES_ROUND( X, Y );
491 DES_ROUND( Y, X ); DES_ROUND( X, Y );
492 DES_ROUND( Y, X ); DES_ROUND( X, Y );
494 DES_FP( Y, X );
496 PUT_UINT32( Y, output, 0 );
497 PUT_UINT32( X, output, 4 );
500 void des3_encrypt( des3_context *ctx, uint8_t input[8], uint8_t output[8] )
502 des3_crypt( ctx->esk, input, output );
505 void des3_decrypt( des3_context *ctx, uint8_t input[8], uint8_t output[8] )
507 des3_crypt( ctx->dsk, input, output );
510 size_t ssl_des3_encrypt( const unsigned char *key, size_t key_len, const unsigned char *input,
511 size_t input_len, const unsigned char *iv, unsigned char **res )
513 des3_context ctx3;
514 size_t off;
515 uint8_t buf[8];
517 /* Keep it simple, for as long as this is just used for MSN auth anyway. */
518 if( key_len != 24 || ( input_len % 8 ) != 0 )
519 return 0;
521 *res = g_malloc( input_len );
522 des3_set_3keys( &ctx3, key, key + 8, key + 16 );
524 /* This loop does CBC 3DES. */
525 memcpy( buf, iv, 8 );
526 for( off = 0; off < input_len; off += 8 )
528 int i;
530 for( i = 0; i < 8; i ++ )
531 buf[i] ^= input[off+i];
532 des3_encrypt( &ctx3, buf, buf );
533 memcpy( *res + off, buf, 8 );
536 return input_len;
539 #ifdef TEST
541 #include <string.h>
542 #include <stdio.h>
545 * Triple-DES Monte Carlo Test: ECB mode
546 * source: NIST - tripledes-vectors.zip
549 static const unsigned char DES3_keys[3][8] =
551 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
552 { 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01 },
553 { 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23 }
556 static const unsigned char DES3_init[8] =
558 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74
561 static const unsigned char DES3_enc_test[3][8] =
563 { 0x6A, 0x2A, 0x19, 0xF4, 0x1E, 0xCA, 0x85, 0x4B },
564 { 0x03, 0xE6, 0x9F, 0x5B, 0xFA, 0x58, 0xEB, 0x42 },
565 { 0xDD, 0x17, 0xE8, 0xB8, 0xB4, 0x37, 0xD2, 0x32 }
568 static const unsigned char DES3_dec_test[3][8] =
570 { 0xCD, 0xD6, 0x4F, 0x2F, 0x94, 0x27, 0xC1, 0x5D },
571 { 0x69, 0x96, 0xC8, 0xFA, 0x47, 0xA2, 0xAB, 0xEB },
572 { 0x83, 0x25, 0x39, 0x76, 0x44, 0x09, 0x1A, 0x0A }
575 int main( void )
577 int m, n, i;
578 des_context ctx;
579 des3_context ctx3;
580 unsigned char buf[8];
582 for( m = 0; m < 2; m++ )
584 printf( "\n Triple-DES Monte Carlo Test (ECB mode) - " );
586 if( m == 0 ) printf( "encryption\n\n" );
587 if( m == 1 ) printf( "decryption\n\n" );
589 for( n = 0; n < 3; n++ )
591 printf( " Test %d, key size = %3d bits: ",
592 n + 1, 64 + n * 64 );
594 fflush( stdout );
596 memcpy( buf, DES3_init, 8 );
598 switch( n )
600 case 0:
601 des_set_key( &ctx, DES3_keys[0] );
602 break;
604 case 1:
605 des3_set_2keys( &ctx3, DES3_keys[0],
606 DES3_keys[1] );
607 break;
609 case 2:
610 des3_set_3keys( &ctx3, DES3_keys[0],
611 DES3_keys[1],
612 DES3_keys[2] );
613 break;
616 for( i = 0; i < 10000; i++ )
618 if( n == 0 )
620 if( m == 0 ) des_encrypt( &ctx, buf, buf );
621 if( m == 1 ) des_decrypt( &ctx, buf, buf );
623 else
625 if( m == 0 ) des3_encrypt( &ctx3, buf, buf );
626 if( m == 1 ) des3_decrypt( &ctx3, buf, buf );
630 if( ( m == 0 && memcmp( buf, DES3_enc_test[n], 8 ) ) ||
631 ( m == 1 && memcmp( buf, DES3_dec_test[n], 8 ) ) )
633 printf( "failed!\n" );
634 return( 1 );
637 printf( "passed.\n" );
641 printf( "\n" );
643 return( 0 );
646 #endif