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