1 /* S/KEY v1.1b (skeysubr.c) 2 * 3 * Authors: 4 * Neil M. Haller <nmh@thumper.bellcore.com> 5 * Philip R. Karn <karn@chicago.qualcomm.com> 6 * John S. Walden <jsw@thumper.bellcore.com> 7 * 8 * Modifications: 9 * Scott Chasin <chasin@crimelab.com> 10 * 11 * S/KEY misc routines. 12 * 13 * $Id: skeysubr.c,v 1.2 1994/05/24 06:25:27 deraadt Exp $ 14 */ 15 16 #include <stdio.h> 17 #include <stdlib.h> 18 #include <string.h> 19 #include <signal.h> 20 #include <sys/termios.h> 21 22 #include "md4.h" 23 #include "skey.h" 24 25 struct termios newtty; 26 struct termios oldtty; 27 28 void trapped(); 29 30 /* Crunch a key: 31 * concatenate the seed and the password, run through MD4 and 32 * collapse to 64 bits. This is defined as the user's starting key. 33 */ 34 int 35 keycrunch(result,seed,passwd) 36 char *result; /* 8-byte result */ 37 char *seed; /* Seed, any length */ 38 char *passwd; /* Password, any length */ 39 { 40 char *buf; 41 MDstruct md; 42 unsigned int buflen; 43 int i; 44 register long tmp; 45 46 buflen = strlen(seed) + strlen(passwd); 47 if ((buf = (char *)malloc(buflen+1)) == NULL) 48 return -1; 49 strcpy(buf,seed); 50 strcat(buf,passwd); 51 52 /* Crunch the key through MD4 */ 53 sevenbit(buf); 54 MDbegin(&md); 55 MDupdate(&md,(unsigned char *)buf,8*buflen); 56 57 free(buf); 58 59 /* Fold result from 128 to 64 bits */ 60 md.buffer[0] ^= md.buffer[2]; 61 md.buffer[1] ^= md.buffer[3]; 62 63 /* Default (but slow) code that will convert to 64 * little-endian byte ordering on any machine 65 */ 66 for (i=0; i<2; i++) { 67 tmp = md.buffer[i]; 68 *result++ = tmp; 69 tmp >>= 8; 70 *result++ = tmp; 71 tmp >>= 8; 72 *result++ = tmp; 73 tmp >>= 8; 74 *result++ = tmp; 75 } 76 77 return 0; 78 } 79 80 /* The one-way function f(). Takes 8 bytes and returns 8 bytes in place */ 81 void f (x) 82 char *x; 83 { 84 MDstruct md; 85 register long tmp; 86 87 MDbegin(&md); 88 MDupdate(&md,(unsigned char *)x,64); 89 90 /* Fold 128 to 64 bits */ 91 md.buffer[0] ^= md.buffer[2]; 92 md.buffer[1] ^= md.buffer[3]; 93 94 /* Default (but slow) code that will convert to 95 * little-endian byte ordering on any machine 96 */ 97 tmp = md.buffer[0]; 98 *x++ = tmp; 99 tmp >>= 8; 100 *x++ = tmp; 101 tmp >>= 8; 102 *x++ = tmp; 103 tmp >>= 8; 104 *x++ = tmp; 105 106 tmp = md.buffer[1]; 107 *x++ = tmp; 108 tmp >>= 8; 109 *x++ = tmp; 110 tmp >>= 8; 111 *x++ = tmp; 112 tmp >>= 8; 113 *x = tmp; 114 } 115 116 /* Strip trailing cr/lf from a line of text */ 117 void rip (buf) 118 char *buf; 119 { 120 char *cp; 121 122 if((cp = strchr(buf,'\r')) != NULL) 123 *cp = '\0'; 124 125 if((cp = strchr(buf,'\n')) != NULL) 126 *cp = '\0'; 127 } 128 129 char *readpass (buf,n) 130 char *buf; 131 int n; 132 { 133 set_term (); 134 echo_off (); 135 136 fgets (buf, n, stdin); 137 138 rip (buf); 139 printf ("\n"); 140 141 sevenbit (buf); 142 143 unset_term (); 144 return buf; 145 } 146 147 set_term () 148 { 149 fflush(stdout); 150 tcgetattr(fileno(stdin), &newtty); 151 tcgetattr(fileno(stdin), &oldtty); 152 153 signal (SIGINT, trapped); 154 } 155 156 echo_off () 157 { 158 newtty.c_lflag &= ~(ICANON | ECHO | ECHONL); 159 newtty.c_cc[VMIN] = 1; 160 newtty.c_cc[VTIME] = 0; 161 newtty.c_cc[VINTR] = 3; 162 163 tcsetattr(fileno(stdin), TCSADRAIN, &newtty); 164 } 165 166 unset_term () 167 { 168 tcsetattr(fileno(stdin), TCSADRAIN, &oldtty); 169 } 170 171 void trapped() 172 { 173 signal (SIGINT, trapped); 174 printf ("^C\n"); 175 unset_term (); 176 exit (-1); 177 } 178 179 /* removebackspaced over charaters from the string */ 180 backspace(buf) 181 char *buf; 182 { 183 char bs = 0x8; 184 char *cp = buf; 185 char *out = buf; 186 187 while(*cp){ 188 if( *cp == bs ) { 189 if(out == buf){ 190 cp++; 191 continue; 192 } 193 else { 194 cp++; 195 out--; 196 } 197 } 198 else { 199 *out++ = *cp++; 200 } 201 202 } 203 *out = '\0'; 204 205 } 206 207 /* sevenbit () 208 * 209 * Make sure line is all seven bits. 210 */ 211 212 sevenbit (s) 213 char *s; 214 { 215 while (*s) { 216 *s = 0x7f & ( *s); 217 s++; 218 } 219 } 220