X-From-Line: dmr@plan9.bell-labs.com Sun Mar 25 03:40:02 2001 >From jidanni Sun Mar 25 03:40:02 2001 Return-Path: Delivered-To: jidanni@localhost.localhost.localdomain Received: from localhost (localhost.localdomain [127.0.0.1]) by localhost.localdomain (Postfix) with ESMTP id 455C59D9 for ; Sun, 25 Mar 2001 03:39:52 +0800 (CST) Received: from pop3.kimo.com.tw [210.59.144.204] by localhost with POP3 (fetchmail-5.5.2) for jidanni@localhost (single-drop); Sun, 25 Mar 2001 03:39:52 +0800 (CST) Received: from plan9.cs.bell-labs.com ([204.178.31.2]) by n47-svc.kimo.com (InterMail vM.4.01.03.10 201-229-121-110) with SMTP id <20010324080736.YUJX26465.n47-svc.kimo.com@plan9.cs.bell-labs.com> for ; Sat, 24 Mar 2001 16:07:36 +0800 Subject: Re: can't find the unix crypt(1) command these days Date: Sat, 24 Mar 2001 03:07:27 -0500 From: dmr@plan9.bell-labs.com To: jidanni@kimo.com.tw MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit X-Gnus-Mail-Source: file:/var/spool/mail/jidanni Message-Id: <20010324080736.YUJX26465.n47-svc.kimo.com@plan9.cs.bell-labs.com> Lines: 519 Xref: localhost.localdomain mail.misc:499 Tacked on is source from our last vax, which seems to produce the same results as on IRIX. You might have to change the location of the makekey executable. No, I'm not a million years old. Dennis --- # To unbundle, run this file echo crypt.c sed 's/.//' >crypt.c <<'//GO.SYSIN DD crypt.c' -/* - * A one-rotor machine designed along the lines of Enigma - * but considerably trivialized. - */ - -#define ECHO 010 -#include -#define ROTORSZ 256 -#define MASK 0377 -char t1[ROTORSZ]; -char t2[ROTORSZ]; -char t3[ROTORSZ]; -char *getpass(); - -setup(pw) -char *pw; -{ - int ic, i, k, temp, pf[2]; - unsigned random; - char buf[13]; - long seed; - - strncpy(buf, pw, 8); - while (*pw) - *pw++ = '\0'; - buf[8] = buf[0]; - buf[9] = buf[1]; - pipe(pf); - if (fork()==0) { - close(0); - close(1); - dup(pf[0]); - dup(pf[1]); - execl("/usr/lib/makekey", "-", 0); - execl("/lib/makekey", "-", 0); - exit(1); - } - write(pf[1], buf, 10); - wait((int *)NULL); - if (read(pf[0], buf, 13) != 13) { - fprintf(stderr, "crypt: cannot generate key\n"); - exit(1); - } - seed = 123; - for (i=0; i<13; i++) - seed = seed*buf[i] + i; - for(i=0;i>= 8; - temp = t1[k]; - t1[k] = t1[ic]; - t1[ic] = temp; - if(t3[k]!=0) continue; - ic = (random&MASK) % k; - while(t3[ic]!=0) ic = (ic+1) % k; - t3[k] = ic; - t3[ic] = k; - } - for(i=0;i=0) { - i = t2[(t3[(t1[(i+n1)&MASK]+n2)&MASK]-n2)&MASK]-n1; - putchar(i); - n1++; - if(n1==ROTORSZ) { - n1 = 0; - n2++; - if(n2==ROTORSZ) n2 = 0; - } - } - return 0; -} //GO.SYSIN DD crypt.c echo libcrypt.c sed 's/.//' >libcrypt.c <<'//GO.SYSIN DD libcrypt.c' -/* @(#)crypt.c 4.1 (Berkeley) 12/21/80 */ -/* - * This program implements the - * Proposed Federal Information Processing - * Data Encryption Standard. - * See Federal Register, March 17, 1975 (40FR12134) - */ - -/* - * Initial permutation, - */ -static char IP[] = { - 58,50,42,34,26,18,10, 2, - 60,52,44,36,28,20,12, 4, - 62,54,46,38,30,22,14, 6, - 64,56,48,40,32,24,16, 8, - 57,49,41,33,25,17, 9, 1, - 59,51,43,35,27,19,11, 3, - 61,53,45,37,29,21,13, 5, - 63,55,47,39,31,23,15, 7, -}; - -/* - * Final permutation, FP = IP^(-1) - */ -static char FP[] = { - 40, 8,48,16,56,24,64,32, - 39, 7,47,15,55,23,63,31, - 38, 6,46,14,54,22,62,30, - 37, 5,45,13,53,21,61,29, - 36, 4,44,12,52,20,60,28, - 35, 3,43,11,51,19,59,27, - 34, 2,42,10,50,18,58,26, - 33, 1,41, 9,49,17,57,25, -}; - -/* - * Permuted-choice 1 from the key bits - * to yield C and D. - * Note that bits 8,16... are left out: - * They are intended for a parity check. - */ -static char PC1_C[] = { - 57,49,41,33,25,17, 9, - 1,58,50,42,34,26,18, - 10, 2,59,51,43,35,27, - 19,11, 3,60,52,44,36, -}; - -static char PC1_D[] = { - 63,55,47,39,31,23,15, - 7,62,54,46,38,30,22, - 14, 6,61,53,45,37,29, - 21,13, 5,28,20,12, 4, -}; - -/* - * Sequence of shifts used for the key schedule. -*/ -static char shifts[] = { - 1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1, -}; - -/* - * Permuted-choice 2, to pick out the bits from - * the CD array that generate the key schedule. - */ -static char PC2_C[] = { - 14,17,11,24, 1, 5, - 3,28,15, 6,21,10, - 23,19,12, 4,26, 8, - 16, 7,27,20,13, 2, -}; - -static char PC2_D[] = { - 41,52,31,37,47,55, - 30,40,51,45,33,48, - 44,49,39,56,34,53, - 46,42,50,36,29,32, -}; - -/* - * The C and D arrays used to calculate the key schedule. - */ - -static char C[28]; -static char D[28]; - -/* - * The E bit-selection table. - */ - -static char E[48]; -static char e[] = { - 32, 1, 2, 3, 4, 5, - 4, 5, 6, 7, 8, 9, - 8, 9,10,11,12,13, - 12,13,14,15,16,17, - 16,17,18,19,20,21, - 20,21,22,23,24,25, - 24,25,26,27,28,29, - 28,29,30,31,32, 1, -}; - -/* - * The key schedule. - * Generated from the key. - */ -static char KS[16][48]; - -/* - * Set up the key schedule from the key. - */ - - -setkey(key) -char *key; -{ - register i, j, k; - int t; - - /* - * First, generate C and D by permuting - * the key. The low order bit of each - * 8-bit char is not used, so C and D are only 28 - * bits apiece. - */ - for (i=0; i<28; i++) { - C[i] = key[PC1_C[i]-1]; - D[i] = key[PC1_D[i]-1]; - } - /* - * To generate Ki, rotate C and D according - * to schedule and pick up a permutation - * using PC2. - */ - for (i=0; i<16; i++) { - /* - * rotate. - */ - for (k=0; k>3)&01; - f[t+1] = (k>>2)&01; - f[t+2] = (k>>1)&01; - f[t+3] = (k>>0)&01; - } - /* - * The new R is L ^ f(R, K). - * The f here has to be permuted first, though. - */ - for (j=0; j<32; j++) - R[j] = L[j] ^ f[P[j]-1]; - /* - * Finally, the new L (the original R) - * is copied back. - */ - for (j=0; j<32; j++) - L[j] = tempL[j]; - } - /* - * The output L and R are reversed. - */ - for (j=0; j<32; j++) { - t = L[j]; - L[j] = R[j]; - R[j] = t; - } - /* - * The final output - * gets the inverse permutation of the very original. - */ - for (j=0; j<64; j++) - block[j] = L[FP[j]-1]; -} - -char * -crypt(pw,salt) -char *pw; -char *salt; -{ - register i, j, c; - int temp; - static char block[66], iobuf[16]; - for(i=0; i<66; i++) - block[i] = 0; - for(i=0; (c= *pw) && i<64; pw++){ - for(j=0; j<7; j++, i++) - block[i] = (c>>(6-j)) & 01; - i++; - } - - setkey(block); - - for(i=0; i<66; i++) - block[i] = 0; - - for(i=0;i<48;i++) - E[i] = e[i]; - - for(i=0;i<2;i++){ - c = *salt++; - iobuf[i] = c; - if(c>'Z') c -= 6; - if(c>'9') c -= 7; - c -= '.'; - for(j=0;j<6;j++){ - if((c>>j) & 01){ - temp = E[6*i+j]; - E[6*i+j] = E[6*i+j+24]; - E[6*i+j+24] = temp; - } - } - } - - for(i=0; i<25; i++) - encrypt(block,0); - - for(i=0; i<11; i++){ - c = 0; - for(j=0; j<6; j++){ - c <<= 1; - c |= block[6*i+j]; - } - c += '.'; - if(c>'9') c += 7; - if(c>'Z') c += 6; - iobuf[i+2] = c; - } - iobuf[i+2] = 0; - if(iobuf[1]==0) - iobuf[1] = iobuf[0]; - return(iobuf); -} //GO.SYSIN DD libcrypt.c echo makekey.c sed 's/.//' >makekey.c <<'//GO.SYSIN DD makekey.c' -/* - * You send it 10 bytes. - * It sends you 13 bytes. - * The transformation is expensive to perform - * (a significant part of a second). - */ - -char *crypt(); - -main() -{ - char key[8]; - char salt[2]; - - read(0, key, 8); - read(0, salt, 2); - write(1, crypt(key, salt), 13); - return(0); -} //GO.SYSIN DD makekey.c