source: trunk/third/ssh/des.c @ 10564

Revision 10564, 22.5 KB checked in by danw, 27 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r10563, which included commits to RCS files with non-trunk default branches.
Line 
1/*
2
3DES implementation; 1995 Tatu Ylonen <ylo@cs.hut.fi>
4
5This implementation is derived from libdes-3.06, which is copyright
6(c) 1993 Eric Young, and distributed under the GNU GPL or the ARTISTIC licence
7(at the user's option).  The original distribution can be found e.g. from
8ftp://ftp.dsi.unimi.it/pub/security/crypt/libdes/libdes-3.06.tar.gz.
9
10This implementation is distributed under the same terms.  See
11libdes-README, libdes-ARTISTIC, and libdes-COPYING for more
12information.
13
14A description of the DES algorithm can be found in every modern book on
15cryptography and data security, including the following:
16
17  Bruce Schneier: Applied Cryptography.  John Wiley & Sons, 1994.
18
19  Jennifer Seberry and Josed Pieprzyk: Cryptography: An Introduction to
20    Computer Security.  Prentice-Hall, 1989.
21
22  Man Young Rhee: Cryptography and Secure Data Communications.  McGraw-Hill,
23    1994.
24
25*/
26
27/*
28 * $Id: des.c,v 1.1.1.1 1997-10-17 22:26:07 danw Exp $
29 * $Log: not supported by cvs2svn $
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:25  ylo
34 *      Added cvs log.
35 *
36 * $Endlog$
37 */
38
39#include "includes.h"
40#include "getput.h"
41#include "des.h"
42
43/* Table for key generation.  This used to be in sk.h. */
44/* Copyright (C) 1993 Eric Young - see README for more details */
45static const word32 des_skb[8][64]={
46/* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
47{ 0x00000000,0x00000010,0x20000000,0x20000010,
480x00010000,0x00010010,0x20010000,0x20010010,
490x00000800,0x00000810,0x20000800,0x20000810,
500x00010800,0x00010810,0x20010800,0x20010810,
510x00000020,0x00000030,0x20000020,0x20000030,
520x00010020,0x00010030,0x20010020,0x20010030,
530x00000820,0x00000830,0x20000820,0x20000830,
540x00010820,0x00010830,0x20010820,0x20010830,
550x00080000,0x00080010,0x20080000,0x20080010,
560x00090000,0x00090010,0x20090000,0x20090010,
570x00080800,0x00080810,0x20080800,0x20080810,
580x00090800,0x00090810,0x20090800,0x20090810,
590x00080020,0x00080030,0x20080020,0x20080030,
600x00090020,0x00090030,0x20090020,0x20090030,
610x00080820,0x00080830,0x20080820,0x20080830,
620x00090820,0x00090830,0x20090820,0x20090830 },
63/* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
64{ 0x00000000,0x02000000,0x00002000,0x02002000,
650x00200000,0x02200000,0x00202000,0x02202000,
660x00000004,0x02000004,0x00002004,0x02002004,
670x00200004,0x02200004,0x00202004,0x02202004,
680x00000400,0x02000400,0x00002400,0x02002400,
690x00200400,0x02200400,0x00202400,0x02202400,
700x00000404,0x02000404,0x00002404,0x02002404,
710x00200404,0x02200404,0x00202404,0x02202404,
720x10000000,0x12000000,0x10002000,0x12002000,
730x10200000,0x12200000,0x10202000,0x12202000,
740x10000004,0x12000004,0x10002004,0x12002004,
750x10200004,0x12200004,0x10202004,0x12202004,
760x10000400,0x12000400,0x10002400,0x12002400,
770x10200400,0x12200400,0x10202400,0x12202400,
780x10000404,0x12000404,0x10002404,0x12002404,
790x10200404,0x12200404,0x10202404,0x12202404 },
80/* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
81{ 0x00000000,0x00000001,0x00040000,0x00040001,
820x01000000,0x01000001,0x01040000,0x01040001,
830x00000002,0x00000003,0x00040002,0x00040003,
840x01000002,0x01000003,0x01040002,0x01040003,
850x00000200,0x00000201,0x00040200,0x00040201,
860x01000200,0x01000201,0x01040200,0x01040201,
870x00000202,0x00000203,0x00040202,0x00040203,
880x01000202,0x01000203,0x01040202,0x01040203,
890x08000000,0x08000001,0x08040000,0x08040001,
900x09000000,0x09000001,0x09040000,0x09040001,
910x08000002,0x08000003,0x08040002,0x08040003,
920x09000002,0x09000003,0x09040002,0x09040003,
930x08000200,0x08000201,0x08040200,0x08040201,
940x09000200,0x09000201,0x09040200,0x09040201,
950x08000202,0x08000203,0x08040202,0x08040203,
960x09000202,0x09000203,0x09040202,0x09040203 },
97/* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
98{ 0x00000000,0x00100000,0x00000100,0x00100100,
990x00000008,0x00100008,0x00000108,0x00100108,
1000x00001000,0x00101000,0x00001100,0x00101100,
1010x00001008,0x00101008,0x00001108,0x00101108,
1020x04000000,0x04100000,0x04000100,0x04100100,
1030x04000008,0x04100008,0x04000108,0x04100108,
1040x04001000,0x04101000,0x04001100,0x04101100,
1050x04001008,0x04101008,0x04001108,0x04101108,
1060x00020000,0x00120000,0x00020100,0x00120100,
1070x00020008,0x00120008,0x00020108,0x00120108,
1080x00021000,0x00121000,0x00021100,0x00121100,
1090x00021008,0x00121008,0x00021108,0x00121108,
1100x04020000,0x04120000,0x04020100,0x04120100,
1110x04020008,0x04120008,0x04020108,0x04120108,
1120x04021000,0x04121000,0x04021100,0x04121100,
1130x04021008,0x04121008,0x04021108,0x04121108 },
114/* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
115{ 0x00000000,0x10000000,0x00010000,0x10010000,
1160x00000004,0x10000004,0x00010004,0x10010004,
1170x20000000,0x30000000,0x20010000,0x30010000,
1180x20000004,0x30000004,0x20010004,0x30010004,
1190x00100000,0x10100000,0x00110000,0x10110000,
1200x00100004,0x10100004,0x00110004,0x10110004,
1210x20100000,0x30100000,0x20110000,0x30110000,
1220x20100004,0x30100004,0x20110004,0x30110004,
1230x00001000,0x10001000,0x00011000,0x10011000,
1240x00001004,0x10001004,0x00011004,0x10011004,
1250x20001000,0x30001000,0x20011000,0x30011000,
1260x20001004,0x30001004,0x20011004,0x30011004,
1270x00101000,0x10101000,0x00111000,0x10111000,
1280x00101004,0x10101004,0x00111004,0x10111004,
1290x20101000,0x30101000,0x20111000,0x30111000,
1300x20101004,0x30101004,0x20111004,0x30111004 },
131/* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
132{ 0x00000000,0x08000000,0x00000008,0x08000008,
1330x00000400,0x08000400,0x00000408,0x08000408,
1340x00020000,0x08020000,0x00020008,0x08020008,
1350x00020400,0x08020400,0x00020408,0x08020408,
1360x00000001,0x08000001,0x00000009,0x08000009,
1370x00000401,0x08000401,0x00000409,0x08000409,
1380x00020001,0x08020001,0x00020009,0x08020009,
1390x00020401,0x08020401,0x00020409,0x08020409,
1400x02000000,0x0A000000,0x02000008,0x0A000008,
1410x02000400,0x0A000400,0x02000408,0x0A000408,
1420x02020000,0x0A020000,0x02020008,0x0A020008,
1430x02020400,0x0A020400,0x02020408,0x0A020408,
1440x02000001,0x0A000001,0x02000009,0x0A000009,
1450x02000401,0x0A000401,0x02000409,0x0A000409,
1460x02020001,0x0A020001,0x02020009,0x0A020009,
1470x02020401,0x0A020401,0x02020409,0x0A020409 },
148/* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
149{ 0x00000000,0x00000100,0x00080000,0x00080100,
1500x01000000,0x01000100,0x01080000,0x01080100,
1510x00000010,0x00000110,0x00080010,0x00080110,
1520x01000010,0x01000110,0x01080010,0x01080110,
1530x00200000,0x00200100,0x00280000,0x00280100,
1540x01200000,0x01200100,0x01280000,0x01280100,
1550x00200010,0x00200110,0x00280010,0x00280110,
1560x01200010,0x01200110,0x01280010,0x01280110,
1570x00000200,0x00000300,0x00080200,0x00080300,
1580x01000200,0x01000300,0x01080200,0x01080300,
1590x00000210,0x00000310,0x00080210,0x00080310,
1600x01000210,0x01000310,0x01080210,0x01080310,
1610x00200200,0x00200300,0x00280200,0x00280300,
1620x01200200,0x01200300,0x01280200,0x01280300,
1630x00200210,0x00200310,0x00280210,0x00280310,
1640x01200210,0x01200310,0x01280210,0x01280310 },
165/* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
166{ 0x00000000,0x04000000,0x00040000,0x04040000,
1670x00000002,0x04000002,0x00040002,0x04040002,
1680x00002000,0x04002000,0x00042000,0x04042000,
1690x00002002,0x04002002,0x00042002,0x04042002,
1700x00000020,0x04000020,0x00040020,0x04040020,
1710x00000022,0x04000022,0x00040022,0x04040022,
1720x00002020,0x04002020,0x00042020,0x04042020,
1730x00002022,0x04002022,0x00042022,0x04042022,
1740x00000800,0x04000800,0x00040800,0x04040800,
1750x00000802,0x04000802,0x00040802,0x04040802,
1760x00002800,0x04002800,0x00042800,0x04042800,
1770x00002802,0x04002802,0x00042802,0x04042802,
1780x00000820,0x04000820,0x00040820,0x04040820,
1790x00000822,0x04000822,0x00040822,0x04040822,
1800x00002820,0x04002820,0x00042820,0x04042820,
1810x00002822,0x04002822,0x00042822,0x04042822 }
182};
183
184/* Tables used for executing des.  This used to be in spr.h. */
185/* Copyright (C) 1993 Eric Young - see README for more details */
186static const word32 des_SPtrans[8][64]={
187/* nibble 0 */
188{ 0x00820200, 0x00020000, 0x80800000, 0x80820200,
1890x00800000, 0x80020200, 0x80020000, 0x80800000,
1900x80020200, 0x00820200, 0x00820000, 0x80000200,
1910x80800200, 0x00800000, 0x00000000, 0x80020000,
1920x00020000, 0x80000000, 0x00800200, 0x00020200,
1930x80820200, 0x00820000, 0x80000200, 0x00800200,
1940x80000000, 0x00000200, 0x00020200, 0x80820000,
1950x00000200, 0x80800200, 0x80820000, 0x00000000,
1960x00000000, 0x80820200, 0x00800200, 0x80020000,
1970x00820200, 0x00020000, 0x80000200, 0x00800200,
1980x80820000, 0x00000200, 0x00020200, 0x80800000,
1990x80020200, 0x80000000, 0x80800000, 0x00820000,
2000x80820200, 0x00020200, 0x00820000, 0x80800200,
2010x00800000, 0x80000200, 0x80020000, 0x00000000,
2020x00020000, 0x00800000, 0x80800200, 0x00820200,
2030x80000000, 0x80820000, 0x00000200, 0x80020200 },
204
205/* nibble 1 */
206{ 0x10042004, 0x00000000, 0x00042000, 0x10040000,
2070x10000004, 0x00002004, 0x10002000, 0x00042000,
2080x00002000, 0x10040004, 0x00000004, 0x10002000,
2090x00040004, 0x10042000, 0x10040000, 0x00000004,
2100x00040000, 0x10002004, 0x10040004, 0x00002000,
2110x00042004, 0x10000000, 0x00000000, 0x00040004,
2120x10002004, 0x00042004, 0x10042000, 0x10000004,
2130x10000000, 0x00040000, 0x00002004, 0x10042004,
2140x00040004, 0x10042000, 0x10002000, 0x00042004,
2150x10042004, 0x00040004, 0x10000004, 0x00000000,
2160x10000000, 0x00002004, 0x00040000, 0x10040004,
2170x00002000, 0x10000000, 0x00042004, 0x10002004,
2180x10042000, 0x00002000, 0x00000000, 0x10000004,
2190x00000004, 0x10042004, 0x00042000, 0x10040000,
2200x10040004, 0x00040000, 0x00002004, 0x10002000,
2210x10002004, 0x00000004, 0x10040000, 0x00042000 },
222
223/* nibble 2 */
224{ 0x41000000, 0x01010040, 0x00000040, 0x41000040,
2250x40010000, 0x01000000, 0x41000040, 0x00010040,
2260x01000040, 0x00010000, 0x01010000, 0x40000000,
2270x41010040, 0x40000040, 0x40000000, 0x41010000,
2280x00000000, 0x40010000, 0x01010040, 0x00000040,
2290x40000040, 0x41010040, 0x00010000, 0x41000000,
2300x41010000, 0x01000040, 0x40010040, 0x01010000,
2310x00010040, 0x00000000, 0x01000000, 0x40010040,
2320x01010040, 0x00000040, 0x40000000, 0x00010000,
2330x40000040, 0x40010000, 0x01010000, 0x41000040,
2340x00000000, 0x01010040, 0x00010040, 0x41010000,
2350x40010000, 0x01000000, 0x41010040, 0x40000000,
2360x40010040, 0x41000000, 0x01000000, 0x41010040,
2370x00010000, 0x01000040, 0x41000040, 0x00010040,
2380x01000040, 0x00000000, 0x41010000, 0x40000040,
2390x41000000, 0x40010040, 0x00000040, 0x01010000 },
240
241/* nibble 3 */
242{ 0x00100402, 0x04000400, 0x00000002, 0x04100402,
2430x00000000, 0x04100000, 0x04000402, 0x00100002,
2440x04100400, 0x04000002, 0x04000000, 0x00000402,
2450x04000002, 0x00100402, 0x00100000, 0x04000000,
2460x04100002, 0x00100400, 0x00000400, 0x00000002,
2470x00100400, 0x04000402, 0x04100000, 0x00000400,
2480x00000402, 0x00000000, 0x00100002, 0x04100400,
2490x04000400, 0x04100002, 0x04100402, 0x00100000,
2500x04100002, 0x00000402, 0x00100000, 0x04000002,
2510x00100400, 0x04000400, 0x00000002, 0x04100000,
2520x04000402, 0x00000000, 0x00000400, 0x00100002,
2530x00000000, 0x04100002, 0x04100400, 0x00000400,
2540x04000000, 0x04100402, 0x00100402, 0x00100000,
2550x04100402, 0x00000002, 0x04000400, 0x00100402,
2560x00100002, 0x00100400, 0x04100000, 0x04000402,
2570x00000402, 0x04000000, 0x04000002, 0x04100400 },
258
259/* nibble 4 */
260{ 0x02000000, 0x00004000, 0x00000100, 0x02004108,
2610x02004008, 0x02000100, 0x00004108, 0x02004000,
2620x00004000, 0x00000008, 0x02000008, 0x00004100,
2630x02000108, 0x02004008, 0x02004100, 0x00000000,
2640x00004100, 0x02000000, 0x00004008, 0x00000108,
2650x02000100, 0x00004108, 0x00000000, 0x02000008,
2660x00000008, 0x02000108, 0x02004108, 0x00004008,
2670x02004000, 0x00000100, 0x00000108, 0x02004100,
2680x02004100, 0x02000108, 0x00004008, 0x02004000,
2690x00004000, 0x00000008, 0x02000008, 0x02000100,
2700x02000000, 0x00004100, 0x02004108, 0x00000000,
2710x00004108, 0x02000000, 0x00000100, 0x00004008,
2720x02000108, 0x00000100, 0x00000000, 0x02004108,
2730x02004008, 0x02004100, 0x00000108, 0x00004000,
2740x00004100, 0x02004008, 0x02000100, 0x00000108,
2750x00000008, 0x00004108, 0x02004000, 0x02000008 },
276
277/* nibble 5 */
278{ 0x20000010, 0x00080010, 0x00000000, 0x20080800,
2790x00080010, 0x00000800, 0x20000810, 0x00080000,
2800x00000810, 0x20080810, 0x00080800, 0x20000000,
2810x20000800, 0x20000010, 0x20080000, 0x00080810,
2820x00080000, 0x20000810, 0x20080010, 0x00000000,
2830x00000800, 0x00000010, 0x20080800, 0x20080010,
2840x20080810, 0x20080000, 0x20000000, 0x00000810,
2850x00000010, 0x00080800, 0x00080810, 0x20000800,
2860x00000810, 0x20000000, 0x20000800, 0x00080810,
2870x20080800, 0x00080010, 0x00000000, 0x20000800,
2880x20000000, 0x00000800, 0x20080010, 0x00080000,
2890x00080010, 0x20080810, 0x00080800, 0x00000010,
2900x20080810, 0x00080800, 0x00080000, 0x20000810,
2910x20000010, 0x20080000, 0x00080810, 0x00000000,
2920x00000800, 0x20000010, 0x20000810, 0x20080800,
2930x20080000, 0x00000810, 0x00000010, 0x20080010 },
294
295/* nibble 6 */
296{ 0x00001000, 0x00000080, 0x00400080, 0x00400001,
2970x00401081, 0x00001001, 0x00001080, 0x00000000,
2980x00400000, 0x00400081, 0x00000081, 0x00401000,
2990x00000001, 0x00401080, 0x00401000, 0x00000081,
3000x00400081, 0x00001000, 0x00001001, 0x00401081,
3010x00000000, 0x00400080, 0x00400001, 0x00001080,
3020x00401001, 0x00001081, 0x00401080, 0x00000001,
3030x00001081, 0x00401001, 0x00000080, 0x00400000,
3040x00001081, 0x00401000, 0x00401001, 0x00000081,
3050x00001000, 0x00000080, 0x00400000, 0x00401001,
3060x00400081, 0x00001081, 0x00001080, 0x00000000,
3070x00000080, 0x00400001, 0x00000001, 0x00400080,
3080x00000000, 0x00400081, 0x00400080, 0x00001080,
3090x00000081, 0x00001000, 0x00401081, 0x00400000,
3100x00401080, 0x00000001, 0x00001001, 0x00401081,
3110x00400001, 0x00401080, 0x00401000, 0x00001001 },
312
313/* nibble 7 */
314{ 0x08200020, 0x08208000, 0x00008020, 0x00000000,
3150x08008000, 0x00200020, 0x08200000, 0x08208020,
3160x00000020, 0x08000000, 0x00208000, 0x00008020,
3170x00208020, 0x08008020, 0x08000020, 0x08200000,
3180x00008000, 0x00208020, 0x00200020, 0x08008000,
3190x08208020, 0x08000020, 0x00000000, 0x00208000,
3200x08000000, 0x00200000, 0x08008020, 0x08200020,
3210x00200000, 0x00008000, 0x08208000, 0x00000020,
3220x00200000, 0x00008000, 0x08000020, 0x08208020,
3230x00008020, 0x08000000, 0x00000000, 0x00208000,
3240x08200020, 0x08008020, 0x08008000, 0x00200020,
3250x08208000, 0x00000020, 0x00200020, 0x08008000,
3260x08208020, 0x00200000, 0x08200000, 0x08000020,
3270x00208000, 0x00008020, 0x08008020, 0x08200000,
3280x00000020, 0x08208000, 0x00208020, 0x00000000,
3290x08000000, 0x08200020, 0x00008000, 0x00208020 }};
330
331/* Some stuff that used to be in des_locl.h.  Heavily modified. */
332        /* IP and FP
333         * The problem is more of a geometric problem that random bit fiddling.
334         0  1  2  3  4  5  6  7      62 54 46 38 30 22 14  6
335         8  9 10 11 12 13 14 15      60 52 44 36 28 20 12  4
336        16 17 18 19 20 21 22 23      58 50 42 34 26 18 10  2
337        24 25 26 27 28 29 30 31  to  56 48 40 32 24 16  8  0
338
339        32 33 34 35 36 37 38 39      63 55 47 39 31 23 15  7
340        40 41 42 43 44 45 46 47      61 53 45 37 29 21 13  5
341        48 49 50 51 52 53 54 55      59 51 43 35 27 19 11  3
342        56 57 58 59 60 61 62 63      57 49 41 33 25 17  9  1
343
344        The output has been subject to swaps of the form
345        0 1 -> 3 1 but the odd and even bits have been put into
346        2 3    2 0
347        different words.  The main trick is to remember that
348        t=((l>>size)^r)&(mask);
349        r^=t;
350        l^=(t<<size);
351        can be used to swap and move bits between words.
352
353        So l =  0  1  2  3  r = 16 17 18 19
354                4  5  6  7      20 21 22 23
355                8  9 10 11      24 25 26 27
356               12 13 14 15      28 29 30 31
357        becomes (for size == 2 and mask == 0x3333)
358           t =   2^16  3^17 -- --   l =  0  1 16 17  r =  2  3 18 19
359                 6^20  7^21 -- --        4  5 20 21       6  7 22 23
360                10^24 11^25 -- --        8  9 24 25      10 11 24 25
361                14^28 15^29 -- --       12 13 28 29      14 15 28 29
362
363        Thanks for hints from Richard Outerbridge - he told me IP&FP
364        could be done in 15 xor, 10 shifts and 5 ands.
365        When I finally started to think of the problem in 2D
366        I first got ~42 operations without xors.  When I remembered
367        how to use xors :-) I got it to its final state.
368        */
369#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
370        (b)^=(t),\
371        (a)^=((t)<<(n)))
372
373#define IP(l,r,t) \
374        PERM_OP(r,l,t, 4,0x0f0f0f0f); \
375        PERM_OP(l,r,t,16,0x0000ffff); \
376        PERM_OP(r,l,t, 2,0x33333333); \
377        PERM_OP(l,r,t, 8,0x00ff00ff); \
378        PERM_OP(r,l,t, 1,0x55555555);
379
380#define FP(l,r,t) \
381        PERM_OP(l,r,t, 1,0x55555555); \
382        PERM_OP(r,l,t, 8,0x00ff00ff); \
383        PERM_OP(l,r,t, 2,0x33333333); \
384        PERM_OP(r,l,t,16,0x0000ffff); \
385        PERM_OP(l,r,t, 4,0x0f0f0f0f);
386
387#define D_ENCRYPT(L,R,S)        \
388        u=(R^s[S  ]); \
389        t=R^s[S+1]; \
390        t=((t>>4)+(t<<28)); \
391        L^=     des_SPtrans[1][(t    )&0x3f]| \
392                des_SPtrans[3][(t>> 8)&0x3f]| \
393                des_SPtrans[5][(t>>16)&0x3f]| \
394                des_SPtrans[7][(t>>24)&0x3f]| \
395                des_SPtrans[0][(u    )&0x3f]| \
396                des_SPtrans[2][(u>> 8)&0x3f]| \
397                des_SPtrans[4][(u>>16)&0x3f]| \
398                des_SPtrans[6][(u>>24)&0x3f];
399
400/* This part is based on code that used to be in ecb_enc.c. */
401/* Copyright (C) 1993 Eric Young - see README for more details */
402
403void des_encrypt(word32 l, word32 r, word32 *output, DESContext *ks,
404                 int encrypt)
405{
406  register word32 t,u;
407  register int i;
408  register word32 *s;
409
410  s = ks->key_schedule;
411
412  IP(l,r,t);
413  /* Things have been modified so that the initial rotate is
414   * done outside the loop.  This required the
415   * des_SPtrans values in sp.h to be rotated 1 bit to the right.
416   * One perl script later and things have a 5% speed up on a sparc2.
417   * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
418   * for pointing this out. */
419  t=(r<<1)|(r>>31);
420  r=(l<<1)|(l>>31);
421  l=t;
422 
423  /* I don't know if it is worth the effort of loop unrolling the
424   * inner loop */
425  if (encrypt)
426    {
427      for (i=0; i<32; i+=4)
428        {
429          D_ENCRYPT(l,r,i+0); /*  1 */
430          D_ENCRYPT(r,l,i+2); /*  2 */
431        }
432    }
433  else
434    {
435      for (i=30; i>0; i-=4)
436        {
437          D_ENCRYPT(l,r,i-0); /* 16 */
438          D_ENCRYPT(r,l,i-2); /* 15 */
439        }
440    }
441  l=(l>>1)|(l<<31);
442  r=(r>>1)|(r<<31);
443 
444  FP(r,l,t);
445  output[0]=l;
446  output[1]=r;
447}
448
449/* Code based on set_key.c. */
450/* Copyright (C) 1993 Eric Young - see README for more details */
451
452#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
453        (a)=(a)^(t)^(t>>(16-(n))))
454
455void des_set_key(unsigned char *key, DESContext *ks)
456{
457  register word32 c, d, t, s, shifts;
458  register int i;
459  register word32 *schedule;
460
461  schedule = ks->key_schedule;
462
463  c = GET_32BIT_LSB_FIRST(key);
464  d = GET_32BIT_LSB_FIRST(key + 4);
465
466  /* I now do it in 47 simple operations :-)
467   * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
468   * for the inspiration. :-) */
469  PERM_OP(d,c,t,4,0x0f0f0f0f);
470  HPERM_OP(c,t,-2,0xcccc0000);
471  HPERM_OP(d,t,-2,0xcccc0000);
472  PERM_OP(d,c,t,1,0x55555555);
473  PERM_OP(c,d,t,8,0x00ff00ff);
474  PERM_OP(d,c,t,1,0x55555555);
475  d = ((d & 0xff) << 16) | (d & 0xff00) |
476    ((d >> 16) & 0xff) | ((c >> 4) & 0xf000000);
477  c&=0x0fffffff;
478 
479  shifts = 0x7efc;
480  for (i=0; i < 16; i++)
481    {
482      if (shifts & 1)
483        { c=((c>>2)|(c<<26)); d=((d>>2)|(d<<26)); }
484      else
485        { c=((c>>1)|(c<<27)); d=((d>>1)|(d<<27)); }
486      shifts >>= 1;
487      c&=0x0fffffff;
488      d&=0x0fffffff;
489
490      /* could be a few less shifts but I am to lazy at this
491       * point in time to investigate */
492
493      s = des_skb[0][ (c    )&0x3f                ] |
494          des_skb[1][((c>> 6)&0x03)|((c>> 7)&0x3c)] |
495          des_skb[2][((c>>13)&0x0f)|((c>>14)&0x30)] |
496          des_skb[3][((c>>20)&0x01)|((c>>21)&0x06)|((c>>22)&0x38)];
497
498      t = des_skb[4][ (d    )&0x3f                ] |
499          des_skb[5][((d>> 7)&0x03)|((d>> 8)&0x3c)] |
500          des_skb[6][ (d>>15)&0x3f                ] |
501          des_skb[7][((d>>21)&0x0f)|((d>>22)&0x30)];
502
503      /* table contained 0213 4657 */
504      *schedule++ = ((t << 16) | (s & 0xffff));
505      s = ((s >> 16) | (t & 0xffff0000));
506      *schedule++ = (s << 4) | (s >> 28);
507    }
508}
509
510void des_cbc_encrypt(DESContext *ks, unsigned char *iv,
511                     unsigned char *dest, const unsigned char *src,
512                     unsigned int len)
513{
514  word32 iv0, iv1, out[2];
515  unsigned int i;
516 
517  assert((len & 7) == 0);
518
519  iv0 = GET_32BIT_LSB_FIRST(iv);
520  iv1 = GET_32BIT_LSB_FIRST(iv + 4);
521 
522  for (i = 0; i < len; i += 8)
523    {
524      iv0 ^= GET_32BIT_LSB_FIRST(src + i);
525      iv1 ^= GET_32BIT_LSB_FIRST(src + i + 4);
526      des_encrypt(iv0, iv1, out, ks, 1);
527      iv0 = out[0];
528      iv1 = out[1];
529      PUT_32BIT_LSB_FIRST(dest + i, iv0);
530      PUT_32BIT_LSB_FIRST(dest + i + 4, iv1);
531    }
532  PUT_32BIT_LSB_FIRST(iv, iv0);
533  PUT_32BIT_LSB_FIRST(iv + 4, iv1);
534}
535
536void des_cbc_decrypt(DESContext *ks, unsigned char *iv,
537                     unsigned char *dest, const unsigned char *src,
538                     unsigned int len)
539{
540  word32 iv0, iv1, d0, d1, out[2];
541  unsigned int i;
542 
543  assert((len & 7) == 0);
544
545  iv0 = GET_32BIT_LSB_FIRST(iv);
546  iv1 = GET_32BIT_LSB_FIRST(iv + 4);
547 
548  for (i = 0; i < len; i += 8)
549    {
550      d0 = GET_32BIT_LSB_FIRST(src + i);
551      d1 = GET_32BIT_LSB_FIRST(src + i + 4);
552      des_encrypt(d0, d1, out, ks, 0);
553      iv0 ^= out[0];
554      iv1 ^= out[1];
555      PUT_32BIT_LSB_FIRST(dest + i, iv0);
556      PUT_32BIT_LSB_FIRST(dest + i + 4, iv1);
557      iv0 = d0;
558      iv1 = d1;
559    }
560  PUT_32BIT_LSB_FIRST(iv, iv0);
561  PUT_32BIT_LSB_FIRST(iv + 4, iv1);
562}
563
564void des_3cbc_encrypt(DESContext *ks1, unsigned char *iv1,
565                      DESContext *ks2, unsigned char *iv2,
566                      DESContext *ks3, unsigned char *iv3,
567                      unsigned char *dest, const unsigned char *src,
568                      unsigned int len)
569{
570  des_cbc_encrypt(ks1, iv1, dest, src, len);
571  des_cbc_decrypt(ks2, iv2, dest, dest, len);
572  des_cbc_encrypt(ks3, iv3, dest, dest, len);
573}
574
575void des_3cbc_decrypt(DESContext *ks1, unsigned char *iv1,
576                      DESContext *ks2, unsigned char *iv2,
577                      DESContext *ks3, unsigned char *iv3,
578                      unsigned char *dest, const unsigned char *src,
579                      unsigned int len)
580{
581  des_cbc_decrypt(ks3, iv3, dest, src, len);
582  des_cbc_encrypt(ks2, iv2, dest, dest, len);
583  des_cbc_decrypt(ks1, iv1, dest, dest, len);
584}
585
586#ifdef DES_TEST
587
588void des_encrypt_buf(DESContext *ks, unsigned char *out,
589                     const unsigned char *in, int encrypt)
590{
591  word32 in0, in1, output[0];
592
593  in0 = GET_32BIT_LSB_FIRST(in);
594  in1 = GET_32BIT_LSB_FIRST(in + 4);
595  des_encrypt(in0, in1, output, ks, encrypt);
596  PUT_32BIT_LSB_FIRST(out, output[0]);
597  PUT_32BIT_LSB_FIRST(out + 4, output[1]);
598}
599
600int main(int ac, char **av)
601{
602  FILE *f;
603  char line[1024], *cp;
604  int i, value;
605  unsigned char key[8], data[8], result[8], output[8];
606  DESContext ks;
607
608  while (fgets(line, sizeof(line), stdin))
609    {
610      for (i = 0; i < 8; i++)
611        {
612          if (sscanf(line + 2 * i, "%02x", &value) != 1)
613            {
614              fprintf(stderr, "1st col, i = %d, line: %s", i, line);
615              exit(1);
616            }
617          key[i] = value;
618        }
619      for (i = 0; i < 8; i++)
620        {
621          if (sscanf(line + 2 * i + 17, "%02x", &value) != 1)
622            {
623              fprintf(stderr, "2nd col, i = %d, line: %s", i, line);
624              exit(1);
625            }
626          data[i] = value;
627        }
628      for (i = 0; i < 8; i++)
629        {
630          if (sscanf(line + 2 * i + 2*17, "%02x", &value) != 1)
631            {
632              fprintf(stderr, "3rd col, i = %d, line: %s", i, line);
633              exit(1);
634            }
635          result[i] = value;
636        }
637      des_set_key(key, &ks);
638      des_encrypt_buf(&ks, output, data, 1);
639      if (memcmp(output, result, 8) != 0)
640        fprintf(stderr, "Encrypt failed: %s", line);
641      des_encrypt_buf(&ks, output, result, 0);
642      if (memcmp(output, data, 8) != 0)
643        fprintf(stderr, "Decrypt failed: %s", line);
644    }
645  exit(0);
646}
647#endif /* DES_TEST */
648
Note: See TracBrowser for help on using the repository browser.