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