John Sullivan's patches plus more fixes:
[u/mdw/putty] / sshdes.c
1 #include <assert.h>
2 #include "ssh.h"
3
4 /*
5
6 DES implementation; 1995 Tatu Ylonen <ylo@cs.hut.fi>
7
8 This implementation is derived from libdes-3.06, which is copyright
9 (c) 1993 Eric Young, and distributed under the GNU GPL or the ARTISTIC licence
10 (at the user's option). The original distribution can be found e.g. from
11 ftp://ftp.dsi.unimi.it/pub/security/crypt/libdes/libdes-3.06.tar.gz.
12
13 This implementation is distributed under the same terms. See
14 libdes-README, libdes-ARTISTIC, and libdes-COPYING for more
15 information.
16
17 */
18
19 /*
20 * $Id: sshdes.c,v 1.2 1999/01/08 13:10:15 simon Exp $
21 * $Log: sshdes.c,v $
22 * Revision 1.2 1999/01/08 13:10:15 simon
23 * John Sullivan's patches plus more fixes:
24 * - Stop using the identifier `environ' as some platforms make it a macro
25 * - Fix silly error box at end of connection in FWHACK mode
26 * - Fix GPF on maximise-then-restore
27 * - Use SetCapture to allow drag-selecting outside the window
28 * - Correctly update window title when iconic and in win_name_always mode
29 *
30 * Revision 1.1.1.1 1996/02/18 21:38:11 ylo
31 * Imported ssh-1.2.13.
32 *
33 * Revision 1.2 1995/07/13 01:22:57 ylo
34 * Added cvs log.
35 *
36 * $Endlog$
37 */
38
39 typedef struct
40 {
41 word32 key_schedule[32];
42 } DESContext;
43
44 /* Sets the des key for the context. Initializes the context. The least
45 significant bit of each byte of the key is ignored as parity. */
46 static void des_set_key(unsigned char *key, DESContext *ks);
47
48 /* Encrypts 32 bits in l,r, and stores the result in output[0] and output[1].
49 Performs encryption if encrypt is non-zero, and decryption if it is zero.
50 The key context must have been initialized previously with des_set_key. */
51 static void des_encrypt(word32 l, word32 r, word32 *output, DESContext *ks,
52 int encrypt);
53
54 /* Encrypts len bytes from src to dest in CBC modes. Len must be a multiple
55 of 8. iv will be modified at end to a value suitable for continuing
56 encryption. */
57 static void des_cbc_encrypt(DESContext *ks, unsigned char *iv, unsigned char *dest,
58 const unsigned char *src, unsigned int len);
59
60 /* Decrypts len bytes from src to dest in CBC modes. Len must be a multiple
61 of 8. iv will be modified at end to a value suitable for continuing
62 decryption. */
63 static void des_cbc_decrypt(DESContext *ks, unsigned char *iv, unsigned char *dest,
64 const unsigned char *src, unsigned int len);
65
66 /* Encrypts in CBC mode using triple-DES. */
67 static void des_3cbc_encrypt(DESContext *ks1, unsigned char *iv1,
68 DESContext *ks2, unsigned char *iv2,
69 DESContext *ks3, unsigned char *iv3,
70 unsigned char *dest, const unsigned char *src,
71 unsigned int len);
72
73 /* Decrypts in CBC mode using triple-DES. */
74 static void des_3cbc_decrypt(DESContext *ks1, unsigned char *iv1,
75 DESContext *ks2, unsigned char *iv2,
76 DESContext *ks3, unsigned char *iv3,
77 unsigned char *dest, const unsigned char *src,
78 unsigned int len);
79
80 #define GET_32BIT_LSB_FIRST(cp) \
81 (((unsigned long)(unsigned char)(cp)[0]) | \
82 ((unsigned long)(unsigned char)(cp)[1] << 8) | \
83 ((unsigned long)(unsigned char)(cp)[2] << 16) | \
84 ((unsigned long)(unsigned char)(cp)[3] << 24))
85
86 #define PUT_32BIT_LSB_FIRST(cp, value) do { \
87 (cp)[0] = (value); \
88 (cp)[1] = (value) >> 8; \
89 (cp)[2] = (value) >> 16; \
90 (cp)[3] = (value) >> 24; } while (0)
91
92 /*
93
94 DES implementation; 1995 Tatu Ylonen <ylo@cs.hut.fi>
95
96 This implementation is derived from libdes-3.06, which is copyright
97 (c) 1993 Eric Young, and distributed under the GNU GPL or the ARTISTIC licence
98 (at the user's option). The original distribution can be found e.g. from
99 ftp://ftp.dsi.unimi.it/pub/security/crypt/libdes/libdes-3.06.tar.gz.
100
101 This implementation is distributed under the same terms. See
102 libdes-README, libdes-ARTISTIC, and libdes-COPYING for more
103 information.
104
105 A description of the DES algorithm can be found in every modern book on
106 cryptography and data security, including the following:
107
108 Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1994.
109
110 Jennifer Seberry and Josed Pieprzyk: Cryptography: An Introduction to
111 Computer Security. Prentice-Hall, 1989.
112
113 Man Young Rhee: Cryptography and Secure Data Communications. McGraw-Hill,
114 1994.
115
116 */
117
118 /*
119 * $Id: sshdes.c,v 1.2 1999/01/08 13:10:15 simon Exp $
120 * $Log: sshdes.c,v $
121 * Revision 1.2 1999/01/08 13:10:15 simon
122 * John Sullivan's patches plus more fixes:
123 * - Stop using the identifier `environ' as some platforms make it a macro
124 * - Fix silly error box at end of connection in FWHACK mode
125 * - Fix GPF on maximise-then-restore
126 * - Use SetCapture to allow drag-selecting outside the window
127 * - Correctly update window title when iconic and in win_name_always mode
128 *
129 * Revision 1.1.1.1 1996/02/18 21:38:11 ylo
130 * Imported ssh-1.2.13.
131 *
132 * Revision 1.2 1995/07/13 01:22:25 ylo
133 * Added cvs log.
134 *
135 * $Endlog$
136 */
137
138 /* Table for key generation. This used to be in sk.h. */
139 /* Copyright (C) 1993 Eric Young - see README for more details */
140 static const word32 des_skb[8][64]={
141 /* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
142 { 0x00000000,0x00000010,0x20000000,0x20000010,
143 0x00010000,0x00010010,0x20010000,0x20010010,
144 0x00000800,0x00000810,0x20000800,0x20000810,
145 0x00010800,0x00010810,0x20010800,0x20010810,
146 0x00000020,0x00000030,0x20000020,0x20000030,
147 0x00010020,0x00010030,0x20010020,0x20010030,
148 0x00000820,0x00000830,0x20000820,0x20000830,
149 0x00010820,0x00010830,0x20010820,0x20010830,
150 0x00080000,0x00080010,0x20080000,0x20080010,
151 0x00090000,0x00090010,0x20090000,0x20090010,
152 0x00080800,0x00080810,0x20080800,0x20080810,
153 0x00090800,0x00090810,0x20090800,0x20090810,
154 0x00080020,0x00080030,0x20080020,0x20080030,
155 0x00090020,0x00090030,0x20090020,0x20090030,
156 0x00080820,0x00080830,0x20080820,0x20080830,
157 0x00090820,0x00090830,0x20090820,0x20090830 },
158 /* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
159 { 0x00000000,0x02000000,0x00002000,0x02002000,
160 0x00200000,0x02200000,0x00202000,0x02202000,
161 0x00000004,0x02000004,0x00002004,0x02002004,
162 0x00200004,0x02200004,0x00202004,0x02202004,
163 0x00000400,0x02000400,0x00002400,0x02002400,
164 0x00200400,0x02200400,0x00202400,0x02202400,
165 0x00000404,0x02000404,0x00002404,0x02002404,
166 0x00200404,0x02200404,0x00202404,0x02202404,
167 0x10000000,0x12000000,0x10002000,0x12002000,
168 0x10200000,0x12200000,0x10202000,0x12202000,
169 0x10000004,0x12000004,0x10002004,0x12002004,
170 0x10200004,0x12200004,0x10202004,0x12202004,
171 0x10000400,0x12000400,0x10002400,0x12002400,
172 0x10200400,0x12200400,0x10202400,0x12202400,
173 0x10000404,0x12000404,0x10002404,0x12002404,
174 0x10200404,0x12200404,0x10202404,0x12202404 },
175 /* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
176 { 0x00000000,0x00000001,0x00040000,0x00040001,
177 0x01000000,0x01000001,0x01040000,0x01040001,
178 0x00000002,0x00000003,0x00040002,0x00040003,
179 0x01000002,0x01000003,0x01040002,0x01040003,
180 0x00000200,0x00000201,0x00040200,0x00040201,
181 0x01000200,0x01000201,0x01040200,0x01040201,
182 0x00000202,0x00000203,0x00040202,0x00040203,
183 0x01000202,0x01000203,0x01040202,0x01040203,
184 0x08000000,0x08000001,0x08040000,0x08040001,
185 0x09000000,0x09000001,0x09040000,0x09040001,
186 0x08000002,0x08000003,0x08040002,0x08040003,
187 0x09000002,0x09000003,0x09040002,0x09040003,
188 0x08000200,0x08000201,0x08040200,0x08040201,
189 0x09000200,0x09000201,0x09040200,0x09040201,
190 0x08000202,0x08000203,0x08040202,0x08040203,
191 0x09000202,0x09000203,0x09040202,0x09040203 },
192 /* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
193 { 0x00000000,0x00100000,0x00000100,0x00100100,
194 0x00000008,0x00100008,0x00000108,0x00100108,
195 0x00001000,0x00101000,0x00001100,0x00101100,
196 0x00001008,0x00101008,0x00001108,0x00101108,
197 0x04000000,0x04100000,0x04000100,0x04100100,
198 0x04000008,0x04100008,0x04000108,0x04100108,
199 0x04001000,0x04101000,0x04001100,0x04101100,
200 0x04001008,0x04101008,0x04001108,0x04101108,
201 0x00020000,0x00120000,0x00020100,0x00120100,
202 0x00020008,0x00120008,0x00020108,0x00120108,
203 0x00021000,0x00121000,0x00021100,0x00121100,
204 0x00021008,0x00121008,0x00021108,0x00121108,
205 0x04020000,0x04120000,0x04020100,0x04120100,
206 0x04020008,0x04120008,0x04020108,0x04120108,
207 0x04021000,0x04121000,0x04021100,0x04121100,
208 0x04021008,0x04121008,0x04021108,0x04121108 },
209 /* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
210 { 0x00000000,0x10000000,0x00010000,0x10010000,
211 0x00000004,0x10000004,0x00010004,0x10010004,
212 0x20000000,0x30000000,0x20010000,0x30010000,
213 0x20000004,0x30000004,0x20010004,0x30010004,
214 0x00100000,0x10100000,0x00110000,0x10110000,
215 0x00100004,0x10100004,0x00110004,0x10110004,
216 0x20100000,0x30100000,0x20110000,0x30110000,
217 0x20100004,0x30100004,0x20110004,0x30110004,
218 0x00001000,0x10001000,0x00011000,0x10011000,
219 0x00001004,0x10001004,0x00011004,0x10011004,
220 0x20001000,0x30001000,0x20011000,0x30011000,
221 0x20001004,0x30001004,0x20011004,0x30011004,
222 0x00101000,0x10101000,0x00111000,0x10111000,
223 0x00101004,0x10101004,0x00111004,0x10111004,
224 0x20101000,0x30101000,0x20111000,0x30111000,
225 0x20101004,0x30101004,0x20111004,0x30111004 },
226 /* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
227 { 0x00000000,0x08000000,0x00000008,0x08000008,
228 0x00000400,0x08000400,0x00000408,0x08000408,
229 0x00020000,0x08020000,0x00020008,0x08020008,
230 0x00020400,0x08020400,0x00020408,0x08020408,
231 0x00000001,0x08000001,0x00000009,0x08000009,
232 0x00000401,0x08000401,0x00000409,0x08000409,
233 0x00020001,0x08020001,0x00020009,0x08020009,
234 0x00020401,0x08020401,0x00020409,0x08020409,
235 0x02000000,0x0A000000,0x02000008,0x0A000008,
236 0x02000400,0x0A000400,0x02000408,0x0A000408,
237 0x02020000,0x0A020000,0x02020008,0x0A020008,
238 0x02020400,0x0A020400,0x02020408,0x0A020408,
239 0x02000001,0x0A000001,0x02000009,0x0A000009,
240 0x02000401,0x0A000401,0x02000409,0x0A000409,
241 0x02020001,0x0A020001,0x02020009,0x0A020009,
242 0x02020401,0x0A020401,0x02020409,0x0A020409 },
243 /* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
244 { 0x00000000,0x00000100,0x00080000,0x00080100,
245 0x01000000,0x01000100,0x01080000,0x01080100,
246 0x00000010,0x00000110,0x00080010,0x00080110,
247 0x01000010,0x01000110,0x01080010,0x01080110,
248 0x00200000,0x00200100,0x00280000,0x00280100,
249 0x01200000,0x01200100,0x01280000,0x01280100,
250 0x00200010,0x00200110,0x00280010,0x00280110,
251 0x01200010,0x01200110,0x01280010,0x01280110,
252 0x00000200,0x00000300,0x00080200,0x00080300,
253 0x01000200,0x01000300,0x01080200,0x01080300,
254 0x00000210,0x00000310,0x00080210,0x00080310,
255 0x01000210,0x01000310,0x01080210,0x01080310,
256 0x00200200,0x00200300,0x00280200,0x00280300,
257 0x01200200,0x01200300,0x01280200,0x01280300,
258 0x00200210,0x00200310,0x00280210,0x00280310,
259 0x01200210,0x01200310,0x01280210,0x01280310 },
260 /* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
261 { 0x00000000,0x04000000,0x00040000,0x04040000,
262 0x00000002,0x04000002,0x00040002,0x04040002,
263 0x00002000,0x04002000,0x00042000,0x04042000,
264 0x00002002,0x04002002,0x00042002,0x04042002,
265 0x00000020,0x04000020,0x00040020,0x04040020,
266 0x00000022,0x04000022,0x00040022,0x04040022,
267 0x00002020,0x04002020,0x00042020,0x04042020,
268 0x00002022,0x04002022,0x00042022,0x04042022,
269 0x00000800,0x04000800,0x00040800,0x04040800,
270 0x00000802,0x04000802,0x00040802,0x04040802,
271 0x00002800,0x04002800,0x00042800,0x04042800,
272 0x00002802,0x04002802,0x00042802,0x04042802,
273 0x00000820,0x04000820,0x00040820,0x04040820,
274 0x00000822,0x04000822,0x00040822,0x04040822,
275 0x00002820,0x04002820,0x00042820,0x04042820,
276 0x00002822,0x04002822,0x00042822,0x04042822 }
277 };
278
279 /* Tables used for executing des. This used to be in spr.h. */
280 /* Copyright (C) 1993 Eric Young - see README for more details */
281 static const word32 des_SPtrans[8][64]={
282 /* nibble 0 */
283 { 0x00820200, 0x00020000, 0x80800000, 0x80820200,
284 0x00800000, 0x80020200, 0x80020000, 0x80800000,
285 0x80020200, 0x00820200, 0x00820000, 0x80000200,
286 0x80800200, 0x00800000, 0x00000000, 0x80020000,
287 0x00020000, 0x80000000, 0x00800200, 0x00020200,
288 0x80820200, 0x00820000, 0x80000200, 0x00800200,
289 0x80000000, 0x00000200, 0x00020200, 0x80820000,
290 0x00000200, 0x80800200, 0x80820000, 0x00000000,
291 0x00000000, 0x80820200, 0x00800200, 0x80020000,
292 0x00820200, 0x00020000, 0x80000200, 0x00800200,
293 0x80820000, 0x00000200, 0x00020200, 0x80800000,
294 0x80020200, 0x80000000, 0x80800000, 0x00820000,
295 0x80820200, 0x00020200, 0x00820000, 0x80800200,
296 0x00800000, 0x80000200, 0x80020000, 0x00000000,
297 0x00020000, 0x00800000, 0x80800200, 0x00820200,
298 0x80000000, 0x80820000, 0x00000200, 0x80020200 },
299
300 /* nibble 1 */
301 { 0x10042004, 0x00000000, 0x00042000, 0x10040000,
302 0x10000004, 0x00002004, 0x10002000, 0x00042000,
303 0x00002000, 0x10040004, 0x00000004, 0x10002000,
304 0x00040004, 0x10042000, 0x10040000, 0x00000004,
305 0x00040000, 0x10002004, 0x10040004, 0x00002000,
306 0x00042004, 0x10000000, 0x00000000, 0x00040004,
307 0x10002004, 0x00042004, 0x10042000, 0x10000004,
308 0x10000000, 0x00040000, 0x00002004, 0x10042004,
309 0x00040004, 0x10042000, 0x10002000, 0x00042004,
310 0x10042004, 0x00040004, 0x10000004, 0x00000000,
311 0x10000000, 0x00002004, 0x00040000, 0x10040004,
312 0x00002000, 0x10000000, 0x00042004, 0x10002004,
313 0x10042000, 0x00002000, 0x00000000, 0x10000004,
314 0x00000004, 0x10042004, 0x00042000, 0x10040000,
315 0x10040004, 0x00040000, 0x00002004, 0x10002000,
316 0x10002004, 0x00000004, 0x10040000, 0x00042000 },
317
318 /* nibble 2 */
319 { 0x41000000, 0x01010040, 0x00000040, 0x41000040,
320 0x40010000, 0x01000000, 0x41000040, 0x00010040,
321 0x01000040, 0x00010000, 0x01010000, 0x40000000,
322 0x41010040, 0x40000040, 0x40000000, 0x41010000,
323 0x00000000, 0x40010000, 0x01010040, 0x00000040,
324 0x40000040, 0x41010040, 0x00010000, 0x41000000,
325 0x41010000, 0x01000040, 0x40010040, 0x01010000,
326 0x00010040, 0x00000000, 0x01000000, 0x40010040,
327 0x01010040, 0x00000040, 0x40000000, 0x00010000,
328 0x40000040, 0x40010000, 0x01010000, 0x41000040,
329 0x00000000, 0x01010040, 0x00010040, 0x41010000,
330 0x40010000, 0x01000000, 0x41010040, 0x40000000,
331 0x40010040, 0x41000000, 0x01000000, 0x41010040,
332 0x00010000, 0x01000040, 0x41000040, 0x00010040,
333 0x01000040, 0x00000000, 0x41010000, 0x40000040,
334 0x41000000, 0x40010040, 0x00000040, 0x01010000 },
335
336 /* nibble 3 */
337 { 0x00100402, 0x04000400, 0x00000002, 0x04100402,
338 0x00000000, 0x04100000, 0x04000402, 0x00100002,
339 0x04100400, 0x04000002, 0x04000000, 0x00000402,
340 0x04000002, 0x00100402, 0x00100000, 0x04000000,
341 0x04100002, 0x00100400, 0x00000400, 0x00000002,
342 0x00100400, 0x04000402, 0x04100000, 0x00000400,
343 0x00000402, 0x00000000, 0x00100002, 0x04100400,
344 0x04000400, 0x04100002, 0x04100402, 0x00100000,
345 0x04100002, 0x00000402, 0x00100000, 0x04000002,
346 0x00100400, 0x04000400, 0x00000002, 0x04100000,
347 0x04000402, 0x00000000, 0x00000400, 0x00100002,
348 0x00000000, 0x04100002, 0x04100400, 0x00000400,
349 0x04000000, 0x04100402, 0x00100402, 0x00100000,
350 0x04100402, 0x00000002, 0x04000400, 0x00100402,
351 0x00100002, 0x00100400, 0x04100000, 0x04000402,
352 0x00000402, 0x04000000, 0x04000002, 0x04100400 },
353
354 /* nibble 4 */
355 { 0x02000000, 0x00004000, 0x00000100, 0x02004108,
356 0x02004008, 0x02000100, 0x00004108, 0x02004000,
357 0x00004000, 0x00000008, 0x02000008, 0x00004100,
358 0x02000108, 0x02004008, 0x02004100, 0x00000000,
359 0x00004100, 0x02000000, 0x00004008, 0x00000108,
360 0x02000100, 0x00004108, 0x00000000, 0x02000008,
361 0x00000008, 0x02000108, 0x02004108, 0x00004008,
362 0x02004000, 0x00000100, 0x00000108, 0x02004100,
363 0x02004100, 0x02000108, 0x00004008, 0x02004000,
364 0x00004000, 0x00000008, 0x02000008, 0x02000100,
365 0x02000000, 0x00004100, 0x02004108, 0x00000000,
366 0x00004108, 0x02000000, 0x00000100, 0x00004008,
367 0x02000108, 0x00000100, 0x00000000, 0x02004108,
368 0x02004008, 0x02004100, 0x00000108, 0x00004000,
369 0x00004100, 0x02004008, 0x02000100, 0x00000108,
370 0x00000008, 0x00004108, 0x02004000, 0x02000008 },
371
372 /* nibble 5 */
373 { 0x20000010, 0x00080010, 0x00000000, 0x20080800,
374 0x00080010, 0x00000800, 0x20000810, 0x00080000,
375 0x00000810, 0x20080810, 0x00080800, 0x20000000,
376 0x20000800, 0x20000010, 0x20080000, 0x00080810,
377 0x00080000, 0x20000810, 0x20080010, 0x00000000,
378 0x00000800, 0x00000010, 0x20080800, 0x20080010,
379 0x20080810, 0x20080000, 0x20000000, 0x00000810,
380 0x00000010, 0x00080800, 0x00080810, 0x20000800,
381 0x00000810, 0x20000000, 0x20000800, 0x00080810,
382 0x20080800, 0x00080010, 0x00000000, 0x20000800,
383 0x20000000, 0x00000800, 0x20080010, 0x00080000,
384 0x00080010, 0x20080810, 0x00080800, 0x00000010,
385 0x20080810, 0x00080800, 0x00080000, 0x20000810,
386 0x20000010, 0x20080000, 0x00080810, 0x00000000,
387 0x00000800, 0x20000010, 0x20000810, 0x20080800,
388 0x20080000, 0x00000810, 0x00000010, 0x20080010 },
389
390 /* nibble 6 */
391 { 0x00001000, 0x00000080, 0x00400080, 0x00400001,
392 0x00401081, 0x00001001, 0x00001080, 0x00000000,
393 0x00400000, 0x00400081, 0x00000081, 0x00401000,
394 0x00000001, 0x00401080, 0x00401000, 0x00000081,
395 0x00400081, 0x00001000, 0x00001001, 0x00401081,
396 0x00000000, 0x00400080, 0x00400001, 0x00001080,
397 0x00401001, 0x00001081, 0x00401080, 0x00000001,
398 0x00001081, 0x00401001, 0x00000080, 0x00400000,
399 0x00001081, 0x00401000, 0x00401001, 0x00000081,
400 0x00001000, 0x00000080, 0x00400000, 0x00401001,
401 0x00400081, 0x00001081, 0x00001080, 0x00000000,
402 0x00000080, 0x00400001, 0x00000001, 0x00400080,
403 0x00000000, 0x00400081, 0x00400080, 0x00001080,
404 0x00000081, 0x00001000, 0x00401081, 0x00400000,
405 0x00401080, 0x00000001, 0x00001001, 0x00401081,
406 0x00400001, 0x00401080, 0x00401000, 0x00001001 },
407
408 /* nibble 7 */
409 { 0x08200020, 0x08208000, 0x00008020, 0x00000000,
410 0x08008000, 0x00200020, 0x08200000, 0x08208020,
411 0x00000020, 0x08000000, 0x00208000, 0x00008020,
412 0x00208020, 0x08008020, 0x08000020, 0x08200000,
413 0x00008000, 0x00208020, 0x00200020, 0x08008000,
414 0x08208020, 0x08000020, 0x00000000, 0x00208000,
415 0x08000000, 0x00200000, 0x08008020, 0x08200020,
416 0x00200000, 0x00008000, 0x08208000, 0x00000020,
417 0x00200000, 0x00008000, 0x08000020, 0x08208020,
418 0x00008020, 0x08000000, 0x00000000, 0x00208000,
419 0x08200020, 0x08008020, 0x08008000, 0x00200020,
420 0x08208000, 0x00000020, 0x00200020, 0x08008000,
421 0x08208020, 0x00200000, 0x08200000, 0x08000020,
422 0x00208000, 0x00008020, 0x08008020, 0x08200000,
423 0x00000020, 0x08208000, 0x00208020, 0x00000000,
424 0x08000000, 0x08200020, 0x00008000, 0x00208020 }};
425
426 /* Some stuff that used to be in des_locl.h. Heavily modified. */
427 /* IP and FP
428 * The problem is more of a geometric problem that random bit fiddling.
429 0 1 2 3 4 5 6 7 62 54 46 38 30 22 14 6
430 8 9 10 11 12 13 14 15 60 52 44 36 28 20 12 4
431 16 17 18 19 20 21 22 23 58 50 42 34 26 18 10 2
432 24 25 26 27 28 29 30 31 to 56 48 40 32 24 16 8 0
433
434 32 33 34 35 36 37 38 39 63 55 47 39 31 23 15 7
435 40 41 42 43 44 45 46 47 61 53 45 37 29 21 13 5
436 48 49 50 51 52 53 54 55 59 51 43 35 27 19 11 3
437 56 57 58 59 60 61 62 63 57 49 41 33 25 17 9 1
438
439 The output has been subject to swaps of the form
440 0 1 -> 3 1 but the odd and even bits have been put into
441 2 3 2 0
442 different words. The main trick is to remember that
443 t=((l>>size)^r)&(mask);
444 r^=t;
445 l^=(t<<size);
446 can be used to swap and move bits between words.
447
448 So l = 0 1 2 3 r = 16 17 18 19
449 4 5 6 7 20 21 22 23
450 8 9 10 11 24 25 26 27
451 12 13 14 15 28 29 30 31
452 becomes (for size == 2 and mask == 0x3333)
453 t = 2^16 3^17 -- -- l = 0 1 16 17 r = 2 3 18 19
454 6^20 7^21 -- -- 4 5 20 21 6 7 22 23
455 10^24 11^25 -- -- 8 9 24 25 10 11 24 25
456 14^28 15^29 -- -- 12 13 28 29 14 15 28 29
457
458 Thanks for hints from Richard Outerbridge - he told me IP&FP
459 could be done in 15 xor, 10 shifts and 5 ands.
460 When I finally started to think of the problem in 2D
461 I first got ~42 operations without xors. When I remembered
462 how to use xors :-) I got it to its final state.
463 */
464 #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
465 (b)^=(t),\
466 (a)^=((t)<<(n)))
467
468 #define IP(l,r,t) \
469 PERM_OP(r,l,t, 4,0x0f0f0f0f); \
470 PERM_OP(l,r,t,16,0x0000ffff); \
471 PERM_OP(r,l,t, 2,0x33333333); \
472 PERM_OP(l,r,t, 8,0x00ff00ff); \
473 PERM_OP(r,l,t, 1,0x55555555);
474
475 #define FP(l,r,t) \
476 PERM_OP(l,r,t, 1,0x55555555); \
477 PERM_OP(r,l,t, 8,0x00ff00ff); \
478 PERM_OP(l,r,t, 2,0x33333333); \
479 PERM_OP(r,l,t,16,0x0000ffff); \
480 PERM_OP(l,r,t, 4,0x0f0f0f0f);
481
482 #define D_ENCRYPT(L,R,S) \
483 u=(R^s[S ]); \
484 t=R^s[S+1]; \
485 t=((t>>4)+(t<<28)); \
486 L^= des_SPtrans[1][(t )&0x3f]| \
487 des_SPtrans[3][(t>> 8)&0x3f]| \
488 des_SPtrans[5][(t>>16)&0x3f]| \
489 des_SPtrans[7][(t>>24)&0x3f]| \
490 des_SPtrans[0][(u )&0x3f]| \
491 des_SPtrans[2][(u>> 8)&0x3f]| \
492 des_SPtrans[4][(u>>16)&0x3f]| \
493 des_SPtrans[6][(u>>24)&0x3f];
494
495 /* This part is based on code that used to be in ecb_enc.c. */
496 /* Copyright (C) 1993 Eric Young - see README for more details */
497
498 static void des_encrypt(word32 l, word32 r, word32 *output, DESContext *ks,
499 int encrypt)
500 {
501 register word32 t,u;
502 register int i;
503 register word32 *s;
504
505 s = ks->key_schedule;
506
507 IP(l,r,t);
508 /* Things have been modified so that the initial rotate is
509 * done outside the loop. This required the
510 * des_SPtrans values in sp.h to be rotated 1 bit to the right.
511 * One perl script later and things have a 5% speed up on a sparc2.
512 * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
513 * for pointing this out. */
514 t=(r<<1)|(r>>31);
515 r=(l<<1)|(l>>31);
516 l=t;
517
518 /* I don't know if it is worth the effort of loop unrolling the
519 * inner loop */
520 if (encrypt)
521 {
522 for (i=0; i<32; i+=4)
523 {
524 D_ENCRYPT(l,r,i+0); /* 1 */
525 D_ENCRYPT(r,l,i+2); /* 2 */
526 }
527 }
528 else
529 {
530 for (i=30; i>0; i-=4)
531 {
532 D_ENCRYPT(l,r,i-0); /* 16 */
533 D_ENCRYPT(r,l,i-2); /* 15 */
534 }
535 }
536 l=(l>>1)|(l<<31);
537 r=(r>>1)|(r<<31);
538
539 FP(r,l,t);
540 output[0]=l;
541 output[1]=r;
542 }
543
544 /* Code based on set_key.c. */
545 /* Copyright (C) 1993 Eric Young - see README for more details */
546
547 #define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
548 (a)=(a)^(t)^(t>>(16-(n))))
549
550 static void des_set_key(unsigned char *key, DESContext *ks)
551 {
552 register word32 c, d, t, s, shifts;
553 register int i;
554 register word32 *schedule;
555
556 schedule = ks->key_schedule;
557
558 c = GET_32BIT_LSB_FIRST(key);
559 d = GET_32BIT_LSB_FIRST(key + 4);
560
561 /* I now do it in 47 simple operations :-)
562 * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
563 * for the inspiration. :-) */
564 PERM_OP(d,c,t,4,0x0f0f0f0f);
565 HPERM_OP(c,t,-2,0xcccc0000);
566 HPERM_OP(d,t,-2,0xcccc0000);
567 PERM_OP(d,c,t,1,0x55555555);
568 PERM_OP(c,d,t,8,0x00ff00ff);
569 PERM_OP(d,c,t,1,0x55555555);
570 d = ((d & 0xff) << 16) | (d & 0xff00) |
571 ((d >> 16) & 0xff) | ((c >> 4) & 0xf000000);
572 c&=0x0fffffff;
573
574 shifts = 0x7efc;
575 for (i=0; i < 16; i++)
576 {
577 if (shifts & 1)
578 { c=((c>>2)|(c<<26)); d=((d>>2)|(d<<26)); }
579 else
580 { c=((c>>1)|(c<<27)); d=((d>>1)|(d<<27)); }
581 shifts >>= 1;
582 c&=0x0fffffff;
583 d&=0x0fffffff;
584
585 /* could be a few less shifts but I am to lazy at this
586 * point in time to investigate */
587
588 s = des_skb[0][ (c )&0x3f ] |
589 des_skb[1][((c>> 6)&0x03)|((c>> 7)&0x3c)] |
590 des_skb[2][((c>>13)&0x0f)|((c>>14)&0x30)] |
591 des_skb[3][((c>>20)&0x01)|((c>>21)&0x06)|((c>>22)&0x38)];
592
593 t = des_skb[4][ (d )&0x3f ] |
594 des_skb[5][((d>> 7)&0x03)|((d>> 8)&0x3c)] |
595 des_skb[6][ (d>>15)&0x3f ] |
596 des_skb[7][((d>>21)&0x0f)|((d>>22)&0x30)];
597
598 /* table contained 0213 4657 */
599 *schedule++ = ((t << 16) | (s & 0xffff));
600 s = ((s >> 16) | (t & 0xffff0000));
601 *schedule++ = (s << 4) | (s >> 28);
602 }
603 }
604
605 static void des_cbc_encrypt(DESContext *ks, unsigned char *iv,
606 unsigned char *dest, const unsigned char *src,
607 unsigned int len)
608 {
609 word32 iv0, iv1, out[2];
610 unsigned int i;
611
612 assert((len & 7) == 0);
613
614 iv0 = GET_32BIT_LSB_FIRST(iv);
615 iv1 = GET_32BIT_LSB_FIRST(iv + 4);
616
617 for (i = 0; i < len; i += 8)
618 {
619 iv0 ^= GET_32BIT_LSB_FIRST(src + i);
620 iv1 ^= GET_32BIT_LSB_FIRST(src + i + 4);
621 des_encrypt(iv0, iv1, out, ks, 1);
622 iv0 = out[0];
623 iv1 = out[1];
624 PUT_32BIT_LSB_FIRST(dest + i, iv0);
625 PUT_32BIT_LSB_FIRST(dest + i + 4, iv1);
626 }
627 PUT_32BIT_LSB_FIRST(iv, iv0);
628 PUT_32BIT_LSB_FIRST(iv + 4, iv1);
629 }
630
631 static void des_cbc_decrypt(DESContext *ks, unsigned char *iv,
632 unsigned char *dest, const unsigned char *src,
633 unsigned int len)
634 {
635 word32 iv0, iv1, d0, d1, out[2];
636 unsigned int i;
637
638 assert((len & 7) == 0);
639
640 iv0 = GET_32BIT_LSB_FIRST(iv);
641 iv1 = GET_32BIT_LSB_FIRST(iv + 4);
642
643 for (i = 0; i < len; i += 8)
644 {
645 d0 = GET_32BIT_LSB_FIRST(src + i);
646 d1 = GET_32BIT_LSB_FIRST(src + i + 4);
647 des_encrypt(d0, d1, out, ks, 0);
648 iv0 ^= out[0];
649 iv1 ^= out[1];
650 PUT_32BIT_LSB_FIRST(dest + i, iv0);
651 PUT_32BIT_LSB_FIRST(dest + i + 4, iv1);
652 iv0 = d0;
653 iv1 = d1;
654 }
655 PUT_32BIT_LSB_FIRST(iv, iv0);
656 PUT_32BIT_LSB_FIRST(iv + 4, iv1);
657 }
658
659 static void des_3cbc_encrypt(DESContext *ks1, unsigned char *iv1,
660 DESContext *ks2, unsigned char *iv2,
661 DESContext *ks3, unsigned char *iv3,
662 unsigned char *dest, const unsigned char *src,
663 unsigned int len)
664 {
665 des_cbc_encrypt(ks1, iv1, dest, src, len);
666 des_cbc_decrypt(ks2, iv2, dest, dest, len);
667 des_cbc_encrypt(ks3, iv3, dest, dest, len);
668 }
669
670 static void des_3cbc_decrypt(DESContext *ks1, unsigned char *iv1,
671 DESContext *ks2, unsigned char *iv2,
672 DESContext *ks3, unsigned char *iv3,
673 unsigned char *dest, const unsigned char *src,
674 unsigned int len)
675 {
676 des_cbc_decrypt(ks3, iv3, dest, src, len);
677 des_cbc_encrypt(ks2, iv2, dest, dest, len);
678 des_cbc_decrypt(ks1, iv1, dest, dest, len);
679 }
680
681 DESContext ekey1, ekey2, ekey3;
682 unsigned char eiv1[8], eiv2[8], eiv3[8];
683
684 DESContext dkey1, dkey2, dkey3;
685 unsigned char div1[8], div2[8], div3[8];
686
687 static void des3_sesskey(unsigned char *key) {
688 des_set_key(key, &ekey1);
689 des_set_key(key+8, &ekey2);
690 des_set_key(key+16, &ekey3);
691 memset(eiv1, 0, sizeof(eiv1));
692 memset(eiv2, 0, sizeof(eiv2));
693 memset(eiv3, 0, sizeof(eiv3));
694 des_set_key(key, &dkey1);
695 des_set_key(key+8, &dkey2);
696 des_set_key(key+16, &dkey3);
697 memset(div1, 0, sizeof(div1));
698 memset(div2, 0, sizeof(div2));
699 memset(div3, 0, sizeof(div3));
700 }
701
702 static void des3_encrypt_blk(unsigned char *blk, int len) {
703 des_3cbc_encrypt(&ekey1, eiv1, &ekey2, eiv2, &ekey3, eiv3, blk, blk, len);
704 }
705
706 static void des3_decrypt_blk(unsigned char *blk, int len) {
707 des_3cbc_decrypt(&dkey1, div1, &dkey2, div2, &dkey3, div3, blk, blk, len);
708 }
709
710 struct ssh_cipher ssh_3des = {
711 des3_sesskey,
712 des3_encrypt_blk,
713 des3_decrypt_blk
714 };
715
716 #ifdef DES_TEST
717
718 void des_encrypt_buf(DESContext *ks, unsigned char *out,
719 const unsigned char *in, int encrypt)
720 {
721 word32 in0, in1, output[0];
722
723 in0 = GET_32BIT_LSB_FIRST(in);
724 in1 = GET_32BIT_LSB_FIRST(in + 4);
725 des_encrypt(in0, in1, output, ks, encrypt);
726 PUT_32BIT_LSB_FIRST(out, output[0]);
727 PUT_32BIT_LSB_FIRST(out + 4, output[1]);
728 }
729
730 int main(int ac, char **av)
731 {
732 FILE *f;
733 char line[1024], *cp;
734 int i, value;
735 unsigned char key[8], data[8], result[8], output[8];
736 DESContext ks;
737
738 while (fgets(line, sizeof(line), stdin))
739 {
740 for (i = 0; i < 8; i++)
741 {
742 if (sscanf(line + 2 * i, "%02x", &value) != 1)
743 {
744 fprintf(stderr, "1st col, i = %d, line: %s", i, line);
745 exit(1);
746 }
747 key[i] = value;
748 }
749 for (i = 0; i < 8; i++)
750 {
751 if (sscanf(line + 2 * i + 17, "%02x", &value) != 1)
752 {
753 fprintf(stderr, "2nd col, i = %d, line: %s", i, line);
754 exit(1);
755 }
756 data[i] = value;
757 }
758 for (i = 0; i < 8; i++)
759 {
760 if (sscanf(line + 2 * i + 2*17, "%02x", &value) != 1)
761 {
762 fprintf(stderr, "3rd col, i = %d, line: %s", i, line);
763 exit(1);
764 }
765 result[i] = value;
766 }
767 des_set_key(key, &ks);
768 des_encrypt_buf(&ks, output, data, 1);
769 if (memcmp(output, result, 8) != 0)
770 fprintf(stderr, "Encrypt failed: %s", line);
771 des_encrypt_buf(&ks, output, result, 0);
772 if (memcmp(output, data, 8) != 0)
773 fprintf(stderr, "Decrypt failed: %s", line);
774 }
775 exit(0);
776 }
777 #endif /* DES_TEST */
778