blob: 956a3e6797d011d772a6a4ee03b3e28eeb05ed93 [file] [log] [blame]
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +00001/*
2 * FreeSec: libcrypt for NetBSD
3 *
4 * Copyright (c) 1994 David Burren
5 * All rights reserved.
6 *
7 * Adapted for FreeBSD-2.0 by Geoffrey M. Rehmet
8 * this file should now *only* export crypt(), in order to make
9 * binaries of libcrypt exportable from the USA
10 *
11 * Adapted for FreeBSD-4.0 by Mark R V Murray
12 * this file should now *only* export crypt_des(), in order to make
13 * a module that can be optionally included in libcrypt.
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 * 1. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in the
22 * documentation and/or other materials provided with the distribution.
23 * 3. Neither the name of the author nor the names of other contributors
24 * may be used to endorse or promote products derived from this software
25 * without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE.
38 *
39 * This is an original implementation of the DES and the crypt(3) interfaces
40 * by David Burren <davidb@werj.com.au>.
41 *
42 * An excellent reference on the underlying algorithm (and related
43 * algorithms) is:
44 *
45 * B. Schneier, Applied Cryptography: protocols, algorithms,
46 * and source code in C, John Wiley & Sons, 1994.
47 *
48 * Note that in that book's description of DES the lookups for the initial,
49 * pbox, and final permutations are inverted (this has been brought to the
50 * attention of the author). A list of errata for this book has been
51 * posted to the sci.crypt newsgroup by the author and is available for FTP.
52 *
53 * ARCHITECTURE ASSUMPTIONS:
54 * It is assumed that the 8-byte arrays passed by reference can be
55 * addressed as arrays of uint32_t's (ie. the CPU is not picky about
56 * alignment).
57 */
58
59/* A pile of data */
60static const uint8_t IP[64] = {
61 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,
62 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
63 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
64 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7
65};
66
67static const uint8_t key_perm[56] = {
68 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18,
69 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36,
70 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22,
71 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4
72};
73
74static const uint8_t key_shifts[16] = {
75 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
76};
77
78static const uint8_t comp_perm[48] = {
79 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10,
80 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2,
81 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
82 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32
83};
84
85/*
86 * No E box is used, as it's replaced by some ANDs, shifts, and ORs.
87 */
88
89static const uint8_t sbox[8][64] = {
90 {
91 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
92 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
93 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
94 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13
95 },
96 {
97 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
98 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
99 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
100 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9
101 },
102 {
103 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
104 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
105 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
106 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12
107 },
108 {
109 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
110 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
111 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
112 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14
113 },
114 {
115 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
116 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
117 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
118 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3
119 },
120 {
121 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
122 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
123 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
124 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13
125 },
126 {
127 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
128 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
129 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
130 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12
131 },
132 {
133 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
134 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
135 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
136 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
137 }
138};
139
140static const uint8_t pbox[32] = {
141 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
142 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25
143};
144
145static const uint32_t bits32[32] =
146{
147 0x80000000, 0x40000000, 0x20000000, 0x10000000,
148 0x08000000, 0x04000000, 0x02000000, 0x01000000,
149 0x00800000, 0x00400000, 0x00200000, 0x00100000,
150 0x00080000, 0x00040000, 0x00020000, 0x00010000,
151 0x00008000, 0x00004000, 0x00002000, 0x00001000,
152 0x00000800, 0x00000400, 0x00000200, 0x00000100,
153 0x00000080, 0x00000040, 0x00000020, 0x00000010,
154 0x00000008, 0x00000004, 0x00000002, 0x00000001
155};
156
157static const uint8_t bits8[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
158
159
160static int
161ascii_to_bin(char ch)
162{
163 if (ch > 'z')
164 return 0;
165 if (ch >= 'a')
166 return (ch - 'a' + 38);
167 if (ch > 'Z')
168 return 0;
169 if (ch >= 'A')
170 return (ch - 'A' + 12);
171 if (ch > '9')
172 return 0;
173 if (ch >= '.')
174 return (ch - '.');
175 return 0;
176}
177
178
179/* Static stuff that stays resident and doesn't change after
180 * being initialized, and therefore doesn't need to be made
181 * reentrant. */
182struct const_des_ctx {
183 uint8_t init_perm[64], final_perm[64]; /* referenced 2 times each */
184 uint8_t m_sbox[4][4096]; /* 5 times */
185};
186#define C (*cctx)
187#define init_perm (C.init_perm )
188#define final_perm (C.final_perm)
189#define m_sbox (C.m_sbox )
190
191static struct const_des_ctx*
192const_des_init(void)
193{
194 int i, j, b;
195 uint8_t u_sbox[8][64];
196 struct const_des_ctx *cctx;
197
198 cctx = xmalloc(sizeof(*cctx));
199
200 /*
201 * Invert the S-boxes, reordering the input bits.
202 */
203 for (i = 0; i < 8; i++) {
204 for (j = 0; j < 64; j++) {
205 b = (j & 0x20) | ((j & 1) << 4) | ((j >> 1) & 0xf);
206 u_sbox[i][j] = sbox[i][b];
207 }
208 }
209
210 /*
211 * Convert the inverted S-boxes into 4 arrays of 8 bits.
212 * Each will handle 12 bits of the S-box input.
213 */
214 for (b = 0; b < 4; b++)
215 for (i = 0; i < 64; i++)
216 for (j = 0; j < 64; j++)
217 m_sbox[b][(i << 6) | j] =
218 (uint8_t)((u_sbox[(b << 1)][i] << 4) |
219 u_sbox[(b << 1) + 1][j]);
220
221 /*
222 * Set up the initial & final permutations into a useful form.
223 */
224 for (i = 0; i < 64; i++) {
225 final_perm[i] = IP[i] - 1;
226 init_perm[final_perm[i]] = (uint8_t)i;
227 }
228
229 return cctx;
230}
231
Denis Vlasenko04087c62008-06-15 08:12:00 +0000232#define WANT_REPETITIVE_SPEEDUP 0
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000233
234struct des_ctx {
235 const struct const_des_ctx *const_ctx;
236 uint32_t saltbits; /* referenced 5 times */
Denis Vlasenko04087c62008-06-15 08:12:00 +0000237#if WANT_REPETITIVE_SPEEDUP
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000238 uint32_t old_salt; /* 3 times */
239 uint32_t old_rawkey0, old_rawkey1; /* 3 times each */
Denis Vlasenko04087c62008-06-15 08:12:00 +0000240#endif
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000241 uint8_t un_pbox[32]; /* 2 times */
242 uint8_t inv_comp_perm[56]; /* 3 times */
243 uint8_t inv_key_perm[64]; /* 3 times */
244 uint32_t en_keysl[16], en_keysr[16]; /* 2 times each */
Denis Vlasenko04087c62008-06-15 08:12:00 +0000245// uint32_t de_keysl[16], de_keysr[16]; /* 2 times each */
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000246 uint32_t ip_maskl[8][256], ip_maskr[8][256]; /* 9 times each */
247 uint32_t fp_maskl[8][256], fp_maskr[8][256]; /* 9 times each */
248 uint32_t key_perm_maskl[8][128], key_perm_maskr[8][128]; /* 9 times */
249 uint32_t comp_maskl[8][128], comp_maskr[8][128]; /* 9 times each */
250 uint32_t psbox[4][256]; /* 5 times */
251};
252#define D (*ctx)
253#define const_ctx (D.const_ctx )
254#define saltbits (D.saltbits )
255#define old_salt (D.old_salt )
256#define old_rawkey0 (D.old_rawkey0 )
257#define old_rawkey1 (D.old_rawkey1 )
258#define un_pbox (D.un_pbox )
259#define inv_comp_perm (D.inv_comp_perm )
260#define inv_key_perm (D.inv_key_perm )
261#define en_keysl (D.en_keysl )
262#define en_keysr (D.en_keysr )
Denis Vlasenko04087c62008-06-15 08:12:00 +0000263//#define de_keysl (D.de_keysl )
264//#define de_keysr (D.de_keysr )
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000265#define ip_maskl (D.ip_maskl )
266#define ip_maskr (D.ip_maskr )
267#define fp_maskl (D.fp_maskl )
268#define fp_maskr (D.fp_maskr )
269#define key_perm_maskl (D.key_perm_maskl )
270#define key_perm_maskr (D.key_perm_maskr )
271#define comp_maskl (D.comp_maskl )
272#define comp_maskr (D.comp_maskr )
273#define psbox (D.psbox )
274
275static struct des_ctx*
276des_init(struct des_ctx *ctx, const struct const_des_ctx *cctx)
277{
278 int i, j, b, k, inbit, obit;
Denis Vlasenko04087c62008-06-15 08:12:00 +0000279 uint32_t p;
280 uint32_t il, ir, fl, fr;
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000281 const uint32_t *bits28, *bits24;
282
283 if (!ctx)
284 ctx = xmalloc(sizeof(*ctx));
285 const_ctx = cctx;
286
Denis Vlasenko04087c62008-06-15 08:12:00 +0000287#if WANT_REPETITIVE_SPEEDUP
288 old_rawkey0 = old_rawkey1 = 0;
289 old_salt = 0;
290#endif
291 saltbits = 0;
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000292 bits28 = bits32 + 4;
293 bits24 = bits28 + 4;
294
295 /*
296 * Initialise the inverted key permutation.
297 */
298 for (i = 0; i < 64; i++) {
299 inv_key_perm[i] = 255;
300 }
301
302 /*
303 * Invert the key permutation and initialise the inverted key
304 * compression permutation.
305 */
306 for (i = 0; i < 56; i++) {
307 inv_key_perm[key_perm[i] - 1] = (uint8_t)i;
308 inv_comp_perm[i] = 255;
309 }
310
311 /*
312 * Invert the key compression permutation.
313 */
314 for (i = 0; i < 48; i++) {
315 inv_comp_perm[comp_perm[i] - 1] = (uint8_t)i;
316 }
317
318 /*
319 * Set up the OR-mask arrays for the initial and final permutations,
320 * and for the key initial and compression permutations.
321 */
322 for (k = 0; k < 8; k++) {
323 for (i = 0; i < 256; i++) {
Denis Vlasenko04087c62008-06-15 08:12:00 +0000324 il = 0;
325 ir = 0;
326 fl = 0;
327 fr = 0;
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000328 for (j = 0; j < 8; j++) {
329 inbit = 8 * k + j;
330 if (i & bits8[j]) {
331 obit = init_perm[inbit];
332 if (obit < 32)
Denis Vlasenko04087c62008-06-15 08:12:00 +0000333 il |= bits32[obit];
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000334 else
Denis Vlasenko04087c62008-06-15 08:12:00 +0000335 ir |= bits32[obit - 32];
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000336 obit = final_perm[inbit];
337 if (obit < 32)
Denis Vlasenko04087c62008-06-15 08:12:00 +0000338 fl |= bits32[obit];
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000339 else
Denis Vlasenko04087c62008-06-15 08:12:00 +0000340 fr |= bits32[obit - 32];
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000341 }
342 }
Denis Vlasenko04087c62008-06-15 08:12:00 +0000343 ip_maskl[k][i] = il;
344 ip_maskr[k][i] = ir;
345 fp_maskl[k][i] = fl;
346 fp_maskr[k][i] = fr;
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000347 }
348 for (i = 0; i < 128; i++) {
Denis Vlasenko04087c62008-06-15 08:12:00 +0000349 il = 0;
350 ir = 0;
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000351 for (j = 0; j < 7; j++) {
352 inbit = 8 * k + j;
353 if (i & bits8[j + 1]) {
354 obit = inv_key_perm[inbit];
355 if (obit == 255)
356 continue;
357 if (obit < 28)
Denis Vlasenko04087c62008-06-15 08:12:00 +0000358 il |= bits28[obit];
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000359 else
Denis Vlasenko04087c62008-06-15 08:12:00 +0000360 ir |= bits28[obit - 28];
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000361 }
362 }
Denis Vlasenko04087c62008-06-15 08:12:00 +0000363 key_perm_maskl[k][i] = il;
364 key_perm_maskr[k][i] = ir;
365 il = 0;
366 ir = 0;
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000367 for (j = 0; j < 7; j++) {
368 inbit = 7 * k + j;
369 if (i & bits8[j + 1]) {
370 obit = inv_comp_perm[inbit];
371 if (obit == 255)
372 continue;
373 if (obit < 24)
Denis Vlasenko04087c62008-06-15 08:12:00 +0000374 il |= bits24[obit];
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000375 else
Denis Vlasenko04087c62008-06-15 08:12:00 +0000376 ir |= bits24[obit - 24];
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000377 }
378 }
Denis Vlasenko04087c62008-06-15 08:12:00 +0000379 comp_maskl[k][i] = il;
380 comp_maskr[k][i] = ir;
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000381 }
382 }
383
384 /*
385 * Invert the P-box permutation, and convert into OR-masks for
386 * handling the output of the S-box arrays setup above.
387 */
388 for (i = 0; i < 32; i++)
389 un_pbox[pbox[i] - 1] = (uint8_t)i;
390
391 for (b = 0; b < 4; b++) {
392 for (i = 0; i < 256; i++) {
Denis Vlasenko04087c62008-06-15 08:12:00 +0000393 p = 0;
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000394 for (j = 0; j < 8; j++) {
395 if (i & bits8[j])
Denis Vlasenko04087c62008-06-15 08:12:00 +0000396 p |= bits32[un_pbox[8 * b + j]];
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000397 }
Denis Vlasenko04087c62008-06-15 08:12:00 +0000398 psbox[b][i] = p;
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000399 }
400 }
401
402 return ctx;
403}
404
405
406static void
407setup_salt(struct des_ctx *ctx, uint32_t salt)
408{
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000409 uint32_t obit, saltbit;
410 int i;
411
Denis Vlasenko04087c62008-06-15 08:12:00 +0000412#if WANT_REPETITIVE_SPEEDUP
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000413 if (salt == old_salt)
414 return;
415 old_salt = salt;
Denis Vlasenko04087c62008-06-15 08:12:00 +0000416#endif
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000417
Denis Vlasenko04087c62008-06-15 08:12:00 +0000418 saltbits = 0;
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000419 saltbit = 1;
420 obit = 0x800000;
421 for (i = 0; i < 24; i++) {
422 if (salt & saltbit)
423 saltbits |= obit;
424 saltbit <<= 1;
425 obit >>= 1;
426 }
427}
428
429static void
430des_setkey(struct des_ctx *ctx, const char *key)
431{
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000432 uint32_t k0, k1, rawkey0, rawkey1;
433 int shifts, round;
434
435 rawkey0 = ntohl(*(const uint32_t *) key);
436 rawkey1 = ntohl(*(const uint32_t *) (key + 4));
437
Denis Vlasenko04087c62008-06-15 08:12:00 +0000438#if WANT_REPETITIVE_SPEEDUP
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000439 if ((rawkey0 | rawkey1)
440 && rawkey0 == old_rawkey0
441 && rawkey1 == old_rawkey1
442 ) {
443 /*
444 * Already setup for this key.
445 * This optimisation fails on a zero key (which is weak and
446 * has bad parity anyway) in order to simplify the starting
447 * conditions.
448 */
449 return;
450 }
451 old_rawkey0 = rawkey0;
452 old_rawkey1 = rawkey1;
Denis Vlasenko04087c62008-06-15 08:12:00 +0000453#endif
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000454
455 /*
456 * Do key permutation and split into two 28-bit subkeys.
457 */
458 k0 = key_perm_maskl[0][rawkey0 >> 25]
459 | key_perm_maskl[1][(rawkey0 >> 17) & 0x7f]
460 | key_perm_maskl[2][(rawkey0 >> 9) & 0x7f]
461 | key_perm_maskl[3][(rawkey0 >> 1) & 0x7f]
462 | key_perm_maskl[4][rawkey1 >> 25]
463 | key_perm_maskl[5][(rawkey1 >> 17) & 0x7f]
464 | key_perm_maskl[6][(rawkey1 >> 9) & 0x7f]
465 | key_perm_maskl[7][(rawkey1 >> 1) & 0x7f];
466 k1 = key_perm_maskr[0][rawkey0 >> 25]
467 | key_perm_maskr[1][(rawkey0 >> 17) & 0x7f]
468 | key_perm_maskr[2][(rawkey0 >> 9) & 0x7f]
469 | key_perm_maskr[3][(rawkey0 >> 1) & 0x7f]
470 | key_perm_maskr[4][rawkey1 >> 25]
471 | key_perm_maskr[5][(rawkey1 >> 17) & 0x7f]
472 | key_perm_maskr[6][(rawkey1 >> 9) & 0x7f]
473 | key_perm_maskr[7][(rawkey1 >> 1) & 0x7f];
474 /*
475 * Rotate subkeys and do compression permutation.
476 */
477 shifts = 0;
478 for (round = 0; round < 16; round++) {
479 uint32_t t0, t1;
480
481 shifts += key_shifts[round];
482
483 t0 = (k0 << shifts) | (k0 >> (28 - shifts));
484 t1 = (k1 << shifts) | (k1 >> (28 - shifts));
485
Denis Vlasenko04087c62008-06-15 08:12:00 +0000486// de_keysl[15 - round] =
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000487 en_keysl[round] = comp_maskl[0][(t0 >> 21) & 0x7f]
488 | comp_maskl[1][(t0 >> 14) & 0x7f]
489 | comp_maskl[2][(t0 >> 7) & 0x7f]
490 | comp_maskl[3][t0 & 0x7f]
491 | comp_maskl[4][(t1 >> 21) & 0x7f]
492 | comp_maskl[5][(t1 >> 14) & 0x7f]
493 | comp_maskl[6][(t1 >> 7) & 0x7f]
494 | comp_maskl[7][t1 & 0x7f];
495
Denis Vlasenko04087c62008-06-15 08:12:00 +0000496// de_keysr[15 - round] =
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000497 en_keysr[round] = comp_maskr[0][(t0 >> 21) & 0x7f]
498 | comp_maskr[1][(t0 >> 14) & 0x7f]
499 | comp_maskr[2][(t0 >> 7) & 0x7f]
500 | comp_maskr[3][t0 & 0x7f]
501 | comp_maskr[4][(t1 >> 21) & 0x7f]
502 | comp_maskr[5][(t1 >> 14) & 0x7f]
503 | comp_maskr[6][(t1 >> 7) & 0x7f]
504 | comp_maskr[7][t1 & 0x7f];
505 }
506}
507
508
Denis Vlasenkoe2352852008-06-14 22:11:29 +0000509static void
Denis Vlasenko04087c62008-06-15 08:12:00 +0000510do_des(struct des_ctx *ctx, /*uint32_t l_in, uint32_t r_in,*/ uint32_t *l_out, uint32_t *r_out, int count)
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000511{
512 const struct const_des_ctx *cctx = const_ctx;
513 /*
514 * l_in, r_in, l_out, and r_out are in pseudo-"big-endian" format.
515 */
Denis Vlasenko04087c62008-06-15 08:12:00 +0000516 uint32_t l, r, *kl, *kr;
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000517 uint32_t f = f; /* silence gcc */
518 uint32_t r48l, r48r;
519 int round;
520
Denis Vlasenko04087c62008-06-15 08:12:00 +0000521 /* Do initial permutation (IP). */
522#if 0
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000523 l = ip_maskl[0][l_in >> 24]
524 | ip_maskl[1][(l_in >> 16) & 0xff]
525 | ip_maskl[2][(l_in >> 8) & 0xff]
526 | ip_maskl[3][l_in & 0xff]
527 | ip_maskl[4][r_in >> 24]
528 | ip_maskl[5][(r_in >> 16) & 0xff]
529 | ip_maskl[6][(r_in >> 8) & 0xff]
530 | ip_maskl[7][r_in & 0xff];
531 r = ip_maskr[0][l_in >> 24]
532 | ip_maskr[1][(l_in >> 16) & 0xff]
533 | ip_maskr[2][(l_in >> 8) & 0xff]
534 | ip_maskr[3][l_in & 0xff]
535 | ip_maskr[4][r_in >> 24]
536 | ip_maskr[5][(r_in >> 16) & 0xff]
537 | ip_maskr[6][(r_in >> 8) & 0xff]
538 | ip_maskr[7][r_in & 0xff];
Denis Vlasenko04087c62008-06-15 08:12:00 +0000539#elif 0 /* -65 bytes (using the fact that l_in == r_in == 0) */
540 l = r = 0;
541 for (round = 0; round < 8; round++) {
542 l |= ip_maskl[round][0];
543 r |= ip_maskr[round][0];
544 }
545 bb_error_msg("l:%x r:%x", l, r); /* reports 0, 0 always! */
546#else /* using the fact that ip_maskX[] is constant (written to by des_init) */
547 l = r = 0;
548#endif
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000549
Denis Vlasenko04087c62008-06-15 08:12:00 +0000550 do {
551 /* Do each round. */
552 kl = en_keysl;
553 kr = en_keysr;
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000554 round = 16;
Denis Vlasenko04087c62008-06-15 08:12:00 +0000555 do {
556 /* Expand R to 48 bits (simulate the E-box). */
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000557 r48l = ((r & 0x00000001) << 23)
558 | ((r & 0xf8000000) >> 9)
559 | ((r & 0x1f800000) >> 11)
560 | ((r & 0x01f80000) >> 13)
561 | ((r & 0x001f8000) >> 15);
562
563 r48r = ((r & 0x0001f800) << 7)
564 | ((r & 0x00001f80) << 5)
565 | ((r & 0x000001f8) << 3)
566 | ((r & 0x0000001f) << 1)
567 | ((r & 0x80000000) >> 31);
568 /*
569 * Do salting for crypt() and friends, and
570 * XOR with the permuted key.
571 */
572 f = (r48l ^ r48r) & saltbits;
573 r48l ^= f ^ *kl++;
574 r48r ^= f ^ *kr++;
575 /*
576 * Do sbox lookups (which shrink it back to 32 bits)
577 * and do the pbox permutation at the same time.
578 */
579 f = psbox[0][m_sbox[0][r48l >> 12]]
580 | psbox[1][m_sbox[1][r48l & 0xfff]]
581 | psbox[2][m_sbox[2][r48r >> 12]]
582 | psbox[3][m_sbox[3][r48r & 0xfff]];
Denis Vlasenko04087c62008-06-15 08:12:00 +0000583 /* Now that we've permuted things, complete f(). */
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000584 f ^= l;
585 l = r;
586 r = f;
Denis Vlasenko04087c62008-06-15 08:12:00 +0000587 } while (--round);
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000588 r = l;
589 l = f;
Denis Vlasenko04087c62008-06-15 08:12:00 +0000590 } while (--count);
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000591 /*
592 * Do final permutation (inverse of IP).
593 */
594 *l_out = fp_maskl[0][l >> 24]
595 | fp_maskl[1][(l >> 16) & 0xff]
596 | fp_maskl[2][(l >> 8) & 0xff]
597 | fp_maskl[3][l & 0xff]
598 | fp_maskl[4][r >> 24]
599 | fp_maskl[5][(r >> 16) & 0xff]
600 | fp_maskl[6][(r >> 8) & 0xff]
601 | fp_maskl[7][r & 0xff];
602 *r_out = fp_maskr[0][l >> 24]
603 | fp_maskr[1][(l >> 16) & 0xff]
604 | fp_maskr[2][(l >> 8) & 0xff]
605 | fp_maskr[3][l & 0xff]
606 | fp_maskr[4][r >> 24]
607 | fp_maskr[5][(r >> 16) & 0xff]
608 | fp_maskr[6][(r >> 8) & 0xff]
609 | fp_maskr[7][r & 0xff];
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000610}
611
612#define DES_OUT_BUFSIZE 21
613
614static char *
Denis Vlasenkoe2352852008-06-14 22:11:29 +0000615NOINLINE
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000616des_crypt(struct des_ctx *ctx, char output[21], const unsigned char *key, const unsigned char *setting)
617{
618 uint32_t salt, l, r0, r1, keybuf[2];
619 uint8_t *p, *q;
620
621 /*
622 * Copy the key, shifting each character up by one bit
623 * and padding with zeros.
624 */
625 q = (uint8_t *)keybuf;
Denis Vlasenkoe2352852008-06-14 22:11:29 +0000626 while (q - (uint8_t *)keybuf != 8) {
627 *q = *key << 1;
628 if (*q)
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000629 key++;
Denis Vlasenkoe2352852008-06-14 22:11:29 +0000630 q++;
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000631 }
632 des_setkey(ctx, (char *)keybuf);
633
634 /*
635 * setting - 2 bytes of salt
636 * key - up to 8 characters
637 */
638 salt = (ascii_to_bin(setting[1]) << 6)
639 | ascii_to_bin(setting[0]);
640
641 output[0] = setting[0];
642 /*
643 * If the encrypted password that the salt was extracted from
644 * is only 1 character long, the salt will be corrupted. We
645 * need to ensure that the output string doesn't have an extra
646 * NUL in it!
647 */
648 output[1] = setting[1] ? setting[1] : output[0];
649
650 p = (uint8_t *)output + 2;
651
652 setup_salt(ctx, salt);
653 /*
654 * Do it.
655 */
Denis Vlasenko04087c62008-06-15 08:12:00 +0000656 do_des(ctx, /*0, 0,*/ &r0, &r1, 25 /* count */);
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000657
658 /*
659 * Now encode the result...
660 */
661 l = (r0 >> 8);
662 *p++ = ascii64[(l >> 18) & 0x3f];
663 *p++ = ascii64[(l >> 12) & 0x3f];
664 *p++ = ascii64[(l >> 6) & 0x3f];
665 *p++ = ascii64[l & 0x3f];
666
Denis Vlasenkoe2352852008-06-14 22:11:29 +0000667 l = ((r0 << 16) | (r1 >> 16));
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000668 *p++ = ascii64[(l >> 18) & 0x3f];
669 *p++ = ascii64[(l >> 12) & 0x3f];
670 *p++ = ascii64[(l >> 6) & 0x3f];
671 *p++ = ascii64[l & 0x3f];
672
673 l = r1 << 2;
674 *p++ = ascii64[(l >> 12) & 0x3f];
675 *p++ = ascii64[(l >> 6) & 0x3f];
676 *p++ = ascii64[l & 0x3f];
677 *p = 0;
678
679 return output;
680}
681
Denis Vlasenko04087c62008-06-15 08:12:00 +0000682#undef WANT_REPETITIVE_SPEEDUP
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000683#undef C
684#undef init_perm
685#undef final_perm
686#undef m_sbox
687#undef D
688#undef const_ctx
689#undef saltbits
690#undef old_salt
691#undef old_rawkey0
692#undef old_rawkey1
693#undef un_pbox
694#undef inv_comp_perm
695#undef inv_key_perm
696#undef en_keysl
697#undef en_keysr
Denis Vlasenko04087c62008-06-15 08:12:00 +0000698//#undef de_keysl
699//#undef de_keysr
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000700#undef ip_maskl
701#undef ip_maskr
702#undef fp_maskl
703#undef fp_maskr
704#undef key_perm_maskl
705#undef key_perm_maskr
706#undef comp_maskl
707#undef comp_maskr
708#undef psbox