Ruby: missing/crypt.c Source File

Ruby 4.0.5p0 (2026-05-20 revision 64336ffd0ee9e1f4c05891695a3d7b49cb709721)

crypt.c
1/*
2 * Copyright (c) 1989, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Tom Truscott.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the University nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33#if defined(LIBC_SCCS) && !defined(lint)
34static char sccsid[] = "@(#)crypt.c 8.1 (Berkeley) 6/4/93";
35#endif /* LIBC_SCCS and not lint */
36
37#include "ruby/missing.h"
38#include "crypt.h"
39#ifdef HAVE_UNISTD_H
40#include <unistd.h>
41#endif
42#include <limits.h>
43#ifdef HAVE_PWD_H
44#include <pwd.h>
45#endif
46#include <stdio.h>
47#include <string.h>
48#ifndef _PASSWORD_EFMT1
49#define _PASSWORD_EFMT1 '_'
50#endif
51
52#ifndef numberof
53#define numberof(array) (int)(sizeof(array) / sizeof((array)[0]))
54#endif
55
56/*
57 * UNIX password, and DES, encryption.
58 * By Tom Truscott, trt@rti.rti.org,
59 * from algorithms by Robert W. Baldwin and James Gillogly.
60 *
61 * References:
62 * "Mathematical Cryptology for Computer Scientists and Mathematicians,"
63 * by Wayne Patterson, 1987, ISBN 0-8476-7438-X.
64 *
65 * "Password Security: A Case History," R. Morris and Ken Thompson,
66 * Communications of the ACM, vol. 22, pp. 594-597, Nov. 1979.
67 *
68 * "DES will be Totally Insecure within Ten Years," M.E. Hellman,
69 * IEEE Spectrum, vol. 16, pp. 32-39, July 1979.
70 */
71
72/* ===== Configuration ==================== */
73
74/*
75 * define "MUST_ALIGN" if your compiler cannot load/store
76 * long integers at arbitrary (e.g. odd) memory locations.
77 * (Either that or never pass unaligned addresses to des_cipher!)
78 */
79#if !defined(vax)
80#define MUST_ALIGN
81#endif
82
83#ifdef CHAR_BITS
84#if CHAR_BITS != 8
85 #error C_block structure assumes 8 bit characters
86#endif
87#endif
88
89#ifndef INIT_DES
90# if defined DUMP || defined NO_DES_TABLES
91# define INIT_DES 1
92# else
93# define INIT_DES 0
94# endif
95#endif
96#if !INIT_DES
97# include "des_tables.c"
98# ifdef HAVE_DES_TABLES
99# define init_des() ((void)0)
100# else
101# undef INIT_DES
102# define INIT_DES 1
103# endif
104#endif
105
106/*
107 * Convert twenty-four-bit long in host-order
108 * to six bits (and 2 low-order zeroes) per char little-endian format.
109 */
110#define TO_SIX_BIT(rslt, src) { \
111 C_block cvt; \
112 cvt.b[0] = (unsigned char)(src); (src) >>= 6; \
113 cvt.b[1] = (unsigned char)(src); (src) >>= 6; \
114 cvt.b[2] = (unsigned char)(src); (src) >>= 6; \
115 cvt.b[3] = (unsigned char)(src); \
116 (rslt) = (cvt.b32.i0 & 0x3f3f3f3fL) << 2; \
117 }
118
119/*
120 * These macros may someday permit efficient use of 64-bit integers.
121 */
122#define ZERO(d,d0,d1) ((d0) = 0, (d1) = 0)
123#define LOAD(d,d0,d1,bl) ((d0) = (bl).b32.i0, (d1) = (bl).b32.i1)
124#define LOADREG(d,d0,d1,s,s0,s1) ((d0) = (s0), (d1) = (s1))
125#define OR(d,d0,d1,bl) ((d0) |= (bl).b32.i0, (d1) |= (bl).b32.i1)
126#define STORE(s,s0,s1,bl) ((bl).b32.i0 = (s0), (bl).b32.i1 = (s1))
127#define DCL_BLOCK(d,d0,d1) long d0, d1
128
129#if defined(LARGEDATA)
130 /* Waste memory like crazy. Also, do permutations in line */
131#define PERM6464(d,d0,d1,cpp,p) \
132 LOAD((d),(d0),(d1),(p)[(0<<CHUNKBITS)+(cpp)[0]]); \
133 OR ((d),(d0),(d1),(p)[(1<<CHUNKBITS)+(cpp)[1]]); \
134 OR ((d),(d0),(d1),(p)[(2<<CHUNKBITS)+(cpp)[2]]); \
135 OR ((d),(d0),(d1),(p)[(3<<CHUNKBITS)+(cpp)[3]]); \
136 OR (d),(d0),(d1),(p)[(4<<CHUNKBITS)+(cpp)[4]]); \
137 OR (d),(d0),(d1),(p)[(5<<CHUNKBITS)+(cpp)[5]]); \
138 OR (d),(d0),(d1),(p)[(6<<CHUNKBITS)+(cpp)[6]]); \
139 OR (d),(d0),(d1),(p)[(7<<CHUNKBITS)+(cpp)[7]]);
140#define PERM3264(d,d0,d1,cpp,p) \
141 LOAD((d),(d0),(d1),(p)[(0<<CHUNKBITS)+(cpp)[0]]); \
142 OR ((d),(d0),(d1),(p)[(1<<CHUNKBITS)+(cpp)[1]]); \
143 OR ((d),(d0),(d1),(p)[(2<<CHUNKBITS)+(cpp)[2]]); \
144 OR ((d),(d0),(d1),(p)[(3<<CHUNKBITS)+(cpp)[3]]);
145#else
146 /* "small data" */
147#define PERM6464(d,d0,d1,cpp,p) \
148 { C_block tblk; permute((cpp),&tblk,(p),8); LOAD ((d),(d0),(d1),tblk); }
149#define PERM3264(d,d0,d1,cpp,p) \
150 { C_block tblk; permute((cpp),&tblk,(p),4); LOAD ((d),(d0),(d1),tblk); }
151
152STATIC void
153permute(const unsigned char *cp, C_block *out, register const C_block *p, int chars_in)
154{
155 register DCL_BLOCK(D,D0,D1);
156 register const C_block *tp;
157 register int t;
158
159 ZERO(D,D0,D1);
160 do {
161 t = *cp++;
162 tp = &p[t&0xf]; OR(D,D0,D1,*tp); p += (1<<CHUNKBITS);
163 tp = &p[t>>4]; OR(D,D0,D1,*tp); p += (1<<CHUNKBITS);
164 } while (--chars_in > 0);
165 STORE(D,D0,D1,*out);
166}
167#endif /* LARGEDATA */
168
169#ifdef DEBUG
170STATIC void prtab(const char *s, const unsigned char *t, int num_rows);
171#endif
172
173#if INIT_DES
174/* ===== (mostly) Standard DES Tables ==================== */
175
176static const unsigned char IP[] = { /* initial permutation */
177 58, 50, 42, 34, 26, 18, 10, 2,
178 60, 52, 44, 36, 28, 20, 12, 4,
179 62, 54, 46, 38, 30, 22, 14, 6,
180 64, 56, 48, 40, 32, 24, 16, 8,
181 57, 49, 41, 33, 25, 17, 9, 1,
182 59, 51, 43, 35, 27, 19, 11, 3,
183 61, 53, 45, 37, 29, 21, 13, 5,
184 63, 55, 47, 39, 31, 23, 15, 7,
185};
186
187/* The final permutation is the inverse of IP - no table is necessary */
188
189static const unsigned char ExpandTr[] = { /* expansion operation */
190 32, 1, 2, 3, 4, 5,
191 4, 5, 6, 7, 8, 9,
192 8, 9, 10, 11, 12, 13,
193 12, 13, 14, 15, 16, 17,
194 16, 17, 18, 19, 20, 21,
195 20, 21, 22, 23, 24, 25,
196 24, 25, 26, 27, 28, 29,
197 28, 29, 30, 31, 32, 1,
198};
199
200static const unsigned char PC1[] = { /* permuted choice table 1 */
201 57, 49, 41, 33, 25, 17, 9,
202 1, 58, 50, 42, 34, 26, 18,
203 10, 2, 59, 51, 43, 35, 27,
204 19, 11, 3, 60, 52, 44, 36,
205
206 63, 55, 47, 39, 31, 23, 15,
207 7, 62, 54, 46, 38, 30, 22,
208 14, 6, 61, 53, 45, 37, 29,
209 21, 13, 5, 28, 20, 12, 4,
210};
211#endif
212
213static const unsigned char Rotates[] = { /* PC1 rotation schedule */
214 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1,
215};
216
217#if INIT_DES
218/* note: each "row" of PC2 is left-padded with bits that make it invertible */
219static const unsigned char PC2[] = { /* permuted choice table 2 */
220 9, 18, 14, 17, 11, 24, 1, 5,
221 22, 25, 3, 28, 15, 6, 21, 10,
222 35, 38, 23, 19, 12, 4, 26, 8,
223 43, 54, 16, 7, 27, 20, 13, 2,
224
225 0, 0, 41, 52, 31, 37, 47, 55,
226 0, 0, 30, 40, 51, 45, 33, 48,
227 0, 0, 44, 49, 39, 56, 34, 53,
228 0, 0, 46, 42, 50, 36, 29, 32,
229};
230
231static const unsigned char S[8][64] = { /* 48->32 bit substitution tables */
232 {
233 /* S[1] */
234 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
235 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
236 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
237 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,
238 },
239 {
240 /* S[2] */
241 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
242 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
243 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
244 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,
245 },
246 {
247 /* S[3] */
248 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
249 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
250 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
251 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,
252 },
253 {
254 /* S[4] */
255 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
256 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
257 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
258 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,
259 },
260 {
261 /* S[5] */
262 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
263 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
264 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
265 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,
266 },
267 {
268 /* S[6] */
269 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
270 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
271 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
272 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,
273 },
274 {
275 /* S[7] */
276 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
277 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
278 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
279 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,
280 },
281 {
282 /* S[8] */
283 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
284 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
285 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
286 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11,
287 },
288};
289
290static const unsigned char P32Tr[] = { /* 32-bit permutation function */
291 16, 7, 20, 21,
292 29, 12, 28, 17,
293 1, 15, 23, 26,
294 5, 18, 31, 10,
295 2, 8, 24, 14,
296 32, 27, 3, 9,
297 19, 13, 30, 6,
298 22, 11, 4, 25,
299};
300
301static const unsigned char CIFP[] = { /* compressed/interleaved permutation */
302 1, 2, 3, 4, 17, 18, 19, 20,
303 5, 6, 7, 8, 21, 22, 23, 24,
304 9, 10, 11, 12, 25, 26, 27, 28,
305 13, 14, 15, 16, 29, 30, 31, 32,
306
307 33, 34, 35, 36, 49, 50, 51, 52,
308 37, 38, 39, 40, 53, 54, 55, 56,
309 41, 42, 43, 44, 57, 58, 59, 60,
310 45, 46, 47, 48, 61, 62, 63, 64,
311};
312#endif
313
314static const unsigned char itoa64[] = /* 0..63 => ascii-64 */
315 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
316
317/* table that converts chars "./0-9A-Za-z"to integers 0-63. */
318static const unsigned char a64toi[256] = {
319#define A64TOI1(c) \
320 ((c) == '.' ? 0 : \
321 (c) == '/' ? 1 : \
322 ('0' <= (c) && (c) <= '9') ? (c) - '0' + 2 : \
323 ('A' <= (c) && (c) <= 'Z') ? (c) - 'A' + 12 : \
324 ('a' <= (c) && (c) <= 'z') ? (c) - 'a' + 38 : \
325 0)
326#define A64TOI4(base) A64TOI1(base+0), A64TOI1(base+1), A64TOI1(base+2), A64TOI1(base+3)
327#define A64TOI16(base) A64TOI4(base+0), A64TOI4(base+4), A64TOI4(base+8), A64TOI4(base+12)
328#define A64TOI64(base) A64TOI16(base+0x00), A64TOI16(base+0x10), A64TOI16(base+0x20), A64TOI16(base+0x30)
329 A64TOI64(0x00), A64TOI64(0x40),
330 A64TOI64(0x00), A64TOI64(0x40),
331};
332
333#if INIT_DES
334/* ===== Tables that are initialized at run time ==================== */
335
336typedef struct {
337 /* Initial key schedule permutation */
338 C_block PC1ROT[64/CHUNKBITS][1<<CHUNKBITS];
339
340 /* Subsequent key schedule rotation permutations */
341 C_block PC2ROT[2][64/CHUNKBITS][1<<CHUNKBITS];
342
343 /* Initial permutation/expansion table */
344 C_block IE3264[32/CHUNKBITS][1<<CHUNKBITS];
345
346 /* Table that combines the S, P, and E operations. */
347 unsigned long SPE[2][8][64];
348
349 /* compressed/interleaved => final permutation table */
350 C_block CF6464[64/CHUNKBITS][1<<CHUNKBITS];
351
352 int ready;
353} des_tables_t;
354static des_tables_t des_tables[1];
355
356#define des_tables ((const des_tables_t *)des_tables)
357#define PC1ROT (des_tables->PC1ROT)
358#define PC2ROT (des_tables->PC2ROT)
359#define IE3264 (des_tables->IE3264)
360#define SPE (des_tables->SPE)
361#define CF6464 (des_tables->CF6464)
362
363STATIC void init_des(void);
364STATIC void init_perm(C_block perm[64/CHUNKBITS][1<<CHUNKBITS], unsigned char p[64], int chars_in, int chars_out);
365#endif
366
367static const C_block constdatablock = {{0}}; /* encryption constant */
368
369#define KS (data->KS)
370#define cryptresult (data->cryptresult)
371
372static void des_setkey_r(const unsigned char *key, struct crypt_data *data);
373static void des_cipher_r(const unsigned char *in, unsigned char *out, long salt, int num_iter, struct crypt_data *data);
374
375#ifdef USE_NONREENTRANT_CRYPT
376static struct crypt_data default_crypt_data;
377#endif
378
379#ifdef USE_NONREENTRANT_CRYPT
380/*
381 * Return a pointer to static data consisting of the "setting"
382 * followed by an encryption produced by the "key" and "setting".
383 */
384char *
385crypt(const char *key, const char *setting)
386{
387 return crypt_r(key, setting, &default_crypt_data);
388}
389#endif
390
391/*
392 * Return a pointer to data consisting of the "setting" followed by an
393 * encryption produced by the "key" and "setting".
394 */
395char *
396crypt_r(const char *key, const char *setting, struct crypt_data *data)
397{
398 register char *encp;
399 register long i;
400 register int t;
401 long salt;
402 int num_iter, salt_size;
403 C_block keyblock, rsltblock;
404
405 for (i = 0; i < 8; i++) {
406 if ((t = 2*(unsigned char)(*key)) != 0)
407 key++;
408 keyblock.b[i] = t;
409 }
410 des_setkey_r(keyblock.b, data); /* also initializes "a64toi" */
411
412 encp = &cryptresult[0];
413 switch (*setting) {
414 case _PASSWORD_EFMT1:
415 /*
416 * Involve the rest of the password 8 characters at a time.
417 */
418 while (*key) {
419 des_cipher_r(keyblock.b, keyblock.b, 0L, 1, data);
420 for (i = 0; i < 8; i++) {
421 if ((t = 2*(unsigned char)(*key)) != 0)
422 key++;
423 keyblock.b[i] ^= t;
424 }
425 des_setkey_r(keyblock.b, data);
426 }
427
428 *encp++ = *setting++;
429
430 /* get iteration count */
431 num_iter = 0;
432 for (i = 4; --i >= 0; ) {
433 if ((t = (unsigned char)setting[i]) == '\0')
434 t = '.';
435 encp[i] = t;
436 num_iter = (num_iter<<6) | a64toi[t];
437 }
438 setting += 4;
439 encp += 4;
440 salt_size = 4;
441 break;
442 default:
443 num_iter = 25;
444 salt_size = 2;
445 }
446
447 salt = 0;
448 for (i = salt_size; --i >= 0; ) {
449 if ((t = (unsigned char)setting[i]) == '\0')
450 t = '.';
451 encp[i] = t;
452 salt = (salt<<6) | a64toi[t];
453 }
454 encp += salt_size;
455 des_cipher_r(constdatablock.b, rsltblock.b, salt, num_iter, data);
456
457 /*
458 * Encode the 64 cipher bits as 11 ascii characters.
459 */
460 i = ((long)((rsltblock.b[0]<<8) | rsltblock.b[1])<<8) | rsltblock.b[2];
461 encp[3] = itoa64[i&0x3f]; i >>= 6;
462 encp[2] = itoa64[i&0x3f]; i >>= 6;
463 encp[1] = itoa64[i&0x3f]; i >>= 6;
464 encp[0] = itoa64[i]; encp += 4;
465 i = ((long)((rsltblock.b[3]<<8) | rsltblock.b[4])<<8) | rsltblock.b[5];
466 encp[3] = itoa64[i&0x3f]; i >>= 6;
467 encp[2] = itoa64[i&0x3f]; i >>= 6;
468 encp[1] = itoa64[i&0x3f]; i >>= 6;
469 encp[0] = itoa64[i]; encp += 4;
470 i = ((long)((rsltblock.b[6])<<8) | rsltblock.b[7])<<2;
471 encp[2] = itoa64[i&0x3f]; i >>= 6;
472 encp[1] = itoa64[i&0x3f]; i >>= 6;
473 encp[0] = itoa64[i];
474
475 encp[3] = 0;
476
477 return (cryptresult);
478}
479
480/*
481 * Set up the key schedule from the key.
482 */
483static void
484des_setkey_r(const unsigned char *key, struct crypt_data *data)
485{
486 register DCL_BLOCK(K, K0, K1);
487 register const C_block *ptabp;
488 register int i;
489 C_block *ksp;
490
491 init_des();
492
493 PERM6464(K,K0,K1,key,PC1ROT[0]);
494 ksp = &KS[0];
495 STORE(K&~0x03030303L, K0&~0x03030303L, K1, *ksp);
496 for (i = 1; i < numberof(KS); i++) {
497 ksp++;
498 STORE(K,K0,K1,*ksp);
499 ptabp = PC2ROT[Rotates[i]-1][0];
500 PERM6464(K,K0,K1,ksp->b,ptabp);
501 STORE(K&~0x03030303L, K0&~0x03030303L, K1, *ksp);
502 }
503}
504
505/*
506 * Encrypt (or decrypt if num_iter < 0) the 8 chars at "in" with abs(num_iter)
507 * iterations of DES, using the given 24-bit salt and the pre-computed key
508 * schedule, and store the resulting 8 chars at "out" (in == out is permitted).
509 *
510 * NOTE: the performance of this routine is critically dependent on your
511 * compiler and machine architecture.
512 */
513void
514des_cipher_r(const unsigned char *in, unsigned char *out, long salt, int num_iter, struct crypt_data *data)
515{
516 /* variables that we want in registers, most important first */
517#if defined(pdp11)
518 register int j;
519#endif
520 register unsigned long L0, L1, R0, R1, k;
521 register const C_block *kp;
522 register int ks_inc, loop_count;
523 C_block B;
524
525 L0 = salt;
526 TO_SIX_BIT(salt, L0); /* convert to 4*(6+2) format */
527
528#if defined(vax) || defined(pdp11)
529 salt = ~salt; /* "x &~ y" is faster than "x & y". */
530#define SALT (~salt)
531#else
532#define SALT salt
533#endif
534
535#if defined(MUST_ALIGN)
536 B.b[0] = in[0]; B.b[1] = in[1]; B.b[2] = in[2]; B.b[3] = in[3];
537 B.b[4] = in[4]; B.b[5] = in[5]; B.b[6] = in[6]; B.b[7] = in[7];
538 LOAD(L,L0,L1,B);
539#else
540 LOAD(L,L0,L1,*(C_block *)in);
541#endif
542 LOADREG(R,R0,R1,L,L0,L1);
543 L0 &= 0x55555555L;
544 L1 &= 0x55555555L;
545 L0 = (L0 << 1) | L1; /* L0 is the even-numbered input bits */
546 R0 &= 0xaaaaaaaaL;
547 R1 = (R1 >> 1) & 0x55555555L;
548 L1 = R0 | R1; /* L1 is the odd-numbered input bits */
549 STORE(L,L0,L1,B);
550 PERM3264(L,L0,L1,B.b, IE3264[0]); /* even bits */
551 PERM3264(R,R0,R1,B.b+4,IE3264[0]); /* odd bits */
552
553 if (num_iter >= 0)
554 { /* encryption */
555 kp = &KS[0];
556 ks_inc = +1;
557 }
558 else
559 { /* decryption */
560 num_iter = -num_iter;
561 kp = &KS[KS_SIZE-1];
562 ks_inc = -1;
563 }
564
565 while (--num_iter >= 0) {
566 loop_count = 8;
567 do {
568
569#define SPTAB(t, i) (*(const unsigned long *)((const unsigned char *)(t) + (i)*(sizeof(long)/4)))
570#if defined(gould)
571 /* use this if B.b[i] is evaluated just once ... */
572#define DOXOR(x,y,i) (x)^=SPTAB(SPE[0][(i)],B.b[(i)]); (y)^=SPTAB(SPE[1][(i)],B.b[(i)]);
573#else
574#if defined(pdp11)
575 /* use this if your "long" int indexing is slow */
576#define DOXOR(x,y,i) j=B.b[(i)]; (x)^=SPTAB(SPE[0][(i)],j); (y)^=SPTAB(SPE[1][(i)],j);
577#else
578 /* use this if "k" is allocated to a register ... */
579#define DOXOR(x,y,i) k=B.b[(i)]; (x)^=SPTAB(SPE[0][(i)],k); (y)^=SPTAB(SPE[1][(i)],k);
580#endif
581#endif
582
583#define CRUNCH(p0, p1, q0, q1) \
584 k = ((q0) ^ (q1)) & SALT; \
585 B.b32.i0 = k ^ (q0) ^ kp->b32.i0; \
586 B.b32.i1 = k ^ (q1) ^ kp->b32.i1; \
587 kp += ks_inc; \
588 \
589 DOXOR((p0), (p1), 0); \
590 DOXOR((p0), (p1), 1); \
591 DOXOR((p0), (p1), 2); \
592 DOXOR((p0), (p1), 3); \
593 DOXOR((p0), (p1), 4); \
594 DOXOR((p0), (p1), 5); \
595 DOXOR((p0), (p1), 6); \
596 DOXOR((p0), (p1), 7);
597
598 CRUNCH(L0, L1, R0, R1);
599 CRUNCH(R0, R1, L0, L1);
600 } while (--loop_count != 0);
601 kp -= (ks_inc*KS_SIZE);
602
603
604 /* swap L and R */
605 L0 ^= R0; L1 ^= R1;
606 R0 ^= L0; R1 ^= L1;
607 L0 ^= R0; L1 ^= R1;
608 }
609
610 /* store the encrypted (or decrypted) result */
611 L0 = ((L0 >> 3) & 0x0f0f0f0fL) | ((L1 << 1) & 0xf0f0f0f0L);
612 L1 = ((R0 >> 3) & 0x0f0f0f0fL) | ((R1 << 1) & 0xf0f0f0f0L);
613 STORE(L,L0,L1,B);
614 PERM6464(L,L0,L1,B.b, CF6464[0]);
615#if defined(MUST_ALIGN)
616 STORE(L,L0,L1,B);
617 out[0] = B.b[0]; out[1] = B.b[1]; out[2] = B.b[2]; out[3] = B.b[3];
618 out[4] = B.b[4]; out[5] = B.b[5]; out[6] = B.b[6]; out[7] = B.b[7];
619#else
620 STORE(L,L0,L1,*(C_block *)out);
621#endif
622}
623
624#undef des_tables
625#undef KS
626#undef cryptresult
627
628#if INIT_DES
629/*
630 * Initialize various tables. This need only be done once. It could even be
631 * done at compile time, if the compiler were capable of that sort of thing.
632 */
633STATIC void
634init_des(void)
635{
636 register int i, j;
637 register long k;
638 register int tableno;
639 unsigned char perm[64], tmp32[32];
640
641 if (des_tables->ready) return;
642
643 /*
644 * PC1ROT - bit reverse, then PC1, then Rotate, then PC2.
645 */
646 for (i = 0; i < 64; i++)
647 perm[i] = 0;
648 for (i = 0; i < 64; i++) {
649 if ((k = PC2[i]) == 0)
650 continue;
651 k += Rotates[0]-1;
652 if ((k%28) < Rotates[0]) k -= 28;
653 k = PC1[k];
654 if (k > 0) {
655 k--;
656 k = (k|07) - (k&07);
657 k++;
658 }
659 perm[i] = (unsigned char)k;
660 }
661#ifdef DEBUG
662 prtab("pc1tab", perm, 8);
663#endif
664 init_perm(PC1ROT, perm, 8, 8);
665
666 /*
667 * PC2ROT - PC2 inverse, then Rotate (once or twice), then PC2.
668 */
669 for (j = 0; j < 2; j++) {
670 unsigned char pc2inv[64];
671 for (i = 0; i < 64; i++)
672 perm[i] = pc2inv[i] = 0;
673 for (i = 0; i < 64; i++) {
674 if ((k = PC2[i]) == 0)
675 continue;
676 pc2inv[k-1] = i+1;
677 }
678 for (i = 0; i < 64; i++) {
679 if ((k = PC2[i]) == 0)
680 continue;
681 k += j;
682 if ((k%28) <= j) k -= 28;
683 perm[i] = pc2inv[k];
684 }
685#ifdef DEBUG
686 prtab("pc2tab", perm, 8);
687#endif
688 init_perm(PC2ROT[j], perm, 8, 8);
689 }
690
691 /*
692 * Bit reverse, then initial permutation, then expansion.
693 */
694 for (i = 0; i < 8; i++) {
695 for (j = 0; j < 8; j++) {
696 k = (j < 2)? 0: IP[ExpandTr[i*6+j-2]-1];
697 if (k > 32)
698 k -= 32;
699 else if (k > 0)
700 k--;
701 if (k > 0) {
702 k--;
703 k = (k|07) - (k&07);
704 k++;
705 }
706 perm[i*8+j] = (unsigned char)k;
707 }
708 }
709#ifdef DEBUG
710 prtab("ietab", perm, 8);
711#endif
712 init_perm(IE3264, perm, 4, 8);
713
714 /*
715 * Compression, then final permutation, then bit reverse.
716 */
717 for (i = 0; i < 64; i++) {
718 k = IP[CIFP[i]-1];
719 if (k > 0) {
720 k--;
721 k = (k|07) - (k&07);
722 k++;
723 }
724 perm[k-1] = i+1;
725 }
726#ifdef DEBUG
727 prtab("cftab", perm, 8);
728#endif
729 init_perm(CF6464, perm, 8, 8);
730
731 /*
732 * SPE table
733 */
734 for (i = 0; i < 48; i++)
735 perm[i] = P32Tr[ExpandTr[i]-1];
736 for (tableno = 0; tableno < 8; tableno++) {
737 for (j = 0; j < 64; j++) {
738 k = (((j >> 0) &01) << 5)|
739 (((j >> 1) &01) << 3)|
740 (((j >> 2) &01) << 2)|
741 (((j >> 3) &01) << 1)|
742 (((j >> 4) &01) << 0)|
743 (((j >> 5) &01) << 4);
744 k = S[tableno][k];
745 k = (((k >> 3)&01) << 0)|
746 (((k >> 2)&01) << 1)|
747 (((k >> 1)&01) << 2)|
748 (((k >> 0)&01) << 3);
749 for (i = 0; i < 32; i++)
750 tmp32[i] = 0;
751 for (i = 0; i < 4; i++)
752 tmp32[4 * tableno + i] = (unsigned char)(k >> i) & 01;
753 k = 0;
754 for (i = 24; --i >= 0; )
755 k = (k<<1) | tmp32[perm[i]-1];
756 TO_SIX_BIT(SPE[0][tableno][j], k);
757 k = 0;
758 for (i = 24; --i >= 0; )
759 k = (k<<1) | tmp32[perm[i+24]-1];
760 TO_SIX_BIT(SPE[1][tableno][j], k);
761 }
762 }
763
764 des_tables->ready = 1;
765}
766
767/*
768 * Initialize "perm" to represent transformation "p", which rearranges
769 * (perhaps with expansion and/or contraction) one packed array of bits
770 * (of size "chars_in" characters) into another array (of size "chars_out"
771 * characters).
772 *
773 * "perm" must be all-zeroes on entry to this routine.
774 */
775STATIC void
776init_perm(C_block perm[64/CHUNKBITS][1<<CHUNKBITS],
777 unsigned char p[64], int chars_in, int chars_out)
778{
779 register int i, j, k, l;
780
781 for (k = 0; k < chars_out*8; k++) { /* each output bit position */
782 l = p[k] - 1; /* where this bit comes from */
783 if (l < 0)
784 continue; /* output bit is always 0 */
785 i = l>>LGCHUNKBITS; /* which chunk this bit comes from */
786 l = 1<<(l&(CHUNKBITS-1)); /* mask for this bit */
787 for (j = 0; j < (1<<CHUNKBITS); j++) { /* each chunk value */
788 if ((j & l) != 0)
789 perm[i][j].b[k>>3] |= 1<<(k&07);
790 }
791 }
792}
793#endif
794
795/*
796 * "setkey" routine (for backwards compatibility)
797 */
798#ifdef USE_NONREENTRANT_CRYPT
799void
800setkey(const char *key)
801{
802 setkey_r(key, &default_crypt_data);
803}
804#endif
805
806void
807setkey_r(const char *key, struct crypt_data *data)
808{
809 register int i, j, k;
810 C_block keyblock;
811
812 for (i = 0; i < 8; i++) {
813 k = 0;
814 for (j = 0; j < 8; j++) {
815 k <<= 1;
816 k |= (unsigned char)*key++;
817 }
818 keyblock.b[i] = k;
819 }
820 des_setkey_r(keyblock.b, data);
821}
822
823/*
824 * "encrypt" routine (for backwards compatibility)
825 */
826#ifdef USE_NONREENTRANT_CRYPT
827void
828encrypt(char *block, int flag)
829{
830 encrypt_r(block, flag, &default_crypt_data);
831}
832#endif
833
834void
835encrypt_r(char *block, int flag, struct crypt_data *data)
836{
837 register int i, j, k;
838 C_block cblock;
839
840 for (i = 0; i < 8; i++) {
841 k = 0;
842 for (j = 0; j < 8; j++) {
843 k <<= 1;
844 k |= (unsigned char)*block++;
845 }
846 cblock.b[i] = k;
847 }
848 des_cipher_r(cblock.b, cblock.b, 0L, (flag ? -1: 1), data);
849 for (i = 7; i >= 0; i--) {
850 k = cblock.b[i];
851 for (j = 7; j >= 0; j--) {
852 *--block = k&01;
853 k >>= 1;
854 }
855 }
856}
857
858#ifdef DEBUG
859STATIC void
860prtab(const char *s, const unsigned char *t, int num_rows)
861{
862 register int i, j;
863
864 (void)printf("%s:\n", s);
865 for (i = 0; i < num_rows; i++) {
866 for (j = 0; j < 8; j++) {
867 (void)printf("%3d", t[i*8+j]);
868 }
869 (void)printf("\n");
870 }
871 (void)printf("\n");
872}
873#endif
874
875#ifdef DUMP
876void
877dump_block(const C_block *block)
878{
879 int i;
880 printf("{{");
881 for (i = 0; i < numberof(block->b); ++i) {
882 printf("%3d,", block->b[i]);
883 }
884 printf("}},\n");
885}
886
887int
888main(void)
889{
890 int i, j, k;
891 init_des();
892
893 printf("#ifndef HAVE_DES_TABLES\n\n");
894 printf("/* Initial key schedule permutation */\n");
895 printf("static const C_block PC1ROT[64/CHUNKBITS][1<<CHUNKBITS] = {\n");
896 for (i = 0; i < numberof(PC1ROT); ++i) {
897 printf("\t{\n");
898 for (j = 0; j < numberof(PC1ROT[0]); ++j) {
899 printf("\t\t");
900 dump_block(&PC1ROT[i][j]);
901 }
902 printf("\t},\n");
903 }
904 printf("};\n\n");
905
906 printf("/* Subsequent key schedule rotation permutations */\n");
907 printf("static const C_block PC2ROT[2][64/CHUNKBITS][1<<CHUNKBITS] = {\n");
908 for (i = 0; i < numberof(PC2ROT); ++i) {
909 printf("\t{\n");
910 for (j = 0; j < numberof(PC2ROT[0]); ++j) {
911 printf("\t\t{\n");
912 for (k = 0; k < numberof(PC2ROT[0][0]); ++k) {
913 printf("\t\t\t");
914 dump_block(&PC2ROT[i][j][k]);
915 }
916 printf("\t\t},\n");
917 }
918 printf("\t},\n");
919 }
920 printf("};\n\n");
921
922 printf("/* Initial permutation/expansion table */\n");
923 printf("static const C_block IE3264[32/CHUNKBITS][1<<CHUNKBITS] = {\n");
924 for (i = 0; i < numberof(IE3264); ++i) {
925 printf("\t{\n");
926 for (j = 0; j < numberof(IE3264[0]); ++j) {
927 printf("\t\t");
928 dump_block(&IE3264[i][j]);
929 }
930 printf("\t},\n");
931 }
932 printf("};\n\n");
933
934 printf("/* Table that combines the S, P, and E operations. */\n");
935 printf("static const unsigned long SPE[2][8][64] = {\n");
936 for (i = 0; i < numberof(SPE); ++i) {
937 printf("\t{\n");
938 for (j = 0; j < numberof(SPE[0]); ++j) {
939 int r = 0;
940 printf("\t\t{");
941 for (k = 0; k < numberof(SPE[0][0]); ++k) {
942 if (r == 0) printf("\n\t\t\t");
943 printf("%#10lx,", SPE[i][j][k]);
944 if (++r == 4) r = 0;
945 }
946 printf("\n\t\t},\n");
947 }
948 printf("\t},\n");
949 }
950 printf("};\n\n");
951
952 printf("/* compressed/interleaved => final permutation table */\n");
953 printf("static const C_block CF6464[64/CHUNKBITS][1<<CHUNKBITS] = {\n");
954 for (i = 0; i < numberof(CF6464); ++i) {
955 printf("\t{\n");
956 for (j = 0; j < numberof(CF6464[0]); ++j) {
957 printf("\t\t");
958 dump_block(&CF6464[i][j]);
959 }
960 printf("\t},\n");
961 }
962 printf("};\n\n");
963 printf("#define HAVE_DES_TABLES 1\n""#endif\n");
964
965 return 0;
966}
967#endif
crypt_data
Definition crypt.h:229
C_block
Definition crypt.h:202