33 #if defined(LIBC_SCCS) && !defined(lint) 34 static char sccsid[] =
"@(#)crypt.c 8.1 (Berkeley) 6/4/93";
48 #ifndef _PASSWORD_EFMT1 49 #define _PASSWORD_EFMT1 '_' 53 #define numberof(array) (int)(sizeof(array) / sizeof((array)[0])) 85 #error C_block structure assumes 8 bit characters 90 # if defined DUMP || defined NO_DES_TABLES 98 # ifdef HAVE_DES_TABLES 99 # define init_des() ((void)0) 110 #define TO_SIX_BIT(rslt, src) { \ 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; \ 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 129 #if defined(LARGEDATA) 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]]); 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); } 164 }
while (--chars_in > 0);
170 STATIC void prtab(
const char *s,
const unsigned char *t,
int num_rows);
176 static const unsigned char IP[] = {
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,
189 static const unsigned char ExpandTr[] = {
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,
200 static const unsigned char PC1[] = {
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,
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,
213 static const unsigned char Rotates[] = {
214 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1,
219 static const unsigned char PC2[] = {
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,
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,
231 static const unsigned char S[8][64] = {
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,
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,
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,
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,
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,
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,
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,
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,
290 static const unsigned char P32Tr[] = {
301 static const unsigned char CIFP[] = {
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,
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,
314 static const unsigned char itoa64[] =
315 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
318 static const unsigned char a64toi[256] = {
322 ('0' <= (c) && (c) <= '9') ? (c) - '0' + 2 : \ 323 ('A' <= (c) && (c) <= 'Z') ? (c) - 'A' + 12 : \ 324 ('a' <= (c) && (c) <= 'z') ? (c) - 'a' + 38 : \ 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) 347 unsigned long SPE[2][8][64];
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) 367 static const C_block constdatablock = {{0}};
369 #define KS (data->KS) 370 #define cryptresult (data->cryptresult) 372 static void des_setkey_r(
const unsigned char *
key,
struct crypt_data *data);
373 static void des_cipher_r(
const unsigned char *in,
unsigned char *out,
long salt,
int num_iter,
struct crypt_data *data);
375 #ifdef USE_NONREENTRANT_CRYPT 379 #ifdef USE_NONREENTRANT_CRYPT 385 crypt(
const char *
key,
const char *setting)
387 return crypt_r(key, setting, &default_crypt_data);
402 int num_iter, salt_size;
405 for (i = 0; i < 8; i++) {
406 if ((t = 2*(
unsigned char)(*key)) != 0)
410 des_setkey_r(keyblock.
b, data);
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)
425 des_setkey_r(keyblock.
b, data);
428 *encp++ = *setting++;
432 for (i = 4; --i >= 0; ) {
433 if ((t = (
unsigned char)setting[i]) ==
'\0')
436 num_iter = (num_iter<<6) | a64toi[t];
448 for (i = salt_size; --i >= 0; ) {
449 if ((t = (
unsigned char)setting[i]) ==
'\0')
452 salt = (salt<<6) | a64toi[t];
455 des_cipher_r(constdatablock.
b, rsltblock.
b, salt, num_iter, data);
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;
484 des_setkey_r(
const unsigned char *
key,
struct crypt_data *data)
495 STORE(K&~0x03030303L, K0&~0x03030303L, K1, *ksp);
499 ptabp =
PC2ROT[Rotates[i]-1][0];
501 STORE(K&~0x03030303L, K0&~0x03030303L, K1, *ksp);
514 des_cipher_r(
const unsigned char *in,
unsigned char *out,
long salt,
int num_iter,
struct crypt_data *data)
520 register unsigned long L0, L1,
R0,
R1, k;
522 register int ks_inc, loop_count;
528 #if defined(vax) || defined(pdp11) 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];
547 R1 = (R1 >> 1) & 0x55555555L;
560 num_iter = -num_iter;
565 while (--num_iter >= 0) {
569 #define SPTAB(t, i) (*(const unsigned long *)((const unsigned char *)(t) + (i)*(sizeof(long)/4))) 572 #define DOXOR(x,y,i) (x)^=SPTAB(SPE[0][(i)],B.b[(i)]); (y)^=SPTAB(SPE[1][(i)],B.b[(i)]); 576 #define DOXOR(x,y,i) j=B.b[(i)]; (x)^=SPTAB(SPE[0][(i)],j); (y)^=SPTAB(SPE[1][(i)],j); 579 #define DOXOR(x,y,i) k=B.b[(i)]; (x)^=SPTAB(SPE[0][(i)],k); (y)^=SPTAB(SPE[1][(i)],k); 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; \ 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); 600 }
while (--loop_count != 0);
611 L0 = ((L0 >> 3) & 0x0f0f0f0fL) | ((L1 << 1) & 0xf0f0f0f0L);
612 L1 = ((R0 >> 3) & 0x0f0f0f0fL) | ((R1 << 1) & 0xf0f0f0f0L);
615 #if defined(MUST_ALIGN) 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];
638 register int tableno;
639 unsigned char perm[64], tmp32[32];
641 if (des_tables->
ready)
return;
646 for (i = 0; i < 64; i++)
648 for (i = 0; i < 64; i++) {
649 if ((k = PC2[i]) == 0)
652 if ((k%28) < Rotates[0]) k -= 28;
659 perm[i] = (
unsigned char)k;
662 prtab(
"pc1tab", perm, 8);
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)
678 for (i = 0; i < 64; i++) {
679 if ((k = PC2[i]) == 0)
682 if ((k%28) <= j) k -= 28;
686 prtab(
"pc2tab", perm, 8);
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];
706 perm[i*8+j] = (
unsigned char)k;
710 prtab(
"ietab", perm, 8);
717 for (i = 0; i < 64; i++) {
727 prtab(
"cftab", perm, 8);
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);
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++)
751 for (i = 0; i < 4; i++)
752 tmp32[4 * tableno + i] = (
unsigned char)(k >> i) & 01;
754 for (i = 24; --i >= 0; )
755 k = (k<<1) | tmp32[perm[i]-1];
758 for (i = 24; --i >= 0; )
759 k = (k<<1) | tmp32[perm[i+24]-1];
764 des_tables->
ready = 1;
777 unsigned char p[64],
int chars_in,
int chars_out)
779 register int i, j, k, l;
781 for (k = 0; k < chars_out*8; k++) {
789 perm[i][j].b[k>>3] |= 1<<(k&07);
798 #ifdef USE_NONREENTRANT_CRYPT 809 register int i, j, k;
812 for (i = 0; i < 8; i++) {
814 for (j = 0; j < 8; j++) {
816 k |= (
unsigned char)*key++;
820 des_setkey_r(keyblock.
b, data);
826 #ifdef USE_NONREENTRANT_CRYPT 830 encrypt_r(block, flag, &default_crypt_data);
837 register int i, j, k;
840 for (i = 0; i < 8; i++) {
842 for (j = 0; j < 8; j++) {
844 k |= (
unsigned char)*block++;
848 des_cipher_r(cblock.
b, cblock.
b, 0L, (flag ? -1: 1), data);
849 for (i = 7; i >= 0; i--) {
851 for (j = 7; j >= 0; j--) {
860 prtab(
const char *s,
const unsigned char *t,
int num_rows)
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]);
877 dump_block(
const C_block *block)
881 for (i = 0; i <
numberof(block->
b); ++i) {
882 printf(
"%3d,", block->
b[i]);
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");
900 dump_block(&
PC1ROT[i][j]);
906 printf(
"/* Subsequent key schedule rotation permutations */\n");
907 printf(
"static const C_block PC2ROT[2][64/CHUNKBITS][1<<CHUNKBITS] = {\n");
914 dump_block(&
PC2ROT[i][j][k]);
922 printf(
"/* Initial permutation/expansion table */\n");
923 printf(
"static const C_block IE3264[32/CHUNKBITS][1<<CHUNKBITS] = {\n");
928 dump_block(&
IE3264[i][j]);
934 printf(
"/* Table that combines the S, P, and E operations. */\n");
935 printf(
"static const unsigned long SPE[2][8][64] = {\n");
942 if (r == 0) printf(
"\n\t\t\t");
943 printf(
"%#10lx,",
SPE[i][j][k]);
946 printf(
"\n\t\t},\n");
952 printf(
"/* compressed/interleaved => final permutation table */\n");
953 printf(
"static const C_block CF6464[64/CHUNKBITS][1<<CHUNKBITS] = {\n");
958 dump_block(&
CF6464[i][j]);
963 printf(
"#define HAVE_DES_TABLES 1\n""#endif\n");
#define TO_SIX_BIT(rslt, src)
#define CRUNCH(p0, p1, q0, q1)
#define LOAD(d, d0, d1, bl)
void encrypt(char *block, int flag)
#define PERM3264(d, d0, d1, cpp, p)
RUBY_EXTERN char * crypt(const char *, const char *)
void setkey(const char *key)
char * crypt_r(const char *key, const char *setting, struct crypt_data *data)
STATIC void init_perm(C_block perm[64/CHUNKBITS][1<< CHUNKBITS], unsigned char p[64], int chars_in, int chars_out)
void setkey_r(const char *key, struct crypt_data *data)
#define PERM6464(d, d0, d1, cpp, p)
#define LOADREG(d, d0, d1, s, s0, s1)
#define STORE(s, s0, s1, bl)
#define R1(v, w, x, y, z, i)
#define DCL_BLOCK(d, d0, d1)
void encrypt_r(char *block, int flag, struct crypt_data *data)
STATIC void init_des(void)
STATIC void permute(const unsigned char *cp, C_block *out, register const C_block *p, int chars_in)
int main(int argc, char **argv)
#define OR(d, d0, d1, bl)
#define R0(v, w, x, y, z, i)