1 /* $NetBSD: skeysubr.c,v 1.7 1996/09/19 19:39:50 thorpej Exp $ */ 2 3 /* S/KEY v1.1b (skeysubr.c) 4 * 5 * Authors: 6 * Neil M. Haller <nmh@thumper.bellcore.com> 7 * Philip R. Karn <karn@chicago.qualcomm.com> 8 * John S. Walden <jsw@thumper.bellcore.com> 9 * 10 * Modifications: 11 * Scott Chasin <chasin@crimelab.com> 12 * 13 * S/KEY misc routines. 14 */ 15 16 #include <stdio.h> 17 #include <stdlib.h> 18 #include <string.h> 19 #include <signal.h> 20 #include <termios.h> 21 22 #include "md4.h" 23 #include "skey.h" 24 25 struct termios newtty; 26 struct termios oldtty; 27 28 static void trapped __ARGS((int sig)); 29 static void set_term __ARGS((void)); 30 static void unset_term __ARGS((void)); 31 static void echo_off __ARGS((void)); 32 33 /* Crunch a key: 34 * concatenate the seed and the password, run through MD4 and 35 * collapse to 64 bits. This is defined as the user's starting key. 36 */ 37 int 38 keycrunch(result,seed,passwd) 39 char *result; /* 8-byte result */ 40 char *seed; /* Seed, any length */ 41 char *passwd; /* Password, any length */ 42 { 43 char *buf; 44 MDstruct md; 45 unsigned int buflen; 46 int i; 47 register int tmp; 48 49 buflen = strlen(seed) + strlen(passwd); 50 if ((buf = (char *)malloc(buflen+1)) == NULL) 51 return -1; 52 strcpy(buf,seed); 53 strcat(buf,passwd); 54 55 /* Crunch the key through MD4 */ 56 sevenbit(buf); 57 MDbegin(&md); 58 MDupdate(&md,(unsigned char *)buf,8*buflen); 59 60 free(buf); 61 62 /* Fold result from 128 to 64 bits */ 63 md.buffer[0] ^= md.buffer[2]; 64 md.buffer[1] ^= md.buffer[3]; 65 66 /* Default (but slow) code that will convert to 67 * little-endian byte ordering on any machine 68 */ 69 for (i=0; i<2; i++) { 70 tmp = md.buffer[i]; 71 *result++ = tmp; 72 tmp >>= 8; 73 *result++ = tmp; 74 tmp >>= 8; 75 *result++ = tmp; 76 tmp >>= 8; 77 *result++ = tmp; 78 } 79 80 return 0; 81 } 82 83 /* The one-way function f(). Takes 8 bytes and returns 8 bytes in place */ 84 void 85 f(x) 86 char *x; 87 { 88 MDstruct md; 89 register int tmp; 90 91 MDbegin(&md); 92 MDupdate(&md,(unsigned char *)x,64); 93 94 /* Fold 128 to 64 bits */ 95 md.buffer[0] ^= md.buffer[2]; 96 md.buffer[1] ^= md.buffer[3]; 97 98 /* Default (but slow) code that will convert to 99 * little-endian byte ordering on any machine 100 */ 101 tmp = md.buffer[0]; 102 *x++ = tmp; 103 tmp >>= 8; 104 *x++ = tmp; 105 tmp >>= 8; 106 *x++ = tmp; 107 tmp >>= 8; 108 *x++ = tmp; 109 110 tmp = md.buffer[1]; 111 *x++ = tmp; 112 tmp >>= 8; 113 *x++ = tmp; 114 tmp >>= 8; 115 *x++ = tmp; 116 tmp >>= 8; 117 *x = tmp; 118 } 119 120 /* Strip trailing cr/lf from a line of text */ 121 void 122 rip(buf) 123 char *buf; 124 { 125 char *cp; 126 127 if ((cp = strchr(buf,'\r')) != NULL) 128 *cp = '\0'; 129 130 if ((cp = strchr(buf,'\n')) != NULL) 131 *cp = '\0'; 132 } 133 134 char * 135 readpass (buf,n) 136 char *buf; 137 int n; 138 { 139 set_term(); 140 echo_off(); 141 142 fgets(buf, n, stdin); 143 144 rip(buf); 145 printf("\n"); 146 147 sevenbit(buf); 148 149 unset_term(); 150 return buf; 151 } 152 153 char * 154 readskey(buf, n) 155 char *buf; 156 int n; 157 { 158 fgets (buf, n, stdin); 159 160 rip(buf); 161 printf ("\n"); 162 163 sevenbit (buf); 164 165 return buf; 166 } 167 168 static void 169 set_term() 170 { 171 fflush(stdout); 172 tcgetattr(fileno(stdin), &newtty); 173 tcgetattr(fileno(stdin), &oldtty); 174 175 signal (SIGINT, trapped); 176 } 177 178 static void 179 echo_off() 180 { 181 newtty.c_lflag &= ~(ICANON | ECHO | ECHONL); 182 newtty.c_cc[VMIN] = 1; 183 newtty.c_cc[VTIME] = 0; 184 newtty.c_cc[VINTR] = 3; 185 186 tcsetattr(fileno(stdin), TCSADRAIN, &newtty); 187 } 188 189 static void 190 unset_term() 191 { 192 tcsetattr(fileno(stdin), TCSADRAIN, &oldtty); 193 } 194 195 static void 196 trapped(sig) 197 int sig; 198 { 199 signal(SIGINT, trapped); 200 printf("^C\n"); 201 unset_term(); 202 exit(-1); 203 } 204 205 /* Convert 8-byte hex-ascii string to binary array 206 * Returns 0 on success, -1 on error 207 */ 208 int 209 atob8(out, in) 210 register char *out, *in; 211 { 212 register int i; 213 register int val; 214 215 if (in == NULL || out == NULL) 216 return -1; 217 218 for (i=0; i<8; i++) { 219 if ((in = skipspace(in)) == NULL) 220 return -1; 221 if ((val = htoi(*in++)) == -1) 222 return -1; 223 *out = val << 4; 224 225 if ((in = skipspace(in)) == NULL) 226 return -1; 227 if ((val = htoi(*in++)) == -1) 228 return -1; 229 *out++ |= val; 230 } 231 return 0; 232 } 233 234 /* Convert 8-byte binary array to hex-ascii string */ 235 int 236 btoa8(out, in) 237 register char *out, *in; 238 { 239 register int i; 240 241 if (in == NULL || out == NULL) 242 return -1; 243 244 for (i=0;i<8;i++) { 245 sprintf(out,"%02x",*in++ & 0xff); 246 out += 2; 247 } 248 return 0; 249 } 250 251 252 /* Convert hex digit to binary integer */ 253 int 254 htoi(c) 255 register char c; 256 { 257 if ('0' <= c && c <= '9') 258 return c - '0'; 259 if ('a' <= c && c <= 'f') 260 return 10 + c - 'a'; 261 if ('A' <= c && c <= 'F') 262 return 10 + c - 'A'; 263 return -1; 264 } 265 266 char * 267 skipspace(cp) 268 register char *cp; 269 { 270 while (*cp == ' ' || *cp == '\t') 271 cp++; 272 273 if (*cp == '\0') 274 return NULL; 275 else 276 return cp; 277 } 278 279 /* removebackspaced over charaters from the string */ 280 void 281 backspace(buf) 282 char *buf; 283 { 284 char bs = 0x8; 285 char *cp = buf; 286 char *out = buf; 287 288 while (*cp) { 289 if (*cp == bs) { 290 if (out == buf) { 291 cp++; 292 continue; 293 } 294 else { 295 cp++; 296 out--; 297 } 298 } else { 299 *out++ = *cp++; 300 } 301 302 } 303 *out = '\0'; 304 } 305 306 /* sevenbit () 307 * 308 * Make sure line is all seven bits. 309 */ 310 311 void 312 sevenbit(s) 313 char *s; 314 { 315 while (*s) 316 *s++ &= 0x7f; 317 } 318