xref: /csrg-svn/lib/libc/gen/crypt.c (revision 48731)
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  *
8*48731Sbostic  * %sccs.include.redist.c%
947038Sbostic  */
1047038Sbostic 
1126545Sdonn #if defined(LIBC_SCCS) && !defined(lint)
12*48731Sbostic static char sccsid[] = "@(#)crypt.c	5.8 (Berkeley) 04/26/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 	}
46047038Sbostic 	des_setkey((char *)keyblock.b);	/* also initializes "a64toi" */
46147038Sbostic 
46247038Sbostic 	encp = &cryptresult[0];
46348485Sbostic 	switch (*setting) {
46448485Sbostic 	case _PASSWORD_EFMT1:
46547038Sbostic 		*encp++ = *setting++;
46647038Sbostic 
46747038Sbostic 		/* get iteration count */
46847038Sbostic 		num_iter = 0;
46947038Sbostic 		for (i = 4; --i >= 0; ) {
47048484Sbostic 			if ((t = (unsigned char)setting[i]) == '\0')
47148484Sbostic 				t = '.';
47248484Sbostic 			encp[i] = t;
47348484Sbostic 			num_iter = (num_iter<<6) | a64toi[t];
47447038Sbostic 		}
47547038Sbostic 		setting += 4;
47647038Sbostic 		encp += 4;
47747038Sbostic 		salt_size = 4;
47847038Sbostic 		key_size = 128;
47948485Sbostic 		break;
48048485Sbostic 	default:
48148485Sbostic 		num_iter = 25;
48248485Sbostic 		salt_size = 2;
48348485Sbostic 		key_size = 8;
48447038Sbostic 	}
48547038Sbostic 
48647038Sbostic 	salt = 0;
48747038Sbostic 	for (i = salt_size; --i >= 0; ) {
48848484Sbostic 		if ((t = (unsigned char)setting[i]) == '\0')
48948484Sbostic 			t = '.';
49048484Sbostic 		encp[i] = t;
49148484Sbostic 		salt = (salt<<6) | a64toi[t];
49247038Sbostic 	}
49347038Sbostic 	encp += salt_size;
49447038Sbostic 	des_cipher((char *)&constdatablock, (char *)&rsltblock, salt, num_iter);
49547038Sbostic 
4961958Swnj 	/*
49747038Sbostic 	 * encrypt the remainder of the password 8 characters at a time.
4981958Swnj 	 */
49947038Sbostic 	while ((key_size -= 8) > 0 && *key) {
50047038Sbostic 		C_block xdatablock;
50147038Sbostic 
50248484Sbostic 		for (i = 0; i < 8; i++) {
50348484Sbostic 			if ((t = 2*(unsigned char)(*key)) != 0)
50447038Sbostic 				key++;
50548484Sbostic 			keyblock.b[i] = t;
50648484Sbostic 			if (t == 0)
50747038Sbostic 				break;	/* pad out with previous key */
50848484Sbostic 		}
50947038Sbostic 		des_setkey((char *)keyblock.b);
51047038Sbostic 		des_cipher((char *)&constdatablock, (char *)&xdatablock, 0L, 1);
51147038Sbostic 		rsltblock.b32.i0 ^= xdatablock.b32.i0;
51247038Sbostic 		rsltblock.b32.i1 ^= xdatablock.b32.i1;
5131958Swnj 	}
51447038Sbostic 
5151958Swnj 	/*
51647038Sbostic 	 * Encode the 64 cipher bits as 11 ascii characters.
5171958Swnj 	 */
51847038Sbostic 	i = ((long)((rsltblock.b[0]<<8) | rsltblock.b[1])<<8) | rsltblock.b[2];
51947038Sbostic 	encp[3] = itoa64[i&0x3f];	i >>= 6;
52047038Sbostic 	encp[2] = itoa64[i&0x3f];	i >>= 6;
52147038Sbostic 	encp[1] = itoa64[i&0x3f];	i >>= 6;
52247038Sbostic 	encp[0] = itoa64[i];		encp += 4;
52347038Sbostic 	i = ((long)((rsltblock.b[3]<<8) | rsltblock.b[4])<<8) | rsltblock.b[5];
52447038Sbostic 	encp[3] = itoa64[i&0x3f];	i >>= 6;
52547038Sbostic 	encp[2] = itoa64[i&0x3f];	i >>= 6;
52647038Sbostic 	encp[1] = itoa64[i&0x3f];	i >>= 6;
52747038Sbostic 	encp[0] = itoa64[i];		encp += 4;
52847038Sbostic 	i = ((long)((rsltblock.b[6])<<8) | rsltblock.b[7])<<2;
52947038Sbostic 	encp[2] = itoa64[i&0x3f];	i >>= 6;
53047038Sbostic 	encp[1] = itoa64[i&0x3f];	i >>= 6;
53147038Sbostic 	encp[0] = itoa64[i];
53247038Sbostic 
53347038Sbostic 	encp[3] = 0;
53448484Sbostic 
53547038Sbostic 	return(cryptresult);
53647038Sbostic }
53747038Sbostic 
53847038Sbostic 
53947038Sbostic /*
54047038Sbostic  * The Key Schedule, filled in by des_setkey() or setkey().
54147038Sbostic  */
54247038Sbostic #define	KS_SIZE	16
54347038Sbostic static C_block	KS[KS_SIZE];
54447038Sbostic 
54547038Sbostic /*
54647038Sbostic  * Set up the key schedule from the key.
54747038Sbostic  */
54847038Sbostic void
54947038Sbostic des_setkey(key)
55047038Sbostic 	register const char *key;
55147038Sbostic {
55247038Sbostic 	register DCL_BLOCK(K, K0, K1);
55347038Sbostic 	register C_block *ptabp;
55447038Sbostic 	register int i;
55547038Sbostic 	static int des_ready = 0;
55647038Sbostic 
55747038Sbostic 	if (!des_ready) {
55847038Sbostic 		init_des();
55947038Sbostic 		des_ready = 1;
5601958Swnj 	}
56117337Sralph 
56247038Sbostic 	PERM6464(K,K0,K1,(unsigned char *)key,(C_block *)PC1ROT);
56347038Sbostic 	key = (char *)&KS[0];
56447038Sbostic 	STORE(K&0xfcfcfcfcL, K0&0xfcfcfcfcL, K1, *(C_block *)key);
56547038Sbostic 	for (i = 1; i < 16; i++) {
56647038Sbostic 		key += sizeof(C_block);
56747038Sbostic 		STORE(K,K0,K1,*(C_block *)key);
56847038Sbostic 		ptabp = (C_block *)PC2ROT[Rotates[i]-1];
56947038Sbostic 		PERM6464(K,K0,K1,(unsigned char *)key,ptabp);
57047038Sbostic 		STORE(K&0xfcfcfcfcL, K0&0xfcfcfcfcL, K1, *(C_block *)key);
57147038Sbostic 	}
5721958Swnj }
5731958Swnj 
5741958Swnj /*
57547038Sbostic  * Encrypt (or decrypt if num_iter < 0) the 8 chars at "in" with abs(num_iter)
57647038Sbostic  * iterations of DES, using the the given 24-bit salt and the pre-computed key
57747038Sbostic  * schedule, and store the resulting 8 chars at "out" (in == out is permitted).
57847038Sbostic  *
57947038Sbostic  * NOTE: the performance of this routine is critically dependent on your
58047038Sbostic  * compiler and machine architecture.
5811958Swnj  */
58247038Sbostic void
58347038Sbostic des_cipher(in, out, salt, num_iter)
58447038Sbostic 	const char *in;
58547038Sbostic 	char *out;
58648484Sbostic 	long salt;
58747038Sbostic 	int num_iter;
58847038Sbostic {
58947038Sbostic 	/* variables that we want in registers, most important first */
59047038Sbostic #if defined(pdp11)
59147038Sbostic 	register int j;
59247038Sbostic #endif
59347038Sbostic 	register long L0, L1, R0, R1, k;
59447038Sbostic 	register C_block *kp;
59547038Sbostic 	register int ks_inc, loop_count;
59647038Sbostic 	C_block B;
5971958Swnj 
59847038Sbostic 	L0 = salt;
59947038Sbostic 	TO_SIX_BIT(salt, L0);	/* convert to 8*(6+2) format */
6001958Swnj 
60147038Sbostic #if defined(vax) || defined(pdp11)
60247038Sbostic 	salt = ~salt;	/* "x &~ y" is faster than "x & y". */
60347038Sbostic #define	SALT (~salt)
60447038Sbostic #else
60547038Sbostic #define	SALT salt
60647038Sbostic #endif
6071958Swnj 
60847038Sbostic #if defined(MUST_ALIGN)
60947038Sbostic 	B.b[0] = in[0]; B.b[1] = in[1]; B.b[2] = in[2]; B.b[3] = in[3];
61047038Sbostic 	B.b[4] = in[4]; B.b[5] = in[5]; B.b[6] = in[6]; B.b[7] = in[7];
61147038Sbostic 	LOAD(L,L0,L1,B);
61247038Sbostic #else
61347038Sbostic 	LOAD(L,L0,L1,*(C_block *)in);
61447038Sbostic #endif
61547038Sbostic 	LOADREG(R,R0,R1,L,L0,L1);
61647038Sbostic 	L0 &= 0x55555555L;
61747038Sbostic 	L1 &= 0x55555555L;
61847038Sbostic 	L0 = (L0 << 1) | L1;	/* L0 is the even-numbered input bits */
61947038Sbostic 	R0 &= 0xaaaaaaaaL;
62047038Sbostic 	R1 = (R1 >> 1) & 0x55555555L;
62147038Sbostic 	L1 = R0 | R1;		/* L1 is the odd-numbered input bits */
62247038Sbostic 	STORE(L,L0,L1,B);
62347038Sbostic 	PERM3264(L,L0,L1,B.b,  (C_block *)IE3264);	/* even bits */
62447038Sbostic 	PERM3264(R,R0,R1,B.b+4,(C_block *)IE3264);	/* odd bits */
6251958Swnj 
62647038Sbostic 	if (num_iter >= 0)
62747038Sbostic 	{		/* encryption */
62847038Sbostic 		kp = &KS[0];
62947038Sbostic 		ks_inc  = sizeof(*kp);
63047038Sbostic 	}
63147038Sbostic 	else
63247038Sbostic 	{		/* decryption */
63347038Sbostic 		num_iter = -num_iter;
63447038Sbostic 		kp = &KS[KS_SIZE-1];
63547038Sbostic 		ks_inc  = -sizeof(*kp);
63647038Sbostic 	}
6371958Swnj 
63847038Sbostic 	while (--num_iter >= 0) {
63947038Sbostic 		loop_count = 8;
64047038Sbostic 		do {
6411958Swnj 
64247038Sbostic #define	BTAB(i)		(((unsigned char *)&B.b[0])[i])
64347038Sbostic #define	SPTAB(t, i)	(*(long *)((unsigned char *)t \
64447038Sbostic 				+ i*(sizeof(long)/4)))
64547038Sbostic #if defined(gould)
64647038Sbostic 			/* use this if BTAB(i) is evaluated just once ... */
64747038Sbostic #define	DOXOR(a,b,i)	a^=SPTAB(SPE[0][i],BTAB(i));b^=SPTAB(SPE[1][i],BTAB(i));
64847038Sbostic #else
64947038Sbostic #if defined(pdp11)
65047038Sbostic 			/* use this if your "long" int indexing is slow */
65147038Sbostic #define	DOXOR(a,b,i)	j=BTAB(i); a^=SPTAB(SPE[0][i],j); b^=SPTAB(SPE[1][i],j);
65247038Sbostic #else
65347038Sbostic 			/* use this if "k" is allocated to a register ... */
65447038Sbostic #define	DOXOR(a,b,i)	k=BTAB(i); a^=SPTAB(SPE[0][i],k); b^=SPTAB(SPE[1][i],k);
65547038Sbostic #endif
65647038Sbostic #endif
6571958Swnj 
65847038Sbostic #define	CRUNCH(L0, L1, R0, R1)	\
65947038Sbostic 			k = (R0 ^ R1) & SALT;	\
66047038Sbostic 			B.b32.i0 = k ^ R0 ^ kp->b32.i0;		\
66147038Sbostic 			B.b32.i1 = k ^ R1 ^ kp->b32.i1;		\
66247038Sbostic 			kp = (C_block *)((char *)kp+ks_inc);	\
66347038Sbostic 							\
66447038Sbostic 			DOXOR(L0, L1, 0);		\
66547038Sbostic 			DOXOR(L0, L1, 1);		\
66647038Sbostic 			DOXOR(L0, L1, 2);		\
66747038Sbostic 			DOXOR(L0, L1, 3);		\
66847038Sbostic 			DOXOR(L0, L1, 4);		\
66947038Sbostic 			DOXOR(L0, L1, 5);		\
67047038Sbostic 			DOXOR(L0, L1, 6);		\
67147038Sbostic 			DOXOR(L0, L1, 7);
6721958Swnj 
67347038Sbostic 			CRUNCH(L0, L1, R0, R1);
67447038Sbostic 			CRUNCH(R0, R1, L0, L1);
67547038Sbostic 		} while (--loop_count != 0);
67647038Sbostic 		kp = (C_block *)((char *)kp-(ks_inc*KS_SIZE));
6771958Swnj 
6781958Swnj 
67947038Sbostic 		/* swap L and R */
68047038Sbostic 		L0 ^= R0;  L1 ^= R1;
68147038Sbostic 		R0 ^= L0;  R1 ^= L1;
68247038Sbostic 		L0 ^= R0;  L1 ^= R1;
68347038Sbostic 	}
6841958Swnj 
68547038Sbostic 	/* store the encrypted (or decrypted) result */
68647038Sbostic 	L0 = ((L0 >> 3) & 0x0f0f0f0fL) | ((L1 << 1) & 0xf0f0f0f0L);
68747038Sbostic 	L1 = ((R0 >> 3) & 0x0f0f0f0fL) | ((R1 << 1) & 0xf0f0f0f0L);
68847038Sbostic 	STORE(L,L0,L1,B);
68947038Sbostic 	PERM6464(L,L0,L1,B.b, (C_block *)CF6464);
69047038Sbostic #if defined(MUST_ALIGN)
69147038Sbostic 	STORE(L,L0,L1,B);
69247038Sbostic 	out[0] = B.b[0]; out[1] = B.b[1]; out[2] = B.b[2]; out[3] = B.b[3];
69347038Sbostic 	out[4] = B.b[4]; out[5] = B.b[5]; out[6] = B.b[6]; out[7] = B.b[7];
69447038Sbostic #else
69547038Sbostic 	STORE(L,L0,L1,*(C_block *)out);
69647038Sbostic #endif
69747038Sbostic }
69847038Sbostic 
69947038Sbostic 
7001958Swnj /*
70147038Sbostic  * Initialize various tables.  This need only be done once.  It could even be
70247038Sbostic  * done at compile time, if the compiler were capable of that sort of thing.
7031958Swnj  */
70447038Sbostic STATIC
70547038Sbostic init_des()
7061958Swnj {
70747038Sbostic 	register int i, j;
70847038Sbostic 	register long k;
70947038Sbostic 	register int tableno;
71047038Sbostic 	static unsigned char perm[64], tmp32[32];	/* "static" for speed */
7111958Swnj 
7121958Swnj 	/*
71347038Sbostic 	 * table that converts chars "./0-9A-Za-z"to integers 0-63.
7141958Swnj 	 */
71547038Sbostic 	for (i = 0; i < 64; i++)
71647038Sbostic 		a64toi[itoa64[i]] = i;
71747038Sbostic 
7181958Swnj 	/*
71947038Sbostic 	 * PC1ROT - bit reverse, then PC1, then Rotate, then PC2.
7201958Swnj 	 */
72147038Sbostic 	for (i = 0; i < 64; i++)
72247038Sbostic 		perm[i] = 0;
72347038Sbostic 	for (i = 0; i < 64; i++) {
72447038Sbostic 		if ((k = PC2[i]) == 0)
72547038Sbostic 			continue;
72647038Sbostic 		k += Rotates[0]-1;
72747038Sbostic 		if ((k%28) < Rotates[0]) k -= 28;
72847038Sbostic 		k = PC1[k];
72947038Sbostic 		if (k > 0) {
73047038Sbostic 			k--;
73147038Sbostic 			k = (k|07) - (k&07);
73247038Sbostic 			k++;
7331958Swnj 		}
73447038Sbostic 		perm[i] = k;
7351958Swnj 	}
73647038Sbostic #ifdef DEBUG
73747038Sbostic 	prtab("pc1tab", perm, 8);
73847038Sbostic #endif
73948484Sbostic 	init_perm(PC1ROT, perm, 8, 8);
74047038Sbostic 
7411958Swnj 	/*
74247038Sbostic 	 * PC2ROT - PC2 inverse, then Rotate (once or twice), then PC2.
7431958Swnj 	 */
74447038Sbostic 	for (j = 0; j < 2; j++) {
74547038Sbostic 		unsigned char pc2inv[64];
74647038Sbostic 		for (i = 0; i < 64; i++)
74747038Sbostic 			perm[i] = pc2inv[i] = 0;
74847038Sbostic 		for (i = 0; i < 64; i++) {
74947038Sbostic 			if ((k = PC2[i]) == 0)
75047038Sbostic 				continue;
75147038Sbostic 			pc2inv[k-1] = i+1;
75247038Sbostic 		}
75347038Sbostic 		for (i = 0; i < 64; i++) {
75447038Sbostic 			if ((k = PC2[i]) == 0)
75547038Sbostic 				continue;
75647038Sbostic 			k += j;
75747038Sbostic 			if ((k%28) <= j) k -= 28;
75847038Sbostic 			perm[i] = pc2inv[k];
75947038Sbostic 		}
76047038Sbostic #ifdef DEBUG
76147038Sbostic 		prtab("pc2tab", perm, 8);
76247038Sbostic #endif
76348484Sbostic 		init_perm(PC2ROT[j], perm, 8, 8);
7641958Swnj 	}
76547038Sbostic 
7661958Swnj 	/*
76747038Sbostic 	 * Bit reverse, then initial permutation, then expansion.
7681958Swnj 	 */
76947038Sbostic 	for (i = 0; i < 8; i++) {
77047038Sbostic 		for (j = 0; j < 8; j++) {
77147038Sbostic 			k = (j < 2)? 0: IP[ExpandTr[i*6+j-2]-1];
77247038Sbostic 			if (k > 32)
77347038Sbostic 				k -= 32;
77447038Sbostic 			else if (k > 0)
77547038Sbostic 				k--;
77647038Sbostic 			if (k > 0) {
77747038Sbostic 				k--;
77847038Sbostic 				k = (k|07) - (k&07);
77947038Sbostic 				k++;
78047038Sbostic 			}
78147038Sbostic 			perm[i*8+j] = k;
78247038Sbostic 		}
78347038Sbostic 	}
78447038Sbostic #ifdef DEBUG
78547038Sbostic 	prtab("ietab", perm, 8);
78647038Sbostic #endif
78748484Sbostic 	init_perm(IE3264, perm, 4, 8);
78847038Sbostic 
78947038Sbostic 	/*
79047038Sbostic 	 * Compression, then final permutation, then bit reverse.
79147038Sbostic 	 */
79247038Sbostic 	for (i = 0; i < 64; i++) {
79347038Sbostic 		k = IP[CIFP[i]-1];
79447038Sbostic 		if (k > 0) {
79547038Sbostic 			k--;
79647038Sbostic 			k = (k|07) - (k&07);
79747038Sbostic 			k++;
79847038Sbostic 		}
79947038Sbostic 		perm[k-1] = i+1;
80047038Sbostic 	}
80147038Sbostic #ifdef DEBUG
80247038Sbostic 	prtab("cftab", perm, 8);
80347038Sbostic #endif
80448484Sbostic 	init_perm(CF6464, perm, 8, 8);
80547038Sbostic 
80647038Sbostic 	/*
80747038Sbostic 	 * SPE table
80847038Sbostic 	 */
80947038Sbostic 	for (i = 0; i < 48; i++)
81047038Sbostic 		perm[i] = P32Tr[ExpandTr[i]-1];
81147038Sbostic 	for (tableno = 0; tableno < 8; tableno++) {
81247038Sbostic 		for (j = 0; j < 64; j++)  {
81347038Sbostic 			k = (((j >> 0) &01) << 5)|
81447038Sbostic 			    (((j >> 1) &01) << 3)|
81547038Sbostic 			    (((j >> 2) &01) << 2)|
81647038Sbostic 			    (((j >> 3) &01) << 1)|
81747038Sbostic 			    (((j >> 4) &01) << 0)|
81847038Sbostic 			    (((j >> 5) &01) << 4);
81947038Sbostic 			k = S[tableno][k];
82047038Sbostic 			k = (((k >> 3)&01) << 0)|
82147038Sbostic 			    (((k >> 2)&01) << 1)|
82247038Sbostic 			    (((k >> 1)&01) << 2)|
82347038Sbostic 			    (((k >> 0)&01) << 3);
82447038Sbostic 			for (i = 0; i < 32; i++)
82547038Sbostic 				tmp32[i] = 0;
82647038Sbostic 			for (i = 0; i < 4; i++)
82747038Sbostic 				tmp32[4 * tableno + i] = (k >> i) & 01;
82847038Sbostic 			k = 0;
82947038Sbostic 			for (i = 24; --i >= 0; )
83047038Sbostic 				k = (k<<1) | tmp32[perm[i]-1];
83147038Sbostic 			TO_SIX_BIT(SPE[0][tableno][j], k);
83247038Sbostic 			k = 0;
83347038Sbostic 			for (i = 24; --i >= 0; )
83447038Sbostic 				k = (k<<1) | tmp32[perm[i+24]-1];
83547038Sbostic 			TO_SIX_BIT(SPE[1][tableno][j], k);
83647038Sbostic 		}
83747038Sbostic 	}
8381958Swnj }
8391958Swnj 
84047038Sbostic /*
84148484Sbostic  * Initialize "perm" to represent transformation "p", which rearranges
84248484Sbostic  * (perhaps with expansion and/or contraction) one packed array of bits
84348484Sbostic  * (of size "chars_in" characters) into another array (of size "chars_out"
84448484Sbostic  * characters).
84548484Sbostic  *
84647038Sbostic  * "perm" must be all-zeroes on entry to this routine.
84747038Sbostic  */
84847038Sbostic STATIC
84948484Sbostic init_perm(perm, p, chars_in, chars_out)
85047038Sbostic 	C_block perm[64/CHUNKBITS][1<<CHUNKBITS];
85147038Sbostic 	unsigned char p[64];
85247038Sbostic 	int chars_in, chars_out;
8531958Swnj {
85447038Sbostic 	register int i, j, k, l;
85517337Sralph 
85647038Sbostic 	for (k = 0; k < chars_out*8; k++) {	/* each output bit position */
85747038Sbostic 		l = p[k] - 1;		/* where this bit comes from */
85847038Sbostic 		if (l < 0)
85947038Sbostic 			continue;	/* output bit is always 0 */
86047038Sbostic 		i = l>>LGCHUNKBITS;	/* which chunk this bit comes from */
86147038Sbostic 		l = 1<<(l&(CHUNKBITS-1));	/* mask for this bit */
86247038Sbostic 		for (j = 0; j < (1<<CHUNKBITS); j++) {	/* each chunk value */
86347038Sbostic 			if ((j & l) != 0)
86447038Sbostic 				perm[i][j].b[k>>3] |= 1<<(k&07);
86547038Sbostic 		}
8661958Swnj 	}
86747038Sbostic }
8681958Swnj 
86947038Sbostic /*
87047038Sbostic  * "setkey" routine (for backwards compatibility)
87147038Sbostic  */
87247038Sbostic void
87347038Sbostic setkey(key)
87447038Sbostic 	register const char *key;
87547038Sbostic {
87647038Sbostic 	register int i, j, k;
87747038Sbostic 	C_block keyblock;
87847038Sbostic 
87947038Sbostic 	for (i = 0; i < 8; i++) {
88047038Sbostic 		k = 0;
88147038Sbostic 		for (j = 0; j < 8; j++) {
88247038Sbostic 			k <<= 1;
88347038Sbostic 			k |= (unsigned char)*key++;
8841958Swnj 		}
88547038Sbostic 		keyblock.b[i] = k;
8861958Swnj 	}
88747038Sbostic 	des_setkey((char *)keyblock.b);
8881958Swnj }
88947038Sbostic 
89047038Sbostic /*
89147038Sbostic  * "encrypt" routine (for backwards compatibility)
89247038Sbostic  */
89347038Sbostic void
89447038Sbostic encrypt(block, flag)
89547038Sbostic 	register char *block;
89647038Sbostic 	int flag;
89747038Sbostic {
89847038Sbostic 	register int i, j, k;
89947038Sbostic 	C_block cblock;
90047038Sbostic 
90147038Sbostic 	for (i = 0; i < 8; i++) {
90247038Sbostic 		k = 0;
90347038Sbostic 		for (j = 0; j < 8; j++) {
90447038Sbostic 			k <<= 1;
90547038Sbostic 			k |= (unsigned char)*block++;
90647038Sbostic 		}
90747038Sbostic 		cblock.b[i] = k;
90847038Sbostic 	}
90947038Sbostic 	des_cipher((char *)&cblock, (char *)&cblock, 0L, (flag? -1: 1));
91047038Sbostic 	for (i = 7; i >= 0; i--) {
91147038Sbostic 		k = cblock.b[i];
91247038Sbostic 		for (j = 7; j >= 0; j--) {
91347038Sbostic 			*--block = k&01;
91447038Sbostic 			k >>= 1;
91547038Sbostic 		}
91647038Sbostic 	}
91747038Sbostic }
91847038Sbostic 
91947038Sbostic #ifdef DEBUG
92047038Sbostic STATIC
92147038Sbostic prtab(s, t, num_rows)
92247038Sbostic 	char *s;
92347038Sbostic 	unsigned char *t;
92447038Sbostic 	int num_rows;
92547038Sbostic {
92647038Sbostic 	register int i, j;
92747038Sbostic 
92848485Sbostic 	(void)printf("%s:\n", s);
92947038Sbostic 	for (i = 0; i < num_rows; i++) {
93047038Sbostic 		for (j = 0; j < 8; j++) {
93148485Sbostic 			 (void)printf("%3d", t[i*8+j]);
93247038Sbostic 		}
93348485Sbostic 		(void)printf("\n");
93447038Sbostic 	}
93548485Sbostic 	(void)printf("\n");
93647038Sbostic }
93747038Sbostic #endif
938