xref: /netbsd-src/lib/libcrypt/crypt.c (revision 56545aba033aa8efa8d23f77b88d951993b8e840)
1*56545abaSkleink /*	$NetBSD: crypt.c,v 1.12 1998/06/01 20:25:24 kleink Exp $	*/
24902ac3dScgd 
3e0b9a84aScgd /*
44902ac3dScgd  * Copyright (c) 1989, 1993
54902ac3dScgd  *	The Regents of the University of California.  All rights reserved.
6e0b9a84aScgd  *
7e0b9a84aScgd  * This code is derived from software contributed to Berkeley by
8e0b9a84aScgd  * Tom Truscott.
9e0b9a84aScgd  *
10e0b9a84aScgd  * Redistribution and use in source and binary forms, with or without
11e0b9a84aScgd  * modification, are permitted provided that the following conditions
12e0b9a84aScgd  * are met:
13e0b9a84aScgd  * 1. Redistributions of source code must retain the above copyright
14e0b9a84aScgd  *    notice, this list of conditions and the following disclaimer.
15e0b9a84aScgd  * 2. Redistributions in binary form must reproduce the above copyright
16e0b9a84aScgd  *    notice, this list of conditions and the following disclaimer in the
17e0b9a84aScgd  *    documentation and/or other materials provided with the distribution.
18e0b9a84aScgd  * 3. All advertising materials mentioning features or use of this software
19e0b9a84aScgd  *    must display the following acknowledgement:
20e0b9a84aScgd  *	This product includes software developed by the University of
21e0b9a84aScgd  *	California, Berkeley and its contributors.
22e0b9a84aScgd  * 4. Neither the name of the University nor the names of its contributors
23e0b9a84aScgd  *    may be used to endorse or promote products derived from this software
24e0b9a84aScgd  *    without specific prior written permission.
25e0b9a84aScgd  *
26e0b9a84aScgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27e0b9a84aScgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28e0b9a84aScgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29e0b9a84aScgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30e0b9a84aScgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31e0b9a84aScgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32e0b9a84aScgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33e0b9a84aScgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34e0b9a84aScgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35e0b9a84aScgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36e0b9a84aScgd  * SUCH DAMAGE.
37e0b9a84aScgd  */
38e0b9a84aScgd 
3906795b86Slukem #include <sys/cdefs.h>
4006795b86Slukem #if !defined(lint)
414902ac3dScgd #if 0
424902ac3dScgd static char sccsid[] = "@(#)crypt.c	8.1.1.1 (Berkeley) 8/18/93";
4306795b86Slukem #else
44*56545abaSkleink __RCSID("$NetBSD: crypt.c,v 1.12 1998/06/01 20:25:24 kleink Exp $");
454902ac3dScgd #endif
4606795b86Slukem #endif /* not lint */
47e0b9a84aScgd 
48e0b9a84aScgd #include <limits.h>
49e0b9a84aScgd #include <pwd.h>
50*56545abaSkleink #include <stdlib.h>
5131a2bdc6Smikel #include <unistd.h>
52e0b9a84aScgd 
53e0b9a84aScgd /*
54e0b9a84aScgd  * UNIX password, and DES, encryption.
55e0b9a84aScgd  * By Tom Truscott, trt@rti.rti.org,
56e0b9a84aScgd  * from algorithms by Robert W. Baldwin and James Gillogly.
57e0b9a84aScgd  *
58e0b9a84aScgd  * References:
59e0b9a84aScgd  * "Mathematical Cryptology for Computer Scientists and Mathematicians,"
60e0b9a84aScgd  * by Wayne Patterson, 1987, ISBN 0-8476-7438-X.
61e0b9a84aScgd  *
62e0b9a84aScgd  * "Password Security: A Case History," R. Morris and Ken Thompson,
63e0b9a84aScgd  * Communications of the ACM, vol. 22, pp. 594-597, Nov. 1979.
64e0b9a84aScgd  *
65e0b9a84aScgd  * "DES will be Totally Insecure within Ten Years," M.E. Hellman,
66e0b9a84aScgd  * IEEE Spectrum, vol. 16, pp. 32-39, July 1979.
67e0b9a84aScgd  */
68e0b9a84aScgd 
69e0b9a84aScgd /* =====  Configuration ==================== */
70e0b9a84aScgd 
71e0b9a84aScgd /*
72e0b9a84aScgd  * define "MUST_ALIGN" if your compiler cannot load/store
73e0b9a84aScgd  * long integers at arbitrary (e.g. odd) memory locations.
74e0b9a84aScgd  * (Either that or never pass unaligned addresses to des_cipher!)
75e0b9a84aScgd  */
76e0b9a84aScgd #if !defined(vax)
77e0b9a84aScgd #define	MUST_ALIGN
78e0b9a84aScgd #endif
79e0b9a84aScgd 
80e0b9a84aScgd #ifdef CHAR_BITS
81e0b9a84aScgd #if CHAR_BITS != 8
82e0b9a84aScgd 	#error C_block structure assumes 8 bit characters
83e0b9a84aScgd #endif
84e0b9a84aScgd #endif
85e0b9a84aScgd 
86e0b9a84aScgd /*
87e0b9a84aScgd  * define "B64" to be the declaration for a 64 bit integer.
88e0b9a84aScgd  * XXX this feature is currently unused, see "endian" comment below.
89e0b9a84aScgd  */
90e0b9a84aScgd #if defined(cray)
91e0b9a84aScgd #define	B64	long
92e0b9a84aScgd #endif
93e0b9a84aScgd #if defined(convex)
94e0b9a84aScgd #define	B64	long long
95e0b9a84aScgd #endif
96e0b9a84aScgd 
97e0b9a84aScgd /*
98e0b9a84aScgd  * define "LARGEDATA" to get faster permutations, by using about 72 kilobytes
99e0b9a84aScgd  * of lookup tables.  This speeds up des_setkey() and des_cipher(), but has
100e0b9a84aScgd  * little effect on crypt().
101e0b9a84aScgd  */
102e0b9a84aScgd #if defined(notdef)
103e0b9a84aScgd #define	LARGEDATA
104e0b9a84aScgd #endif
105e0b9a84aScgd 
10631a2bdc6Smikel /* compile with "-DSTATIC=void" when profiling */
107e0b9a84aScgd #ifndef STATIC
10831a2bdc6Smikel #define	STATIC	static void
109e0b9a84aScgd #endif
110e0b9a84aScgd 
111e0b9a84aScgd /* ==================================== */
112e0b9a84aScgd 
113e0b9a84aScgd /*
114e0b9a84aScgd  * Cipher-block representation (Bob Baldwin):
115e0b9a84aScgd  *
116e0b9a84aScgd  * DES operates on groups of 64 bits, numbered 1..64 (sigh).  One
117e0b9a84aScgd  * representation is to store one bit per byte in an array of bytes.  Bit N of
118e0b9a84aScgd  * the NBS spec is stored as the LSB of the Nth byte (index N-1) in the array.
119e0b9a84aScgd  * Another representation stores the 64 bits in 8 bytes, with bits 1..8 in the
120e0b9a84aScgd  * first byte, 9..16 in the second, and so on.  The DES spec apparently has
121e0b9a84aScgd  * bit 1 in the MSB of the first byte, but that is particularly noxious so we
122e0b9a84aScgd  * bit-reverse each byte so that bit 1 is the LSB of the first byte, bit 8 is
123e0b9a84aScgd  * the MSB of the first byte.  Specifically, the 64-bit input data and key are
124e0b9a84aScgd  * converted to LSB format, and the output 64-bit block is converted back into
125e0b9a84aScgd  * MSB format.
126e0b9a84aScgd  *
127e0b9a84aScgd  * DES operates internally on groups of 32 bits which are expanded to 48 bits
128e0b9a84aScgd  * by permutation E and shrunk back to 32 bits by the S boxes.  To speed up
129e0b9a84aScgd  * the computation, the expansion is applied only once, the expanded
130e0b9a84aScgd  * representation is maintained during the encryption, and a compression
131e0b9a84aScgd  * permutation is applied only at the end.  To speed up the S-box lookups,
132e0b9a84aScgd  * the 48 bits are maintained as eight 6 bit groups, one per byte, which
133e0b9a84aScgd  * directly feed the eight S-boxes.  Within each byte, the 6 bits are the
134e0b9a84aScgd  * most significant ones.  The low two bits of each byte are zero.  (Thus,
135e0b9a84aScgd  * bit 1 of the 48 bit E expansion is stored as the "4"-valued bit of the
136e0b9a84aScgd  * first byte in the eight byte representation, bit 2 of the 48 bit value is
137e0b9a84aScgd  * the "8"-valued bit, and so on.)  In fact, a combined "SPE"-box lookup is
138e0b9a84aScgd  * used, in which the output is the 64 bit result of an S-box lookup which
139e0b9a84aScgd  * has been permuted by P and expanded by E, and is ready for use in the next
140e0b9a84aScgd  * iteration.  Two 32-bit wide tables, SPE[0] and SPE[1], are used for this
141e0b9a84aScgd  * lookup.  Since each byte in the 48 bit path is a multiple of four, indexed
142e0b9a84aScgd  * lookup of SPE[0] and SPE[1] is simple and fast.  The key schedule and
143e0b9a84aScgd  * "salt" are also converted to this 8*(6+2) format.  The SPE table size is
144e0b9a84aScgd  * 8*64*8 = 4K bytes.
145e0b9a84aScgd  *
146e0b9a84aScgd  * To speed up bit-parallel operations (such as XOR), the 8 byte
147e0b9a84aScgd  * representation is "union"ed with 32 bit values "i0" and "i1", and, on
148e0b9a84aScgd  * machines which support it, a 64 bit value "b64".  This data structure,
149e0b9a84aScgd  * "C_block", has two problems.  First, alignment restrictions must be
150e0b9a84aScgd  * honored.  Second, the byte-order (e.g. little-endian or big-endian) of
151e0b9a84aScgd  * the architecture becomes visible.
152e0b9a84aScgd  *
153e0b9a84aScgd  * The byte-order problem is unfortunate, since on the one hand it is good
154e0b9a84aScgd  * to have a machine-independent C_block representation (bits 1..8 in the
155e0b9a84aScgd  * first byte, etc.), and on the other hand it is good for the LSB of the
156e0b9a84aScgd  * first byte to be the LSB of i0.  We cannot have both these things, so we
157e0b9a84aScgd  * currently use the "little-endian" representation and avoid any multi-byte
158e0b9a84aScgd  * operations that depend on byte order.  This largely precludes use of the
159e0b9a84aScgd  * 64-bit datatype since the relative order of i0 and i1 are unknown.  It
160e0b9a84aScgd  * also inhibits grouping the SPE table to look up 12 bits at a time.  (The
161e0b9a84aScgd  * 12 bits can be stored in a 16-bit field with 3 low-order zeroes and 1
162e0b9a84aScgd  * high-order zero, providing fast indexing into a 64-bit wide SPE.)  On the
163e0b9a84aScgd  * other hand, 64-bit datatypes are currently rare, and a 12-bit SPE lookup
164e0b9a84aScgd  * requires a 128 kilobyte table, so perhaps this is not a big loss.
165e0b9a84aScgd  *
166e0b9a84aScgd  * Permutation representation (Jim Gillogly):
167e0b9a84aScgd  *
168e0b9a84aScgd  * A transformation is defined by its effect on each of the 8 bytes of the
169e0b9a84aScgd  * 64-bit input.  For each byte we give a 64-bit output that has the bits in
170e0b9a84aScgd  * the input distributed appropriately.  The transformation is then the OR
171e0b9a84aScgd  * of the 8 sets of 64-bits.  This uses 8*256*8 = 16K bytes of storage for
172e0b9a84aScgd  * each transformation.  Unless LARGEDATA is defined, however, a more compact
173e0b9a84aScgd  * table is used which looks up 16 4-bit "chunks" rather than 8 8-bit chunks.
174e0b9a84aScgd  * The smaller table uses 16*16*8 = 2K bytes for each transformation.  This
175e0b9a84aScgd  * is slower but tolerable, particularly for password encryption in which
176e0b9a84aScgd  * the SPE transformation is iterated many times.  The small tables total 9K
177e0b9a84aScgd  * bytes, the large tables total 72K bytes.
178e0b9a84aScgd  *
179e0b9a84aScgd  * The transformations used are:
180e0b9a84aScgd  * IE3264: MSB->LSB conversion, initial permutation, and expansion.
181e0b9a84aScgd  *	This is done by collecting the 32 even-numbered bits and applying
182e0b9a84aScgd  *	a 32->64 bit transformation, and then collecting the 32 odd-numbered
183e0b9a84aScgd  *	bits and applying the same transformation.  Since there are only
184e0b9a84aScgd  *	32 input bits, the IE3264 transformation table is half the size of
185e0b9a84aScgd  *	the usual table.
186e0b9a84aScgd  * CF6464: Compression, final permutation, and LSB->MSB conversion.
187e0b9a84aScgd  *	This is done by two trivial 48->32 bit compressions to obtain
188e0b9a84aScgd  *	a 64-bit block (the bit numbering is given in the "CIFP" table)
189e0b9a84aScgd  *	followed by a 64->64 bit "cleanup" transformation.  (It would
190e0b9a84aScgd  *	be possible to group the bits in the 64-bit block so that 2
191e0b9a84aScgd  *	identical 32->32 bit transformations could be used instead,
192e0b9a84aScgd  *	saving a factor of 4 in space and possibly 2 in time, but
193e0b9a84aScgd  *	byte-ordering and other complications rear their ugly head.
194e0b9a84aScgd  *	Similar opportunities/problems arise in the key schedule
195e0b9a84aScgd  *	transforms.)
196e0b9a84aScgd  * PC1ROT: MSB->LSB, PC1 permutation, rotate, and PC2 permutation.
197e0b9a84aScgd  *	This admittedly baroque 64->64 bit transformation is used to
198e0b9a84aScgd  *	produce the first code (in 8*(6+2) format) of the key schedule.
199e0b9a84aScgd  * PC2ROT[0]: Inverse PC2 permutation, rotate, and PC2 permutation.
200e0b9a84aScgd  *	It would be possible to define 15 more transformations, each
201e0b9a84aScgd  *	with a different rotation, to generate the entire key schedule.
202e0b9a84aScgd  *	To save space, however, we instead permute each code into the
203e0b9a84aScgd  *	next by using a transformation that "undoes" the PC2 permutation,
204e0b9a84aScgd  *	rotates the code, and then applies PC2.  Unfortunately, PC2
205e0b9a84aScgd  *	transforms 56 bits into 48 bits, dropping 8 bits, so PC2 is not
206e0b9a84aScgd  *	invertible.  We get around that problem by using a modified PC2
207e0b9a84aScgd  *	which retains the 8 otherwise-lost bits in the unused low-order
208e0b9a84aScgd  *	bits of each byte.  The low-order bits are cleared when the
209e0b9a84aScgd  *	codes are stored into the key schedule.
210e0b9a84aScgd  * PC2ROT[1]: Same as PC2ROT[0], but with two rotations.
211e0b9a84aScgd  *	This is faster than applying PC2ROT[0] twice,
212e0b9a84aScgd  *
213e0b9a84aScgd  * The Bell Labs "salt" (Bob Baldwin):
214e0b9a84aScgd  *
215e0b9a84aScgd  * The salting is a simple permutation applied to the 48-bit result of E.
216e0b9a84aScgd  * Specifically, if bit i (1 <= i <= 24) of the salt is set then bits i and
217e0b9a84aScgd  * i+24 of the result are swapped.  The salt is thus a 24 bit number, with
218e0b9a84aScgd  * 16777216 possible values.  (The original salt was 12 bits and could not
219e0b9a84aScgd  * swap bits 13..24 with 36..48.)
220e0b9a84aScgd  *
221e0b9a84aScgd  * It is possible, but ugly, to warp the SPE table to account for the salt
222e0b9a84aScgd  * permutation.  Fortunately, the conditional bit swapping requires only
223e0b9a84aScgd  * about four machine instructions and can be done on-the-fly with about an
224e0b9a84aScgd  * 8% performance penalty.
225e0b9a84aScgd  */
226e0b9a84aScgd 
227e0b9a84aScgd typedef union {
228e0b9a84aScgd 	unsigned char b[8];
229e0b9a84aScgd 	struct {
230688980ebScgd 		int32_t	i0;
231688980ebScgd 		int32_t	i1;
232e0b9a84aScgd 	} b32;
233e0b9a84aScgd #if defined(B64)
234e0b9a84aScgd 	B64	b64;
235e0b9a84aScgd #endif
236e0b9a84aScgd } C_block;
237e0b9a84aScgd 
238e0b9a84aScgd /*
239e0b9a84aScgd  * Convert twenty-four-bit long in host-order
240e0b9a84aScgd  * to six bits (and 2 low-order zeroes) per char little-endian format.
241e0b9a84aScgd  */
242e0b9a84aScgd #define	TO_SIX_BIT(rslt, src) {				\
243e0b9a84aScgd 		C_block cvt;				\
244e0b9a84aScgd 		cvt.b[0] = src; src >>= 6;		\
245e0b9a84aScgd 		cvt.b[1] = src; src >>= 6;		\
246e0b9a84aScgd 		cvt.b[2] = src; src >>= 6;		\
247e0b9a84aScgd 		cvt.b[3] = src;				\
248e0b9a84aScgd 		rslt = (cvt.b32.i0 & 0x3f3f3f3fL) << 2;	\
249e0b9a84aScgd 	}
250e0b9a84aScgd 
251e0b9a84aScgd /*
252e0b9a84aScgd  * These macros may someday permit efficient use of 64-bit integers.
253e0b9a84aScgd  */
254e0b9a84aScgd #define	ZERO(d,d0,d1)			d0 = 0, d1 = 0
255e0b9a84aScgd #define	LOAD(d,d0,d1,bl)		d0 = (bl).b32.i0, d1 = (bl).b32.i1
256e0b9a84aScgd #define	LOADREG(d,d0,d1,s,s0,s1)	d0 = s0, d1 = s1
257e0b9a84aScgd #define	OR(d,d0,d1,bl)			d0 |= (bl).b32.i0, d1 |= (bl).b32.i1
258e0b9a84aScgd #define	STORE(s,s0,s1,bl)		(bl).b32.i0 = s0, (bl).b32.i1 = s1
259688980ebScgd #define	DCL_BLOCK(d,d0,d1)		int32_t d0, d1
260e0b9a84aScgd 
261e0b9a84aScgd #if defined(LARGEDATA)
262e0b9a84aScgd 	/* Waste memory like crazy.  Also, do permutations in line */
263e0b9a84aScgd #define	LGCHUNKBITS	3
264e0b9a84aScgd #define	CHUNKBITS	(1<<LGCHUNKBITS)
265e0b9a84aScgd #define	PERM6464(d,d0,d1,cpp,p)				\
266e0b9a84aScgd 	LOAD(d,d0,d1,(p)[(0<<CHUNKBITS)+(cpp)[0]]);		\
267e0b9a84aScgd 	OR (d,d0,d1,(p)[(1<<CHUNKBITS)+(cpp)[1]]);		\
268e0b9a84aScgd 	OR (d,d0,d1,(p)[(2<<CHUNKBITS)+(cpp)[2]]);		\
269e0b9a84aScgd 	OR (d,d0,d1,(p)[(3<<CHUNKBITS)+(cpp)[3]]);		\
270e0b9a84aScgd 	OR (d,d0,d1,(p)[(4<<CHUNKBITS)+(cpp)[4]]);		\
271e0b9a84aScgd 	OR (d,d0,d1,(p)[(5<<CHUNKBITS)+(cpp)[5]]);		\
272e0b9a84aScgd 	OR (d,d0,d1,(p)[(6<<CHUNKBITS)+(cpp)[6]]);		\
273e0b9a84aScgd 	OR (d,d0,d1,(p)[(7<<CHUNKBITS)+(cpp)[7]]);
274e0b9a84aScgd #define	PERM3264(d,d0,d1,cpp,p)				\
275e0b9a84aScgd 	LOAD(d,d0,d1,(p)[(0<<CHUNKBITS)+(cpp)[0]]);		\
276e0b9a84aScgd 	OR (d,d0,d1,(p)[(1<<CHUNKBITS)+(cpp)[1]]);		\
277e0b9a84aScgd 	OR (d,d0,d1,(p)[(2<<CHUNKBITS)+(cpp)[2]]);		\
278e0b9a84aScgd 	OR (d,d0,d1,(p)[(3<<CHUNKBITS)+(cpp)[3]]);
279e0b9a84aScgd #else
280e0b9a84aScgd 	/* "small data" */
281e0b9a84aScgd #define	LGCHUNKBITS	2
282e0b9a84aScgd #define	CHUNKBITS	(1<<LGCHUNKBITS)
283e0b9a84aScgd #define	PERM6464(d,d0,d1,cpp,p)				\
284e0b9a84aScgd 	{ C_block tblk; permute(cpp,&tblk,p,8); LOAD (d,d0,d1,tblk); }
285e0b9a84aScgd #define	PERM3264(d,d0,d1,cpp,p)				\
286e0b9a84aScgd 	{ C_block tblk; permute(cpp,&tblk,p,4); LOAD (d,d0,d1,tblk); }
287cd0a22a4Smikel #endif /* LARGEDATA */
28806795b86Slukem 
28906795b86Slukem STATIC	init_des __P((void));
290226f67d0Scgd STATIC	init_perm __P((C_block [64/CHUNKBITS][1<<CHUNKBITS], unsigned char [64], int, int));
291cd0a22a4Smikel #ifndef LARGEDATA
29206795b86Slukem STATIC	permute __P((unsigned char *, C_block *, C_block *, int));
293cd0a22a4Smikel #endif
29406795b86Slukem #ifdef DEBUG
29506795b86Slukem STATIC	prtab __P((char *, unsigned char *, int));
29606795b86Slukem #endif
29706795b86Slukem 
29806795b86Slukem 
299cd0a22a4Smikel #ifndef LARGEDATA
300e0b9a84aScgd STATIC
301e0b9a84aScgd permute(cp, out, p, chars_in)
302e0b9a84aScgd 	unsigned char *cp;
303e0b9a84aScgd 	C_block *out;
30406795b86Slukem 	C_block *p;
305e0b9a84aScgd 	int chars_in;
306e0b9a84aScgd {
30706795b86Slukem 	DCL_BLOCK(D,D0,D1);
30806795b86Slukem 	C_block *tp;
30906795b86Slukem 	int t;
310e0b9a84aScgd 
311e0b9a84aScgd 	ZERO(D,D0,D1);
312e0b9a84aScgd 	do {
313e0b9a84aScgd 		t = *cp++;
314e0b9a84aScgd 		tp = &p[t&0xf]; OR(D,D0,D1,*tp); p += (1<<CHUNKBITS);
315e0b9a84aScgd 		tp = &p[t>>4];  OR(D,D0,D1,*tp); p += (1<<CHUNKBITS);
316e0b9a84aScgd 	} while (--chars_in > 0);
317e0b9a84aScgd 	STORE(D,D0,D1,*out);
318e0b9a84aScgd }
319e0b9a84aScgd #endif /* LARGEDATA */
320e0b9a84aScgd 
321e0b9a84aScgd 
322e0b9a84aScgd /* =====  (mostly) Standard DES Tables ==================== */
323e0b9a84aScgd 
324e0b9a84aScgd static unsigned char IP[] = {		/* initial permutation */
325e0b9a84aScgd 	58, 50, 42, 34, 26, 18, 10,  2,
326e0b9a84aScgd 	60, 52, 44, 36, 28, 20, 12,  4,
327e0b9a84aScgd 	62, 54, 46, 38, 30, 22, 14,  6,
328e0b9a84aScgd 	64, 56, 48, 40, 32, 24, 16,  8,
329e0b9a84aScgd 	57, 49, 41, 33, 25, 17,  9,  1,
330e0b9a84aScgd 	59, 51, 43, 35, 27, 19, 11,  3,
331e0b9a84aScgd 	61, 53, 45, 37, 29, 21, 13,  5,
332e0b9a84aScgd 	63, 55, 47, 39, 31, 23, 15,  7,
333e0b9a84aScgd };
334e0b9a84aScgd 
335e0b9a84aScgd /* The final permutation is the inverse of IP - no table is necessary */
336e0b9a84aScgd 
337e0b9a84aScgd static unsigned char ExpandTr[] = {	/* expansion operation */
338e0b9a84aScgd 	32,  1,  2,  3,  4,  5,
339e0b9a84aScgd 	 4,  5,  6,  7,  8,  9,
340e0b9a84aScgd 	 8,  9, 10, 11, 12, 13,
341e0b9a84aScgd 	12, 13, 14, 15, 16, 17,
342e0b9a84aScgd 	16, 17, 18, 19, 20, 21,
343e0b9a84aScgd 	20, 21, 22, 23, 24, 25,
344e0b9a84aScgd 	24, 25, 26, 27, 28, 29,
345e0b9a84aScgd 	28, 29, 30, 31, 32,  1,
346e0b9a84aScgd };
347e0b9a84aScgd 
348e0b9a84aScgd static unsigned char PC1[] = {		/* permuted choice table 1 */
349e0b9a84aScgd 	57, 49, 41, 33, 25, 17,  9,
350e0b9a84aScgd 	 1, 58, 50, 42, 34, 26, 18,
351e0b9a84aScgd 	10,  2, 59, 51, 43, 35, 27,
352e0b9a84aScgd 	19, 11,  3, 60, 52, 44, 36,
353e0b9a84aScgd 
354e0b9a84aScgd 	63, 55, 47, 39, 31, 23, 15,
355e0b9a84aScgd 	 7, 62, 54, 46, 38, 30, 22,
356e0b9a84aScgd 	14,  6, 61, 53, 45, 37, 29,
357e0b9a84aScgd 	21, 13,  5, 28, 20, 12,  4,
358e0b9a84aScgd };
359e0b9a84aScgd 
360e0b9a84aScgd static unsigned char Rotates[] = {	/* PC1 rotation schedule */
361e0b9a84aScgd 	1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1,
362e0b9a84aScgd };
363e0b9a84aScgd 
364e0b9a84aScgd /* note: each "row" of PC2 is left-padded with bits that make it invertible */
365e0b9a84aScgd static unsigned char PC2[] = {		/* permuted choice table 2 */
366e0b9a84aScgd 	 9, 18,    14, 17, 11, 24,  1,  5,
367e0b9a84aScgd 	22, 25,     3, 28, 15,  6, 21, 10,
368e0b9a84aScgd 	35, 38,    23, 19, 12,  4, 26,  8,
369e0b9a84aScgd 	43, 54,    16,  7, 27, 20, 13,  2,
370e0b9a84aScgd 
371e0b9a84aScgd 	 0,  0,    41, 52, 31, 37, 47, 55,
372e0b9a84aScgd 	 0,  0,    30, 40, 51, 45, 33, 48,
373e0b9a84aScgd 	 0,  0,    44, 49, 39, 56, 34, 53,
374e0b9a84aScgd 	 0,  0,    46, 42, 50, 36, 29, 32,
375e0b9a84aScgd };
376e0b9a84aScgd 
377e0b9a84aScgd static unsigned char S[8][64] = {	/* 48->32 bit substitution tables */
378e0b9a84aScgd 					/* S[1]			*/
37931a2bdc6Smikel 	{ 14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7,
380e0b9a84aScgd 	   0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8,
381e0b9a84aScgd 	   4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0,
38231a2bdc6Smikel 	  15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13 },
383e0b9a84aScgd 					/* S[2]			*/
38431a2bdc6Smikel 	{ 15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10,
385e0b9a84aScgd 	   3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5,
386e0b9a84aScgd 	   0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15,
38731a2bdc6Smikel 	  13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9 },
388e0b9a84aScgd 					/* S[3]			*/
38931a2bdc6Smikel 	{ 10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8,
390e0b9a84aScgd 	  13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1,
391e0b9a84aScgd 	  13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7,
39231a2bdc6Smikel 	   1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12 },
393e0b9a84aScgd 					/* S[4]			*/
39431a2bdc6Smikel 	{  7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15,
395e0b9a84aScgd 	  13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9,
396e0b9a84aScgd 	  10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4,
39731a2bdc6Smikel 	   3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14 },
398e0b9a84aScgd 					/* S[5]			*/
39931a2bdc6Smikel 	{  2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9,
400e0b9a84aScgd 	  14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6,
401e0b9a84aScgd 	   4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14,
40231a2bdc6Smikel 	  11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3 },
403e0b9a84aScgd 					/* S[6]			*/
40431a2bdc6Smikel 	{ 12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11,
405e0b9a84aScgd 	  10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8,
406e0b9a84aScgd 	   9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6,
40731a2bdc6Smikel 	   4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13 },
408e0b9a84aScgd 					/* S[7]			*/
40931a2bdc6Smikel 	{  4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1,
410e0b9a84aScgd 	  13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6,
411e0b9a84aScgd 	   1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2,
41231a2bdc6Smikel 	   6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12 },
413e0b9a84aScgd 					/* S[8]			*/
41431a2bdc6Smikel 	{ 13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7,
415e0b9a84aScgd 	   1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2,
416e0b9a84aScgd 	   7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8,
41731a2bdc6Smikel 	   2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11 }
418e0b9a84aScgd };
419e0b9a84aScgd 
420e0b9a84aScgd static unsigned char P32Tr[] = {	/* 32-bit permutation function */
421e0b9a84aScgd 	16,  7, 20, 21,
422e0b9a84aScgd 	29, 12, 28, 17,
423e0b9a84aScgd 	 1, 15, 23, 26,
424e0b9a84aScgd 	 5, 18, 31, 10,
425e0b9a84aScgd 	 2,  8, 24, 14,
426e0b9a84aScgd 	32, 27,  3,  9,
427e0b9a84aScgd 	19, 13, 30,  6,
428e0b9a84aScgd 	22, 11,  4, 25,
429e0b9a84aScgd };
430e0b9a84aScgd 
431e0b9a84aScgd static unsigned char CIFP[] = {		/* compressed/interleaved permutation */
432e0b9a84aScgd 	 1,  2,  3,  4,   17, 18, 19, 20,
433e0b9a84aScgd 	 5,  6,  7,  8,   21, 22, 23, 24,
434e0b9a84aScgd 	 9, 10, 11, 12,   25, 26, 27, 28,
435e0b9a84aScgd 	13, 14, 15, 16,   29, 30, 31, 32,
436e0b9a84aScgd 
437e0b9a84aScgd 	33, 34, 35, 36,   49, 50, 51, 52,
438e0b9a84aScgd 	37, 38, 39, 40,   53, 54, 55, 56,
439e0b9a84aScgd 	41, 42, 43, 44,   57, 58, 59, 60,
440e0b9a84aScgd 	45, 46, 47, 48,   61, 62, 63, 64,
441e0b9a84aScgd };
442e0b9a84aScgd 
443e0b9a84aScgd static unsigned char itoa64[] =		/* 0..63 => ascii-64 */
444e0b9a84aScgd 	"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
445e0b9a84aScgd 
446e0b9a84aScgd 
447e0b9a84aScgd /* =====  Tables that are initialized at run time  ==================== */
448e0b9a84aScgd 
449e0b9a84aScgd 
450e0b9a84aScgd static unsigned char a64toi[128];	/* ascii-64 => 0..63 */
451e0b9a84aScgd 
452e0b9a84aScgd /* Initial key schedule permutation */
453e0b9a84aScgd static C_block	PC1ROT[64/CHUNKBITS][1<<CHUNKBITS];
454e0b9a84aScgd 
455e0b9a84aScgd /* Subsequent key schedule rotation permutations */
456e0b9a84aScgd static C_block	PC2ROT[2][64/CHUNKBITS][1<<CHUNKBITS];
457e0b9a84aScgd 
458e0b9a84aScgd /* Initial permutation/expansion table */
459e0b9a84aScgd static C_block	IE3264[32/CHUNKBITS][1<<CHUNKBITS];
460e0b9a84aScgd 
461e0b9a84aScgd /* Table that combines the S, P, and E operations.  */
462688980ebScgd static int32_t SPE[2][8][64];
463e0b9a84aScgd 
464e0b9a84aScgd /* compressed/interleaved => final permutation table */
465e0b9a84aScgd static C_block	CF6464[64/CHUNKBITS][1<<CHUNKBITS];
466e0b9a84aScgd 
467e0b9a84aScgd 
468e0b9a84aScgd /* ==================================== */
469e0b9a84aScgd 
470e0b9a84aScgd 
471e0b9a84aScgd static C_block	constdatablock;			/* encryption constant */
472e0b9a84aScgd static char	cryptresult[1+4+4+11+1];	/* encrypted result */
473e0b9a84aScgd 
474e0b9a84aScgd /*
475e0b9a84aScgd  * Return a pointer to static data consisting of the "setting"
476e0b9a84aScgd  * followed by an encryption produced by the "key" and "setting".
477e0b9a84aScgd  */
478e0b9a84aScgd char *
479e0b9a84aScgd crypt(key, setting)
48006795b86Slukem 	const char *key;
48106795b86Slukem 	const char *setting;
482e0b9a84aScgd {
48306795b86Slukem 	char *encp;
48406795b86Slukem 	int32_t i;
48506795b86Slukem 	int t;
486688980ebScgd 	int32_t salt;
487e0b9a84aScgd 	int num_iter, salt_size;
488e0b9a84aScgd 	C_block keyblock, rsltblock;
489e0b9a84aScgd 
490e0b9a84aScgd 	for (i = 0; i < 8; i++) {
491e0b9a84aScgd 		if ((t = 2*(unsigned char)(*key)) != 0)
492e0b9a84aScgd 			key++;
493e0b9a84aScgd 		keyblock.b[i] = t;
494e0b9a84aScgd 	}
495e0b9a84aScgd 	if (des_setkey((char *)keyblock.b))	/* also initializes "a64toi" */
496e0b9a84aScgd 		return (NULL);
497e0b9a84aScgd 
498e0b9a84aScgd 	encp = &cryptresult[0];
499e0b9a84aScgd 	switch (*setting) {
500e0b9a84aScgd 	case _PASSWORD_EFMT1:
501e0b9a84aScgd 		/*
502e0b9a84aScgd 		 * Involve the rest of the password 8 characters at a time.
503e0b9a84aScgd 		 */
504e0b9a84aScgd 		while (*key) {
505e0b9a84aScgd 			if (des_cipher((char *)&keyblock,
506e0b9a84aScgd 			    (char *)&keyblock, 0L, 1))
507e0b9a84aScgd 				return (NULL);
508e0b9a84aScgd 			for (i = 0; i < 8; i++) {
509e0b9a84aScgd 				if ((t = 2*(unsigned char)(*key)) != 0)
510e0b9a84aScgd 					key++;
511e0b9a84aScgd 				keyblock.b[i] ^= t;
512e0b9a84aScgd 			}
513e0b9a84aScgd 			if (des_setkey((char *)keyblock.b))
514e0b9a84aScgd 				return (NULL);
515e0b9a84aScgd 		}
516e0b9a84aScgd 
517e0b9a84aScgd 		*encp++ = *setting++;
518e0b9a84aScgd 
519e0b9a84aScgd 		/* get iteration count */
520e0b9a84aScgd 		num_iter = 0;
521e0b9a84aScgd 		for (i = 4; --i >= 0; ) {
522e0b9a84aScgd 			if ((t = (unsigned char)setting[i]) == '\0')
523e0b9a84aScgd 				t = '.';
524e0b9a84aScgd 			encp[i] = t;
525e0b9a84aScgd 			num_iter = (num_iter<<6) | a64toi[t];
526e0b9a84aScgd 		}
527e0b9a84aScgd 		setting += 4;
528e0b9a84aScgd 		encp += 4;
529e0b9a84aScgd 		salt_size = 4;
530e0b9a84aScgd 		break;
531e0b9a84aScgd 	default:
532e0b9a84aScgd 		num_iter = 25;
533e0b9a84aScgd 		salt_size = 2;
534e0b9a84aScgd 	}
535e0b9a84aScgd 
536e0b9a84aScgd 	salt = 0;
537e0b9a84aScgd 	for (i = salt_size; --i >= 0; ) {
538e0b9a84aScgd 		if ((t = (unsigned char)setting[i]) == '\0')
539e0b9a84aScgd 			t = '.';
540e0b9a84aScgd 		encp[i] = t;
541e0b9a84aScgd 		salt = (salt<<6) | a64toi[t];
542e0b9a84aScgd 	}
543e0b9a84aScgd 	encp += salt_size;
544e0b9a84aScgd 	if (des_cipher((char *)&constdatablock, (char *)&rsltblock,
545e0b9a84aScgd 	    salt, num_iter))
546e0b9a84aScgd 		return (NULL);
547e0b9a84aScgd 
548e0b9a84aScgd 	/*
549e0b9a84aScgd 	 * Encode the 64 cipher bits as 11 ascii characters.
550e0b9a84aScgd 	 */
551688980ebScgd 	i = ((int32_t)((rsltblock.b[0]<<8) | rsltblock.b[1])<<8) |
552688980ebScgd 	    rsltblock.b[2];
553e0b9a84aScgd 	encp[3] = itoa64[i&0x3f];	i >>= 6;
554e0b9a84aScgd 	encp[2] = itoa64[i&0x3f];	i >>= 6;
555e0b9a84aScgd 	encp[1] = itoa64[i&0x3f];	i >>= 6;
556e0b9a84aScgd 	encp[0] = itoa64[i];		encp += 4;
557688980ebScgd 	i = ((int32_t)((rsltblock.b[3]<<8) | rsltblock.b[4])<<8) |
558688980ebScgd 	    rsltblock.b[5];
559e0b9a84aScgd 	encp[3] = itoa64[i&0x3f];	i >>= 6;
560e0b9a84aScgd 	encp[2] = itoa64[i&0x3f];	i >>= 6;
561e0b9a84aScgd 	encp[1] = itoa64[i&0x3f];	i >>= 6;
562e0b9a84aScgd 	encp[0] = itoa64[i];		encp += 4;
563688980ebScgd 	i = ((int32_t)((rsltblock.b[6])<<8) | rsltblock.b[7])<<2;
564e0b9a84aScgd 	encp[2] = itoa64[i&0x3f];	i >>= 6;
565e0b9a84aScgd 	encp[1] = itoa64[i&0x3f];	i >>= 6;
566e0b9a84aScgd 	encp[0] = itoa64[i];
567e0b9a84aScgd 
568e0b9a84aScgd 	encp[3] = 0;
569e0b9a84aScgd 
570e0b9a84aScgd 	return (cryptresult);
571e0b9a84aScgd }
572e0b9a84aScgd 
573e0b9a84aScgd 
574e0b9a84aScgd /*
575e0b9a84aScgd  * The Key Schedule, filled in by des_setkey() or setkey().
576e0b9a84aScgd  */
577e0b9a84aScgd #define	KS_SIZE	16
578e0b9a84aScgd static C_block	KS[KS_SIZE];
579e0b9a84aScgd 
580e0b9a84aScgd /*
581e0b9a84aScgd  * Set up the key schedule from the key.
582e0b9a84aScgd  */
58331a2bdc6Smikel int
584e0b9a84aScgd des_setkey(key)
58506795b86Slukem 	const char *key;
586e0b9a84aScgd {
58706795b86Slukem 	DCL_BLOCK(K, K0, K1);
58806795b86Slukem 	C_block *ptabp;
58906795b86Slukem 	int i;
590e0b9a84aScgd 	static int des_ready = 0;
591e0b9a84aScgd 
592e0b9a84aScgd 	if (!des_ready) {
593e0b9a84aScgd 		init_des();
594e0b9a84aScgd 		des_ready = 1;
595e0b9a84aScgd 	}
596e0b9a84aScgd 
597e0b9a84aScgd 	PERM6464(K,K0,K1,(unsigned char *)key,(C_block *)PC1ROT);
598e0b9a84aScgd 	key = (char *)&KS[0];
599e0b9a84aScgd 	STORE(K&~0x03030303L, K0&~0x03030303L, K1, *(C_block *)key);
600e0b9a84aScgd 	for (i = 1; i < 16; i++) {
601e0b9a84aScgd 		key += sizeof(C_block);
602e0b9a84aScgd 		STORE(K,K0,K1,*(C_block *)key);
603e0b9a84aScgd 		ptabp = (C_block *)PC2ROT[Rotates[i]-1];
604e0b9a84aScgd 		PERM6464(K,K0,K1,(unsigned char *)key,ptabp);
605e0b9a84aScgd 		STORE(K&~0x03030303L, K0&~0x03030303L, K1, *(C_block *)key);
606e0b9a84aScgd 	}
607e0b9a84aScgd 	return (0);
608e0b9a84aScgd }
609e0b9a84aScgd 
610e0b9a84aScgd /*
611e0b9a84aScgd  * Encrypt (or decrypt if num_iter < 0) the 8 chars at "in" with abs(num_iter)
612e0b9a84aScgd  * iterations of DES, using the the given 24-bit salt and the pre-computed key
613e0b9a84aScgd  * schedule, and store the resulting 8 chars at "out" (in == out is permitted).
614e0b9a84aScgd  *
615e0b9a84aScgd  * NOTE: the performance of this routine is critically dependent on your
616e0b9a84aScgd  * compiler and machine architecture.
617e0b9a84aScgd  */
61831a2bdc6Smikel int
619e0b9a84aScgd des_cipher(in, out, salt, num_iter)
620e0b9a84aScgd 	const char *in;
621e0b9a84aScgd 	char *out;
622e0b9a84aScgd 	long salt;
623e0b9a84aScgd 	int num_iter;
624e0b9a84aScgd {
625e0b9a84aScgd 	/* variables that we want in registers, most important first */
626e0b9a84aScgd #if defined(pdp11)
6270b7831a3Sperry 	int j;
628e0b9a84aScgd #endif
6290b7831a3Sperry 	int32_t L0, L1, R0, R1, k;
6300b7831a3Sperry 	C_block *kp;
6310b7831a3Sperry 	int ks_inc, loop_count;
632e0b9a84aScgd 	C_block B;
633e0b9a84aScgd 
634e0b9a84aScgd 	L0 = salt;
635e0b9a84aScgd 	TO_SIX_BIT(salt, L0);	/* convert to 4*(6+2) format */
636e0b9a84aScgd 
637e0b9a84aScgd #if defined(vax) || defined(pdp11)
638e0b9a84aScgd 	salt = ~salt;	/* "x &~ y" is faster than "x & y". */
639e0b9a84aScgd #define	SALT (~salt)
640e0b9a84aScgd #else
641e0b9a84aScgd #define	SALT salt
642e0b9a84aScgd #endif
643e0b9a84aScgd 
644e0b9a84aScgd #if defined(MUST_ALIGN)
645e0b9a84aScgd 	B.b[0] = in[0]; B.b[1] = in[1]; B.b[2] = in[2]; B.b[3] = in[3];
646e0b9a84aScgd 	B.b[4] = in[4]; B.b[5] = in[5]; B.b[6] = in[6]; B.b[7] = in[7];
647e0b9a84aScgd 	LOAD(L,L0,L1,B);
648e0b9a84aScgd #else
649e0b9a84aScgd 	LOAD(L,L0,L1,*(C_block *)in);
650e0b9a84aScgd #endif
651e0b9a84aScgd 	LOADREG(R,R0,R1,L,L0,L1);
652e0b9a84aScgd 	L0 &= 0x55555555L;
653e0b9a84aScgd 	L1 &= 0x55555555L;
654e0b9a84aScgd 	L0 = (L0 << 1) | L1;	/* L0 is the even-numbered input bits */
655e0b9a84aScgd 	R0 &= 0xaaaaaaaaL;
656e0b9a84aScgd 	R1 = (R1 >> 1) & 0x55555555L;
657e0b9a84aScgd 	L1 = R0 | R1;		/* L1 is the odd-numbered input bits */
658e0b9a84aScgd 	STORE(L,L0,L1,B);
659e0b9a84aScgd 	PERM3264(L,L0,L1,B.b,  (C_block *)IE3264);	/* even bits */
660e0b9a84aScgd 	PERM3264(R,R0,R1,B.b+4,(C_block *)IE3264);	/* odd bits */
661e0b9a84aScgd 
662e0b9a84aScgd 	if (num_iter >= 0)
663e0b9a84aScgd 	{		/* encryption */
664e0b9a84aScgd 		kp = &KS[0];
665e0b9a84aScgd 		ks_inc  = sizeof(*kp);
666e0b9a84aScgd 	}
667e0b9a84aScgd 	else
668e0b9a84aScgd 	{		/* decryption */
6694902ac3dScgd 		return (1); /* always fail */
670e0b9a84aScgd 	}
671e0b9a84aScgd 
672e0b9a84aScgd 	while (--num_iter >= 0) {
673e0b9a84aScgd 		loop_count = 8;
674e0b9a84aScgd 		do {
675e0b9a84aScgd 
676688980ebScgd #define	SPTAB(t, i) \
677688980ebScgd 	    (*(int32_t *)((unsigned char *)t + i*(sizeof(int32_t)/4)))
678e0b9a84aScgd #if defined(gould)
679e0b9a84aScgd 			/* use this if B.b[i] is evaluated just once ... */
680e0b9a84aScgd #define	DOXOR(x,y,i)	x^=SPTAB(SPE[0][i],B.b[i]); y^=SPTAB(SPE[1][i],B.b[i]);
681e0b9a84aScgd #else
682e0b9a84aScgd #if defined(pdp11)
683e0b9a84aScgd 			/* use this if your "long" int indexing is slow */
684e0b9a84aScgd #define	DOXOR(x,y,i)	j=B.b[i]; x^=SPTAB(SPE[0][i],j); y^=SPTAB(SPE[1][i],j);
685e0b9a84aScgd #else
68695eeab3bSmikel 			/* use this if "k" is allocated to a register ... */
687e0b9a84aScgd #define	DOXOR(x,y,i)	k=B.b[i]; x^=SPTAB(SPE[0][i],k); y^=SPTAB(SPE[1][i],k);
688e0b9a84aScgd #endif
689e0b9a84aScgd #endif
690e0b9a84aScgd 
691e0b9a84aScgd #define	CRUNCH(p0, p1, q0, q1)	\
692e0b9a84aScgd 			k = (q0 ^ q1) & SALT;	\
693e0b9a84aScgd 			B.b32.i0 = k ^ q0 ^ kp->b32.i0;		\
694e0b9a84aScgd 			B.b32.i1 = k ^ q1 ^ kp->b32.i1;		\
695e0b9a84aScgd 			kp = (C_block *)((char *)kp+ks_inc);	\
696e0b9a84aScgd 							\
697e0b9a84aScgd 			DOXOR(p0, p1, 0);		\
698e0b9a84aScgd 			DOXOR(p0, p1, 1);		\
699e0b9a84aScgd 			DOXOR(p0, p1, 2);		\
700e0b9a84aScgd 			DOXOR(p0, p1, 3);		\
701e0b9a84aScgd 			DOXOR(p0, p1, 4);		\
702e0b9a84aScgd 			DOXOR(p0, p1, 5);		\
703e0b9a84aScgd 			DOXOR(p0, p1, 6);		\
704e0b9a84aScgd 			DOXOR(p0, p1, 7);
705e0b9a84aScgd 
706e0b9a84aScgd 			CRUNCH(L0, L1, R0, R1);
707e0b9a84aScgd 			CRUNCH(R0, R1, L0, L1);
708e0b9a84aScgd 		} while (--loop_count != 0);
709e0b9a84aScgd 		kp = (C_block *)((char *)kp-(ks_inc*KS_SIZE));
710e0b9a84aScgd 
711e0b9a84aScgd 
712e0b9a84aScgd 		/* swap L and R */
713e0b9a84aScgd 		L0 ^= R0;  L1 ^= R1;
714e0b9a84aScgd 		R0 ^= L0;  R1 ^= L1;
715e0b9a84aScgd 		L0 ^= R0;  L1 ^= R1;
716e0b9a84aScgd 	}
717e0b9a84aScgd 
718e0b9a84aScgd 	/* store the encrypted (or decrypted) result */
719e0b9a84aScgd 	L0 = ((L0 >> 3) & 0x0f0f0f0fL) | ((L1 << 1) & 0xf0f0f0f0L);
720e0b9a84aScgd 	L1 = ((R0 >> 3) & 0x0f0f0f0fL) | ((R1 << 1) & 0xf0f0f0f0L);
721e0b9a84aScgd 	STORE(L,L0,L1,B);
722e0b9a84aScgd 	PERM6464(L,L0,L1,B.b, (C_block *)CF6464);
723e0b9a84aScgd #if defined(MUST_ALIGN)
724e0b9a84aScgd 	STORE(L,L0,L1,B);
725e0b9a84aScgd 	out[0] = B.b[0]; out[1] = B.b[1]; out[2] = B.b[2]; out[3] = B.b[3];
726e0b9a84aScgd 	out[4] = B.b[4]; out[5] = B.b[5]; out[6] = B.b[6]; out[7] = B.b[7];
727e0b9a84aScgd #else
728e0b9a84aScgd 	STORE(L,L0,L1,*(C_block *)out);
729e0b9a84aScgd #endif
730e0b9a84aScgd 	return (0);
731e0b9a84aScgd }
732e0b9a84aScgd 
733e0b9a84aScgd 
734e0b9a84aScgd /*
735e0b9a84aScgd  * Initialize various tables.  This need only be done once.  It could even be
736e0b9a84aScgd  * done at compile time, if the compiler were capable of that sort of thing.
737e0b9a84aScgd  */
738e0b9a84aScgd STATIC
739e0b9a84aScgd init_des()
740e0b9a84aScgd {
74106795b86Slukem 	int i, j;
74206795b86Slukem 	int32_t k;
74306795b86Slukem 	int tableno;
744e0b9a84aScgd 	static unsigned char perm[64], tmp32[32];	/* "static" for speed */
745e0b9a84aScgd 
746e0b9a84aScgd 	/*
747e0b9a84aScgd 	 * table that converts chars "./0-9A-Za-z"to integers 0-63.
748e0b9a84aScgd 	 */
749e0b9a84aScgd 	for (i = 0; i < 64; i++)
750e0b9a84aScgd 		a64toi[itoa64[i]] = i;
751e0b9a84aScgd 
752e0b9a84aScgd 	/*
753e0b9a84aScgd 	 * PC1ROT - bit reverse, then PC1, then Rotate, then PC2.
754e0b9a84aScgd 	 */
755e0b9a84aScgd 	for (i = 0; i < 64; i++)
756e0b9a84aScgd 		perm[i] = 0;
757e0b9a84aScgd 	for (i = 0; i < 64; i++) {
758e0b9a84aScgd 		if ((k = PC2[i]) == 0)
759e0b9a84aScgd 			continue;
760e0b9a84aScgd 		k += Rotates[0]-1;
761e0b9a84aScgd 		if ((k%28) < Rotates[0]) k -= 28;
762e0b9a84aScgd 		k = PC1[k];
763e0b9a84aScgd 		if (k > 0) {
764e0b9a84aScgd 			k--;
765e0b9a84aScgd 			k = (k|07) - (k&07);
766e0b9a84aScgd 			k++;
767e0b9a84aScgd 		}
768e0b9a84aScgd 		perm[i] = k;
769e0b9a84aScgd 	}
770e0b9a84aScgd #ifdef DEBUG
771e0b9a84aScgd 	prtab("pc1tab", perm, 8);
772e0b9a84aScgd #endif
773e0b9a84aScgd 	init_perm(PC1ROT, perm, 8, 8);
774e0b9a84aScgd 
775e0b9a84aScgd 	/*
776e0b9a84aScgd 	 * PC2ROT - PC2 inverse, then Rotate (once or twice), then PC2.
777e0b9a84aScgd 	 */
778e0b9a84aScgd 	for (j = 0; j < 2; j++) {
779e0b9a84aScgd 		unsigned char pc2inv[64];
780e0b9a84aScgd 		for (i = 0; i < 64; i++)
781e0b9a84aScgd 			perm[i] = pc2inv[i] = 0;
782e0b9a84aScgd 		for (i = 0; i < 64; i++) {
783e0b9a84aScgd 			if ((k = PC2[i]) == 0)
784e0b9a84aScgd 				continue;
785e0b9a84aScgd 			pc2inv[k-1] = i+1;
786e0b9a84aScgd 		}
787e0b9a84aScgd 		for (i = 0; i < 64; i++) {
788e0b9a84aScgd 			if ((k = PC2[i]) == 0)
789e0b9a84aScgd 				continue;
790e0b9a84aScgd 			k += j;
791e0b9a84aScgd 			if ((k%28) <= j) k -= 28;
792e0b9a84aScgd 			perm[i] = pc2inv[k];
793e0b9a84aScgd 		}
794e0b9a84aScgd #ifdef DEBUG
795e0b9a84aScgd 		prtab("pc2tab", perm, 8);
796e0b9a84aScgd #endif
797e0b9a84aScgd 		init_perm(PC2ROT[j], perm, 8, 8);
798e0b9a84aScgd 	}
799e0b9a84aScgd 
800e0b9a84aScgd 	/*
801e0b9a84aScgd 	 * Bit reverse, then initial permutation, then expansion.
802e0b9a84aScgd 	 */
803e0b9a84aScgd 	for (i = 0; i < 8; i++) {
804e0b9a84aScgd 		for (j = 0; j < 8; j++) {
805e0b9a84aScgd 			k = (j < 2)? 0: IP[ExpandTr[i*6+j-2]-1];
806e0b9a84aScgd 			if (k > 32)
807e0b9a84aScgd 				k -= 32;
808e0b9a84aScgd 			else if (k > 0)
809e0b9a84aScgd 				k--;
810e0b9a84aScgd 			if (k > 0) {
811e0b9a84aScgd 				k--;
812e0b9a84aScgd 				k = (k|07) - (k&07);
813e0b9a84aScgd 				k++;
814e0b9a84aScgd 			}
815e0b9a84aScgd 			perm[i*8+j] = k;
816e0b9a84aScgd 		}
817e0b9a84aScgd 	}
818e0b9a84aScgd #ifdef DEBUG
819e0b9a84aScgd 	prtab("ietab", perm, 8);
820e0b9a84aScgd #endif
821e0b9a84aScgd 	init_perm(IE3264, perm, 4, 8);
822e0b9a84aScgd 
823e0b9a84aScgd 	/*
824e0b9a84aScgd 	 * Compression, then final permutation, then bit reverse.
825e0b9a84aScgd 	 */
826e0b9a84aScgd 	for (i = 0; i < 64; i++) {
827e0b9a84aScgd 		k = IP[CIFP[i]-1];
828e0b9a84aScgd 		if (k > 0) {
829e0b9a84aScgd 			k--;
830e0b9a84aScgd 			k = (k|07) - (k&07);
831e0b9a84aScgd 			k++;
832e0b9a84aScgd 		}
833e0b9a84aScgd 		perm[k-1] = i+1;
834e0b9a84aScgd 	}
835e0b9a84aScgd #ifdef DEBUG
836e0b9a84aScgd 	prtab("cftab", perm, 8);
837e0b9a84aScgd #endif
838e0b9a84aScgd 	init_perm(CF6464, perm, 8, 8);
839e0b9a84aScgd 
840e0b9a84aScgd 	/*
841e0b9a84aScgd 	 * SPE table
842e0b9a84aScgd 	 */
843e0b9a84aScgd 	for (i = 0; i < 48; i++)
844e0b9a84aScgd 		perm[i] = P32Tr[ExpandTr[i]-1];
845e0b9a84aScgd 	for (tableno = 0; tableno < 8; tableno++) {
846e0b9a84aScgd 		for (j = 0; j < 64; j++)  {
847e0b9a84aScgd 			k = (((j >> 0) &01) << 5)|
848e0b9a84aScgd 			    (((j >> 1) &01) << 3)|
849e0b9a84aScgd 			    (((j >> 2) &01) << 2)|
850e0b9a84aScgd 			    (((j >> 3) &01) << 1)|
851e0b9a84aScgd 			    (((j >> 4) &01) << 0)|
852e0b9a84aScgd 			    (((j >> 5) &01) << 4);
853e0b9a84aScgd 			k = S[tableno][k];
854e0b9a84aScgd 			k = (((k >> 3)&01) << 0)|
855e0b9a84aScgd 			    (((k >> 2)&01) << 1)|
856e0b9a84aScgd 			    (((k >> 1)&01) << 2)|
857e0b9a84aScgd 			    (((k >> 0)&01) << 3);
858e0b9a84aScgd 			for (i = 0; i < 32; i++)
859e0b9a84aScgd 				tmp32[i] = 0;
860e0b9a84aScgd 			for (i = 0; i < 4; i++)
861e0b9a84aScgd 				tmp32[4 * tableno + i] = (k >> i) & 01;
862e0b9a84aScgd 			k = 0;
863e0b9a84aScgd 			for (i = 24; --i >= 0; )
864e0b9a84aScgd 				k = (k<<1) | tmp32[perm[i]-1];
865e0b9a84aScgd 			TO_SIX_BIT(SPE[0][tableno][j], k);
866e0b9a84aScgd 			k = 0;
867e0b9a84aScgd 			for (i = 24; --i >= 0; )
868e0b9a84aScgd 				k = (k<<1) | tmp32[perm[i+24]-1];
869e0b9a84aScgd 			TO_SIX_BIT(SPE[1][tableno][j], k);
870e0b9a84aScgd 		}
871e0b9a84aScgd 	}
872e0b9a84aScgd }
873e0b9a84aScgd 
874e0b9a84aScgd /*
875e0b9a84aScgd  * Initialize "perm" to represent transformation "p", which rearranges
876e0b9a84aScgd  * (perhaps with expansion and/or contraction) one packed array of bits
877e0b9a84aScgd  * (of size "chars_in" characters) into another array (of size "chars_out"
878e0b9a84aScgd  * characters).
879e0b9a84aScgd  *
880e0b9a84aScgd  * "perm" must be all-zeroes on entry to this routine.
881e0b9a84aScgd  */
882e0b9a84aScgd STATIC
883e0b9a84aScgd init_perm(perm, p, chars_in, chars_out)
884e0b9a84aScgd 	C_block perm[64/CHUNKBITS][1<<CHUNKBITS];
885e0b9a84aScgd 	unsigned char p[64];
886e0b9a84aScgd 	int chars_in, chars_out;
887e0b9a84aScgd {
88806795b86Slukem 	int i, j, k, l;
889e0b9a84aScgd 
890e0b9a84aScgd 	for (k = 0; k < chars_out*8; k++) {	/* each output bit position */
891e0b9a84aScgd 		l = p[k] - 1;		/* where this bit comes from */
892e0b9a84aScgd 		if (l < 0)
893e0b9a84aScgd 			continue;	/* output bit is always 0 */
894e0b9a84aScgd 		i = l>>LGCHUNKBITS;	/* which chunk this bit comes from */
895e0b9a84aScgd 		l = 1<<(l&(CHUNKBITS-1));	/* mask for this bit */
896e0b9a84aScgd 		for (j = 0; j < (1<<CHUNKBITS); j++) {	/* each chunk value */
897e0b9a84aScgd 			if ((j & l) != 0)
898e0b9a84aScgd 				perm[i][j].b[k>>3] |= 1<<(k&07);
899e0b9a84aScgd 		}
900e0b9a84aScgd 	}
901e0b9a84aScgd }
902e0b9a84aScgd 
903e0b9a84aScgd /*
904e0b9a84aScgd  * "setkey" routine (for backwards compatibility)
905e0b9a84aScgd  */
90631a2bdc6Smikel int
907e0b9a84aScgd setkey(key)
90806795b86Slukem 	const char *key;
909e0b9a84aScgd {
91006795b86Slukem 	int i, j, k;
911e0b9a84aScgd 	C_block keyblock;
912e0b9a84aScgd 
913e0b9a84aScgd 	for (i = 0; i < 8; i++) {
914e0b9a84aScgd 		k = 0;
915e0b9a84aScgd 		for (j = 0; j < 8; j++) {
916e0b9a84aScgd 			k <<= 1;
917e0b9a84aScgd 			k |= (unsigned char)*key++;
918e0b9a84aScgd 		}
919e0b9a84aScgd 		keyblock.b[i] = k;
920e0b9a84aScgd 	}
921e0b9a84aScgd 	return (des_setkey((char *)keyblock.b));
922e0b9a84aScgd }
923e0b9a84aScgd 
924e0b9a84aScgd /*
925e0b9a84aScgd  * "encrypt" routine (for backwards compatibility)
926e0b9a84aScgd  */
92731a2bdc6Smikel int
928e0b9a84aScgd encrypt(block, flag)
92906795b86Slukem 	char *block;
930e0b9a84aScgd 	int flag;
931e0b9a84aScgd {
93206795b86Slukem 	int i, j, k;
933e0b9a84aScgd 	C_block cblock;
934e0b9a84aScgd 
935e0b9a84aScgd 	for (i = 0; i < 8; i++) {
936e0b9a84aScgd 		k = 0;
937e0b9a84aScgd 		for (j = 0; j < 8; j++) {
938e0b9a84aScgd 			k <<= 1;
939e0b9a84aScgd 			k |= (unsigned char)*block++;
940e0b9a84aScgd 		}
941e0b9a84aScgd 		cblock.b[i] = k;
942e0b9a84aScgd 	}
943e0b9a84aScgd 	if (des_cipher((char *)&cblock, (char *)&cblock, 0L, (flag ? -1: 1)))
944e0b9a84aScgd 		return (1);
945e0b9a84aScgd 	for (i = 7; i >= 0; i--) {
946e0b9a84aScgd 		k = cblock.b[i];
947e0b9a84aScgd 		for (j = 7; j >= 0; j--) {
948e0b9a84aScgd 			*--block = k&01;
949e0b9a84aScgd 			k >>= 1;
950e0b9a84aScgd 		}
951e0b9a84aScgd 	}
952e0b9a84aScgd 	return (0);
953e0b9a84aScgd }
954e0b9a84aScgd 
955e0b9a84aScgd #ifdef DEBUG
956e0b9a84aScgd STATIC
957e0b9a84aScgd prtab(s, t, num_rows)
958e0b9a84aScgd 	char *s;
959e0b9a84aScgd 	unsigned char *t;
960e0b9a84aScgd 	int num_rows;
961e0b9a84aScgd {
96206795b86Slukem 	int i, j;
963e0b9a84aScgd 
964e0b9a84aScgd 	(void)printf("%s:\n", s);
965e0b9a84aScgd 	for (i = 0; i < num_rows; i++) {
966e0b9a84aScgd 		for (j = 0; j < 8; j++) {
967e0b9a84aScgd 			 (void)printf("%3d", t[i*8+j]);
968e0b9a84aScgd 		}
969e0b9a84aScgd 		(void)printf("\n");
970e0b9a84aScgd 	}
971e0b9a84aScgd 	(void)printf("\n");
972e0b9a84aScgd }
973e0b9a84aScgd #endif
974