1c4f09032SGeoff Rehmet /*
2c4f09032SGeoff Rehmet * FreeSec: libcrypt for NetBSD
3c4f09032SGeoff Rehmet *
4c4f09032SGeoff Rehmet * Copyright (c) 1994 David Burren
5c4f09032SGeoff Rehmet * All rights reserved.
6c4f09032SGeoff Rehmet *
7712ca8b4SGeoff Rehmet * Adapted for FreeBSD-2.0 by Geoffrey M. Rehmet
8e1e54354SMark Murray * this file should now *only* export crypt(), in order to make
9712ca8b4SGeoff Rehmet * binaries of libcrypt exportable from the USA
10712ca8b4SGeoff Rehmet *
11e1e54354SMark Murray * Adapted for FreeBSD-4.0 by Mark R V Murray
12e1e54354SMark Murray * this file should now *only* export crypt_des(), in order to make
13e1e54354SMark Murray * a module that can be optionally included in libcrypt.
14e1e54354SMark Murray *
15c4f09032SGeoff Rehmet * Redistribution and use in source and binary forms, with or without
16c4f09032SGeoff Rehmet * modification, are permitted provided that the following conditions
17c4f09032SGeoff Rehmet * are met:
18c4f09032SGeoff Rehmet * 1. Redistributions of source code must retain the above copyright
19c4f09032SGeoff Rehmet * notice, this list of conditions and the following disclaimer.
20c4f09032SGeoff Rehmet * 2. Redistributions in binary form must reproduce the above copyright
21c4f09032SGeoff Rehmet * notice, this list of conditions and the following disclaimer in the
22c4f09032SGeoff Rehmet * documentation and/or other materials provided with the distribution.
23e1e54354SMark Murray * 3. Neither the name of the author nor the names of other contributors
24c4f09032SGeoff Rehmet * may be used to endorse or promote products derived from this software
25c4f09032SGeoff Rehmet * without specific prior written permission.
26c4f09032SGeoff Rehmet *
27c4f09032SGeoff Rehmet * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
28c4f09032SGeoff Rehmet * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29c4f09032SGeoff Rehmet * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30c4f09032SGeoff Rehmet * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
31c4f09032SGeoff Rehmet * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32c4f09032SGeoff Rehmet * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33c4f09032SGeoff Rehmet * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34c4f09032SGeoff Rehmet * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35c4f09032SGeoff Rehmet * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36c4f09032SGeoff Rehmet * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37c4f09032SGeoff Rehmet * SUCH DAMAGE.
38c4f09032SGeoff Rehmet *
39c4f09032SGeoff Rehmet * This is an original implementation of the DES and the crypt(3) interfaces
40c4f09032SGeoff Rehmet * by David Burren <davidb@werj.com.au>.
41c4f09032SGeoff Rehmet *
42c4f09032SGeoff Rehmet * An excellent reference on the underlying algorithm (and related
43c4f09032SGeoff Rehmet * algorithms) is:
44c4f09032SGeoff Rehmet *
45c4f09032SGeoff Rehmet * B. Schneier, Applied Cryptography: protocols, algorithms,
46c4f09032SGeoff Rehmet * and source code in C, John Wiley & Sons, 1994.
47c4f09032SGeoff Rehmet *
48c4f09032SGeoff Rehmet * Note that in that book's description of DES the lookups for the initial,
49c4f09032SGeoff Rehmet * pbox, and final permutations are inverted (this has been brought to the
50c4f09032SGeoff Rehmet * attention of the author). A list of errata for this book has been
51c4f09032SGeoff Rehmet * posted to the sci.crypt newsgroup by the author and is available for FTP.
52c4f09032SGeoff Rehmet *
53c4f09032SGeoff Rehmet * ARCHITECTURE ASSUMPTIONS:
54c4f09032SGeoff Rehmet * It is assumed that the 8-byte arrays passed by reference can be
55e1e54354SMark Murray * addressed as arrays of u_int32_t's (ie. the CPU is not picky about
56c4f09032SGeoff Rehmet * alignment).
57c4f09032SGeoff Rehmet */
5868344a95SPeter Wemm
59c4f09032SGeoff Rehmet #include <sys/types.h>
60c4f09032SGeoff Rehmet #include <sys/param.h>
61fd8e4ebcSMike Barcroft #include <arpa/inet.h>
62c4f09032SGeoff Rehmet #include <pwd.h>
6396e718feSMark Murray #include <string.h>
64e1e54354SMark Murray #include "crypt.h"
65c4f09032SGeoff Rehmet
66712ca8b4SGeoff Rehmet /* We can't always assume gcc */
67f2ac424aSMark Murray #if defined(__GNUC__) && !defined(lint)
68712ca8b4SGeoff Rehmet #define INLINE inline
69f2ac424aSMark Murray #else
70f2ac424aSMark Murray #define INLINE
71712ca8b4SGeoff Rehmet #endif
72712ca8b4SGeoff Rehmet
73c4f09032SGeoff Rehmet
74*7d681ad7SEdward Tomasz Napierala static const u_char IP[64] = {
75c4f09032SGeoff Rehmet 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,
76c4f09032SGeoff Rehmet 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
77c4f09032SGeoff Rehmet 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
78c4f09032SGeoff Rehmet 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7
79c4f09032SGeoff Rehmet };
80c4f09032SGeoff Rehmet
81*7d681ad7SEdward Tomasz Napierala static __thread u_char inv_key_perm[64];
82*7d681ad7SEdward Tomasz Napierala static const u_char key_perm[56] = {
83c4f09032SGeoff Rehmet 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18,
84c4f09032SGeoff Rehmet 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36,
85c4f09032SGeoff Rehmet 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22,
86c4f09032SGeoff Rehmet 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4
87c4f09032SGeoff Rehmet };
88c4f09032SGeoff Rehmet
89*7d681ad7SEdward Tomasz Napierala static const u_char key_shifts[16] = {
90c4f09032SGeoff Rehmet 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
91c4f09032SGeoff Rehmet };
92c4f09032SGeoff Rehmet
93*7d681ad7SEdward Tomasz Napierala static __thread u_char inv_comp_perm[56];
94*7d681ad7SEdward Tomasz Napierala static const u_char comp_perm[48] = {
95c4f09032SGeoff Rehmet 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10,
96c4f09032SGeoff Rehmet 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2,
97c4f09032SGeoff Rehmet 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
98c4f09032SGeoff Rehmet 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32
99c4f09032SGeoff Rehmet };
100c4f09032SGeoff Rehmet
101c4f09032SGeoff Rehmet /*
102c4f09032SGeoff Rehmet * No E box is used, as it's replaced by some ANDs, shifts, and ORs.
103c4f09032SGeoff Rehmet */
104c4f09032SGeoff Rehmet
105*7d681ad7SEdward Tomasz Napierala static __thread u_char u_sbox[8][64];
106*7d681ad7SEdward Tomasz Napierala static const u_char sbox[8][64] = {
107c4f09032SGeoff Rehmet {
108c4f09032SGeoff Rehmet 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
109c4f09032SGeoff Rehmet 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
110c4f09032SGeoff Rehmet 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
111c4f09032SGeoff Rehmet 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13
112c4f09032SGeoff Rehmet },
113c4f09032SGeoff Rehmet {
114c4f09032SGeoff Rehmet 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
115c4f09032SGeoff Rehmet 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
116c4f09032SGeoff Rehmet 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
117c4f09032SGeoff Rehmet 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9
118c4f09032SGeoff Rehmet },
119c4f09032SGeoff Rehmet {
120c4f09032SGeoff Rehmet 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
121c4f09032SGeoff Rehmet 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
122c4f09032SGeoff Rehmet 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
123c4f09032SGeoff Rehmet 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12
124c4f09032SGeoff Rehmet },
125c4f09032SGeoff Rehmet {
126c4f09032SGeoff Rehmet 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
127c4f09032SGeoff Rehmet 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
128c4f09032SGeoff Rehmet 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
129c4f09032SGeoff Rehmet 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14
130c4f09032SGeoff Rehmet },
131c4f09032SGeoff Rehmet {
132c4f09032SGeoff Rehmet 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
133c4f09032SGeoff Rehmet 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
134c4f09032SGeoff Rehmet 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
135c4f09032SGeoff Rehmet 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3
136c4f09032SGeoff Rehmet },
137c4f09032SGeoff Rehmet {
138c4f09032SGeoff Rehmet 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
139c4f09032SGeoff Rehmet 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
140c4f09032SGeoff Rehmet 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
141c4f09032SGeoff Rehmet 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13
142c4f09032SGeoff Rehmet },
143c4f09032SGeoff Rehmet {
144c4f09032SGeoff Rehmet 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
145c4f09032SGeoff Rehmet 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
146c4f09032SGeoff Rehmet 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
147c4f09032SGeoff Rehmet 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12
148c4f09032SGeoff Rehmet },
149c4f09032SGeoff Rehmet {
150c4f09032SGeoff Rehmet 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
151c4f09032SGeoff Rehmet 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
152c4f09032SGeoff Rehmet 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
153c4f09032SGeoff Rehmet 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
154c4f09032SGeoff Rehmet }
155c4f09032SGeoff Rehmet };
156c4f09032SGeoff Rehmet
157*7d681ad7SEdward Tomasz Napierala static __thread u_char un_pbox[32];
158*7d681ad7SEdward Tomasz Napierala static const u_char pbox[32] = {
159c4f09032SGeoff Rehmet 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
160c4f09032SGeoff Rehmet 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25
161c4f09032SGeoff Rehmet };
162c4f09032SGeoff Rehmet
163*7d681ad7SEdward Tomasz Napierala static const u_int32_t bits32[32] =
164c4f09032SGeoff Rehmet {
165c4f09032SGeoff Rehmet 0x80000000, 0x40000000, 0x20000000, 0x10000000,
166c4f09032SGeoff Rehmet 0x08000000, 0x04000000, 0x02000000, 0x01000000,
167c4f09032SGeoff Rehmet 0x00800000, 0x00400000, 0x00200000, 0x00100000,
168c4f09032SGeoff Rehmet 0x00080000, 0x00040000, 0x00020000, 0x00010000,
169c4f09032SGeoff Rehmet 0x00008000, 0x00004000, 0x00002000, 0x00001000,
170c4f09032SGeoff Rehmet 0x00000800, 0x00000400, 0x00000200, 0x00000100,
171c4f09032SGeoff Rehmet 0x00000080, 0x00000040, 0x00000020, 0x00000010,
172c4f09032SGeoff Rehmet 0x00000008, 0x00000004, 0x00000002, 0x00000001
173c4f09032SGeoff Rehmet };
174c4f09032SGeoff Rehmet
175*7d681ad7SEdward Tomasz Napierala static const u_char bits8[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
176c4f09032SGeoff Rehmet
177*7d681ad7SEdward Tomasz Napierala static __thread u_int32_t saltbits;
178*7d681ad7SEdward Tomasz Napierala static __thread u_int32_t old_salt;
179*7d681ad7SEdward Tomasz Napierala static __thread const u_int32_t *bits28, *bits24;
180*7d681ad7SEdward Tomasz Napierala static __thread u_char init_perm[64], final_perm[64];
181*7d681ad7SEdward Tomasz Napierala static __thread u_int32_t en_keysl[16], en_keysr[16];
182*7d681ad7SEdward Tomasz Napierala static __thread u_int32_t de_keysl[16], de_keysr[16];
183*7d681ad7SEdward Tomasz Napierala static __thread int des_initialised = 0;
184*7d681ad7SEdward Tomasz Napierala static __thread u_char m_sbox[4][4096];
185*7d681ad7SEdward Tomasz Napierala static __thread u_int32_t psbox[4][256];
186*7d681ad7SEdward Tomasz Napierala static __thread u_int32_t ip_maskl[8][256], ip_maskr[8][256];
187*7d681ad7SEdward Tomasz Napierala static __thread u_int32_t fp_maskl[8][256], fp_maskr[8][256];
188*7d681ad7SEdward Tomasz Napierala static __thread u_int32_t key_perm_maskl[8][128], key_perm_maskr[8][128];
189*7d681ad7SEdward Tomasz Napierala static __thread u_int32_t comp_maskl[8][128], comp_maskr[8][128];
190*7d681ad7SEdward Tomasz Napierala static __thread u_int32_t old_rawkey0, old_rawkey1;
191c4f09032SGeoff Rehmet
192*7d681ad7SEdward Tomasz Napierala static const u_char ascii64[] =
193c4f09032SGeoff Rehmet "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
194c4f09032SGeoff Rehmet /* 0000000000111111111122222222223333333333444444444455555555556666 */
195c4f09032SGeoff Rehmet /* 0123456789012345678901234567890123456789012345678901234567890123 */
196c4f09032SGeoff Rehmet
197712ca8b4SGeoff Rehmet static INLINE int
ascii_to_bin(char ch)198c4f09032SGeoff Rehmet ascii_to_bin(char ch)
199c4f09032SGeoff Rehmet {
200c4f09032SGeoff Rehmet if (ch > 'z')
201c4f09032SGeoff Rehmet return(0);
202c4f09032SGeoff Rehmet if (ch >= 'a')
203c4f09032SGeoff Rehmet return(ch - 'a' + 38);
204c4f09032SGeoff Rehmet if (ch > 'Z')
205c4f09032SGeoff Rehmet return(0);
206c4f09032SGeoff Rehmet if (ch >= 'A')
207c4f09032SGeoff Rehmet return(ch - 'A' + 12);
208c4f09032SGeoff Rehmet if (ch > '9')
209c4f09032SGeoff Rehmet return(0);
210c4f09032SGeoff Rehmet if (ch >= '.')
211c4f09032SGeoff Rehmet return(ch - '.');
212c4f09032SGeoff Rehmet return(0);
213c4f09032SGeoff Rehmet }
214c4f09032SGeoff Rehmet
215c4f09032SGeoff Rehmet static void
des_init(void)216f2ac424aSMark Murray des_init(void)
217c4f09032SGeoff Rehmet {
218c4f09032SGeoff Rehmet int i, j, b, k, inbit, obit;
219e1e54354SMark Murray u_int32_t *p, *il, *ir, *fl, *fr;
220c4f09032SGeoff Rehmet
221c4f09032SGeoff Rehmet old_rawkey0 = old_rawkey1 = 0L;
222c4f09032SGeoff Rehmet saltbits = 0L;
223c4f09032SGeoff Rehmet old_salt = 0L;
224c4f09032SGeoff Rehmet bits24 = (bits28 = bits32 + 4) + 4;
225c4f09032SGeoff Rehmet
226c4f09032SGeoff Rehmet /*
227c4f09032SGeoff Rehmet * Invert the S-boxes, reordering the input bits.
228c4f09032SGeoff Rehmet */
229c4f09032SGeoff Rehmet for (i = 0; i < 8; i++)
230c4f09032SGeoff Rehmet for (j = 0; j < 64; j++) {
231c4f09032SGeoff Rehmet b = (j & 0x20) | ((j & 1) << 4) | ((j >> 1) & 0xf);
232c4f09032SGeoff Rehmet u_sbox[i][j] = sbox[i][b];
233c4f09032SGeoff Rehmet }
234c4f09032SGeoff Rehmet
235c4f09032SGeoff Rehmet /*
236c4f09032SGeoff Rehmet * Convert the inverted S-boxes into 4 arrays of 8 bits.
237c4f09032SGeoff Rehmet * Each will handle 12 bits of the S-box input.
238c4f09032SGeoff Rehmet */
239c4f09032SGeoff Rehmet for (b = 0; b < 4; b++)
240c4f09032SGeoff Rehmet for (i = 0; i < 64; i++)
241c4f09032SGeoff Rehmet for (j = 0; j < 64; j++)
242c4f09032SGeoff Rehmet m_sbox[b][(i << 6) | j] =
243f2ac424aSMark Murray (u_char)((u_sbox[(b << 1)][i] << 4) |
244f2ac424aSMark Murray u_sbox[(b << 1) + 1][j]);
245c4f09032SGeoff Rehmet
246c4f09032SGeoff Rehmet /*
247c4f09032SGeoff Rehmet * Set up the initial & final permutations into a useful form, and
248c4f09032SGeoff Rehmet * initialise the inverted key permutation.
249c4f09032SGeoff Rehmet */
250c4f09032SGeoff Rehmet for (i = 0; i < 64; i++) {
251f2ac424aSMark Murray init_perm[final_perm[i] = IP[i] - 1] = (u_char)i;
252c4f09032SGeoff Rehmet inv_key_perm[i] = 255;
253c4f09032SGeoff Rehmet }
254c4f09032SGeoff Rehmet
255c4f09032SGeoff Rehmet /*
256c4f09032SGeoff Rehmet * Invert the key permutation and initialise the inverted key
257c4f09032SGeoff Rehmet * compression permutation.
258c4f09032SGeoff Rehmet */
259c4f09032SGeoff Rehmet for (i = 0; i < 56; i++) {
260f2ac424aSMark Murray inv_key_perm[key_perm[i] - 1] = (u_char)i;
261c4f09032SGeoff Rehmet inv_comp_perm[i] = 255;
262c4f09032SGeoff Rehmet }
263c4f09032SGeoff Rehmet
264c4f09032SGeoff Rehmet /*
265c4f09032SGeoff Rehmet * Invert the key compression permutation.
266c4f09032SGeoff Rehmet */
267c4f09032SGeoff Rehmet for (i = 0; i < 48; i++) {
268f2ac424aSMark Murray inv_comp_perm[comp_perm[i] - 1] = (u_char)i;
269c4f09032SGeoff Rehmet }
270c4f09032SGeoff Rehmet
271c4f09032SGeoff Rehmet /*
272c4f09032SGeoff Rehmet * Set up the OR-mask arrays for the initial and final permutations,
273c4f09032SGeoff Rehmet * and for the key initial and compression permutations.
274c4f09032SGeoff Rehmet */
275c4f09032SGeoff Rehmet for (k = 0; k < 8; k++) {
276c4f09032SGeoff Rehmet for (i = 0; i < 256; i++) {
277c4f09032SGeoff Rehmet *(il = &ip_maskl[k][i]) = 0L;
278c4f09032SGeoff Rehmet *(ir = &ip_maskr[k][i]) = 0L;
279c4f09032SGeoff Rehmet *(fl = &fp_maskl[k][i]) = 0L;
280c4f09032SGeoff Rehmet *(fr = &fp_maskr[k][i]) = 0L;
281c4f09032SGeoff Rehmet for (j = 0; j < 8; j++) {
282c4f09032SGeoff Rehmet inbit = 8 * k + j;
283c4f09032SGeoff Rehmet if (i & bits8[j]) {
284c4f09032SGeoff Rehmet if ((obit = init_perm[inbit]) < 32)
285c4f09032SGeoff Rehmet *il |= bits32[obit];
286c4f09032SGeoff Rehmet else
287c4f09032SGeoff Rehmet *ir |= bits32[obit-32];
288c4f09032SGeoff Rehmet if ((obit = final_perm[inbit]) < 32)
289c4f09032SGeoff Rehmet *fl |= bits32[obit];
290c4f09032SGeoff Rehmet else
291c4f09032SGeoff Rehmet *fr |= bits32[obit - 32];
292c4f09032SGeoff Rehmet }
293c4f09032SGeoff Rehmet }
294c4f09032SGeoff Rehmet }
295c4f09032SGeoff Rehmet for (i = 0; i < 128; i++) {
296c4f09032SGeoff Rehmet *(il = &key_perm_maskl[k][i]) = 0L;
297c4f09032SGeoff Rehmet *(ir = &key_perm_maskr[k][i]) = 0L;
298c4f09032SGeoff Rehmet for (j = 0; j < 7; j++) {
299c4f09032SGeoff Rehmet inbit = 8 * k + j;
300c4f09032SGeoff Rehmet if (i & bits8[j + 1]) {
301c4f09032SGeoff Rehmet if ((obit = inv_key_perm[inbit]) == 255)
302c4f09032SGeoff Rehmet continue;
303c4f09032SGeoff Rehmet if (obit < 28)
304c4f09032SGeoff Rehmet *il |= bits28[obit];
305c4f09032SGeoff Rehmet else
306c4f09032SGeoff Rehmet *ir |= bits28[obit - 28];
307c4f09032SGeoff Rehmet }
308c4f09032SGeoff Rehmet }
309c4f09032SGeoff Rehmet *(il = &comp_maskl[k][i]) = 0L;
310c4f09032SGeoff Rehmet *(ir = &comp_maskr[k][i]) = 0L;
311c4f09032SGeoff Rehmet for (j = 0; j < 7; j++) {
312c4f09032SGeoff Rehmet inbit = 7 * k + j;
313c4f09032SGeoff Rehmet if (i & bits8[j + 1]) {
314c4f09032SGeoff Rehmet if ((obit=inv_comp_perm[inbit]) == 255)
315c4f09032SGeoff Rehmet continue;
316c4f09032SGeoff Rehmet if (obit < 24)
317c4f09032SGeoff Rehmet *il |= bits24[obit];
318c4f09032SGeoff Rehmet else
319c4f09032SGeoff Rehmet *ir |= bits24[obit - 24];
320c4f09032SGeoff Rehmet }
321c4f09032SGeoff Rehmet }
322c4f09032SGeoff Rehmet }
323c4f09032SGeoff Rehmet }
324c4f09032SGeoff Rehmet
325c4f09032SGeoff Rehmet /*
326c4f09032SGeoff Rehmet * Invert the P-box permutation, and convert into OR-masks for
327c4f09032SGeoff Rehmet * handling the output of the S-box arrays setup above.
328c4f09032SGeoff Rehmet */
329c4f09032SGeoff Rehmet for (i = 0; i < 32; i++)
330f2ac424aSMark Murray un_pbox[pbox[i] - 1] = (u_char)i;
331c4f09032SGeoff Rehmet
332c4f09032SGeoff Rehmet for (b = 0; b < 4; b++)
333c4f09032SGeoff Rehmet for (i = 0; i < 256; i++) {
334c4f09032SGeoff Rehmet *(p = &psbox[b][i]) = 0L;
335c4f09032SGeoff Rehmet for (j = 0; j < 8; j++) {
336c4f09032SGeoff Rehmet if (i & bits8[j])
337c4f09032SGeoff Rehmet *p |= bits32[un_pbox[8 * b + j]];
338c4f09032SGeoff Rehmet }
339c4f09032SGeoff Rehmet }
340c4f09032SGeoff Rehmet
341c4f09032SGeoff Rehmet des_initialised = 1;
342c4f09032SGeoff Rehmet }
343c4f09032SGeoff Rehmet
344c4f09032SGeoff Rehmet static void
setup_salt(u_int32_t salt)345f2ac424aSMark Murray setup_salt(u_int32_t salt)
346c4f09032SGeoff Rehmet {
347e1e54354SMark Murray u_int32_t obit, saltbit;
348c4f09032SGeoff Rehmet int i;
349c4f09032SGeoff Rehmet
350c4f09032SGeoff Rehmet if (salt == old_salt)
351c4f09032SGeoff Rehmet return;
352c4f09032SGeoff Rehmet old_salt = salt;
353c4f09032SGeoff Rehmet
354c4f09032SGeoff Rehmet saltbits = 0L;
355c4f09032SGeoff Rehmet saltbit = 1;
356c4f09032SGeoff Rehmet obit = 0x800000;
357c4f09032SGeoff Rehmet for (i = 0; i < 24; i++) {
358c4f09032SGeoff Rehmet if (salt & saltbit)
359c4f09032SGeoff Rehmet saltbits |= obit;
360c4f09032SGeoff Rehmet saltbit <<= 1;
361c4f09032SGeoff Rehmet obit >>= 1;
362c4f09032SGeoff Rehmet }
363c4f09032SGeoff Rehmet }
364c4f09032SGeoff Rehmet
365bf8f9d53SPaul Traina static int
des_setkey(const char * key)366c4f09032SGeoff Rehmet des_setkey(const char *key)
367c4f09032SGeoff Rehmet {
368e1e54354SMark Murray u_int32_t k0, k1, rawkey0, rawkey1;
36996e718feSMark Murray int shifts, round;
370c4f09032SGeoff Rehmet
371c4f09032SGeoff Rehmet if (!des_initialised)
372c4f09032SGeoff Rehmet des_init();
373c4f09032SGeoff Rehmet
374f2ac424aSMark Murray rawkey0 = ntohl(*(const u_int32_t *) key);
375f2ac424aSMark Murray rawkey1 = ntohl(*(const u_int32_t *) (key + 4));
376c4f09032SGeoff Rehmet
377c4f09032SGeoff Rehmet if ((rawkey0 | rawkey1)
378c4f09032SGeoff Rehmet && rawkey0 == old_rawkey0
379c4f09032SGeoff Rehmet && rawkey1 == old_rawkey1) {
380c4f09032SGeoff Rehmet /*
381c4f09032SGeoff Rehmet * Already setup for this key.
382c4f09032SGeoff Rehmet * This optimisation fails on a zero key (which is weak and
383c4f09032SGeoff Rehmet * has bad parity anyway) in order to simplify the starting
384c4f09032SGeoff Rehmet * conditions.
385c4f09032SGeoff Rehmet */
386c4f09032SGeoff Rehmet return(0);
387c4f09032SGeoff Rehmet }
388c4f09032SGeoff Rehmet old_rawkey0 = rawkey0;
389c4f09032SGeoff Rehmet old_rawkey1 = rawkey1;
390c4f09032SGeoff Rehmet
391c4f09032SGeoff Rehmet /*
392c4f09032SGeoff Rehmet * Do key permutation and split into two 28-bit subkeys.
393c4f09032SGeoff Rehmet */
394c4f09032SGeoff Rehmet k0 = key_perm_maskl[0][rawkey0 >> 25]
395c4f09032SGeoff Rehmet | key_perm_maskl[1][(rawkey0 >> 17) & 0x7f]
396c4f09032SGeoff Rehmet | key_perm_maskl[2][(rawkey0 >> 9) & 0x7f]
397c4f09032SGeoff Rehmet | key_perm_maskl[3][(rawkey0 >> 1) & 0x7f]
398c4f09032SGeoff Rehmet | key_perm_maskl[4][rawkey1 >> 25]
399c4f09032SGeoff Rehmet | key_perm_maskl[5][(rawkey1 >> 17) & 0x7f]
400c4f09032SGeoff Rehmet | key_perm_maskl[6][(rawkey1 >> 9) & 0x7f]
401c4f09032SGeoff Rehmet | key_perm_maskl[7][(rawkey1 >> 1) & 0x7f];
402c4f09032SGeoff Rehmet k1 = key_perm_maskr[0][rawkey0 >> 25]
403c4f09032SGeoff Rehmet | key_perm_maskr[1][(rawkey0 >> 17) & 0x7f]
404c4f09032SGeoff Rehmet | key_perm_maskr[2][(rawkey0 >> 9) & 0x7f]
405c4f09032SGeoff Rehmet | key_perm_maskr[3][(rawkey0 >> 1) & 0x7f]
406c4f09032SGeoff Rehmet | key_perm_maskr[4][rawkey1 >> 25]
407c4f09032SGeoff Rehmet | key_perm_maskr[5][(rawkey1 >> 17) & 0x7f]
408c4f09032SGeoff Rehmet | key_perm_maskr[6][(rawkey1 >> 9) & 0x7f]
409c4f09032SGeoff Rehmet | key_perm_maskr[7][(rawkey1 >> 1) & 0x7f];
410c4f09032SGeoff Rehmet /*
411c4f09032SGeoff Rehmet * Rotate subkeys and do compression permutation.
412c4f09032SGeoff Rehmet */
413c4f09032SGeoff Rehmet shifts = 0;
414c4f09032SGeoff Rehmet for (round = 0; round < 16; round++) {
415e1e54354SMark Murray u_int32_t t0, t1;
416c4f09032SGeoff Rehmet
417c4f09032SGeoff Rehmet shifts += key_shifts[round];
418c4f09032SGeoff Rehmet
419c4f09032SGeoff Rehmet t0 = (k0 << shifts) | (k0 >> (28 - shifts));
420c4f09032SGeoff Rehmet t1 = (k1 << shifts) | (k1 >> (28 - shifts));
421c4f09032SGeoff Rehmet
422c4f09032SGeoff Rehmet de_keysl[15 - round] =
423c4f09032SGeoff Rehmet en_keysl[round] = comp_maskl[0][(t0 >> 21) & 0x7f]
424c4f09032SGeoff Rehmet | comp_maskl[1][(t0 >> 14) & 0x7f]
425c4f09032SGeoff Rehmet | comp_maskl[2][(t0 >> 7) & 0x7f]
426c4f09032SGeoff Rehmet | comp_maskl[3][t0 & 0x7f]
427c4f09032SGeoff Rehmet | comp_maskl[4][(t1 >> 21) & 0x7f]
428c4f09032SGeoff Rehmet | comp_maskl[5][(t1 >> 14) & 0x7f]
429c4f09032SGeoff Rehmet | comp_maskl[6][(t1 >> 7) & 0x7f]
430c4f09032SGeoff Rehmet | comp_maskl[7][t1 & 0x7f];
431c4f09032SGeoff Rehmet
432c4f09032SGeoff Rehmet de_keysr[15 - round] =
433c4f09032SGeoff Rehmet en_keysr[round] = comp_maskr[0][(t0 >> 21) & 0x7f]
434c4f09032SGeoff Rehmet | comp_maskr[1][(t0 >> 14) & 0x7f]
435c4f09032SGeoff Rehmet | comp_maskr[2][(t0 >> 7) & 0x7f]
436c4f09032SGeoff Rehmet | comp_maskr[3][t0 & 0x7f]
437c4f09032SGeoff Rehmet | comp_maskr[4][(t1 >> 21) & 0x7f]
438c4f09032SGeoff Rehmet | comp_maskr[5][(t1 >> 14) & 0x7f]
439c4f09032SGeoff Rehmet | comp_maskr[6][(t1 >> 7) & 0x7f]
440c4f09032SGeoff Rehmet | comp_maskr[7][t1 & 0x7f];
441c4f09032SGeoff Rehmet }
442c4f09032SGeoff Rehmet return(0);
443c4f09032SGeoff Rehmet }
444c4f09032SGeoff Rehmet
445c4f09032SGeoff Rehmet static int
do_des(u_int32_t l_in,u_int32_t r_in,u_int32_t * l_out,u_int32_t * r_out,int count)446e1e54354SMark Murray do_des( u_int32_t l_in, u_int32_t r_in, u_int32_t *l_out, u_int32_t *r_out, int count)
447c4f09032SGeoff Rehmet {
448c4f09032SGeoff Rehmet /*
449c4f09032SGeoff Rehmet * l_in, r_in, l_out, and r_out are in pseudo-"big-endian" format.
450c4f09032SGeoff Rehmet */
451e1e54354SMark Murray u_int32_t l, r, *kl, *kr, *kl1, *kr1;
452e1e54354SMark Murray u_int32_t f, r48l, r48r;
45396e718feSMark Murray int round;
454c4f09032SGeoff Rehmet
455c4f09032SGeoff Rehmet if (count == 0) {
456c4f09032SGeoff Rehmet return(1);
457c4f09032SGeoff Rehmet } else if (count > 0) {
458c4f09032SGeoff Rehmet /*
459c4f09032SGeoff Rehmet * Encrypting
460c4f09032SGeoff Rehmet */
461c4f09032SGeoff Rehmet kl1 = en_keysl;
462c4f09032SGeoff Rehmet kr1 = en_keysr;
463c4f09032SGeoff Rehmet } else {
464c4f09032SGeoff Rehmet /*
465c4f09032SGeoff Rehmet * Decrypting
466c4f09032SGeoff Rehmet */
467c4f09032SGeoff Rehmet count = -count;
468c4f09032SGeoff Rehmet kl1 = de_keysl;
469c4f09032SGeoff Rehmet kr1 = de_keysr;
470c4f09032SGeoff Rehmet }
471c4f09032SGeoff Rehmet
472c4f09032SGeoff Rehmet /*
473c4f09032SGeoff Rehmet * Do initial permutation (IP).
474c4f09032SGeoff Rehmet */
475c4f09032SGeoff Rehmet l = ip_maskl[0][l_in >> 24]
476c4f09032SGeoff Rehmet | ip_maskl[1][(l_in >> 16) & 0xff]
477c4f09032SGeoff Rehmet | ip_maskl[2][(l_in >> 8) & 0xff]
478c4f09032SGeoff Rehmet | ip_maskl[3][l_in & 0xff]
479c4f09032SGeoff Rehmet | ip_maskl[4][r_in >> 24]
480c4f09032SGeoff Rehmet | ip_maskl[5][(r_in >> 16) & 0xff]
481c4f09032SGeoff Rehmet | ip_maskl[6][(r_in >> 8) & 0xff]
482c4f09032SGeoff Rehmet | ip_maskl[7][r_in & 0xff];
483c4f09032SGeoff Rehmet r = ip_maskr[0][l_in >> 24]
484c4f09032SGeoff Rehmet | ip_maskr[1][(l_in >> 16) & 0xff]
485c4f09032SGeoff Rehmet | ip_maskr[2][(l_in >> 8) & 0xff]
486c4f09032SGeoff Rehmet | ip_maskr[3][l_in & 0xff]
487c4f09032SGeoff Rehmet | ip_maskr[4][r_in >> 24]
488c4f09032SGeoff Rehmet | ip_maskr[5][(r_in >> 16) & 0xff]
489c4f09032SGeoff Rehmet | ip_maskr[6][(r_in >> 8) & 0xff]
490c4f09032SGeoff Rehmet | ip_maskr[7][r_in & 0xff];
491c4f09032SGeoff Rehmet
492c4f09032SGeoff Rehmet while (count--) {
493c4f09032SGeoff Rehmet /*
494c4f09032SGeoff Rehmet * Do each round.
495c4f09032SGeoff Rehmet */
496c4f09032SGeoff Rehmet kl = kl1;
497c4f09032SGeoff Rehmet kr = kr1;
498c4f09032SGeoff Rehmet round = 16;
499c4f09032SGeoff Rehmet while (round--) {
500c4f09032SGeoff Rehmet /*
501c4f09032SGeoff Rehmet * Expand R to 48 bits (simulate the E-box).
502c4f09032SGeoff Rehmet */
503c4f09032SGeoff Rehmet r48l = ((r & 0x00000001) << 23)
504c4f09032SGeoff Rehmet | ((r & 0xf8000000) >> 9)
505c4f09032SGeoff Rehmet | ((r & 0x1f800000) >> 11)
506c4f09032SGeoff Rehmet | ((r & 0x01f80000) >> 13)
507c4f09032SGeoff Rehmet | ((r & 0x001f8000) >> 15);
508c4f09032SGeoff Rehmet
509c4f09032SGeoff Rehmet r48r = ((r & 0x0001f800) << 7)
510c4f09032SGeoff Rehmet | ((r & 0x00001f80) << 5)
511c4f09032SGeoff Rehmet | ((r & 0x000001f8) << 3)
512c4f09032SGeoff Rehmet | ((r & 0x0000001f) << 1)
513c4f09032SGeoff Rehmet | ((r & 0x80000000) >> 31);
514c4f09032SGeoff Rehmet /*
515c4f09032SGeoff Rehmet * Do salting for crypt() and friends, and
516c4f09032SGeoff Rehmet * XOR with the permuted key.
517c4f09032SGeoff Rehmet */
518c4f09032SGeoff Rehmet f = (r48l ^ r48r) & saltbits;
519c4f09032SGeoff Rehmet r48l ^= f ^ *kl++;
520c4f09032SGeoff Rehmet r48r ^= f ^ *kr++;
521c4f09032SGeoff Rehmet /*
522c4f09032SGeoff Rehmet * Do sbox lookups (which shrink it back to 32 bits)
523c4f09032SGeoff Rehmet * and do the pbox permutation at the same time.
524c4f09032SGeoff Rehmet */
525c4f09032SGeoff Rehmet f = psbox[0][m_sbox[0][r48l >> 12]]
526c4f09032SGeoff Rehmet | psbox[1][m_sbox[1][r48l & 0xfff]]
527c4f09032SGeoff Rehmet | psbox[2][m_sbox[2][r48r >> 12]]
528c4f09032SGeoff Rehmet | psbox[3][m_sbox[3][r48r & 0xfff]];
529c4f09032SGeoff Rehmet /*
530c4f09032SGeoff Rehmet * Now that we've permuted things, complete f().
531c4f09032SGeoff Rehmet */
532c4f09032SGeoff Rehmet f ^= l;
533c4f09032SGeoff Rehmet l = r;
534c4f09032SGeoff Rehmet r = f;
535c4f09032SGeoff Rehmet }
536c4f09032SGeoff Rehmet r = l;
537c4f09032SGeoff Rehmet l = f;
538c4f09032SGeoff Rehmet }
539c4f09032SGeoff Rehmet /*
540c4f09032SGeoff Rehmet * Do final permutation (inverse of IP).
541c4f09032SGeoff Rehmet */
542c4f09032SGeoff Rehmet *l_out = fp_maskl[0][l >> 24]
543c4f09032SGeoff Rehmet | fp_maskl[1][(l >> 16) & 0xff]
544c4f09032SGeoff Rehmet | fp_maskl[2][(l >> 8) & 0xff]
545c4f09032SGeoff Rehmet | fp_maskl[3][l & 0xff]
546c4f09032SGeoff Rehmet | fp_maskl[4][r >> 24]
547c4f09032SGeoff Rehmet | fp_maskl[5][(r >> 16) & 0xff]
548c4f09032SGeoff Rehmet | fp_maskl[6][(r >> 8) & 0xff]
549c4f09032SGeoff Rehmet | fp_maskl[7][r & 0xff];
550c4f09032SGeoff Rehmet *r_out = fp_maskr[0][l >> 24]
551c4f09032SGeoff Rehmet | fp_maskr[1][(l >> 16) & 0xff]
552c4f09032SGeoff Rehmet | fp_maskr[2][(l >> 8) & 0xff]
553c4f09032SGeoff Rehmet | fp_maskr[3][l & 0xff]
554c4f09032SGeoff Rehmet | fp_maskr[4][r >> 24]
555c4f09032SGeoff Rehmet | fp_maskr[5][(r >> 16) & 0xff]
556c4f09032SGeoff Rehmet | fp_maskr[6][(r >> 8) & 0xff]
557c4f09032SGeoff Rehmet | fp_maskr[7][r & 0xff];
558c4f09032SGeoff Rehmet return(0);
559c4f09032SGeoff Rehmet }
560c4f09032SGeoff Rehmet
561bf8f9d53SPaul Traina static int
des_cipher(const char * in,char * out,u_long salt,int count)562f2ac424aSMark Murray des_cipher(const char *in, char *out, u_long salt, int count)
563c4f09032SGeoff Rehmet {
564e1e54354SMark Murray u_int32_t l_out, r_out, rawl, rawr;
565c4f09032SGeoff Rehmet int retval;
566f2ac424aSMark Murray union {
567f2ac424aSMark Murray u_int32_t *ui32;
568f2ac424aSMark Murray const char *c;
569f2ac424aSMark Murray } trans;
570c4f09032SGeoff Rehmet
571c4f09032SGeoff Rehmet if (!des_initialised)
572c4f09032SGeoff Rehmet des_init();
573c4f09032SGeoff Rehmet
574c4f09032SGeoff Rehmet setup_salt(salt);
575c4f09032SGeoff Rehmet
576f2ac424aSMark Murray trans.c = in;
577f2ac424aSMark Murray rawl = ntohl(*trans.ui32++);
578f2ac424aSMark Murray rawr = ntohl(*trans.ui32);
579c4f09032SGeoff Rehmet
580c4f09032SGeoff Rehmet retval = do_des(rawl, rawr, &l_out, &r_out, count);
581c4f09032SGeoff Rehmet
582f2ac424aSMark Murray trans.c = out;
583f2ac424aSMark Murray *trans.ui32++ = htonl(l_out);
584f2ac424aSMark Murray *trans.ui32 = htonl(r_out);
585c4f09032SGeoff Rehmet return(retval);
586c4f09032SGeoff Rehmet }
587c4f09032SGeoff Rehmet
5885f521d7bSEd Schouten int
crypt_des(const char * key,const char * setting,char * buffer)5895f521d7bSEd Schouten crypt_des(const char *key, const char *setting, char *buffer)
590c4f09032SGeoff Rehmet {
591c4f09032SGeoff Rehmet int i;
592e1e54354SMark Murray u_int32_t count, salt, l, r0, r1, keybuf[2];
5935f521d7bSEd Schouten u_char *q;
594c4f09032SGeoff Rehmet
595c4f09032SGeoff Rehmet if (!des_initialised)
596c4f09032SGeoff Rehmet des_init();
597c4f09032SGeoff Rehmet
598c4f09032SGeoff Rehmet /*
599c4f09032SGeoff Rehmet * Copy the key, shifting each character up by one bit
600c4f09032SGeoff Rehmet * and padding with zeros.
601c4f09032SGeoff Rehmet */
602c4f09032SGeoff Rehmet q = (u_char *)keybuf;
603c4f09032SGeoff Rehmet while (q - (u_char *)keybuf - 8) {
604f2ac424aSMark Murray *q++ = *key << 1;
605071183efSBjoern A. Zeeb if (*key != '\0')
606c4f09032SGeoff Rehmet key++;
607c4f09032SGeoff Rehmet }
608f2ac424aSMark Murray if (des_setkey((char *)keybuf))
6095f521d7bSEd Schouten return (-1);
610c4f09032SGeoff Rehmet
611c4f09032SGeoff Rehmet if (*setting == _PASSWORD_EFMT1) {
612c4f09032SGeoff Rehmet /*
613c4f09032SGeoff Rehmet * "new"-style:
614c4f09032SGeoff Rehmet * setting - underscore, 4 bytes of count, 4 bytes of salt
615c4f09032SGeoff Rehmet * key - unlimited characters
616c4f09032SGeoff Rehmet */
617c4f09032SGeoff Rehmet for (i = 1, count = 0L; i < 5; i++)
618f2ac424aSMark Murray count |= ascii_to_bin(setting[i]) << ((i - 1) * 6);
619c4f09032SGeoff Rehmet
620c4f09032SGeoff Rehmet for (i = 5, salt = 0L; i < 9; i++)
621f2ac424aSMark Murray salt |= ascii_to_bin(setting[i]) << ((i - 5) * 6);
622c4f09032SGeoff Rehmet
623c4f09032SGeoff Rehmet while (*key) {
624c4f09032SGeoff Rehmet /*
625c4f09032SGeoff Rehmet * Encrypt the key with itself.
626c4f09032SGeoff Rehmet */
627f2ac424aSMark Murray if (des_cipher((char *)keybuf, (char *)keybuf, 0L, 1))
6285f521d7bSEd Schouten return (-1);
629c4f09032SGeoff Rehmet /*
630c4f09032SGeoff Rehmet * And XOR with the next 8 characters of the key.
631c4f09032SGeoff Rehmet */
632c4f09032SGeoff Rehmet q = (u_char *)keybuf;
633c4f09032SGeoff Rehmet while (q - (u_char *)keybuf - 8 && *key)
634c4f09032SGeoff Rehmet *q++ ^= *key++ << 1;
635c4f09032SGeoff Rehmet
636f2ac424aSMark Murray if (des_setkey((char *)keybuf))
6375f521d7bSEd Schouten return (-1);
638c4f09032SGeoff Rehmet }
6395f521d7bSEd Schouten buffer = stpncpy(buffer, setting, 9);
640c4f09032SGeoff Rehmet } else {
641c4f09032SGeoff Rehmet /*
642c4f09032SGeoff Rehmet * "old"-style:
643c4f09032SGeoff Rehmet * setting - 2 bytes of salt
644c4f09032SGeoff Rehmet * key - up to 8 characters
645c4f09032SGeoff Rehmet */
646c4f09032SGeoff Rehmet count = 25;
647c4f09032SGeoff Rehmet
648c4f09032SGeoff Rehmet salt = (ascii_to_bin(setting[1]) << 6)
649c4f09032SGeoff Rehmet | ascii_to_bin(setting[0]);
650c4f09032SGeoff Rehmet
6515f521d7bSEd Schouten *buffer++ = setting[0];
65249de4157SGeoff Rehmet /*
65349de4157SGeoff Rehmet * If the encrypted password that the salt was extracted from
65449de4157SGeoff Rehmet * is only 1 character long, the salt will be corrupted. We
65549de4157SGeoff Rehmet * need to ensure that the output string doesn't have an extra
65649de4157SGeoff Rehmet * NUL in it!
65749de4157SGeoff Rehmet */
6585f521d7bSEd Schouten *buffer++ = setting[1] ? setting[1] : setting[0];
659c4f09032SGeoff Rehmet }
660c4f09032SGeoff Rehmet setup_salt(salt);
661c4f09032SGeoff Rehmet /*
662c4f09032SGeoff Rehmet * Do it.
663c4f09032SGeoff Rehmet */
664f2ac424aSMark Murray if (do_des(0L, 0L, &r0, &r1, (int)count))
6655f521d7bSEd Schouten return (-1);
666c4f09032SGeoff Rehmet /*
667c4f09032SGeoff Rehmet * Now encode the result...
668c4f09032SGeoff Rehmet */
669c4f09032SGeoff Rehmet l = (r0 >> 8);
6705f521d7bSEd Schouten *buffer++ = ascii64[(l >> 18) & 0x3f];
6715f521d7bSEd Schouten *buffer++ = ascii64[(l >> 12) & 0x3f];
6725f521d7bSEd Schouten *buffer++ = ascii64[(l >> 6) & 0x3f];
6735f521d7bSEd Schouten *buffer++ = ascii64[l & 0x3f];
674c4f09032SGeoff Rehmet
675c4f09032SGeoff Rehmet l = (r0 << 16) | ((r1 >> 16) & 0xffff);
6765f521d7bSEd Schouten *buffer++ = ascii64[(l >> 18) & 0x3f];
6775f521d7bSEd Schouten *buffer++ = ascii64[(l >> 12) & 0x3f];
6785f521d7bSEd Schouten *buffer++ = ascii64[(l >> 6) & 0x3f];
6795f521d7bSEd Schouten *buffer++ = ascii64[l & 0x3f];
680c4f09032SGeoff Rehmet
681c4f09032SGeoff Rehmet l = r1 << 2;
6825f521d7bSEd Schouten *buffer++ = ascii64[(l >> 12) & 0x3f];
6835f521d7bSEd Schouten *buffer++ = ascii64[(l >> 6) & 0x3f];
6845f521d7bSEd Schouten *buffer++ = ascii64[l & 0x3f];
6855f521d7bSEd Schouten *buffer = '\0';
686c4f09032SGeoff Rehmet
6875f521d7bSEd Schouten return (0);
688c4f09032SGeoff Rehmet }
689