xref: /netbsd-src/lib/libcrypt/crypt.c (revision 4d92dbe90eae91beded70db613c2e6a1fd6dd84a)
1*4d92dbe9Sriastradh /*	$NetBSD: crypt.c,v 1.41 2024/07/23 22:37:11 riastradh 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.
18eb7c1594Sagc  * 3. Neither the name of the University nor the names of its contributors
19e0b9a84aScgd  *    may be used to endorse or promote products derived from this software
20e0b9a84aScgd  *    without specific prior written permission.
21e0b9a84aScgd  *
22e0b9a84aScgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23e0b9a84aScgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24e0b9a84aScgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25e0b9a84aScgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26e0b9a84aScgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27e0b9a84aScgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28e0b9a84aScgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29e0b9a84aScgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30e0b9a84aScgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31e0b9a84aScgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32e0b9a84aScgd  * SUCH DAMAGE.
33e0b9a84aScgd  */
34e0b9a84aScgd 
3506795b86Slukem #include <sys/cdefs.h>
3606795b86Slukem #if !defined(lint)
374902ac3dScgd #if 0
384902ac3dScgd static char sccsid[] = "@(#)crypt.c	8.1.1.1 (Berkeley) 8/18/93";
3906795b86Slukem #else
40*4d92dbe9Sriastradh __RCSID("$NetBSD: crypt.c,v 1.41 2024/07/23 22:37:11 riastradh Exp $");
414902ac3dScgd #endif
4206795b86Slukem #endif /* not lint */
43e0b9a84aScgd 
44e0b9a84aScgd #include <limits.h>
45e0b9a84aScgd #include <pwd.h>
4656545abaSkleink #include <stdlib.h>
47c7ab523eSjhigh #include <string.h> /* for strcmp */
4831a2bdc6Smikel #include <unistd.h>
4955ac93d3Shubertf #if defined(DEBUG) || defined(MAIN) || defined(UNIT_TEST)
50a0d45c26Schristos #include <stdio.h>
51a0d45c26Schristos #endif
52e0b9a84aScgd 
533a0c68edSsjg #include "crypt.h"
543a0c68edSsjg 
55e0b9a84aScgd /*
56e0b9a84aScgd  * UNIX password, and DES, encryption.
57e0b9a84aScgd  * By Tom Truscott, trt@rti.rti.org,
58e0b9a84aScgd  * from algorithms by Robert W. Baldwin and James Gillogly.
59e0b9a84aScgd  *
60e0b9a84aScgd  * References:
61e0b9a84aScgd  * "Mathematical Cryptology for Computer Scientists and Mathematicians,"
62e0b9a84aScgd  * by Wayne Patterson, 1987, ISBN 0-8476-7438-X.
63e0b9a84aScgd  *
64e0b9a84aScgd  * "Password Security: A Case History," R. Morris and Ken Thompson,
65e0b9a84aScgd  * Communications of the ACM, vol. 22, pp. 594-597, Nov. 1979.
66e0b9a84aScgd  *
67e0b9a84aScgd  * "DES will be Totally Insecure within Ten Years," M.E. Hellman,
68e0b9a84aScgd  * IEEE Spectrum, vol. 16, pp. 32-39, July 1979.
69e0b9a84aScgd  */
70e0b9a84aScgd 
71e0b9a84aScgd /* =====  Configuration ==================== */
72e0b9a84aScgd 
73e0b9a84aScgd /*
74e0b9a84aScgd  * define "MUST_ALIGN" if your compiler cannot load/store
75e0b9a84aScgd  * long integers at arbitrary (e.g. odd) memory locations.
76e0b9a84aScgd  * (Either that or never pass unaligned addresses to des_cipher!)
77e0b9a84aScgd  */
7859695352Smatt #if !defined(__vax__) && !defined(__i386__)
79e0b9a84aScgd #define	MUST_ALIGN
80e0b9a84aScgd #endif
81e0b9a84aScgd 
82e0b9a84aScgd #ifdef CHAR_BITS
83e0b9a84aScgd #if CHAR_BITS != 8
84e0b9a84aScgd 	#error C_block structure assumes 8 bit characters
85e0b9a84aScgd #endif
86e0b9a84aScgd #endif
87e0b9a84aScgd 
88e0b9a84aScgd /*
89e0b9a84aScgd  * define "B64" to be the declaration for a 64 bit integer.
90e0b9a84aScgd  * XXX this feature is currently unused, see "endian" comment below.
91e0b9a84aScgd  */
92e0b9a84aScgd #if defined(cray)
93e0b9a84aScgd #define	B64	long
94e0b9a84aScgd #endif
95e0b9a84aScgd #if defined(convex)
96e0b9a84aScgd #define	B64	long long
97e0b9a84aScgd #endif
98e0b9a84aScgd 
99e0b9a84aScgd /*
100e0b9a84aScgd  * define "LARGEDATA" to get faster permutations, by using about 72 kilobytes
101e0b9a84aScgd  * of lookup tables.  This speeds up des_setkey() and des_cipher(), but has
102e0b9a84aScgd  * little effect on crypt().
103e0b9a84aScgd  */
104e0b9a84aScgd #if defined(notdef)
105e0b9a84aScgd #define	LARGEDATA
106e0b9a84aScgd #endif
107e0b9a84aScgd 
10831a2bdc6Smikel /* compile with "-DSTATIC=void" when profiling */
109e0b9a84aScgd #ifndef STATIC
11031a2bdc6Smikel #define	STATIC	static void
111e0b9a84aScgd #endif
112e0b9a84aScgd 
113e0b9a84aScgd /* ==================================== */
114e0b9a84aScgd 
115e0b9a84aScgd /*
116e0b9a84aScgd  * Cipher-block representation (Bob Baldwin):
117e0b9a84aScgd  *
118e0b9a84aScgd  * DES operates on groups of 64 bits, numbered 1..64 (sigh).  One
119e0b9a84aScgd  * representation is to store one bit per byte in an array of bytes.  Bit N of
120e0b9a84aScgd  * the NBS spec is stored as the LSB of the Nth byte (index N-1) in the array.
121e0b9a84aScgd  * Another representation stores the 64 bits in 8 bytes, with bits 1..8 in the
122e0b9a84aScgd  * first byte, 9..16 in the second, and so on.  The DES spec apparently has
123e0b9a84aScgd  * bit 1 in the MSB of the first byte, but that is particularly noxious so we
124e0b9a84aScgd  * bit-reverse each byte so that bit 1 is the LSB of the first byte, bit 8 is
125e0b9a84aScgd  * the MSB of the first byte.  Specifically, the 64-bit input data and key are
126e0b9a84aScgd  * converted to LSB format, and the output 64-bit block is converted back into
127e0b9a84aScgd  * MSB format.
128e0b9a84aScgd  *
129e0b9a84aScgd  * DES operates internally on groups of 32 bits which are expanded to 48 bits
130e0b9a84aScgd  * by permutation E and shrunk back to 32 bits by the S boxes.  To speed up
131e0b9a84aScgd  * the computation, the expansion is applied only once, the expanded
132e0b9a84aScgd  * representation is maintained during the encryption, and a compression
133e0b9a84aScgd  * permutation is applied only at the end.  To speed up the S-box lookups,
134e0b9a84aScgd  * the 48 bits are maintained as eight 6 bit groups, one per byte, which
135e0b9a84aScgd  * directly feed the eight S-boxes.  Within each byte, the 6 bits are the
136e0b9a84aScgd  * most significant ones.  The low two bits of each byte are zero.  (Thus,
137e0b9a84aScgd  * bit 1 of the 48 bit E expansion is stored as the "4"-valued bit of the
138e0b9a84aScgd  * first byte in the eight byte representation, bit 2 of the 48 bit value is
139e0b9a84aScgd  * the "8"-valued bit, and so on.)  In fact, a combined "SPE"-box lookup is
140e0b9a84aScgd  * used, in which the output is the 64 bit result of an S-box lookup which
141e0b9a84aScgd  * has been permuted by P and expanded by E, and is ready for use in the next
142e0b9a84aScgd  * iteration.  Two 32-bit wide tables, SPE[0] and SPE[1], are used for this
143e0b9a84aScgd  * lookup.  Since each byte in the 48 bit path is a multiple of four, indexed
144e0b9a84aScgd  * lookup of SPE[0] and SPE[1] is simple and fast.  The key schedule and
145e0b9a84aScgd  * "salt" are also converted to this 8*(6+2) format.  The SPE table size is
146e0b9a84aScgd  * 8*64*8 = 4K bytes.
147e0b9a84aScgd  *
148e0b9a84aScgd  * To speed up bit-parallel operations (such as XOR), the 8 byte
149e0b9a84aScgd  * representation is "union"ed with 32 bit values "i0" and "i1", and, on
150e0b9a84aScgd  * machines which support it, a 64 bit value "b64".  This data structure,
151e0b9a84aScgd  * "C_block", has two problems.  First, alignment restrictions must be
152e0b9a84aScgd  * honored.  Second, the byte-order (e.g. little-endian or big-endian) of
153e0b9a84aScgd  * the architecture becomes visible.
154e0b9a84aScgd  *
155e0b9a84aScgd  * The byte-order problem is unfortunate, since on the one hand it is good
156e0b9a84aScgd  * to have a machine-independent C_block representation (bits 1..8 in the
157e0b9a84aScgd  * first byte, etc.), and on the other hand it is good for the LSB of the
158e0b9a84aScgd  * first byte to be the LSB of i0.  We cannot have both these things, so we
159e0b9a84aScgd  * currently use the "little-endian" representation and avoid any multi-byte
160e0b9a84aScgd  * operations that depend on byte order.  This largely precludes use of the
161e0b9a84aScgd  * 64-bit datatype since the relative order of i0 and i1 are unknown.  It
162e0b9a84aScgd  * also inhibits grouping the SPE table to look up 12 bits at a time.  (The
163e0b9a84aScgd  * 12 bits can be stored in a 16-bit field with 3 low-order zeroes and 1
164e0b9a84aScgd  * high-order zero, providing fast indexing into a 64-bit wide SPE.)  On the
165e0b9a84aScgd  * other hand, 64-bit datatypes are currently rare, and a 12-bit SPE lookup
166e0b9a84aScgd  * requires a 128 kilobyte table, so perhaps this is not a big loss.
167e0b9a84aScgd  *
168e0b9a84aScgd  * Permutation representation (Jim Gillogly):
169e0b9a84aScgd  *
170e0b9a84aScgd  * A transformation is defined by its effect on each of the 8 bytes of the
171e0b9a84aScgd  * 64-bit input.  For each byte we give a 64-bit output that has the bits in
172e0b9a84aScgd  * the input distributed appropriately.  The transformation is then the OR
173e0b9a84aScgd  * of the 8 sets of 64-bits.  This uses 8*256*8 = 16K bytes of storage for
174e0b9a84aScgd  * each transformation.  Unless LARGEDATA is defined, however, a more compact
175e0b9a84aScgd  * table is used which looks up 16 4-bit "chunks" rather than 8 8-bit chunks.
176e0b9a84aScgd  * The smaller table uses 16*16*8 = 2K bytes for each transformation.  This
177e0b9a84aScgd  * is slower but tolerable, particularly for password encryption in which
178e0b9a84aScgd  * the SPE transformation is iterated many times.  The small tables total 9K
179e0b9a84aScgd  * bytes, the large tables total 72K bytes.
180e0b9a84aScgd  *
181e0b9a84aScgd  * The transformations used are:
182e0b9a84aScgd  * IE3264: MSB->LSB conversion, initial permutation, and expansion.
183e0b9a84aScgd  *	This is done by collecting the 32 even-numbered bits and applying
184e0b9a84aScgd  *	a 32->64 bit transformation, and then collecting the 32 odd-numbered
185e0b9a84aScgd  *	bits and applying the same transformation.  Since there are only
186e0b9a84aScgd  *	32 input bits, the IE3264 transformation table is half the size of
187e0b9a84aScgd  *	the usual table.
188e0b9a84aScgd  * CF6464: Compression, final permutation, and LSB->MSB conversion.
189e0b9a84aScgd  *	This is done by two trivial 48->32 bit compressions to obtain
190e0b9a84aScgd  *	a 64-bit block (the bit numbering is given in the "CIFP" table)
191e0b9a84aScgd  *	followed by a 64->64 bit "cleanup" transformation.  (It would
192e0b9a84aScgd  *	be possible to group the bits in the 64-bit block so that 2
193e0b9a84aScgd  *	identical 32->32 bit transformations could be used instead,
194e0b9a84aScgd  *	saving a factor of 4 in space and possibly 2 in time, but
195e0b9a84aScgd  *	byte-ordering and other complications rear their ugly head.
196e0b9a84aScgd  *	Similar opportunities/problems arise in the key schedule
197e0b9a84aScgd  *	transforms.)
198e0b9a84aScgd  * PC1ROT: MSB->LSB, PC1 permutation, rotate, and PC2 permutation.
199e0b9a84aScgd  *	This admittedly baroque 64->64 bit transformation is used to
200e0b9a84aScgd  *	produce the first code (in 8*(6+2) format) of the key schedule.
201e0b9a84aScgd  * PC2ROT[0]: Inverse PC2 permutation, rotate, and PC2 permutation.
202e0b9a84aScgd  *	It would be possible to define 15 more transformations, each
203e0b9a84aScgd  *	with a different rotation, to generate the entire key schedule.
204e0b9a84aScgd  *	To save space, however, we instead permute each code into the
205e0b9a84aScgd  *	next by using a transformation that "undoes" the PC2 permutation,
206e0b9a84aScgd  *	rotates the code, and then applies PC2.  Unfortunately, PC2
207e0b9a84aScgd  *	transforms 56 bits into 48 bits, dropping 8 bits, so PC2 is not
208e0b9a84aScgd  *	invertible.  We get around that problem by using a modified PC2
209e0b9a84aScgd  *	which retains the 8 otherwise-lost bits in the unused low-order
210e0b9a84aScgd  *	bits of each byte.  The low-order bits are cleared when the
211e0b9a84aScgd  *	codes are stored into the key schedule.
212e0b9a84aScgd  * PC2ROT[1]: Same as PC2ROT[0], but with two rotations.
213e0b9a84aScgd  *	This is faster than applying PC2ROT[0] twice,
214e0b9a84aScgd  *
215e0b9a84aScgd  * The Bell Labs "salt" (Bob Baldwin):
216e0b9a84aScgd  *
217e0b9a84aScgd  * The salting is a simple permutation applied to the 48-bit result of E.
218e0b9a84aScgd  * Specifically, if bit i (1 <= i <= 24) of the salt is set then bits i and
219e0b9a84aScgd  * i+24 of the result are swapped.  The salt is thus a 24 bit number, with
220e0b9a84aScgd  * 16777216 possible values.  (The original salt was 12 bits and could not
221e0b9a84aScgd  * swap bits 13..24 with 36..48.)
222e0b9a84aScgd  *
223e0b9a84aScgd  * It is possible, but ugly, to warp the SPE table to account for the salt
224e0b9a84aScgd  * permutation.  Fortunately, the conditional bit swapping requires only
225e0b9a84aScgd  * about four machine instructions and can be done on-the-fly with about an
226e0b9a84aScgd  * 8% performance penalty.
227e0b9a84aScgd  */
228e0b9a84aScgd 
229e0b9a84aScgd typedef union {
230e0b9a84aScgd 	unsigned char b[8];
231e0b9a84aScgd 	struct {
232688980ebScgd 		int32_t	i0;
233688980ebScgd 		int32_t	i1;
234e0b9a84aScgd 	} b32;
235e0b9a84aScgd #if defined(B64)
236e0b9a84aScgd 	B64	b64;
237e0b9a84aScgd #endif
238e0b9a84aScgd } C_block;
239e0b9a84aScgd 
240e0b9a84aScgd /*
241e0b9a84aScgd  * Convert twenty-four-bit long in host-order
242e0b9a84aScgd  * to six bits (and 2 low-order zeroes) per char little-endian format.
243e0b9a84aScgd  */
244e0b9a84aScgd #define	TO_SIX_BIT(rslt, src) {				\
245e0b9a84aScgd 		C_block cvt;				\
246e0b9a84aScgd 		cvt.b[0] = src; src >>= 6;		\
247e0b9a84aScgd 		cvt.b[1] = src; src >>= 6;		\
248e0b9a84aScgd 		cvt.b[2] = src; src >>= 6;		\
249e0b9a84aScgd 		cvt.b[3] = src;				\
250e0b9a84aScgd 		rslt = (cvt.b32.i0 & 0x3f3f3f3fL) << 2;	\
251e0b9a84aScgd 	}
252e0b9a84aScgd 
253e0b9a84aScgd /*
254e0b9a84aScgd  * These macros may someday permit efficient use of 64-bit integers.
255e0b9a84aScgd  */
256e0b9a84aScgd #define	ZERO(d,d0,d1)			d0 = 0, d1 = 0
257e0b9a84aScgd #define	LOAD(d,d0,d1,bl)		d0 = (bl).b32.i0, d1 = (bl).b32.i1
258e0b9a84aScgd #define	LOADREG(d,d0,d1,s,s0,s1)	d0 = s0, d1 = s1
259e0b9a84aScgd #define	OR(d,d0,d1,bl)			d0 |= (bl).b32.i0, d1 |= (bl).b32.i1
260e0b9a84aScgd #define	STORE(s,s0,s1,bl)		(bl).b32.i0 = s0, (bl).b32.i1 = s1
261688980ebScgd #define	DCL_BLOCK(d,d0,d1)		int32_t d0, d1
262e0b9a84aScgd 
263e0b9a84aScgd #if defined(LARGEDATA)
264e0b9a84aScgd 	/* Waste memory like crazy.  Also, do permutations in line */
265e0b9a84aScgd #define	LGCHUNKBITS	3
266e0b9a84aScgd #define	CHUNKBITS	(1<<LGCHUNKBITS)
267e0b9a84aScgd #define	PERM6464(d,d0,d1,cpp,p)				\
268e0b9a84aScgd 	LOAD(d,d0,d1,(p)[(0<<CHUNKBITS)+(cpp)[0]]);		\
269e0b9a84aScgd 	OR (d,d0,d1,(p)[(1<<CHUNKBITS)+(cpp)[1]]);		\
270e0b9a84aScgd 	OR (d,d0,d1,(p)[(2<<CHUNKBITS)+(cpp)[2]]);		\
271e0b9a84aScgd 	OR (d,d0,d1,(p)[(3<<CHUNKBITS)+(cpp)[3]]);		\
272e0b9a84aScgd 	OR (d,d0,d1,(p)[(4<<CHUNKBITS)+(cpp)[4]]);		\
273e0b9a84aScgd 	OR (d,d0,d1,(p)[(5<<CHUNKBITS)+(cpp)[5]]);		\
274e0b9a84aScgd 	OR (d,d0,d1,(p)[(6<<CHUNKBITS)+(cpp)[6]]);		\
275e0b9a84aScgd 	OR (d,d0,d1,(p)[(7<<CHUNKBITS)+(cpp)[7]]);
276e0b9a84aScgd #define	PERM3264(d,d0,d1,cpp,p)				\
277e0b9a84aScgd 	LOAD(d,d0,d1,(p)[(0<<CHUNKBITS)+(cpp)[0]]);		\
278e0b9a84aScgd 	OR (d,d0,d1,(p)[(1<<CHUNKBITS)+(cpp)[1]]);		\
279e0b9a84aScgd 	OR (d,d0,d1,(p)[(2<<CHUNKBITS)+(cpp)[2]]);		\
280e0b9a84aScgd 	OR (d,d0,d1,(p)[(3<<CHUNKBITS)+(cpp)[3]]);
281e0b9a84aScgd #else
282e0b9a84aScgd 	/* "small data" */
283e0b9a84aScgd #define	LGCHUNKBITS	2
284e0b9a84aScgd #define	CHUNKBITS	(1<<LGCHUNKBITS)
285e0b9a84aScgd #define	PERM6464(d,d0,d1,cpp,p)				\
286e0b9a84aScgd 	{ C_block tblk; permute(cpp,&tblk,p,8); LOAD (d,d0,d1,tblk); }
287e0b9a84aScgd #define	PERM3264(d,d0,d1,cpp,p)				\
288e0b9a84aScgd 	{ C_block tblk; permute(cpp,&tblk,p,4); LOAD (d,d0,d1,tblk); }
289cd0a22a4Smikel #endif /* LARGEDATA */
29006795b86Slukem 
291b34e9d9fSperry STATIC	init_des(void);
292b34e9d9fSperry STATIC	init_perm(C_block [64/CHUNKBITS][1<<CHUNKBITS],
293b34e9d9fSperry 		       const unsigned char [64], int, int);
294cd0a22a4Smikel #ifndef LARGEDATA
295b34e9d9fSperry STATIC	permute(const unsigned char *, C_block *, C_block *, int);
296cd0a22a4Smikel #endif
29706795b86Slukem #ifdef DEBUG
298b34e9d9fSperry STATIC	prtab(const char *, unsigned char *, int);
29906795b86Slukem #endif
30006795b86Slukem 
30106795b86Slukem 
302cd0a22a4Smikel #ifndef LARGEDATA
303e0b9a84aScgd STATIC
30459153410Sperry permute(const unsigned char *cp, C_block *out, C_block *p, int chars_in)
305e0b9a84aScgd {
30606795b86Slukem 	DCL_BLOCK(D,D0,D1);
30706795b86Slukem 	C_block *tp;
30806795b86Slukem 	int t;
309e0b9a84aScgd 
310e0b9a84aScgd 	ZERO(D,D0,D1);
311e0b9a84aScgd 	do {
312e0b9a84aScgd 		t = *cp++;
313e0b9a84aScgd 		tp = &p[t&0xf]; OR(D,D0,D1,*tp); p += (1<<CHUNKBITS);
314e0b9a84aScgd 		tp = &p[t>>4];  OR(D,D0,D1,*tp); p += (1<<CHUNKBITS);
315e0b9a84aScgd 	} while (--chars_in > 0);
316e0b9a84aScgd 	STORE(D,D0,D1,*out);
317e0b9a84aScgd }
318e0b9a84aScgd #endif /* LARGEDATA */
319e0b9a84aScgd 
320e0b9a84aScgd 
321e0b9a84aScgd /* =====  (mostly) Standard DES Tables ==================== */
322e0b9a84aScgd 
323d7d75e06Sjdolecek static const unsigned char IP[] = {	/* initial permutation */
324e0b9a84aScgd 	58, 50, 42, 34, 26, 18, 10,  2,
325e0b9a84aScgd 	60, 52, 44, 36, 28, 20, 12,  4,
326e0b9a84aScgd 	62, 54, 46, 38, 30, 22, 14,  6,
327e0b9a84aScgd 	64, 56, 48, 40, 32, 24, 16,  8,
328e0b9a84aScgd 	57, 49, 41, 33, 25, 17,  9,  1,
329e0b9a84aScgd 	59, 51, 43, 35, 27, 19, 11,  3,
330e0b9a84aScgd 	61, 53, 45, 37, 29, 21, 13,  5,
331e0b9a84aScgd 	63, 55, 47, 39, 31, 23, 15,  7,
332e0b9a84aScgd };
333e0b9a84aScgd 
334e0b9a84aScgd /* The final permutation is the inverse of IP - no table is necessary */
335e0b9a84aScgd 
336d7d75e06Sjdolecek static const unsigned char ExpandTr[] = {	/* expansion operation */
337e0b9a84aScgd 	32,  1,  2,  3,  4,  5,
338e0b9a84aScgd 	 4,  5,  6,  7,  8,  9,
339e0b9a84aScgd 	 8,  9, 10, 11, 12, 13,
340e0b9a84aScgd 	12, 13, 14, 15, 16, 17,
341e0b9a84aScgd 	16, 17, 18, 19, 20, 21,
342e0b9a84aScgd 	20, 21, 22, 23, 24, 25,
343e0b9a84aScgd 	24, 25, 26, 27, 28, 29,
344e0b9a84aScgd 	28, 29, 30, 31, 32,  1,
345e0b9a84aScgd };
346e0b9a84aScgd 
347d7d75e06Sjdolecek static const unsigned char PC1[] = {	/* permuted choice table 1 */
348e0b9a84aScgd 	57, 49, 41, 33, 25, 17,  9,
349e0b9a84aScgd 	 1, 58, 50, 42, 34, 26, 18,
350e0b9a84aScgd 	10,  2, 59, 51, 43, 35, 27,
351e0b9a84aScgd 	19, 11,  3, 60, 52, 44, 36,
352e0b9a84aScgd 
353e0b9a84aScgd 	63, 55, 47, 39, 31, 23, 15,
354e0b9a84aScgd 	 7, 62, 54, 46, 38, 30, 22,
355e0b9a84aScgd 	14,  6, 61, 53, 45, 37, 29,
356e0b9a84aScgd 	21, 13,  5, 28, 20, 12,  4,
357e0b9a84aScgd };
358e0b9a84aScgd 
359d7d75e06Sjdolecek static const unsigned char Rotates[] = {/* PC1 rotation schedule */
360e0b9a84aScgd 	1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1,
361e0b9a84aScgd };
362e0b9a84aScgd 
363e0b9a84aScgd /* note: each "row" of PC2 is left-padded with bits that make it invertible */
364d7d75e06Sjdolecek static const unsigned char PC2[] = {	/* permuted choice table 2 */
365e0b9a84aScgd 	 9, 18,    14, 17, 11, 24,  1,  5,
366e0b9a84aScgd 	22, 25,     3, 28, 15,  6, 21, 10,
367e0b9a84aScgd 	35, 38,    23, 19, 12,  4, 26,  8,
368e0b9a84aScgd 	43, 54,    16,  7, 27, 20, 13,  2,
369e0b9a84aScgd 
370e0b9a84aScgd 	 0,  0,    41, 52, 31, 37, 47, 55,
371e0b9a84aScgd 	 0,  0,    30, 40, 51, 45, 33, 48,
372e0b9a84aScgd 	 0,  0,    44, 49, 39, 56, 34, 53,
373e0b9a84aScgd 	 0,  0,    46, 42, 50, 36, 29, 32,
374e0b9a84aScgd };
375e0b9a84aScgd 
376d7d75e06Sjdolecek static const unsigned char S[8][64] = {	/* 48->32 bit substitution tables */
377e0b9a84aScgd 					/* S[1]			*/
37831a2bdc6Smikel 	{ 14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7,
379e0b9a84aScgd 	   0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8,
380e0b9a84aScgd 	   4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0,
38131a2bdc6Smikel 	  15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13 },
382e0b9a84aScgd 					/* S[2]			*/
38331a2bdc6Smikel 	{ 15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10,
384e0b9a84aScgd 	   3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5,
385e0b9a84aScgd 	   0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15,
38631a2bdc6Smikel 	  13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9 },
387e0b9a84aScgd 					/* S[3]			*/
38831a2bdc6Smikel 	{ 10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8,
389e0b9a84aScgd 	  13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1,
390e0b9a84aScgd 	  13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7,
39131a2bdc6Smikel 	   1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12 },
392e0b9a84aScgd 					/* S[4]			*/
39331a2bdc6Smikel 	{  7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15,
394e0b9a84aScgd 	  13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9,
395e0b9a84aScgd 	  10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4,
39631a2bdc6Smikel 	   3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14 },
397e0b9a84aScgd 					/* S[5]			*/
39831a2bdc6Smikel 	{  2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9,
399e0b9a84aScgd 	  14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6,
400e0b9a84aScgd 	   4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14,
40131a2bdc6Smikel 	  11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3 },
402e0b9a84aScgd 					/* S[6]			*/
40331a2bdc6Smikel 	{ 12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11,
404e0b9a84aScgd 	  10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8,
405e0b9a84aScgd 	   9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6,
40631a2bdc6Smikel 	   4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13 },
407e0b9a84aScgd 					/* S[7]			*/
40831a2bdc6Smikel 	{  4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1,
409e0b9a84aScgd 	  13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6,
410e0b9a84aScgd 	   1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2,
41131a2bdc6Smikel 	   6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12 },
412e0b9a84aScgd 					/* S[8]			*/
41331a2bdc6Smikel 	{ 13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7,
414e0b9a84aScgd 	   1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2,
415e0b9a84aScgd 	   7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8,
41631a2bdc6Smikel 	   2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11 }
417e0b9a84aScgd };
418e0b9a84aScgd 
419d7d75e06Sjdolecek static const unsigned char P32Tr[] = {	/* 32-bit permutation function */
420e0b9a84aScgd 	16,  7, 20, 21,
421e0b9a84aScgd 	29, 12, 28, 17,
422e0b9a84aScgd 	 1, 15, 23, 26,
423e0b9a84aScgd 	 5, 18, 31, 10,
424e0b9a84aScgd 	 2,  8, 24, 14,
425e0b9a84aScgd 	32, 27,  3,  9,
426e0b9a84aScgd 	19, 13, 30,  6,
427e0b9a84aScgd 	22, 11,  4, 25,
428e0b9a84aScgd };
429e0b9a84aScgd 
430d7d75e06Sjdolecek static const unsigned char CIFP[] = {	/* compressed/interleaved permutation */
431e0b9a84aScgd 	 1,  2,  3,  4,   17, 18, 19, 20,
432e0b9a84aScgd 	 5,  6,  7,  8,   21, 22, 23, 24,
433e0b9a84aScgd 	 9, 10, 11, 12,   25, 26, 27, 28,
434e0b9a84aScgd 	13, 14, 15, 16,   29, 30, 31, 32,
435e0b9a84aScgd 
436e0b9a84aScgd 	33, 34, 35, 36,   49, 50, 51, 52,
437e0b9a84aScgd 	37, 38, 39, 40,   53, 54, 55, 56,
438e0b9a84aScgd 	41, 42, 43, 44,   57, 58, 59, 60,
439e0b9a84aScgd 	45, 46, 47, 48,   61, 62, 63, 64,
440e0b9a84aScgd };
441e0b9a84aScgd 
442d7d75e06Sjdolecek static const unsigned char itoa64[] =		/* 0..63 => ascii-64 */
443e0b9a84aScgd 	"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
444e0b9a84aScgd 
445e0b9a84aScgd 
446e0b9a84aScgd /* =====  Tables that are initialized at run time  ==================== */
447e0b9a84aScgd 
448e0b9a84aScgd 
449e0b9a84aScgd /* Initial key schedule permutation */
450e0b9a84aScgd static C_block	PC1ROT[64/CHUNKBITS][1<<CHUNKBITS];
451e0b9a84aScgd 
452e0b9a84aScgd /* Subsequent key schedule rotation permutations */
453e0b9a84aScgd static C_block	PC2ROT[2][64/CHUNKBITS][1<<CHUNKBITS];
454e0b9a84aScgd 
455e0b9a84aScgd /* Initial permutation/expansion table */
456e0b9a84aScgd static C_block	IE3264[32/CHUNKBITS][1<<CHUNKBITS];
457e0b9a84aScgd 
458e0b9a84aScgd /* Table that combines the S, P, and E operations.  */
459688980ebScgd static int32_t SPE[2][8][64];
460e0b9a84aScgd 
461e0b9a84aScgd /* compressed/interleaved => final permutation table */
462e0b9a84aScgd static C_block	CF6464[64/CHUNKBITS][1<<CHUNKBITS];
463e0b9a84aScgd 
464e0b9a84aScgd 
465e0b9a84aScgd /* ==================================== */
466e0b9a84aScgd 
467e0b9a84aScgd 
468e0b9a84aScgd static C_block	constdatablock;			/* encryption constant */
469e0b9a84aScgd static char	cryptresult[1+4+4+11+1];	/* encrypted result */
470e0b9a84aScgd 
471aeeea54dSchristos /*
472aeeea54dSchristos  * We match the behavior of UFC-crypt on systems where "char" is signed by
473aeeea54dSchristos  * default (the majority), regardless of char's signedness on our system.
474aeeea54dSchristos  */
475aeeea54dSchristos static inline int
476aeeea54dSchristos ascii_to_bin(char ch)
477aeeea54dSchristos {
478aeeea54dSchristos 	signed char sch = ch;
479aeeea54dSchristos 	int retval;
480aeeea54dSchristos 
481aeeea54dSchristos 	if (sch >= 'a')
482aeeea54dSchristos 		retval = sch - ('a' - 38);
483aeeea54dSchristos 	else if (sch >= 'A')
484aeeea54dSchristos 		retval = sch - ('A' - 12);
485aeeea54dSchristos 	else
486aeeea54dSchristos 		retval = sch - '.';
487aeeea54dSchristos 
488aeeea54dSchristos 	return retval & 0x3f;
489aeeea54dSchristos }
490dbd46365Schristos 
491aeeea54dSchristos /*
492aeeea54dSchristos  * When we choose to "support" invalid salts, nevertheless disallow those
493aeeea54dSchristos  * containing characters that would violate the passwd file format.
494aeeea54dSchristos  */
495aeeea54dSchristos static inline int
496aeeea54dSchristos ascii_is_unsafe(char ch)
497aeeea54dSchristos {
498aeeea54dSchristos 	return !ch || ch == '\n' || ch == ':';
499aeeea54dSchristos }
500a46d295dSchristos 
501e0b9a84aScgd /*
502c7ab523eSjhigh  * We extract the scheme from setting str to allow for
503c7ab523eSjhigh  * full scheme name comparison
504c7ab523eSjhigh  * Updated to reflect alc suggestion(s)
505c7ab523eSjhigh  *
50637a23ecfSmsaitoh  * returns boolean 0 on failure, 1 on success,
507c7ab523eSjhigh  */
508c7ab523eSjhigh static int
509c7ab523eSjhigh nondes_scheme_substr(const char * setting,char * scheme, unsigned int len)
510c7ab523eSjhigh {
511c7ab523eSjhigh 	const char * start;
512c7ab523eSjhigh 	const char * sep;
513c7ab523eSjhigh 
514c7ab523eSjhigh 	/* initialize head pointer */
515c7ab523eSjhigh 	start = setting;
516c7ab523eSjhigh 
517c7ab523eSjhigh 	/* clear out scheme buffer regardless of result */
518c7ab523eSjhigh 	memset(scheme, 0, len);
519c7ab523eSjhigh 
520c7ab523eSjhigh 	/* make sure we are working on non-des scheme string */
521c7ab523eSjhigh 	if (*start != _PASSWORD_NONDES) {
522c7ab523eSjhigh 		return 0;
523c7ab523eSjhigh 	}
524c7ab523eSjhigh 
525c7ab523eSjhigh 	/* increment passed initial _PASSWORD_NONDES */
526c7ab523eSjhigh 	start++;
527c7ab523eSjhigh 
528c7ab523eSjhigh 	if ((sep = memchr(start, _PASSWORD_NONDES,len-1)) == NULL) {
529c7ab523eSjhigh 		return 0;
530c7ab523eSjhigh 	}
531c7ab523eSjhigh 
532c7ab523eSjhigh 	/* if empty string, we are done */
533c7ab523eSjhigh 	if (sep == start) {
534c7ab523eSjhigh 		return 1;
535c7ab523eSjhigh 	}
536c7ab523eSjhigh 
537c7ab523eSjhigh 	/* copy scheme substr to buffer */
538c7ab523eSjhigh 	memcpy(scheme, start, (size_t)(sep - start));
539c7ab523eSjhigh 
540c7ab523eSjhigh 	return 1;
541c7ab523eSjhigh }
542c7ab523eSjhigh 
543c7ab523eSjhigh /*
544e0b9a84aScgd  * Return a pointer to static data consisting of the "setting"
545e0b9a84aScgd  * followed by an encryption produced by the "key" and "setting".
546e0b9a84aScgd  */
547e7926f1eSchristos static char *
548dbd46365Schristos __crypt(const char *key, const char *setting)
549e0b9a84aScgd {
55006795b86Slukem 	char *encp;
551c7ab523eSjhigh 	char scheme[12];
55206795b86Slukem 	int32_t i;
55306795b86Slukem 	int t;
554c7ab523eSjhigh 	int r;
555688980ebScgd 	int32_t salt;
556e0b9a84aScgd 	int num_iter, salt_size;
557e0b9a84aScgd 	C_block keyblock, rsltblock;
558e0b9a84aScgd 
559ac9fc8f4Sad 	/* Non-DES encryption schemes hook in here. */
560ac9fc8f4Sad 	if (setting[0] == _PASSWORD_NONDES) {
561c7ab523eSjhigh 		r = nondes_scheme_substr(
562c7ab523eSjhigh 			setting, scheme, sizeof(scheme));
563c7ab523eSjhigh 
564c7ab523eSjhigh 		/* return NULL if we are unable to extract substring */
565c7ab523eSjhigh 		if (!r) {
566c7ab523eSjhigh 			return NULL;
567c7ab523eSjhigh 		}
568c7ab523eSjhigh 
569c7ab523eSjhigh 		/* $2a$ found in bcrypt.c:encode_salt  */
570c7ab523eSjhigh 		if (strcmp(scheme, "2a") == 0) {
571ac9fc8f4Sad 			return (__bcrypt(key, setting));
572c7ab523eSjhigh 		} else if (strcmp(scheme, "sha1") == 0) {
573c7ab523eSjhigh 		     /* $sha1$ found in crypt.h:SHA1_MAGIC */
5743a0c68edSsjg 			return (__crypt_sha1(key, setting));
575c7ab523eSjhigh 		} else if (strcmp(scheme, "1") == 0) {
576c7ab523eSjhigh 		     /* $1$ found in pw_gensalt.c:__gensalt_md5 */
577ac9fc8f4Sad 			return (__md5crypt(key, setting));
578b302373fSjhigh #ifdef HAVE_ARGON2
579b302373fSjhigh 		/* explicit argon2 variant */
580b302373fSjhigh 		} else if (strcmp(scheme, "argon2id") == 0) {
581b302373fSjhigh 		     /* $argon2id$ found in pw_gensalt.c:__gensalt_argon2 */
582b302373fSjhigh 			return (__crypt_argon2(key, setting));
583b302373fSjhigh 		} else if (strcmp(scheme, "argon2i") == 0) {
584b302373fSjhigh 		     /* $argon2i$ found in pw_gensalt.c:__gensalt_argon2 */
585b302373fSjhigh 			return (__crypt_argon2(key, setting));
586b302373fSjhigh 		} else if (strcmp(scheme, "argon2d") == 0) {
587b302373fSjhigh 		     /* $argon2d$ found in pw_gensalt.c:__gensalt_argon2 */
588b302373fSjhigh 			return (__crypt_argon2(key, setting));
589b302373fSjhigh #endif /* HAVE_ARGON2 */
590c7ab523eSjhigh 		} else {
591c7ab523eSjhigh 		     /* invalid scheme, including empty string */
592c7ab523eSjhigh 			return NULL;
593ac9fc8f4Sad 		}
594ac9fc8f4Sad 	}
595c7ab523eSjhigh 	/* End non-DES handling */
596ac9fc8f4Sad 
597e0b9a84aScgd 	for (i = 0; i < 8; i++) {
598e0b9a84aScgd 		if ((t = 2*(unsigned char)(*key)) != 0)
599e0b9a84aScgd 			key++;
600e0b9a84aScgd 		keyblock.b[i] = t;
601e0b9a84aScgd 	}
602aeeea54dSchristos 	if (des_setkey((char *)keyblock.b))
603e0b9a84aScgd 		return (NULL);
604e0b9a84aScgd 
605e0b9a84aScgd 	encp = &cryptresult[0];
606e0b9a84aScgd 	switch (*setting) {
607e0b9a84aScgd 	case _PASSWORD_EFMT1:
608e0b9a84aScgd 		/*
609e0b9a84aScgd 		 * Involve the rest of the password 8 characters at a time.
610e0b9a84aScgd 		 */
611e0b9a84aScgd 		while (*key) {
612ddb7e7aaSwiz 			if (des_cipher((char *)(void *)&keyblock,
613ddb7e7aaSwiz 			    (char *)(void *)&keyblock, 0L, 1))
614e0b9a84aScgd 				return (NULL);
615e0b9a84aScgd 			for (i = 0; i < 8; i++) {
616e0b9a84aScgd 				if ((t = 2*(unsigned char)(*key)) != 0)
617e0b9a84aScgd 					key++;
618e0b9a84aScgd 				keyblock.b[i] ^= t;
619e0b9a84aScgd 			}
620e0b9a84aScgd 			if (des_setkey((char *)keyblock.b))
621e0b9a84aScgd 				return (NULL);
622e0b9a84aScgd 		}
623e0b9a84aScgd 
624e0b9a84aScgd 		*encp++ = *setting++;
625e0b9a84aScgd 
626e0b9a84aScgd 		/* get iteration count */
627e0b9a84aScgd 		num_iter = 0;
628e0b9a84aScgd 		for (i = 4; --i >= 0; ) {
629aeeea54dSchristos 			int value = ascii_to_bin(setting[i]);
630aeeea54dSchristos 			if (itoa64[value] != setting[i])
631aeeea54dSchristos 				return NULL;
632aeeea54dSchristos 			encp[i] = setting[i];
633aeeea54dSchristos 			num_iter = (num_iter << 6) | value;
634e0b9a84aScgd 		}
635aeeea54dSchristos 		if (num_iter == 0)
636aeeea54dSchristos 			return NULL;
637e0b9a84aScgd 		setting += 4;
638e0b9a84aScgd 		encp += 4;
639e0b9a84aScgd 		salt_size = 4;
640e0b9a84aScgd 		break;
641e0b9a84aScgd 	default:
642e0b9a84aScgd 		num_iter = 25;
643e0b9a84aScgd 		salt_size = 2;
644aeeea54dSchristos 		if (ascii_is_unsafe(setting[0]) || ascii_is_unsafe(setting[1]))
645aeeea54dSchristos 			return NULL;
646e0b9a84aScgd 	}
647e0b9a84aScgd 
648e0b9a84aScgd 	salt = 0;
649e0b9a84aScgd 	for (i = salt_size; --i >= 0; ) {
650aeeea54dSchristos 		int value = ascii_to_bin(setting[i]);
651b0ca4d4eSchristos 		if (salt_size > 2 && itoa64[value] != setting[i])
652aeeea54dSchristos 			return NULL;
653aeeea54dSchristos 		encp[i] = setting[i];
654aeeea54dSchristos 		salt = (salt << 6) | value;
655e0b9a84aScgd 	}
656e0b9a84aScgd 	encp += salt_size;
657ddb7e7aaSwiz 	if (des_cipher((char *)(void *)&constdatablock,
658ddb7e7aaSwiz 	    (char *)(void *)&rsltblock, salt, num_iter))
659e0b9a84aScgd 		return (NULL);
660e0b9a84aScgd 
661e0b9a84aScgd 	/*
662e0b9a84aScgd 	 * Encode the 64 cipher bits as 11 ascii characters.
663e0b9a84aScgd 	 */
664688980ebScgd 	i = ((int32_t)((rsltblock.b[0]<<8) | rsltblock.b[1])<<8) |
665688980ebScgd 	    rsltblock.b[2];
666e0b9a84aScgd 	encp[3] = itoa64[i&0x3f];	i >>= 6;
667e0b9a84aScgd 	encp[2] = itoa64[i&0x3f];	i >>= 6;
668e0b9a84aScgd 	encp[1] = itoa64[i&0x3f];	i >>= 6;
669e0b9a84aScgd 	encp[0] = itoa64[i];		encp += 4;
670688980ebScgd 	i = ((int32_t)((rsltblock.b[3]<<8) | rsltblock.b[4])<<8) |
671688980ebScgd 	    rsltblock.b[5];
672e0b9a84aScgd 	encp[3] = itoa64[i&0x3f];	i >>= 6;
673e0b9a84aScgd 	encp[2] = itoa64[i&0x3f];	i >>= 6;
674e0b9a84aScgd 	encp[1] = itoa64[i&0x3f];	i >>= 6;
675e0b9a84aScgd 	encp[0] = itoa64[i];		encp += 4;
676688980ebScgd 	i = ((int32_t)((rsltblock.b[6])<<8) | rsltblock.b[7])<<2;
677e0b9a84aScgd 	encp[2] = itoa64[i&0x3f];	i >>= 6;
678e0b9a84aScgd 	encp[1] = itoa64[i&0x3f];	i >>= 6;
679e0b9a84aScgd 	encp[0] = itoa64[i];
680e0b9a84aScgd 
681e0b9a84aScgd 	encp[3] = 0;
682e0b9a84aScgd 
683e0b9a84aScgd 	return (cryptresult);
684e0b9a84aScgd }
685e0b9a84aScgd 
686dbd46365Schristos char *
687dbd46365Schristos crypt(const char *key, const char *salt)
688dbd46365Schristos {
689dbd46365Schristos 	char *res = __crypt(key, salt);
690b302373fSjhigh 
691dbd46365Schristos 	if (res)
692dbd46365Schristos 		return res;
693dbd46365Schristos 	/* How do I handle errors ? Return "*0" or "*1" */
694dbd46365Schristos 	return __UNCONST(salt[0] == '*' && salt[1] == '0' ? "*1" : "*0");
695dbd46365Schristos }
696e0b9a84aScgd 
697e0b9a84aScgd /*
698e0b9a84aScgd  * The Key Schedule, filled in by des_setkey() or setkey().
699e0b9a84aScgd  */
700e0b9a84aScgd #define	KS_SIZE	16
701e0b9a84aScgd static C_block	KS[KS_SIZE];
702e0b9a84aScgd 
703e0b9a84aScgd /*
704e0b9a84aScgd  * Set up the key schedule from the key.
705e0b9a84aScgd  */
70631a2bdc6Smikel int
70759153410Sperry des_setkey(const char *key)
708e0b9a84aScgd {
70906795b86Slukem 	DCL_BLOCK(K, K0, K1);
71065b9988bSdrochner 	C_block *help, *ptabp;
71106795b86Slukem 	int i;
712e0b9a84aScgd 	static int des_ready = 0;
713e0b9a84aScgd 
714e0b9a84aScgd 	if (!des_ready) {
715e0b9a84aScgd 		init_des();
716e0b9a84aScgd 		des_ready = 1;
717e0b9a84aScgd 	}
718e0b9a84aScgd 
71965b9988bSdrochner 	PERM6464(K,K0,K1,(const unsigned char *)key,(C_block *)PC1ROT);
72065b9988bSdrochner 	help = &KS[0];
72165b9988bSdrochner 	STORE(K&~0x03030303L, K0&~0x03030303L, K1, *help);
722e0b9a84aScgd 	for (i = 1; i < 16; i++) {
72365b9988bSdrochner 		help++;
72465b9988bSdrochner 		STORE(K,K0,K1,*help);
725e0b9a84aScgd 		ptabp = (C_block *)PC2ROT[Rotates[i]-1];
72665b9988bSdrochner 		PERM6464(K,K0,K1,(const unsigned char *)help,ptabp);
72765b9988bSdrochner 		STORE(K&~0x03030303L, K0&~0x03030303L, K1, *help);
728e0b9a84aScgd 	}
729e0b9a84aScgd 	return (0);
730e0b9a84aScgd }
731e0b9a84aScgd 
732e0b9a84aScgd /*
733e0b9a84aScgd  * Encrypt (or decrypt if num_iter < 0) the 8 chars at "in" with abs(num_iter)
73489c5a767Ssoren  * iterations of DES, using the given 24-bit salt and the pre-computed key
735e0b9a84aScgd  * schedule, and store the resulting 8 chars at "out" (in == out is permitted).
736e0b9a84aScgd  *
737e0b9a84aScgd  * NOTE: the performance of this routine is critically dependent on your
738e0b9a84aScgd  * compiler and machine architecture.
739e0b9a84aScgd  */
74031a2bdc6Smikel int
74159153410Sperry des_cipher(const char *in, char *out, long salt, int num_iter)
742e0b9a84aScgd {
743e0b9a84aScgd 	/* variables that we want in registers, most important first */
744e0b9a84aScgd #if defined(pdp11)
7450b7831a3Sperry 	int j;
746e0b9a84aScgd #endif
7470b7831a3Sperry 	int32_t L0, L1, R0, R1, k;
7480b7831a3Sperry 	C_block *kp;
7490b7831a3Sperry 	int ks_inc, loop_count;
750e0b9a84aScgd 	C_block B;
751e0b9a84aScgd 
752e0b9a84aScgd 	L0 = salt;
753e0b9a84aScgd 	TO_SIX_BIT(salt, L0);	/* convert to 4*(6+2) format */
754e0b9a84aScgd 
75559695352Smatt #if defined(__vax__) || defined(pdp11)
756e0b9a84aScgd 	salt = ~salt;	/* "x &~ y" is faster than "x & y". */
757e0b9a84aScgd #define	SALT (~salt)
758e0b9a84aScgd #else
759e0b9a84aScgd #define	SALT salt
760e0b9a84aScgd #endif
761e0b9a84aScgd 
762e0b9a84aScgd #if defined(MUST_ALIGN)
763e0b9a84aScgd 	B.b[0] = in[0]; B.b[1] = in[1]; B.b[2] = in[2]; B.b[3] = in[3];
764e0b9a84aScgd 	B.b[4] = in[4]; B.b[5] = in[5]; B.b[6] = in[6]; B.b[7] = in[7];
765e0b9a84aScgd 	LOAD(L,L0,L1,B);
766e0b9a84aScgd #else
76765b9988bSdrochner 	LOAD(L,L0,L1,*(const C_block *)in);
768e0b9a84aScgd #endif
769e0b9a84aScgd 	LOADREG(R,R0,R1,L,L0,L1);
770e0b9a84aScgd 	L0 &= 0x55555555L;
771e0b9a84aScgd 	L1 &= 0x55555555L;
7726ab39b67Skamil 	L0 = ((uint32_t)L0 << 1) | L1;	/* L0 is the even-numbered input bits */
773e0b9a84aScgd 	R0 &= 0xaaaaaaaaL;
7746ab39b67Skamil 	R1 = ((uint32_t)R1 >> 1) & 0x55555555L;
775e0b9a84aScgd 	L1 = R0 | R1;		/* L1 is the odd-numbered input bits */
776e0b9a84aScgd 	STORE(L,L0,L1,B);
777e0b9a84aScgd 	PERM3264(L,L0,L1,B.b,  (C_block *)IE3264);	/* even bits */
778e0b9a84aScgd 	PERM3264(R,R0,R1,B.b+4,(C_block *)IE3264);	/* odd bits */
779e0b9a84aScgd 
780e0b9a84aScgd 	if (num_iter >= 0)
781e0b9a84aScgd 	{		/* encryption */
782e0b9a84aScgd 		kp = &KS[0];
783e0b9a84aScgd 		ks_inc  = sizeof(*kp);
784e0b9a84aScgd 	}
785e0b9a84aScgd 	else
786e0b9a84aScgd 	{		/* decryption */
7879323d932Sthorpej 		num_iter = -num_iter;
7889323d932Sthorpej 		kp = &KS[KS_SIZE-1];
7899323d932Sthorpej 		ks_inc  = -(long)sizeof(*kp);
790e0b9a84aScgd 	}
791e0b9a84aScgd 
792e0b9a84aScgd 	while (--num_iter >= 0) {
793e0b9a84aScgd 		loop_count = 8;
794e0b9a84aScgd 		do {
795e0b9a84aScgd 
796688980ebScgd #define	SPTAB(t, i) \
797688980ebScgd 	    (*(int32_t *)((unsigned char *)t + i*(sizeof(int32_t)/4)))
798e0b9a84aScgd #if defined(gould)
799e0b9a84aScgd 			/* use this if B.b[i] is evaluated just once ... */
800e0b9a84aScgd #define	DOXOR(x,y,i)	x^=SPTAB(SPE[0][i],B.b[i]); y^=SPTAB(SPE[1][i],B.b[i]);
801e0b9a84aScgd #else
802e0b9a84aScgd #if defined(pdp11)
803e0b9a84aScgd 			/* use this if your "long" int indexing is slow */
804e0b9a84aScgd #define	DOXOR(x,y,i)	j=B.b[i]; x^=SPTAB(SPE[0][i],j); y^=SPTAB(SPE[1][i],j);
805e0b9a84aScgd #else
80695eeab3bSmikel 			/* use this if "k" is allocated to a register ... */
807e0b9a84aScgd #define	DOXOR(x,y,i)	k=B.b[i]; x^=SPTAB(SPE[0][i],k); y^=SPTAB(SPE[1][i],k);
808e0b9a84aScgd #endif
809e0b9a84aScgd #endif
810e0b9a84aScgd 
811e0b9a84aScgd #define	CRUNCH(p0, p1, q0, q1)	\
812e0b9a84aScgd 			k = (q0 ^ q1) & SALT;	\
813e0b9a84aScgd 			B.b32.i0 = k ^ q0 ^ kp->b32.i0;		\
814e0b9a84aScgd 			B.b32.i1 = k ^ q1 ^ kp->b32.i1;		\
815e0b9a84aScgd 			kp = (C_block *)((char *)kp+ks_inc);	\
816e0b9a84aScgd 							\
817e0b9a84aScgd 			DOXOR(p0, p1, 0);		\
818e0b9a84aScgd 			DOXOR(p0, p1, 1);		\
819e0b9a84aScgd 			DOXOR(p0, p1, 2);		\
820e0b9a84aScgd 			DOXOR(p0, p1, 3);		\
821e0b9a84aScgd 			DOXOR(p0, p1, 4);		\
822e0b9a84aScgd 			DOXOR(p0, p1, 5);		\
823e0b9a84aScgd 			DOXOR(p0, p1, 6);		\
824e0b9a84aScgd 			DOXOR(p0, p1, 7);
825e0b9a84aScgd 
826e0b9a84aScgd 			CRUNCH(L0, L1, R0, R1);
827e0b9a84aScgd 			CRUNCH(R0, R1, L0, L1);
828e0b9a84aScgd 		} while (--loop_count != 0);
829e0b9a84aScgd 		kp = (C_block *)((char *)kp-(ks_inc*KS_SIZE));
830e0b9a84aScgd 
831e0b9a84aScgd 
832e0b9a84aScgd 		/* swap L and R */
833e0b9a84aScgd 		L0 ^= R0;  L1 ^= R1;
834e0b9a84aScgd 		R0 ^= L0;  R1 ^= L1;
835e0b9a84aScgd 		L0 ^= R0;  L1 ^= R1;
836e0b9a84aScgd 	}
837e0b9a84aScgd 
838e0b9a84aScgd 	/* store the encrypted (or decrypted) result */
83996be1c99Skamil 	L0 = (((uint32_t)L0 >> 3) & 0x0f0f0f0fL) | (((uint32_t)L1 << 1) & 0xf0f0f0f0L);
84096be1c99Skamil 	L1 = (((uint32_t)R0 >> 3) & 0x0f0f0f0fL) | (((uint32_t)R1 << 1) & 0xf0f0f0f0L);
841e0b9a84aScgd 	STORE(L,L0,L1,B);
842e0b9a84aScgd 	PERM6464(L,L0,L1,B.b, (C_block *)CF6464);
843e0b9a84aScgd #if defined(MUST_ALIGN)
844e0b9a84aScgd 	STORE(L,L0,L1,B);
845e0b9a84aScgd 	out[0] = B.b[0]; out[1] = B.b[1]; out[2] = B.b[2]; out[3] = B.b[3];
846e0b9a84aScgd 	out[4] = B.b[4]; out[5] = B.b[5]; out[6] = B.b[6]; out[7] = B.b[7];
847e0b9a84aScgd #else
848e0b9a84aScgd 	STORE(L,L0,L1,*(C_block *)out);
849e0b9a84aScgd #endif
850e0b9a84aScgd 	return (0);
851e0b9a84aScgd }
852e0b9a84aScgd 
853e0b9a84aScgd 
854e0b9a84aScgd /*
855e0b9a84aScgd  * Initialize various tables.  This need only be done once.  It could even be
856e0b9a84aScgd  * done at compile time, if the compiler were capable of that sort of thing.
857e0b9a84aScgd  */
858e0b9a84aScgd STATIC
85959153410Sperry init_des(void)
860e0b9a84aScgd {
86106795b86Slukem 	int i, j;
86206795b86Slukem 	int32_t k;
86306795b86Slukem 	int tableno;
864e0b9a84aScgd 	static unsigned char perm[64], tmp32[32];	/* "static" for speed */
865e0b9a84aScgd 
866e0b9a84aScgd 	/*
867e0b9a84aScgd 	 * PC1ROT - bit reverse, then PC1, then Rotate, then PC2.
868e0b9a84aScgd 	 */
869e0b9a84aScgd 	for (i = 0; i < 64; i++)
870e0b9a84aScgd 		perm[i] = 0;
871e0b9a84aScgd 	for (i = 0; i < 64; i++) {
872e0b9a84aScgd 		if ((k = PC2[i]) == 0)
873e0b9a84aScgd 			continue;
874e0b9a84aScgd 		k += Rotates[0]-1;
875e0b9a84aScgd 		if ((k%28) < Rotates[0]) k -= 28;
876e0b9a84aScgd 		k = PC1[k];
877e0b9a84aScgd 		if (k > 0) {
878e0b9a84aScgd 			k--;
879e0b9a84aScgd 			k = (k|07) - (k&07);
880e0b9a84aScgd 			k++;
881e0b9a84aScgd 		}
882e0b9a84aScgd 		perm[i] = k;
883e0b9a84aScgd 	}
884e0b9a84aScgd #ifdef DEBUG
885e0b9a84aScgd 	prtab("pc1tab", perm, 8);
886e0b9a84aScgd #endif
887e0b9a84aScgd 	init_perm(PC1ROT, perm, 8, 8);
888e0b9a84aScgd 
889e0b9a84aScgd 	/*
890e0b9a84aScgd 	 * PC2ROT - PC2 inverse, then Rotate (once or twice), then PC2.
891e0b9a84aScgd 	 */
892e0b9a84aScgd 	for (j = 0; j < 2; j++) {
893e0b9a84aScgd 		unsigned char pc2inv[64];
894e0b9a84aScgd 		for (i = 0; i < 64; i++)
895e0b9a84aScgd 			perm[i] = pc2inv[i] = 0;
896e0b9a84aScgd 		for (i = 0; i < 64; i++) {
897e0b9a84aScgd 			if ((k = PC2[i]) == 0)
898e0b9a84aScgd 				continue;
899e0b9a84aScgd 			pc2inv[k-1] = i+1;
900e0b9a84aScgd 		}
901e0b9a84aScgd 		for (i = 0; i < 64; i++) {
902e0b9a84aScgd 			if ((k = PC2[i]) == 0)
903e0b9a84aScgd 				continue;
904e0b9a84aScgd 			k += j;
905e0b9a84aScgd 			if ((k%28) <= j) k -= 28;
906e0b9a84aScgd 			perm[i] = pc2inv[k];
907e0b9a84aScgd 		}
908e0b9a84aScgd #ifdef DEBUG
909e0b9a84aScgd 		prtab("pc2tab", perm, 8);
910e0b9a84aScgd #endif
911e0b9a84aScgd 		init_perm(PC2ROT[j], perm, 8, 8);
912e0b9a84aScgd 	}
913e0b9a84aScgd 
914e0b9a84aScgd 	/*
915e0b9a84aScgd 	 * Bit reverse, then initial permutation, then expansion.
916e0b9a84aScgd 	 */
917e0b9a84aScgd 	for (i = 0; i < 8; i++) {
918e0b9a84aScgd 		for (j = 0; j < 8; j++) {
919e0b9a84aScgd 			k = (j < 2)? 0: IP[ExpandTr[i*6+j-2]-1];
920e0b9a84aScgd 			if (k > 32)
921e0b9a84aScgd 				k -= 32;
922e0b9a84aScgd 			else if (k > 0)
923e0b9a84aScgd 				k--;
924e0b9a84aScgd 			if (k > 0) {
925e0b9a84aScgd 				k--;
926e0b9a84aScgd 				k = (k|07) - (k&07);
927e0b9a84aScgd 				k++;
928e0b9a84aScgd 			}
929e0b9a84aScgd 			perm[i*8+j] = k;
930e0b9a84aScgd 		}
931e0b9a84aScgd 	}
932e0b9a84aScgd #ifdef DEBUG
933e0b9a84aScgd 	prtab("ietab", perm, 8);
934e0b9a84aScgd #endif
935e0b9a84aScgd 	init_perm(IE3264, perm, 4, 8);
936e0b9a84aScgd 
937e0b9a84aScgd 	/*
938e0b9a84aScgd 	 * Compression, then final permutation, then bit reverse.
939e0b9a84aScgd 	 */
940e0b9a84aScgd 	for (i = 0; i < 64; i++) {
941e0b9a84aScgd 		k = IP[CIFP[i]-1];
942e0b9a84aScgd 		if (k > 0) {
943e0b9a84aScgd 			k--;
944e0b9a84aScgd 			k = (k|07) - (k&07);
945e0b9a84aScgd 			k++;
946e0b9a84aScgd 		}
947e0b9a84aScgd 		perm[k-1] = i+1;
948e0b9a84aScgd 	}
949e0b9a84aScgd #ifdef DEBUG
950e0b9a84aScgd 	prtab("cftab", perm, 8);
951e0b9a84aScgd #endif
952e0b9a84aScgd 	init_perm(CF6464, perm, 8, 8);
953e0b9a84aScgd 
954e0b9a84aScgd 	/*
955e0b9a84aScgd 	 * SPE table
956e0b9a84aScgd 	 */
957e0b9a84aScgd 	for (i = 0; i < 48; i++)
958e0b9a84aScgd 		perm[i] = P32Tr[ExpandTr[i]-1];
959e0b9a84aScgd 	for (tableno = 0; tableno < 8; tableno++) {
960e0b9a84aScgd 		for (j = 0; j < 64; j++)  {
961e0b9a84aScgd 			k = (((j >> 0) &01) << 5)|
962e0b9a84aScgd 			    (((j >> 1) &01) << 3)|
963e0b9a84aScgd 			    (((j >> 2) &01) << 2)|
964e0b9a84aScgd 			    (((j >> 3) &01) << 1)|
965e0b9a84aScgd 			    (((j >> 4) &01) << 0)|
966e0b9a84aScgd 			    (((j >> 5) &01) << 4);
967e0b9a84aScgd 			k = S[tableno][k];
968e0b9a84aScgd 			k = (((k >> 3)&01) << 0)|
969e0b9a84aScgd 			    (((k >> 2)&01) << 1)|
970e0b9a84aScgd 			    (((k >> 1)&01) << 2)|
971e0b9a84aScgd 			    (((k >> 0)&01) << 3);
972e0b9a84aScgd 			for (i = 0; i < 32; i++)
973e0b9a84aScgd 				tmp32[i] = 0;
974e0b9a84aScgd 			for (i = 0; i < 4; i++)
975e0b9a84aScgd 				tmp32[4 * tableno + i] = (k >> i) & 01;
976e0b9a84aScgd 			k = 0;
977e0b9a84aScgd 			for (i = 24; --i >= 0; )
978e0b9a84aScgd 				k = (k<<1) | tmp32[perm[i]-1];
979e0b9a84aScgd 			TO_SIX_BIT(SPE[0][tableno][j], k);
980e0b9a84aScgd 			k = 0;
981e0b9a84aScgd 			for (i = 24; --i >= 0; )
982e0b9a84aScgd 				k = (k<<1) | tmp32[perm[i+24]-1];
983e0b9a84aScgd 			TO_SIX_BIT(SPE[1][tableno][j], k);
984e0b9a84aScgd 		}
985e0b9a84aScgd 	}
986e0b9a84aScgd }
987e0b9a84aScgd 
988e0b9a84aScgd /*
989e0b9a84aScgd  * Initialize "perm" to represent transformation "p", which rearranges
990e0b9a84aScgd  * (perhaps with expansion and/or contraction) one packed array of bits
991e0b9a84aScgd  * (of size "chars_in" characters) into another array (of size "chars_out"
992e0b9a84aScgd  * characters).
993e0b9a84aScgd  *
994e0b9a84aScgd  * "perm" must be all-zeroes on entry to this routine.
995e0b9a84aScgd  */
996e0b9a84aScgd STATIC
99759153410Sperry init_perm(C_block perm[64/CHUNKBITS][1<<CHUNKBITS], const unsigned char p[64],
99859153410Sperry     int chars_in, int chars_out)
999e0b9a84aScgd {
100006795b86Slukem 	int i, j, k, l;
1001e0b9a84aScgd 
1002e0b9a84aScgd 	for (k = 0; k < chars_out*8; k++) {	/* each output bit position */
1003e0b9a84aScgd 		l = p[k] - 1;		/* where this bit comes from */
1004e0b9a84aScgd 		if (l < 0)
1005e0b9a84aScgd 			continue;	/* output bit is always 0 */
1006e0b9a84aScgd 		i = l>>LGCHUNKBITS;	/* which chunk this bit comes from */
1007e0b9a84aScgd 		l = 1<<(l&(CHUNKBITS-1));	/* mask for this bit */
1008e0b9a84aScgd 		for (j = 0; j < (1<<CHUNKBITS); j++) {	/* each chunk value */
1009e0b9a84aScgd 			if ((j & l) != 0)
1010e0b9a84aScgd 				perm[i][j].b[k>>3] |= 1<<(k&07);
1011e0b9a84aScgd 		}
1012e0b9a84aScgd 	}
1013e0b9a84aScgd }
1014e0b9a84aScgd 
1015e0b9a84aScgd /*
1016e0b9a84aScgd  * "setkey" routine (for backwards compatibility)
1017e0b9a84aScgd  */
101831a2bdc6Smikel int
101959153410Sperry setkey(const char *key)
1020e0b9a84aScgd {
102106795b86Slukem 	int i, j, k;
1022e0b9a84aScgd 	C_block keyblock;
1023e0b9a84aScgd 
1024e0b9a84aScgd 	for (i = 0; i < 8; i++) {
1025e0b9a84aScgd 		k = 0;
1026e0b9a84aScgd 		for (j = 0; j < 8; j++) {
1027e0b9a84aScgd 			k <<= 1;
1028e0b9a84aScgd 			k |= (unsigned char)*key++;
1029e0b9a84aScgd 		}
1030e0b9a84aScgd 		keyblock.b[i] = k;
1031e0b9a84aScgd 	}
1032e0b9a84aScgd 	return (des_setkey((char *)keyblock.b));
1033e0b9a84aScgd }
1034e0b9a84aScgd 
1035e0b9a84aScgd /*
1036e0b9a84aScgd  * "encrypt" routine (for backwards compatibility)
1037e0b9a84aScgd  */
103831a2bdc6Smikel int
103959153410Sperry encrypt(char *block, int flag)
1040e0b9a84aScgd {
104106795b86Slukem 	int i, j, k;
1042e0b9a84aScgd 	C_block cblock;
1043e0b9a84aScgd 
1044e0b9a84aScgd 	for (i = 0; i < 8; i++) {
1045e0b9a84aScgd 		k = 0;
1046e0b9a84aScgd 		for (j = 0; j < 8; j++) {
1047e0b9a84aScgd 			k <<= 1;
1048e0b9a84aScgd 			k |= (unsigned char)*block++;
1049e0b9a84aScgd 		}
1050e0b9a84aScgd 		cblock.b[i] = k;
1051e0b9a84aScgd 	}
1052e0b9a84aScgd 	if (des_cipher((char *)&cblock, (char *)&cblock, 0L, (flag ? -1: 1)))
1053e0b9a84aScgd 		return (1);
1054e0b9a84aScgd 	for (i = 7; i >= 0; i--) {
1055e0b9a84aScgd 		k = cblock.b[i];
1056e0b9a84aScgd 		for (j = 7; j >= 0; j--) {
1057e0b9a84aScgd 			*--block = k&01;
1058e0b9a84aScgd 			k >>= 1;
1059e0b9a84aScgd 		}
1060e0b9a84aScgd 	}
1061e0b9a84aScgd 	return (0);
1062e0b9a84aScgd }
1063e0b9a84aScgd 
1064e0b9a84aScgd #ifdef DEBUG
1065e0b9a84aScgd STATIC
106659153410Sperry prtab(const char *s, unsigned char *t, int num_rows)
1067e0b9a84aScgd {
106806795b86Slukem 	int i, j;
1069e0b9a84aScgd 
1070e0b9a84aScgd 	(void)printf("%s:\n", s);
1071e0b9a84aScgd 	for (i = 0; i < num_rows; i++) {
1072e0b9a84aScgd 		for (j = 0; j < 8; j++) {
1073e0b9a84aScgd 			 (void)printf("%3d", t[i*8+j]);
1074e0b9a84aScgd 		}
1075e0b9a84aScgd 		(void)printf("\n");
1076e0b9a84aScgd 	}
1077e0b9a84aScgd 	(void)printf("\n");
1078e0b9a84aScgd }
1079e0b9a84aScgd #endif
10803a0c68edSsjg 
10813a0c68edSsjg #if defined(MAIN) || defined(UNIT_TEST)
10823a0c68edSsjg #include <err.h>
10833a0c68edSsjg 
10843a0c68edSsjg int
10853a0c68edSsjg main(int argc, char *argv[])
10863a0c68edSsjg {
10875521b51aSchristos 	if (argc < 2) {
10885521b51aSchristos 		fprintf(stderr, "Usage: %s password [salt]\n", getprogname());
10895521b51aSchristos 		return EXIT_FAILURE;
10905521b51aSchristos 	}
10913a0c68edSsjg 
10923a0c68edSsjg 	printf("%s\n", crypt(argv[1], (argc > 2) ? argv[2] : argv[1]));
10935521b51aSchristos 	return EXIT_SUCCESS;
10943a0c68edSsjg }
10953a0c68edSsjg #endif
1096