6 DES implementation; 1995 Tatu Ylonen <ylo@cs.hut.fi>
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.
13 This implementation is distributed under the same terms. See
14 libdes-README, libdes-ARTISTIC, and libdes-COPYING for more
20 * $Id: sshdes.c,v 1.1 1999/01/08 13:02:12 simon Exp $
22 * Revision 1.1 1999/01/08 13:02:12 simon
23 * Initial checkin: beta 0.43
25 * Revision 1.1.1.1 1996/02/18 21:38:11 ylo
26 * Imported ssh-1.2.13.
28 * Revision 1.2 1995/07/13 01:22:57 ylo
36 word32 key_schedule
[32];
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
);
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
,
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
52 static void des_cbc_encrypt(DESContext
*ks
, unsigned char *iv
, unsigned char *dest
,
53 const unsigned char *src
, unsigned int len
);
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
58 static void des_cbc_decrypt(DESContext
*ks
, unsigned char *iv
, unsigned char *dest
,
59 const unsigned char *src
, unsigned int len
);
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
,
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
,
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))
81 #define PUT_32BIT_LSB_FIRST(cp, value) do { \
83 (cp)[1] = (value) >> 8; \
84 (cp)[2] = (value) >> 16; \
85 (cp)[3] = (value) >> 24; } while (0)
89 DES implementation; 1995 Tatu Ylonen <ylo@cs.hut.fi>
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.
96 This implementation is distributed under the same terms. See
97 libdes-README, libdes-ARTISTIC, and libdes-COPYING for more
100 A description of the DES algorithm can be found in every modern book on
101 cryptography and data security, including the following:
103 Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1994.
105 Jennifer Seberry and Josed Pieprzyk: Cryptography: An Introduction to
106 Computer Security. Prentice-Hall, 1989.
108 Man Young Rhee: Cryptography and Secure Data Communications. McGraw-Hill,
114 * $Id: sshdes.c,v 1.1 1999/01/08 13:02:12 simon Exp $
116 * Revision 1.1 1999/01/08 13:02:12 simon
117 * Initial checkin: beta 0.43
119 * Revision 1.1.1.1 1996/02/18 21:38:11 ylo
120 * Imported ssh-1.2.13.
122 * Revision 1.2 1995/07/13 01:22:25 ylo
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 }
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]={
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 },
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 },
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 },
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 },
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 },
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 },
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 },
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 }};
416 /* Some stuff that used to be in des_locl.h. Heavily modified. */
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
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
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
432 different words. The main trick is to remember that
433 t=((l>>size)^r)&(mask);
436 can be used to swap and move bits between words.
438 So l = 0 1 2 3 r = 16 17 18 19
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
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.
454 #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
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);
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);
472 #define D_ENCRYPT(L,R,S) \
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];
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 */
488 static void des_encrypt(word32 l
, word32 r
, word32
*output
, DESContext
*ks
,
495 s
= ks
->key_schedule
;
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. */
508 /* I don't know if it is worth the effort of loop unrolling the
512 for (i
=0; i
<32; i
+=4)
514 D_ENCRYPT(l
,r
,i
+0); /* 1 */
515 D_ENCRYPT(r
,l
,i
+2); /* 2 */
520 for (i
=30; i
>0; i
-=4)
522 D_ENCRYPT(l
,r
,i
-0); /* 16 */
523 D_ENCRYPT(r
,l
,i
-2); /* 15 */
534 /* Code based on set_key.c. */
535 /* Copyright (C) 1993 Eric Young - see README for more details */
537 #define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
538 (a)=(a)^(t)^(t>>(16-(n))))
540 static void des_set_key(unsigned char *key
, DESContext
*ks
)
542 register word32 c
, d
, t
, s
, shifts
;
544 register word32
*schedule
;
546 schedule
= ks
->key_schedule
;
548 c
= GET_32BIT_LSB_FIRST(key
);
549 d
= GET_32BIT_LSB_FIRST(key
+ 4);
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);
565 for (i
=0; i
< 16; i
++)
568 { c
=((c
>>2)|(c
<<26)); d
=((d
>>2)|(d
<<26)); }
570 { c
=((c
>>1)|(c
<<27)); d
=((d
>>1)|(d
<<27)); }
575 /* could be a few less shifts but I am to lazy at this
576 * point in time to investigate */
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)];
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)];
588 /* table contained 0213 4657 */
589 *schedule
++ = ((t
<< 16) | (s
& 0xffff));
590 s
= ((s
>> 16) | (t
& 0xffff0000));
591 *schedule
++ = (s
<< 4) | (s
>> 28);
595 static void des_cbc_encrypt(DESContext
*ks
, unsigned char *iv
,
596 unsigned char *dest
, const unsigned char *src
,
599 word32 iv0
, iv1
, out
[2];
602 assert((len
& 7) == 0);
604 iv0
= GET_32BIT_LSB_FIRST(iv
);
605 iv1
= GET_32BIT_LSB_FIRST(iv
+ 4);
607 for (i
= 0; i
< len
; i
+= 8)
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);
614 PUT_32BIT_LSB_FIRST(dest
+ i
, iv0
);
615 PUT_32BIT_LSB_FIRST(dest
+ i
+ 4, iv1
);
617 PUT_32BIT_LSB_FIRST(iv
, iv0
);
618 PUT_32BIT_LSB_FIRST(iv
+ 4, iv1
);
621 static void des_cbc_decrypt(DESContext
*ks
, unsigned char *iv
,
622 unsigned char *dest
, const unsigned char *src
,
625 word32 iv0
, iv1
, d0
, d1
, out
[2];
628 assert((len
& 7) == 0);
630 iv0
= GET_32BIT_LSB_FIRST(iv
);
631 iv1
= GET_32BIT_LSB_FIRST(iv
+ 4);
633 for (i
= 0; i
< len
; i
+= 8)
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);
640 PUT_32BIT_LSB_FIRST(dest
+ i
, iv0
);
641 PUT_32BIT_LSB_FIRST(dest
+ i
+ 4, iv1
);
645 PUT_32BIT_LSB_FIRST(iv
, iv0
);
646 PUT_32BIT_LSB_FIRST(iv
+ 4, iv1
);
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
,
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
);
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
,
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
);
671 DESContext ekey1
, ekey2
, ekey3
;
672 unsigned char eiv1
[8], eiv2
[8], eiv3
[8];
674 DESContext dkey1
, dkey2
, dkey3
;
675 unsigned char div1
[8], div2
[8], div3
[8];
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
));
692 static void des3_encrypt_blk(unsigned char *blk
, int len
) {
693 des_3cbc_encrypt(&ekey1
, eiv1
, &ekey2
, eiv2
, &ekey3
, eiv3
, blk
, blk
, len
);
696 static void des3_decrypt_blk(unsigned char *blk
, int len
) {
697 des_3cbc_decrypt(&dkey1
, div1
, &dkey2
, div2
, &dkey3
, div3
, blk
, blk
, len
);
700 struct ssh_cipher ssh_3des
= {
708 void des_encrypt_buf(DESContext
*ks
, unsigned char *out
,
709 const unsigned char *in
, int encrypt
)
711 word32 in0
, in1
, output
[0];
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]);
720 int main(int ac
, char **av
)
723 char line
[1024], *cp
;
725 unsigned char key
[8], data
[8], result
[8], output
[8];
728 while (fgets(line
, sizeof(line
), stdin
))
730 for (i
= 0; i
< 8; i
++)
732 if (sscanf(line
+ 2 * i
, "%02x", &value
) != 1)
734 fprintf(stderr
, "1st col, i = %d, line: %s", i
, line
);
739 for (i
= 0; i
< 8; i
++)
741 if (sscanf(line
+ 2 * i
+ 17, "%02x", &value
) != 1)
743 fprintf(stderr
, "2nd col, i = %d, line: %s", i
, line
);
748 for (i
= 0; i
< 8; i
++)
750 if (sscanf(line
+ 2 * i
+ 2*17, "%02x", &value
) != 1)
752 fprintf(stderr
, "3rd col, i = %d, line: %s", i
, line
);
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
);
767 #endif /* DES_TEST */