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