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