/* $NetBSD: skeysubr.c,v 1.15 2000/01/23 02:11:02 mycroft Exp $ */ /* S/KEY v1.1b (skeysubr.c) * * Authors: * Neil M. Haller * Philip R. Karn * John S. Walden * * Modifications: * Scott Chasin * * S/KEY misc routines. */ #include #include #include #include #include #include #include "skey.h" struct termios newtty; struct termios oldtty; static void trapped __ARGS((int sig)); static void set_term __ARGS((void)); static void unset_term __ARGS((void)); static void echo_off __ARGS((void)); /* Crunch a key: * concatenate the seed and the password, run through MD4 and * collapse to 64 bits. This is defined as the user's starting key. */ int keycrunch(result,seed,passwd) char *result; /* 8-byte result */ const char *seed; /* Seed, any length */ const char *passwd; /* Password, any length */ { char *buf; MD4_CTX md; unsigned int buflen; u_int32_t hash[4]; buflen = strlen(seed) + strlen(passwd); if ((buf = (char *)malloc(buflen+1)) == NULL) return -1; strcpy(buf, seed); /* XXX strcpy is safe */ strcat(buf, passwd); /* XXX strcat is safe */ /* Crunch the key through MD4 */ sevenbit(buf); MD4Init(&md); MD4Update(&md, (unsigned char *) buf, buflen); MD4Final((unsigned char *)(void *) hash, &md); free(buf); /* Fold result from 128 to 64 bits */ hash[0] ^= hash[2]; hash[1] ^= hash[3]; (void)memcpy(result, hash, 8); return 0; } /* The one-way function f(). Takes 8 bytes and returns 8 bytes in place */ void f(x) char *x; { MD4_CTX md; u_int32_t hash[4]; MD4Init(&md); MD4Update(&md, (unsigned char *) x, 8); MD4Final((unsigned char *)(void *) hash, &md); /* Fold 128 to 64 bits */ hash[0] ^= hash[2]; hash[1] ^= hash[3]; (void)memcpy(x, hash, 8); } /* Strip trailing cr/lf from a line of text */ void rip(buf) char *buf; { char *cp; if ((cp = strchr(buf,'\r')) != NULL) *cp = '\0'; if ((cp = strchr(buf,'\n')) != NULL) *cp = '\0'; } char * readpass (buf,n) char *buf; int n; { set_term(); echo_off(); fgets(buf, n, stdin); rip(buf); printf("\n"); sevenbit(buf); unset_term(); return buf; } char * readskey(buf, n) char *buf; int n; { fgets (buf, n, stdin); rip(buf); printf ("\n"); sevenbit (buf); return buf; } static void set_term() { fflush(stdout); tcgetattr(fileno(stdin), &newtty); tcgetattr(fileno(stdin), &oldtty); signal (SIGINT, trapped); } static void echo_off() { newtty.c_lflag &= ~(ICANON | ECHO | ECHONL); newtty.c_cc[VMIN] = 1; newtty.c_cc[VTIME] = 0; newtty.c_cc[VINTR] = 3; tcsetattr(fileno(stdin), TCSADRAIN, &newtty); } static void unset_term() { tcsetattr(fileno(stdin), TCSADRAIN, &oldtty); } /*ARGSUSED*/ static void trapped(sig) int sig; { signal(SIGINT, trapped); printf("^C\n"); unset_term(); exit(-1); } /* Convert 8-byte hex-ascii string to binary array * Returns 0 on success, -1 on error */ int atob8(out, in) char *out; const char *in; { int i; int val; if (in == NULL || out == NULL) return -1; for (i=0; i<8; i++) { if ((in = skipspace(in)) == NULL) return -1; if ((val = htoi(*in++)) == -1) return -1; *out = val << 4; if ((in = skipspace(in)) == NULL) return -1; if ((val = htoi(*in++)) == -1) return -1; *out++ |= val; } return 0; } /* Convert 8-byte binary array to hex-ascii string */ int btoa8(out, in) char *out; const char *in; { int i; if (in == NULL || out == NULL) return -1; for (i=0;i<8;i++) { sprintf(out,"%02x",*in++ & 0xff); /* XXX: sprintf() (btoa8() appears to be unused */ out += 2; } return 0; } /* Convert hex digit to binary integer */ int htoi(c) int c; { if ('0' <= c && c <= '9') return c - '0'; if ('a' <= c && c <= 'f') return 10 + c - 'a'; if ('A' <= c && c <= 'F') return 10 + c - 'A'; return -1; } const char * skipspace(cp) const char *cp; { while (*cp == ' ' || *cp == '\t') cp++; if (*cp == '\0') return NULL; else return cp; } /* removebackspaced over charaters from the string */ void backspace(buf) char *buf; { char bs = 0x8; char *cp = buf; char *out = buf; while (*cp) { if (*cp == bs) { if (out == buf) { cp++; continue; } else { cp++; out--; } } else { *out++ = *cp++; } } *out = '\0'; } /* sevenbit () * * Make sure line is all seven bits. */ void sevenbit(s) char *s; { while (*s) *s++ &= 0x7f; }