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