xref: /original-bsd/lib/libc/gen/crypt.c (revision eecd7825)
1ebc0fb5aSbostic /*
2bac379f5Sbostic  * Copyright (c) 1989, 1993
3bac379f5Sbostic  *	The Regents of the University of California.  All rights reserved.
4ebc0fb5aSbostic  *
5ebc0fb5aSbostic  * This code is derived from software contributed to Berkeley by
6ebc0fb5aSbostic  * Tom Truscott.
7ebc0fb5aSbostic  *
8489556ffSbostic  * %sccs.include.redist.c%
9ebc0fb5aSbostic  */
10a4214ab6Smckusick 
11ebc0fb5aSbostic #if defined(LIBC_SCCS) && !defined(lint)
12*eecd7825Smckusick static char sccsid[] = "@(#)crypt.c	8.1.1.1 (Berkeley) 08/18/93";
13ebc0fb5aSbostic #endif /* LIBC_SCCS and not lint */
14ebc0fb5aSbostic 
15ae227ee3Sdonn #include <unistd.h>
164514fd74Sbostic #include <limits.h>
17870683b6Sbostic #include <pwd.h>
18ae227ee3Sdonn 
1985ac702bSwnj /*
20ebc0fb5aSbostic  * UNIX password, and DES, encryption.
21ebc0fb5aSbostic  * By Tom Truscott, trt@rti.rti.org,
22ebc0fb5aSbostic  * from algorithms by Robert W. Baldwin and James Gillogly.
23ebc0fb5aSbostic  *
24ebc0fb5aSbostic  * References:
25ebc0fb5aSbostic  * "Mathematical Cryptology for Computer Scientists and Mathematicians,"
26ebc0fb5aSbostic  * by Wayne Patterson, 1987, ISBN 0-8476-7438-X.
27ebc0fb5aSbostic  *
28ebc0fb5aSbostic  * "Password Security: A Case History," R. Morris and Ken Thompson,
29ebc0fb5aSbostic  * Communications of the ACM, vol. 22, pp. 594-597, Nov. 1979.
30ebc0fb5aSbostic  *
31ebc0fb5aSbostic  * "DES will be Totally Insecure within Ten Years," M.E. Hellman,
32ebc0fb5aSbostic  * IEEE Spectrum, vol. 16, pp. 32-39, July 1979.
3385ac702bSwnj  */
3485ac702bSwnj 
35ebc0fb5aSbostic /* =====  Configuration ==================== */
36ebc0fb5aSbostic 
3785ac702bSwnj /*
38ebc0fb5aSbostic  * define "MUST_ALIGN" if your compiler cannot load/store
39ebc0fb5aSbostic  * long integers at arbitrary (e.g. odd) memory locations.
40ebc0fb5aSbostic  * (Either that or never pass unaligned addresses to des_cipher!)
4185ac702bSwnj  */
42ebc0fb5aSbostic #if !defined(vax)
43ebc0fb5aSbostic #define	MUST_ALIGN
44ebc0fb5aSbostic #endif
45ebc0fb5aSbostic 
464514fd74Sbostic #ifdef CHAR_BITS
474514fd74Sbostic #if CHAR_BITS != 8
484514fd74Sbostic 	#error C_block structure assumes 8 bit characters
494514fd74Sbostic #endif
504514fd74Sbostic #endif
514514fd74Sbostic 
52ebc0fb5aSbostic /*
53ebc0fb5aSbostic  * define "LONG_IS_32_BITS" only if sizeof(long)==4.
54ebc0fb5aSbostic  * This avoids use of bit fields (your compiler may be sloppy with them).
55ebc0fb5aSbostic  */
56ebc0fb5aSbostic #if !defined(cray)
57ebc0fb5aSbostic #define	LONG_IS_32_BITS
58ebc0fb5aSbostic #endif
59ebc0fb5aSbostic 
60ebc0fb5aSbostic /*
61ebc0fb5aSbostic  * define "B64" to be the declaration for a 64 bit integer.
62ebc0fb5aSbostic  * XXX this feature is currently unused, see "endian" comment below.
63ebc0fb5aSbostic  */
64ebc0fb5aSbostic #if defined(cray)
65ebc0fb5aSbostic #define	B64	long
66ebc0fb5aSbostic #endif
67ebc0fb5aSbostic #if defined(convex)
68ebc0fb5aSbostic #define	B64	long long
69ebc0fb5aSbostic #endif
70ebc0fb5aSbostic 
71ebc0fb5aSbostic /*
72ebc0fb5aSbostic  * define "LARGEDATA" to get faster permutations, by using about 72 kilobytes
73ebc0fb5aSbostic  * of lookup tables.  This speeds up des_setkey() and des_cipher(), but has
74ebc0fb5aSbostic  * little effect on crypt().
75ebc0fb5aSbostic  */
76ebc0fb5aSbostic #if defined(notdef)
77ebc0fb5aSbostic #define	LARGEDATA
78ebc0fb5aSbostic #endif
79ebc0fb5aSbostic 
80b47d4dc5Sbostic /* compile with "-DSTATIC=int" when profiling */
81b47d4dc5Sbostic #ifndef STATIC
82ebc0fb5aSbostic #define	STATIC	static
83b47d4dc5Sbostic #endif
84b47d4dc5Sbostic STATIC init_des(), init_perm(), permute();
85ebc0fb5aSbostic #ifdef DEBUG
86ebc0fb5aSbostic STATIC prtab();
87ebc0fb5aSbostic #endif
88ebc0fb5aSbostic 
89ebc0fb5aSbostic /* ==================================== */
90ebc0fb5aSbostic 
91ebc0fb5aSbostic /*
92ebc0fb5aSbostic  * Cipher-block representation (Bob Baldwin):
93ebc0fb5aSbostic  *
94ebc0fb5aSbostic  * DES operates on groups of 64 bits, numbered 1..64 (sigh).  One
95ebc0fb5aSbostic  * representation is to store one bit per byte in an array of bytes.  Bit N of
96ebc0fb5aSbostic  * the NBS spec is stored as the LSB of the Nth byte (index N-1) in the array.
97ebc0fb5aSbostic  * Another representation stores the 64 bits in 8 bytes, with bits 1..8 in the
98ebc0fb5aSbostic  * first byte, 9..16 in the second, and so on.  The DES spec apparently has
99ebc0fb5aSbostic  * bit 1 in the MSB of the first byte, but that is particularly noxious so we
100ebc0fb5aSbostic  * bit-reverse each byte so that bit 1 is the LSB of the first byte, bit 8 is
101ebc0fb5aSbostic  * the MSB of the first byte.  Specifically, the 64-bit input data and key are
102ebc0fb5aSbostic  * converted to LSB format, and the output 64-bit block is converted back into
103ebc0fb5aSbostic  * MSB format.
104ebc0fb5aSbostic  *
105ebc0fb5aSbostic  * DES operates internally on groups of 32 bits which are expanded to 48 bits
106ebc0fb5aSbostic  * by permutation E and shrunk back to 32 bits by the S boxes.  To speed up
107ebc0fb5aSbostic  * the computation, the expansion is applied only once, the expanded
108ebc0fb5aSbostic  * representation is maintained during the encryption, and a compression
109ebc0fb5aSbostic  * permutation is applied only at the end.  To speed up the S-box lookups,
110ebc0fb5aSbostic  * the 48 bits are maintained as eight 6 bit groups, one per byte, which
111ebc0fb5aSbostic  * directly feed the eight S-boxes.  Within each byte, the 6 bits are the
112ebc0fb5aSbostic  * most significant ones.  The low two bits of each byte are zero.  (Thus,
113ebc0fb5aSbostic  * bit 1 of the 48 bit E expansion is stored as the "4"-valued bit of the
114ebc0fb5aSbostic  * first byte in the eight byte representation, bit 2 of the 48 bit value is
115ebc0fb5aSbostic  * the "8"-valued bit, and so on.)  In fact, a combined "SPE"-box lookup is
116ebc0fb5aSbostic  * used, in which the output is the 64 bit result of an S-box lookup which
117ebc0fb5aSbostic  * has been permuted by P and expanded by E, and is ready for use in the next
118ebc0fb5aSbostic  * iteration.  Two 32-bit wide tables, SPE[0] and SPE[1], are used for this
119ebc0fb5aSbostic  * lookup.  Since each byte in the 48 bit path is a multiple of four, indexed
120ebc0fb5aSbostic  * lookup of SPE[0] and SPE[1] is simple and fast.  The key schedule and
121ebc0fb5aSbostic  * "salt" are also converted to this 8*(6+2) format.  The SPE table size is
122ebc0fb5aSbostic  * 8*64*8 = 4K bytes.
123ebc0fb5aSbostic  *
124ebc0fb5aSbostic  * To speed up bit-parallel operations (such as XOR), the 8 byte
125ebc0fb5aSbostic  * representation is "union"ed with 32 bit values "i0" and "i1", and, on
126ebc0fb5aSbostic  * machines which support it, a 64 bit value "b64".  This data structure,
127ebc0fb5aSbostic  * "C_block", has two problems.  First, alignment restrictions must be
128ebc0fb5aSbostic  * honored.  Second, the byte-order (e.g. little-endian or big-endian) of
129ebc0fb5aSbostic  * the architecture becomes visible.
130ebc0fb5aSbostic  *
131ebc0fb5aSbostic  * The byte-order problem is unfortunate, since on the one hand it is good
132ebc0fb5aSbostic  * to have a machine-independent C_block representation (bits 1..8 in the
133ebc0fb5aSbostic  * first byte, etc.), and on the other hand it is good for the LSB of the
134ebc0fb5aSbostic  * first byte to be the LSB of i0.  We cannot have both these things, so we
135ebc0fb5aSbostic  * currently use the "little-endian" representation and avoid any multi-byte
136ebc0fb5aSbostic  * operations that depend on byte order.  This largely precludes use of the
137ebc0fb5aSbostic  * 64-bit datatype since the relative order of i0 and i1 are unknown.  It
138ebc0fb5aSbostic  * also inhibits grouping the SPE table to look up 12 bits at a time.  (The
139ebc0fb5aSbostic  * 12 bits can be stored in a 16-bit field with 3 low-order zeroes and 1
140ebc0fb5aSbostic  * high-order zero, providing fast indexing into a 64-bit wide SPE.)  On the
141ebc0fb5aSbostic  * other hand, 64-bit datatypes are currently rare, and a 12-bit SPE lookup
142ebc0fb5aSbostic  * requires a 128 kilobyte table, so perhaps this is not a big loss.
143ebc0fb5aSbostic  *
144ebc0fb5aSbostic  * Permutation representation (Jim Gillogly):
145ebc0fb5aSbostic  *
146ebc0fb5aSbostic  * A transformation is defined by its effect on each of the 8 bytes of the
147ebc0fb5aSbostic  * 64-bit input.  For each byte we give a 64-bit output that has the bits in
148ebc0fb5aSbostic  * the input distributed appropriately.  The transformation is then the OR
149ebc0fb5aSbostic  * of the 8 sets of 64-bits.  This uses 8*256*8 = 16K bytes of storage for
150ebc0fb5aSbostic  * each transformation.  Unless LARGEDATA is defined, however, a more compact
151ebc0fb5aSbostic  * table is used which looks up 16 4-bit "chunks" rather than 8 8-bit chunks.
152ebc0fb5aSbostic  * The smaller table uses 16*16*8 = 2K bytes for each transformation.  This
153ebc0fb5aSbostic  * is slower but tolerable, particularly for password encryption in which
154ebc0fb5aSbostic  * the SPE transformation is iterated many times.  The small tables total 9K
155ebc0fb5aSbostic  * bytes, the large tables total 72K bytes.
156ebc0fb5aSbostic  *
157ebc0fb5aSbostic  * The transformations used are:
158ebc0fb5aSbostic  * IE3264: MSB->LSB conversion, initial permutation, and expansion.
159ebc0fb5aSbostic  *	This is done by collecting the 32 even-numbered bits and applying
160ebc0fb5aSbostic  *	a 32->64 bit transformation, and then collecting the 32 odd-numbered
161ebc0fb5aSbostic  *	bits and applying the same transformation.  Since there are only
162ebc0fb5aSbostic  *	32 input bits, the IE3264 transformation table is half the size of
163ebc0fb5aSbostic  *	the usual table.
164ebc0fb5aSbostic  * CF6464: Compression, final permutation, and LSB->MSB conversion.
165ebc0fb5aSbostic  *	This is done by two trivial 48->32 bit compressions to obtain
166ebc0fb5aSbostic  *	a 64-bit block (the bit numbering is given in the "CIFP" table)
167ebc0fb5aSbostic  *	followed by a 64->64 bit "cleanup" transformation.  (It would
168ebc0fb5aSbostic  *	be possible to group the bits in the 64-bit block so that 2
169ebc0fb5aSbostic  *	identical 32->32 bit transformations could be used instead,
170ebc0fb5aSbostic  *	saving a factor of 4 in space and possibly 2 in time, but
171ebc0fb5aSbostic  *	byte-ordering and other complications rear their ugly head.
172ebc0fb5aSbostic  *	Similar opportunities/problems arise in the key schedule
173ebc0fb5aSbostic  *	transforms.)
174ebc0fb5aSbostic  * PC1ROT: MSB->LSB, PC1 permutation, rotate, and PC2 permutation.
175ebc0fb5aSbostic  *	This admittedly baroque 64->64 bit transformation is used to
176ebc0fb5aSbostic  *	produce the first code (in 8*(6+2) format) of the key schedule.
177ebc0fb5aSbostic  * PC2ROT[0]: Inverse PC2 permutation, rotate, and PC2 permutation.
178ebc0fb5aSbostic  *	It would be possible to define 15 more transformations, each
179ebc0fb5aSbostic  *	with a different rotation, to generate the entire key schedule.
180ebc0fb5aSbostic  *	To save space, however, we instead permute each code into the
181ebc0fb5aSbostic  *	next by using a transformation that "undoes" the PC2 permutation,
182ebc0fb5aSbostic  *	rotates the code, and then applies PC2.  Unfortunately, PC2
183ebc0fb5aSbostic  *	transforms 56 bits into 48 bits, dropping 8 bits, so PC2 is not
184ebc0fb5aSbostic  *	invertible.  We get around that problem by using a modified PC2
185ebc0fb5aSbostic  *	which retains the 8 otherwise-lost bits in the unused low-order
186ebc0fb5aSbostic  *	bits of each byte.  The low-order bits are cleared when the
187ebc0fb5aSbostic  *	codes are stored into the key schedule.
188ebc0fb5aSbostic  * PC2ROT[1]: Same as PC2ROT[0], but with two rotations.
189ebc0fb5aSbostic  *	This is faster than applying PC2ROT[0] twice,
190ebc0fb5aSbostic  *
191ebc0fb5aSbostic  * The Bell Labs "salt" (Bob Baldwin):
192ebc0fb5aSbostic  *
193ebc0fb5aSbostic  * The salting is a simple permutation applied to the 48-bit result of E.
194ebc0fb5aSbostic  * Specifically, if bit i (1 <= i <= 24) of the salt is set then bits i and
195ebc0fb5aSbostic  * i+24 of the result are swapped.  The salt is thus a 24 bit number, with
196ebc0fb5aSbostic  * 16777216 possible values.  (The original salt was 12 bits and could not
197ebc0fb5aSbostic  * swap bits 13..24 with 36..48.)
198ebc0fb5aSbostic  *
199b47d4dc5Sbostic  * It is possible, but ugly, to warp the SPE table to account for the salt
200b47d4dc5Sbostic  * permutation.  Fortunately, the conditional bit swapping requires only
201b47d4dc5Sbostic  * about four machine instructions and can be done on-the-fly with about an
202b47d4dc5Sbostic  * 8% performance penalty.
203ebc0fb5aSbostic  */
204b47d4dc5Sbostic 
205ebc0fb5aSbostic typedef union {
206ebc0fb5aSbostic 	unsigned char b[8];
207ebc0fb5aSbostic 	struct {
208ebc0fb5aSbostic #if defined(LONG_IS_32_BITS)
209ebc0fb5aSbostic 		/* long is often faster than a 32-bit bit field */
210ebc0fb5aSbostic 		long	i0;
211ebc0fb5aSbostic 		long	i1;
212ebc0fb5aSbostic #else
213ebc0fb5aSbostic 		long	i0: 32;
214ebc0fb5aSbostic 		long	i1: 32;
215ebc0fb5aSbostic #endif
216ebc0fb5aSbostic 	} b32;
217ebc0fb5aSbostic #if defined(B64)
218ebc0fb5aSbostic 	B64	b64;
219ebc0fb5aSbostic #endif
220ebc0fb5aSbostic } C_block;
221ebc0fb5aSbostic 
222ebc0fb5aSbostic /*
223ebc0fb5aSbostic  * Convert twenty-four-bit long in host-order
224ebc0fb5aSbostic  * to six bits (and 2 low-order zeroes) per char little-endian format.
225ebc0fb5aSbostic  */
226ebc0fb5aSbostic #define	TO_SIX_BIT(rslt, src) {				\
227ebc0fb5aSbostic 		C_block cvt;				\
228ebc0fb5aSbostic 		cvt.b[0] = src; src >>= 6;		\
229ebc0fb5aSbostic 		cvt.b[1] = src; src >>= 6;		\
230ebc0fb5aSbostic 		cvt.b[2] = src; src >>= 6;		\
231ebc0fb5aSbostic 		cvt.b[3] = src;				\
232ebc0fb5aSbostic 		rslt = (cvt.b32.i0 & 0x3f3f3f3fL) << 2;	\
233ebc0fb5aSbostic 	}
234ebc0fb5aSbostic 
235ebc0fb5aSbostic /*
236ebc0fb5aSbostic  * These macros may someday permit efficient use of 64-bit integers.
237ebc0fb5aSbostic  */
238ebc0fb5aSbostic #define	ZERO(d,d0,d1)			d0 = 0, d1 = 0
239ebc0fb5aSbostic #define	LOAD(d,d0,d1,bl)		d0 = (bl).b32.i0, d1 = (bl).b32.i1
240ebc0fb5aSbostic #define	LOADREG(d,d0,d1,s,s0,s1)	d0 = s0, d1 = s1
241ebc0fb5aSbostic #define	OR(d,d0,d1,bl)			d0 |= (bl).b32.i0, d1 |= (bl).b32.i1
242ebc0fb5aSbostic #define	STORE(s,s0,s1,bl)		(bl).b32.i0 = s0, (bl).b32.i1 = s1
243ebc0fb5aSbostic #define	DCL_BLOCK(d,d0,d1)		long d0, d1
244ebc0fb5aSbostic 
245ebc0fb5aSbostic #if defined(LARGEDATA)
246ebc0fb5aSbostic 	/* Waste memory like crazy.  Also, do permutations in line */
247ebc0fb5aSbostic #define	LGCHUNKBITS	3
248ebc0fb5aSbostic #define	CHUNKBITS	(1<<LGCHUNKBITS)
249ebc0fb5aSbostic #define	PERM6464(d,d0,d1,cpp,p)				\
250ebc0fb5aSbostic 	LOAD(d,d0,d1,(p)[(0<<CHUNKBITS)+(cpp)[0]]);		\
251ebc0fb5aSbostic 	OR (d,d0,d1,(p)[(1<<CHUNKBITS)+(cpp)[1]]);		\
252ebc0fb5aSbostic 	OR (d,d0,d1,(p)[(2<<CHUNKBITS)+(cpp)[2]]);		\
253ebc0fb5aSbostic 	OR (d,d0,d1,(p)[(3<<CHUNKBITS)+(cpp)[3]]);		\
254ebc0fb5aSbostic 	OR (d,d0,d1,(p)[(4<<CHUNKBITS)+(cpp)[4]]);		\
255ebc0fb5aSbostic 	OR (d,d0,d1,(p)[(5<<CHUNKBITS)+(cpp)[5]]);		\
256ebc0fb5aSbostic 	OR (d,d0,d1,(p)[(6<<CHUNKBITS)+(cpp)[6]]);		\
257ebc0fb5aSbostic 	OR (d,d0,d1,(p)[(7<<CHUNKBITS)+(cpp)[7]]);
258ebc0fb5aSbostic #define	PERM3264(d,d0,d1,cpp,p)				\
259ebc0fb5aSbostic 	LOAD(d,d0,d1,(p)[(0<<CHUNKBITS)+(cpp)[0]]);		\
260ebc0fb5aSbostic 	OR (d,d0,d1,(p)[(1<<CHUNKBITS)+(cpp)[1]]);		\
261ebc0fb5aSbostic 	OR (d,d0,d1,(p)[(2<<CHUNKBITS)+(cpp)[2]]);		\
262ebc0fb5aSbostic 	OR (d,d0,d1,(p)[(3<<CHUNKBITS)+(cpp)[3]]);
263ebc0fb5aSbostic #else
264ebc0fb5aSbostic 	/* "small data" */
265ebc0fb5aSbostic #define	LGCHUNKBITS	2
266ebc0fb5aSbostic #define	CHUNKBITS	(1<<LGCHUNKBITS)
267ebc0fb5aSbostic #define	PERM6464(d,d0,d1,cpp,p)				\
268ebc0fb5aSbostic 	{ C_block tblk; permute(cpp,&tblk,p,8); LOAD (d,d0,d1,tblk); }
269ebc0fb5aSbostic #define	PERM3264(d,d0,d1,cpp,p)				\
270ebc0fb5aSbostic 	{ C_block tblk; permute(cpp,&tblk,p,4); LOAD (d,d0,d1,tblk); }
271ebc0fb5aSbostic 
272ebc0fb5aSbostic STATIC
permute(cp,out,p,chars_in)273ebc0fb5aSbostic permute(cp, out, p, chars_in)
274ebc0fb5aSbostic 	unsigned char *cp;
275ebc0fb5aSbostic 	C_block *out;
276ebc0fb5aSbostic 	register C_block *p;
277ebc0fb5aSbostic 	int chars_in;
278ebc0fb5aSbostic {
279ebc0fb5aSbostic 	register DCL_BLOCK(D,D0,D1);
280ebc0fb5aSbostic 	register C_block *tp;
281ebc0fb5aSbostic 	register int t;
282ebc0fb5aSbostic 
283ebc0fb5aSbostic 	ZERO(D,D0,D1);
284ebc0fb5aSbostic 	do {
285ebc0fb5aSbostic 		t = *cp++;
286ebc0fb5aSbostic 		tp = &p[t&0xf]; OR(D,D0,D1,*tp); p += (1<<CHUNKBITS);
287ebc0fb5aSbostic 		tp = &p[t>>4];  OR(D,D0,D1,*tp); p += (1<<CHUNKBITS);
288ebc0fb5aSbostic 	} while (--chars_in > 0);
289ebc0fb5aSbostic 	STORE(D,D0,D1,*out);
290ebc0fb5aSbostic }
291ebc0fb5aSbostic #endif /* LARGEDATA */
292ebc0fb5aSbostic 
293ebc0fb5aSbostic 
294ebc0fb5aSbostic /* =====  (mostly) Standard DES Tables ==================== */
295ebc0fb5aSbostic 
296ebc0fb5aSbostic static unsigned char IP[] = {		/* initial permutation */
29785ac702bSwnj 	58, 50, 42, 34, 26, 18, 10,  2,
29885ac702bSwnj 	60, 52, 44, 36, 28, 20, 12,  4,
29985ac702bSwnj 	62, 54, 46, 38, 30, 22, 14,  6,
30085ac702bSwnj 	64, 56, 48, 40, 32, 24, 16,  8,
30185ac702bSwnj 	57, 49, 41, 33, 25, 17,  9,  1,
30285ac702bSwnj 	59, 51, 43, 35, 27, 19, 11,  3,
30385ac702bSwnj 	61, 53, 45, 37, 29, 21, 13,  5,
30485ac702bSwnj 	63, 55, 47, 39, 31, 23, 15,  7,
30585ac702bSwnj };
30685ac702bSwnj 
307ebc0fb5aSbostic /* The final permutation is the inverse of IP - no table is necessary */
30885ac702bSwnj 
309ebc0fb5aSbostic static unsigned char ExpandTr[] = {	/* expansion operation */
31019c91eebSralph 	32,  1,  2,  3,  4,  5,
31119c91eebSralph 	 4,  5,  6,  7,  8,  9,
31219c91eebSralph 	 8,  9, 10, 11, 12, 13,
31319c91eebSralph 	12, 13, 14, 15, 16, 17,
31419c91eebSralph 	16, 17, 18, 19, 20, 21,
31519c91eebSralph 	20, 21, 22, 23, 24, 25,
31619c91eebSralph 	24, 25, 26, 27, 28, 29,
31719c91eebSralph 	28, 29, 30, 31, 32,  1,
31819c91eebSralph };
31919c91eebSralph 
3204514fd74Sbostic static unsigned char PC1[] = {		/* permuted choice table 1 */
321ebc0fb5aSbostic 	57, 49, 41, 33, 25, 17,  9,
322ebc0fb5aSbostic 	 1, 58, 50, 42, 34, 26, 18,
323ebc0fb5aSbostic 	10,  2, 59, 51, 43, 35, 27,
324ebc0fb5aSbostic 	19, 11,  3, 60, 52, 44, 36,
32585ac702bSwnj 
326ebc0fb5aSbostic 	63, 55, 47, 39, 31, 23, 15,
327ebc0fb5aSbostic 	 7, 62, 54, 46, 38, 30, 22,
328ebc0fb5aSbostic 	14,  6, 61, 53, 45, 37, 29,
329ebc0fb5aSbostic 	21, 13,  5, 28, 20, 12,  4,
330ebc0fb5aSbostic };
33185ac702bSwnj 
3324514fd74Sbostic static unsigned char Rotates[] = {	/* PC1 rotation schedule */
333ebc0fb5aSbostic 	1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1,
334ebc0fb5aSbostic };
33585ac702bSwnj 
336ebc0fb5aSbostic /* note: each "row" of PC2 is left-padded with bits that make it invertible */
3374514fd74Sbostic static unsigned char PC2[] = {		/* permuted choice table 2 */
338ebc0fb5aSbostic 	 9, 18,    14, 17, 11, 24,  1,  5,
339ebc0fb5aSbostic 	22, 25,     3, 28, 15,  6, 21, 10,
340ebc0fb5aSbostic 	35, 38,    23, 19, 12,  4, 26,  8,
341ebc0fb5aSbostic 	43, 54,    16,  7, 27, 20, 13,  2,
34285ac702bSwnj 
343ebc0fb5aSbostic 	 0,  0,    41, 52, 31, 37, 47, 55,
344ebc0fb5aSbostic 	 0,  0,    30, 40, 51, 45, 33, 48,
345ebc0fb5aSbostic 	 0,  0,    44, 49, 39, 56, 34, 53,
346ebc0fb5aSbostic 	 0,  0,    46, 42, 50, 36, 29, 32,
347ebc0fb5aSbostic };
348ebc0fb5aSbostic 
349ebc0fb5aSbostic static unsigned char S[8][64] = {	/* 48->32 bit substitution tables */
350ebc0fb5aSbostic 					/* S[1]			*/
35185ac702bSwnj 	14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7,
35285ac702bSwnj 	 0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8,
35385ac702bSwnj 	 4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0,
35485ac702bSwnj 	15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13,
355ebc0fb5aSbostic 					/* S[2]			*/
35685ac702bSwnj 	15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10,
35785ac702bSwnj 	 3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5,
35885ac702bSwnj 	 0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15,
35985ac702bSwnj 	13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9,
360ebc0fb5aSbostic 					/* S[3]			*/
36185ac702bSwnj 	10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8,
36285ac702bSwnj 	13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1,
36385ac702bSwnj 	13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7,
36485ac702bSwnj 	 1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12,
365ebc0fb5aSbostic 					/* S[4]			*/
36685ac702bSwnj 	 7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15,
36785ac702bSwnj 	13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9,
36885ac702bSwnj 	10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4,
36985ac702bSwnj 	 3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14,
370ebc0fb5aSbostic 					/* S[5]			*/
37185ac702bSwnj 	 2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9,
37285ac702bSwnj 	14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6,
37385ac702bSwnj 	 4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14,
37485ac702bSwnj 	11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3,
375ebc0fb5aSbostic 					/* S[6]			*/
37685ac702bSwnj 	12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11,
37785ac702bSwnj 	10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8,
37885ac702bSwnj 	 9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6,
37985ac702bSwnj 	 4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13,
380ebc0fb5aSbostic 					/* S[7]			*/
38185ac702bSwnj 	 4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1,
38285ac702bSwnj 	13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6,
38385ac702bSwnj 	 1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2,
38485ac702bSwnj 	 6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12,
385ebc0fb5aSbostic 					/* S[8]			*/
38685ac702bSwnj 	13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7,
38785ac702bSwnj 	 1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2,
38885ac702bSwnj 	 7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8,
38985ac702bSwnj 	 2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11,
39085ac702bSwnj };
39185ac702bSwnj 
392ebc0fb5aSbostic static unsigned char P32Tr[] = {	/* 32-bit permutation function */
39385ac702bSwnj 	16,  7, 20, 21,
39485ac702bSwnj 	29, 12, 28, 17,
39585ac702bSwnj 	 1, 15, 23, 26,
39685ac702bSwnj 	 5, 18, 31, 10,
39785ac702bSwnj 	 2,  8, 24, 14,
39885ac702bSwnj 	32, 27,  3,  9,
39985ac702bSwnj 	19, 13, 30,  6,
40085ac702bSwnj 	22, 11,  4, 25,
40185ac702bSwnj };
40285ac702bSwnj 
403ebc0fb5aSbostic static unsigned char CIFP[] = {		/* compressed/interleaved permutation */
404ebc0fb5aSbostic 	 1,  2,  3,  4,   17, 18, 19, 20,
405ebc0fb5aSbostic 	 5,  6,  7,  8,   21, 22, 23, 24,
406ebc0fb5aSbostic 	 9, 10, 11, 12,   25, 26, 27, 28,
407ebc0fb5aSbostic 	13, 14, 15, 16,   29, 30, 31, 32,
408ebc0fb5aSbostic 
409ebc0fb5aSbostic 	33, 34, 35, 36,   49, 50, 51, 52,
410ebc0fb5aSbostic 	37, 38, 39, 40,   53, 54, 55, 56,
411ebc0fb5aSbostic 	41, 42, 43, 44,   57, 58, 59, 60,
412ebc0fb5aSbostic 	45, 46, 47, 48,   61, 62, 63, 64,
413ebc0fb5aSbostic };
414ebc0fb5aSbostic 
415ebc0fb5aSbostic static unsigned char itoa64[] =		/* 0..63 => ascii-64 */
416ebc0fb5aSbostic 	"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
417ebc0fb5aSbostic 
418ebc0fb5aSbostic 
419ebc0fb5aSbostic /* =====  Tables that are initialized at run time  ==================== */
420ebc0fb5aSbostic 
421ebc0fb5aSbostic 
422ebc0fb5aSbostic static unsigned char a64toi[128];	/* ascii-64 => 0..63 */
423ebc0fb5aSbostic 
424ebc0fb5aSbostic /* Initial key schedule permutation */
425ebc0fb5aSbostic static C_block	PC1ROT[64/CHUNKBITS][1<<CHUNKBITS];
426ebc0fb5aSbostic 
427ebc0fb5aSbostic /* Subsequent key schedule rotation permutations */
428ebc0fb5aSbostic static C_block	PC2ROT[2][64/CHUNKBITS][1<<CHUNKBITS];
429ebc0fb5aSbostic 
430ebc0fb5aSbostic /* Initial permutation/expansion table */
431ebc0fb5aSbostic static C_block	IE3264[32/CHUNKBITS][1<<CHUNKBITS];
432ebc0fb5aSbostic 
433ebc0fb5aSbostic /* Table that combines the S, P, and E operations.  */
434ebc0fb5aSbostic static long SPE[2][8][64];
435ebc0fb5aSbostic 
436ebc0fb5aSbostic /* compressed/interleaved => final permutation table */
437ebc0fb5aSbostic static C_block	CF6464[64/CHUNKBITS][1<<CHUNKBITS];
438ebc0fb5aSbostic 
439ebc0fb5aSbostic 
440ebc0fb5aSbostic /* ==================================== */
441ebc0fb5aSbostic 
442ebc0fb5aSbostic 
443ebc0fb5aSbostic static C_block	constdatablock;			/* encryption constant */
444ebc0fb5aSbostic static char	cryptresult[1+4+4+11+1];	/* encrypted result */
44585ac702bSwnj 
44685ac702bSwnj /*
447b47d4dc5Sbostic  * Return a pointer to static data consisting of the "setting"
448b47d4dc5Sbostic  * followed by an encryption produced by the "key" and "setting".
44985ac702bSwnj  */
45085ac702bSwnj char *
crypt(key,setting)451ebc0fb5aSbostic crypt(key, setting)
452ebc0fb5aSbostic 	register const char *key;
453ebc0fb5aSbostic 	register const char *setting;
45485ac702bSwnj {
455ebc0fb5aSbostic 	register char *encp;
456ebc0fb5aSbostic 	register long i;
457b47d4dc5Sbostic 	register int t;
458ebc0fb5aSbostic 	long salt;
4594514fd74Sbostic 	int num_iter, salt_size;
460ebc0fb5aSbostic 	C_block keyblock, rsltblock;
46119c91eebSralph 
462b47d4dc5Sbostic 	for (i = 0; i < 8; i++) {
463b47d4dc5Sbostic 		if ((t = 2*(unsigned char)(*key)) != 0)
464ebc0fb5aSbostic 			key++;
465b47d4dc5Sbostic 		keyblock.b[i] = t;
466b47d4dc5Sbostic 	}
46789b81385Sbostic 	if (des_setkey((char *)keyblock.b))	/* also initializes "a64toi" */
46889b81385Sbostic 		return (NULL);
469ebc0fb5aSbostic 
470ebc0fb5aSbostic 	encp = &cryptresult[0];
471870683b6Sbostic 	switch (*setting) {
472870683b6Sbostic 	case _PASSWORD_EFMT1:
4734514fd74Sbostic 		/*
4744514fd74Sbostic 		 * Involve the rest of the password 8 characters at a time.
4754514fd74Sbostic 		 */
4764514fd74Sbostic 		while (*key) {
4774514fd74Sbostic 			if (des_cipher((char *)&keyblock,
4784514fd74Sbostic 			    (char *)&keyblock, 0L, 1))
4794514fd74Sbostic 				return (NULL);
4804514fd74Sbostic 			for (i = 0; i < 8; i++) {
4814514fd74Sbostic 				if ((t = 2*(unsigned char)(*key)) != 0)
4824514fd74Sbostic 					key++;
4834514fd74Sbostic 				keyblock.b[i] ^= t;
4844514fd74Sbostic 			}
4854514fd74Sbostic 			if (des_setkey((char *)keyblock.b))
4865e87113eSkarels 				return (NULL);
4874514fd74Sbostic 		}
4884514fd74Sbostic 
489ebc0fb5aSbostic 		*encp++ = *setting++;
490ebc0fb5aSbostic 
491ebc0fb5aSbostic 		/* get iteration count */
492ebc0fb5aSbostic 		num_iter = 0;
493ebc0fb5aSbostic 		for (i = 4; --i >= 0; ) {
494b47d4dc5Sbostic 			if ((t = (unsigned char)setting[i]) == '\0')
495b47d4dc5Sbostic 				t = '.';
496b47d4dc5Sbostic 			encp[i] = t;
497b47d4dc5Sbostic 			num_iter = (num_iter<<6) | a64toi[t];
498ebc0fb5aSbostic 		}
499ebc0fb5aSbostic 		setting += 4;
500ebc0fb5aSbostic 		encp += 4;
501ebc0fb5aSbostic 		salt_size = 4;
502870683b6Sbostic 		break;
503870683b6Sbostic 	default:
504870683b6Sbostic 		num_iter = 25;
505870683b6Sbostic 		salt_size = 2;
50685ac702bSwnj 	}
50785ac702bSwnj 
508ebc0fb5aSbostic 	salt = 0;
509ebc0fb5aSbostic 	for (i = salt_size; --i >= 0; ) {
510b47d4dc5Sbostic 		if ((t = (unsigned char)setting[i]) == '\0')
511b47d4dc5Sbostic 			t = '.';
512b47d4dc5Sbostic 		encp[i] = t;
513b47d4dc5Sbostic 		salt = (salt<<6) | a64toi[t];
514ebc0fb5aSbostic 	}
515ebc0fb5aSbostic 	encp += salt_size;
51689b81385Sbostic 	if (des_cipher((char *)&constdatablock, (char *)&rsltblock,
51789b81385Sbostic 	    salt, num_iter))
51889b81385Sbostic 		return (NULL);
51985ac702bSwnj 
520ebc0fb5aSbostic 	/*
521ebc0fb5aSbostic 	 * Encode the 64 cipher bits as 11 ascii characters.
522ebc0fb5aSbostic 	 */
523ebc0fb5aSbostic 	i = ((long)((rsltblock.b[0]<<8) | rsltblock.b[1])<<8) | rsltblock.b[2];
524ebc0fb5aSbostic 	encp[3] = itoa64[i&0x3f];	i >>= 6;
525ebc0fb5aSbostic 	encp[2] = itoa64[i&0x3f];	i >>= 6;
526ebc0fb5aSbostic 	encp[1] = itoa64[i&0x3f];	i >>= 6;
527ebc0fb5aSbostic 	encp[0] = itoa64[i];		encp += 4;
528ebc0fb5aSbostic 	i = ((long)((rsltblock.b[3]<<8) | rsltblock.b[4])<<8) | rsltblock.b[5];
529ebc0fb5aSbostic 	encp[3] = itoa64[i&0x3f];	i >>= 6;
530ebc0fb5aSbostic 	encp[2] = itoa64[i&0x3f];	i >>= 6;
531ebc0fb5aSbostic 	encp[1] = itoa64[i&0x3f];	i >>= 6;
532ebc0fb5aSbostic 	encp[0] = itoa64[i];		encp += 4;
533ebc0fb5aSbostic 	i = ((long)((rsltblock.b[6])<<8) | rsltblock.b[7])<<2;
534ebc0fb5aSbostic 	encp[2] = itoa64[i&0x3f];	i >>= 6;
535ebc0fb5aSbostic 	encp[1] = itoa64[i&0x3f];	i >>= 6;
536ebc0fb5aSbostic 	encp[0] = itoa64[i];
537ebc0fb5aSbostic 
538ebc0fb5aSbostic 	encp[3] = 0;
539b47d4dc5Sbostic 
540ebc0fb5aSbostic 	return (cryptresult);
541ebc0fb5aSbostic }
542ebc0fb5aSbostic 
543ebc0fb5aSbostic 
544ebc0fb5aSbostic /*
545ebc0fb5aSbostic  * The Key Schedule, filled in by des_setkey() or setkey().
546ebc0fb5aSbostic  */
547ebc0fb5aSbostic #define	KS_SIZE	16
548ebc0fb5aSbostic static C_block	KS[KS_SIZE];
549ebc0fb5aSbostic 
550ebc0fb5aSbostic /*
551ebc0fb5aSbostic  * Set up the key schedule from the key.
552ebc0fb5aSbostic  */
des_setkey(key)553ebc0fb5aSbostic des_setkey(key)
554ebc0fb5aSbostic 	register const char *key;
555ebc0fb5aSbostic {
556ebc0fb5aSbostic 	register DCL_BLOCK(K, K0, K1);
557ebc0fb5aSbostic 	register C_block *ptabp;
558ebc0fb5aSbostic 	register int i;
559ebc0fb5aSbostic 	static int des_ready = 0;
560ebc0fb5aSbostic 
561ebc0fb5aSbostic 	if (!des_ready) {
562ebc0fb5aSbostic 		init_des();
563ebc0fb5aSbostic 		des_ready = 1;
564ebc0fb5aSbostic 	}
565ebc0fb5aSbostic 
566ebc0fb5aSbostic 	PERM6464(K,K0,K1,(unsigned char *)key,(C_block *)PC1ROT);
567ebc0fb5aSbostic 	key = (char *)&KS[0];
5684514fd74Sbostic 	STORE(K&~0x03030303L, K0&~0x03030303L, K1, *(C_block *)key);
569ebc0fb5aSbostic 	for (i = 1; i < 16; i++) {
570ebc0fb5aSbostic 		key += sizeof(C_block);
571ebc0fb5aSbostic 		STORE(K,K0,K1,*(C_block *)key);
572ebc0fb5aSbostic 		ptabp = (C_block *)PC2ROT[Rotates[i]-1];
573ebc0fb5aSbostic 		PERM6464(K,K0,K1,(unsigned char *)key,ptabp);
5744514fd74Sbostic 		STORE(K&~0x03030303L, K0&~0x03030303L, K1, *(C_block *)key);
575ebc0fb5aSbostic 	}
57689b81385Sbostic 	return (0);
577ebc0fb5aSbostic }
578ebc0fb5aSbostic 
579ebc0fb5aSbostic /*
580ebc0fb5aSbostic  * Encrypt (or decrypt if num_iter < 0) the 8 chars at "in" with abs(num_iter)
581ebc0fb5aSbostic  * iterations of DES, using the the given 24-bit salt and the pre-computed key
582ebc0fb5aSbostic  * schedule, and store the resulting 8 chars at "out" (in == out is permitted).
583ebc0fb5aSbostic  *
584ebc0fb5aSbostic  * NOTE: the performance of this routine is critically dependent on your
585ebc0fb5aSbostic  * compiler and machine architecture.
586ebc0fb5aSbostic  */
des_cipher(in,out,salt,num_iter)587ebc0fb5aSbostic des_cipher(in, out, salt, num_iter)
588ebc0fb5aSbostic 	const char *in;
589ebc0fb5aSbostic 	char *out;
590b47d4dc5Sbostic 	long salt;
591ebc0fb5aSbostic 	int num_iter;
592ebc0fb5aSbostic {
593ebc0fb5aSbostic 	/* variables that we want in registers, most important first */
594ebc0fb5aSbostic #if defined(pdp11)
595ebc0fb5aSbostic 	register int j;
596ebc0fb5aSbostic #endif
597ebc0fb5aSbostic 	register long L0, L1, R0, R1, k;
598ebc0fb5aSbostic 	register C_block *kp;
599ebc0fb5aSbostic 	register int ks_inc, loop_count;
600ebc0fb5aSbostic 	C_block B;
601ebc0fb5aSbostic 
602ebc0fb5aSbostic 	L0 = salt;
6034514fd74Sbostic 	TO_SIX_BIT(salt, L0);	/* convert to 4*(6+2) format */
604ebc0fb5aSbostic 
605ebc0fb5aSbostic #if defined(vax) || defined(pdp11)
606ebc0fb5aSbostic 	salt = ~salt;	/* "x &~ y" is faster than "x & y". */
607ebc0fb5aSbostic #define	SALT (~salt)
608ebc0fb5aSbostic #else
609ebc0fb5aSbostic #define	SALT salt
610ebc0fb5aSbostic #endif
611ebc0fb5aSbostic 
612ebc0fb5aSbostic #if defined(MUST_ALIGN)
613ebc0fb5aSbostic 	B.b[0] = in[0]; B.b[1] = in[1]; B.b[2] = in[2]; B.b[3] = in[3];
614ebc0fb5aSbostic 	B.b[4] = in[4]; B.b[5] = in[5]; B.b[6] = in[6]; B.b[7] = in[7];
615ebc0fb5aSbostic 	LOAD(L,L0,L1,B);
616ebc0fb5aSbostic #else
617ebc0fb5aSbostic 	LOAD(L,L0,L1,*(C_block *)in);
618ebc0fb5aSbostic #endif
619ebc0fb5aSbostic 	LOADREG(R,R0,R1,L,L0,L1);
620ebc0fb5aSbostic 	L0 &= 0x55555555L;
621ebc0fb5aSbostic 	L1 &= 0x55555555L;
622ebc0fb5aSbostic 	L0 = (L0 << 1) | L1;	/* L0 is the even-numbered input bits */
623ebc0fb5aSbostic 	R0 &= 0xaaaaaaaaL;
624ebc0fb5aSbostic 	R1 = (R1 >> 1) & 0x55555555L;
625ebc0fb5aSbostic 	L1 = R0 | R1;		/* L1 is the odd-numbered input bits */
626ebc0fb5aSbostic 	STORE(L,L0,L1,B);
627ebc0fb5aSbostic 	PERM3264(L,L0,L1,B.b,  (C_block *)IE3264);	/* even bits */
628ebc0fb5aSbostic 	PERM3264(R,R0,R1,B.b+4,(C_block *)IE3264);	/* odd bits */
629ebc0fb5aSbostic 
630ebc0fb5aSbostic 	if (num_iter >= 0)
631ebc0fb5aSbostic 	{		/* encryption */
632ebc0fb5aSbostic 		kp = &KS[0];
633ebc0fb5aSbostic 		ks_inc  = sizeof(*kp);
634ebc0fb5aSbostic 	}
635ebc0fb5aSbostic 	else
636ebc0fb5aSbostic 	{		/* decryption */
637*eecd7825Smckusick 		return (1); /* always fail */
638ebc0fb5aSbostic 	}
639ebc0fb5aSbostic 
640ebc0fb5aSbostic 	while (--num_iter >= 0) {
641ebc0fb5aSbostic 		loop_count = 8;
642ebc0fb5aSbostic 		do {
643ebc0fb5aSbostic 
6444514fd74Sbostic #define	SPTAB(t, i)	(*(long *)((unsigned char *)t + i*(sizeof(long)/4)))
645ebc0fb5aSbostic #if defined(gould)
6464514fd74Sbostic 			/* use this if B.b[i] is evaluated just once ... */
6474514fd74Sbostic #define	DOXOR(x,y,i)	x^=SPTAB(SPE[0][i],B.b[i]); y^=SPTAB(SPE[1][i],B.b[i]);
648ebc0fb5aSbostic #else
649ebc0fb5aSbostic #if defined(pdp11)
650ebc0fb5aSbostic 			/* use this if your "long" int indexing is slow */
6514514fd74Sbostic #define	DOXOR(x,y,i)	j=B.b[i]; x^=SPTAB(SPE[0][i],j); y^=SPTAB(SPE[1][i],j);
652ebc0fb5aSbostic #else
653ebc0fb5aSbostic 			/* use this if "k" is allocated to a register ... */
6544514fd74Sbostic #define	DOXOR(x,y,i)	k=B.b[i]; x^=SPTAB(SPE[0][i],k); y^=SPTAB(SPE[1][i],k);
655ebc0fb5aSbostic #endif
656ebc0fb5aSbostic #endif
657ebc0fb5aSbostic 
6584514fd74Sbostic #define	CRUNCH(p0, p1, q0, q1)	\
6594514fd74Sbostic 			k = (q0 ^ q1) & SALT;	\
6604514fd74Sbostic 			B.b32.i0 = k ^ q0 ^ kp->b32.i0;		\
6614514fd74Sbostic 			B.b32.i1 = k ^ q1 ^ kp->b32.i1;		\
662ebc0fb5aSbostic 			kp = (C_block *)((char *)kp+ks_inc);	\
663ebc0fb5aSbostic 							\
6644514fd74Sbostic 			DOXOR(p0, p1, 0);		\
6654514fd74Sbostic 			DOXOR(p0, p1, 1);		\
6664514fd74Sbostic 			DOXOR(p0, p1, 2);		\
6674514fd74Sbostic 			DOXOR(p0, p1, 3);		\
6684514fd74Sbostic 			DOXOR(p0, p1, 4);		\
6694514fd74Sbostic 			DOXOR(p0, p1, 5);		\
6704514fd74Sbostic 			DOXOR(p0, p1, 6);		\
6714514fd74Sbostic 			DOXOR(p0, p1, 7);
672ebc0fb5aSbostic 
673ebc0fb5aSbostic 			CRUNCH(L0, L1, R0, R1);
674ebc0fb5aSbostic 			CRUNCH(R0, R1, L0, L1);
675ebc0fb5aSbostic 		} while (--loop_count != 0);
676ebc0fb5aSbostic 		kp = (C_block *)((char *)kp-(ks_inc*KS_SIZE));
677ebc0fb5aSbostic 
678ebc0fb5aSbostic 
679ebc0fb5aSbostic 		/* swap L and R */
680ebc0fb5aSbostic 		L0 ^= R0;  L1 ^= R1;
681ebc0fb5aSbostic 		R0 ^= L0;  R1 ^= L1;
682ebc0fb5aSbostic 		L0 ^= R0;  L1 ^= R1;
683ebc0fb5aSbostic 	}
684ebc0fb5aSbostic 
685ebc0fb5aSbostic 	/* store the encrypted (or decrypted) result */
686ebc0fb5aSbostic 	L0 = ((L0 >> 3) & 0x0f0f0f0fL) | ((L1 << 1) & 0xf0f0f0f0L);
687ebc0fb5aSbostic 	L1 = ((R0 >> 3) & 0x0f0f0f0fL) | ((R1 << 1) & 0xf0f0f0f0L);
688ebc0fb5aSbostic 	STORE(L,L0,L1,B);
689ebc0fb5aSbostic 	PERM6464(L,L0,L1,B.b, (C_block *)CF6464);
690ebc0fb5aSbostic #if defined(MUST_ALIGN)
691ebc0fb5aSbostic 	STORE(L,L0,L1,B);
692ebc0fb5aSbostic 	out[0] = B.b[0]; out[1] = B.b[1]; out[2] = B.b[2]; out[3] = B.b[3];
693ebc0fb5aSbostic 	out[4] = B.b[4]; out[5] = B.b[5]; out[6] = B.b[6]; out[7] = B.b[7];
694ebc0fb5aSbostic #else
695ebc0fb5aSbostic 	STORE(L,L0,L1,*(C_block *)out);
696ebc0fb5aSbostic #endif
69789b81385Sbostic 	return (0);
698ebc0fb5aSbostic }
699ebc0fb5aSbostic 
700ebc0fb5aSbostic 
701ebc0fb5aSbostic /*
702ebc0fb5aSbostic  * Initialize various tables.  This need only be done once.  It could even be
703ebc0fb5aSbostic  * done at compile time, if the compiler were capable of that sort of thing.
704ebc0fb5aSbostic  */
705ebc0fb5aSbostic STATIC
init_des()706ebc0fb5aSbostic init_des()
707ebc0fb5aSbostic {
708ebc0fb5aSbostic 	register int i, j;
709ebc0fb5aSbostic 	register long k;
710ebc0fb5aSbostic 	register int tableno;
711ebc0fb5aSbostic 	static unsigned char perm[64], tmp32[32];	/* "static" for speed */
712ebc0fb5aSbostic 
713ebc0fb5aSbostic 	/*
714ebc0fb5aSbostic 	 * table that converts chars "./0-9A-Za-z"to integers 0-63.
715ebc0fb5aSbostic 	 */
716ebc0fb5aSbostic 	for (i = 0; i < 64; i++)
717ebc0fb5aSbostic 		a64toi[itoa64[i]] = i;
718ebc0fb5aSbostic 
719ebc0fb5aSbostic 	/*
720ebc0fb5aSbostic 	 * PC1ROT - bit reverse, then PC1, then Rotate, then PC2.
721ebc0fb5aSbostic 	 */
722ebc0fb5aSbostic 	for (i = 0; i < 64; i++)
723ebc0fb5aSbostic 		perm[i] = 0;
724ebc0fb5aSbostic 	for (i = 0; i < 64; i++) {
725ebc0fb5aSbostic 		if ((k = PC2[i]) == 0)
726ebc0fb5aSbostic 			continue;
727ebc0fb5aSbostic 		k += Rotates[0]-1;
728ebc0fb5aSbostic 		if ((k%28) < Rotates[0]) k -= 28;
729ebc0fb5aSbostic 		k = PC1[k];
730ebc0fb5aSbostic 		if (k > 0) {
731ebc0fb5aSbostic 			k--;
732ebc0fb5aSbostic 			k = (k|07) - (k&07);
733ebc0fb5aSbostic 			k++;
734ebc0fb5aSbostic 		}
735ebc0fb5aSbostic 		perm[i] = k;
736ebc0fb5aSbostic 	}
737ebc0fb5aSbostic #ifdef DEBUG
738ebc0fb5aSbostic 	prtab("pc1tab", perm, 8);
739ebc0fb5aSbostic #endif
740b47d4dc5Sbostic 	init_perm(PC1ROT, perm, 8, 8);
741ebc0fb5aSbostic 
742ebc0fb5aSbostic 	/*
743ebc0fb5aSbostic 	 * PC2ROT - PC2 inverse, then Rotate (once or twice), then PC2.
744ebc0fb5aSbostic 	 */
745ebc0fb5aSbostic 	for (j = 0; j < 2; j++) {
746ebc0fb5aSbostic 		unsigned char pc2inv[64];
747ebc0fb5aSbostic 		for (i = 0; i < 64; i++)
748ebc0fb5aSbostic 			perm[i] = pc2inv[i] = 0;
749ebc0fb5aSbostic 		for (i = 0; i < 64; i++) {
750ebc0fb5aSbostic 			if ((k = PC2[i]) == 0)
751ebc0fb5aSbostic 				continue;
752ebc0fb5aSbostic 			pc2inv[k-1] = i+1;
753ebc0fb5aSbostic 		}
754ebc0fb5aSbostic 		for (i = 0; i < 64; i++) {
755ebc0fb5aSbostic 			if ((k = PC2[i]) == 0)
756ebc0fb5aSbostic 				continue;
757ebc0fb5aSbostic 			k += j;
758ebc0fb5aSbostic 			if ((k%28) <= j) k -= 28;
759ebc0fb5aSbostic 			perm[i] = pc2inv[k];
760ebc0fb5aSbostic 		}
761ebc0fb5aSbostic #ifdef DEBUG
762ebc0fb5aSbostic 		prtab("pc2tab", perm, 8);
763ebc0fb5aSbostic #endif
764b47d4dc5Sbostic 		init_perm(PC2ROT[j], perm, 8, 8);
765ebc0fb5aSbostic 	}
766ebc0fb5aSbostic 
767ebc0fb5aSbostic 	/*
768ebc0fb5aSbostic 	 * Bit reverse, then initial permutation, then expansion.
769ebc0fb5aSbostic 	 */
770ebc0fb5aSbostic 	for (i = 0; i < 8; i++) {
771ebc0fb5aSbostic 		for (j = 0; j < 8; j++) {
772ebc0fb5aSbostic 			k = (j < 2)? 0: IP[ExpandTr[i*6+j-2]-1];
773ebc0fb5aSbostic 			if (k > 32)
774ebc0fb5aSbostic 				k -= 32;
775ebc0fb5aSbostic 			else if (k > 0)
776ebc0fb5aSbostic 				k--;
777ebc0fb5aSbostic 			if (k > 0) {
778ebc0fb5aSbostic 				k--;
779ebc0fb5aSbostic 				k = (k|07) - (k&07);
780ebc0fb5aSbostic 				k++;
781ebc0fb5aSbostic 			}
782ebc0fb5aSbostic 			perm[i*8+j] = k;
783ebc0fb5aSbostic 		}
784ebc0fb5aSbostic 	}
785ebc0fb5aSbostic #ifdef DEBUG
786ebc0fb5aSbostic 	prtab("ietab", perm, 8);
787ebc0fb5aSbostic #endif
788b47d4dc5Sbostic 	init_perm(IE3264, perm, 4, 8);
789ebc0fb5aSbostic 
790ebc0fb5aSbostic 	/*
791ebc0fb5aSbostic 	 * Compression, then final permutation, then bit reverse.
792ebc0fb5aSbostic 	 */
793ebc0fb5aSbostic 	for (i = 0; i < 64; i++) {
794ebc0fb5aSbostic 		k = IP[CIFP[i]-1];
795ebc0fb5aSbostic 		if (k > 0) {
796ebc0fb5aSbostic 			k--;
797ebc0fb5aSbostic 			k = (k|07) - (k&07);
798ebc0fb5aSbostic 			k++;
799ebc0fb5aSbostic 		}
800ebc0fb5aSbostic 		perm[k-1] = i+1;
801ebc0fb5aSbostic 	}
802ebc0fb5aSbostic #ifdef DEBUG
803ebc0fb5aSbostic 	prtab("cftab", perm, 8);
804ebc0fb5aSbostic #endif
805b47d4dc5Sbostic 	init_perm(CF6464, perm, 8, 8);
806ebc0fb5aSbostic 
807ebc0fb5aSbostic 	/*
808ebc0fb5aSbostic 	 * SPE table
809ebc0fb5aSbostic 	 */
810ebc0fb5aSbostic 	for (i = 0; i < 48; i++)
811ebc0fb5aSbostic 		perm[i] = P32Tr[ExpandTr[i]-1];
812ebc0fb5aSbostic 	for (tableno = 0; tableno < 8; tableno++) {
813ebc0fb5aSbostic 		for (j = 0; j < 64; j++)  {
814ebc0fb5aSbostic 			k = (((j >> 0) &01) << 5)|
815ebc0fb5aSbostic 			    (((j >> 1) &01) << 3)|
816ebc0fb5aSbostic 			    (((j >> 2) &01) << 2)|
817ebc0fb5aSbostic 			    (((j >> 3) &01) << 1)|
818ebc0fb5aSbostic 			    (((j >> 4) &01) << 0)|
819ebc0fb5aSbostic 			    (((j >> 5) &01) << 4);
820ebc0fb5aSbostic 			k = S[tableno][k];
821ebc0fb5aSbostic 			k = (((k >> 3)&01) << 0)|
822ebc0fb5aSbostic 			    (((k >> 2)&01) << 1)|
823ebc0fb5aSbostic 			    (((k >> 1)&01) << 2)|
824ebc0fb5aSbostic 			    (((k >> 0)&01) << 3);
825ebc0fb5aSbostic 			for (i = 0; i < 32; i++)
826ebc0fb5aSbostic 				tmp32[i] = 0;
827ebc0fb5aSbostic 			for (i = 0; i < 4; i++)
828ebc0fb5aSbostic 				tmp32[4 * tableno + i] = (k >> i) & 01;
829ebc0fb5aSbostic 			k = 0;
830ebc0fb5aSbostic 			for (i = 24; --i >= 0; )
831ebc0fb5aSbostic 				k = (k<<1) | tmp32[perm[i]-1];
832ebc0fb5aSbostic 			TO_SIX_BIT(SPE[0][tableno][j], k);
833ebc0fb5aSbostic 			k = 0;
834ebc0fb5aSbostic 			for (i = 24; --i >= 0; )
835ebc0fb5aSbostic 				k = (k<<1) | tmp32[perm[i+24]-1];
836ebc0fb5aSbostic 			TO_SIX_BIT(SPE[1][tableno][j], k);
83785ac702bSwnj 		}
83885ac702bSwnj 	}
83985ac702bSwnj }
84085ac702bSwnj 
841ebc0fb5aSbostic /*
842b47d4dc5Sbostic  * Initialize "perm" to represent transformation "p", which rearranges
843b47d4dc5Sbostic  * (perhaps with expansion and/or contraction) one packed array of bits
844b47d4dc5Sbostic  * (of size "chars_in" characters) into another array (of size "chars_out"
845b47d4dc5Sbostic  * characters).
846b47d4dc5Sbostic  *
847ebc0fb5aSbostic  * "perm" must be all-zeroes on entry to this routine.
848ebc0fb5aSbostic  */
849ebc0fb5aSbostic STATIC
init_perm(perm,p,chars_in,chars_out)850b47d4dc5Sbostic init_perm(perm, p, chars_in, chars_out)
851ebc0fb5aSbostic 	C_block perm[64/CHUNKBITS][1<<CHUNKBITS];
852ebc0fb5aSbostic 	unsigned char p[64];
853ebc0fb5aSbostic 	int chars_in, chars_out;
854ebc0fb5aSbostic {
855ebc0fb5aSbostic 	register int i, j, k, l;
856ebc0fb5aSbostic 
857ebc0fb5aSbostic 	for (k = 0; k < chars_out*8; k++) {	/* each output bit position */
858ebc0fb5aSbostic 		l = p[k] - 1;		/* where this bit comes from */
859ebc0fb5aSbostic 		if (l < 0)
860ebc0fb5aSbostic 			continue;	/* output bit is always 0 */
861ebc0fb5aSbostic 		i = l>>LGCHUNKBITS;	/* which chunk this bit comes from */
862ebc0fb5aSbostic 		l = 1<<(l&(CHUNKBITS-1));	/* mask for this bit */
863ebc0fb5aSbostic 		for (j = 0; j < (1<<CHUNKBITS); j++) {	/* each chunk value */
864ebc0fb5aSbostic 			if ((j & l) != 0)
865ebc0fb5aSbostic 				perm[i][j].b[k>>3] |= 1<<(k&07);
86685ac702bSwnj 		}
86785ac702bSwnj 	}
86885ac702bSwnj }
869ebc0fb5aSbostic 
870ebc0fb5aSbostic /*
871ebc0fb5aSbostic  * "setkey" routine (for backwards compatibility)
872ebc0fb5aSbostic  */
setkey(key)873ebc0fb5aSbostic setkey(key)
874ebc0fb5aSbostic 	register const char *key;
875ebc0fb5aSbostic {
876ebc0fb5aSbostic 	register int i, j, k;
877ebc0fb5aSbostic 	C_block keyblock;
878ebc0fb5aSbostic 
879ebc0fb5aSbostic 	for (i = 0; i < 8; i++) {
880ebc0fb5aSbostic 		k = 0;
881ebc0fb5aSbostic 		for (j = 0; j < 8; j++) {
882ebc0fb5aSbostic 			k <<= 1;
883ebc0fb5aSbostic 			k |= (unsigned char)*key++;
884ebc0fb5aSbostic 		}
885ebc0fb5aSbostic 		keyblock.b[i] = k;
886ebc0fb5aSbostic 	}
88789b81385Sbostic 	return (des_setkey((char *)keyblock.b));
888ebc0fb5aSbostic }
889ebc0fb5aSbostic 
890ebc0fb5aSbostic /*
891ebc0fb5aSbostic  * "encrypt" routine (for backwards compatibility)
892ebc0fb5aSbostic  */
encrypt(block,flag)893ebc0fb5aSbostic encrypt(block, flag)
894ebc0fb5aSbostic 	register char *block;
895ebc0fb5aSbostic 	int flag;
896ebc0fb5aSbostic {
897ebc0fb5aSbostic 	register int i, j, k;
898ebc0fb5aSbostic 	C_block cblock;
899ebc0fb5aSbostic 
900ebc0fb5aSbostic 	for (i = 0; i < 8; i++) {
901ebc0fb5aSbostic 		k = 0;
902ebc0fb5aSbostic 		for (j = 0; j < 8; j++) {
903ebc0fb5aSbostic 			k <<= 1;
904ebc0fb5aSbostic 			k |= (unsigned char)*block++;
905ebc0fb5aSbostic 		}
906ebc0fb5aSbostic 		cblock.b[i] = k;
907ebc0fb5aSbostic 	}
90889b81385Sbostic 	if (des_cipher((char *)&cblock, (char *)&cblock, 0L, (flag ? -1: 1)))
90989b81385Sbostic 		return (1);
910ebc0fb5aSbostic 	for (i = 7; i >= 0; i--) {
911ebc0fb5aSbostic 		k = cblock.b[i];
912ebc0fb5aSbostic 		for (j = 7; j >= 0; j--) {
913ebc0fb5aSbostic 			*--block = k&01;
914ebc0fb5aSbostic 			k >>= 1;
915ebc0fb5aSbostic 		}
916ebc0fb5aSbostic 	}
91789b81385Sbostic 	return (0);
918ebc0fb5aSbostic }
919ebc0fb5aSbostic 
920ebc0fb5aSbostic #ifdef DEBUG
921ebc0fb5aSbostic STATIC
prtab(s,t,num_rows)922ebc0fb5aSbostic prtab(s, t, num_rows)
923ebc0fb5aSbostic 	char *s;
924ebc0fb5aSbostic 	unsigned char *t;
925ebc0fb5aSbostic 	int num_rows;
926ebc0fb5aSbostic {
927ebc0fb5aSbostic 	register int i, j;
928ebc0fb5aSbostic 
929870683b6Sbostic 	(void)printf("%s:\n", s);
930ebc0fb5aSbostic 	for (i = 0; i < num_rows; i++) {
931ebc0fb5aSbostic 		for (j = 0; j < 8; j++) {
932870683b6Sbostic 			 (void)printf("%3d", t[i*8+j]);
933ebc0fb5aSbostic 		}
934870683b6Sbostic 		(void)printf("\n");
935ebc0fb5aSbostic 	}
936870683b6Sbostic 	(void)printf("\n");
937ebc0fb5aSbostic }
938ebc0fb5aSbostic #endif
939