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