xref: /csrg-svn/lib/libc/gen/crypt.c (revision 64292)
147038Sbostic /*
261111Sbostic  * Copyright (c) 1989, 1993
361111Sbostic  *	The Regents of the University of California.  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*64292Smckusick static char sccsid[] = "@(#)crypt.c	8.1.1.1 (Berkeley) 08/18/93";
1347038Sbostic #endif /* LIBC_SCCS and not lint */
1422083Smckusick 
1546597Sdonn #include <unistd.h>
1649831Sbostic #include <limits.h>
1748485Sbostic #include <pwd.h>
1846597Sdonn 
191958Swnj /*
2047038Sbostic  * UNIX password, and DES, encryption.
2147038Sbostic  * By Tom Truscott, trt@rti.rti.org,
2247038Sbostic  * from algorithms by Robert W. Baldwin and James Gillogly.
2347038Sbostic  *
2447038Sbostic  * References:
2547038Sbostic  * "Mathematical Cryptology for Computer Scientists and Mathematicians,"
2647038Sbostic  * by Wayne Patterson, 1987, ISBN 0-8476-7438-X.
2747038Sbostic  *
2847038Sbostic  * "Password Security: A Case History," R. Morris and Ken Thompson,
2947038Sbostic  * Communications of the ACM, vol. 22, pp. 594-597, Nov. 1979.
3047038Sbostic  *
3147038Sbostic  * "DES will be Totally Insecure within Ten Years," M.E. Hellman,
3247038Sbostic  * IEEE Spectrum, vol. 16, pp. 32-39, July 1979.
331958Swnj  */
341958Swnj 
3547038Sbostic /* =====  Configuration ==================== */
3647038Sbostic 
371958Swnj /*
3847038Sbostic  * define "MUST_ALIGN" if your compiler cannot load/store
3947038Sbostic  * long integers at arbitrary (e.g. odd) memory locations.
4047038Sbostic  * (Either that or never pass unaligned addresses to des_cipher!)
411958Swnj  */
4247038Sbostic #if !defined(vax)
4347038Sbostic #define	MUST_ALIGN
4447038Sbostic #endif
451958Swnj 
4649831Sbostic #ifdef CHAR_BITS
4749831Sbostic #if CHAR_BITS != 8
4849831Sbostic 	#error C_block structure assumes 8 bit characters
4949831Sbostic #endif
5049831Sbostic #endif
5149831Sbostic 
521958Swnj /*
5347038Sbostic  * define "LONG_IS_32_BITS" only if sizeof(long)==4.
5447038Sbostic  * This avoids use of bit fields (your compiler may be sloppy with them).
551958Swnj  */
5647038Sbostic #if !defined(cray)
5747038Sbostic #define	LONG_IS_32_BITS
5847038Sbostic #endif
591958Swnj 
601958Swnj /*
6147038Sbostic  * define "B64" to be the declaration for a 64 bit integer.
6247038Sbostic  * XXX this feature is currently unused, see "endian" comment below.
631958Swnj  */
6447038Sbostic #if defined(cray)
6547038Sbostic #define	B64	long
6647038Sbostic #endif
6747038Sbostic #if defined(convex)
6847038Sbostic #define	B64	long long
6947038Sbostic #endif
701958Swnj 
711958Swnj /*
7247038Sbostic  * define "LARGEDATA" to get faster permutations, by using about 72 kilobytes
7347038Sbostic  * of lookup tables.  This speeds up des_setkey() and des_cipher(), but has
7448484Sbostic  * little effect on crypt().
751958Swnj  */
7647038Sbostic #if defined(notdef)
7747038Sbostic #define	LARGEDATA
7847038Sbostic #endif
791958Swnj 
8048484Sbostic /* compile with "-DSTATIC=int" when profiling */
8148484Sbostic #ifndef STATIC
8247038Sbostic #define	STATIC	static
8348484Sbostic #endif
8448484Sbostic STATIC init_des(), init_perm(), permute();
8547038Sbostic #ifdef DEBUG
8647038Sbostic STATIC prtab();
8747038Sbostic #endif
881958Swnj 
8947038Sbostic /* ==================================== */
9047038Sbostic 
911958Swnj /*
9247038Sbostic  * Cipher-block representation (Bob Baldwin):
9347038Sbostic  *
9447038Sbostic  * DES operates on groups of 64 bits, numbered 1..64 (sigh).  One
9547038Sbostic  * representation is to store one bit per byte in an array of bytes.  Bit N of
9647038Sbostic  * the NBS spec is stored as the LSB of the Nth byte (index N-1) in the array.
9747038Sbostic  * Another representation stores the 64 bits in 8 bytes, with bits 1..8 in the
9847038Sbostic  * first byte, 9..16 in the second, and so on.  The DES spec apparently has
9947038Sbostic  * bit 1 in the MSB of the first byte, but that is particularly noxious so we
10047038Sbostic  * bit-reverse each byte so that bit 1 is the LSB of the first byte, bit 8 is
10147038Sbostic  * the MSB of the first byte.  Specifically, the 64-bit input data and key are
10247038Sbostic  * converted to LSB format, and the output 64-bit block is converted back into
10347038Sbostic  * MSB format.
10447038Sbostic  *
10547038Sbostic  * DES operates internally on groups of 32 bits which are expanded to 48 bits
10647038Sbostic  * by permutation E and shrunk back to 32 bits by the S boxes.  To speed up
10747038Sbostic  * the computation, the expansion is applied only once, the expanded
10847038Sbostic  * representation is maintained during the encryption, and a compression
10947038Sbostic  * permutation is applied only at the end.  To speed up the S-box lookups,
11047038Sbostic  * the 48 bits are maintained as eight 6 bit groups, one per byte, which
11147038Sbostic  * directly feed the eight S-boxes.  Within each byte, the 6 bits are the
11247038Sbostic  * most significant ones.  The low two bits of each byte are zero.  (Thus,
11347038Sbostic  * bit 1 of the 48 bit E expansion is stored as the "4"-valued bit of the
11447038Sbostic  * first byte in the eight byte representation, bit 2 of the 48 bit value is
11548484Sbostic  * the "8"-valued bit, and so on.)  In fact, a combined "SPE"-box lookup is
11647038Sbostic  * used, in which the output is the 64 bit result of an S-box lookup which
11747038Sbostic  * has been permuted by P and expanded by E, and is ready for use in the next
11847038Sbostic  * iteration.  Two 32-bit wide tables, SPE[0] and SPE[1], are used for this
11947038Sbostic  * lookup.  Since each byte in the 48 bit path is a multiple of four, indexed
12047038Sbostic  * lookup of SPE[0] and SPE[1] is simple and fast.  The key schedule and
12147038Sbostic  * "salt" are also converted to this 8*(6+2) format.  The SPE table size is
12247038Sbostic  * 8*64*8 = 4K bytes.
12347038Sbostic  *
12447038Sbostic  * To speed up bit-parallel operations (such as XOR), the 8 byte
12547038Sbostic  * representation is "union"ed with 32 bit values "i0" and "i1", and, on
12647038Sbostic  * machines which support it, a 64 bit value "b64".  This data structure,
12747038Sbostic  * "C_block", has two problems.  First, alignment restrictions must be
12847038Sbostic  * honored.  Second, the byte-order (e.g. little-endian or big-endian) of
12947038Sbostic  * the architecture becomes visible.
13047038Sbostic  *
13147038Sbostic  * The byte-order problem is unfortunate, since on the one hand it is good
13247038Sbostic  * to have a machine-independent C_block representation (bits 1..8 in the
13347038Sbostic  * first byte, etc.), and on the other hand it is good for the LSB of the
13447038Sbostic  * first byte to be the LSB of i0.  We cannot have both these things, so we
13547038Sbostic  * currently use the "little-endian" representation and avoid any multi-byte
13647038Sbostic  * operations that depend on byte order.  This largely precludes use of the
13747038Sbostic  * 64-bit datatype since the relative order of i0 and i1 are unknown.  It
13847038Sbostic  * also inhibits grouping the SPE table to look up 12 bits at a time.  (The
13947038Sbostic  * 12 bits can be stored in a 16-bit field with 3 low-order zeroes and 1
14048484Sbostic  * high-order zero, providing fast indexing into a 64-bit wide SPE.)  On the
14147038Sbostic  * other hand, 64-bit datatypes are currently rare, and a 12-bit SPE lookup
14247038Sbostic  * requires a 128 kilobyte table, so perhaps this is not a big loss.
14347038Sbostic  *
14447038Sbostic  * Permutation representation (Jim Gillogly):
14547038Sbostic  *
14647038Sbostic  * A transformation is defined by its effect on each of the 8 bytes of the
14747038Sbostic  * 64-bit input.  For each byte we give a 64-bit output that has the bits in
14847038Sbostic  * the input distributed appropriately.  The transformation is then the OR
14947038Sbostic  * of the 8 sets of 64-bits.  This uses 8*256*8 = 16K bytes of storage for
15047038Sbostic  * each transformation.  Unless LARGEDATA is defined, however, a more compact
15147038Sbostic  * table is used which looks up 16 4-bit "chunks" rather than 8 8-bit chunks.
15247038Sbostic  * The smaller table uses 16*16*8 = 2K bytes for each transformation.  This
15347038Sbostic  * is slower but tolerable, particularly for password encryption in which
15447038Sbostic  * the SPE transformation is iterated many times.  The small tables total 9K
15547038Sbostic  * bytes, the large tables total 72K bytes.
15647038Sbostic  *
15747038Sbostic  * The transformations used are:
15847038Sbostic  * IE3264: MSB->LSB conversion, initial permutation, and expansion.
15947038Sbostic  *	This is done by collecting the 32 even-numbered bits and applying
16047038Sbostic  *	a 32->64 bit transformation, and then collecting the 32 odd-numbered
16147038Sbostic  *	bits and applying the same transformation.  Since there are only
16247038Sbostic  *	32 input bits, the IE3264 transformation table is half the size of
16347038Sbostic  *	the usual table.
16447038Sbostic  * CF6464: Compression, final permutation, and LSB->MSB conversion.
16547038Sbostic  *	This is done by two trivial 48->32 bit compressions to obtain
16647038Sbostic  *	a 64-bit block (the bit numbering is given in the "CIFP" table)
16747038Sbostic  *	followed by a 64->64 bit "cleanup" transformation.  (It would
16847038Sbostic  *	be possible to group the bits in the 64-bit block so that 2
16947038Sbostic  *	identical 32->32 bit transformations could be used instead,
17047038Sbostic  *	saving a factor of 4 in space and possibly 2 in time, but
17147038Sbostic  *	byte-ordering and other complications rear their ugly head.
17247038Sbostic  *	Similar opportunities/problems arise in the key schedule
17347038Sbostic  *	transforms.)
17447038Sbostic  * PC1ROT: MSB->LSB, PC1 permutation, rotate, and PC2 permutation.
17547038Sbostic  *	This admittedly baroque 64->64 bit transformation is used to
17647038Sbostic  *	produce the first code (in 8*(6+2) format) of the key schedule.
17747038Sbostic  * PC2ROT[0]: Inverse PC2 permutation, rotate, and PC2 permutation.
17847038Sbostic  *	It would be possible to define 15 more transformations, each
17947038Sbostic  *	with a different rotation, to generate the entire key schedule.
18047038Sbostic  *	To save space, however, we instead permute each code into the
18147038Sbostic  *	next by using a transformation that "undoes" the PC2 permutation,
18247038Sbostic  *	rotates the code, and then applies PC2.  Unfortunately, PC2
18347038Sbostic  *	transforms 56 bits into 48 bits, dropping 8 bits, so PC2 is not
18447038Sbostic  *	invertible.  We get around that problem by using a modified PC2
18547038Sbostic  *	which retains the 8 otherwise-lost bits in the unused low-order
18647038Sbostic  *	bits of each byte.  The low-order bits are cleared when the
18747038Sbostic  *	codes are stored into the key schedule.
18847038Sbostic  * PC2ROT[1]: Same as PC2ROT[0], but with two rotations.
18947038Sbostic  *	This is faster than applying PC2ROT[0] twice,
19047038Sbostic  *
19147038Sbostic  * The Bell Labs "salt" (Bob Baldwin):
19247038Sbostic  *
19347038Sbostic  * The salting is a simple permutation applied to the 48-bit result of E.
19447038Sbostic  * Specifically, if bit i (1 <= i <= 24) of the salt is set then bits i and
19547038Sbostic  * i+24 of the result are swapped.  The salt is thus a 24 bit number, with
19647038Sbostic  * 16777216 possible values.  (The original salt was 12 bits and could not
19747038Sbostic  * swap bits 13..24 with 36..48.)
19847038Sbostic  *
19948484Sbostic  * It is possible, but ugly, to warp the SPE table to account for the salt
20048484Sbostic  * permutation.  Fortunately, the conditional bit swapping requires only
20148484Sbostic  * about four machine instructions and can be done on-the-fly with about an
20248484Sbostic  * 8% performance penalty.
2031958Swnj  */
20448484Sbostic 
20547038Sbostic typedef union {
20647038Sbostic 	unsigned char b[8];
20747038Sbostic 	struct {
20847038Sbostic #if defined(LONG_IS_32_BITS)
20947038Sbostic 		/* long is often faster than a 32-bit bit field */
21047038Sbostic 		long	i0;
21147038Sbostic 		long	i1;
21247038Sbostic #else
21347038Sbostic 		long	i0: 32;
21447038Sbostic 		long	i1: 32;
21547038Sbostic #endif
21647038Sbostic 	} b32;
21747038Sbostic #if defined(B64)
21847038Sbostic 	B64	b64;
21947038Sbostic #endif
22047038Sbostic } C_block;
2211958Swnj 
2221958Swnj /*
22347038Sbostic  * Convert twenty-four-bit long in host-order
22447038Sbostic  * to six bits (and 2 low-order zeroes) per char little-endian format.
2251958Swnj  */
22647038Sbostic #define	TO_SIX_BIT(rslt, src) {				\
22747038Sbostic 		C_block cvt;				\
22847038Sbostic 		cvt.b[0] = src; src >>= 6;		\
22947038Sbostic 		cvt.b[1] = src; src >>= 6;		\
23047038Sbostic 		cvt.b[2] = src; src >>= 6;		\
23147038Sbostic 		cvt.b[3] = src;				\
23247038Sbostic 		rslt = (cvt.b32.i0 & 0x3f3f3f3fL) << 2;	\
23347038Sbostic 	}
2341958Swnj 
2351958Swnj /*
23647038Sbostic  * These macros may someday permit efficient use of 64-bit integers.
23717337Sralph  */
23847038Sbostic #define	ZERO(d,d0,d1)			d0 = 0, d1 = 0
23947038Sbostic #define	LOAD(d,d0,d1,bl)		d0 = (bl).b32.i0, d1 = (bl).b32.i1
24047038Sbostic #define	LOADREG(d,d0,d1,s,s0,s1)	d0 = s0, d1 = s1
24147038Sbostic #define	OR(d,d0,d1,bl)			d0 |= (bl).b32.i0, d1 |= (bl).b32.i1
24247038Sbostic #define	STORE(s,s0,s1,bl)		(bl).b32.i0 = s0, (bl).b32.i1 = s1
24347038Sbostic #define	DCL_BLOCK(d,d0,d1)		long d0, d1
24447038Sbostic 
24547038Sbostic #if defined(LARGEDATA)
24647038Sbostic 	/* Waste memory like crazy.  Also, do permutations in line */
24747038Sbostic #define	LGCHUNKBITS	3
24847038Sbostic #define	CHUNKBITS	(1<<LGCHUNKBITS)
24947038Sbostic #define	PERM6464(d,d0,d1,cpp,p)				\
25047038Sbostic 	LOAD(d,d0,d1,(p)[(0<<CHUNKBITS)+(cpp)[0]]);		\
25147038Sbostic 	OR (d,d0,d1,(p)[(1<<CHUNKBITS)+(cpp)[1]]);		\
25247038Sbostic 	OR (d,d0,d1,(p)[(2<<CHUNKBITS)+(cpp)[2]]);		\
25347038Sbostic 	OR (d,d0,d1,(p)[(3<<CHUNKBITS)+(cpp)[3]]);		\
25447038Sbostic 	OR (d,d0,d1,(p)[(4<<CHUNKBITS)+(cpp)[4]]);		\
25547038Sbostic 	OR (d,d0,d1,(p)[(5<<CHUNKBITS)+(cpp)[5]]);		\
25647038Sbostic 	OR (d,d0,d1,(p)[(6<<CHUNKBITS)+(cpp)[6]]);		\
25747038Sbostic 	OR (d,d0,d1,(p)[(7<<CHUNKBITS)+(cpp)[7]]);
25847038Sbostic #define	PERM3264(d,d0,d1,cpp,p)				\
25947038Sbostic 	LOAD(d,d0,d1,(p)[(0<<CHUNKBITS)+(cpp)[0]]);		\
26047038Sbostic 	OR (d,d0,d1,(p)[(1<<CHUNKBITS)+(cpp)[1]]);		\
26147038Sbostic 	OR (d,d0,d1,(p)[(2<<CHUNKBITS)+(cpp)[2]]);		\
26247038Sbostic 	OR (d,d0,d1,(p)[(3<<CHUNKBITS)+(cpp)[3]]);
26347038Sbostic #else
26447038Sbostic 	/* "small data" */
26547038Sbostic #define	LGCHUNKBITS	2
26647038Sbostic #define	CHUNKBITS	(1<<LGCHUNKBITS)
26747038Sbostic #define	PERM6464(d,d0,d1,cpp,p)				\
26847038Sbostic 	{ C_block tblk; permute(cpp,&tblk,p,8); LOAD (d,d0,d1,tblk); }
26947038Sbostic #define	PERM3264(d,d0,d1,cpp,p)				\
27047038Sbostic 	{ C_block tblk; permute(cpp,&tblk,p,4); LOAD (d,d0,d1,tblk); }
27147038Sbostic 
27247038Sbostic STATIC
permute(cp,out,p,chars_in)27347038Sbostic permute(cp, out, p, chars_in)
27447038Sbostic 	unsigned char *cp;
27547038Sbostic 	C_block *out;
27647038Sbostic 	register C_block *p;
27747038Sbostic 	int chars_in;
27847038Sbostic {
27947038Sbostic 	register DCL_BLOCK(D,D0,D1);
28047038Sbostic 	register C_block *tp;
28147038Sbostic 	register int t;
28247038Sbostic 
28347038Sbostic 	ZERO(D,D0,D1);
28447038Sbostic 	do {
28547038Sbostic 		t = *cp++;
28647038Sbostic 		tp = &p[t&0xf]; OR(D,D0,D1,*tp); p += (1<<CHUNKBITS);
28747038Sbostic 		tp = &p[t>>4];  OR(D,D0,D1,*tp); p += (1<<CHUNKBITS);
28847038Sbostic 	} while (--chars_in > 0);
28947038Sbostic 	STORE(D,D0,D1,*out);
29047038Sbostic }
29147038Sbostic #endif /* LARGEDATA */
29247038Sbostic 
29347038Sbostic 
29447038Sbostic /* =====  (mostly) Standard DES Tables ==================== */
29547038Sbostic 
29647038Sbostic static unsigned char IP[] = {		/* initial permutation */
29747038Sbostic 	58, 50, 42, 34, 26, 18, 10,  2,
29847038Sbostic 	60, 52, 44, 36, 28, 20, 12,  4,
29947038Sbostic 	62, 54, 46, 38, 30, 22, 14,  6,
30047038Sbostic 	64, 56, 48, 40, 32, 24, 16,  8,
30147038Sbostic 	57, 49, 41, 33, 25, 17,  9,  1,
30247038Sbostic 	59, 51, 43, 35, 27, 19, 11,  3,
30347038Sbostic 	61, 53, 45, 37, 29, 21, 13,  5,
30447038Sbostic 	63, 55, 47, 39, 31, 23, 15,  7,
30517337Sralph };
30617337Sralph 
30747038Sbostic /* The final permutation is the inverse of IP - no table is necessary */
30847038Sbostic 
30947038Sbostic static unsigned char ExpandTr[] = {	/* expansion operation */
31047038Sbostic 	32,  1,  2,  3,  4,  5,
31147038Sbostic 	 4,  5,  6,  7,  8,  9,
31247038Sbostic 	 8,  9, 10, 11, 12, 13,
31347038Sbostic 	12, 13, 14, 15, 16, 17,
31447038Sbostic 	16, 17, 18, 19, 20, 21,
31547038Sbostic 	20, 21, 22, 23, 24, 25,
31647038Sbostic 	24, 25, 26, 27, 28, 29,
31747038Sbostic 	28, 29, 30, 31, 32,  1,
31847038Sbostic };
31947038Sbostic 
32049831Sbostic static unsigned char PC1[] = {		/* permuted choice table 1 */
32147038Sbostic 	57, 49, 41, 33, 25, 17,  9,
32247038Sbostic 	 1, 58, 50, 42, 34, 26, 18,
32347038Sbostic 	10,  2, 59, 51, 43, 35, 27,
32447038Sbostic 	19, 11,  3, 60, 52, 44, 36,
32547038Sbostic 
32647038Sbostic 	63, 55, 47, 39, 31, 23, 15,
32747038Sbostic 	 7, 62, 54, 46, 38, 30, 22,
32847038Sbostic 	14,  6, 61, 53, 45, 37, 29,
32947038Sbostic 	21, 13,  5, 28, 20, 12,  4,
33047038Sbostic };
33147038Sbostic 
33249831Sbostic static unsigned char Rotates[] = {	/* PC1 rotation schedule */
33347038Sbostic 	1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1,
33447038Sbostic };
33547038Sbostic 
33647038Sbostic /* note: each "row" of PC2 is left-padded with bits that make it invertible */
33749831Sbostic static unsigned char PC2[] = {		/* permuted choice table 2 */
33847038Sbostic 	 9, 18,    14, 17, 11, 24,  1,  5,
33947038Sbostic 	22, 25,     3, 28, 15,  6, 21, 10,
34047038Sbostic 	35, 38,    23, 19, 12,  4, 26,  8,
34147038Sbostic 	43, 54,    16,  7, 27, 20, 13,  2,
34247038Sbostic 
34347038Sbostic 	 0,  0,    41, 52, 31, 37, 47, 55,
34447038Sbostic 	 0,  0,    30, 40, 51, 45, 33, 48,
34547038Sbostic 	 0,  0,    44, 49, 39, 56, 34, 53,
34647038Sbostic 	 0,  0,    46, 42, 50, 36, 29, 32,
34747038Sbostic };
34847038Sbostic 
34947038Sbostic static unsigned char S[8][64] = {	/* 48->32 bit substitution tables */
35047038Sbostic 					/* S[1]			*/
35147038Sbostic 	14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7,
35247038Sbostic 	 0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8,
35347038Sbostic 	 4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0,
35447038Sbostic 	15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13,
35547038Sbostic 					/* S[2]			*/
35647038Sbostic 	15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10,
35747038Sbostic 	 3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5,
35847038Sbostic 	 0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15,
35947038Sbostic 	13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9,
36047038Sbostic 					/* S[3]			*/
36147038Sbostic 	10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8,
36247038Sbostic 	13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1,
36347038Sbostic 	13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7,
36447038Sbostic 	 1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12,
36547038Sbostic 					/* S[4]			*/
36647038Sbostic 	 7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15,
36747038Sbostic 	13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9,
36847038Sbostic 	10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4,
36947038Sbostic 	 3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14,
37047038Sbostic 					/* S[5]			*/
37147038Sbostic 	 2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9,
37247038Sbostic 	14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6,
37347038Sbostic 	 4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14,
37447038Sbostic 	11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3,
37547038Sbostic 					/* S[6]			*/
37647038Sbostic 	12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11,
37747038Sbostic 	10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8,
37847038Sbostic 	 9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6,
37947038Sbostic 	 4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13,
38047038Sbostic 					/* S[7]			*/
38147038Sbostic 	 4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1,
38247038Sbostic 	13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6,
38347038Sbostic 	 1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2,
38447038Sbostic 	 6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12,
38547038Sbostic 					/* S[8]			*/
38647038Sbostic 	13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7,
38747038Sbostic 	 1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2,
38847038Sbostic 	 7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8,
38947038Sbostic 	 2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11,
39047038Sbostic };
39147038Sbostic 
39247038Sbostic static unsigned char P32Tr[] = {	/* 32-bit permutation function */
39347038Sbostic 	16,  7, 20, 21,
39447038Sbostic 	29, 12, 28, 17,
39547038Sbostic 	 1, 15, 23, 26,
39647038Sbostic 	 5, 18, 31, 10,
39747038Sbostic 	 2,  8, 24, 14,
39847038Sbostic 	32, 27,  3,  9,
39947038Sbostic 	19, 13, 30,  6,
40047038Sbostic 	22, 11,  4, 25,
40147038Sbostic };
40247038Sbostic 
40347038Sbostic static unsigned char CIFP[] = {		/* compressed/interleaved permutation */
40447038Sbostic 	 1,  2,  3,  4,   17, 18, 19, 20,
40547038Sbostic 	 5,  6,  7,  8,   21, 22, 23, 24,
40647038Sbostic 	 9, 10, 11, 12,   25, 26, 27, 28,
40747038Sbostic 	13, 14, 15, 16,   29, 30, 31, 32,
40847038Sbostic 
40947038Sbostic 	33, 34, 35, 36,   49, 50, 51, 52,
41047038Sbostic 	37, 38, 39, 40,   53, 54, 55, 56,
41147038Sbostic 	41, 42, 43, 44,   57, 58, 59, 60,
41247038Sbostic 	45, 46, 47, 48,   61, 62, 63, 64,
41347038Sbostic };
41447038Sbostic 
41547038Sbostic static unsigned char itoa64[] =		/* 0..63 => ascii-64 */
41647038Sbostic 	"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
41747038Sbostic 
41847038Sbostic 
41947038Sbostic /* =====  Tables that are initialized at run time  ==================== */
42047038Sbostic 
42147038Sbostic 
42247038Sbostic static unsigned char a64toi[128];	/* ascii-64 => 0..63 */
42347038Sbostic 
42447038Sbostic /* Initial key schedule permutation */
42547038Sbostic static C_block	PC1ROT[64/CHUNKBITS][1<<CHUNKBITS];
42647038Sbostic 
42747038Sbostic /* Subsequent key schedule rotation permutations */
42847038Sbostic static C_block	PC2ROT[2][64/CHUNKBITS][1<<CHUNKBITS];
42947038Sbostic 
43047038Sbostic /* Initial permutation/expansion table */
43147038Sbostic static C_block	IE3264[32/CHUNKBITS][1<<CHUNKBITS];
43247038Sbostic 
43347038Sbostic /* Table that combines the S, P, and E operations.  */
43447038Sbostic static long SPE[2][8][64];
43547038Sbostic 
43647038Sbostic /* compressed/interleaved => final permutation table */
43747038Sbostic static C_block	CF6464[64/CHUNKBITS][1<<CHUNKBITS];
43847038Sbostic 
43947038Sbostic 
44047038Sbostic /* ==================================== */
44147038Sbostic 
44247038Sbostic 
44347038Sbostic static C_block	constdatablock;			/* encryption constant */
44447038Sbostic static char	cryptresult[1+4+4+11+1];	/* encrypted result */
44547038Sbostic 
44617337Sralph /*
44748484Sbostic  * Return a pointer to static data consisting of the "setting"
44848484Sbostic  * followed by an encryption produced by the "key" and "setting".
4491958Swnj  */
45047038Sbostic char *
crypt(key,setting)45147038Sbostic crypt(key, setting)
45247038Sbostic 	register const char *key;
45347038Sbostic 	register const char *setting;
4541958Swnj {
45547038Sbostic 	register char *encp;
45647038Sbostic 	register long i;
45748484Sbostic 	register int t;
45847038Sbostic 	long salt;
45949831Sbostic 	int num_iter, salt_size;
46047038Sbostic 	C_block keyblock, rsltblock;
4611958Swnj 
46248484Sbostic 	for (i = 0; i < 8; i++) {
46348484Sbostic 		if ((t = 2*(unsigned char)(*key)) != 0)
46447038Sbostic 			key++;
46548484Sbostic 		keyblock.b[i] = t;
46648484Sbostic 	}
46749804Sbostic 	if (des_setkey((char *)keyblock.b))	/* also initializes "a64toi" */
46850127Skarels 		return (NULL);
46947038Sbostic 
47047038Sbostic 	encp = &cryptresult[0];
47148485Sbostic 	switch (*setting) {
47248485Sbostic 	case _PASSWORD_EFMT1:
47349831Sbostic 		/*
47449831Sbostic 		 * Involve the rest of the password 8 characters at a time.
47549831Sbostic 		 */
47649831Sbostic 		while (*key) {
47749831Sbostic 			if (des_cipher((char *)&keyblock,
47849831Sbostic 			    (char *)&keyblock, 0L, 1))
47950127Skarels 				return (NULL);
48049831Sbostic 			for (i = 0; i < 8; i++) {
48149831Sbostic 				if ((t = 2*(unsigned char)(*key)) != 0)
48249831Sbostic 					key++;
48349831Sbostic 				keyblock.b[i] ^= t;
48449831Sbostic 			}
48549831Sbostic 			if (des_setkey((char *)keyblock.b))
48650127Skarels 				return (NULL);
48749831Sbostic 		}
48849831Sbostic 
48947038Sbostic 		*encp++ = *setting++;
49047038Sbostic 
49147038Sbostic 		/* get iteration count */
49247038Sbostic 		num_iter = 0;
49347038Sbostic 		for (i = 4; --i >= 0; ) {
49448484Sbostic 			if ((t = (unsigned char)setting[i]) == '\0')
49548484Sbostic 				t = '.';
49648484Sbostic 			encp[i] = t;
49748484Sbostic 			num_iter = (num_iter<<6) | a64toi[t];
49847038Sbostic 		}
49947038Sbostic 		setting += 4;
50047038Sbostic 		encp += 4;
50147038Sbostic 		salt_size = 4;
50248485Sbostic 		break;
50348485Sbostic 	default:
50448485Sbostic 		num_iter = 25;
50548485Sbostic 		salt_size = 2;
50647038Sbostic 	}
50747038Sbostic 
50847038Sbostic 	salt = 0;
50947038Sbostic 	for (i = salt_size; --i >= 0; ) {
51048484Sbostic 		if ((t = (unsigned char)setting[i]) == '\0')
51148484Sbostic 			t = '.';
51248484Sbostic 		encp[i] = t;
51348484Sbostic 		salt = (salt<<6) | a64toi[t];
51447038Sbostic 	}
51547038Sbostic 	encp += salt_size;
51649804Sbostic 	if (des_cipher((char *)&constdatablock, (char *)&rsltblock,
51749804Sbostic 	    salt, num_iter))
51850127Skarels 		return (NULL);
51947038Sbostic 
5201958Swnj 	/*
52147038Sbostic 	 * Encode the 64 cipher bits as 11 ascii characters.
5221958Swnj 	 */
52347038Sbostic 	i = ((long)((rsltblock.b[0]<<8) | rsltblock.b[1])<<8) | rsltblock.b[2];
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[3]<<8) | rsltblock.b[4])<<8) | rsltblock.b[5];
52947038Sbostic 	encp[3] = itoa64[i&0x3f];	i >>= 6;
53047038Sbostic 	encp[2] = itoa64[i&0x3f];	i >>= 6;
53147038Sbostic 	encp[1] = itoa64[i&0x3f];	i >>= 6;
53247038Sbostic 	encp[0] = itoa64[i];		encp += 4;
53347038Sbostic 	i = ((long)((rsltblock.b[6])<<8) | rsltblock.b[7])<<2;
53447038Sbostic 	encp[2] = itoa64[i&0x3f];	i >>= 6;
53547038Sbostic 	encp[1] = itoa64[i&0x3f];	i >>= 6;
53647038Sbostic 	encp[0] = itoa64[i];
53747038Sbostic 
53847038Sbostic 	encp[3] = 0;
53948484Sbostic 
54050127Skarels 	return (cryptresult);
54147038Sbostic }
54247038Sbostic 
54347038Sbostic 
54447038Sbostic /*
54547038Sbostic  * The Key Schedule, filled in by des_setkey() or setkey().
54647038Sbostic  */
54747038Sbostic #define	KS_SIZE	16
54847038Sbostic static C_block	KS[KS_SIZE];
54947038Sbostic 
55047038Sbostic /*
55147038Sbostic  * Set up the key schedule from the key.
55247038Sbostic  */
des_setkey(key)55347038Sbostic des_setkey(key)
55447038Sbostic 	register const char *key;
55547038Sbostic {
55647038Sbostic 	register DCL_BLOCK(K, K0, K1);
55747038Sbostic 	register C_block *ptabp;
55847038Sbostic 	register int i;
55947038Sbostic 	static int des_ready = 0;
56047038Sbostic 
56147038Sbostic 	if (!des_ready) {
56247038Sbostic 		init_des();
56347038Sbostic 		des_ready = 1;
5641958Swnj 	}
56517337Sralph 
56647038Sbostic 	PERM6464(K,K0,K1,(unsigned char *)key,(C_block *)PC1ROT);
56747038Sbostic 	key = (char *)&KS[0];
56849831Sbostic 	STORE(K&~0x03030303L, K0&~0x03030303L, K1, *(C_block *)key);
56947038Sbostic 	for (i = 1; i < 16; i++) {
57047038Sbostic 		key += sizeof(C_block);
57147038Sbostic 		STORE(K,K0,K1,*(C_block *)key);
57247038Sbostic 		ptabp = (C_block *)PC2ROT[Rotates[i]-1];
57347038Sbostic 		PERM6464(K,K0,K1,(unsigned char *)key,ptabp);
57449831Sbostic 		STORE(K&~0x03030303L, K0&~0x03030303L, K1, *(C_block *)key);
57547038Sbostic 	}
57650127Skarels 	return (0);
5771958Swnj }
5781958Swnj 
5791958Swnj /*
58047038Sbostic  * Encrypt (or decrypt if num_iter < 0) the 8 chars at "in" with abs(num_iter)
58147038Sbostic  * iterations of DES, using the the given 24-bit salt and the pre-computed key
58247038Sbostic  * schedule, and store the resulting 8 chars at "out" (in == out is permitted).
58347038Sbostic  *
58447038Sbostic  * NOTE: the performance of this routine is critically dependent on your
58547038Sbostic  * compiler and machine architecture.
5861958Swnj  */
des_cipher(in,out,salt,num_iter)58747038Sbostic des_cipher(in, out, salt, num_iter)
58847038Sbostic 	const char *in;
58947038Sbostic 	char *out;
59048484Sbostic 	long salt;
59147038Sbostic 	int num_iter;
59247038Sbostic {
59347038Sbostic 	/* variables that we want in registers, most important first */
59447038Sbostic #if defined(pdp11)
59547038Sbostic 	register int j;
59647038Sbostic #endif
59747038Sbostic 	register long L0, L1, R0, R1, k;
59847038Sbostic 	register C_block *kp;
59947038Sbostic 	register int ks_inc, loop_count;
60047038Sbostic 	C_block B;
6011958Swnj 
60247038Sbostic 	L0 = salt;
60349831Sbostic 	TO_SIX_BIT(salt, L0);	/* convert to 4*(6+2) format */
6041958Swnj 
60547038Sbostic #if defined(vax) || defined(pdp11)
60647038Sbostic 	salt = ~salt;	/* "x &~ y" is faster than "x & y". */
60747038Sbostic #define	SALT (~salt)
60847038Sbostic #else
60947038Sbostic #define	SALT salt
61047038Sbostic #endif
6111958Swnj 
61247038Sbostic #if defined(MUST_ALIGN)
61347038Sbostic 	B.b[0] = in[0]; B.b[1] = in[1]; B.b[2] = in[2]; B.b[3] = in[3];
61447038Sbostic 	B.b[4] = in[4]; B.b[5] = in[5]; B.b[6] = in[6]; B.b[7] = in[7];
61547038Sbostic 	LOAD(L,L0,L1,B);
61647038Sbostic #else
61747038Sbostic 	LOAD(L,L0,L1,*(C_block *)in);
61847038Sbostic #endif
61947038Sbostic 	LOADREG(R,R0,R1,L,L0,L1);
62047038Sbostic 	L0 &= 0x55555555L;
62147038Sbostic 	L1 &= 0x55555555L;
62247038Sbostic 	L0 = (L0 << 1) | L1;	/* L0 is the even-numbered input bits */
62347038Sbostic 	R0 &= 0xaaaaaaaaL;
62447038Sbostic 	R1 = (R1 >> 1) & 0x55555555L;
62547038Sbostic 	L1 = R0 | R1;		/* L1 is the odd-numbered input bits */
62647038Sbostic 	STORE(L,L0,L1,B);
62747038Sbostic 	PERM3264(L,L0,L1,B.b,  (C_block *)IE3264);	/* even bits */
62847038Sbostic 	PERM3264(R,R0,R1,B.b+4,(C_block *)IE3264);	/* odd bits */
6291958Swnj 
63047038Sbostic 	if (num_iter >= 0)
63147038Sbostic 	{		/* encryption */
63247038Sbostic 		kp = &KS[0];
63347038Sbostic 		ks_inc  = sizeof(*kp);
63447038Sbostic 	}
63547038Sbostic 	else
63647038Sbostic 	{		/* decryption */
637*64292Smckusick 		return (1); /* always fail */
63847038Sbostic 	}
6391958Swnj 
64047038Sbostic 	while (--num_iter >= 0) {
64147038Sbostic 		loop_count = 8;
64247038Sbostic 		do {
6431958Swnj 
64449831Sbostic #define	SPTAB(t, i)	(*(long *)((unsigned char *)t + i*(sizeof(long)/4)))
64547038Sbostic #if defined(gould)
64649831Sbostic 			/* use this if B.b[i] is evaluated just once ... */
64749831Sbostic #define	DOXOR(x,y,i)	x^=SPTAB(SPE[0][i],B.b[i]); y^=SPTAB(SPE[1][i],B.b[i]);
64847038Sbostic #else
64947038Sbostic #if defined(pdp11)
65047038Sbostic 			/* use this if your "long" int indexing is slow */
65149831Sbostic #define	DOXOR(x,y,i)	j=B.b[i]; x^=SPTAB(SPE[0][i],j); y^=SPTAB(SPE[1][i],j);
65247038Sbostic #else
65347038Sbostic 			/* use this if "k" is allocated to a register ... */
65449831Sbostic #define	DOXOR(x,y,i)	k=B.b[i]; x^=SPTAB(SPE[0][i],k); y^=SPTAB(SPE[1][i],k);
65547038Sbostic #endif
65647038Sbostic #endif
6571958Swnj 
65849831Sbostic #define	CRUNCH(p0, p1, q0, q1)	\
65949831Sbostic 			k = (q0 ^ q1) & SALT;	\
66049831Sbostic 			B.b32.i0 = k ^ q0 ^ kp->b32.i0;		\
66149831Sbostic 			B.b32.i1 = k ^ q1 ^ kp->b32.i1;		\
66247038Sbostic 			kp = (C_block *)((char *)kp+ks_inc);	\
66347038Sbostic 							\
66449831Sbostic 			DOXOR(p0, p1, 0);		\
66549831Sbostic 			DOXOR(p0, p1, 1);		\
66649831Sbostic 			DOXOR(p0, p1, 2);		\
66749831Sbostic 			DOXOR(p0, p1, 3);		\
66849831Sbostic 			DOXOR(p0, p1, 4);		\
66949831Sbostic 			DOXOR(p0, p1, 5);		\
67049831Sbostic 			DOXOR(p0, p1, 6);		\
67149831Sbostic 			DOXOR(p0, p1, 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
69750127Skarels 	return (0);
69847038Sbostic }
69947038Sbostic 
70047038Sbostic 
7011958Swnj /*
70247038Sbostic  * Initialize various tables.  This need only be done once.  It could even be
70347038Sbostic  * done at compile time, if the compiler were capable of that sort of thing.
7041958Swnj  */
70547038Sbostic STATIC
init_des()70647038Sbostic init_des()
7071958Swnj {
70847038Sbostic 	register int i, j;
70947038Sbostic 	register long k;
71047038Sbostic 	register int tableno;
71147038Sbostic 	static unsigned char perm[64], tmp32[32];	/* "static" for speed */
7121958Swnj 
7131958Swnj 	/*
71447038Sbostic 	 * table that converts chars "./0-9A-Za-z"to integers 0-63.
7151958Swnj 	 */
71647038Sbostic 	for (i = 0; i < 64; i++)
71747038Sbostic 		a64toi[itoa64[i]] = i;
71847038Sbostic 
7191958Swnj 	/*
72047038Sbostic 	 * PC1ROT - bit reverse, then PC1, then Rotate, then PC2.
7211958Swnj 	 */
72247038Sbostic 	for (i = 0; i < 64; i++)
72347038Sbostic 		perm[i] = 0;
72447038Sbostic 	for (i = 0; i < 64; i++) {
72547038Sbostic 		if ((k = PC2[i]) == 0)
72647038Sbostic 			continue;
72747038Sbostic 		k += Rotates[0]-1;
72847038Sbostic 		if ((k%28) < Rotates[0]) k -= 28;
72947038Sbostic 		k = PC1[k];
73047038Sbostic 		if (k > 0) {
73147038Sbostic 			k--;
73247038Sbostic 			k = (k|07) - (k&07);
73347038Sbostic 			k++;
7341958Swnj 		}
73547038Sbostic 		perm[i] = k;
7361958Swnj 	}
73747038Sbostic #ifdef DEBUG
73847038Sbostic 	prtab("pc1tab", perm, 8);
73947038Sbostic #endif
74048484Sbostic 	init_perm(PC1ROT, perm, 8, 8);
74147038Sbostic 
7421958Swnj 	/*
74347038Sbostic 	 * PC2ROT - PC2 inverse, then Rotate (once or twice), then PC2.
7441958Swnj 	 */
74547038Sbostic 	for (j = 0; j < 2; j++) {
74647038Sbostic 		unsigned char pc2inv[64];
74747038Sbostic 		for (i = 0; i < 64; i++)
74847038Sbostic 			perm[i] = pc2inv[i] = 0;
74947038Sbostic 		for (i = 0; i < 64; i++) {
75047038Sbostic 			if ((k = PC2[i]) == 0)
75147038Sbostic 				continue;
75247038Sbostic 			pc2inv[k-1] = i+1;
75347038Sbostic 		}
75447038Sbostic 		for (i = 0; i < 64; i++) {
75547038Sbostic 			if ((k = PC2[i]) == 0)
75647038Sbostic 				continue;
75747038Sbostic 			k += j;
75847038Sbostic 			if ((k%28) <= j) k -= 28;
75947038Sbostic 			perm[i] = pc2inv[k];
76047038Sbostic 		}
76147038Sbostic #ifdef DEBUG
76247038Sbostic 		prtab("pc2tab", perm, 8);
76347038Sbostic #endif
76448484Sbostic 		init_perm(PC2ROT[j], perm, 8, 8);
7651958Swnj 	}
76647038Sbostic 
7671958Swnj 	/*
76847038Sbostic 	 * Bit reverse, then initial permutation, then expansion.
7691958Swnj 	 */
77047038Sbostic 	for (i = 0; i < 8; i++) {
77147038Sbostic 		for (j = 0; j < 8; j++) {
77247038Sbostic 			k = (j < 2)? 0: IP[ExpandTr[i*6+j-2]-1];
77347038Sbostic 			if (k > 32)
77447038Sbostic 				k -= 32;
77547038Sbostic 			else if (k > 0)
77647038Sbostic 				k--;
77747038Sbostic 			if (k > 0) {
77847038Sbostic 				k--;
77947038Sbostic 				k = (k|07) - (k&07);
78047038Sbostic 				k++;
78147038Sbostic 			}
78247038Sbostic 			perm[i*8+j] = k;
78347038Sbostic 		}
78447038Sbostic 	}
78547038Sbostic #ifdef DEBUG
78647038Sbostic 	prtab("ietab", perm, 8);
78747038Sbostic #endif
78848484Sbostic 	init_perm(IE3264, perm, 4, 8);
78947038Sbostic 
79047038Sbostic 	/*
79147038Sbostic 	 * Compression, then final permutation, then bit reverse.
79247038Sbostic 	 */
79347038Sbostic 	for (i = 0; i < 64; i++) {
79447038Sbostic 		k = IP[CIFP[i]-1];
79547038Sbostic 		if (k > 0) {
79647038Sbostic 			k--;
79747038Sbostic 			k = (k|07) - (k&07);
79847038Sbostic 			k++;
79947038Sbostic 		}
80047038Sbostic 		perm[k-1] = i+1;
80147038Sbostic 	}
80247038Sbostic #ifdef DEBUG
80347038Sbostic 	prtab("cftab", perm, 8);
80447038Sbostic #endif
80548484Sbostic 	init_perm(CF6464, perm, 8, 8);
80647038Sbostic 
80747038Sbostic 	/*
80847038Sbostic 	 * SPE table
80947038Sbostic 	 */
81047038Sbostic 	for (i = 0; i < 48; i++)
81147038Sbostic 		perm[i] = P32Tr[ExpandTr[i]-1];
81247038Sbostic 	for (tableno = 0; tableno < 8; tableno++) {
81347038Sbostic 		for (j = 0; j < 64; j++)  {
81447038Sbostic 			k = (((j >> 0) &01) << 5)|
81547038Sbostic 			    (((j >> 1) &01) << 3)|
81647038Sbostic 			    (((j >> 2) &01) << 2)|
81747038Sbostic 			    (((j >> 3) &01) << 1)|
81847038Sbostic 			    (((j >> 4) &01) << 0)|
81947038Sbostic 			    (((j >> 5) &01) << 4);
82047038Sbostic 			k = S[tableno][k];
82147038Sbostic 			k = (((k >> 3)&01) << 0)|
82247038Sbostic 			    (((k >> 2)&01) << 1)|
82347038Sbostic 			    (((k >> 1)&01) << 2)|
82447038Sbostic 			    (((k >> 0)&01) << 3);
82547038Sbostic 			for (i = 0; i < 32; i++)
82647038Sbostic 				tmp32[i] = 0;
82747038Sbostic 			for (i = 0; i < 4; i++)
82847038Sbostic 				tmp32[4 * tableno + i] = (k >> i) & 01;
82947038Sbostic 			k = 0;
83047038Sbostic 			for (i = 24; --i >= 0; )
83147038Sbostic 				k = (k<<1) | tmp32[perm[i]-1];
83247038Sbostic 			TO_SIX_BIT(SPE[0][tableno][j], k);
83347038Sbostic 			k = 0;
83447038Sbostic 			for (i = 24; --i >= 0; )
83547038Sbostic 				k = (k<<1) | tmp32[perm[i+24]-1];
83647038Sbostic 			TO_SIX_BIT(SPE[1][tableno][j], k);
83747038Sbostic 		}
83847038Sbostic 	}
8391958Swnj }
8401958Swnj 
84147038Sbostic /*
84248484Sbostic  * Initialize "perm" to represent transformation "p", which rearranges
84348484Sbostic  * (perhaps with expansion and/or contraction) one packed array of bits
84448484Sbostic  * (of size "chars_in" characters) into another array (of size "chars_out"
84548484Sbostic  * characters).
84648484Sbostic  *
84747038Sbostic  * "perm" must be all-zeroes on entry to this routine.
84847038Sbostic  */
84947038Sbostic STATIC
init_perm(perm,p,chars_in,chars_out)85048484Sbostic init_perm(perm, p, chars_in, chars_out)
85147038Sbostic 	C_block perm[64/CHUNKBITS][1<<CHUNKBITS];
85247038Sbostic 	unsigned char p[64];
85347038Sbostic 	int chars_in, chars_out;
8541958Swnj {
85547038Sbostic 	register int i, j, k, l;
85617337Sralph 
85747038Sbostic 	for (k = 0; k < chars_out*8; k++) {	/* each output bit position */
85847038Sbostic 		l = p[k] - 1;		/* where this bit comes from */
85947038Sbostic 		if (l < 0)
86047038Sbostic 			continue;	/* output bit is always 0 */
86147038Sbostic 		i = l>>LGCHUNKBITS;	/* which chunk this bit comes from */
86247038Sbostic 		l = 1<<(l&(CHUNKBITS-1));	/* mask for this bit */
86347038Sbostic 		for (j = 0; j < (1<<CHUNKBITS); j++) {	/* each chunk value */
86447038Sbostic 			if ((j & l) != 0)
86547038Sbostic 				perm[i][j].b[k>>3] |= 1<<(k&07);
86647038Sbostic 		}
8671958Swnj 	}
86847038Sbostic }
8691958Swnj 
87047038Sbostic /*
87147038Sbostic  * "setkey" routine (for backwards compatibility)
87247038Sbostic  */
setkey(key)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 	}
88750127Skarels 	return (des_setkey((char *)keyblock.b));
8881958Swnj }
88947038Sbostic 
89047038Sbostic /*
89147038Sbostic  * "encrypt" routine (for backwards compatibility)
89247038Sbostic  */
encrypt(block,flag)89347038Sbostic encrypt(block, flag)
89447038Sbostic 	register char *block;
89547038Sbostic 	int flag;
89647038Sbostic {
89747038Sbostic 	register int i, j, k;
89847038Sbostic 	C_block cblock;
89947038Sbostic 
90047038Sbostic 	for (i = 0; i < 8; i++) {
90147038Sbostic 		k = 0;
90247038Sbostic 		for (j = 0; j < 8; j++) {
90347038Sbostic 			k <<= 1;
90447038Sbostic 			k |= (unsigned char)*block++;
90547038Sbostic 		}
90647038Sbostic 		cblock.b[i] = k;
90747038Sbostic 	}
90849804Sbostic 	if (des_cipher((char *)&cblock, (char *)&cblock, 0L, (flag ? -1: 1)))
90950127Skarels 		return (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 	}
91750127Skarels 	return (0);
91847038Sbostic }
91947038Sbostic 
92047038Sbostic #ifdef DEBUG
92147038Sbostic STATIC
prtab(s,t,num_rows)92247038Sbostic prtab(s, t, num_rows)
92347038Sbostic 	char *s;
92447038Sbostic 	unsigned char *t;
92547038Sbostic 	int num_rows;
92647038Sbostic {
92747038Sbostic 	register int i, j;
92847038Sbostic 
92948485Sbostic 	(void)printf("%s:\n", s);
93047038Sbostic 	for (i = 0; i < num_rows; i++) {
93147038Sbostic 		for (j = 0; j < 8; j++) {
93248485Sbostic 			 (void)printf("%3d", t[i*8+j]);
93347038Sbostic 		}
93448485Sbostic 		(void)printf("\n");
93547038Sbostic 	}
93648485Sbostic 	(void)printf("\n");
93747038Sbostic }
93847038Sbostic #endif
939