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