home *** CD-ROM | disk | FTP | other *** search
- /* Found and distributed by Sauron
- * This file contains two unix password hackers, found on a local
- * system. Apparently they were written for sysops to test their
- * systems - and that's all we're doing, right?
- */
- /* pverify - A Unix System Password Security Checker
- *
- * This procedure is intended for those who are concerned
- * about password security. As more Unix applications, notably
- * uucp and sendmail, are made more secure, the weak link in
- * system security remains the user-chosen password.
- *
- * This program reports on users whose passwords are "suspect":
- * too easily guessable.
- *
- * Usage (on Berkeley Unix)
- * cc -O pverify.c -o pverify
- * nohup nice -20 pverify > p.out &
- * chmod 600 p.out
- * /etc/renice 20 -p `ps aux | egrep "[0-9] pverify | awk '{print $2}'
- *
- * Monitor progress with: tail -f 100 p.out
- */
- #include <stdio.h>
- #include <pwd.h>
- #include <sys/types.h>
- #include <sys/times.h>
- #include <sys/param.h>
-
- #define MAXWORD 30
-
- char *crypt();
- char fname[80];
- char storage[64];
- char pass[64];
-
- struct passwd *getpwent();
- struct passwd *pptr;
- char reduced[40], two[3];
- char notreduced[40];
-
- FILE *fp;
- char *fgets();
- char word[MAXWORD];
-
- main(argc,argv)
- int argc;
- char **argv;
- {
- register i;
- int usercnt,found,crypts;
- long tim;
- struct tms clock1,clock2;
-
- usercnt = found = crypts = 0;
- fp = fopen("/usr/dict/words","r");
- pptr = getpwent();
- times(&clock1);
- while (pptr != NULL) {
- usercnt++;
- printf("Investigating user %s\n",pptr->pw_name); fflush(stdout);
- strcpy(notreduced,pptr->pw_passwd);
- for (i = 0; i < strlen(pptr->pw_passwd); i++) {
- if (i >= 2)
- reduced[i-2] = pptr->pw_passwd[i];
- if (i < 2)
- two[i] = pptr->pw_passwd[i];
- }
- while (fgets(word,MAXWORD,fp) != NULL) {
- word[strlen(word)-1] = NULL;
- if (strlen(word) >= 6) { /* check only words of right length */
- if (strcmp(crypt(word,two),notreduced) == 0) {
- printf("\t*** %s %s ***\n",pptr->pw_name,word);
- found++;
- }
- crypts++;
- }
- }
- fseek(fp,0,0);
- pptr = getpwent();
- }
- times(&clock2);
- endpwent();
- printf("Statistics: Found %d in %d users (%3.1f%%)\n",
- found,usercnt,((float)found/(float)usercnt)*100.0);
- tim = (float)(clock2.tms_utime+clock2.tms_stime -
- clock1.tms_utime-clock1.tms_stime) / (float)HZ;
- printf("Statistics: Time used: %d, Crypts: %d, Time per crypt: %4.2f\n",
- tim, crypts, tim / (float)crypts);
- }
-
- -------------------cut here------------------------------------------
-
- #include <stdio.h>
- #include <pwd.h>
- #include <ctype.h>
-
- /*
- * Warning: this program burns a lot of cpu.
- */
- /*
- * Insecure - find accounts with poor passwords
- Date: Tue, 29 Nov 83 18:19:32 pst
- From: leres%ucbarpa@Berkeley (Craig Leres)
- Modified by Seth Alford, Roger Southwick, Steve Dum, and
- Rick Lindsley for Tektronix
- */
-
- /*
- * $Log: pwchkr.c,v $
- * Revision 1.1 85/09/10 16:00:56 root
- * Initial revision
- *
- *
- * By default, this program only checks for accounts with passwords the same
- * as the login name. The following options add more extensive checking. (The
- * tradeoff is cpu time -- with all options enabled it can run into the 100's
- * of MINUTES.) Any argument that does not begin with a "-" is assumed to be
- * a file name. (A single '-' means stdin.) If no file name is given,
- * /etc/passwd is used.
- *
- * Options:
- *
- * -v: verbose -- list all guesses on stdout
- * -u: output the username on the line of the password file
- * currently being checked. If the program stops
- * abruptly you will then know how far it got.
- * -w file: use the list of words contained in "file" as likely
- * passwords. Words in the file are one to a line.
- * -b: check all guesses backwards too
- * -g: use the Full Name portion of the gecos field to
- * generate more guesses
- * -s: check the single letters a-z, A-Z, 0-9 as passwords
- * -c: with each guess, check for all-lowercase and
- * all-uppercase versions too.
- * -n: complain about null passwords (default is to keep quiet)
- * -p: print the password when guessed
- */
-
- int verbose = 0, singles = 0, backwards = 0, checkgecos = 0, checkcase = 0,
- chknulls = 0, printit = 0, users = 0, chkwords = 0;
-
- char *index(),*reverse();
- long atol();
- FILE *fopen();
- char *fgets();
-
- char PASSWD[] = "/etc/passwd";
- char EMPTY[] = "";
- static FILE *pwf = NULL, *wlf = NULL;
- char line[BUFSIZ+1];
- char *Curpw, *Wordlist = NULL;
-
- main(argc, argv)
- char **argv;
- {
- register int i;
- register char *arg;
- int onedone = 0;
-
- for (i = 1; i < argc; i++)
- if ((arg = argv[i]) && *arg == '-')
- while (*++arg) {
- switch (*arg) {
- case 'n':
- /*
- * complain about null passwords
- */
- chknulls++;
- break;
- case 'c':
- /*
- * check cases
- */
- checkcase++;
- break;
- case 'g':
- /*
- * use gecos
- */
- checkgecos++;
- break;
- case 'v':
- /*
- * turn on motormouth
- */
- verbose++;
- break;
- case 'b':
- /*
- * check all attempts forwards and backwards
- */
- backwards++;
- break;
- case 's':
- /*
- * carry out a more intensive search, checking for
- * single letter passwords
- */
- singles++;
- break;
- case 'p':
- /*
- * print out the password when found
- */
- printit++;
- break;
- case 'u':
- /*
- * print out users as testing
- */
- users++;
- break;
- case 'w':
- /*
- * consult word list of likely passwords
- */
- if ((Wordlist = argv[i+1]) == NULL) {
- fprintf(stderr,
- "%s: No file supplied with -w option\n",
- argv[0]);
- exit (1);
- }
- argv[i+1] = NULL;
- break;
- case '\0':
- /*
- * read from stdin
- */
- break;
- default:
- fprintf(stderr,
- "%s: unknown option '%c'. Options are:\n",argv[0],
- *arg);
- /* FALL THRU */
- case '-':
- fprintf(stderr,"-v:\t\tverbose -- list all guesses on stdout\n");
- fprintf(stderr,"-u:\t\toutput the username currently being checked\n");
- fprintf(stderr,"-w file:\tconsult the indicated file for words to check as passwords\n");
- fprintf(stderr,"-b:\t\tcheck all guesses forwards and backwards\n");
- fprintf(stderr,"-g:\t\tuse the Full name portion of the gecos field for more guesses\n");
- fprintf(stderr,"-s:\t\tcheck the single letters a-z, A-Z, 0-9 as passwords\n");
- fprintf(stderr,"-c:\t\tcheck the all-upper and all-lower case version of each guess\n");
- fprintf(stderr,"-n:\t\tcomplain about null passwords\n");
- fprintf(stderr,"-p:\t\tprint the password when guessed\n");
- exit(1);
- }
- argv[i] = NULL;
- }
-
- for (i = 1; i < argc; i++) {
- if (argv[i] == NULL) continue;
- onedone++;
- if (*(argv[i]) == '-') {
- /*
- * read from stdin; we'll cheat and set pwf directly
- */
- pwf = stdin;
- chkpw();
- /*
- * don't fclose stdin!
- */
- clearerr(stdin);
- }
- else {
- if (setpwent(argv[i])) {
- perror(argv[i]);
- continue;
- }
- Curpw = argv[i];
- chkpw();
- endpwent();
- }
- }
- if (!onedone) {
- Curpw = NULL;
- chkpw();
- }
- exit(0);
- }
-
- #define ARB_CONST 100
-
- chkpw()
-
- {
- register char *cp, *cp2;
- register struct passwd *pwd;
- struct passwd *getpwent();
- char guess[100];
- char *wordarray[ARB_CONST];
- char *malloc(), **wordptr, **endptr;
- int done = 0;
-
-
- if (Wordlist)
- {
- if ((wlf = fopen(Wordlist,"r")) == NULL)
- {
- perror(Wordlist);
- exit(1);
- }
-
- wordptr = wordarray;
- /*
- * note that endptr points to space OUTSIDE of wordarray
- */
- endptr = wordarray + (sizeof(wordarray)/sizeof(char *));
-
- while (fscanf(wlf,"%[^\n]\n",guess) != EOF)
- {
- if (wordptr == endptr)
- {
- fprintf(stderr,"Ran out of wordlist space. ARB_CONST %d must be too small.\n", ARB_CONST);
- exit(1);
- }
- if ((*wordptr = malloc(1+strlen(guess))) == NULL)
- {
- fprintf(stderr,"malloc: no more memory for wordlist\n");
- exit (1);
- }
- strcpy(*wordptr,guess);
- wordptr++;
- }
- *wordptr = NULL;
- }
-
- while ((pwd = getpwent()) != 0 ) {
-
- if (verbose || users) {
- if (Curpw == NULL)
- printf("\t%s \"%s\"\n", pwd->pw_name, pwd->pw_gecos);
- else
- printf("%s -- \t%s \"%s\"\n", Curpw, pwd->pw_name,
- pwd->pw_gecos);
- fflush(stdout);
- }
- if (*pwd->pw_passwd == '\0') {
- if (chknulls) {
- if (Curpw == NULL)
- printf("Problem: null passwd:\t%s\tshell: %s\n",
- pwd->pw_name, pwd->pw_shell);
- else
- printf("%s -- Problem: null passwd:\t%s\tshell: %s\n",
- Curpw, pwd->pw_name, pwd->pw_shell);
- fflush(stdout);
- }
- continue;
- }
- /*
- * Try the user's login name
- */
- if (uandltry(pwd,pwd->pw_name))
- continue;
-
- /*
- * Try names from the gecos field
- */
- if (checkgecos) {
- strcpy(guess, pwd->pw_gecos);
- cp = guess;
- if (*cp == '-') cp++; /* special gecos field */
- if ((cp2 = index(cp, ';')) != NULL)
- *cp2 = '\0';
-
- for (;;) {
- if ((cp2 = index(cp, ' ')) == NULL) {
- if (uandltry(pwd,cp)) done++;
- break;
- }
-
- *cp2 = '\0';
-
- if (uandltry(pwd,cp)) {
- done++;
- break;
- }
- cp = ++cp2;
- }
- }
-
- if (!done && Wordlist)
- {
- /*
- * try the words in the wordlist
- */
- wordptr = wordarray;
- while (endptr != wordptr)
- {
- if (*wordptr == NULL)
- break;
- if (uandltry(pwd,*wordptr++))
- {
- done++;
- break;
- }
- }
- }
- if (!done && singles) {
- /*
- * Try all single letters
- * (try digits too . --Seth)
- */
- guess[1] = '\0';
- for (guess[0]='a'; guess[0] <= 'z'; guess[0]++)
- if (try(pwd,guess))
- break;
- for (guess[0]='A'; guess[0] <= 'Z'; guess[0]++)
- if (try(pwd,guess))
- break;
- for (guess[0]='0'; guess[0] <= '9'; guess[0]++)
- if (try(pwd,guess))
- break;
- }
- }
- }
-
- /*
- * Stands for "upper and lower" try. Calls the "real" try, below,
- * with the supplied version of the password, and with
- * an upper and lowercase version of the password. If the user doesn't
- * want to try upper and lower case then we just return after the one
- * check.
- */
-
- uandltry (pwd,guess)
- char *guess;
- struct passwd *pwd;
- {
- register char *cp;
- char buf[100];
- int alllower, allupper;
-
- alllower = allupper = 1;
-
- if (try(pwd,guess) || (backwards && try(pwd,reverse(guess)))) return (1);
-
- if (!checkcase) return(0);
-
- strcpy (buf, guess);
- cp = buf-1;
- while (*++cp) {
- if (isupper(*cp))
- alllower = 0;
- if (islower(*cp))
- allupper = 0;
- }
-
- if (!allupper) {
- for ( cp=buf; *cp != '\0'; cp++)
- if (islower (*cp))
- *cp += 'A' - 'a';
-
- if (try(pwd,buf) || (backwards && try(pwd,reverse(buf)))) return (1);
- }
-
- if (!alllower) {
- for ( cp = buf; *cp != '\0'; cp++)
- if (isupper (*cp))
- *cp += 'a' - 'A';
-
- if (try(pwd,buf) || (backwards && try(pwd,reverse(buf)))) return (1);
- }
- return (0);
- }
-
- try(pwd,guess)
- char *guess;
- register struct passwd *pwd;
- {
- register char *cp;
- char *crypt ();
-
- if (verbose) {
- if (Curpw == NULL)
- printf ("Trying \"%s\" on %s\n", guess, pwd -> pw_name);
- else
- printf ("%s -- Trying \"%s\" on %s\n", Curpw, guess,
- pwd -> pw_name);
- fflush (stdout);
- }
- if (! guess || ! *guess) return(0);
- cp = crypt (guess, pwd -> pw_passwd);
- if (strcmp (cp, pwd -> pw_passwd))
- return (0);
- if (Curpw == NULL)
- if (printit)
- printf ("Problem: Guessed:\t%s\tshell: %s passwd: %s\n",
- pwd -> pw_name, pwd -> pw_shell, guess);
- else
- printf ("Problem: Guessed:\t%s\tshell: %s\n", pwd -> pw_name,
- pwd -> pw_shell);
- else
- if (printit)
- printf ("%s -- Problem: Guessed:\t%s\tshell: %s passwd: %s\n",
- Curpw, pwd -> pw_name, pwd -> pw_shell, guess);
- else
- printf ("%s -- Problem: Guessed:\t%s\tshell: %s\n",
- Curpw, pwd -> pw_name, pwd -> pw_shell);
- fflush (stdout);
- return (1);
- }
- /* end of PW guessing program */
-
- #define MAXUID 0x7fff /* added by tonyb 12/29/83 */
- /* altered to a reasonable number - mae 8/20/84 */
-
- /*
- * Add a parameter to "setpwent" so I can override the file name.
- */
-
- setpwent(file)
- char *file;
- {
- if ((pwf = fopen(file,"r")) == NULL)
- return(1);
- return(0);
- }
-
- endpwent()
-
- {
- fclose(pwf);
- pwf = NULL;
- }
-
- char *
- pwskip(p)
- register char *p;
- {
- while(*p && *p != ':' && *p != '\n')
- ++p;
- if(*p == '\n')
- *p = '\0';
- else if(*p)
- *p++ = '\0';
- return(p);
- }
-
- struct passwd *
- getpwent()
- {
- static struct passwd passwd;
- register char *p;
- long x;
-
- if(pwf == NULL)
- if (setpwent(PASSWD)) {
- perror(PASSWD);
- return(NULL);
- }
- p = fgets(line, BUFSIZ, pwf);
- if(p == NULL)
- return(0);
- passwd.pw_name = p;
- p = pwskip(p);
- passwd.pw_passwd = p;
- p = pwskip(p);
- x = atol(p);
- passwd.pw_uid = (x < 0 || x > MAXUID)? (MAXUID+1): x;
- p = pwskip(p);
- x = atol(p);
- passwd.pw_gid = (x < 0 || x > MAXUID)? (MAXUID+1): x;
- passwd.pw_comment = EMPTY;
- p = pwskip(p);
- passwd.pw_gecos = p;
- p = pwskip(p);
- passwd.pw_dir = p;
- p = pwskip(p);
- passwd.pw_shell = p;
- (void) pwskip(p);
-
- p = passwd.pw_passwd;
-
- return(&passwd);
-
- }
-
-
- /*
- * reverse a string
- */
- char *reverse(str)
- char *str;
-
- {
- register char *ptr;
- register int len;
- char *malloc();
-
- if ((ptr = malloc((len = strlen(str))+1)) == NULL)
- return(NULL);
- ptr += len;
- *ptr = '\0';
- while (*str && (*--ptr = *str++))
- ;
- return(ptr);
- }
-
-
- char *index(ptr,c)
- char c,*ptr;
- {
- while (*ptr != c) {
- if (*ptr++ == '\0') return((char *)0L);
- }
- return(ptr);
- }
-
-
- /*
- * 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 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<shifts[i]; k++) {
- t = C[0];
- for (j=0; j<28-1; j++)
- C[j] = C[j+1];
- C[27] = t;
- t = D[0];
- for (j=0; j<28-1; j++)
- D[j] = D[j+1];
- D[27] = t;
- }
- /*
- * get Ki. Note C and D are concatenated.
- */
- for (j=0; j<24; j++) {
- KS[i][j] = C[PC2_C[j]-1];
- KS[i][j+24] = D[PC2_D[j]-28-1];
- }
- }
- }
-
- /*
- * 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 8 selection functions.
- * For some reason, they give a 0-origin
- * index, unlike everything else.
- */
- static char S[8][64] = {
- 14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7,
- 0,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8,
- 4, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0,
- 15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13,
-
- 15, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10,
- 3,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5,
- 0,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15,
- 13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9,
-
- 10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8,
- 13, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1,
- 13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7,
- 1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12,
-
- 7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15,
- 13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9,
- 10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4,
- 3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14,
-
- 2,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9,
- 14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6,
- 4, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14,
- 11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3,
-
- 12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11,
- 10,15, 4, 2, 7,12, 9, 5, 6, 1,13,14, 0,11, 3, 8,
- 9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6,
- 4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13,
-
- 4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1,
- 13, 0,11, 7, 4, 9, 1,10,14, 3, 5,12, 2,15, 8, 6,
- 1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2,
- 6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12,
-
- 13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7,
- 1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2,
- 7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8,
- 2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11,
- };
-
- /*
- * P is a permutation on the selected combination
- * of the current L and key.
- */
- static char P[] = {
- 16, 7,20,21,
- 29,12,28,17,
- 1,15,23,26,
- 5,18,31,10,
- 2, 8,24,14,
- 32,27, 3, 9,
- 19,13,30, 6,
- 22,11, 4,25,
- };
-
- /*
- * The current block, divided into 2 halves.
- */
- static char L[32], R[32];
- static char tempL[32];
- static char f[32];
-
- /*
- * The combination of the key and the input, before selection.
- */
- static char preS[48];
-
- /*
- * The payoff: encrypt a block.
- */
-
- encrypt(block, edflag)
- char *block;
- {
- int i, ii;
- register t, j, k;
-
- /*
- * First, permute the bits in the input
- */
- for (j=0; j<64; j++)
- L[j] = block[IP[j]-1];
- /*
- * Perform an encryption operation 16 times.
- */
- for (ii=0; ii<16; ii++) {
- /*
- * Set direction
- */
- if (edflag)
- i = 15-ii;
- else
- i = ii;
- /*
- * Save the R array,
- * which will be the new L.
- */
- for (j=0; j<32; j++)
- tempL[j] = R[j];
- /*
- * Expand R to 48 bits using the E selector;
- * exclusive-or with the current key bits.
- */
- for (j=0; j<48; j++)
- preS[j] = R[E[j]-1] ^ KS[i][j];
- /*
- * The pre-select bits are now considered
- * in 8 groups of 6 bits each.
- * The 8 selection functions map these
- * 6-bit quantities into 4-bit quantities
- * and the results permuted
- * to make an f(R, K).
- * The indexing into the selection functions
- * is peculiar; it could be simplified by
- * rewriting the tables.
- */
- for (j=0; j<8; j++) {
- t = 6*j;
- k = S[j][(preS[t+0]<<5)+
- (preS[t+1]<<3)+
- (preS[t+2]<<2)+
- (preS[t+3]<<1)+
- (preS[t+4]<<0)+
- (preS[t+5]<<4)];
- t = 4*j;
- f[t+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;"[V-)jR$H 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);
- }
-