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