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