1 /*- 2 * Copyright (c) 1991 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Matt Bishop of Dartmouth College. 7 * 8 * The United States Government has rights in this work pursuant 9 * to contract no. NAG 2-680 between the National Aeronautics and 10 * Space Administration and Dartmouth College. 11 * 12 * %sccs.include.redist.c% 13 */ 14 15 #ifndef lint 16 char copyright[] = 17 "@(#) Copyright (c) 1991 The Regents of the University of California.\n\ 18 All rights reserved.\n"; 19 #endif /* not lint */ 20 21 #ifndef lint 22 static char sccsid[] = "@(#)bdes.c 5.2 (Berkeley) 04/22/91"; 23 #endif /* not lint */ 24 25 /* 26 * BDES -- DES encryption package for Berkeley Software Distribution 4.4 27 * options: 28 * -a key is in ASCII 29 * -e use ECB (electronic code book) mode 30 * -f b use b-bit CFB (cipher feedback) mode 31 * -F b use b-bit CFB (cipher feedback) alternative mode 32 * -i invert (decrypt) input 33 * -m b generate a MAC of length b 34 * -o b use b-bit OFB (output feedback) mode 35 * -p don't reset the parity bit 36 * -v v use v as the initialization vector (ignored for ECB) 37 * note: the last character of the last block is the integer indicating 38 * how many characters of that block are to be output 39 * 40 * Author: Matt Bishop 41 * Department of Mathematics and Computer Science 42 * Dartmouth College 43 * Hanover, NH 03755 44 * Email: Matt.Bishop@dartmouth.edu 45 * ...!decvax!dartvax!Matt.Bishop 46 * 47 * See Technical Report PCS-TR91-158, Department of Mathematics and Computer 48 * Science, Dartmouth College, for a detailed description of the implemen- 49 * tation and differences between it and Sun's. The DES is described in 50 * FIPS PUB 46, and the modes in FIPS PUB 81 (see either the manual page 51 * or the technical report for a complete reference). 52 */ 53 54 #include <errno.h> 55 #include <unistd.h> 56 #include <stdio.h> 57 #include <ctype.h> 58 #include <stdlib.h> 59 #include <string.h> 60 61 /* 62 * BSD and System V systems offer special library calls that do 63 * block moves and fills, so if possible we take advantage of them 64 */ 65 #define MEMCPY(dest,src,len) bcopy((src),(dest),(len)) 66 #define MEMZERO(dest,len) bzero((dest),(len)) 67 68 /* 69 * these "hide" the calls to the primitive encryption routines 70 */ 71 #define DES_KEY(buf) { \ 72 char bits1[64]; /* bits of key */ \ 73 expand(buf, bits1); \ 74 setkey(bits1); \ 75 } 76 #define DES_XFORM(buf) { \ 77 char bits1[64]; /* bits of message */ \ 78 expand(buf, bits1); \ 79 encrypt(bits1, inverse); \ 80 compress(bits1, buf); \ 81 } 82 83 /* 84 * this does an error-checking write 85 */ 86 #define READ(buf, n) fread(buf, sizeof(char), n, stdin) 87 #define WRITE(buf,n) \ 88 if (fwrite(buf, sizeof(char), n, stdout) != n) \ 89 err(bn, NULL); 90 91 /* 92 * some things to make references easier 93 */ 94 typedef char Desbuf[8]; 95 #define CHAR(x,i) (x[i]) 96 #define UCHAR(x,i) (x[i]) 97 #define BUFFER(x) (x) 98 #define UBUFFER(x) (x) 99 100 /* 101 * global variables and related macros 102 */ 103 #define KEY_DEFAULT 0 /* interpret radix of key from key */ 104 #define KEY_ASCII 1 /* key is in ASCII characters */ 105 int keybase = KEY_DEFAULT; /* how to interpret the key */ 106 107 enum { MODE_ENCRYPT, MODE_DECRYPT, MODE_AUTHENTICATE } mode = MODE_ENCRYPT; 108 enum { ALG_ECB, ALG_CBC, ALG_CFB, ALG_OFB, ALG_CFBA } alg = ALG_CBC; 109 110 Desbuf ivec; /* initialization vector */ 111 char bits[] = { /* used to extract bits from a char */ 112 '\200', '\100', '\040', '\020', '\010', '\004', '\002', '\001' 113 }; 114 int inverse; /* 0 to encrypt, 1 to decrypt */ 115 int macbits = -1; /* number of bits in authentication */ 116 int fbbits = -1; /* number of feedback bits */ 117 int pflag; /* 1 to preserve parity bits */ 118 119 main(ac, av) 120 int ac; 121 char **av; 122 { 123 extern int optind; /* option (argument) number */ 124 extern char *optarg; /* argument to option if any */ 125 register int i; /* counter in a for loop */ 126 register char *p; /* used to obtain the key */ 127 Desbuf msgbuf; /* I/O buffer */ 128 int argc, kflag; 129 char **argv; 130 131 /* hide the arguments from ps(1) */ 132 argc = ac; 133 ac = 1; 134 argv = malloc((argc + 1) * sizeof(char *)); 135 for (i = 0; i < argc; ++i) { 136 argv[i] = strdup(av[i]); 137 MEMZERO(av[i], strlen(av[i])); 138 } 139 argv[argc] = NULL; 140 141 /* initialize the initialization vctor */ 142 MEMZERO(ivec, 8); 143 144 /* process the argument list */ 145 kflag = 0; 146 while ((i = getopt(argc, argv, "abdF:f:k:m:o:pv:")) != EOF) 147 switch(i) { 148 case 'a': /* key is ASCII */ 149 keybase = KEY_ASCII; 150 break; 151 case 'b': /* use ECB mode */ 152 alg = ALG_ECB; 153 break; 154 case 'd': /* decrypt */ 155 mode = MODE_DECRYPT; 156 break; 157 case 'F': /* use alternative CFB mode */ 158 alg = ALG_CFBA; 159 if ((fbbits = setbits(optarg, 7)) > 56 || fbbits == 0) 160 err(-1, "-F: number must be 1-56 inclusive"); 161 else if (fbbits == -1) 162 err(-1, "-F: number must be a multiple of 7"); 163 break; 164 case 'f': /* use CFB mode */ 165 alg = ALG_CFB; 166 if ((fbbits = setbits(optarg, 8)) > 64 || fbbits == 0) 167 err(-1, "-f: number must be 1-64 inclusive"); 168 else if (fbbits == -1) 169 err(-1, "-f: number must be a multiple of 8"); 170 break; 171 case 'k': /* encryption key */ 172 kflag = 1; 173 cvtkey(BUFFER(msgbuf), optarg); 174 break; 175 case 'm': /* number of bits for MACing */ 176 mode = MODE_AUTHENTICATE; 177 if ((macbits = setbits(optarg, 1)) > 64) 178 err(-1, "-m: number must be 0-64 inclusive"); 179 break; 180 case 'o': /* use OFB mode */ 181 alg = ALG_OFB; 182 if ((fbbits = setbits(optarg, 8)) > 64 || fbbits == 0) 183 err(-1, "-o: number must be 1-64 inclusive"); 184 else if (fbbits == -1) 185 err(-1, "-o: number must be a multiple of 8"); 186 break; 187 case 'p': /* preserve parity bits */ 188 pflag = 1; 189 break; 190 case 'v': /* set initialization vector */ 191 cvtkey(BUFFER(ivec), optarg); 192 break; 193 default: /* error */ 194 usage(); 195 } 196 197 if (!kflag) { 198 /* 199 * if the key's not ASCII, assume it is 200 */ 201 keybase = KEY_ASCII; 202 /* 203 * get the key 204 */ 205 p = getpass("Enter key: "); 206 /* 207 * copy it, nul-padded, into the key area 208 */ 209 strncpy(BUFFER(msgbuf), p, 8); 210 } 211 212 makekey(msgbuf); 213 inverse = (alg == ALG_CBC || alg == ALG_ECB) && mode == MODE_DECRYPT; 214 215 switch(alg) { 216 case ALG_CBC: 217 switch(mode) { 218 case MODE_AUTHENTICATE: /* authenticate using CBC mode */ 219 cbcauth(); 220 break; 221 case MODE_DECRYPT: /* decrypt using CBC mode */ 222 cbcdec(); 223 break; 224 case MODE_ENCRYPT: /* encrypt using CBC mode */ 225 cbcenc(); 226 break; 227 } 228 break; 229 case ALG_CFB: 230 switch(mode) { 231 case MODE_AUTHENTICATE: /* authenticate using CFB mode */ 232 cfbauth(); 233 break; 234 case MODE_DECRYPT: /* decrypt using CFB mode */ 235 cfbdec(); 236 break; 237 case MODE_ENCRYPT: /* encrypt using CFB mode */ 238 cfbenc(); 239 break; 240 } 241 break; 242 case ALG_CFBA: 243 switch(mode) { 244 case MODE_AUTHENTICATE: /* authenticate using CFBA mode */ 245 err(-1, "can't authenticate with CFBA mode"); 246 break; 247 case MODE_DECRYPT: /* decrypt using CFBA mode */ 248 cfbadec(); 249 break; 250 case MODE_ENCRYPT: /* encrypt using CFBA mode */ 251 cfbaenc(); 252 break; 253 } 254 break; 255 case ALG_ECB: 256 switch(mode) { 257 case MODE_AUTHENTICATE: /* authenticate using ECB mode */ 258 err(-1, "can't authenticate with ECB mode"); 259 break; 260 case MODE_DECRYPT: /* decrypt using ECB mode */ 261 ecbdec(); 262 break; 263 case MODE_ENCRYPT: /* encrypt using ECB mode */ 264 ecbenc(); 265 break; 266 } 267 break; 268 case ALG_OFB: 269 switch(mode) { 270 case MODE_AUTHENTICATE: /* authenticate using OFB mode */ 271 err(-1, "can't authenticate with OFB mode"); 272 break; 273 case MODE_DECRYPT: /* decrypt using OFB mode */ 274 ofbdec(); 275 break; 276 case MODE_ENCRYPT: /* encrypt using OFB mode */ 277 ofbenc(); 278 break; 279 } 280 break; 281 } 282 exit(0); 283 } 284 285 /* 286 * print a warning message and, possibly, terminate 287 */ 288 err(n, s) 289 int n; /* offending block number */ 290 char *s; /* the message */ 291 { 292 if (n > 0) 293 (void)fprintf(stderr, "bdes (block %d): ", n); 294 else 295 (void)fprintf(stderr, "bdes: "); 296 (void)fprintf(stderr, "%s\n", s ? s : strerror(errno)); 297 exit(1); 298 } 299 300 /* 301 * map a hex character to an integer 302 */ 303 tobinhex(c, radix) 304 char c; 305 int radix; 306 { 307 switch(c) { 308 case '0': return(0x0); 309 case '1': return(0x1); 310 case '2': return(radix > 2 ? 0x2 : -1); 311 case '3': return(radix > 3 ? 0x3 : -1); 312 case '4': return(radix > 4 ? 0x4 : -1); 313 case '5': return(radix > 5 ? 0x5 : -1); 314 case '6': return(radix > 6 ? 0x6 : -1); 315 case '7': return(radix > 7 ? 0x7 : -1); 316 case '8': return(radix > 8 ? 0x8 : -1); 317 case '9': return(radix > 9 ? 0x9 : -1); 318 case 'A': case 'a': return(radix > 10 ? 0xa : -1); 319 case 'B': case 'b': return(radix > 11 ? 0xb : -1); 320 case 'C': case 'c': return(radix > 12 ? 0xc : -1); 321 case 'D': case 'd': return(radix > 13 ? 0xd : -1); 322 case 'E': case 'e': return(radix > 14 ? 0xe : -1); 323 case 'F': case 'f': return(radix > 15 ? 0xf : -1); 324 } 325 /* 326 * invalid character 327 */ 328 return(-1); 329 } 330 331 /* 332 * convert the key to a bit pattern 333 */ 334 cvtkey(obuf, ibuf) 335 char *obuf, *ibuf; 336 { 337 register int i, j; /* counter in a for loop */ 338 int nbuf[64]; /* used for hex/key translation */ 339 340 /* 341 * just switch on the key base 342 */ 343 switch(keybase) { 344 case KEY_ASCII: /* ascii to integer */ 345 (void)strncpy(obuf, ibuf, 8); 346 return; 347 case KEY_DEFAULT: /* tell from context */ 348 /* 349 * leading '0x' or '0X' == hex key 350 */ 351 if (ibuf[0] == '0' && (ibuf[1] == 'x' || ibuf[1] == 'X')) { 352 ibuf = &ibuf[2]; 353 /* 354 * now translate it, bombing on any illegal hex digit 355 */ 356 for (i = 0; ibuf[i] && i < 16; i++) 357 if ((nbuf[i] = tobinhex(ibuf[i], 16)) == -1) 358 err(-1, "bad hex digit in key"); 359 while (i < 16) 360 nbuf[i++] = 0; 361 for (i = 0; i < 8; i++) 362 obuf[i] = 363 ((nbuf[2*i]&0xf)<<4) | (nbuf[2*i+1]&0xf); 364 /* preserve parity bits */ 365 pflag = 1; 366 return; 367 } 368 /* 369 * leading '0b' or '0B' == binary key 370 */ 371 if (ibuf[0] == '0' && (ibuf[1] == 'b' || ibuf[1] == 'B')) { 372 ibuf = &ibuf[2]; 373 /* 374 * now translate it, bombing on any illegal binary digit 375 */ 376 for (i = 0; ibuf[i] && i < 16; i++) 377 if ((nbuf[i] = tobinhex(ibuf[i], 2)) == -1) 378 err(-1, "bad binary digit in key"); 379 while (i < 64) 380 nbuf[i++] = 0; 381 for (i = 0; i < 8; i++) 382 for (j = 0; j < 8; j++) 383 obuf[i] = (obuf[i]<<1)|nbuf[8*i+j]; 384 /* preserve parity bits */ 385 pflag = 1; 386 return; 387 } 388 /* 389 * no special leader -- ASCII 390 */ 391 (void)strncpy(obuf, ibuf, 8); 392 } 393 } 394 395 /* 396 * convert an ASCII string into a decimal number: 397 * 1. must be between 0 and 64 inclusive 398 * 2. must be a valid decimal number 399 * 3. must be a multiple of mult 400 */ 401 setbits(s, mult) 402 char *s; 403 int mult; 404 { 405 register char *p; 406 register int n = 0; 407 408 /* 409 * skip white space 410 */ 411 while (isspace(*s)) 412 s++; 413 /* 414 * get the integer 415 */ 416 for (p = s; *p; p++) { 417 if (isdigit(*p)) 418 n = n * 10 + *p - '0'; 419 else { 420 err(-1, "bad decimal digit in MAC length"); 421 } 422 } 423 /* 424 * be sure it's a multiple of mult 425 */ 426 return((n % mult != 0) ? -1 : n); 427 } 428 429 /***************** 430 * DES FUNCTIONS * 431 *****************/ 432 /* 433 * This sets the DES key and (if you're using the deszip version) 434 * the direction of the transformation. This uses the Sun 435 * to map the 64-bit key onto the 56 bits that the key schedule 436 * generation routines use: the old way, which just uses the user- 437 * supplied 64 bits as is, and the new way, which resets the parity 438 * bit to be the same as the low-order bit in each character. The 439 * new way generates a greater variety of key schedules, since many 440 * systems set the parity (high) bit of each character to 0, and the 441 * DES ignores the low order bit of each character. 442 */ 443 makekey(buf) 444 Desbuf buf; /* key block */ 445 { 446 register int i, j; /* counter in a for loop */ 447 register int par; /* parity counter */ 448 449 /* 450 * if the parity is not preserved, flip it 451 */ 452 if (!pflag) { 453 for (i = 0; i < 8; i++) { 454 par = 0; 455 for (j = 1; j < 8; j++) 456 if ((bits[j]&UCHAR(buf, i)) != 0) 457 par++; 458 if ((par&01) == 01) 459 UCHAR(buf, i) = UCHAR(buf, i)&0177; 460 else 461 UCHAR(buf, i) = (UCHAR(buf, i)&0177)|0200; 462 } 463 } 464 /* 465 * Make the key schedule 466 */ 467 DES_KEY(UBUFFER(buf)); 468 } 469 470 /* 471 * This encrypts using the Electronic Code Book mode of DES 472 */ 473 ecbenc() 474 { 475 register int n; /* number of bytes actually read */ 476 register int bn; /* block number */ 477 Desbuf msgbuf; /* I/O buffer */ 478 479 for (bn = 0; (n = READ(BUFFER(msgbuf), 8)) == 8; bn++) { 480 /* 481 * do the transformation 482 */ 483 DES_XFORM(UBUFFER(msgbuf)); 484 WRITE(BUFFER(msgbuf), 8); 485 } 486 /* 487 * at EOF or last block -- in either ase, the last byte contains 488 * the character representation of the number of bytes in it 489 */ 490 bn++; 491 MEMZERO(&CHAR(msgbuf, n), 8 - n); 492 CHAR(msgbuf, 7) = n; 493 DES_XFORM(UBUFFER(msgbuf)); 494 WRITE(BUFFER(msgbuf), 8); 495 496 } 497 498 /* 499 * This decrypts using the Electronic Code Book mode of DES 500 */ 501 ecbdec() 502 { 503 register int n; /* number of bytes actually read */ 504 register int c; /* used to test for EOF */ 505 register int bn; /* block number */ 506 Desbuf msgbuf; /* I/O buffer */ 507 508 for (bn = 1; (n = READ(BUFFER(msgbuf), 8)) == 8; bn++) { 509 /* 510 * do the transformation 511 */ 512 DES_XFORM(UBUFFER(msgbuf)); 513 /* 514 * if the last one, handle it specially 515 */ 516 if ((c = getchar()) == EOF) { 517 n = CHAR(msgbuf, 7); 518 if (n < 0 || n > 7) 519 err(bn, "decryption failed (block corrupted)"); 520 } 521 else 522 (void)ungetc(c, stdin); 523 WRITE(BUFFER(msgbuf), n); 524 } 525 if (n > 0) 526 err(bn, "decryption failed (incomplete block)"); 527 } 528 529 /* 530 * This encrypts using the Cipher Block Chaining mode of DES 531 */ 532 cbcenc() 533 { 534 register int n; /* number of bytes actually read */ 535 register int bn; /* block number */ 536 Desbuf msgbuf; /* I/O buffer */ 537 538 /* 539 * do the transformation 540 */ 541 for (bn = 1; (n = READ(BUFFER(msgbuf), 8)) == 8; bn++) { 542 for (n = 0; n < 8; n++) 543 CHAR(msgbuf, n) ^= CHAR(ivec, n); 544 DES_XFORM(UBUFFER(msgbuf)); 545 MEMCPY(BUFFER(ivec), BUFFER(msgbuf), 8); 546 WRITE(BUFFER(msgbuf), 8); 547 } 548 /* 549 * at EOF or last block -- in either case, the last byte contains 550 * the character representation of the number of bytes in it 551 */ 552 bn++; 553 MEMZERO(&CHAR(msgbuf, n), 8 - n); 554 CHAR(msgbuf, 7) = n; 555 for (n = 0; n < 8; n++) 556 CHAR(msgbuf, n) ^= CHAR(ivec, n); 557 DES_XFORM(UBUFFER(msgbuf)); 558 WRITE(BUFFER(msgbuf), 8); 559 560 } 561 562 /* 563 * This decrypts using the Cipher Block Chaining mode of DES 564 */ 565 cbcdec() 566 { 567 register int n; /* number of bytes actually read */ 568 Desbuf msgbuf; /* I/O buffer */ 569 Desbuf ibuf; /* temp buffer for initialization vector */ 570 register int c; /* used to test for EOF */ 571 register int bn; /* block number */ 572 573 for (bn = 0; (n = READ(BUFFER(msgbuf), 8)) == 8; bn++) { 574 /* 575 * do the transformation 576 */ 577 MEMCPY(BUFFER(ibuf), BUFFER(msgbuf), 8); 578 DES_XFORM(UBUFFER(msgbuf)); 579 for (c = 0; c < 8; c++) 580 UCHAR(msgbuf, c) ^= UCHAR(ivec, c); 581 MEMCPY(BUFFER(ivec), BUFFER(ibuf), 8); 582 /* 583 * if the last one, handle it specially 584 */ 585 if ((c = getchar()) == EOF) { 586 n = CHAR(msgbuf, 7); 587 if (n < 0 || n > 7) 588 err(bn, "decryption failed (block corrupted)"); 589 } 590 else 591 (void)ungetc(c, stdin); 592 WRITE(BUFFER(msgbuf), n); 593 } 594 if (n > 0) 595 err(bn, "decryption failed (incomplete block)"); 596 } 597 598 /* 599 * This authenticates using the Cipher Block Chaining mode of DES 600 */ 601 cbcauth() 602 { 603 register int n, j; /* number of bytes actually read */ 604 Desbuf msgbuf; /* I/O buffer */ 605 Desbuf encbuf; /* encryption buffer */ 606 607 /* 608 * do the transformation 609 * note we DISCARD the encrypted block; 610 * we only care about the last one 611 */ 612 while ((n = READ(BUFFER(msgbuf), 8)) == 8) { 613 for (n = 0; n < 8; n++) 614 CHAR(encbuf, n) = CHAR(msgbuf, n) ^ CHAR(ivec, n); 615 DES_XFORM(UBUFFER(encbuf)); 616 MEMCPY(BUFFER(ivec), BUFFER(encbuf), 8); 617 } 618 /* 619 * now compute the last one, right padding with '\0' if need be 620 */ 621 if (n > 0) { 622 MEMZERO(&CHAR(msgbuf, n), 8 - n); 623 for (n = 0; n < 8; n++) 624 CHAR(encbuf, n) = CHAR(msgbuf, n) ^ CHAR(ivec, n); 625 DES_XFORM(UBUFFER(encbuf)); 626 } 627 /* 628 * drop the bits 629 * we write chars until fewer than 7 bits, 630 * and then pad the last one with 0 bits 631 */ 632 for (n = 0; macbits > 7; n++, macbits -= 8) 633 (void)putchar(CHAR(encbuf, n)); 634 if (macbits > 0) { 635 CHAR(msgbuf, 0) = 0x00; 636 for (j = 0; j < macbits; j++) 637 CHAR(msgbuf, 0) |= (CHAR(encbuf, n)&bits[j]); 638 (void)putchar(CHAR(msgbuf, 0)); 639 } 640 } 641 642 /* 643 * This encrypts using the Cipher FeedBack mode of DES 644 */ 645 cfbenc() 646 { 647 register int n; /* number of bytes actually read */ 648 register int nbytes; /* number of bytes to read */ 649 register int bn; /* block number */ 650 char ibuf[8]; /* input buffer */ 651 Desbuf msgbuf; /* encryption buffer */ 652 653 /* 654 * do things in bytes, not bits 655 */ 656 nbytes = fbbits / 8; 657 /* 658 * do the transformation 659 */ 660 for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) { 661 MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8); 662 DES_XFORM(UBUFFER(msgbuf)); 663 for (n = 0; n < 8 - nbytes; n++) 664 UCHAR(ivec, n) = UCHAR(ivec, n+nbytes); 665 for (n = 0; n < nbytes; n++) 666 UCHAR(ivec, 8-nbytes+n) = ibuf[n] ^ UCHAR(msgbuf, n); 667 WRITE(&CHAR(ivec, 8-nbytes), nbytes); 668 } 669 /* 670 * at EOF or last block -- in either case, the last byte contains 671 * the character representation of the number of bytes in it 672 */ 673 bn++; 674 MEMZERO(&ibuf[n], nbytes - n); 675 ibuf[nbytes - 1] = n; 676 MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8); 677 DES_XFORM(UBUFFER(msgbuf)); 678 for (n = 0; n < nbytes; n++) 679 ibuf[n] ^= UCHAR(msgbuf, n); 680 WRITE(ibuf, nbytes); 681 } 682 683 /* 684 * This decrypts using the Cipher Block Chaining mode of DES 685 */ 686 cfbdec() 687 { 688 register int n; /* number of bytes actually read */ 689 register int c; /* used to test for EOF */ 690 register int nbytes; /* number of bytes to read */ 691 register int bn; /* block number */ 692 char ibuf[8]; /* input buffer */ 693 char obuf[8]; /* output buffer */ 694 Desbuf msgbuf; /* encryption buffer */ 695 696 /* 697 * do things in bytes, not bits 698 */ 699 nbytes = fbbits / 8; 700 /* 701 * do the transformation 702 */ 703 for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) { 704 MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8); 705 DES_XFORM(UBUFFER(msgbuf)); 706 for (c = 0; c < 8 - nbytes; c++) 707 CHAR(ivec, c) = CHAR(ivec, c+nbytes); 708 for (c = 0; c < nbytes; c++) { 709 CHAR(ivec, 8-nbytes+c) = ibuf[c]; 710 obuf[c] = ibuf[c] ^ UCHAR(msgbuf, c); 711 } 712 /* 713 * if the last one, handle it specially 714 */ 715 if ((c = getchar()) == EOF) { 716 n = obuf[nbytes-1]; 717 if (n < 0 || n > nbytes-1) 718 err(bn, "decryption failed (block corrupted)"); 719 } 720 else 721 (void)ungetc(c, stdin); 722 WRITE(obuf, n); 723 } 724 if (n > 0) 725 err(bn, "decryption failed (incomplete block)"); 726 } 727 728 /* 729 * This encrypts using the alternative Cipher FeedBack mode of DES 730 */ 731 cfbaenc() 732 { 733 register int n; /* number of bytes actually read */ 734 register int nbytes; /* number of bytes to read */ 735 register int bn; /* block number */ 736 char ibuf[8]; /* input buffer */ 737 char obuf[8]; /* output buffer */ 738 Desbuf msgbuf; /* encryption buffer */ 739 740 /* 741 * do things in bytes, not bits 742 */ 743 nbytes = fbbits / 7; 744 /* 745 * do the transformation 746 */ 747 for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) { 748 MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8); 749 DES_XFORM(UBUFFER(msgbuf)); 750 for (n = 0; n < 8 - nbytes; n++) 751 UCHAR(ivec, n) = UCHAR(ivec, n+nbytes); 752 for (n = 0; n < nbytes; n++) 753 UCHAR(ivec, 8-nbytes+n) = (ibuf[n] ^ UCHAR(msgbuf, n)) 754 |0200; 755 for (n = 0; n < nbytes; n++) 756 obuf[n] = CHAR(ivec, 8-nbytes+n)&0177; 757 WRITE(obuf, nbytes); 758 } 759 /* 760 * at EOF or last block -- in either case, the last byte contains 761 * the character representation of the number of bytes in it 762 */ 763 bn++; 764 MEMZERO(&ibuf[n], nbytes - n); 765 ibuf[nbytes - 1] = ('0' + n)|0200; 766 MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8); 767 DES_XFORM(UBUFFER(msgbuf)); 768 for (n = 0; n < nbytes; n++) 769 ibuf[n] ^= UCHAR(msgbuf, n); 770 WRITE(ibuf, nbytes); 771 } 772 773 /* 774 * This decrypts using the alternative Cipher Block Chaining mode of DES 775 */ 776 cfbadec() 777 { 778 register int n; /* number of bytes actually read */ 779 register int c; /* used to test for EOF */ 780 register int nbytes; /* number of bytes to read */ 781 register int bn; /* block number */ 782 char ibuf[8]; /* input buffer */ 783 char obuf[8]; /* output buffer */ 784 Desbuf msgbuf; /* encryption buffer */ 785 786 /* 787 * do things in bytes, not bits 788 */ 789 nbytes = fbbits / 7; 790 /* 791 * do the transformation 792 */ 793 for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) { 794 MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8); 795 DES_XFORM(UBUFFER(msgbuf)); 796 for (c = 0; c < 8 - nbytes; c++) 797 CHAR(ivec, c) = CHAR(ivec, c+nbytes); 798 for (c = 0; c < nbytes; c++) { 799 CHAR(ivec, 8-nbytes+c) = ibuf[c]|0200; 800 obuf[c] = (ibuf[c] ^ UCHAR(msgbuf, c))&0177; 801 } 802 /* 803 * if the last one, handle it specially 804 */ 805 if ((c = getchar()) == EOF) { 806 if ((n = (obuf[nbytes-1] - '0')) < 0 807 || n > nbytes-1) 808 err(bn, "decryption failed (block corrupted)"); 809 } 810 else 811 (void)ungetc(c, stdin); 812 WRITE(obuf, n); 813 } 814 if (n > 0) 815 err(bn, "decryption failed (incomplete block)"); 816 } 817 818 819 /* 820 * This encrypts using the Output FeedBack mode of DES 821 */ 822 ofbenc() 823 { 824 register int n; /* number of bytes actually read */ 825 register int c; /* used to test for EOF */ 826 register int nbytes; /* number of bytes to read */ 827 register int bn; /* block number */ 828 char ibuf[8]; /* input buffer */ 829 char obuf[8]; /* output buffer */ 830 Desbuf msgbuf; /* encryption buffer */ 831 832 /* 833 * do things in bytes, not bits 834 */ 835 nbytes = fbbits / 8; 836 /* 837 * do the transformation 838 */ 839 for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) { 840 MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8); 841 DES_XFORM(UBUFFER(msgbuf)); 842 for (n = 0; n < 8 - nbytes; n++) 843 UCHAR(ivec, n) = UCHAR(ivec, n+nbytes); 844 for (n = 0; n < nbytes; n++) { 845 UCHAR(ivec, 8-nbytes+n) = UCHAR(msgbuf, n); 846 obuf[n] = ibuf[n] ^ UCHAR(msgbuf, n); 847 } 848 WRITE(obuf, nbytes); 849 } 850 /* 851 * at EOF or last block -- in either case, the last byte contains 852 * the character representation of the number of bytes in it 853 */ 854 bn++; 855 MEMZERO(&ibuf[n], nbytes - n); 856 ibuf[nbytes - 1] = n; 857 MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8); 858 DES_XFORM(UBUFFER(msgbuf)); 859 for (c = 0; c < nbytes; c++) 860 ibuf[c] ^= UCHAR(msgbuf, c); 861 WRITE(ibuf, nbytes); 862 } 863 864 /* 865 * This decrypts using the Output Block Chaining mode of DES 866 */ 867 ofbdec() 868 { 869 register int n; /* number of bytes actually read */ 870 register int c; /* used to test for EOF */ 871 register int nbytes; /* number of bytes to read */ 872 register int bn; /* block number */ 873 char ibuf[8]; /* input buffer */ 874 char obuf[8]; /* output buffer */ 875 Desbuf msgbuf; /* encryption buffer */ 876 877 /* 878 * do things in bytes, not bits 879 */ 880 nbytes = fbbits / 8; 881 /* 882 * do the transformation 883 */ 884 for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) { 885 MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8); 886 DES_XFORM(UBUFFER(msgbuf)); 887 for (c = 0; c < 8 - nbytes; c++) 888 CHAR(ivec, c) = CHAR(ivec, c+nbytes); 889 for (c = 0; c < nbytes; c++) { 890 CHAR(ivec, 8-nbytes+c) = UCHAR(msgbuf, c); 891 obuf[c] = ibuf[c] ^ UCHAR(msgbuf, c); 892 } 893 /* 894 * if the last one, handle it specially 895 */ 896 if ((c = getchar()) == EOF) { 897 n = obuf[nbytes-1]; 898 if (n < 0 || n > nbytes-1) 899 err(bn, "decryption failed (block corrupted)"); 900 } 901 else 902 (void)ungetc(c, stdin); 903 /* 904 * dump it 905 */ 906 WRITE(obuf, n); 907 } 908 if (n > 0) 909 err(bn, "decryption failed (incomplete block)"); 910 } 911 912 /* 913 * This authenticates using the Cipher FeedBack mode of DES 914 */ 915 cfbauth() 916 { 917 register int n, j; /* number of bytes actually read */ 918 register int nbytes; /* number of bytes to read */ 919 char ibuf[8]; /* input buffer */ 920 Desbuf msgbuf; /* encryption buffer */ 921 922 /* 923 * do things in bytes, not bits 924 */ 925 nbytes = fbbits / 8; 926 /* 927 * do the transformation 928 */ 929 while ((n = READ(ibuf, nbytes)) == nbytes) { 930 MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8); 931 DES_XFORM(UBUFFER(msgbuf)); 932 for (n = 0; n < 8 - nbytes; n++) 933 UCHAR(ivec, n) = UCHAR(ivec, n+nbytes); 934 for (n = 0; n < nbytes; n++) 935 UCHAR(ivec, 8-nbytes+n) = ibuf[n] ^ UCHAR(msgbuf, n); 936 } 937 /* 938 * at EOF or last block -- in either case, the last byte contains 939 * the character representation of the number of bytes in it 940 */ 941 MEMZERO(&ibuf[n], nbytes - n); 942 ibuf[nbytes - 1] = '0' + n; 943 MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8); 944 DES_XFORM(UBUFFER(msgbuf)); 945 for (n = 0; n < nbytes; n++) 946 ibuf[n] ^= UCHAR(msgbuf, n); 947 /* 948 * drop the bits 949 * we write chars until fewer than 7 bits, 950 * and then pad the last one with 0 bits 951 */ 952 for (n = 0; macbits > 7; n++, macbits -= 8) 953 (void)putchar(CHAR(msgbuf, n)); 954 if (macbits > 0) { 955 CHAR(msgbuf, 0) = 0x00; 956 for (j = 0; j < macbits; j++) 957 CHAR(msgbuf, 0) |= (CHAR(msgbuf, n)&bits[j]); 958 (void)putchar(CHAR(msgbuf, 0)); 959 } 960 } 961 962 /* 963 * change from 8 bits/Uchar to 1 bit/Uchar 964 */ 965 expand(from, to) 966 Desbuf from; /* 8bit/unsigned char string */ 967 char to[64]; /* 1bit/char string */ 968 { 969 register int i, j; /* counters in for loop */ 970 971 for (i = 0; i < 8; i++) 972 for (j = 0; j < 8; j++) 973 to[i*8+j] = (CHAR(from, i)>>(7-j))&01; 974 } 975 976 /* 977 * change from 1 bit/char to 8 bits/Uchar 978 */ 979 compress(from, to) 980 char from[64]; /* 1bit/char string */ 981 Desbuf to; /* 8bit/unsigned char string */ 982 { 983 register int i, j; /* counters in for loop */ 984 985 for (i = 0; i < 8; i++) { 986 CHAR(to, i) = 0; 987 for (j = 0; j < 8; j++) 988 CHAR(to, i) = (from[i*8+j]<<(7-j))|CHAR(to, i); 989 } 990 } 991 992 usage() 993 { 994 (void)fprintf(stderr, 995 "usage: bdes [-aceip] [-F bit] [-f bit] [-m bit] [-o bit] [-v vector] [key]\n"); 996 exit(1); 997 } 998