1 /*- 2 * Copyright (c) 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)enc_des.c 8.3 (Berkeley) 05/30/95"; 10 #endif /* not lint */ 11 12 #ifdef ENCRYPTION 13 # ifdef AUTHENTICATION 14 # ifdef DES_ENCRYPTION 15 #include <arpa/telnet.h> 16 #include <stdio.h> 17 #ifdef __STDC__ 18 #include <stdlib.h> 19 #endif 20 21 #include "encrypt.h" 22 #include "key-proto.h" 23 #include "misc-proto.h" 24 25 extern encrypt_debug_mode; 26 27 #define CFB 0 28 #define OFB 1 29 30 #define NO_SEND_IV 1 31 #define NO_RECV_IV 2 32 #define NO_KEYID 4 33 #define IN_PROGRESS (NO_SEND_IV|NO_RECV_IV|NO_KEYID) 34 #define SUCCESS 0 35 #define FAILED -1 36 37 38 struct fb { 39 Block krbdes_key; 40 Schedule krbdes_sched; 41 Block temp_feed; 42 unsigned char fb_feed[64]; 43 int need_start; 44 int state[2]; 45 int keyid[2]; 46 int once; 47 struct stinfo { 48 Block str_output; 49 Block str_feed; 50 Block str_iv; 51 Block str_ikey; 52 Schedule str_sched; 53 int str_index; 54 int str_flagshift; 55 } streams[2]; 56 }; 57 58 static struct fb fb[2]; 59 60 struct keyidlist { 61 char *keyid; 62 int keyidlen; 63 char *key; 64 int keylen; 65 int flags; 66 } keyidlist [] = { 67 { "\0", 1, 0, 0, 0 }, /* default key of zero */ 68 { 0, 0, 0, 0, 0 } 69 }; 70 71 #define KEYFLAG_MASK 03 72 73 #define KEYFLAG_NOINIT 00 74 #define KEYFLAG_INIT 01 75 #define KEYFLAG_OK 02 76 #define KEYFLAG_BAD 03 77 78 #define KEYFLAG_SHIFT 2 79 80 #define SHIFT_VAL(a,b) (KEYFLAG_SHIFT*((a)+((b)*2))) 81 82 #define FB64_IV 1 83 #define FB64_IV_OK 2 84 #define FB64_IV_BAD 3 85 86 87 void fb64_stream_iv P((Block, struct stinfo *)); 88 void fb64_init P((struct fb *)); 89 static int fb64_start P((struct fb *, int, int)); 90 int fb64_is P((unsigned char *, int, struct fb *)); 91 int fb64_reply P((unsigned char *, int, struct fb *)); 92 static void fb64_session P((Session_Key *, int, struct fb *)); 93 void fb64_stream_key P((Block, struct stinfo *)); 94 int fb64_keyid P((int, unsigned char *, int *, struct fb *)); 95 96 void 97 cfb64_init(server) 98 int server; 99 { 100 fb64_init(&fb[CFB]); 101 fb[CFB].fb_feed[4] = ENCTYPE_DES_CFB64; 102 fb[CFB].streams[0].str_flagshift = SHIFT_VAL(0, CFB); 103 fb[CFB].streams[1].str_flagshift = SHIFT_VAL(1, CFB); 104 } 105 106 void 107 ofb64_init(server) 108 int server; 109 { 110 fb64_init(&fb[OFB]); 111 fb[OFB].fb_feed[4] = ENCTYPE_DES_OFB64; 112 fb[CFB].streams[0].str_flagshift = SHIFT_VAL(0, OFB); 113 fb[CFB].streams[1].str_flagshift = SHIFT_VAL(1, OFB); 114 } 115 116 void 117 fb64_init(fbp) 118 register struct fb *fbp; 119 { 120 memset((void *)fbp, 0, sizeof(*fbp)); 121 fbp->state[0] = fbp->state[1] = FAILED; 122 fbp->fb_feed[0] = IAC; 123 fbp->fb_feed[1] = SB; 124 fbp->fb_feed[2] = TELOPT_ENCRYPT; 125 fbp->fb_feed[3] = ENCRYPT_IS; 126 } 127 128 /* 129 * Returns: 130 * -1: some error. Negotiation is done, encryption not ready. 131 * 0: Successful, initial negotiation all done. 132 * 1: successful, negotiation not done yet. 133 * 2: Not yet. Other things (like getting the key from 134 * Kerberos) have to happen before we can continue. 135 */ 136 int 137 cfb64_start(dir, server) 138 int dir; 139 int server; 140 { 141 return(fb64_start(&fb[CFB], dir, server)); 142 } 143 int 144 ofb64_start(dir, server) 145 int dir; 146 int server; 147 { 148 return(fb64_start(&fb[OFB], dir, server)); 149 } 150 151 static int 152 fb64_start(fbp, dir, server) 153 struct fb *fbp; 154 int dir; 155 int server; 156 { 157 Block b; 158 int x; 159 unsigned char *p; 160 register int state; 161 162 switch (dir) { 163 case DIR_DECRYPT: 164 /* 165 * This is simply a request to have the other side 166 * start output (our input). He will negotiate an 167 * IV so we need not look for it. 168 */ 169 state = fbp->state[dir-1]; 170 if (state == FAILED) 171 state = IN_PROGRESS; 172 break; 173 174 case DIR_ENCRYPT: 175 state = fbp->state[dir-1]; 176 if (state == FAILED) 177 state = IN_PROGRESS; 178 else if ((state & NO_SEND_IV) == 0) 179 break; 180 181 if (!VALIDKEY(fbp->krbdes_key)) { 182 fbp->need_start = 1; 183 break; 184 } 185 state &= ~NO_SEND_IV; 186 state |= NO_RECV_IV; 187 if (encrypt_debug_mode) 188 printf("Creating new feed\r\n"); 189 /* 190 * Create a random feed and send it over. 191 */ 192 des_new_random_key(fbp->temp_feed); 193 des_ecb_encrypt(fbp->temp_feed, fbp->temp_feed, 194 fbp->krbdes_sched, 1); 195 p = fbp->fb_feed + 3; 196 *p++ = ENCRYPT_IS; 197 p++; 198 *p++ = FB64_IV; 199 for (x = 0; x < sizeof(Block); ++x) { 200 if ((*p++ = fbp->temp_feed[x]) == IAC) 201 *p++ = IAC; 202 } 203 *p++ = IAC; 204 *p++ = SE; 205 printsub('>', &fbp->fb_feed[2], p - &fbp->fb_feed[2]); 206 net_write(fbp->fb_feed, p - fbp->fb_feed); 207 break; 208 default: 209 return(FAILED); 210 } 211 return(fbp->state[dir-1] = state); 212 } 213 214 /* 215 * Returns: 216 * -1: some error. Negotiation is done, encryption not ready. 217 * 0: Successful, initial negotiation all done. 218 * 1: successful, negotiation not done yet. 219 */ 220 int 221 cfb64_is(data, cnt) 222 unsigned char *data; 223 int cnt; 224 { 225 return(fb64_is(data, cnt, &fb[CFB])); 226 } 227 int 228 ofb64_is(data, cnt) 229 unsigned char *data; 230 int cnt; 231 { 232 return(fb64_is(data, cnt, &fb[OFB])); 233 } 234 235 int 236 fb64_is(data, cnt, fbp) 237 unsigned char *data; 238 int cnt; 239 struct fb *fbp; 240 { 241 int x; 242 unsigned char *p; 243 Block b; 244 register int state = fbp->state[DIR_DECRYPT-1]; 245 246 if (cnt-- < 1) 247 goto failure; 248 249 switch (*data++) { 250 case FB64_IV: 251 if (cnt != sizeof(Block)) { 252 if (encrypt_debug_mode) 253 printf("CFB64: initial vector failed on size\r\n"); 254 state = FAILED; 255 goto failure; 256 } 257 258 if (encrypt_debug_mode) 259 printf("CFB64: initial vector received\r\n"); 260 261 if (encrypt_debug_mode) 262 printf("Initializing Decrypt stream\r\n"); 263 264 fb64_stream_iv((void *)data, &fbp->streams[DIR_DECRYPT-1]); 265 266 p = fbp->fb_feed + 3; 267 *p++ = ENCRYPT_REPLY; 268 p++; 269 *p++ = FB64_IV_OK; 270 *p++ = IAC; 271 *p++ = SE; 272 printsub('>', &fbp->fb_feed[2], p - &fbp->fb_feed[2]); 273 net_write(fbp->fb_feed, p - fbp->fb_feed); 274 275 state = fbp->state[DIR_DECRYPT-1] = IN_PROGRESS; 276 break; 277 278 default: 279 if (encrypt_debug_mode) { 280 printf("Unknown option type: %d\r\n", *(data-1)); 281 printd(data, cnt); 282 printf("\r\n"); 283 } 284 /* FALL THROUGH */ 285 failure: 286 /* 287 * We failed. Send an FB64_IV_BAD option 288 * to the other side so it will know that 289 * things failed. 290 */ 291 p = fbp->fb_feed + 3; 292 *p++ = ENCRYPT_REPLY; 293 p++; 294 *p++ = FB64_IV_BAD; 295 *p++ = IAC; 296 *p++ = SE; 297 printsub('>', &fbp->fb_feed[2], p - &fbp->fb_feed[2]); 298 net_write(fbp->fb_feed, p - fbp->fb_feed); 299 300 break; 301 } 302 return(fbp->state[DIR_DECRYPT-1] = state); 303 } 304 305 /* 306 * Returns: 307 * -1: some error. Negotiation is done, encryption not ready. 308 * 0: Successful, initial negotiation all done. 309 * 1: successful, negotiation not done yet. 310 */ 311 int 312 cfb64_reply(data, cnt) 313 unsigned char *data; 314 int cnt; 315 { 316 return(fb64_reply(data, cnt, &fb[CFB])); 317 } 318 int 319 ofb64_reply(data, cnt) 320 unsigned char *data; 321 int cnt; 322 { 323 return(fb64_reply(data, cnt, &fb[OFB])); 324 } 325 326 327 int 328 fb64_reply(data, cnt, fbp) 329 unsigned char *data; 330 int cnt; 331 struct fb *fbp; 332 { 333 int x; 334 unsigned char *p; 335 Block b; 336 register int state = fbp->state[DIR_ENCRYPT-1]; 337 338 if (cnt-- < 1) 339 goto failure; 340 341 switch (*data++) { 342 case FB64_IV_OK: 343 fb64_stream_iv(fbp->temp_feed, &fbp->streams[DIR_ENCRYPT-1]); 344 if (state == FAILED) 345 state = IN_PROGRESS; 346 state &= ~NO_RECV_IV; 347 encrypt_send_keyid(DIR_ENCRYPT, (unsigned char *)"\0", 1, 1); 348 break; 349 350 case FB64_IV_BAD: 351 memset(fbp->temp_feed, 0, sizeof(Block)); 352 fb64_stream_iv(fbp->temp_feed, &fbp->streams[DIR_ENCRYPT-1]); 353 state = FAILED; 354 break; 355 356 default: 357 if (encrypt_debug_mode) { 358 printf("Unknown option type: %d\r\n", data[-1]); 359 printd(data, cnt); 360 printf("\r\n"); 361 } 362 /* FALL THROUGH */ 363 failure: 364 state = FAILED; 365 break; 366 } 367 return(fbp->state[DIR_ENCRYPT-1] = state); 368 } 369 370 void 371 cfb64_session(key, server) 372 Session_Key *key; 373 int server; 374 { 375 fb64_session(key, server, &fb[CFB]); 376 } 377 378 void 379 ofb64_session(key, server) 380 Session_Key *key; 381 int server; 382 { 383 fb64_session(key, server, &fb[OFB]); 384 } 385 386 static void 387 fb64_session(key, server, fbp) 388 Session_Key *key; 389 int server; 390 struct fb *fbp; 391 { 392 393 if (!key || key->type != SK_DES) { 394 if (encrypt_debug_mode) 395 printf("Can't set krbdes's session key (%d != %d)\r\n", 396 key ? key->type : -1, SK_DES); 397 return; 398 } 399 memmove((void *)fbp->krbdes_key, (void *)key->data, sizeof(Block)); 400 401 fb64_stream_key(fbp->krbdes_key, &fbp->streams[DIR_ENCRYPT-1]); 402 fb64_stream_key(fbp->krbdes_key, &fbp->streams[DIR_DECRYPT-1]); 403 404 if (fbp->once == 0) { 405 des_set_random_generator_seed(fbp->krbdes_key); 406 fbp->once = 1; 407 } 408 des_key_sched(fbp->krbdes_key, fbp->krbdes_sched); 409 /* 410 * Now look to see if krbdes_start() was was waiting for 411 * the key to show up. If so, go ahead an call it now 412 * that we have the key. 413 */ 414 if (fbp->need_start) { 415 fbp->need_start = 0; 416 fb64_start(fbp, DIR_ENCRYPT, server); 417 } 418 } 419 420 /* 421 * We only accept a keyid of 0. If we get a keyid of 422 * 0, then mark the state as SUCCESS. 423 */ 424 int 425 cfb64_keyid(dir, kp, lenp) 426 int dir, *lenp; 427 unsigned char *kp; 428 { 429 return(fb64_keyid(dir, kp, lenp, &fb[CFB])); 430 } 431 432 int 433 ofb64_keyid(dir, kp, lenp) 434 int dir, *lenp; 435 unsigned char *kp; 436 { 437 return(fb64_keyid(dir, kp, lenp, &fb[OFB])); 438 } 439 440 int 441 fb64_keyid(dir, kp, lenp, fbp) 442 int dir, *lenp; 443 unsigned char *kp; 444 struct fb *fbp; 445 { 446 register int state = fbp->state[dir-1]; 447 448 if (*lenp != 1 || (*kp != '\0')) { 449 *lenp = 0; 450 return(state); 451 } 452 453 if (state == FAILED) 454 state = IN_PROGRESS; 455 456 state &= ~NO_KEYID; 457 458 return(fbp->state[dir-1] = state); 459 } 460 461 void 462 fb64_printsub(data, cnt, buf, buflen, type) 463 unsigned char *data, *buf, *type; 464 int cnt, buflen; 465 { 466 char lbuf[32]; 467 register int i; 468 char *cp; 469 470 buf[buflen-1] = '\0'; /* make sure it's NULL terminated */ 471 buflen -= 1; 472 473 switch(data[2]) { 474 case FB64_IV: 475 sprintf(lbuf, "%s_IV", type); 476 cp = lbuf; 477 goto common; 478 479 case FB64_IV_OK: 480 sprintf(lbuf, "%s_IV_OK", type); 481 cp = lbuf; 482 goto common; 483 484 case FB64_IV_BAD: 485 sprintf(lbuf, "%s_IV_BAD", type); 486 cp = lbuf; 487 goto common; 488 489 default: 490 sprintf(lbuf, " %d (unknown)", data[2]); 491 cp = lbuf; 492 common: 493 for (; (buflen > 0) && (*buf = *cp++); buf++) 494 buflen--; 495 for (i = 3; i < cnt; i++) { 496 sprintf(lbuf, " %d", data[i]); 497 for (cp = lbuf; (buflen > 0) && (*buf = *cp++); buf++) 498 buflen--; 499 } 500 break; 501 } 502 } 503 504 void 505 cfb64_printsub(data, cnt, buf, buflen) 506 unsigned char *data, *buf; 507 int cnt, buflen; 508 { 509 fb64_printsub(data, cnt, buf, buflen, "CFB64"); 510 } 511 512 void 513 ofb64_printsub(data, cnt, buf, buflen) 514 unsigned char *data, *buf; 515 int cnt, buflen; 516 { 517 fb64_printsub(data, cnt, buf, buflen, "OFB64"); 518 } 519 520 void 521 fb64_stream_iv(seed, stp) 522 Block seed; 523 register struct stinfo *stp; 524 { 525 526 memmove((void *)stp->str_iv, (void *)seed, sizeof(Block)); 527 memmove((void *)stp->str_output, (void *)seed, sizeof(Block)); 528 529 des_key_sched(stp->str_ikey, stp->str_sched); 530 531 stp->str_index = sizeof(Block); 532 } 533 534 void 535 fb64_stream_key(key, stp) 536 Block key; 537 register struct stinfo *stp; 538 { 539 memmove((void *)stp->str_ikey, (void *)key, sizeof(Block)); 540 des_key_sched(key, stp->str_sched); 541 542 memmove((void *)stp->str_output, (void *)stp->str_iv, sizeof(Block)); 543 544 stp->str_index = sizeof(Block); 545 } 546 547 /* 548 * DES 64 bit Cipher Feedback 549 * 550 * key --->+-----+ 551 * +->| DES |--+ 552 * | +-----+ | 553 * | v 554 * INPUT --(--------->(+)+---> DATA 555 * | | 556 * +-------------+ 557 * 558 * 559 * Given: 560 * iV: Initial vector, 64 bits (8 bytes) long. 561 * Dn: the nth chunk of 64 bits (8 bytes) of data to encrypt (decrypt). 562 * On: the nth chunk of 64 bits (8 bytes) of encrypted (decrypted) output. 563 * 564 * V0 = DES(iV, key) 565 * On = Dn ^ Vn 566 * V(n+1) = DES(On, key) 567 */ 568 569 void 570 cfb64_encrypt(s, c) 571 register unsigned char *s; 572 int c; 573 { 574 register struct stinfo *stp = &fb[CFB].streams[DIR_ENCRYPT-1]; 575 register int index; 576 577 index = stp->str_index; 578 while (c-- > 0) { 579 if (index == sizeof(Block)) { 580 Block b; 581 des_ecb_encrypt(stp->str_output, b, stp->str_sched, 1); 582 memmove((void *)stp->str_feed, (void *)b, sizeof(Block)); 583 index = 0; 584 } 585 586 /* On encryption, we store (feed ^ data) which is cypher */ 587 *s = stp->str_output[index] = (stp->str_feed[index] ^ *s); 588 s++; 589 index++; 590 } 591 stp->str_index = index; 592 } 593 594 int 595 cfb64_decrypt(data) 596 int data; 597 { 598 register struct stinfo *stp = &fb[CFB].streams[DIR_DECRYPT-1]; 599 int index; 600 601 if (data == -1) { 602 /* 603 * Back up one byte. It is assumed that we will 604 * never back up more than one byte. If we do, this 605 * may or may not work. 606 */ 607 if (stp->str_index) 608 --stp->str_index; 609 return(0); 610 } 611 612 index = stp->str_index++; 613 if (index == sizeof(Block)) { 614 Block b; 615 des_ecb_encrypt(stp->str_output, b, stp->str_sched, 1); 616 memmove((void *)stp->str_feed, (void *)b, sizeof(Block)); 617 stp->str_index = 1; /* Next time will be 1 */ 618 index = 0; /* But now use 0 */ 619 } 620 621 /* On decryption we store (data) which is cypher. */ 622 stp->str_output[index] = data; 623 return(data ^ stp->str_feed[index]); 624 } 625 626 /* 627 * DES 64 bit Output Feedback 628 * 629 * key --->+-----+ 630 * +->| DES |--+ 631 * | +-----+ | 632 * +-----------+ 633 * v 634 * INPUT -------->(+) ----> DATA 635 * 636 * Given: 637 * iV: Initial vector, 64 bits (8 bytes) long. 638 * Dn: the nth chunk of 64 bits (8 bytes) of data to encrypt (decrypt). 639 * On: the nth chunk of 64 bits (8 bytes) of encrypted (decrypted) output. 640 * 641 * V0 = DES(iV, key) 642 * V(n+1) = DES(Vn, key) 643 * On = Dn ^ Vn 644 */ 645 void 646 ofb64_encrypt(s, c) 647 register unsigned char *s; 648 int c; 649 { 650 register struct stinfo *stp = &fb[OFB].streams[DIR_ENCRYPT-1]; 651 register int index; 652 653 index = stp->str_index; 654 while (c-- > 0) { 655 if (index == sizeof(Block)) { 656 Block b; 657 des_ecb_encrypt(stp->str_feed, b, stp->str_sched, 1); 658 memmove((void *)stp->str_feed, (void *)b, sizeof(Block)); 659 index = 0; 660 } 661 *s++ ^= stp->str_feed[index]; 662 index++; 663 } 664 stp->str_index = index; 665 } 666 667 int 668 ofb64_decrypt(data) 669 int data; 670 { 671 register struct stinfo *stp = &fb[OFB].streams[DIR_DECRYPT-1]; 672 int index; 673 674 if (data == -1) { 675 /* 676 * Back up one byte. It is assumed that we will 677 * never back up more than one byte. If we do, this 678 * may or may not work. 679 */ 680 if (stp->str_index) 681 --stp->str_index; 682 return(0); 683 } 684 685 index = stp->str_index++; 686 if (index == sizeof(Block)) { 687 Block b; 688 des_ecb_encrypt(stp->str_feed, b, stp->str_sched, 1); 689 memmove((void *)stp->str_feed, (void *)b, sizeof(Block)); 690 stp->str_index = 1; /* Next time will be 1 */ 691 index = 0; /* But now use 0 */ 692 } 693 694 return(data ^ stp->str_feed[index]); 695 } 696 # endif /* DES_ENCRYPTION */ 697 # endif /* AUTHENTICATION */ 698 #endif /* ENCRYPTION */ 699