blob: dcd3521e258082e475628897346c3dbf60d12ba2 [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 *
Denys Vlasenko95f79532017-08-02 14:26:33 +020027 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ''AS IS'' AND
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +000028 * 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
Denis Vlasenko5cdc2472008-06-15 09:48:18 +000059
60/* Parts busybox doesn't need or had optimized */
61#define USE_PRECOMPUTED_u_sbox 1
62#define USE_REPETITIVE_SPEEDUP 0
63#define USE_ip_mask 0
64#define USE_de_keys 0
65
66
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +000067/* A pile of data */
Denys Vlasenko965b7952020-11-30 13:03:03 +010068static const uint8_t IP[64] ALIGN1 = {
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +000069 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,
70 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
71 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
72 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7
73};
74
Denys Vlasenko965b7952020-11-30 13:03:03 +010075static const uint8_t key_perm[56] ALIGN1 = {
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +000076 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18,
77 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36,
78 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22,
79 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4
80};
81
Denys Vlasenko965b7952020-11-30 13:03:03 +010082static const uint8_t key_shifts[16] ALIGN1 = {
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +000083 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
84};
85
Denys Vlasenko965b7952020-11-30 13:03:03 +010086static const uint8_t comp_perm[48] ALIGN1 = {
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +000087 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10,
88 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2,
89 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
90 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32
91};
92
93/*
94 * No E box is used, as it's replaced by some ANDs, shifts, and ORs.
95 */
Denis Vlasenko5cdc2472008-06-15 09:48:18 +000096#if !USE_PRECOMPUTED_u_sbox
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +000097static const uint8_t sbox[8][64] = {
Denis Vlasenko5cdc2472008-06-15 09:48:18 +000098 { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +000099 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
100 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
101 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13
102 },
Denis Vlasenko5cdc2472008-06-15 09:48:18 +0000103 { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000104 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
105 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
106 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9
107 },
Denis Vlasenko5cdc2472008-06-15 09:48:18 +0000108 { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000109 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
110 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
111 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12
112 },
Denis Vlasenko5cdc2472008-06-15 09:48:18 +0000113 { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000114 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
115 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
116 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14
117 },
Denis Vlasenko5cdc2472008-06-15 09:48:18 +0000118 { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000119 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
120 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
121 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3
122 },
Denis Vlasenko5cdc2472008-06-15 09:48:18 +0000123 { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000124 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
125 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
126 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13
127 },
Denis Vlasenko5cdc2472008-06-15 09:48:18 +0000128 { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000129 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
130 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
131 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12
132 },
Denis Vlasenko5cdc2472008-06-15 09:48:18 +0000133 { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000134 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};
Denis Vlasenko5cdc2472008-06-15 09:48:18 +0000139#else /* precomputed, with half-bytes packed into one byte */
140static const uint8_t u_sbox[8][32] = {
141 { 0x0e, 0xf4, 0x7d, 0x41, 0xe2, 0x2f, 0xdb, 0x18,
142 0xa3, 0x6a, 0xc6, 0xbc, 0x95, 0x59, 0x30, 0x87,
143 0xf4, 0xc1, 0x8e, 0x28, 0x4d, 0x96, 0x12, 0x7b,
144 0x5f, 0xbc, 0x39, 0xe7, 0xa3, 0x0a, 0x65, 0xd0,
145 },
146 { 0x3f, 0xd1, 0x48, 0x7e, 0xf6, 0x2b, 0x83, 0xe4,
147 0xc9, 0x07, 0x12, 0xad, 0x6c, 0x90, 0xb5, 0x5a,
148 0xd0, 0x8e, 0xa7, 0x1b, 0x3a, 0xf4, 0x4d, 0x21,
149 0xb5, 0x68, 0x7c, 0xc6, 0x09, 0x53, 0xe2, 0x9f,
150 },
151 { 0xda, 0x70, 0x09, 0x9e, 0x36, 0x43, 0x6f, 0xa5,
152 0x21, 0x8d, 0x5c, 0xe7, 0xcb, 0xb4, 0xf2, 0x18,
153 0x1d, 0xa6, 0xd4, 0x09, 0x68, 0x9f, 0x83, 0x70,
154 0x4b, 0xf1, 0xe2, 0x3c, 0xb5, 0x5a, 0x2e, 0xc7,
155 },
156 { 0xd7, 0x8d, 0xbe, 0x53, 0x60, 0xf6, 0x09, 0x3a,
157 0x41, 0x72, 0x28, 0xc5, 0x1b, 0xac, 0xe4, 0x9f,
158 0x3a, 0xf6, 0x09, 0x60, 0xac, 0x1b, 0xd7, 0x8d,
159 0x9f, 0x41, 0x53, 0xbe, 0xc5, 0x72, 0x28, 0xe4,
160 },
161 { 0xe2, 0xbc, 0x24, 0xc1, 0x47, 0x7a, 0xdb, 0x16,
162 0x58, 0x05, 0xf3, 0xaf, 0x3d, 0x90, 0x8e, 0x69,
163 0xb4, 0x82, 0xc1, 0x7b, 0x1a, 0xed, 0x27, 0xd8,
164 0x6f, 0xf9, 0x0c, 0x95, 0xa6, 0x43, 0x50, 0x3e,
165 },
166 { 0xac, 0xf1, 0x4a, 0x2f, 0x79, 0xc2, 0x96, 0x58,
167 0x60, 0x1d, 0xd3, 0xe4, 0x0e, 0xb7, 0x35, 0x8b,
168 0x49, 0x3e, 0x2f, 0xc5, 0x92, 0x58, 0xfc, 0xa3,
169 0xb7, 0xe0, 0x14, 0x7a, 0x61, 0x0d, 0x8b, 0xd6,
170 },
171 { 0xd4, 0x0b, 0xb2, 0x7e, 0x4f, 0x90, 0x18, 0xad,
172 0xe3, 0x3c, 0x59, 0xc7, 0x25, 0xfa, 0x86, 0x61,
173 0x61, 0xb4, 0xdb, 0x8d, 0x1c, 0x43, 0xa7, 0x7e,
174 0x9a, 0x5f, 0x06, 0xf8, 0xe0, 0x25, 0x39, 0xc2,
175 },
176 { 0x1d, 0xf2, 0xd8, 0x84, 0xa6, 0x3f, 0x7b, 0x41,
177 0xca, 0x59, 0x63, 0xbe, 0x05, 0xe0, 0x9c, 0x27,
178 0x27, 0x1b, 0xe4, 0x71, 0x49, 0xac, 0x8e, 0xd2,
179 0xf0, 0xc6, 0x9a, 0x0d, 0x3f, 0x53, 0x65, 0xb8,
180 },
181};
182#endif
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000183
Denys Vlasenko965b7952020-11-30 13:03:03 +0100184static const uint8_t pbox[32] ALIGN1 = {
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000185 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
186 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25
187};
188
Denys Vlasenko965b7952020-11-30 13:03:03 +0100189static const uint32_t bits32[32] ALIGN4 = {
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000190 0x80000000, 0x40000000, 0x20000000, 0x10000000,
191 0x08000000, 0x04000000, 0x02000000, 0x01000000,
192 0x00800000, 0x00400000, 0x00200000, 0x00100000,
193 0x00080000, 0x00040000, 0x00020000, 0x00010000,
194 0x00008000, 0x00004000, 0x00002000, 0x00001000,
195 0x00000800, 0x00000400, 0x00000200, 0x00000100,
196 0x00000080, 0x00000040, 0x00000020, 0x00000010,
197 0x00000008, 0x00000004, 0x00000002, 0x00000001
198};
199
Denys Vlasenko965b7952020-11-30 13:03:03 +0100200static const uint8_t bits8[8] ALIGN1 = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000201
202
Denis Vlasenkof45c4f42008-06-16 04:09:25 +0000203static int
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000204ascii_to_bin(char ch)
205{
206 if (ch > 'z')
207 return 0;
208 if (ch >= 'a')
209 return (ch - 'a' + 38);
210 if (ch > 'Z')
211 return 0;
212 if (ch >= 'A')
213 return (ch - 'A' + 12);
214 if (ch > '9')
215 return 0;
216 if (ch >= '.')
217 return (ch - '.');
218 return 0;
219}
220
221
Denis Vlasenkof45c4f42008-06-16 04:09:25 +0000222/* Static stuff that stays resident and doesn't change after
223 * being initialized, and therefore doesn't need to be made
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000224 * reentrant. */
225struct const_des_ctx {
Denis Vlasenko5cdc2472008-06-15 09:48:18 +0000226#if USE_ip_mask
227 uint8_t init_perm[64]; /* referenced 2 times */
228#endif
229 uint8_t final_perm[64]; /* 2 times */
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000230 uint8_t m_sbox[4][4096]; /* 5 times */
231};
232#define C (*cctx)
233#define init_perm (C.init_perm )
234#define final_perm (C.final_perm)
235#define m_sbox (C.m_sbox )
236
237static struct const_des_ctx*
238const_des_init(void)
239{
Denis Vlasenko5cdc2472008-06-15 09:48:18 +0000240 unsigned i, j, b;
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000241 struct const_des_ctx *cctx;
242
Denis Vlasenko5cdc2472008-06-15 09:48:18 +0000243#if !USE_PRECOMPUTED_u_sbox
244 uint8_t u_sbox[8][64];
245
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000246 cctx = xmalloc(sizeof(*cctx));
247
Denis Vlasenko5cdc2472008-06-15 09:48:18 +0000248 /* Invert the S-boxes, reordering the input bits. */
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000249 for (i = 0; i < 8; i++) {
250 for (j = 0; j < 64; j++) {
251 b = (j & 0x20) | ((j & 1) << 4) | ((j >> 1) & 0xf);
252 u_sbox[i][j] = sbox[i][b];
253 }
254 }
Denis Vlasenko5cdc2472008-06-15 09:48:18 +0000255 for (i = 0; i < 8; i++) {
256 fprintf(stderr, "\t{\t");
257 for (j = 0; j < 64; j+=2)
258 fprintf(stderr, " 0x%02x,", u_sbox[i][j] + u_sbox[i][j+1]*16);
259 fprintf(stderr, "\n\t},\n");
260 }
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000261 /*
262 * Convert the inverted S-boxes into 4 arrays of 8 bits.
263 * Each will handle 12 bits of the S-box input.
264 */
265 for (b = 0; b < 4; b++)
266 for (i = 0; i < 64; i++)
267 for (j = 0; j < 64; j++)
268 m_sbox[b][(i << 6) | j] =
269 (uint8_t)((u_sbox[(b << 1)][i] << 4) |
270 u_sbox[(b << 1) + 1][j]);
Denis Vlasenko5cdc2472008-06-15 09:48:18 +0000271#else
272 cctx = xmalloc(sizeof(*cctx));
273
274 /*
275 * Convert the inverted S-boxes into 4 arrays of 8 bits.
276 * Each will handle 12 bits of the S-box input.
277 */
278 for (b = 0; b < 4; b++)
279 for (i = 0; i < 64; i++)
280 for (j = 0; j < 64; j++) {
281 uint8_t lo, hi;
282 hi = u_sbox[(b << 1)][i / 2];
283 if (!(i & 1))
284 hi <<= 4;
285 lo = u_sbox[(b << 1) + 1][j / 2];
286 if (j & 1)
287 lo >>= 4;
288 m_sbox[b][(i << 6) | j] = (hi & 0xf0) | (lo & 0x0f);
289 }
290#endif
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000291
292 /*
293 * Set up the initial & final permutations into a useful form.
294 */
295 for (i = 0; i < 64; i++) {
296 final_perm[i] = IP[i] - 1;
Denis Vlasenko5cdc2472008-06-15 09:48:18 +0000297#if USE_ip_mask
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000298 init_perm[final_perm[i]] = (uint8_t)i;
Denis Vlasenko5cdc2472008-06-15 09:48:18 +0000299#endif
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000300 }
301
302 return cctx;
303}
304
305
306struct des_ctx {
307 const struct const_des_ctx *const_ctx;
308 uint32_t saltbits; /* referenced 5 times */
Denis Vlasenko5cdc2472008-06-15 09:48:18 +0000309#if USE_REPETITIVE_SPEEDUP
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000310 uint32_t old_salt; /* 3 times */
311 uint32_t old_rawkey0, old_rawkey1; /* 3 times each */
Denis Vlasenko04087c62008-06-15 08:12:00 +0000312#endif
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000313 uint8_t un_pbox[32]; /* 2 times */
314 uint8_t inv_comp_perm[56]; /* 3 times */
315 uint8_t inv_key_perm[64]; /* 3 times */
316 uint32_t en_keysl[16], en_keysr[16]; /* 2 times each */
Denis Vlasenko5cdc2472008-06-15 09:48:18 +0000317#if USE_de_keys
318 uint32_t de_keysl[16], de_keysr[16]; /* 2 times each */
319#endif
320#if USE_ip_mask
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000321 uint32_t ip_maskl[8][256], ip_maskr[8][256]; /* 9 times each */
Denis Vlasenko5cdc2472008-06-15 09:48:18 +0000322#endif
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000323 uint32_t fp_maskl[8][256], fp_maskr[8][256]; /* 9 times each */
324 uint32_t key_perm_maskl[8][128], key_perm_maskr[8][128]; /* 9 times */
325 uint32_t comp_maskl[8][128], comp_maskr[8][128]; /* 9 times each */
326 uint32_t psbox[4][256]; /* 5 times */
327};
328#define D (*ctx)
329#define const_ctx (D.const_ctx )
330#define saltbits (D.saltbits )
331#define old_salt (D.old_salt )
332#define old_rawkey0 (D.old_rawkey0 )
333#define old_rawkey1 (D.old_rawkey1 )
334#define un_pbox (D.un_pbox )
335#define inv_comp_perm (D.inv_comp_perm )
336#define inv_key_perm (D.inv_key_perm )
337#define en_keysl (D.en_keysl )
338#define en_keysr (D.en_keysr )
Denis Vlasenko5cdc2472008-06-15 09:48:18 +0000339#define de_keysl (D.de_keysl )
340#define de_keysr (D.de_keysr )
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000341#define ip_maskl (D.ip_maskl )
342#define ip_maskr (D.ip_maskr )
343#define fp_maskl (D.fp_maskl )
344#define fp_maskr (D.fp_maskr )
345#define key_perm_maskl (D.key_perm_maskl )
346#define key_perm_maskr (D.key_perm_maskr )
347#define comp_maskl (D.comp_maskl )
348#define comp_maskr (D.comp_maskr )
349#define psbox (D.psbox )
350
351static struct des_ctx*
352des_init(struct des_ctx *ctx, const struct const_des_ctx *cctx)
353{
354 int i, j, b, k, inbit, obit;
Denis Vlasenko04087c62008-06-15 08:12:00 +0000355 uint32_t p;
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000356 const uint32_t *bits28, *bits24;
357
358 if (!ctx)
359 ctx = xmalloc(sizeof(*ctx));
360 const_ctx = cctx;
361
Denis Vlasenko5cdc2472008-06-15 09:48:18 +0000362#if USE_REPETITIVE_SPEEDUP
Denis Vlasenko04087c62008-06-15 08:12:00 +0000363 old_rawkey0 = old_rawkey1 = 0;
364 old_salt = 0;
365#endif
366 saltbits = 0;
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000367 bits28 = bits32 + 4;
368 bits24 = bits28 + 4;
369
Denis Vlasenko5cdc2472008-06-15 09:48:18 +0000370 /* Initialise the inverted key permutation. */
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000371 for (i = 0; i < 64; i++) {
372 inv_key_perm[i] = 255;
373 }
374
375 /*
376 * Invert the key permutation and initialise the inverted key
377 * compression permutation.
378 */
379 for (i = 0; i < 56; i++) {
380 inv_key_perm[key_perm[i] - 1] = (uint8_t)i;
381 inv_comp_perm[i] = 255;
382 }
383
Denis Vlasenko5cdc2472008-06-15 09:48:18 +0000384 /* Invert the key compression permutation. */
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000385 for (i = 0; i < 48; i++) {
386 inv_comp_perm[comp_perm[i] - 1] = (uint8_t)i;
387 }
388
389 /*
390 * Set up the OR-mask arrays for the initial and final permutations,
391 * and for the key initial and compression permutations.
392 */
393 for (k = 0; k < 8; k++) {
Denis Vlasenko5cdc2472008-06-15 09:48:18 +0000394 uint32_t il, ir;
395 uint32_t fl, fr;
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000396 for (i = 0; i < 256; i++) {
Denis Vlasenko5cdc2472008-06-15 09:48:18 +0000397#if USE_ip_mask
Denis Vlasenko04087c62008-06-15 08:12:00 +0000398 il = 0;
399 ir = 0;
Denis Vlasenko5cdc2472008-06-15 09:48:18 +0000400#endif
Denis Vlasenko04087c62008-06-15 08:12:00 +0000401 fl = 0;
402 fr = 0;
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000403 for (j = 0; j < 8; j++) {
404 inbit = 8 * k + j;
405 if (i & bits8[j]) {
Denis Vlasenko5cdc2472008-06-15 09:48:18 +0000406#if USE_ip_mask
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000407 obit = init_perm[inbit];
408 if (obit < 32)
Denis Vlasenko04087c62008-06-15 08:12:00 +0000409 il |= bits32[obit];
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000410 else
Denis Vlasenko04087c62008-06-15 08:12:00 +0000411 ir |= bits32[obit - 32];
Denis Vlasenko5cdc2472008-06-15 09:48:18 +0000412#endif
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000413 obit = final_perm[inbit];
414 if (obit < 32)
Denis Vlasenko04087c62008-06-15 08:12:00 +0000415 fl |= bits32[obit];
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000416 else
Denis Vlasenko04087c62008-06-15 08:12:00 +0000417 fr |= bits32[obit - 32];
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000418 }
419 }
Denis Vlasenko5cdc2472008-06-15 09:48:18 +0000420#if USE_ip_mask
Denis Vlasenko04087c62008-06-15 08:12:00 +0000421 ip_maskl[k][i] = il;
422 ip_maskr[k][i] = ir;
Denis Vlasenko5cdc2472008-06-15 09:48:18 +0000423#endif
Denis Vlasenko04087c62008-06-15 08:12:00 +0000424 fp_maskl[k][i] = fl;
425 fp_maskr[k][i] = fr;
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000426 }
427 for (i = 0; i < 128; i++) {
Denis Vlasenko04087c62008-06-15 08:12:00 +0000428 il = 0;
429 ir = 0;
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000430 for (j = 0; j < 7; j++) {
431 inbit = 8 * k + j;
432 if (i & bits8[j + 1]) {
433 obit = inv_key_perm[inbit];
434 if (obit == 255)
435 continue;
436 if (obit < 28)
Denis Vlasenko04087c62008-06-15 08:12:00 +0000437 il |= bits28[obit];
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000438 else
Denis Vlasenko04087c62008-06-15 08:12:00 +0000439 ir |= bits28[obit - 28];
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000440 }
441 }
Denis Vlasenko04087c62008-06-15 08:12:00 +0000442 key_perm_maskl[k][i] = il;
443 key_perm_maskr[k][i] = ir;
444 il = 0;
445 ir = 0;
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000446 for (j = 0; j < 7; j++) {
447 inbit = 7 * k + j;
448 if (i & bits8[j + 1]) {
449 obit = inv_comp_perm[inbit];
450 if (obit == 255)
451 continue;
452 if (obit < 24)
Denis Vlasenko04087c62008-06-15 08:12:00 +0000453 il |= bits24[obit];
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000454 else
Denis Vlasenko04087c62008-06-15 08:12:00 +0000455 ir |= bits24[obit - 24];
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000456 }
457 }
Denis Vlasenko04087c62008-06-15 08:12:00 +0000458 comp_maskl[k][i] = il;
459 comp_maskr[k][i] = ir;
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000460 }
461 }
462
463 /*
464 * Invert the P-box permutation, and convert into OR-masks for
465 * handling the output of the S-box arrays setup above.
466 */
467 for (i = 0; i < 32; i++)
468 un_pbox[pbox[i] - 1] = (uint8_t)i;
469
470 for (b = 0; b < 4; b++) {
471 for (i = 0; i < 256; i++) {
Denis Vlasenko04087c62008-06-15 08:12:00 +0000472 p = 0;
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000473 for (j = 0; j < 8; j++) {
474 if (i & bits8[j])
Denis Vlasenko04087c62008-06-15 08:12:00 +0000475 p |= bits32[un_pbox[8 * b + j]];
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000476 }
Denis Vlasenko04087c62008-06-15 08:12:00 +0000477 psbox[b][i] = p;
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000478 }
479 }
480
481 return ctx;
482}
483
484
485static void
486setup_salt(struct des_ctx *ctx, uint32_t salt)
487{
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000488 uint32_t obit, saltbit;
489 int i;
490
Denis Vlasenko5cdc2472008-06-15 09:48:18 +0000491#if USE_REPETITIVE_SPEEDUP
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000492 if (salt == old_salt)
493 return;
494 old_salt = salt;
Denis Vlasenko04087c62008-06-15 08:12:00 +0000495#endif
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000496
Denis Vlasenko04087c62008-06-15 08:12:00 +0000497 saltbits = 0;
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000498 saltbit = 1;
499 obit = 0x800000;
500 for (i = 0; i < 24; i++) {
501 if (salt & saltbit)
502 saltbits |= obit;
503 saltbit <<= 1;
504 obit >>= 1;
505 }
506}
507
508static void
509des_setkey(struct des_ctx *ctx, const char *key)
510{
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000511 uint32_t k0, k1, rawkey0, rawkey1;
512 int shifts, round;
513
514 rawkey0 = ntohl(*(const uint32_t *) key);
515 rawkey1 = ntohl(*(const uint32_t *) (key + 4));
516
Denis Vlasenko5cdc2472008-06-15 09:48:18 +0000517#if USE_REPETITIVE_SPEEDUP
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000518 if ((rawkey0 | rawkey1)
519 && rawkey0 == old_rawkey0
520 && rawkey1 == old_rawkey1
521 ) {
522 /*
523 * Already setup for this key.
524 * This optimisation fails on a zero key (which is weak and
525 * has bad parity anyway) in order to simplify the starting
526 * conditions.
527 */
528 return;
529 }
530 old_rawkey0 = rawkey0;
531 old_rawkey1 = rawkey1;
Denis Vlasenko04087c62008-06-15 08:12:00 +0000532#endif
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000533
534 /*
Denis Vlasenko5cdc2472008-06-15 09:48:18 +0000535 * Do key permutation and split into two 28-bit subkeys.
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000536 */
537 k0 = key_perm_maskl[0][rawkey0 >> 25]
538 | key_perm_maskl[1][(rawkey0 >> 17) & 0x7f]
539 | key_perm_maskl[2][(rawkey0 >> 9) & 0x7f]
540 | key_perm_maskl[3][(rawkey0 >> 1) & 0x7f]
541 | key_perm_maskl[4][rawkey1 >> 25]
542 | key_perm_maskl[5][(rawkey1 >> 17) & 0x7f]
543 | key_perm_maskl[6][(rawkey1 >> 9) & 0x7f]
544 | key_perm_maskl[7][(rawkey1 >> 1) & 0x7f];
545 k1 = key_perm_maskr[0][rawkey0 >> 25]
546 | key_perm_maskr[1][(rawkey0 >> 17) & 0x7f]
547 | key_perm_maskr[2][(rawkey0 >> 9) & 0x7f]
548 | key_perm_maskr[3][(rawkey0 >> 1) & 0x7f]
549 | key_perm_maskr[4][rawkey1 >> 25]
550 | key_perm_maskr[5][(rawkey1 >> 17) & 0x7f]
551 | key_perm_maskr[6][(rawkey1 >> 9) & 0x7f]
552 | key_perm_maskr[7][(rawkey1 >> 1) & 0x7f];
553 /*
Denis Vlasenko5cdc2472008-06-15 09:48:18 +0000554 * Rotate subkeys and do compression permutation.
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000555 */
556 shifts = 0;
557 for (round = 0; round < 16; round++) {
558 uint32_t t0, t1;
559
560 shifts += key_shifts[round];
561
562 t0 = (k0 << shifts) | (k0 >> (28 - shifts));
563 t1 = (k1 << shifts) | (k1 >> (28 - shifts));
564
Denis Vlasenko5cdc2472008-06-15 09:48:18 +0000565#if USE_de_keys
566 de_keysl[15 - round] =
567#endif
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000568 en_keysl[round] = comp_maskl[0][(t0 >> 21) & 0x7f]
569 | comp_maskl[1][(t0 >> 14) & 0x7f]
570 | comp_maskl[2][(t0 >> 7) & 0x7f]
571 | comp_maskl[3][t0 & 0x7f]
572 | comp_maskl[4][(t1 >> 21) & 0x7f]
573 | comp_maskl[5][(t1 >> 14) & 0x7f]
574 | comp_maskl[6][(t1 >> 7) & 0x7f]
575 | comp_maskl[7][t1 & 0x7f];
576
Denis Vlasenko5cdc2472008-06-15 09:48:18 +0000577#if USE_de_keys
578 de_keysr[15 - round] =
579#endif
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000580 en_keysr[round] = comp_maskr[0][(t0 >> 21) & 0x7f]
581 | comp_maskr[1][(t0 >> 14) & 0x7f]
582 | comp_maskr[2][(t0 >> 7) & 0x7f]
583 | comp_maskr[3][t0 & 0x7f]
584 | comp_maskr[4][(t1 >> 21) & 0x7f]
585 | comp_maskr[5][(t1 >> 14) & 0x7f]
586 | comp_maskr[6][(t1 >> 7) & 0x7f]
587 | comp_maskr[7][t1 & 0x7f];
588 }
589}
590
591
Denis Vlasenkoe2352852008-06-14 22:11:29 +0000592static void
Denis Vlasenko04087c62008-06-15 08:12:00 +0000593do_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 +0000594{
595 const struct const_des_ctx *cctx = const_ctx;
596 /*
597 * l_in, r_in, l_out, and r_out are in pseudo-"big-endian" format.
598 */
Denis Vlasenko04087c62008-06-15 08:12:00 +0000599 uint32_t l, r, *kl, *kr;
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000600 uint32_t f = f; /* silence gcc */
601 uint32_t r48l, r48r;
602 int round;
603
Denis Vlasenko04087c62008-06-15 08:12:00 +0000604 /* Do initial permutation (IP). */
Denis Vlasenko5cdc2472008-06-15 09:48:18 +0000605#if USE_ip_mask
606 uint32_t l_in = 0;
607 uint32_t r_in = 0;
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000608 l = ip_maskl[0][l_in >> 24]
609 | ip_maskl[1][(l_in >> 16) & 0xff]
610 | ip_maskl[2][(l_in >> 8) & 0xff]
611 | ip_maskl[3][l_in & 0xff]
612 | ip_maskl[4][r_in >> 24]
613 | ip_maskl[5][(r_in >> 16) & 0xff]
614 | ip_maskl[6][(r_in >> 8) & 0xff]
615 | ip_maskl[7][r_in & 0xff];
616 r = ip_maskr[0][l_in >> 24]
617 | ip_maskr[1][(l_in >> 16) & 0xff]
618 | ip_maskr[2][(l_in >> 8) & 0xff]
619 | ip_maskr[3][l_in & 0xff]
620 | ip_maskr[4][r_in >> 24]
621 | ip_maskr[5][(r_in >> 16) & 0xff]
622 | ip_maskr[6][(r_in >> 8) & 0xff]
623 | ip_maskr[7][r_in & 0xff];
Denis Vlasenko04087c62008-06-15 08:12:00 +0000624#elif 0 /* -65 bytes (using the fact that l_in == r_in == 0) */
625 l = r = 0;
626 for (round = 0; round < 8; round++) {
627 l |= ip_maskl[round][0];
628 r |= ip_maskr[round][0];
629 }
630 bb_error_msg("l:%x r:%x", l, r); /* reports 0, 0 always! */
631#else /* using the fact that ip_maskX[] is constant (written to by des_init) */
632 l = r = 0;
633#endif
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000634
Denis Vlasenko04087c62008-06-15 08:12:00 +0000635 do {
636 /* Do each round. */
637 kl = en_keysl;
638 kr = en_keysr;
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000639 round = 16;
Denis Vlasenko04087c62008-06-15 08:12:00 +0000640 do {
641 /* Expand R to 48 bits (simulate the E-box). */
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000642 r48l = ((r & 0x00000001) << 23)
643 | ((r & 0xf8000000) >> 9)
644 | ((r & 0x1f800000) >> 11)
645 | ((r & 0x01f80000) >> 13)
646 | ((r & 0x001f8000) >> 15);
647
648 r48r = ((r & 0x0001f800) << 7)
649 | ((r & 0x00001f80) << 5)
650 | ((r & 0x000001f8) << 3)
651 | ((r & 0x0000001f) << 1)
652 | ((r & 0x80000000) >> 31);
653 /*
654 * Do salting for crypt() and friends, and
655 * XOR with the permuted key.
656 */
657 f = (r48l ^ r48r) & saltbits;
658 r48l ^= f ^ *kl++;
659 r48r ^= f ^ *kr++;
660 /*
661 * Do sbox lookups (which shrink it back to 32 bits)
662 * and do the pbox permutation at the same time.
663 */
664 f = psbox[0][m_sbox[0][r48l >> 12]]
665 | psbox[1][m_sbox[1][r48l & 0xfff]]
666 | psbox[2][m_sbox[2][r48r >> 12]]
667 | psbox[3][m_sbox[3][r48r & 0xfff]];
Denis Vlasenko04087c62008-06-15 08:12:00 +0000668 /* Now that we've permuted things, complete f(). */
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000669 f ^= l;
670 l = r;
671 r = f;
Denis Vlasenko04087c62008-06-15 08:12:00 +0000672 } while (--round);
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000673 r = l;
674 l = f;
Denis Vlasenko04087c62008-06-15 08:12:00 +0000675 } while (--count);
Denis Vlasenko5cdc2472008-06-15 09:48:18 +0000676
677 /* Do final permutation (inverse of IP). */
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000678 *l_out = fp_maskl[0][l >> 24]
679 | fp_maskl[1][(l >> 16) & 0xff]
680 | fp_maskl[2][(l >> 8) & 0xff]
681 | fp_maskl[3][l & 0xff]
682 | fp_maskl[4][r >> 24]
683 | fp_maskl[5][(r >> 16) & 0xff]
684 | fp_maskl[6][(r >> 8) & 0xff]
685 | fp_maskl[7][r & 0xff];
686 *r_out = fp_maskr[0][l >> 24]
687 | fp_maskr[1][(l >> 16) & 0xff]
688 | fp_maskr[2][(l >> 8) & 0xff]
689 | fp_maskr[3][l & 0xff]
690 | fp_maskr[4][r >> 24]
691 | fp_maskr[5][(r >> 16) & 0xff]
692 | fp_maskr[6][(r >> 8) & 0xff]
693 | fp_maskr[7][r & 0xff];
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000694}
695
696#define DES_OUT_BUFSIZE 21
697
Denis Vlasenkod324e1b2008-12-04 15:29:35 +0000698static void
699to64_msb_first(char *s, unsigned v)
700{
Denis Vlasenkod1a84a22008-12-07 01:16:34 +0000701#if 0
Denis Vlasenkod324e1b2008-12-04 15:29:35 +0000702 *s++ = ascii64[(v >> 18) & 0x3f]; /* bits 23..18 */
703 *s++ = ascii64[(v >> 12) & 0x3f]; /* bits 17..12 */
704 *s++ = ascii64[(v >> 6) & 0x3f]; /* bits 11..6 */
Denis Vlasenkod1a84a22008-12-07 01:16:34 +0000705 *s = ascii64[v & 0x3f]; /* bits 5..0 */
706#endif
707 *s++ = i64c(v >> 18); /* bits 23..18 */
708 *s++ = i64c(v >> 12); /* bits 17..12 */
709 *s++ = i64c(v >> 6); /* bits 11..6 */
710 *s = i64c(v); /* bits 5..0 */
Denis Vlasenkod324e1b2008-12-04 15:29:35 +0000711}
712
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000713static char *
Denis Vlasenkoe2352852008-06-14 22:11:29 +0000714NOINLINE
Denis Vlasenko5cdc2472008-06-15 09:48:18 +0000715des_crypt(struct des_ctx *ctx, char output[DES_OUT_BUFSIZE],
Denys Vlasenko73d93d92020-12-15 23:19:22 +0100716 const unsigned char *key, const unsigned char *salt_str)
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000717{
Denis Vlasenkod324e1b2008-12-04 15:29:35 +0000718 uint32_t salt, r0, r1, keybuf[2];
719 uint8_t *q;
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000720
Denys Vlasenko73d93d92020-12-15 23:19:22 +0100721 /* Bad salt? Mimic crypt() API - return NULL */
722 if (!salt_str[0] || !salt_str[1])
723 return NULL;
724
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000725 /*
726 * Copy the key, shifting each character up by one bit
727 * and padding with zeros.
728 */
729 q = (uint8_t *)keybuf;
Denis Vlasenkoe2352852008-06-14 22:11:29 +0000730 while (q - (uint8_t *)keybuf != 8) {
731 *q = *key << 1;
732 if (*q)
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000733 key++;
Denis Vlasenkoe2352852008-06-14 22:11:29 +0000734 q++;
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000735 }
736 des_setkey(ctx, (char *)keybuf);
737
738 /*
Denys Vlasenko73d93d92020-12-15 23:19:22 +0100739 * salt_str - 2 bytes of salt
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000740 * key - up to 8 characters
741 */
Denys Vlasenko73d93d92020-12-15 23:19:22 +0100742 output[0] = salt_str[0];
743 output[1] = salt_str[1];
744 salt = (ascii_to_bin(salt_str[1]) << 6)
745 | ascii_to_bin(salt_str[0]);
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000746 setup_salt(ctx, salt);
Denys Vlasenko73d93d92020-12-15 23:19:22 +0100747
Denis Vlasenkod324e1b2008-12-04 15:29:35 +0000748 /* Do it. */
Denis Vlasenko04087c62008-06-15 08:12:00 +0000749 do_des(ctx, /*0, 0,*/ &r0, &r1, 25 /* count */);
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000750
Denis Vlasenkod324e1b2008-12-04 15:29:35 +0000751 /* Now encode the result. */
752#if 0
753{
754 uint32_t l = (r0 >> 8);
755 q = (uint8_t *)output + 2;
756 *q++ = ascii64[(l >> 18) & 0x3f]; /* bits 31..26 of r0 */
757 *q++ = ascii64[(l >> 12) & 0x3f]; /* bits 25..20 of r0 */
758 *q++ = ascii64[(l >> 6) & 0x3f]; /* bits 19..14 of r0 */
759 *q++ = ascii64[l & 0x3f]; /* bits 13..8 of r0 */
Denis Vlasenkoe2352852008-06-14 22:11:29 +0000760 l = ((r0 << 16) | (r1 >> 16));
Denis Vlasenkod324e1b2008-12-04 15:29:35 +0000761 *q++ = ascii64[(l >> 18) & 0x3f]; /* bits 7..2 of r0 */
762 *q++ = ascii64[(l >> 12) & 0x3f]; /* bits 1..2 of r0 and 31..28 of r1 */
763 *q++ = ascii64[(l >> 6) & 0x3f]; /* bits 27..22 of r1 */
764 *q++ = ascii64[l & 0x3f]; /* bits 21..16 of r1 */
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000765 l = r1 << 2;
Denis Vlasenkod324e1b2008-12-04 15:29:35 +0000766 *q++ = ascii64[(l >> 12) & 0x3f]; /* bits 15..10 of r1 */
767 *q++ = ascii64[(l >> 6) & 0x3f]; /* bits 9..4 of r1 */
768 *q++ = ascii64[l & 0x3f]; /* bits 3..0 of r1 + 00 */
769 *q = 0;
770}
771#else
772 /* Each call takes low-order 24 bits and stores 4 chars */
773 /* bits 31..8 of r0 */
774 to64_msb_first(output + 2, (r0 >> 8));
775 /* bits 7..0 of r0 and 31..16 of r1 */
776 to64_msb_first(output + 6, (r0 << 16) | (r1 >> 16));
Denys Vlasenko44d19892009-05-01 03:41:25 +0200777 /* bits 15..0 of r1 and two zero bits (plus extra zero byte) */
Denis Vlasenkod324e1b2008-12-04 15:29:35 +0000778 to64_msb_first(output + 10, (r1 << 8));
Denys Vlasenko44d19892009-05-01 03:41:25 +0200779 /* extra zero byte is encoded as '.', fixing it */
780 output[13] = '\0';
Denis Vlasenkod324e1b2008-12-04 15:29:35 +0000781#endif
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000782
783 return output;
784}
785
Denis Vlasenko5cdc2472008-06-15 09:48:18 +0000786#undef USE_PRECOMPUTED_u_sbox
787#undef USE_REPETITIVE_SPEEDUP
788#undef USE_ip_mask
789#undef USE_de_keys
790
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000791#undef C
792#undef init_perm
793#undef final_perm
794#undef m_sbox
795#undef D
796#undef const_ctx
797#undef saltbits
798#undef old_salt
799#undef old_rawkey0
800#undef old_rawkey1
801#undef un_pbox
802#undef inv_comp_perm
803#undef inv_key_perm
804#undef en_keysl
805#undef en_keysr
Denis Vlasenko5cdc2472008-06-15 09:48:18 +0000806#undef de_keysl
807#undef de_keysr
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000808#undef ip_maskl
809#undef ip_maskr
810#undef fp_maskl
811#undef fp_maskr
812#undef key_perm_maskl
813#undef key_perm_maskr
814#undef comp_maskl
815#undef comp_maskr
816#undef psbox