xref: /minix3/usr.bin/bdes/bdes.c (revision 84d9c625bfea59e274550651111ae9edfdc40fbd)
1*84d9c625SLionel Sambuc /*	$NetBSD: bdes.c,v 1.9 2013/08/15 20:48:56 joerg Exp $	*/
292f7a4abSThomas Cort 
392f7a4abSThomas Cort /*-
492f7a4abSThomas Cort  * Copyright (c) 1991, 1993
592f7a4abSThomas Cort  *	The Regents of the University of California.  All rights reserved.
692f7a4abSThomas Cort  *
792f7a4abSThomas Cort  * This code is derived from software contributed to Berkeley by
892f7a4abSThomas Cort  * Matt Bishop of Dartmouth College.
992f7a4abSThomas Cort  *
1092f7a4abSThomas Cort  * The United States Government has rights in this work pursuant
1192f7a4abSThomas Cort  * to contract no. NAG 2-680 between the National Aeronautics and
1292f7a4abSThomas Cort  * Space Administration and Dartmouth College.
1392f7a4abSThomas Cort  *
1492f7a4abSThomas Cort  * Redistribution and use in source and binary forms, with or without
1592f7a4abSThomas Cort  * modification, are permitted provided that the following conditions
1692f7a4abSThomas Cort  * are met:
1792f7a4abSThomas Cort  * 1. Redistributions of source code must retain the above copyright
1892f7a4abSThomas Cort  *    notice, this list of conditions and the following disclaimer.
1992f7a4abSThomas Cort  * 2. Redistributions in binary form must reproduce the above copyright
2092f7a4abSThomas Cort  *    notice, this list of conditions and the following disclaimer in the
2192f7a4abSThomas Cort  *    documentation and/or other materials provided with the distribution.
2292f7a4abSThomas Cort  * 3. Neither the name of the University nor the names of its contributors
2392f7a4abSThomas Cort  *    may be used to endorse or promote products derived from this software
2492f7a4abSThomas Cort  *    without specific prior written permission.
2592f7a4abSThomas Cort  *
2692f7a4abSThomas Cort  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2792f7a4abSThomas Cort  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2892f7a4abSThomas Cort  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2992f7a4abSThomas Cort  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
3092f7a4abSThomas Cort  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3192f7a4abSThomas Cort  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3292f7a4abSThomas Cort  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3392f7a4abSThomas Cort  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3492f7a4abSThomas Cort  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3592f7a4abSThomas Cort  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3692f7a4abSThomas Cort  * SUCH DAMAGE.
3792f7a4abSThomas Cort  */
3892f7a4abSThomas Cort 
3992f7a4abSThomas Cort #include <sys/cdefs.h>
4092f7a4abSThomas Cort #ifndef lint
4192f7a4abSThomas Cort __COPYRIGHT("@(#) Copyright (c) 1991, 1993\
4292f7a4abSThomas Cort  The Regents of the University of California.  All rights reserved.");
4392f7a4abSThomas Cort #endif /* not lint */
4492f7a4abSThomas Cort 
4592f7a4abSThomas Cort #ifndef lint
4692f7a4abSThomas Cort #if 0
4792f7a4abSThomas Cort static char sccsid[] = "@(#)bdes.c	8.1 (Berkeley) 6/6/93";
4892f7a4abSThomas Cort #else
49*84d9c625SLionel Sambuc __RCSID("$NetBSD: bdes.c,v 1.9 2013/08/15 20:48:56 joerg Exp $");
5092f7a4abSThomas Cort #endif
5192f7a4abSThomas Cort #endif /* not lint */
5292f7a4abSThomas Cort 
5392f7a4abSThomas Cort /*
5492f7a4abSThomas Cort  * BDES -- DES encryption package for Berkeley Software Distribution 4.4
5592f7a4abSThomas Cort  * options:
5692f7a4abSThomas Cort  *	-a	key is in ASCII
5792f7a4abSThomas Cort  *	-b	use ECB (electronic code book) mode
5892f7a4abSThomas Cort  *	-d	invert (decrypt) input
5992f7a4abSThomas Cort  *	-f b	use b-bit CFB (cipher feedback) mode
6092f7a4abSThomas Cort  *	-F b	use b-bit CFB (cipher feedback) alternative mode
6192f7a4abSThomas Cort  *	-k key	use key as the cryptographic key
6292f7a4abSThomas Cort  *	-m b	generate a MAC of length b
6392f7a4abSThomas Cort  *	-o b	use b-bit OFB (output feedback) mode
6492f7a4abSThomas Cort  *	-p	don't reset the parity bit
6592f7a4abSThomas Cort  *	-v v	use v as the initialization vector (ignored for ECB)
6692f7a4abSThomas Cort  * note: the last character of the last block is the integer indicating
6792f7a4abSThomas Cort  * how many characters of that block are to be output
6892f7a4abSThomas Cort  *
6992f7a4abSThomas Cort  * Author: Matt Bishop
7092f7a4abSThomas Cort  *	   Department of Mathematics and Computer Science
7192f7a4abSThomas Cort  *	   Dartmouth College
7292f7a4abSThomas Cort  *	   Hanover, NH  03755
7392f7a4abSThomas Cort  * Email:  Matt.Bishop@dartmouth.edu
7492f7a4abSThomas Cort  *	   ...!decvax!dartvax!Matt.Bishop
7592f7a4abSThomas Cort  *
7692f7a4abSThomas Cort  * See Technical Report PCS-TR91-158, Department of Mathematics and Computer
7792f7a4abSThomas Cort  * Science, Dartmouth College, for a detailed description of the implemen-
7892f7a4abSThomas Cort  * tation and differences between it and Sun's.  The DES is described in
7992f7a4abSThomas Cort  * FIPS PUB 46, and the modes in FIPS PUB 81 (see either the manual page
8092f7a4abSThomas Cort  * or the technical report for a complete reference).
8192f7a4abSThomas Cort  */
8292f7a4abSThomas Cort 
8392f7a4abSThomas Cort #include <errno.h>
8492f7a4abSThomas Cort #include <unistd.h>
8592f7a4abSThomas Cort #include <stdio.h>
8692f7a4abSThomas Cort #include <ctype.h>
8792f7a4abSThomas Cort #include <stdlib.h>
8892f7a4abSThomas Cort #include <string.h>
8992f7a4abSThomas Cort 
9092f7a4abSThomas Cort /*
9192f7a4abSThomas Cort  * BSD and System V systems offer special library calls that do
9292f7a4abSThomas Cort  * block moves and fills, so if possible we take advantage of them
9392f7a4abSThomas Cort  */
9492f7a4abSThomas Cort #define	MEMCPY(dest,src,len)	bcopy((src),(dest),(len))
9592f7a4abSThomas Cort #define	MEMZERO(dest,len)	bzero((dest),(len))
9692f7a4abSThomas Cort 
9792f7a4abSThomas Cort /* Hide the calls to the primitive encryption routines. */
9892f7a4abSThomas Cort #define	FASTWAY
9992f7a4abSThomas Cort #ifdef	FASTWAY
10092f7a4abSThomas Cort #define	DES_KEY(buf) \
10192f7a4abSThomas Cort 	if (des_setkey(buf)) \
10292f7a4abSThomas Cort 		bdes_err(0, "des_setkey");
10392f7a4abSThomas Cort #define	DES_XFORM(buf) \
10492f7a4abSThomas Cort 	if (des_cipher(buf, buf, 0L, (inverse ? -1 : 1))) \
10592f7a4abSThomas Cort 		bdes_err(0, "des_cipher");
10692f7a4abSThomas Cort #else
10792f7a4abSThomas Cort #define	DES_KEY(buf)	{						\
10892f7a4abSThomas Cort 				char bits1[64];	/* bits of key */	\
10992f7a4abSThomas Cort 				expand(buf, bits1);			\
11092f7a4abSThomas Cort 				if (setkey(bits1))			\
11192f7a4abSThomas Cort 					bdes_err(0, "setkey");		\
11292f7a4abSThomas Cort 			}
11392f7a4abSThomas Cort #define	DES_XFORM(buf)	{						\
11492f7a4abSThomas Cort 				char bits1[64];	/* bits of message */	\
11592f7a4abSThomas Cort 				expand(buf, bits1);			\
11692f7a4abSThomas Cort 				if (encrypt(bits1, inverse))		\
11792f7a4abSThomas Cort 					bdes_err(0, "encrypt");		\
11892f7a4abSThomas Cort 				compress(bits1, buf);			\
11992f7a4abSThomas Cort 			}
12092f7a4abSThomas Cort #endif
12192f7a4abSThomas Cort 
12292f7a4abSThomas Cort /*
12392f7a4abSThomas Cort  * this does an error-checking write
12492f7a4abSThomas Cort  */
12592f7a4abSThomas Cort #define	READ(buf, n)	fread(buf, sizeof(char), n, stdin)
12692f7a4abSThomas Cort #define WRITE(buf,n)						\
12792f7a4abSThomas Cort 		if (fwrite(buf, sizeof(char), n, stdout) != (size_t)n)	\
12892f7a4abSThomas Cort 			bdes_err(bn, NULL);
12992f7a4abSThomas Cort 
13092f7a4abSThomas Cort /*
13192f7a4abSThomas Cort  * some things to make references easier
13292f7a4abSThomas Cort  */
13392f7a4abSThomas Cort typedef char Desbuf[8];
13492f7a4abSThomas Cort #define	CHAR(x,i)	(x[i])
13592f7a4abSThomas Cort #define	UCHAR(x,i)	(x[i])
13692f7a4abSThomas Cort #define	BUFFER(x)	(x)
13792f7a4abSThomas Cort #define	UBUFFER(x)	(x)
13892f7a4abSThomas Cort 
13992f7a4abSThomas Cort /*
14092f7a4abSThomas Cort  * global variables and related macros
14192f7a4abSThomas Cort  */
14292f7a4abSThomas Cort #define KEY_DEFAULT		0	/* interpret radix of key from key */
14392f7a4abSThomas Cort #define KEY_ASCII		1	/* key is in ASCII characters */
144*84d9c625SLionel Sambuc static int keybase = KEY_DEFAULT;	/* how to interpret the key */
14592f7a4abSThomas Cort 
146*84d9c625SLionel Sambuc static enum { 				/* encrypt, decrypt, authenticate */
14792f7a4abSThomas Cort 	MODE_ENCRYPT, MODE_DECRYPT, MODE_AUTHENTICATE
14892f7a4abSThomas Cort } mode = MODE_ENCRYPT;
149*84d9c625SLionel Sambuc static enum {				/* ecb, cbc, cfb, cfba, ofb? */
15092f7a4abSThomas Cort 	ALG_ECB, ALG_CBC, ALG_CFB, ALG_OFB, ALG_CFBA
15192f7a4abSThomas Cort } alg = ALG_CBC;
15292f7a4abSThomas Cort 
153*84d9c625SLionel Sambuc static Desbuf ivec;				/* initialization vector */
154*84d9c625SLionel Sambuc static const char bits[] = {				/* used to extract bits from a char */
15592f7a4abSThomas Cort 	'\200', '\100', '\040', '\020', '\010', '\004', '\002', '\001'
15692f7a4abSThomas Cort };
157*84d9c625SLionel Sambuc static int inverse;				/* 0 to encrypt, 1 to decrypt */
158*84d9c625SLionel Sambuc static int macbits = -1;			/* number of bits in authentication */
159*84d9c625SLionel Sambuc static int fbbits = -1;			/* number of feedback bits */
160*84d9c625SLionel Sambuc static int pflag;				/* 1 to preserve parity bits */
16192f7a4abSThomas Cort 
162*84d9c625SLionel Sambuc static int	setbits(char *, int);
163*84d9c625SLionel Sambuc static void	bdes_err(int, const char *) __dead;
164*84d9c625SLionel Sambuc static int	tobinhex(char, int);
165*84d9c625SLionel Sambuc static void	cvtkey(char *, char *);
166*84d9c625SLionel Sambuc static void	makekey(Desbuf);
167*84d9c625SLionel Sambuc static void	ecbenc(void);
168*84d9c625SLionel Sambuc static void	ecbdec(void);
169*84d9c625SLionel Sambuc static void	cbcenc(void);
170*84d9c625SLionel Sambuc static void	cbcdec(void);
171*84d9c625SLionel Sambuc static void	cbcauth(void);
172*84d9c625SLionel Sambuc static void	cfbenc(void);
173*84d9c625SLionel Sambuc static void	cfbdec(void);
174*84d9c625SLionel Sambuc static void	cfbaenc(void);
175*84d9c625SLionel Sambuc static void	cfbadec(void);
176*84d9c625SLionel Sambuc static void	ofbenc(void);
177*84d9c625SLionel Sambuc static void	ofbdec(void);
178*84d9c625SLionel Sambuc static void	cfbauth(void);
179*84d9c625SLionel Sambuc #ifndef FASTWAY
180*84d9c625SLionel Sambuc static void	expand(Desbuf, char *);
181*84d9c625SLionel Sambuc static void	compress(char *, Desbuf);
182*84d9c625SLionel Sambuc #endif
183*84d9c625SLionel Sambuc static void	usage(void) __dead;
18492f7a4abSThomas Cort 
18592f7a4abSThomas Cort int
main(int ac,char * av[])18692f7a4abSThomas Cort main(int ac, char *av[])
18792f7a4abSThomas Cort {
18892f7a4abSThomas Cort 	register int i;			/* counter in a for loop */
18992f7a4abSThomas Cort 	register char *p;		/* used to obtain the key */
19092f7a4abSThomas Cort 	Desbuf msgbuf;			/* I/O buffer */
19192f7a4abSThomas Cort 	int kflag;			/* command-line encryptiooon key */
19292f7a4abSThomas Cort 	int argc;			/* the real arg count */
19392f7a4abSThomas Cort 	char **argv;			/* the real argument vector */
19492f7a4abSThomas Cort 
19592f7a4abSThomas Cort 	/*
19692f7a4abSThomas Cort 	 * Hide the arguments from ps(1) by making private copies of them
19792f7a4abSThomas Cort 	 * and clobbering the global (visible to ps(1)) ones.
19892f7a4abSThomas Cort 	 */
19992f7a4abSThomas Cort 	argc = ac;
20092f7a4abSThomas Cort 	ac = 1;
20192f7a4abSThomas Cort 	argv = malloc((argc + 1) * sizeof(char *));
20292f7a4abSThomas Cort 	for (i = 0; i < argc; ++i) {
20392f7a4abSThomas Cort 		argv[i] = strdup(av[i]);
20492f7a4abSThomas Cort 		MEMZERO(av[i], strlen(av[i]));
20592f7a4abSThomas Cort 	}
20692f7a4abSThomas Cort 	argv[argc] = NULL;
20792f7a4abSThomas Cort 
20892f7a4abSThomas Cort 	/* initialize the initialization vctor */
20992f7a4abSThomas Cort 	MEMZERO(ivec, 8);
21092f7a4abSThomas Cort 
21192f7a4abSThomas Cort 	/* process the argument list */
21292f7a4abSThomas Cort 	kflag = 0;
21392f7a4abSThomas Cort 	while ((i = getopt(argc, argv, "abdF:f:k:m:o:pv:")) != -1)
21492f7a4abSThomas Cort 		switch(i) {
21592f7a4abSThomas Cort 		case 'a':		/* key is ASCII */
21692f7a4abSThomas Cort 			keybase = KEY_ASCII;
21792f7a4abSThomas Cort 			break;
21892f7a4abSThomas Cort 		case 'b':		/* use ECB mode */
21992f7a4abSThomas Cort 			alg = ALG_ECB;
22092f7a4abSThomas Cort 			break;
22192f7a4abSThomas Cort 		case 'd':		/* decrypt */
22292f7a4abSThomas Cort 			mode = MODE_DECRYPT;
22392f7a4abSThomas Cort 			break;
22492f7a4abSThomas Cort 		case 'F':		/* use alternative CFB mode */
22592f7a4abSThomas Cort 			alg = ALG_CFBA;
22692f7a4abSThomas Cort 			if ((fbbits = setbits(optarg, 7)) > 56 || fbbits == 0)
22792f7a4abSThomas Cort 				bdes_err(-1,
22892f7a4abSThomas Cort 				    "-F: number must be 1-56 inclusive");
22992f7a4abSThomas Cort 			else if (fbbits == -1)
23092f7a4abSThomas Cort 				bdes_err(-1,
23192f7a4abSThomas Cort 				    "-F: number must be a multiple of 7");
23292f7a4abSThomas Cort 			break;
23392f7a4abSThomas Cort 		case 'f':		/* use CFB mode */
23492f7a4abSThomas Cort 			alg = ALG_CFB;
23592f7a4abSThomas Cort 			if ((fbbits = setbits(optarg, 8)) > 64 || fbbits == 0)
23692f7a4abSThomas Cort 				bdes_err(-1,
23792f7a4abSThomas Cort 				    "-f: number must be 1-64 inclusive");
23892f7a4abSThomas Cort 			else if (fbbits == -1)
23992f7a4abSThomas Cort 				bdes_err(-1,
24092f7a4abSThomas Cort 				    "-f: number must be a multiple of 8");
24192f7a4abSThomas Cort 			break;
24292f7a4abSThomas Cort 		case 'k':		/* encryption key */
24392f7a4abSThomas Cort 			kflag = 1;
24492f7a4abSThomas Cort 			cvtkey(BUFFER(msgbuf), optarg);
24592f7a4abSThomas Cort 			break;
24692f7a4abSThomas Cort 		case 'm':		/* number of bits for MACing */
24792f7a4abSThomas Cort 			mode = MODE_AUTHENTICATE;
24892f7a4abSThomas Cort 			if ((macbits = setbits(optarg, 1)) > 64)
24992f7a4abSThomas Cort 				bdes_err(-1,
25092f7a4abSThomas Cort 				    "-m: number must be 0-64 inclusive");
25192f7a4abSThomas Cort 			break;
25292f7a4abSThomas Cort 		case 'o':		/* use OFB mode */
25392f7a4abSThomas Cort 			alg = ALG_OFB;
25492f7a4abSThomas Cort 			if ((fbbits = setbits(optarg, 8)) > 64 || fbbits == 0)
25592f7a4abSThomas Cort 				bdes_err(-1,
25692f7a4abSThomas Cort 				    "-o: number must be 1-64 inclusive");
25792f7a4abSThomas Cort 			else if (fbbits == -1)
25892f7a4abSThomas Cort 				bdes_err(-1,
25992f7a4abSThomas Cort 				    "-o: number must be a multiple of 8");
26092f7a4abSThomas Cort 			break;
26192f7a4abSThomas Cort 		case 'p':		/* preserve parity bits */
26292f7a4abSThomas Cort 			pflag = 1;
26392f7a4abSThomas Cort 			break;
26492f7a4abSThomas Cort 		case 'v':		/* set initialization vector */
26592f7a4abSThomas Cort 			cvtkey(BUFFER(ivec), optarg);
26692f7a4abSThomas Cort 			break;
26792f7a4abSThomas Cort 		default:		/* error */
26892f7a4abSThomas Cort 			usage();
26992f7a4abSThomas Cort 		}
27092f7a4abSThomas Cort 
27192f7a4abSThomas Cort 	if (!kflag) {
27292f7a4abSThomas Cort 		/*
27392f7a4abSThomas Cort 		 * if the key's not ASCII, assume it is
27492f7a4abSThomas Cort 		 */
27592f7a4abSThomas Cort 		keybase = KEY_ASCII;
27692f7a4abSThomas Cort 		/*
27792f7a4abSThomas Cort 		 * get the key
27892f7a4abSThomas Cort 		 */
27992f7a4abSThomas Cort 		p = getpass("Enter key: ");
28092f7a4abSThomas Cort 		/*
28192f7a4abSThomas Cort 		 * copy it, nul-padded, into the key area
28292f7a4abSThomas Cort 		 */
28392f7a4abSThomas Cort 		cvtkey(BUFFER(msgbuf), p);
28492f7a4abSThomas Cort 	}
28592f7a4abSThomas Cort 
28692f7a4abSThomas Cort 	makekey(msgbuf);
28792f7a4abSThomas Cort 	inverse = (alg == ALG_CBC || alg == ALG_ECB) && mode == MODE_DECRYPT;
28892f7a4abSThomas Cort 
28992f7a4abSThomas Cort 	switch(alg) {
29092f7a4abSThomas Cort 	case ALG_CBC:
29192f7a4abSThomas Cort 		switch(mode) {
29292f7a4abSThomas Cort 		case MODE_AUTHENTICATE:	/* authenticate using CBC mode */
29392f7a4abSThomas Cort 			cbcauth();
29492f7a4abSThomas Cort 			break;
29592f7a4abSThomas Cort 		case MODE_DECRYPT:	/* decrypt using CBC mode */
29692f7a4abSThomas Cort 			cbcdec();
29792f7a4abSThomas Cort 			break;
29892f7a4abSThomas Cort 		case MODE_ENCRYPT:	/* encrypt using CBC mode */
29992f7a4abSThomas Cort 			cbcenc();
30092f7a4abSThomas Cort 			break;
30192f7a4abSThomas Cort 		}
30292f7a4abSThomas Cort 		break;
30392f7a4abSThomas Cort 	case ALG_CFB:
30492f7a4abSThomas Cort 		switch(mode) {
30592f7a4abSThomas Cort 		case MODE_AUTHENTICATE:	/* authenticate using CFB mode */
30692f7a4abSThomas Cort 			cfbauth();
30792f7a4abSThomas Cort 			break;
30892f7a4abSThomas Cort 		case MODE_DECRYPT:	/* decrypt using CFB mode */
30992f7a4abSThomas Cort 			cfbdec();
31092f7a4abSThomas Cort 			break;
31192f7a4abSThomas Cort 		case MODE_ENCRYPT:	/* encrypt using CFB mode */
31292f7a4abSThomas Cort 			cfbenc();
31392f7a4abSThomas Cort 			break;
31492f7a4abSThomas Cort 		}
31592f7a4abSThomas Cort 		break;
31692f7a4abSThomas Cort 	case ALG_CFBA:
31792f7a4abSThomas Cort 		switch(mode) {
31892f7a4abSThomas Cort 		case MODE_AUTHENTICATE:	/* authenticate using CFBA mode */
31992f7a4abSThomas Cort 			bdes_err(-1, "can't authenticate with CFBA mode");
32092f7a4abSThomas Cort 			break;
32192f7a4abSThomas Cort 		case MODE_DECRYPT:	/* decrypt using CFBA mode */
32292f7a4abSThomas Cort 			cfbadec();
32392f7a4abSThomas Cort 			break;
32492f7a4abSThomas Cort 		case MODE_ENCRYPT:	/* encrypt using CFBA mode */
32592f7a4abSThomas Cort 			cfbaenc();
32692f7a4abSThomas Cort 			break;
32792f7a4abSThomas Cort 		}
32892f7a4abSThomas Cort 		break;
32992f7a4abSThomas Cort 	case ALG_ECB:
33092f7a4abSThomas Cort 		switch(mode) {
33192f7a4abSThomas Cort 		case MODE_AUTHENTICATE:	/* authenticate using ECB mode */
33292f7a4abSThomas Cort 			bdes_err(-1, "can't authenticate with ECB mode");
33392f7a4abSThomas Cort 			break;
33492f7a4abSThomas Cort 		case MODE_DECRYPT:	/* decrypt using ECB mode */
33592f7a4abSThomas Cort 			ecbdec();
33692f7a4abSThomas Cort 			break;
33792f7a4abSThomas Cort 		case MODE_ENCRYPT:	/* encrypt using ECB mode */
33892f7a4abSThomas Cort 			ecbenc();
33992f7a4abSThomas Cort 			break;
34092f7a4abSThomas Cort 		}
34192f7a4abSThomas Cort 		break;
34292f7a4abSThomas Cort 	case ALG_OFB:
34392f7a4abSThomas Cort 		switch(mode) {
34492f7a4abSThomas Cort 		case MODE_AUTHENTICATE:	/* authenticate using OFB mode */
34592f7a4abSThomas Cort 			bdes_err(-1, "can't authenticate with OFB mode");
34692f7a4abSThomas Cort 			break;
34792f7a4abSThomas Cort 		case MODE_DECRYPT:	/* decrypt using OFB mode */
34892f7a4abSThomas Cort 			ofbdec();
34992f7a4abSThomas Cort 			break;
35092f7a4abSThomas Cort 		case MODE_ENCRYPT:	/* encrypt using OFB mode */
35192f7a4abSThomas Cort 			ofbenc();
35292f7a4abSThomas Cort 			break;
35392f7a4abSThomas Cort 		}
35492f7a4abSThomas Cort 		break;
35592f7a4abSThomas Cort 	}
35692f7a4abSThomas Cort 	exit(0);
35792f7a4abSThomas Cort }
35892f7a4abSThomas Cort 
35992f7a4abSThomas Cort /*
36092f7a4abSThomas Cort  * print a warning message and, possibly, terminate
36192f7a4abSThomas Cort  */
362*84d9c625SLionel Sambuc static void
bdes_err(int n,const char * s)36392f7a4abSThomas Cort bdes_err(int n, const char *s)
36492f7a4abSThomas Cort {
36592f7a4abSThomas Cort 	if (n > 0)
36692f7a4abSThomas Cort 		(void)fprintf(stderr, "bdes (block %d): ", n);
36792f7a4abSThomas Cort 	else
36892f7a4abSThomas Cort 		(void)fprintf(stderr, "bdes: ");
36992f7a4abSThomas Cort 	(void)fprintf(stderr, "%s\n", s ? s : strerror(errno));
37092f7a4abSThomas Cort 	exit(1);
37192f7a4abSThomas Cort }
37292f7a4abSThomas Cort 
37392f7a4abSThomas Cort /*
37492f7a4abSThomas Cort  * map a hex character to an integer
37592f7a4abSThomas Cort  */
376*84d9c625SLionel Sambuc static int
tobinhex(char c,int radix)37792f7a4abSThomas Cort tobinhex(char c, int radix)
37892f7a4abSThomas Cort {
37992f7a4abSThomas Cort 	switch(c) {
38092f7a4abSThomas Cort 	case '0':		return(0x0);
38192f7a4abSThomas Cort 	case '1':		return(0x1);
38292f7a4abSThomas Cort 	case '2':		return(radix > 2 ? 0x2 : -1);
38392f7a4abSThomas Cort 	case '3':		return(radix > 3 ? 0x3 : -1);
38492f7a4abSThomas Cort 	case '4':		return(radix > 4 ? 0x4 : -1);
38592f7a4abSThomas Cort 	case '5':		return(radix > 5 ? 0x5 : -1);
38692f7a4abSThomas Cort 	case '6':		return(radix > 6 ? 0x6 : -1);
38792f7a4abSThomas Cort 	case '7':		return(radix > 7 ? 0x7 : -1);
38892f7a4abSThomas Cort 	case '8':		return(radix > 8 ? 0x8 : -1);
38992f7a4abSThomas Cort 	case '9':		return(radix > 9 ? 0x9 : -1);
39092f7a4abSThomas Cort 	case 'A': case 'a':	return(radix > 10 ? 0xa : -1);
39192f7a4abSThomas Cort 	case 'B': case 'b':	return(radix > 11 ? 0xb : -1);
39292f7a4abSThomas Cort 	case 'C': case 'c':	return(radix > 12 ? 0xc : -1);
39392f7a4abSThomas Cort 	case 'D': case 'd':	return(radix > 13 ? 0xd : -1);
39492f7a4abSThomas Cort 	case 'E': case 'e':	return(radix > 14 ? 0xe : -1);
39592f7a4abSThomas Cort 	case 'F': case 'f':	return(radix > 15 ? 0xf : -1);
39692f7a4abSThomas Cort 	}
39792f7a4abSThomas Cort 	/*
39892f7a4abSThomas Cort 	 * invalid character
39992f7a4abSThomas Cort 	 */
40092f7a4abSThomas Cort 	return(-1);
40192f7a4abSThomas Cort }
40292f7a4abSThomas Cort 
40392f7a4abSThomas Cort /*
40492f7a4abSThomas Cort  * convert the key to a bit pattern
40592f7a4abSThomas Cort  */
406*84d9c625SLionel Sambuc static void
cvtkey(char * obuf,char * ibuf)40792f7a4abSThomas Cort cvtkey(char *obuf, char *ibuf)
40892f7a4abSThomas Cort {
40992f7a4abSThomas Cort 	register int i, j;		/* counter in a for loop */
41092f7a4abSThomas Cort 	int nbuf[64];			/* used for hex/key translation */
41192f7a4abSThomas Cort 
41292f7a4abSThomas Cort 	/*
41392f7a4abSThomas Cort 	 * just switch on the key base
41492f7a4abSThomas Cort 	 */
41592f7a4abSThomas Cort 	switch(keybase) {
41692f7a4abSThomas Cort 	case KEY_ASCII:			/* ascii to integer */
41792f7a4abSThomas Cort 		(void)strncpy(obuf, ibuf, 8);
41892f7a4abSThomas Cort 		return;
41992f7a4abSThomas Cort 	case KEY_DEFAULT:		/* tell from context */
42092f7a4abSThomas Cort 		/*
42192f7a4abSThomas Cort 		 * leading '0x' or '0X' == hex key
42292f7a4abSThomas Cort 		 */
42392f7a4abSThomas Cort 		if (ibuf[0] == '0' && (ibuf[1] == 'x' || ibuf[1] == 'X')) {
42492f7a4abSThomas Cort 			ibuf = &ibuf[2];
42592f7a4abSThomas Cort 			/*
42692f7a4abSThomas Cort 			 * now translate it, bombing on any illegal hex digit
42792f7a4abSThomas Cort 			 */
42892f7a4abSThomas Cort 			for (i = 0; ibuf[i] && i < 16; i++)
42992f7a4abSThomas Cort 				if ((nbuf[i] = tobinhex(ibuf[i], 16)) == -1)
43092f7a4abSThomas Cort 					bdes_err(-1, "bad hex digit in key");
43192f7a4abSThomas Cort 			while (i < 16)
43292f7a4abSThomas Cort 				nbuf[i++] = 0;
43392f7a4abSThomas Cort 			for (i = 0; i < 8; i++)
43492f7a4abSThomas Cort 				obuf[i] =
43592f7a4abSThomas Cort 				    ((nbuf[2*i]&0xf)<<4) | (nbuf[2*i+1]&0xf);
43692f7a4abSThomas Cort 			/* preserve parity bits */
43792f7a4abSThomas Cort 			pflag = 1;
43892f7a4abSThomas Cort 			return;
43992f7a4abSThomas Cort 		}
44092f7a4abSThomas Cort 		/*
44192f7a4abSThomas Cort 		 * leading '0b' or '0B' == binary key
44292f7a4abSThomas Cort 		 */
44392f7a4abSThomas Cort 		if (ibuf[0] == '0' && (ibuf[1] == 'b' || ibuf[1] == 'B')) {
44492f7a4abSThomas Cort 			ibuf = &ibuf[2];
44592f7a4abSThomas Cort 			/*
44692f7a4abSThomas Cort 			 * now translate it, bombing on any illegal binary digit
44792f7a4abSThomas Cort 			 */
44892f7a4abSThomas Cort 			for (i = 0; ibuf[i] && i < 16; i++)
44992f7a4abSThomas Cort 				if ((nbuf[i] = tobinhex(ibuf[i], 2)) == -1)
45092f7a4abSThomas Cort 					bdes_err(-1, "bad binary digit in key");
45192f7a4abSThomas Cort 			while (i < 64)
45292f7a4abSThomas Cort 				nbuf[i++] = 0;
45392f7a4abSThomas Cort 			for (i = 0; i < 8; i++)
45492f7a4abSThomas Cort 				for (j = 0; j < 8; j++)
45592f7a4abSThomas Cort 					obuf[i] = (obuf[i]<<1)|nbuf[8*i+j];
45692f7a4abSThomas Cort 			/* preserve parity bits */
45792f7a4abSThomas Cort 			pflag = 1;
45892f7a4abSThomas Cort 			return;
45992f7a4abSThomas Cort 		}
46092f7a4abSThomas Cort 		/*
46192f7a4abSThomas Cort 		 * no special leader -- ASCII
46292f7a4abSThomas Cort 		 */
46392f7a4abSThomas Cort 		(void)strncpy(obuf, ibuf, 8);
46492f7a4abSThomas Cort 	}
46592f7a4abSThomas Cort }
46692f7a4abSThomas Cort 
46792f7a4abSThomas Cort /*
46892f7a4abSThomas Cort  * convert an ASCII string into a decimal number:
46992f7a4abSThomas Cort  * 1. must be between 0 and 64 inclusive (or 56, checked by caller)
47092f7a4abSThomas Cort  * 2. must be a valid decimal number
47192f7a4abSThomas Cort  * 3. must be a multiple of mult
47292f7a4abSThomas Cort  */
473*84d9c625SLionel Sambuc static int
setbits(char * s,int mult)47492f7a4abSThomas Cort setbits(char *s, int mult)
47592f7a4abSThomas Cort {
47692f7a4abSThomas Cort 	char *p;
47792f7a4abSThomas Cort 	int n;		/* the integer collected */
47892f7a4abSThomas Cort 
47992f7a4abSThomas Cort 	n = strtoul(s, &p, 10);
48092f7a4abSThomas Cort 	if (*p != 0)
48192f7a4abSThomas Cort 		bdes_err(-1, "bad decimal digit in MAC length");
48292f7a4abSThomas Cort 	/*
48392f7a4abSThomas Cort 	 * be sure it's a multiple of mult
48492f7a4abSThomas Cort 	 */
48592f7a4abSThomas Cort 	return((n % mult != 0) ? -1 : n);
48692f7a4abSThomas Cort }
48792f7a4abSThomas Cort 
48892f7a4abSThomas Cort /*****************
48992f7a4abSThomas Cort  * DES FUNCTIONS *
49092f7a4abSThomas Cort  *****************/
49192f7a4abSThomas Cort /*
49292f7a4abSThomas Cort  * This sets the DES key and (if you're using the deszip version)
49392f7a4abSThomas Cort  * the direction of the transformation.  This uses the Sun
49492f7a4abSThomas Cort  * to map the 64-bit key onto the 56 bits that the key schedule
49592f7a4abSThomas Cort  * generation routines use: the old way, which just uses the user-
49692f7a4abSThomas Cort  * supplied 64 bits as is, and the new way, which resets the parity
49792f7a4abSThomas Cort  * bit to be the same as the low-order bit in each character.  The
49892f7a4abSThomas Cort  * new way generates a greater variety of key schedules, since many
49992f7a4abSThomas Cort  * systems set the parity (high) bit of each character to 0, and the
50092f7a4abSThomas Cort  * DES ignores the low order bit of each character.
50192f7a4abSThomas Cort  */
502*84d9c625SLionel Sambuc static void
makekey(Desbuf buf)50392f7a4abSThomas Cort makekey(Desbuf buf)
50492f7a4abSThomas Cort {
50592f7a4abSThomas Cort 	register int i, j;			/* counter in a for loop */
50692f7a4abSThomas Cort 	register int par;			/* parity counter */
50792f7a4abSThomas Cort 
50892f7a4abSThomas Cort 	/*
50992f7a4abSThomas Cort 	 * if the parity is not preserved, flip it
51092f7a4abSThomas Cort 	 */
51192f7a4abSThomas Cort 	if (!pflag) {
51292f7a4abSThomas Cort 		for (i = 0; i < 8; i++) {
51392f7a4abSThomas Cort 			par = 0;
51492f7a4abSThomas Cort 			for (j = 1; j < 8; j++)
51592f7a4abSThomas Cort 				if ((bits[j]&UCHAR(buf, i)) != 0)
51692f7a4abSThomas Cort 					par++;
51792f7a4abSThomas Cort 			if ((par&01) == 01)
51892f7a4abSThomas Cort 				UCHAR(buf, i) = UCHAR(buf, i)&0177;
51992f7a4abSThomas Cort 			else
52092f7a4abSThomas Cort 				UCHAR(buf, i) = (UCHAR(buf, i)&0177)|0200;
52192f7a4abSThomas Cort 		}
52292f7a4abSThomas Cort 	}
52392f7a4abSThomas Cort 
52492f7a4abSThomas Cort 	DES_KEY(UBUFFER(buf));
52592f7a4abSThomas Cort }
52692f7a4abSThomas Cort 
52792f7a4abSThomas Cort /*
52892f7a4abSThomas Cort  * This encrypts using the Electronic Code Book mode of DES
52992f7a4abSThomas Cort  */
530*84d9c625SLionel Sambuc static void
ecbenc(void)53192f7a4abSThomas Cort ecbenc(void)
53292f7a4abSThomas Cort {
53392f7a4abSThomas Cort 	register int n;		/* number of bytes actually read */
53492f7a4abSThomas Cort 	register int bn;	/* block number */
53592f7a4abSThomas Cort 	Desbuf msgbuf;		/* I/O buffer */
53692f7a4abSThomas Cort 
53792f7a4abSThomas Cort 	for (bn = 0; (n = READ(BUFFER(msgbuf),  8)) == 8; bn++) {
53892f7a4abSThomas Cort 		/*
53992f7a4abSThomas Cort 		 * do the transformation
54092f7a4abSThomas Cort 		 */
54192f7a4abSThomas Cort 		DES_XFORM(UBUFFER(msgbuf));
54292f7a4abSThomas Cort 		WRITE(BUFFER(msgbuf), 8);
54392f7a4abSThomas Cort 	}
54492f7a4abSThomas Cort 	/*
54592f7a4abSThomas Cort 	 * at EOF or last block -- in either ase, the last byte contains
54692f7a4abSThomas Cort 	 * the character representation of the number of bytes in it
54792f7a4abSThomas Cort 	 */
54892f7a4abSThomas Cort 	bn++;
54992f7a4abSThomas Cort 	MEMZERO(&CHAR(msgbuf, n), 8 - n);
55092f7a4abSThomas Cort 	CHAR(msgbuf, 7) = n;
55192f7a4abSThomas Cort 	DES_XFORM(UBUFFER(msgbuf));
55292f7a4abSThomas Cort 	WRITE(BUFFER(msgbuf), 8);
55392f7a4abSThomas Cort 
55492f7a4abSThomas Cort }
55592f7a4abSThomas Cort 
55692f7a4abSThomas Cort /*
55792f7a4abSThomas Cort  * This decrypts using the Electronic Code Book mode of DES
55892f7a4abSThomas Cort  */
559*84d9c625SLionel Sambuc static void
ecbdec(void)56092f7a4abSThomas Cort ecbdec(void)
56192f7a4abSThomas Cort {
56292f7a4abSThomas Cort 	register int n;		/* number of bytes actually read */
56392f7a4abSThomas Cort 	register int c;		/* used to test for EOF */
56492f7a4abSThomas Cort 	register int bn;	/* block number */
56592f7a4abSThomas Cort 	Desbuf msgbuf;		/* I/O buffer */
56692f7a4abSThomas Cort 
56792f7a4abSThomas Cort 	for (bn = 1; (n = READ(BUFFER(msgbuf), 8)) == 8; bn++) {
56892f7a4abSThomas Cort 		/*
56992f7a4abSThomas Cort 		 * do the transformation
57092f7a4abSThomas Cort 		 */
57192f7a4abSThomas Cort 		DES_XFORM(UBUFFER(msgbuf));
57292f7a4abSThomas Cort 		/*
57392f7a4abSThomas Cort 		 * if the last one, handle it specially
57492f7a4abSThomas Cort 		 */
57592f7a4abSThomas Cort 		if ((c = getchar()) == EOF) {
57692f7a4abSThomas Cort 			n = CHAR(msgbuf, 7);
57792f7a4abSThomas Cort 			if (n < 0 || n > 7)
57892f7a4abSThomas Cort 				bdes_err(bn,
57992f7a4abSThomas Cort 				    "decryption failed (block corrupted)");
58092f7a4abSThomas Cort 		}
58192f7a4abSThomas Cort 		else
58292f7a4abSThomas Cort 			(void)ungetc(c, stdin);
58392f7a4abSThomas Cort 		WRITE(BUFFER(msgbuf), n);
58492f7a4abSThomas Cort 	}
58592f7a4abSThomas Cort 	if (n > 0)
58692f7a4abSThomas Cort 		bdes_err(bn, "decryption failed (incomplete block)");
58792f7a4abSThomas Cort }
58892f7a4abSThomas Cort 
58992f7a4abSThomas Cort /*
59092f7a4abSThomas Cort  * This encrypts using the Cipher Block Chaining mode of DES
59192f7a4abSThomas Cort  */
592*84d9c625SLionel Sambuc static void
cbcenc(void)59392f7a4abSThomas Cort cbcenc(void)
59492f7a4abSThomas Cort {
59592f7a4abSThomas Cort 	register int n;		/* number of bytes actually read */
59692f7a4abSThomas Cort 	register int bn;	/* block number */
59792f7a4abSThomas Cort 	Desbuf msgbuf;		/* I/O buffer */
59892f7a4abSThomas Cort 
59992f7a4abSThomas Cort 	/*
60092f7a4abSThomas Cort 	 * do the transformation
60192f7a4abSThomas Cort 	 */
60292f7a4abSThomas Cort 	for (bn = 1; (n = READ(BUFFER(msgbuf), 8)) == 8; bn++) {
60392f7a4abSThomas Cort 		for (n = 0; n < 8; n++)
60492f7a4abSThomas Cort 			CHAR(msgbuf, n) ^= CHAR(ivec, n);
60592f7a4abSThomas Cort 		DES_XFORM(UBUFFER(msgbuf));
60692f7a4abSThomas Cort 		MEMCPY(BUFFER(ivec), BUFFER(msgbuf), 8);
60792f7a4abSThomas Cort 		WRITE(BUFFER(msgbuf), 8);
60892f7a4abSThomas Cort 	}
60992f7a4abSThomas Cort 	/*
61092f7a4abSThomas Cort 	 * at EOF or last block -- in either case, the last byte contains
61192f7a4abSThomas Cort 	 * the character representation of the number of bytes in it
61292f7a4abSThomas Cort 	 */
61392f7a4abSThomas Cort 	bn++;
61492f7a4abSThomas Cort 	MEMZERO(&CHAR(msgbuf, n), 8 - n);
61592f7a4abSThomas Cort 	CHAR(msgbuf, 7) = n;
61692f7a4abSThomas Cort 	for (n = 0; n < 8; n++)
61792f7a4abSThomas Cort 		CHAR(msgbuf, n) ^= CHAR(ivec, n);
61892f7a4abSThomas Cort 	DES_XFORM(UBUFFER(msgbuf));
61992f7a4abSThomas Cort 	WRITE(BUFFER(msgbuf), 8);
62092f7a4abSThomas Cort 
62192f7a4abSThomas Cort }
62292f7a4abSThomas Cort 
62392f7a4abSThomas Cort /*
62492f7a4abSThomas Cort  * This decrypts using the Cipher Block Chaining mode of DES
62592f7a4abSThomas Cort  */
626*84d9c625SLionel Sambuc static void
cbcdec(void)62792f7a4abSThomas Cort cbcdec(void)
62892f7a4abSThomas Cort {
62992f7a4abSThomas Cort 	register int n;		/* number of bytes actually read */
63092f7a4abSThomas Cort 	Desbuf msgbuf;		/* I/O buffer */
63192f7a4abSThomas Cort 	Desbuf ibuf;		/* temp buffer for initialization vector */
63292f7a4abSThomas Cort 	register int c;		/* used to test for EOF */
63392f7a4abSThomas Cort 	register int bn;	/* block number */
63492f7a4abSThomas Cort 
63592f7a4abSThomas Cort 	for (bn = 0; (n = READ(BUFFER(msgbuf), 8)) == 8; bn++) {
63692f7a4abSThomas Cort 		/*
63792f7a4abSThomas Cort 		 * do the transformation
63892f7a4abSThomas Cort 		 */
63992f7a4abSThomas Cort 		MEMCPY(BUFFER(ibuf), BUFFER(msgbuf), 8);
64092f7a4abSThomas Cort 		DES_XFORM(UBUFFER(msgbuf));
64192f7a4abSThomas Cort 		for (c = 0; c < 8; c++)
64292f7a4abSThomas Cort 			UCHAR(msgbuf, c) ^= UCHAR(ivec, c);
64392f7a4abSThomas Cort 		MEMCPY(BUFFER(ivec), BUFFER(ibuf), 8);
64492f7a4abSThomas Cort 		/*
64592f7a4abSThomas Cort 		 * if the last one, handle it specially
64692f7a4abSThomas Cort 		 */
64792f7a4abSThomas Cort 		if ((c = getchar()) == EOF) {
64892f7a4abSThomas Cort 			n = CHAR(msgbuf, 7);
64992f7a4abSThomas Cort 			if (n < 0 || n > 7)
65092f7a4abSThomas Cort 				bdes_err(bn,
65192f7a4abSThomas Cort 				    "decryption failed (block corrupted)");
65292f7a4abSThomas Cort 		}
65392f7a4abSThomas Cort 		else
65492f7a4abSThomas Cort 			(void)ungetc(c, stdin);
65592f7a4abSThomas Cort 		WRITE(BUFFER(msgbuf), n);
65692f7a4abSThomas Cort 	}
65792f7a4abSThomas Cort 	if (n > 0)
65892f7a4abSThomas Cort 		bdes_err(bn, "decryption failed (incomplete block)");
65992f7a4abSThomas Cort }
66092f7a4abSThomas Cort 
66192f7a4abSThomas Cort /*
66292f7a4abSThomas Cort  * This authenticates using the Cipher Block Chaining mode of DES
66392f7a4abSThomas Cort  */
664*84d9c625SLionel Sambuc static void
cbcauth(void)66592f7a4abSThomas Cort cbcauth(void)
66692f7a4abSThomas Cort {
66792f7a4abSThomas Cort 	register int n, j;		/* number of bytes actually read */
66892f7a4abSThomas Cort 	Desbuf msgbuf;		/* I/O buffer */
66992f7a4abSThomas Cort 	Desbuf encbuf;		/* encryption buffer */
67092f7a4abSThomas Cort 
67192f7a4abSThomas Cort 	/*
67292f7a4abSThomas Cort 	 * do the transformation
67392f7a4abSThomas Cort 	 * note we DISCARD the encrypted block;
67492f7a4abSThomas Cort 	 * we only care about the last one
67592f7a4abSThomas Cort 	 */
67692f7a4abSThomas Cort 	while ((n = READ(BUFFER(msgbuf), 8)) == 8) {
67792f7a4abSThomas Cort 		for (n = 0; n < 8; n++)
67892f7a4abSThomas Cort 			CHAR(encbuf, n) = CHAR(msgbuf, n) ^ CHAR(ivec, n);
67992f7a4abSThomas Cort 		DES_XFORM(UBUFFER(encbuf));
68092f7a4abSThomas Cort 		MEMCPY(BUFFER(ivec), BUFFER(encbuf), 8);
68192f7a4abSThomas Cort 	}
68292f7a4abSThomas Cort 	/*
68392f7a4abSThomas Cort 	 * now compute the last one, right padding with '\0' if need be
68492f7a4abSThomas Cort 	 */
68592f7a4abSThomas Cort 	if (n > 0) {
68692f7a4abSThomas Cort 		MEMZERO(&CHAR(msgbuf, n), 8 - n);
68792f7a4abSThomas Cort 		for (n = 0; n < 8; n++)
68892f7a4abSThomas Cort 			CHAR(encbuf, n) = CHAR(msgbuf, n) ^ CHAR(ivec, n);
68992f7a4abSThomas Cort 		DES_XFORM(UBUFFER(encbuf));
69092f7a4abSThomas Cort 	}
69192f7a4abSThomas Cort 	/*
69292f7a4abSThomas Cort 	 * drop the bits
69392f7a4abSThomas Cort 	 * we write chars until fewer than 7 bits,
69492f7a4abSThomas Cort 	 * and then pad the last one with 0 bits
69592f7a4abSThomas Cort 	 */
69692f7a4abSThomas Cort 	for (n = 0; macbits > 7; n++, macbits -= 8)
69792f7a4abSThomas Cort 		(void)putchar(CHAR(encbuf, n));
69892f7a4abSThomas Cort 	if (macbits > 0) {
69992f7a4abSThomas Cort 		CHAR(msgbuf, 0) = 0x00;
70092f7a4abSThomas Cort 		for (j = 0; j < macbits; j++)
70192f7a4abSThomas Cort 			CHAR(msgbuf, 0) |= (CHAR(encbuf, n)&bits[j]);
70292f7a4abSThomas Cort 		(void)putchar(CHAR(msgbuf, 0));
70392f7a4abSThomas Cort 	}
70492f7a4abSThomas Cort }
70592f7a4abSThomas Cort 
70692f7a4abSThomas Cort /*
70792f7a4abSThomas Cort  * This encrypts using the Cipher FeedBack mode of DES
70892f7a4abSThomas Cort  */
709*84d9c625SLionel Sambuc static void
cfbenc(void)71092f7a4abSThomas Cort cfbenc(void)
71192f7a4abSThomas Cort {
71292f7a4abSThomas Cort 	register int n;		/* number of bytes actually read */
71392f7a4abSThomas Cort 	register int nbytes;	/* number of bytes to read */
71492f7a4abSThomas Cort 	register int bn;	/* block number */
71592f7a4abSThomas Cort 	char ibuf[8];		/* input buffer */
71692f7a4abSThomas Cort 	Desbuf msgbuf;		/* encryption buffer */
71792f7a4abSThomas Cort 
71892f7a4abSThomas Cort 	/*
71992f7a4abSThomas Cort 	 * do things in bytes, not bits
72092f7a4abSThomas Cort 	 */
72192f7a4abSThomas Cort 	nbytes = fbbits / 8;
72292f7a4abSThomas Cort 	/*
72392f7a4abSThomas Cort 	 * do the transformation
72492f7a4abSThomas Cort 	 */
72592f7a4abSThomas Cort 	for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) {
72692f7a4abSThomas Cort 		MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
72792f7a4abSThomas Cort 		DES_XFORM(UBUFFER(msgbuf));
72892f7a4abSThomas Cort 		for (n = 0; n < 8 - nbytes; n++)
72992f7a4abSThomas Cort 			UCHAR(ivec, n) = UCHAR(ivec, n+nbytes);
73092f7a4abSThomas Cort 		for (n = 0; n < nbytes; n++)
73192f7a4abSThomas Cort 			UCHAR(ivec, 8-nbytes+n) = ibuf[n] ^ UCHAR(msgbuf, n);
73292f7a4abSThomas Cort 		WRITE(&CHAR(ivec, 8-nbytes), nbytes);
73392f7a4abSThomas Cort 	}
73492f7a4abSThomas Cort 	/*
73592f7a4abSThomas Cort 	 * at EOF or last block -- in either case, the last byte contains
73692f7a4abSThomas Cort 	 * the character representation of the number of bytes in it
73792f7a4abSThomas Cort 	 */
73892f7a4abSThomas Cort 	bn++;
73992f7a4abSThomas Cort 	MEMZERO(&ibuf[n], nbytes - n);
74092f7a4abSThomas Cort 	ibuf[nbytes - 1] = n;
74192f7a4abSThomas Cort 	MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
74292f7a4abSThomas Cort 	DES_XFORM(UBUFFER(msgbuf));
74392f7a4abSThomas Cort 	for (n = 0; n < nbytes; n++)
74492f7a4abSThomas Cort 		ibuf[n] ^= UCHAR(msgbuf, n);
74592f7a4abSThomas Cort 	WRITE(ibuf, nbytes);
74692f7a4abSThomas Cort }
74792f7a4abSThomas Cort 
74892f7a4abSThomas Cort /*
74992f7a4abSThomas Cort  * This decrypts using the Cipher Block Chaining mode of DES
75092f7a4abSThomas Cort  */
751*84d9c625SLionel Sambuc static void
cfbdec(void)75292f7a4abSThomas Cort cfbdec(void)
75392f7a4abSThomas Cort {
75492f7a4abSThomas Cort 	register int n;		/* number of bytes actually read */
75592f7a4abSThomas Cort 	register int c;		/* used to test for EOF */
75692f7a4abSThomas Cort 	register int nbytes;	/* number of bytes to read */
75792f7a4abSThomas Cort 	register int bn;	/* block number */
75892f7a4abSThomas Cort 	char ibuf[8];		/* input buffer */
75992f7a4abSThomas Cort 	char obuf[8];		/* output buffer */
76092f7a4abSThomas Cort 	Desbuf msgbuf;		/* encryption buffer */
76192f7a4abSThomas Cort 
76292f7a4abSThomas Cort 	/*
76392f7a4abSThomas Cort 	 * do things in bytes, not bits
76492f7a4abSThomas Cort 	 */
76592f7a4abSThomas Cort 	nbytes = fbbits / 8;
76692f7a4abSThomas Cort 	/*
76792f7a4abSThomas Cort 	 * do the transformation
76892f7a4abSThomas Cort 	 */
76992f7a4abSThomas Cort 	for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) {
77092f7a4abSThomas Cort 		MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
77192f7a4abSThomas Cort 		DES_XFORM(UBUFFER(msgbuf));
77292f7a4abSThomas Cort 		for (c = 0; c < 8 - nbytes; c++)
77392f7a4abSThomas Cort 			CHAR(ivec, c) = CHAR(ivec, c+nbytes);
77492f7a4abSThomas Cort 		for (c = 0; c < nbytes; c++) {
77592f7a4abSThomas Cort 			CHAR(ivec, 8-nbytes+c) = ibuf[c];
77692f7a4abSThomas Cort 			obuf[c] = ibuf[c] ^ UCHAR(msgbuf, c);
77792f7a4abSThomas Cort 		}
77892f7a4abSThomas Cort 		/*
77992f7a4abSThomas Cort 		 * if the last one, handle it specially
78092f7a4abSThomas Cort 		 */
78192f7a4abSThomas Cort 		if ((c = getchar()) == EOF) {
78292f7a4abSThomas Cort 			n = obuf[nbytes-1];
78392f7a4abSThomas Cort 			if (n < 0 || n > nbytes-1)
78492f7a4abSThomas Cort 				bdes_err(bn,
78592f7a4abSThomas Cort 				    "decryption failed (block corrupted)");
78692f7a4abSThomas Cort 		}
78792f7a4abSThomas Cort 		else
78892f7a4abSThomas Cort 			(void)ungetc(c, stdin);
78992f7a4abSThomas Cort 		WRITE(obuf, n);
79092f7a4abSThomas Cort 	}
79192f7a4abSThomas Cort 	if (n > 0)
79292f7a4abSThomas Cort 		bdes_err(bn, "decryption failed (incomplete block)");
79392f7a4abSThomas Cort }
79492f7a4abSThomas Cort 
79592f7a4abSThomas Cort /*
79692f7a4abSThomas Cort  * This encrypts using the alternative Cipher FeedBack mode of DES
79792f7a4abSThomas Cort  */
798*84d9c625SLionel Sambuc static void
cfbaenc(void)79992f7a4abSThomas Cort cfbaenc(void)
80092f7a4abSThomas Cort {
80192f7a4abSThomas Cort 	register int n;		/* number of bytes actually read */
80292f7a4abSThomas Cort 	register int nbytes;	/* number of bytes to read */
80392f7a4abSThomas Cort 	register int bn;	/* block number */
80492f7a4abSThomas Cort 	char ibuf[8];		/* input buffer */
80592f7a4abSThomas Cort 	char obuf[8];		/* output buffer */
80692f7a4abSThomas Cort 	Desbuf msgbuf;		/* encryption buffer */
80792f7a4abSThomas Cort 
80892f7a4abSThomas Cort 	/*
80992f7a4abSThomas Cort 	 * do things in bytes, not bits
81092f7a4abSThomas Cort 	 */
81192f7a4abSThomas Cort 	nbytes = fbbits / 7;
81292f7a4abSThomas Cort 	/*
81392f7a4abSThomas Cort 	 * do the transformation
81492f7a4abSThomas Cort 	 */
81592f7a4abSThomas Cort 	for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) {
81692f7a4abSThomas Cort 		MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
81792f7a4abSThomas Cort 		DES_XFORM(UBUFFER(msgbuf));
81892f7a4abSThomas Cort 		for (n = 0; n < 8 - nbytes; n++)
81992f7a4abSThomas Cort 			UCHAR(ivec, n) = UCHAR(ivec, n+nbytes);
82092f7a4abSThomas Cort 		for (n = 0; n < nbytes; n++)
82192f7a4abSThomas Cort 			UCHAR(ivec, 8-nbytes+n) = (ibuf[n] ^ UCHAR(msgbuf, n))
82292f7a4abSThomas Cort 							|0200;
82392f7a4abSThomas Cort 		for (n = 0; n < nbytes; n++)
82492f7a4abSThomas Cort 			obuf[n] = CHAR(ivec, 8-nbytes+n)&0177;
82592f7a4abSThomas Cort 		WRITE(obuf, nbytes);
82692f7a4abSThomas Cort 	}
82792f7a4abSThomas Cort 	/*
82892f7a4abSThomas Cort 	 * at EOF or last block -- in either case, the last byte contains
82992f7a4abSThomas Cort 	 * the character representation of the number of bytes in it
83092f7a4abSThomas Cort 	 */
83192f7a4abSThomas Cort 	bn++;
83292f7a4abSThomas Cort 	MEMZERO(&ibuf[n], nbytes - n);
83392f7a4abSThomas Cort 	ibuf[nbytes - 1] = ('0' + n)|0200;
83492f7a4abSThomas Cort 	MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
83592f7a4abSThomas Cort 	DES_XFORM(UBUFFER(msgbuf));
83692f7a4abSThomas Cort 	for (n = 0; n < nbytes; n++)
83792f7a4abSThomas Cort 		ibuf[n] ^= UCHAR(msgbuf, n);
83892f7a4abSThomas Cort 	WRITE(ibuf, nbytes);
83992f7a4abSThomas Cort }
84092f7a4abSThomas Cort 
84192f7a4abSThomas Cort /*
84292f7a4abSThomas Cort  * This decrypts using the alternative Cipher Block Chaining mode of DES
84392f7a4abSThomas Cort  */
844*84d9c625SLionel Sambuc static void
cfbadec(void)84592f7a4abSThomas Cort cfbadec(void)
84692f7a4abSThomas Cort {
84792f7a4abSThomas Cort 	register int n;		/* number of bytes actually read */
84892f7a4abSThomas Cort 	register int c;		/* used to test for EOF */
84992f7a4abSThomas Cort 	register int nbytes;	/* number of bytes to read */
85092f7a4abSThomas Cort 	register int bn;	/* block number */
85192f7a4abSThomas Cort 	char ibuf[8];		/* input buffer */
85292f7a4abSThomas Cort 	char obuf[8];		/* output buffer */
85392f7a4abSThomas Cort 	Desbuf msgbuf;		/* encryption buffer */
85492f7a4abSThomas Cort 
85592f7a4abSThomas Cort 	/*
85692f7a4abSThomas Cort 	 * do things in bytes, not bits
85792f7a4abSThomas Cort 	 */
85892f7a4abSThomas Cort 	nbytes = fbbits / 7;
85992f7a4abSThomas Cort 	/*
86092f7a4abSThomas Cort 	 * do the transformation
86192f7a4abSThomas Cort 	 */
86292f7a4abSThomas Cort 	for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) {
86392f7a4abSThomas Cort 		MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
86492f7a4abSThomas Cort 		DES_XFORM(UBUFFER(msgbuf));
86592f7a4abSThomas Cort 		for (c = 0; c < 8 - nbytes; c++)
86692f7a4abSThomas Cort 			CHAR(ivec, c) = CHAR(ivec, c+nbytes);
86792f7a4abSThomas Cort 		for (c = 0; c < nbytes; c++) {
86892f7a4abSThomas Cort 			CHAR(ivec, 8-nbytes+c) = ibuf[c]|0200;
86992f7a4abSThomas Cort 			obuf[c] = (ibuf[c] ^ UCHAR(msgbuf, c))&0177;
87092f7a4abSThomas Cort 		}
87192f7a4abSThomas Cort 		/*
87292f7a4abSThomas Cort 		 * if the last one, handle it specially
87392f7a4abSThomas Cort 		 */
87492f7a4abSThomas Cort 		if ((c = getchar()) == EOF) {
87592f7a4abSThomas Cort 			if ((n = (obuf[nbytes-1] - '0')) < 0
87692f7a4abSThomas Cort 						|| n > nbytes-1)
87792f7a4abSThomas Cort 				bdes_err(bn,
87892f7a4abSThomas Cort 				    "decryption failed (block corrupted)");
87992f7a4abSThomas Cort 		}
88092f7a4abSThomas Cort 		else
88192f7a4abSThomas Cort 			(void)ungetc(c, stdin);
88292f7a4abSThomas Cort 		WRITE(obuf, n);
88392f7a4abSThomas Cort 	}
88492f7a4abSThomas Cort 	if (n > 0)
88592f7a4abSThomas Cort 		bdes_err(bn, "decryption failed (incomplete block)");
88692f7a4abSThomas Cort }
88792f7a4abSThomas Cort 
88892f7a4abSThomas Cort 
88992f7a4abSThomas Cort /*
89092f7a4abSThomas Cort  * This encrypts using the Output FeedBack mode of DES
89192f7a4abSThomas Cort  */
892*84d9c625SLionel Sambuc static void
ofbenc(void)89392f7a4abSThomas Cort ofbenc(void)
89492f7a4abSThomas Cort {
89592f7a4abSThomas Cort 	register int n;		/* number of bytes actually read */
89692f7a4abSThomas Cort 	register int c;		/* used to test for EOF */
89792f7a4abSThomas Cort 	register int nbytes;	/* number of bytes to read */
89892f7a4abSThomas Cort 	register int bn;	/* block number */
89992f7a4abSThomas Cort 	char ibuf[8];		/* input buffer */
90092f7a4abSThomas Cort 	char obuf[8];		/* output buffer */
90192f7a4abSThomas Cort 	Desbuf msgbuf;		/* encryption buffer */
90292f7a4abSThomas Cort 
90392f7a4abSThomas Cort 	/*
90492f7a4abSThomas Cort 	 * do things in bytes, not bits
90592f7a4abSThomas Cort 	 */
90692f7a4abSThomas Cort 	nbytes = fbbits / 8;
90792f7a4abSThomas Cort 	/*
90892f7a4abSThomas Cort 	 * do the transformation
90992f7a4abSThomas Cort 	 */
91092f7a4abSThomas Cort 	for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) {
91192f7a4abSThomas Cort 		MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
91292f7a4abSThomas Cort 		DES_XFORM(UBUFFER(msgbuf));
91392f7a4abSThomas Cort 		for (n = 0; n < 8 - nbytes; n++)
91492f7a4abSThomas Cort 			UCHAR(ivec, n) = UCHAR(ivec, n+nbytes);
91592f7a4abSThomas Cort 		for (n = 0; n < nbytes; n++) {
91692f7a4abSThomas Cort 			UCHAR(ivec, 8-nbytes+n) = UCHAR(msgbuf, n);
91792f7a4abSThomas Cort 			obuf[n] = ibuf[n] ^ UCHAR(msgbuf, n);
91892f7a4abSThomas Cort 		}
91992f7a4abSThomas Cort 		WRITE(obuf, nbytes);
92092f7a4abSThomas Cort 	}
92192f7a4abSThomas Cort 	/*
92292f7a4abSThomas Cort 	 * at EOF or last block -- in either case, the last byte contains
92392f7a4abSThomas Cort 	 * the character representation of the number of bytes in it
92492f7a4abSThomas Cort 	 */
92592f7a4abSThomas Cort 	bn++;
92692f7a4abSThomas Cort 	MEMZERO(&ibuf[n], nbytes - n);
92792f7a4abSThomas Cort 	ibuf[nbytes - 1] = n;
92892f7a4abSThomas Cort 	MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
92992f7a4abSThomas Cort 	DES_XFORM(UBUFFER(msgbuf));
93092f7a4abSThomas Cort 	for (c = 0; c < nbytes; c++)
93192f7a4abSThomas Cort 		ibuf[c] ^= UCHAR(msgbuf, c);
93292f7a4abSThomas Cort 	WRITE(ibuf, nbytes);
93392f7a4abSThomas Cort }
93492f7a4abSThomas Cort 
93592f7a4abSThomas Cort /*
93692f7a4abSThomas Cort  * This decrypts using the Output Block Chaining mode of DES
93792f7a4abSThomas Cort  */
938*84d9c625SLionel Sambuc static void
ofbdec(void)93992f7a4abSThomas Cort ofbdec(void)
94092f7a4abSThomas Cort {
94192f7a4abSThomas Cort 	register int n;		/* number of bytes actually read */
94292f7a4abSThomas Cort 	register int c;		/* used to test for EOF */
94392f7a4abSThomas Cort 	register int nbytes;	/* number of bytes to read */
94492f7a4abSThomas Cort 	register int bn;	/* block number */
94592f7a4abSThomas Cort 	char ibuf[8];		/* input buffer */
94692f7a4abSThomas Cort 	char obuf[8];		/* output buffer */
94792f7a4abSThomas Cort 	Desbuf msgbuf;		/* encryption buffer */
94892f7a4abSThomas Cort 
94992f7a4abSThomas Cort 	/*
95092f7a4abSThomas Cort 	 * do things in bytes, not bits
95192f7a4abSThomas Cort 	 */
95292f7a4abSThomas Cort 	nbytes = fbbits / 8;
95392f7a4abSThomas Cort 	/*
95492f7a4abSThomas Cort 	 * do the transformation
95592f7a4abSThomas Cort 	 */
95692f7a4abSThomas Cort 	for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) {
95792f7a4abSThomas Cort 		MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
95892f7a4abSThomas Cort 		DES_XFORM(UBUFFER(msgbuf));
95992f7a4abSThomas Cort 		for (c = 0; c < 8 - nbytes; c++)
96092f7a4abSThomas Cort 			CHAR(ivec, c) = CHAR(ivec, c+nbytes);
96192f7a4abSThomas Cort 		for (c = 0; c < nbytes; c++) {
96292f7a4abSThomas Cort 			CHAR(ivec, 8-nbytes+c) = UCHAR(msgbuf, c);
96392f7a4abSThomas Cort 			obuf[c] = ibuf[c] ^ UCHAR(msgbuf, c);
96492f7a4abSThomas Cort 		}
96592f7a4abSThomas Cort 		/*
96692f7a4abSThomas Cort 		 * if the last one, handle it specially
96792f7a4abSThomas Cort 		 */
96892f7a4abSThomas Cort 		if ((c = getchar()) == EOF) {
96992f7a4abSThomas Cort 			n = obuf[nbytes-1];
97092f7a4abSThomas Cort 			if (n < 0 || n > nbytes-1)
97192f7a4abSThomas Cort 				bdes_err(bn,
97292f7a4abSThomas Cort 				    "decryption failed (block corrupted)");
97392f7a4abSThomas Cort 		}
97492f7a4abSThomas Cort 		else
97592f7a4abSThomas Cort 			(void)ungetc(c, stdin);
97692f7a4abSThomas Cort 		/*
97792f7a4abSThomas Cort 		 * dump it
97892f7a4abSThomas Cort 		 */
97992f7a4abSThomas Cort 		WRITE(obuf, n);
98092f7a4abSThomas Cort 	}
98192f7a4abSThomas Cort 	if (n > 0)
98292f7a4abSThomas Cort 		bdes_err(bn, "decryption failed (incomplete block)");
98392f7a4abSThomas Cort }
98492f7a4abSThomas Cort 
98592f7a4abSThomas Cort /*
98692f7a4abSThomas Cort  * This authenticates using the Cipher FeedBack mode of DES
98792f7a4abSThomas Cort  */
988*84d9c625SLionel Sambuc static void
cfbauth(void)98992f7a4abSThomas Cort cfbauth(void)
99092f7a4abSThomas Cort {
99192f7a4abSThomas Cort 	register int n, j;	/* number of bytes actually read */
99292f7a4abSThomas Cort 	register int nbytes;	/* number of bytes to read */
99392f7a4abSThomas Cort 	char ibuf[8];		/* input buffer */
99492f7a4abSThomas Cort 	Desbuf msgbuf;		/* encryption buffer */
99592f7a4abSThomas Cort 
99692f7a4abSThomas Cort 	/*
99792f7a4abSThomas Cort 	 * do things in bytes, not bits
99892f7a4abSThomas Cort 	 */
99992f7a4abSThomas Cort 	nbytes = fbbits / 8;
100092f7a4abSThomas Cort 	/*
100192f7a4abSThomas Cort 	 * do the transformation
100292f7a4abSThomas Cort 	 */
100392f7a4abSThomas Cort 	while ((n = READ(ibuf, nbytes)) == nbytes) {
100492f7a4abSThomas Cort 		MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
100592f7a4abSThomas Cort 		DES_XFORM(UBUFFER(msgbuf));
100692f7a4abSThomas Cort 		for (n = 0; n < 8 - nbytes; n++)
100792f7a4abSThomas Cort 			UCHAR(ivec, n) = UCHAR(ivec, n+nbytes);
100892f7a4abSThomas Cort 		for (n = 0; n < nbytes; n++)
100992f7a4abSThomas Cort 			UCHAR(ivec, 8-nbytes+n) = ibuf[n] ^ UCHAR(msgbuf, n);
101092f7a4abSThomas Cort 	}
101192f7a4abSThomas Cort 	/*
101292f7a4abSThomas Cort 	 * at EOF or last block -- in either case, the last byte contains
101392f7a4abSThomas Cort 	 * the character representation of the number of bytes in it
101492f7a4abSThomas Cort 	 */
101592f7a4abSThomas Cort 	MEMZERO(&ibuf[n], nbytes - n);
101692f7a4abSThomas Cort 	ibuf[nbytes - 1] = '0' + n;
101792f7a4abSThomas Cort 	MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
101892f7a4abSThomas Cort 	DES_XFORM(UBUFFER(msgbuf));
101992f7a4abSThomas Cort 	for (n = 0; n < nbytes; n++)
102092f7a4abSThomas Cort 		ibuf[n] ^= UCHAR(msgbuf, n);
102192f7a4abSThomas Cort 	/*
102292f7a4abSThomas Cort 	 * drop the bits
102392f7a4abSThomas Cort 	 * we write chars until fewer than 7 bits,
102492f7a4abSThomas Cort 	 * and then pad the last one with 0 bits
102592f7a4abSThomas Cort 	 */
102692f7a4abSThomas Cort 	for (n = 0; macbits > 7; n++, macbits -= 8)
102792f7a4abSThomas Cort 		(void)putchar(CHAR(msgbuf, n));
102892f7a4abSThomas Cort 	if (macbits > 0) {
102992f7a4abSThomas Cort 		CHAR(msgbuf, 0) = 0x00;
103092f7a4abSThomas Cort 		for (j = 0; j < macbits; j++)
103192f7a4abSThomas Cort 			CHAR(msgbuf, 0) |= (CHAR(msgbuf, n)&bits[j]);
103292f7a4abSThomas Cort 		(void)putchar(CHAR(msgbuf, 0));
103392f7a4abSThomas Cort 	}
103492f7a4abSThomas Cort }
103592f7a4abSThomas Cort 
103692f7a4abSThomas Cort #ifndef FASTWAY
103792f7a4abSThomas Cort /*
103892f7a4abSThomas Cort  * change from 8 bits/Uchar to 1 bit/Uchar
103992f7a4abSThomas Cort  */
1040*84d9c625SLionel Sambuc static void
expand(Desbuf from,char * to)104192f7a4abSThomas Cort expand(Desbuf from, char *to)
104292f7a4abSThomas Cort {
104392f7a4abSThomas Cort 	register int i, j;		/* counters in for loop */
104492f7a4abSThomas Cort 
104592f7a4abSThomas Cort 	for (i = 0; i < 8; i++)
104692f7a4abSThomas Cort 		for (j = 0; j < 8; j++)
104792f7a4abSThomas Cort 			*to++ = (CHAR(from, i)>>(7-j))&01;
104892f7a4abSThomas Cort }
104992f7a4abSThomas Cort 
105092f7a4abSThomas Cort /*
105192f7a4abSThomas Cort  * change from 1 bit/char to 8 bits/Uchar
105292f7a4abSThomas Cort  */
1053*84d9c625SLionel Sambuc static void
compress(char * from,Desbuf to)105492f7a4abSThomas Cort compress(char *from, Desbuf to)
105592f7a4abSThomas Cort {
105692f7a4abSThomas Cort 	register int i, j;		/* counters in for loop */
105792f7a4abSThomas Cort 
105892f7a4abSThomas Cort 	for (i = 0; i < 8; i++) {
105992f7a4abSThomas Cort 	 	CHAR(to, i) = 0;
106092f7a4abSThomas Cort 		for (j = 0; j < 8; j++)
106192f7a4abSThomas Cort 			CHAR(to, i) = ((*from++)<<(7-j))|CHAR(to, i);
106292f7a4abSThomas Cort 	}
106392f7a4abSThomas Cort }
106492f7a4abSThomas Cort #endif
106592f7a4abSThomas Cort 
106692f7a4abSThomas Cort /*
106792f7a4abSThomas Cort  * message about usage
106892f7a4abSThomas Cort  */
1069*84d9c625SLionel Sambuc static void
usage(void)107092f7a4abSThomas Cort usage(void)
107192f7a4abSThomas Cort {
107292f7a4abSThomas Cort 
107392f7a4abSThomas Cort 	(void) fprintf(stderr, "usage: %s %s\n", getprogname(),
107492f7a4abSThomas Cort 	    "[-abdp] [-F bit] [-f bit] [-k key] [-m bit] [-o bit] [-v vector]");
107592f7a4abSThomas Cort 	exit(1);
107692f7a4abSThomas Cort }
1077