source: lib/des.c @ 191ac9d

Last change on this file since 191ac9d was a366cca, checked in by Wilmer van der Gaast <wilmer@…>, at 2010-08-20T23:04:12Z

Now including a nice and compact 3DES implementation done by Christophe
Devine. OpenSSL exports nice cipher functions, but GnuTLS only just started
doing this in 2.10 or so (not even in Debian Sid yet).

So instead of adding a whole library for encrypting 72 bytes of data, let's
have a built-in 3DES implementation for a while..

  • Property mode set to 100644
File size: 21.4 KB
RevLine 
[a366cca]1/*
2 *  FIPS-46-3 compliant 3DES implementation
3 *
4 *  Copyright (C) 2001-2003  Christophe Devine
5 *
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.
10 *
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.
15 *
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
19 */
20
21/*
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).
25 *
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.
28 *
29 * *Many* thanks to Christophe for this compact and easy to import code.
30 */
31
32#include <string.h>
33#include <glib.h>
34#include "des.h"
35
36/* the eight DES S-boxes */
37
38static const uint32_t SB1[64] =
39{
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
56};
57
58static const uint32_t SB2[64] =
59{
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
76};
77
78static const uint32_t SB3[64] =
79{
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
96};
97
98static const uint32_t SB4[64] =
99{
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
116};
117
118static const uint32_t SB5[64] =
119{
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
136};
137
138static const uint32_t SB6[64] =
139{
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
156};
157
158static const uint32_t SB7[64] =
159{
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
176};
177
178static const uint32_t SB8[64] =
179{
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
196};
197
198/* PC1: left and right halves bit-swap */
199
200static const uint32_t LHs[16] =
201{
202    0x00000000, 0x00000001, 0x00000100, 0x00000101,
203    0x00010000, 0x00010001, 0x00010100, 0x00010101,
204    0x01000000, 0x01000001, 0x01000100, 0x01000101,
205    0x01010000, 0x01010001, 0x01010100, 0x01010101
206};
207
208static const uint32_t RHs[16] =
209{
210    0x00000000, 0x01000000, 0x00010000, 0x01010000,
211    0x00000100, 0x01000100, 0x00010100, 0x01010100,
212    0x00000001, 0x01000001, 0x00010001, 0x01010001,
213    0x00000101, 0x01000101, 0x00010101, 0x01010101,
214};
215
216/* platform-independant 32-bit integer manipulation macros */
217
218#define GET_UINT32(n,b,i)                         \
219{                                                 \
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]       );      \
224}
225
226#define PUT_UINT32(n,b,i)                         \
227{                                                 \
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)       );       \
232}
233
234/* Initial Permutation macro */
235
236#define DES_IP(X,Y)                                             \
237{                                                               \
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;                    \
245}
246
247/* Final Permutation macro */
248
249#define DES_FP(X,Y)                                             \
250{                                                               \
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);   \
258}
259
260/* DES round macro */
261
262#define DES_ROUND(X,Y)                          \
263{                                               \
264    T = *SK++ ^ X;                              \
265    Y ^= SB8[ (T      ) & 0x3F ] ^              \
266         SB6[ (T >>  8) & 0x3F ] ^              \
267         SB4[ (T >> 16) & 0x3F ] ^              \
268         SB2[ (T >> 24) & 0x3F ];               \
269                                                \
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 ];               \
275}
276
277/* DES key schedule */
278
279int des_main_ks( uint32_t SK[32], const uint8_t key[8] )
280{
281    int i;
282    uint32_t X, Y, T;
283
284    GET_UINT32( X, key, 0 );
285    GET_UINT32( Y, key, 4 );
286
287    /* Permuted Choice 1 */
288
289    T =  ((Y >>  4) ^ X) & 0x0F0F0F0F;  X ^= T; Y ^= (T <<  4);
290    T =  ((Y      ) ^ X) & 0x10101010;  X ^= T; Y ^= (T      );
291
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);
296
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);
301
302    X &= 0x0FFFFFFF;
303    Y &= 0x0FFFFFFF;
304
305    /* calculate subkeys */
306
307    for( i = 0; i < 16; i++ )
308    {
309        if( i < 2 || i == 8 || i == 15 )
310        {
311            X = ((X <<  1) | (X >> 27)) & 0x0FFFFFFF;
312            Y = ((Y <<  1) | (Y >> 27)) & 0x0FFFFFFF;
313        }
314        else
315        {
316            X = ((X <<  2) | (X >> 26)) & 0x0FFFFFFF;
317            Y = ((Y <<  2) | (Y >> 26)) & 0x0FFFFFFF;
318        }
319
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);
331
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);
343    }
344
345    return( 0 );
346}
347
348#if TEST
349int des_set_key( des_context *ctx, uint8_t key[8] )
350{
351    int i;
352
353    /* setup encryption subkeys */
354
355    des_main_ks( ctx->esk, key );
356
357    /* setup decryption subkeys */
358
359    for( i = 0; i < 32; i += 2 )
360    {
361        ctx->dsk[i    ] = ctx->esk[30 - i];
362        ctx->dsk[i + 1] = ctx->esk[31 - i];
363    }
364
365    return( 0 );
366}
367
368/* DES 64-bit block encryption/decryption */
369
370void des_crypt( uint32_t SK[32], uint8_t input[8], uint8_t output[8] )
371{
372    uint32_t X, Y, T;
373
374    GET_UINT32( X, input, 0 );
375    GET_UINT32( Y, input, 4 );
376
377    DES_IP( X, Y );
378
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 );
387
388    DES_FP( Y, X );
389
390    PUT_UINT32( Y, output, 0 );
391    PUT_UINT32( X, output, 4 );
392}
393
394void des_encrypt( des_context *ctx, uint8_t input[8], uint8_t output[8] )
395{
396    des_crypt( ctx->esk, input, output );
397}
398
399void des_decrypt( des_context *ctx, uint8_t input[8], uint8_t output[8] )
400{
401    des_crypt( ctx->dsk, input, output );
402}
403
404/* Triple-DES key schedule */
405
406int des3_set_2keys( des3_context *ctx, const uint8_t key1[8], const uint8_t key2[8] )
407{
408    int i;
409
410    des_main_ks( ctx->esk     , key1 );
411    des_main_ks( ctx->dsk + 32, key2 );
412
413    for( i = 0; i < 32; i += 2 )
414    {
415        ctx->dsk[i     ] = ctx->esk[30 - i];
416        ctx->dsk[i +  1] = ctx->esk[31 - i];
417
418        ctx->esk[i + 32] = ctx->dsk[62 - i];
419        ctx->esk[i + 33] = ctx->dsk[63 - i];
420
421        ctx->esk[i + 64] = ctx->esk[     i];
422        ctx->esk[i + 65] = ctx->esk[ 1 + i];
423
424        ctx->dsk[i + 64] = ctx->dsk[     i];
425        ctx->dsk[i + 65] = ctx->dsk[ 1 + i];
426    }
427
428    return( 0 );
429}
430#endif
431
432int des3_set_3keys( des3_context *ctx, const uint8_t key1[8], const uint8_t key2[8],
433                                       const uint8_t key3[8] )
434{
435    int i;
436
437    des_main_ks( ctx->esk     , key1 );
438    des_main_ks( ctx->dsk + 32, key2 );
439    des_main_ks( ctx->esk + 64, key3 );
440
441    for( i = 0; i < 32; i += 2 )
442    {
443        ctx->dsk[i     ] = ctx->esk[94 - i];
444        ctx->dsk[i +  1] = ctx->esk[95 - i];
445
446        ctx->esk[i + 32] = ctx->dsk[62 - i];
447        ctx->esk[i + 33] = ctx->dsk[63 - i];
448
449        ctx->dsk[i + 64] = ctx->esk[30 - i];
450        ctx->dsk[i + 65] = ctx->esk[31 - i];
451    }
452
453    return( 0 );
454}
455
456/* Triple-DES 64-bit block encryption/decryption */
457
458void des3_crypt( uint32_t SK[96], uint8_t input[8], uint8_t output[8] )
459{
460    uint32_t X, Y, T;
461
462    GET_UINT32( X, input, 0 );
463    GET_UINT32( Y, input, 4 );
464
465    DES_IP( X, Y );
466
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 );
475
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 );
484
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 );
493
494    DES_FP( Y, X );
495
496    PUT_UINT32( Y, output, 0 );
497    PUT_UINT32( X, output, 4 );
498}
499
500void des3_encrypt( des3_context *ctx, uint8_t input[8], uint8_t output[8] )
501{
502    des3_crypt( ctx->esk, input, output );
503}
504
505void des3_decrypt( des3_context *ctx, uint8_t input[8], uint8_t output[8] )
506{
507    des3_crypt( ctx->dsk, input, output );
508}
509
510size_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 )
512{
513        des3_context ctx3;
514        size_t off;
515        uint8_t buf[8];
516               
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;
520       
521        *res = g_malloc( input_len );
522        des3_set_3keys( &ctx3, key, key + 8, key + 16 );
523       
524        /* This loop does CBC 3DES. */
525        memcpy( buf, iv, 8 );
526        for( off = 0; off < input_len; off += 8 )
527        {
528                int i;
529               
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 );
534        }
535       
536        return input_len;
537}
538
539#ifdef TEST
540
541#include <string.h>
542#include <stdio.h>
543
544/*
545 * Triple-DES Monte Carlo Test: ECB mode
546 * source: NIST - tripledes-vectors.zip
547 */
548
549static const unsigned char DES3_keys[3][8] =
550{
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 }
554};
555
556static const unsigned char DES3_init[8] =
557{
558    0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74
559};
560
561static const unsigned char DES3_enc_test[3][8] =
562{
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 }
566};
567   
568static const unsigned char DES3_dec_test[3][8] =
569{
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 }
573};
574
575int main( void )
576{
577    int m, n, i;
578    des_context ctx;
579    des3_context ctx3;
580    unsigned char buf[8];
581
582    for( m = 0; m < 2; m++ )
583    {
584        printf( "\n Triple-DES Monte Carlo Test (ECB mode) - " );
585
586        if( m == 0 ) printf( "encryption\n\n" );
587        if( m == 1 ) printf( "decryption\n\n" );
588
589        for( n = 0; n < 3; n++ )
590        {
591            printf( " Test %d, key size = %3d bits: ",
592                    n + 1, 64 + n * 64 );
593
594            fflush( stdout );
595
596            memcpy( buf, DES3_init, 8 );
597
598            switch( n )
599            {
600                case 0:
601                    des_set_key( &ctx, DES3_keys[0] );
602                    break;
603
604                case 1:
605                    des3_set_2keys( &ctx3, DES3_keys[0],
606                                           DES3_keys[1] );
607                    break;
608
609                case 2:
610                    des3_set_3keys( &ctx3, DES3_keys[0],
611                                           DES3_keys[1],
612                                           DES3_keys[2] );
613                    break;
614            }
615
616            for( i = 0; i < 10000; i++ )
617            {
618                if( n == 0 )
619                {
620                    if( m == 0 ) des_encrypt( &ctx, buf, buf );
621                    if( m == 1 ) des_decrypt( &ctx, buf, buf );
622                }
623                else
624                {
625                    if( m == 0 ) des3_encrypt( &ctx3, buf, buf );
626                    if( m == 1 ) des3_decrypt( &ctx3, buf, buf );
627                }
628            }
629
630            if( ( m == 0 && memcmp( buf, DES3_enc_test[n], 8 ) ) ||
631                ( m == 1 && memcmp( buf, DES3_dec_test[n], 8 ) ) )
632            {
633                printf( "failed!\n" );
634                return( 1 );
635            }
636
637            printf( "passed.\n" );
638        }
639    }
640
641    printf( "\n" );
642
643    return( 0 );
644}
645
646#endif
Note: See TracBrowser for help on using the repository browser.