xref: /csrg-svn/lib/libc/gen/crypt.c (revision 49804)
147038Sbostic /*
247038Sbostic  * Copyright (c) 1989 The Regents of the University of California.
347038Sbostic  * All rights reserved.
447038Sbostic  *
547038Sbostic  * This code is derived from software contributed to Berkeley by
647038Sbostic  * Tom Truscott.
747038Sbostic  *
848731Sbostic  * %sccs.include.redist.c%
947038Sbostic  */
1047038Sbostic 
1126545Sdonn #if defined(LIBC_SCCS) && !defined(lint)
12*49804Sbostic static char sccsid[] = "@(#)crypt.c	5.9 (Berkeley) 05/18/91";
1347038Sbostic #endif /* LIBC_SCCS and not lint */
1422083Smckusick 
1546597Sdonn #include <unistd.h>
1648485Sbostic #include <pwd.h>
1746597Sdonn 
181958Swnj /*
1947038Sbostic  * UNIX password, and DES, encryption.
2047038Sbostic  * By Tom Truscott, trt@rti.rti.org,
2147038Sbostic  * from algorithms by Robert W. Baldwin and James Gillogly.
2247038Sbostic  *
2347038Sbostic  * References:
2447038Sbostic  * "Mathematical Cryptology for Computer Scientists and Mathematicians,"
2547038Sbostic  * by Wayne Patterson, 1987, ISBN 0-8476-7438-X.
2647038Sbostic  *
2747038Sbostic  * "Password Security: A Case History," R. Morris and Ken Thompson,
2847038Sbostic  * Communications of the ACM, vol. 22, pp. 594-597, Nov. 1979.
2947038Sbostic  *
3047038Sbostic  * "DES will be Totally Insecure within Ten Years," M.E. Hellman,
3147038Sbostic  * IEEE Spectrum, vol. 16, pp. 32-39, July 1979.
321958Swnj  */
331958Swnj 
3447038Sbostic /* =====  Configuration ==================== */
3547038Sbostic 
361958Swnj /*
3747038Sbostic  * define "MUST_ALIGN" if your compiler cannot load/store
3847038Sbostic  * long integers at arbitrary (e.g. odd) memory locations.
3947038Sbostic  * (Either that or never pass unaligned addresses to des_cipher!)
401958Swnj  */
4147038Sbostic #if !defined(vax)
4247038Sbostic #define	MUST_ALIGN
4347038Sbostic #endif
441958Swnj 
451958Swnj /*
4647038Sbostic  * define "LONG_IS_32_BITS" only if sizeof(long)==4.
4747038Sbostic  * This avoids use of bit fields (your compiler may be sloppy with them).
481958Swnj  */
4947038Sbostic #if !defined(cray)
5047038Sbostic #define	LONG_IS_32_BITS
5147038Sbostic #endif
521958Swnj 
531958Swnj /*
5447038Sbostic  * define "B64" to be the declaration for a 64 bit integer.
5547038Sbostic  * XXX this feature is currently unused, see "endian" comment below.
561958Swnj  */
5747038Sbostic #if defined(cray)
5847038Sbostic #define	B64	long
5947038Sbostic #endif
6047038Sbostic #if defined(convex)
6147038Sbostic #define	B64	long long
6247038Sbostic #endif
631958Swnj 
641958Swnj /*
6547038Sbostic  * define "LARGEDATA" to get faster permutations, by using about 72 kilobytes
6647038Sbostic  * of lookup tables.  This speeds up des_setkey() and des_cipher(), but has
6748484Sbostic  * little effect on crypt().
681958Swnj  */
6947038Sbostic #if defined(notdef)
7047038Sbostic #define	LARGEDATA
7147038Sbostic #endif
721958Swnj 
7348484Sbostic /* compile with "-DSTATIC=int" when profiling */
7448484Sbostic #ifndef STATIC
7547038Sbostic #define	STATIC	static
7648484Sbostic #endif
7748484Sbostic STATIC init_des(), init_perm(), permute();
7847038Sbostic #ifdef DEBUG
7947038Sbostic STATIC prtab();
8047038Sbostic #endif
811958Swnj 
8247038Sbostic /* ==================================== */
8347038Sbostic 
841958Swnj /*
8547038Sbostic  * Cipher-block representation (Bob Baldwin):
8647038Sbostic  *
8747038Sbostic  * DES operates on groups of 64 bits, numbered 1..64 (sigh).  One
8847038Sbostic  * representation is to store one bit per byte in an array of bytes.  Bit N of
8947038Sbostic  * the NBS spec is stored as the LSB of the Nth byte (index N-1) in the array.
9047038Sbostic  * Another representation stores the 64 bits in 8 bytes, with bits 1..8 in the
9147038Sbostic  * first byte, 9..16 in the second, and so on.  The DES spec apparently has
9247038Sbostic  * bit 1 in the MSB of the first byte, but that is particularly noxious so we
9347038Sbostic  * bit-reverse each byte so that bit 1 is the LSB of the first byte, bit 8 is
9447038Sbostic  * the MSB of the first byte.  Specifically, the 64-bit input data and key are
9547038Sbostic  * converted to LSB format, and the output 64-bit block is converted back into
9647038Sbostic  * MSB format.
9747038Sbostic  *
9847038Sbostic  * DES operates internally on groups of 32 bits which are expanded to 48 bits
9947038Sbostic  * by permutation E and shrunk back to 32 bits by the S boxes.  To speed up
10047038Sbostic  * the computation, the expansion is applied only once, the expanded
10147038Sbostic  * representation is maintained during the encryption, and a compression
10247038Sbostic  * permutation is applied only at the end.  To speed up the S-box lookups,
10347038Sbostic  * the 48 bits are maintained as eight 6 bit groups, one per byte, which
10447038Sbostic  * directly feed the eight S-boxes.  Within each byte, the 6 bits are the
10547038Sbostic  * most significant ones.  The low two bits of each byte are zero.  (Thus,
10647038Sbostic  * bit 1 of the 48 bit E expansion is stored as the "4"-valued bit of the
10747038Sbostic  * first byte in the eight byte representation, bit 2 of the 48 bit value is
10848484Sbostic  * the "8"-valued bit, and so on.)  In fact, a combined "SPE"-box lookup is
10947038Sbostic  * used, in which the output is the 64 bit result of an S-box lookup which
11047038Sbostic  * has been permuted by P and expanded by E, and is ready for use in the next
11147038Sbostic  * iteration.  Two 32-bit wide tables, SPE[0] and SPE[1], are used for this
11247038Sbostic  * lookup.  Since each byte in the 48 bit path is a multiple of four, indexed
11347038Sbostic  * lookup of SPE[0] and SPE[1] is simple and fast.  The key schedule and
11447038Sbostic  * "salt" are also converted to this 8*(6+2) format.  The SPE table size is
11547038Sbostic  * 8*64*8 = 4K bytes.
11647038Sbostic  *
11747038Sbostic  * To speed up bit-parallel operations (such as XOR), the 8 byte
11847038Sbostic  * representation is "union"ed with 32 bit values "i0" and "i1", and, on
11947038Sbostic  * machines which support it, a 64 bit value "b64".  This data structure,
12047038Sbostic  * "C_block", has two problems.  First, alignment restrictions must be
12147038Sbostic  * honored.  Second, the byte-order (e.g. little-endian or big-endian) of
12247038Sbostic  * the architecture becomes visible.
12347038Sbostic  *
12447038Sbostic  * The byte-order problem is unfortunate, since on the one hand it is good
12547038Sbostic  * to have a machine-independent C_block representation (bits 1..8 in the
12647038Sbostic  * first byte, etc.), and on the other hand it is good for the LSB of the
12747038Sbostic  * first byte to be the LSB of i0.  We cannot have both these things, so we
12847038Sbostic  * currently use the "little-endian" representation and avoid any multi-byte
12947038Sbostic  * operations that depend on byte order.  This largely precludes use of the
13047038Sbostic  * 64-bit datatype since the relative order of i0 and i1 are unknown.  It
13147038Sbostic  * also inhibits grouping the SPE table to look up 12 bits at a time.  (The
13247038Sbostic  * 12 bits can be stored in a 16-bit field with 3 low-order zeroes and 1
13348484Sbostic  * high-order zero, providing fast indexing into a 64-bit wide SPE.)  On the
13447038Sbostic  * other hand, 64-bit datatypes are currently rare, and a 12-bit SPE lookup
13547038Sbostic  * requires a 128 kilobyte table, so perhaps this is not a big loss.
13647038Sbostic  *
13747038Sbostic  * Permutation representation (Jim Gillogly):
13847038Sbostic  *
13947038Sbostic  * A transformation is defined by its effect on each of the 8 bytes of the
14047038Sbostic  * 64-bit input.  For each byte we give a 64-bit output that has the bits in
14147038Sbostic  * the input distributed appropriately.  The transformation is then the OR
14247038Sbostic  * of the 8 sets of 64-bits.  This uses 8*256*8 = 16K bytes of storage for
14347038Sbostic  * each transformation.  Unless LARGEDATA is defined, however, a more compact
14447038Sbostic  * table is used which looks up 16 4-bit "chunks" rather than 8 8-bit chunks.
14547038Sbostic  * The smaller table uses 16*16*8 = 2K bytes for each transformation.  This
14647038Sbostic  * is slower but tolerable, particularly for password encryption in which
14747038Sbostic  * the SPE transformation is iterated many times.  The small tables total 9K
14847038Sbostic  * bytes, the large tables total 72K bytes.
14947038Sbostic  *
15047038Sbostic  * The transformations used are:
15147038Sbostic  * IE3264: MSB->LSB conversion, initial permutation, and expansion.
15247038Sbostic  *	This is done by collecting the 32 even-numbered bits and applying
15347038Sbostic  *	a 32->64 bit transformation, and then collecting the 32 odd-numbered
15447038Sbostic  *	bits and applying the same transformation.  Since there are only
15547038Sbostic  *	32 input bits, the IE3264 transformation table is half the size of
15647038Sbostic  *	the usual table.
15747038Sbostic  * CF6464: Compression, final permutation, and LSB->MSB conversion.
15847038Sbostic  *	This is done by two trivial 48->32 bit compressions to obtain
15947038Sbostic  *	a 64-bit block (the bit numbering is given in the "CIFP" table)
16047038Sbostic  *	followed by a 64->64 bit "cleanup" transformation.  (It would
16147038Sbostic  *	be possible to group the bits in the 64-bit block so that 2
16247038Sbostic  *	identical 32->32 bit transformations could be used instead,
16347038Sbostic  *	saving a factor of 4 in space and possibly 2 in time, but
16447038Sbostic  *	byte-ordering and other complications rear their ugly head.
16547038Sbostic  *	Similar opportunities/problems arise in the key schedule
16647038Sbostic  *	transforms.)
16747038Sbostic  * PC1ROT: MSB->LSB, PC1 permutation, rotate, and PC2 permutation.
16847038Sbostic  *	This admittedly baroque 64->64 bit transformation is used to
16947038Sbostic  *	produce the first code (in 8*(6+2) format) of the key schedule.
17047038Sbostic  * PC2ROT[0]: Inverse PC2 permutation, rotate, and PC2 permutation.
17147038Sbostic  *	It would be possible to define 15 more transformations, each
17247038Sbostic  *	with a different rotation, to generate the entire key schedule.
17347038Sbostic  *	To save space, however, we instead permute each code into the
17447038Sbostic  *	next by using a transformation that "undoes" the PC2 permutation,
17547038Sbostic  *	rotates the code, and then applies PC2.  Unfortunately, PC2
17647038Sbostic  *	transforms 56 bits into 48 bits, dropping 8 bits, so PC2 is not
17747038Sbostic  *	invertible.  We get around that problem by using a modified PC2
17847038Sbostic  *	which retains the 8 otherwise-lost bits in the unused low-order
17947038Sbostic  *	bits of each byte.  The low-order bits are cleared when the
18047038Sbostic  *	codes are stored into the key schedule.
18147038Sbostic  * PC2ROT[1]: Same as PC2ROT[0], but with two rotations.
18247038Sbostic  *	This is faster than applying PC2ROT[0] twice,
18347038Sbostic  *
18447038Sbostic  * The Bell Labs "salt" (Bob Baldwin):
18547038Sbostic  *
18647038Sbostic  * The salting is a simple permutation applied to the 48-bit result of E.
18747038Sbostic  * Specifically, if bit i (1 <= i <= 24) of the salt is set then bits i and
18847038Sbostic  * i+24 of the result are swapped.  The salt is thus a 24 bit number, with
18947038Sbostic  * 16777216 possible values.  (The original salt was 12 bits and could not
19047038Sbostic  * swap bits 13..24 with 36..48.)
19147038Sbostic  *
19248484Sbostic  * It is possible, but ugly, to warp the SPE table to account for the salt
19348484Sbostic  * permutation.  Fortunately, the conditional bit swapping requires only
19448484Sbostic  * about four machine instructions and can be done on-the-fly with about an
19548484Sbostic  * 8% performance penalty.
1961958Swnj  */
19748484Sbostic 
19847038Sbostic typedef union {
19947038Sbostic 	unsigned char b[8];
20047038Sbostic 	struct {
20147038Sbostic #if defined(LONG_IS_32_BITS)
20247038Sbostic 		/* long is often faster than a 32-bit bit field */
20347038Sbostic 		long	i0;
20447038Sbostic 		long	i1;
20547038Sbostic #else
20647038Sbostic 		long	i0: 32;
20747038Sbostic 		long	i1: 32;
20847038Sbostic #endif
20947038Sbostic 	} b32;
21047038Sbostic #if defined(B64)
21147038Sbostic 	B64	b64;
21247038Sbostic #endif
21347038Sbostic } C_block;
2141958Swnj 
2151958Swnj /*
21647038Sbostic  * Convert twenty-four-bit long in host-order
21747038Sbostic  * to six bits (and 2 low-order zeroes) per char little-endian format.
2181958Swnj  */
21947038Sbostic #define	TO_SIX_BIT(rslt, src) {				\
22047038Sbostic 		C_block cvt;				\
22147038Sbostic 		cvt.b[0] = src; src >>= 6;		\
22247038Sbostic 		cvt.b[1] = src; src >>= 6;		\
22347038Sbostic 		cvt.b[2] = src; src >>= 6;		\
22447038Sbostic 		cvt.b[3] = src;				\
22547038Sbostic 		rslt = (cvt.b32.i0 & 0x3f3f3f3fL) << 2;	\
22647038Sbostic 	}
2271958Swnj 
2281958Swnj /*
22947038Sbostic  * These macros may someday permit efficient use of 64-bit integers.
23017337Sralph  */
23147038Sbostic #define	ZERO(d,d0,d1)			d0 = 0, d1 = 0
23247038Sbostic #define	LOAD(d,d0,d1,bl)		d0 = (bl).b32.i0, d1 = (bl).b32.i1
23347038Sbostic #define	LOADREG(d,d0,d1,s,s0,s1)	d0 = s0, d1 = s1
23447038Sbostic #define	OR(d,d0,d1,bl)			d0 |= (bl).b32.i0, d1 |= (bl).b32.i1
23547038Sbostic #define	STORE(s,s0,s1,bl)		(bl).b32.i0 = s0, (bl).b32.i1 = s1
23647038Sbostic #define	DCL_BLOCK(d,d0,d1)		long d0, d1
23747038Sbostic 
23847038Sbostic #if defined(LARGEDATA)
23947038Sbostic 	/* Waste memory like crazy.  Also, do permutations in line */
24047038Sbostic #define	LGCHUNKBITS	3
24147038Sbostic #define	CHUNKBITS	(1<<LGCHUNKBITS)
24247038Sbostic #define	PERM6464(d,d0,d1,cpp,p)				\
24347038Sbostic 	LOAD(d,d0,d1,(p)[(0<<CHUNKBITS)+(cpp)[0]]);		\
24447038Sbostic 	OR (d,d0,d1,(p)[(1<<CHUNKBITS)+(cpp)[1]]);		\
24547038Sbostic 	OR (d,d0,d1,(p)[(2<<CHUNKBITS)+(cpp)[2]]);		\
24647038Sbostic 	OR (d,d0,d1,(p)[(3<<CHUNKBITS)+(cpp)[3]]);		\
24747038Sbostic 	OR (d,d0,d1,(p)[(4<<CHUNKBITS)+(cpp)[4]]);		\
24847038Sbostic 	OR (d,d0,d1,(p)[(5<<CHUNKBITS)+(cpp)[5]]);		\
24947038Sbostic 	OR (d,d0,d1,(p)[(6<<CHUNKBITS)+(cpp)[6]]);		\
25047038Sbostic 	OR (d,d0,d1,(p)[(7<<CHUNKBITS)+(cpp)[7]]);
25147038Sbostic #define	PERM3264(d,d0,d1,cpp,p)				\
25247038Sbostic 	LOAD(d,d0,d1,(p)[(0<<CHUNKBITS)+(cpp)[0]]);		\
25347038Sbostic 	OR (d,d0,d1,(p)[(1<<CHUNKBITS)+(cpp)[1]]);		\
25447038Sbostic 	OR (d,d0,d1,(p)[(2<<CHUNKBITS)+(cpp)[2]]);		\
25547038Sbostic 	OR (d,d0,d1,(p)[(3<<CHUNKBITS)+(cpp)[3]]);
25647038Sbostic #else
25747038Sbostic 	/* "small data" */
25847038Sbostic #define	LGCHUNKBITS	2
25947038Sbostic #define	CHUNKBITS	(1<<LGCHUNKBITS)
26047038Sbostic #define	PERM6464(d,d0,d1,cpp,p)				\
26147038Sbostic 	{ C_block tblk; permute(cpp,&tblk,p,8); LOAD (d,d0,d1,tblk); }
26247038Sbostic #define	PERM3264(d,d0,d1,cpp,p)				\
26347038Sbostic 	{ C_block tblk; permute(cpp,&tblk,p,4); LOAD (d,d0,d1,tblk); }
26447038Sbostic 
26547038Sbostic STATIC
26647038Sbostic permute(cp, out, p, chars_in)
26747038Sbostic 	unsigned char *cp;
26847038Sbostic 	C_block *out;
26947038Sbostic 	register C_block *p;
27047038Sbostic 	int chars_in;
27147038Sbostic {
27247038Sbostic 	register DCL_BLOCK(D,D0,D1);
27347038Sbostic 	register C_block *tp;
27447038Sbostic 	register int t;
27547038Sbostic 
27647038Sbostic 	ZERO(D,D0,D1);
27747038Sbostic 	do {
27847038Sbostic 		t = *cp++;
27947038Sbostic 		tp = &p[t&0xf]; OR(D,D0,D1,*tp); p += (1<<CHUNKBITS);
28047038Sbostic 		tp = &p[t>>4];  OR(D,D0,D1,*tp); p += (1<<CHUNKBITS);
28147038Sbostic 	} while (--chars_in > 0);
28247038Sbostic 	STORE(D,D0,D1,*out);
28347038Sbostic }
28447038Sbostic #endif /* LARGEDATA */
28547038Sbostic 
28647038Sbostic 
28747038Sbostic /* =====  (mostly) Standard DES Tables ==================== */
28847038Sbostic 
28947038Sbostic static unsigned char IP[] = {		/* initial permutation */
29047038Sbostic 	58, 50, 42, 34, 26, 18, 10,  2,
29147038Sbostic 	60, 52, 44, 36, 28, 20, 12,  4,
29247038Sbostic 	62, 54, 46, 38, 30, 22, 14,  6,
29347038Sbostic 	64, 56, 48, 40, 32, 24, 16,  8,
29447038Sbostic 	57, 49, 41, 33, 25, 17,  9,  1,
29547038Sbostic 	59, 51, 43, 35, 27, 19, 11,  3,
29647038Sbostic 	61, 53, 45, 37, 29, 21, 13,  5,
29747038Sbostic 	63, 55, 47, 39, 31, 23, 15,  7,
29817337Sralph };
29917337Sralph 
30047038Sbostic /* The final permutation is the inverse of IP - no table is necessary */
30147038Sbostic 
30247038Sbostic static unsigned char ExpandTr[] = {	/* expansion operation */
30347038Sbostic 	32,  1,  2,  3,  4,  5,
30447038Sbostic 	 4,  5,  6,  7,  8,  9,
30547038Sbostic 	 8,  9, 10, 11, 12, 13,
30647038Sbostic 	12, 13, 14, 15, 16, 17,
30747038Sbostic 	16, 17, 18, 19, 20, 21,
30847038Sbostic 	20, 21, 22, 23, 24, 25,
30947038Sbostic 	24, 25, 26, 27, 28, 29,
31047038Sbostic 	28, 29, 30, 31, 32,  1,
31147038Sbostic };
31247038Sbostic 
31347038Sbostic static unsigned char PC1[] = {		/* permuted choice table (key)  */
31447038Sbostic 	57, 49, 41, 33, 25, 17,  9,
31547038Sbostic 	 1, 58, 50, 42, 34, 26, 18,
31647038Sbostic 	10,  2, 59, 51, 43, 35, 27,
31747038Sbostic 	19, 11,  3, 60, 52, 44, 36,
31847038Sbostic 
31947038Sbostic 	63, 55, 47, 39, 31, 23, 15,
32047038Sbostic 	 7, 62, 54, 46, 38, 30, 22,
32147038Sbostic 	14,  6, 61, 53, 45, 37, 29,
32247038Sbostic 	21, 13,  5, 28, 20, 12,  4,
32347038Sbostic };
32447038Sbostic 
32547038Sbostic static unsigned char Rotates[] = {	/* number of rotations of PC1 */
32647038Sbostic 	1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1,
32747038Sbostic };
32847038Sbostic 
32947038Sbostic /* note: each "row" of PC2 is left-padded with bits that make it invertible */
33047038Sbostic static unsigned char PC2[] = {		/* permuted choice key (table)  */
33147038Sbostic 	 9, 18,    14, 17, 11, 24,  1,  5,
33247038Sbostic 	22, 25,     3, 28, 15,  6, 21, 10,
33347038Sbostic 	35, 38,    23, 19, 12,  4, 26,  8,
33447038Sbostic 	43, 54,    16,  7, 27, 20, 13,  2,
33547038Sbostic 
33647038Sbostic 	 0,  0,    41, 52, 31, 37, 47, 55,
33747038Sbostic 	 0,  0,    30, 40, 51, 45, 33, 48,
33847038Sbostic 	 0,  0,    44, 49, 39, 56, 34, 53,
33947038Sbostic 	 0,  0,    46, 42, 50, 36, 29, 32,
34047038Sbostic };
34147038Sbostic 
34247038Sbostic static unsigned char S[8][64] = {	/* 48->32 bit substitution tables */
34347038Sbostic 					/* S[1]			*/
34447038Sbostic 	14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7,
34547038Sbostic 	 0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8,
34647038Sbostic 	 4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0,
34747038Sbostic 	15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13,
34847038Sbostic 					/* S[2]			*/
34947038Sbostic 	15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10,
35047038Sbostic 	 3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5,
35147038Sbostic 	 0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15,
35247038Sbostic 	13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9,
35347038Sbostic 					/* S[3]			*/
35447038Sbostic 	10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8,
35547038Sbostic 	13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1,
35647038Sbostic 	13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7,
35747038Sbostic 	 1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12,
35847038Sbostic 					/* S[4]			*/
35947038Sbostic 	 7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15,
36047038Sbostic 	13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9,
36147038Sbostic 	10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4,
36247038Sbostic 	 3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14,
36347038Sbostic 					/* S[5]			*/
36447038Sbostic 	 2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9,
36547038Sbostic 	14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6,
36647038Sbostic 	 4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14,
36747038Sbostic 	11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3,
36847038Sbostic 					/* S[6]			*/
36947038Sbostic 	12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11,
37047038Sbostic 	10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8,
37147038Sbostic 	 9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6,
37247038Sbostic 	 4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13,
37347038Sbostic 					/* S[7]			*/
37447038Sbostic 	 4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1,
37547038Sbostic 	13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6,
37647038Sbostic 	 1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2,
37747038Sbostic 	 6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12,
37847038Sbostic 					/* S[8]			*/
37947038Sbostic 	13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7,
38047038Sbostic 	 1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2,
38147038Sbostic 	 7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8,
38247038Sbostic 	 2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11,
38347038Sbostic };
38447038Sbostic 
38547038Sbostic static unsigned char P32Tr[] = {	/* 32-bit permutation function */
38647038Sbostic 	16,  7, 20, 21,
38747038Sbostic 	29, 12, 28, 17,
38847038Sbostic 	 1, 15, 23, 26,
38947038Sbostic 	 5, 18, 31, 10,
39047038Sbostic 	 2,  8, 24, 14,
39147038Sbostic 	32, 27,  3,  9,
39247038Sbostic 	19, 13, 30,  6,
39347038Sbostic 	22, 11,  4, 25,
39447038Sbostic };
39547038Sbostic 
39647038Sbostic static unsigned char CIFP[] = {		/* compressed/interleaved permutation */
39747038Sbostic 	 1,  2,  3,  4,   17, 18, 19, 20,
39847038Sbostic 	 5,  6,  7,  8,   21, 22, 23, 24,
39947038Sbostic 	 9, 10, 11, 12,   25, 26, 27, 28,
40047038Sbostic 	13, 14, 15, 16,   29, 30, 31, 32,
40147038Sbostic 
40247038Sbostic 	33, 34, 35, 36,   49, 50, 51, 52,
40347038Sbostic 	37, 38, 39, 40,   53, 54, 55, 56,
40447038Sbostic 	41, 42, 43, 44,   57, 58, 59, 60,
40547038Sbostic 	45, 46, 47, 48,   61, 62, 63, 64,
40647038Sbostic };
40747038Sbostic 
40847038Sbostic static unsigned char itoa64[] =		/* 0..63 => ascii-64 */
40947038Sbostic 	"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
41047038Sbostic 
41147038Sbostic 
41247038Sbostic /* =====  Tables that are initialized at run time  ==================== */
41347038Sbostic 
41447038Sbostic 
41547038Sbostic static unsigned char a64toi[128];	/* ascii-64 => 0..63 */
41647038Sbostic 
41747038Sbostic /* Initial key schedule permutation */
41847038Sbostic static C_block	PC1ROT[64/CHUNKBITS][1<<CHUNKBITS];
41947038Sbostic 
42047038Sbostic /* Subsequent key schedule rotation permutations */
42147038Sbostic static C_block	PC2ROT[2][64/CHUNKBITS][1<<CHUNKBITS];
42247038Sbostic 
42347038Sbostic /* Initial permutation/expansion table */
42447038Sbostic static C_block	IE3264[32/CHUNKBITS][1<<CHUNKBITS];
42547038Sbostic 
42647038Sbostic /* Table that combines the S, P, and E operations.  */
42747038Sbostic static long SPE[2][8][64];
42847038Sbostic 
42947038Sbostic /* compressed/interleaved => final permutation table */
43047038Sbostic static C_block	CF6464[64/CHUNKBITS][1<<CHUNKBITS];
43147038Sbostic 
43247038Sbostic 
43347038Sbostic /* ==================================== */
43447038Sbostic 
43547038Sbostic 
43647038Sbostic static C_block	constdatablock;			/* encryption constant */
43747038Sbostic static char	cryptresult[1+4+4+11+1];	/* encrypted result */
43847038Sbostic 
43917337Sralph /*
44048484Sbostic  * Return a pointer to static data consisting of the "setting"
44148484Sbostic  * followed by an encryption produced by the "key" and "setting".
4421958Swnj  */
44347038Sbostic char *
44447038Sbostic crypt(key, setting)
44547038Sbostic 	register const char *key;
44647038Sbostic 	register const char *setting;
4471958Swnj {
44847038Sbostic 	register char *encp;
44947038Sbostic 	register long i;
45048484Sbostic 	register int t;
45147038Sbostic 	long salt;
45247038Sbostic 	int num_iter, salt_size, key_size;
45347038Sbostic 	C_block keyblock, rsltblock;
4541958Swnj 
45548484Sbostic 	for (i = 0; i < 8; i++) {
45648484Sbostic 		if ((t = 2*(unsigned char)(*key)) != 0)
45747038Sbostic 			key++;
45848484Sbostic 		keyblock.b[i] = t;
45948484Sbostic 	}
460*49804Sbostic 	if (des_setkey((char *)keyblock.b))	/* also initializes "a64toi" */
461*49804Sbostic 		return(NULL);
46247038Sbostic 
46347038Sbostic 	encp = &cryptresult[0];
46448485Sbostic 	switch (*setting) {
46548485Sbostic 	case _PASSWORD_EFMT1:
46647038Sbostic 		*encp++ = *setting++;
46747038Sbostic 
46847038Sbostic 		/* get iteration count */
46947038Sbostic 		num_iter = 0;
47047038Sbostic 		for (i = 4; --i >= 0; ) {
47148484Sbostic 			if ((t = (unsigned char)setting[i]) == '\0')
47248484Sbostic 				t = '.';
47348484Sbostic 			encp[i] = t;
47448484Sbostic 			num_iter = (num_iter<<6) | a64toi[t];
47547038Sbostic 		}
47647038Sbostic 		setting += 4;
47747038Sbostic 		encp += 4;
47847038Sbostic 		salt_size = 4;
47947038Sbostic 		key_size = 128;
48048485Sbostic 		break;
48148485Sbostic 	default:
48248485Sbostic 		num_iter = 25;
48348485Sbostic 		salt_size = 2;
48448485Sbostic 		key_size = 8;
48547038Sbostic 	}
48647038Sbostic 
48747038Sbostic 	salt = 0;
48847038Sbostic 	for (i = salt_size; --i >= 0; ) {
48948484Sbostic 		if ((t = (unsigned char)setting[i]) == '\0')
49048484Sbostic 			t = '.';
49148484Sbostic 		encp[i] = t;
49248484Sbostic 		salt = (salt<<6) | a64toi[t];
49347038Sbostic 	}
49447038Sbostic 	encp += salt_size;
495*49804Sbostic 	if (des_cipher((char *)&constdatablock, (char *)&rsltblock,
496*49804Sbostic 	    salt, num_iter))
497*49804Sbostic 		return(NULL);
49847038Sbostic 
4991958Swnj 	/*
50047038Sbostic 	 * encrypt the remainder of the password 8 characters at a time.
5011958Swnj 	 */
50247038Sbostic 	while ((key_size -= 8) > 0 && *key) {
50347038Sbostic 		C_block xdatablock;
50447038Sbostic 
50548484Sbostic 		for (i = 0; i < 8; i++) {
50648484Sbostic 			if ((t = 2*(unsigned char)(*key)) != 0)
50747038Sbostic 				key++;
50848484Sbostic 			keyblock.b[i] = t;
50948484Sbostic 			if (t == 0)
51047038Sbostic 				break;	/* pad out with previous key */
51148484Sbostic 		}
512*49804Sbostic 		if (des_setkey((char *)keyblock.b))
513*49804Sbostic 			return(NULL);
514*49804Sbostic 		if (des_cipher((char *)&constdatablock,
515*49804Sbostic 		    (char *)&xdatablock, 0L, 1))
516*49804Sbostic 			return(NULL);
51747038Sbostic 		rsltblock.b32.i0 ^= xdatablock.b32.i0;
51847038Sbostic 		rsltblock.b32.i1 ^= xdatablock.b32.i1;
5191958Swnj 	}
52047038Sbostic 
5211958Swnj 	/*
52247038Sbostic 	 * Encode the 64 cipher bits as 11 ascii characters.
5231958Swnj 	 */
52447038Sbostic 	i = ((long)((rsltblock.b[0]<<8) | rsltblock.b[1])<<8) | rsltblock.b[2];
52547038Sbostic 	encp[3] = itoa64[i&0x3f];	i >>= 6;
52647038Sbostic 	encp[2] = itoa64[i&0x3f];	i >>= 6;
52747038Sbostic 	encp[1] = itoa64[i&0x3f];	i >>= 6;
52847038Sbostic 	encp[0] = itoa64[i];		encp += 4;
52947038Sbostic 	i = ((long)((rsltblock.b[3]<<8) | rsltblock.b[4])<<8) | rsltblock.b[5];
53047038Sbostic 	encp[3] = itoa64[i&0x3f];	i >>= 6;
53147038Sbostic 	encp[2] = itoa64[i&0x3f];	i >>= 6;
53247038Sbostic 	encp[1] = itoa64[i&0x3f];	i >>= 6;
53347038Sbostic 	encp[0] = itoa64[i];		encp += 4;
53447038Sbostic 	i = ((long)((rsltblock.b[6])<<8) | rsltblock.b[7])<<2;
53547038Sbostic 	encp[2] = itoa64[i&0x3f];	i >>= 6;
53647038Sbostic 	encp[1] = itoa64[i&0x3f];	i >>= 6;
53747038Sbostic 	encp[0] = itoa64[i];
53847038Sbostic 
53947038Sbostic 	encp[3] = 0;
54048484Sbostic 
54147038Sbostic 	return(cryptresult);
54247038Sbostic }
54347038Sbostic 
54447038Sbostic 
54547038Sbostic /*
54647038Sbostic  * The Key Schedule, filled in by des_setkey() or setkey().
54747038Sbostic  */
54847038Sbostic #define	KS_SIZE	16
54947038Sbostic static C_block	KS[KS_SIZE];
55047038Sbostic 
55147038Sbostic /*
55247038Sbostic  * Set up the key schedule from the key.
55347038Sbostic  */
55447038Sbostic des_setkey(key)
55547038Sbostic 	register const char *key;
55647038Sbostic {
55747038Sbostic 	register DCL_BLOCK(K, K0, K1);
55847038Sbostic 	register C_block *ptabp;
55947038Sbostic 	register int i;
56047038Sbostic 	static int des_ready = 0;
56147038Sbostic 
56247038Sbostic 	if (!des_ready) {
56347038Sbostic 		init_des();
56447038Sbostic 		des_ready = 1;
5651958Swnj 	}
56617337Sralph 
56747038Sbostic 	PERM6464(K,K0,K1,(unsigned char *)key,(C_block *)PC1ROT);
56847038Sbostic 	key = (char *)&KS[0];
56947038Sbostic 	STORE(K&0xfcfcfcfcL, K0&0xfcfcfcfcL, K1, *(C_block *)key);
57047038Sbostic 	for (i = 1; i < 16; i++) {
57147038Sbostic 		key += sizeof(C_block);
57247038Sbostic 		STORE(K,K0,K1,*(C_block *)key);
57347038Sbostic 		ptabp = (C_block *)PC2ROT[Rotates[i]-1];
57447038Sbostic 		PERM6464(K,K0,K1,(unsigned char *)key,ptabp);
57547038Sbostic 		STORE(K&0xfcfcfcfcL, K0&0xfcfcfcfcL, K1, *(C_block *)key);
57647038Sbostic 	}
577*49804Sbostic 	return(0);
5781958Swnj }
5791958Swnj 
5801958Swnj /*
58147038Sbostic  * Encrypt (or decrypt if num_iter < 0) the 8 chars at "in" with abs(num_iter)
58247038Sbostic  * iterations of DES, using the the given 24-bit salt and the pre-computed key
58347038Sbostic  * schedule, and store the resulting 8 chars at "out" (in == out is permitted).
58447038Sbostic  *
58547038Sbostic  * NOTE: the performance of this routine is critically dependent on your
58647038Sbostic  * compiler and machine architecture.
5871958Swnj  */
58847038Sbostic des_cipher(in, out, salt, num_iter)
58947038Sbostic 	const char *in;
59047038Sbostic 	char *out;
59148484Sbostic 	long salt;
59247038Sbostic 	int num_iter;
59347038Sbostic {
59447038Sbostic 	/* variables that we want in registers, most important first */
59547038Sbostic #if defined(pdp11)
59647038Sbostic 	register int j;
59747038Sbostic #endif
59847038Sbostic 	register long L0, L1, R0, R1, k;
59947038Sbostic 	register C_block *kp;
60047038Sbostic 	register int ks_inc, loop_count;
60147038Sbostic 	C_block B;
6021958Swnj 
60347038Sbostic 	L0 = salt;
60447038Sbostic 	TO_SIX_BIT(salt, L0);	/* convert to 8*(6+2) format */
6051958Swnj 
60647038Sbostic #if defined(vax) || defined(pdp11)
60747038Sbostic 	salt = ~salt;	/* "x &~ y" is faster than "x & y". */
60847038Sbostic #define	SALT (~salt)
60947038Sbostic #else
61047038Sbostic #define	SALT salt
61147038Sbostic #endif
6121958Swnj 
61347038Sbostic #if defined(MUST_ALIGN)
61447038Sbostic 	B.b[0] = in[0]; B.b[1] = in[1]; B.b[2] = in[2]; B.b[3] = in[3];
61547038Sbostic 	B.b[4] = in[4]; B.b[5] = in[5]; B.b[6] = in[6]; B.b[7] = in[7];
61647038Sbostic 	LOAD(L,L0,L1,B);
61747038Sbostic #else
61847038Sbostic 	LOAD(L,L0,L1,*(C_block *)in);
61947038Sbostic #endif
62047038Sbostic 	LOADREG(R,R0,R1,L,L0,L1);
62147038Sbostic 	L0 &= 0x55555555L;
62247038Sbostic 	L1 &= 0x55555555L;
62347038Sbostic 	L0 = (L0 << 1) | L1;	/* L0 is the even-numbered input bits */
62447038Sbostic 	R0 &= 0xaaaaaaaaL;
62547038Sbostic 	R1 = (R1 >> 1) & 0x55555555L;
62647038Sbostic 	L1 = R0 | R1;		/* L1 is the odd-numbered input bits */
62747038Sbostic 	STORE(L,L0,L1,B);
62847038Sbostic 	PERM3264(L,L0,L1,B.b,  (C_block *)IE3264);	/* even bits */
62947038Sbostic 	PERM3264(R,R0,R1,B.b+4,(C_block *)IE3264);	/* odd bits */
6301958Swnj 
63147038Sbostic 	if (num_iter >= 0)
63247038Sbostic 	{		/* encryption */
63347038Sbostic 		kp = &KS[0];
63447038Sbostic 		ks_inc  = sizeof(*kp);
63547038Sbostic 	}
63647038Sbostic 	else
63747038Sbostic 	{		/* decryption */
63847038Sbostic 		num_iter = -num_iter;
63947038Sbostic 		kp = &KS[KS_SIZE-1];
64047038Sbostic 		ks_inc  = -sizeof(*kp);
64147038Sbostic 	}
6421958Swnj 
64347038Sbostic 	while (--num_iter >= 0) {
64447038Sbostic 		loop_count = 8;
64547038Sbostic 		do {
6461958Swnj 
64747038Sbostic #define	BTAB(i)		(((unsigned char *)&B.b[0])[i])
64847038Sbostic #define	SPTAB(t, i)	(*(long *)((unsigned char *)t \
64947038Sbostic 				+ i*(sizeof(long)/4)))
65047038Sbostic #if defined(gould)
65147038Sbostic 			/* use this if BTAB(i) is evaluated just once ... */
65247038Sbostic #define	DOXOR(a,b,i)	a^=SPTAB(SPE[0][i],BTAB(i));b^=SPTAB(SPE[1][i],BTAB(i));
65347038Sbostic #else
65447038Sbostic #if defined(pdp11)
65547038Sbostic 			/* use this if your "long" int indexing is slow */
65647038Sbostic #define	DOXOR(a,b,i)	j=BTAB(i); a^=SPTAB(SPE[0][i],j); b^=SPTAB(SPE[1][i],j);
65747038Sbostic #else
65847038Sbostic 			/* use this if "k" is allocated to a register ... */
65947038Sbostic #define	DOXOR(a,b,i)	k=BTAB(i); a^=SPTAB(SPE[0][i],k); b^=SPTAB(SPE[1][i],k);
66047038Sbostic #endif
66147038Sbostic #endif
6621958Swnj 
66347038Sbostic #define	CRUNCH(L0, L1, R0, R1)	\
66447038Sbostic 			k = (R0 ^ R1) & SALT;	\
66547038Sbostic 			B.b32.i0 = k ^ R0 ^ kp->b32.i0;		\
66647038Sbostic 			B.b32.i1 = k ^ R1 ^ kp->b32.i1;		\
66747038Sbostic 			kp = (C_block *)((char *)kp+ks_inc);	\
66847038Sbostic 							\
66947038Sbostic 			DOXOR(L0, L1, 0);		\
67047038Sbostic 			DOXOR(L0, L1, 1);		\
67147038Sbostic 			DOXOR(L0, L1, 2);		\
67247038Sbostic 			DOXOR(L0, L1, 3);		\
67347038Sbostic 			DOXOR(L0, L1, 4);		\
67447038Sbostic 			DOXOR(L0, L1, 5);		\
67547038Sbostic 			DOXOR(L0, L1, 6);		\
67647038Sbostic 			DOXOR(L0, L1, 7);
6771958Swnj 
67847038Sbostic 			CRUNCH(L0, L1, R0, R1);
67947038Sbostic 			CRUNCH(R0, R1, L0, L1);
68047038Sbostic 		} while (--loop_count != 0);
68147038Sbostic 		kp = (C_block *)((char *)kp-(ks_inc*KS_SIZE));
6821958Swnj 
6831958Swnj 
68447038Sbostic 		/* swap L and R */
68547038Sbostic 		L0 ^= R0;  L1 ^= R1;
68647038Sbostic 		R0 ^= L0;  R1 ^= L1;
68747038Sbostic 		L0 ^= R0;  L1 ^= R1;
68847038Sbostic 	}
6891958Swnj 
69047038Sbostic 	/* store the encrypted (or decrypted) result */
69147038Sbostic 	L0 = ((L0 >> 3) & 0x0f0f0f0fL) | ((L1 << 1) & 0xf0f0f0f0L);
69247038Sbostic 	L1 = ((R0 >> 3) & 0x0f0f0f0fL) | ((R1 << 1) & 0xf0f0f0f0L);
69347038Sbostic 	STORE(L,L0,L1,B);
69447038Sbostic 	PERM6464(L,L0,L1,B.b, (C_block *)CF6464);
69547038Sbostic #if defined(MUST_ALIGN)
69647038Sbostic 	STORE(L,L0,L1,B);
69747038Sbostic 	out[0] = B.b[0]; out[1] = B.b[1]; out[2] = B.b[2]; out[3] = B.b[3];
69847038Sbostic 	out[4] = B.b[4]; out[5] = B.b[5]; out[6] = B.b[6]; out[7] = B.b[7];
69947038Sbostic #else
70047038Sbostic 	STORE(L,L0,L1,*(C_block *)out);
70147038Sbostic #endif
702*49804Sbostic 	return(0);
70347038Sbostic }
70447038Sbostic 
70547038Sbostic 
7061958Swnj /*
70747038Sbostic  * Initialize various tables.  This need only be done once.  It could even be
70847038Sbostic  * done at compile time, if the compiler were capable of that sort of thing.
7091958Swnj  */
71047038Sbostic STATIC
71147038Sbostic init_des()
7121958Swnj {
71347038Sbostic 	register int i, j;
71447038Sbostic 	register long k;
71547038Sbostic 	register int tableno;
71647038Sbostic 	static unsigned char perm[64], tmp32[32];	/* "static" for speed */
7171958Swnj 
7181958Swnj 	/*
71947038Sbostic 	 * table that converts chars "./0-9A-Za-z"to integers 0-63.
7201958Swnj 	 */
72147038Sbostic 	for (i = 0; i < 64; i++)
72247038Sbostic 		a64toi[itoa64[i]] = i;
72347038Sbostic 
7241958Swnj 	/*
72547038Sbostic 	 * PC1ROT - bit reverse, then PC1, then Rotate, then PC2.
7261958Swnj 	 */
72747038Sbostic 	for (i = 0; i < 64; i++)
72847038Sbostic 		perm[i] = 0;
72947038Sbostic 	for (i = 0; i < 64; i++) {
73047038Sbostic 		if ((k = PC2[i]) == 0)
73147038Sbostic 			continue;
73247038Sbostic 		k += Rotates[0]-1;
73347038Sbostic 		if ((k%28) < Rotates[0]) k -= 28;
73447038Sbostic 		k = PC1[k];
73547038Sbostic 		if (k > 0) {
73647038Sbostic 			k--;
73747038Sbostic 			k = (k|07) - (k&07);
73847038Sbostic 			k++;
7391958Swnj 		}
74047038Sbostic 		perm[i] = k;
7411958Swnj 	}
74247038Sbostic #ifdef DEBUG
74347038Sbostic 	prtab("pc1tab", perm, 8);
74447038Sbostic #endif
74548484Sbostic 	init_perm(PC1ROT, perm, 8, 8);
74647038Sbostic 
7471958Swnj 	/*
74847038Sbostic 	 * PC2ROT - PC2 inverse, then Rotate (once or twice), then PC2.
7491958Swnj 	 */
75047038Sbostic 	for (j = 0; j < 2; j++) {
75147038Sbostic 		unsigned char pc2inv[64];
75247038Sbostic 		for (i = 0; i < 64; i++)
75347038Sbostic 			perm[i] = pc2inv[i] = 0;
75447038Sbostic 		for (i = 0; i < 64; i++) {
75547038Sbostic 			if ((k = PC2[i]) == 0)
75647038Sbostic 				continue;
75747038Sbostic 			pc2inv[k-1] = i+1;
75847038Sbostic 		}
75947038Sbostic 		for (i = 0; i < 64; i++) {
76047038Sbostic 			if ((k = PC2[i]) == 0)
76147038Sbostic 				continue;
76247038Sbostic 			k += j;
76347038Sbostic 			if ((k%28) <= j) k -= 28;
76447038Sbostic 			perm[i] = pc2inv[k];
76547038Sbostic 		}
76647038Sbostic #ifdef DEBUG
76747038Sbostic 		prtab("pc2tab", perm, 8);
76847038Sbostic #endif
76948484Sbostic 		init_perm(PC2ROT[j], perm, 8, 8);
7701958Swnj 	}
77147038Sbostic 
7721958Swnj 	/*
77347038Sbostic 	 * Bit reverse, then initial permutation, then expansion.
7741958Swnj 	 */
77547038Sbostic 	for (i = 0; i < 8; i++) {
77647038Sbostic 		for (j = 0; j < 8; j++) {
77747038Sbostic 			k = (j < 2)? 0: IP[ExpandTr[i*6+j-2]-1];
77847038Sbostic 			if (k > 32)
77947038Sbostic 				k -= 32;
78047038Sbostic 			else if (k > 0)
78147038Sbostic 				k--;
78247038Sbostic 			if (k > 0) {
78347038Sbostic 				k--;
78447038Sbostic 				k = (k|07) - (k&07);
78547038Sbostic 				k++;
78647038Sbostic 			}
78747038Sbostic 			perm[i*8+j] = k;
78847038Sbostic 		}
78947038Sbostic 	}
79047038Sbostic #ifdef DEBUG
79147038Sbostic 	prtab("ietab", perm, 8);
79247038Sbostic #endif
79348484Sbostic 	init_perm(IE3264, perm, 4, 8);
79447038Sbostic 
79547038Sbostic 	/*
79647038Sbostic 	 * Compression, then final permutation, then bit reverse.
79747038Sbostic 	 */
79847038Sbostic 	for (i = 0; i < 64; i++) {
79947038Sbostic 		k = IP[CIFP[i]-1];
80047038Sbostic 		if (k > 0) {
80147038Sbostic 			k--;
80247038Sbostic 			k = (k|07) - (k&07);
80347038Sbostic 			k++;
80447038Sbostic 		}
80547038Sbostic 		perm[k-1] = i+1;
80647038Sbostic 	}
80747038Sbostic #ifdef DEBUG
80847038Sbostic 	prtab("cftab", perm, 8);
80947038Sbostic #endif
81048484Sbostic 	init_perm(CF6464, perm, 8, 8);
81147038Sbostic 
81247038Sbostic 	/*
81347038Sbostic 	 * SPE table
81447038Sbostic 	 */
81547038Sbostic 	for (i = 0; i < 48; i++)
81647038Sbostic 		perm[i] = P32Tr[ExpandTr[i]-1];
81747038Sbostic 	for (tableno = 0; tableno < 8; tableno++) {
81847038Sbostic 		for (j = 0; j < 64; j++)  {
81947038Sbostic 			k = (((j >> 0) &01) << 5)|
82047038Sbostic 			    (((j >> 1) &01) << 3)|
82147038Sbostic 			    (((j >> 2) &01) << 2)|
82247038Sbostic 			    (((j >> 3) &01) << 1)|
82347038Sbostic 			    (((j >> 4) &01) << 0)|
82447038Sbostic 			    (((j >> 5) &01) << 4);
82547038Sbostic 			k = S[tableno][k];
82647038Sbostic 			k = (((k >> 3)&01) << 0)|
82747038Sbostic 			    (((k >> 2)&01) << 1)|
82847038Sbostic 			    (((k >> 1)&01) << 2)|
82947038Sbostic 			    (((k >> 0)&01) << 3);
83047038Sbostic 			for (i = 0; i < 32; i++)
83147038Sbostic 				tmp32[i] = 0;
83247038Sbostic 			for (i = 0; i < 4; i++)
83347038Sbostic 				tmp32[4 * tableno + i] = (k >> i) & 01;
83447038Sbostic 			k = 0;
83547038Sbostic 			for (i = 24; --i >= 0; )
83647038Sbostic 				k = (k<<1) | tmp32[perm[i]-1];
83747038Sbostic 			TO_SIX_BIT(SPE[0][tableno][j], k);
83847038Sbostic 			k = 0;
83947038Sbostic 			for (i = 24; --i >= 0; )
84047038Sbostic 				k = (k<<1) | tmp32[perm[i+24]-1];
84147038Sbostic 			TO_SIX_BIT(SPE[1][tableno][j], k);
84247038Sbostic 		}
84347038Sbostic 	}
8441958Swnj }
8451958Swnj 
84647038Sbostic /*
84748484Sbostic  * Initialize "perm" to represent transformation "p", which rearranges
84848484Sbostic  * (perhaps with expansion and/or contraction) one packed array of bits
84948484Sbostic  * (of size "chars_in" characters) into another array (of size "chars_out"
85048484Sbostic  * characters).
85148484Sbostic  *
85247038Sbostic  * "perm" must be all-zeroes on entry to this routine.
85347038Sbostic  */
85447038Sbostic STATIC
85548484Sbostic init_perm(perm, p, chars_in, chars_out)
85647038Sbostic 	C_block perm[64/CHUNKBITS][1<<CHUNKBITS];
85747038Sbostic 	unsigned char p[64];
85847038Sbostic 	int chars_in, chars_out;
8591958Swnj {
86047038Sbostic 	register int i, j, k, l;
86117337Sralph 
86247038Sbostic 	for (k = 0; k < chars_out*8; k++) {	/* each output bit position */
86347038Sbostic 		l = p[k] - 1;		/* where this bit comes from */
86447038Sbostic 		if (l < 0)
86547038Sbostic 			continue;	/* output bit is always 0 */
86647038Sbostic 		i = l>>LGCHUNKBITS;	/* which chunk this bit comes from */
86747038Sbostic 		l = 1<<(l&(CHUNKBITS-1));	/* mask for this bit */
86847038Sbostic 		for (j = 0; j < (1<<CHUNKBITS); j++) {	/* each chunk value */
86947038Sbostic 			if ((j & l) != 0)
87047038Sbostic 				perm[i][j].b[k>>3] |= 1<<(k&07);
87147038Sbostic 		}
8721958Swnj 	}
87347038Sbostic }
8741958Swnj 
87547038Sbostic /*
87647038Sbostic  * "setkey" routine (for backwards compatibility)
87747038Sbostic  */
87847038Sbostic setkey(key)
87947038Sbostic 	register const char *key;
88047038Sbostic {
88147038Sbostic 	register int i, j, k;
88247038Sbostic 	C_block keyblock;
88347038Sbostic 
88447038Sbostic 	for (i = 0; i < 8; i++) {
88547038Sbostic 		k = 0;
88647038Sbostic 		for (j = 0; j < 8; j++) {
88747038Sbostic 			k <<= 1;
88847038Sbostic 			k |= (unsigned char)*key++;
8891958Swnj 		}
89047038Sbostic 		keyblock.b[i] = k;
8911958Swnj 	}
892*49804Sbostic 	return(des_setkey((char *)keyblock.b));
8931958Swnj }
89447038Sbostic 
89547038Sbostic /*
89647038Sbostic  * "encrypt" routine (for backwards compatibility)
89747038Sbostic  */
89847038Sbostic encrypt(block, flag)
89947038Sbostic 	register char *block;
90047038Sbostic 	int flag;
90147038Sbostic {
90247038Sbostic 	register int i, j, k;
90347038Sbostic 	C_block cblock;
90447038Sbostic 
90547038Sbostic 	for (i = 0; i < 8; i++) {
90647038Sbostic 		k = 0;
90747038Sbostic 		for (j = 0; j < 8; j++) {
90847038Sbostic 			k <<= 1;
90947038Sbostic 			k |= (unsigned char)*block++;
91047038Sbostic 		}
91147038Sbostic 		cblock.b[i] = k;
91247038Sbostic 	}
913*49804Sbostic 	if (des_cipher((char *)&cblock, (char *)&cblock, 0L, (flag ? -1: 1)))
914*49804Sbostic 		return(1);
91547038Sbostic 	for (i = 7; i >= 0; i--) {
91647038Sbostic 		k = cblock.b[i];
91747038Sbostic 		for (j = 7; j >= 0; j--) {
91847038Sbostic 			*--block = k&01;
91947038Sbostic 			k >>= 1;
92047038Sbostic 		}
92147038Sbostic 	}
922*49804Sbostic 	return(0);
92347038Sbostic }
92447038Sbostic 
92547038Sbostic #ifdef DEBUG
92647038Sbostic STATIC
92747038Sbostic prtab(s, t, num_rows)
92847038Sbostic 	char *s;
92947038Sbostic 	unsigned char *t;
93047038Sbostic 	int num_rows;
93147038Sbostic {
93247038Sbostic 	register int i, j;
93347038Sbostic 
93448485Sbostic 	(void)printf("%s:\n", s);
93547038Sbostic 	for (i = 0; i < num_rows; i++) {
93647038Sbostic 		for (j = 0; j < 8; j++) {
93748485Sbostic 			 (void)printf("%3d", t[i*8+j]);
93847038Sbostic 		}
93948485Sbostic 		(void)printf("\n");
94047038Sbostic 	}
94148485Sbostic 	(void)printf("\n");
94247038Sbostic }
94347038Sbostic #endif
944