11899Swollman/*-
21899Swollman * Copyright (c) 1991, 1993
31899Swollman *	The Regents of the University of California.  All rights reserved.
41899Swollman *
51899Swollman * This code is derived from software contributed to Berkeley by
61899Swollman * Matt Bishop of Dartmouth College.
71899Swollman *
81899Swollman * The United States Government has rights in this work pursuant
91899Swollman * to contract no. NAG 2-680 between the National Aeronautics and
101899Swollman * Space Administration and Dartmouth College.
111899Swollman *
121899Swollman * Redistribution and use in source and binary forms, with or without
131899Swollman * modification, are permitted provided that the following conditions
141899Swollman * are met:
151899Swollman * 1. Redistributions of source code must retain the above copyright
161899Swollman *    notice, this list of conditions and the following disclaimer.
171899Swollman * 2. Redistributions in binary form must reproduce the above copyright
181899Swollman *    notice, this list of conditions and the following disclaimer in the
191899Swollman *    documentation and/or other materials provided with the distribution.
201899Swollman * 3. All advertising materials mentioning features or use of this software
211899Swollman *    must display the following acknowledgement:
221899Swollman *	This product includes software developed by the University of
231899Swollman *	California, Berkeley and its contributors.
241899Swollman * 4. Neither the name of the University nor the names of its contributors
251899Swollman *    may be used to endorse or promote products derived from this software
261899Swollman *    without specific prior written permission.
271899Swollman *
281899Swollman * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
291899Swollman * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
301899Swollman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
311899Swollman * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
321899Swollman * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
331899Swollman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
341899Swollman * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
351899Swollman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
361899Swollman * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
371899Swollman * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
381899Swollman * SUCH DAMAGE.
391899Swollman */
401899Swollman
411899Swollman#ifndef lint
42115718Smarkmstatic const char copyright[] =
431899Swollman"@(#) Copyright (c) 1991, 1993\n\
441899Swollman	The Regents of the University of California.  All rights reserved.\n";
451899Swollman#endif /* not lint */
461899Swollman
471899Swollman#ifndef lint
4863248Speter#if 0
491899Swollmanstatic char sccsid[] = "@(#)bdes.c	8.1 (Berkeley) 6/6/93";
5063248Speter#endif
511899Swollman#endif /* not lint */
521899Swollman
531899Swollman/*
541899Swollman * BDES -- DES encryption package for Berkeley Software Distribution 4.4
551899Swollman * options:
561899Swollman *	-a	key is in ASCII
571899Swollman *	-b	use ECB (electronic code book) mode
581899Swollman *	-d	invert (decrypt) input
591899Swollman *	-f b	use b-bit CFB (cipher feedback) mode
601899Swollman *	-F b	use b-bit CFB (cipher feedback) alternative mode
611899Swollman *	-k key	use key as the cryptographic key
621899Swollman *	-m b	generate a MAC of length b
631899Swollman *	-o b	use b-bit OFB (output feedback) mode
641899Swollman *	-p	don't reset the parity bit
651899Swollman *	-v v	use v as the initialization vector (ignored for ECB)
661899Swollman * note: the last character of the last block is the integer indicating
671899Swollman * how many characters of that block are to be output
681899Swollman *
691899Swollman * Author: Matt Bishop
701899Swollman *	   Department of Mathematics and Computer Science
711899Swollman *	   Dartmouth College
721899Swollman *	   Hanover, NH  03755
731899Swollman * Email:  Matt.Bishop@dartmouth.edu
741899Swollman *	   ...!decvax!dartvax!Matt.Bishop
751899Swollman *
761899Swollman * See Technical Report PCS-TR91-158, Department of Mathematics and Computer
771899Swollman * Science, Dartmouth College, for a detailed description of the implemen-
781899Swollman * tation and differences between it and Sun's.  The DES is described in
791899Swollman * FIPS PUB 46, and the modes in FIPS PUB 81 (see either the manual page
801899Swollman * or the technical report for a complete reference).
811899Swollman */
821899Swollman
83115718Smarkm#include <sys/cdefs.h>
84115718Smarkm__FBSDID("$FreeBSD: releng/10.3/secure/usr.bin/bdes/bdes.c 198856 2009-11-03 18:40:42Z jhb $");
85115718Smarkm
86115718Smarkm#include <sys/types.h>
87115718Smarkm
88115718Smarkm#include <ctype.h>
89115718Smarkm#include <err.h>
901899Swollman#include <errno.h>
911899Swollman#include <stdio.h>
921899Swollman#include <stdlib.h>
931899Swollman#include <string.h>
94115718Smarkm#include <unistd.h>
951899Swollman
96115718Smarkm#include <openssl/des.h>
97115718Smarkm
981899Swollman/*
991899Swollman * BSD and System V systems offer special library calls that do
1001899Swollman * block moves and fills, so if possible we take advantage of them
1011899Swollman */
1021899Swollman#define	MEMCPY(dest,src,len)	bcopy((src),(dest),(len))
1031899Swollman#define	MEMZERO(dest,len)	bzero((dest),(len))
1041899Swollman
105115718Smarkm#define	DES_XFORM(buf)							\
106115718Smarkm		DES_ecb_encrypt(buf, buf, &schedule, 			\
107115718Smarkm		    mode == MODE_ENCRYPT ? DES_ENCRYPT : DES_DECRYPT);
1081899Swollman
1091899Swollman/*
1101899Swollman * this does an error-checking write
1111899Swollman */
1121899Swollman#define	READ(buf, n)	fread(buf, sizeof(char), n, stdin)
1131899Swollman#define WRITE(buf,n)						\
1141899Swollman		if (fwrite(buf, sizeof(char), n, stdout) != n)	\
115115718Smarkm			warnx("fwrite error at %d", n);
1161899Swollman
1171899Swollman/*
1181899Swollman * global variables and related macros
1191899Swollman */
1201899Swollman#define KEY_DEFAULT		0	/* interpret radix of key from key */
1211899Swollman#define KEY_ASCII		1	/* key is in ASCII characters */
1221899Swollmanint keybase = KEY_DEFAULT;		/* how to interpret the key */
1231899Swollman
1241899Swollmanenum { 					/* encrypt, decrypt, authenticate */
1251899Swollman	MODE_ENCRYPT, MODE_DECRYPT, MODE_AUTHENTICATE
1261899Swollman} mode = MODE_ENCRYPT;
127115718Smarkm
1281899Swollmanenum {					/* ecb, cbc, cfb, cfba, ofb? */
1291899Swollman	ALG_ECB, ALG_CBC, ALG_CFB, ALG_OFB, ALG_CFBA
1301899Swollman} alg = ALG_CBC;
1311899Swollman
132115718SmarkmDES_cblock ivec;				/* initialization vector */
133115718Smarkm
1341899Swollmanchar bits[] = {				/* used to extract bits from a char */
1351899Swollman	'\200', '\100', '\040', '\020', '\010', '\004', '\002', '\001'
1361899Swollman};
137115718Smarkm
1381899Swollmanint inverse;				/* 0 to encrypt, 1 to decrypt */
1391899Swollmanint macbits = -1;			/* number of bits in authentication */
1401899Swollmanint fbbits = -1;			/* number of feedback bits */
1411899Swollmanint pflag;				/* 1 to preserve parity bits */
1421899Swollman
143115718SmarkmDES_key_schedule schedule;		/* expanded DES key */
144115718Smarkm
145115718Smarkmstatic void ecbenc(void);
146115718Smarkmstatic void ecbdec(void);
147115718Smarkmstatic void cbcenc(void);
148115718Smarkmstatic void cbcdec(void);
149115718Smarkmstatic void cfbenc(void);
150115718Smarkmstatic void cfbdec(void);
151115718Smarkmstatic void cfbaenc(void);
152115718Smarkmstatic void cfbadec(void);
153115718Smarkmstatic void ofbenc(void);
154115718Smarkmstatic void ofbdec(void);
155115718Smarkm
156115718Smarkmstatic void cbcauth(void);
157115718Smarkmstatic void cfbauth(void);
158115718Smarkm
159115718Smarkmstatic void cvtkey(DES_cblock, char *);
160115718Smarkmstatic int setbits(char *, int);
161115718Smarkmstatic void makekey(DES_cblock *);
162115718Smarkmstatic int tobinhex(char, int);
163115718Smarkm
164115718Smarkmstatic void usage(void);
165115718Smarkm
166115718Smarkmint
167140394Sddsmain(int argc, char *argv[])
1681899Swollman{
1691899Swollman	extern char *optarg;		/* argument to option if any */
170115718Smarkm	int i;				/* counter in a for loop */
171115718Smarkm	char *p;			/* used to obtain the key */
172115718Smarkm	DES_cblock msgbuf;		/* I/O buffer */
173198856Sjhb	int kflag;			/* command-line encryption key */
1741899Swollman
175140394Sdds	setproctitle("-");		/* Hide command-line arguments */
1761899Swollman
177198856Sjhb	/* initialize the initialization vector */
1781899Swollman	MEMZERO(ivec, 8);
1791899Swollman
1801899Swollman	/* process the argument list */
1811899Swollman	kflag = 0;
182176407Sru	while ((i = getopt(argc, argv, "abdF:f:k:m:o:pv:")) != -1)
1831899Swollman		switch(i) {
1841899Swollman		case 'a':		/* key is ASCII */
1851899Swollman			keybase = KEY_ASCII;
1861899Swollman			break;
1871899Swollman		case 'b':		/* use ECB mode */
1881899Swollman			alg = ALG_ECB;
1891899Swollman			break;
1901899Swollman		case 'd':		/* decrypt */
1911899Swollman			mode = MODE_DECRYPT;
1921899Swollman			break;
1931899Swollman		case 'F':		/* use alternative CFB mode */
1941899Swollman			alg = ALG_CFBA;
1951899Swollman			if ((fbbits = setbits(optarg, 7)) > 56 || fbbits == 0)
196115718Smarkm				errx(1, "-F: number must be 1-56 inclusive");
1971899Swollman			else if (fbbits == -1)
198115718Smarkm				errx(1, "-F: number must be a multiple of 7");
1991899Swollman			break;
2001899Swollman		case 'f':		/* use CFB mode */
2011899Swollman			alg = ALG_CFB;
2021899Swollman			if ((fbbits = setbits(optarg, 8)) > 64 || fbbits == 0)
203115718Smarkm				errx(1, "-f: number must be 1-64 inclusive");
2041899Swollman			else if (fbbits == -1)
205115718Smarkm				errx(1, "-f: number must be a multiple of 8");
2061899Swollman			break;
2071899Swollman		case 'k':		/* encryption key */
2081899Swollman			kflag = 1;
209115718Smarkm			cvtkey(msgbuf, optarg);
2101899Swollman			break;
2111899Swollman		case 'm':		/* number of bits for MACing */
2121899Swollman			mode = MODE_AUTHENTICATE;
2131899Swollman			if ((macbits = setbits(optarg, 1)) > 64)
214115718Smarkm				errx(1, "-m: number must be 0-64 inclusive");
2151899Swollman			break;
2161899Swollman		case 'o':		/* use OFB mode */
2171899Swollman			alg = ALG_OFB;
2181899Swollman			if ((fbbits = setbits(optarg, 8)) > 64 || fbbits == 0)
219115718Smarkm				errx(1, "-o: number must be 1-64 inclusive");
2201899Swollman			else if (fbbits == -1)
221115718Smarkm				errx(1, "-o: number must be a multiple of 8");
2221899Swollman			break;
2231899Swollman		case 'p':		/* preserve parity bits */
2241899Swollman			pflag = 1;
2251899Swollman			break;
2261899Swollman		case 'v':		/* set initialization vector */
227115718Smarkm			cvtkey(ivec, optarg);
2281899Swollman			break;
2291899Swollman		default:		/* error */
2301899Swollman			usage();
2311899Swollman		}
2321899Swollman
2331899Swollman	if (!kflag) {
2341899Swollman		/*
2351899Swollman		 * if the key's not ASCII, assume it is
2361899Swollman		 */
2371899Swollman		keybase = KEY_ASCII;
2381899Swollman		/*
2391899Swollman		 * get the key
2401899Swollman		 */
2411899Swollman		p = getpass("Enter key: ");
2421899Swollman		/*
2431899Swollman		 * copy it, nul-padded, into the key area
2441899Swollman		 */
245115718Smarkm		cvtkey(msgbuf, p);
2461899Swollman	}
2471899Swollman
248115718Smarkm	makekey(&msgbuf);
2491899Swollman	inverse = (alg == ALG_CBC || alg == ALG_ECB) && mode == MODE_DECRYPT;
2501899Swollman
2511899Swollman	switch(alg) {
2521899Swollman	case ALG_CBC:
2531899Swollman		switch(mode) {
2541899Swollman		case MODE_AUTHENTICATE:	/* authenticate using CBC mode */
2551899Swollman			cbcauth();
2561899Swollman			break;
2571899Swollman		case MODE_DECRYPT:	/* decrypt using CBC mode */
2581899Swollman			cbcdec();
2591899Swollman			break;
2601899Swollman		case MODE_ENCRYPT:	/* encrypt using CBC mode */
2611899Swollman			cbcenc();
2621899Swollman			break;
2631899Swollman		}
2641899Swollman		break;
2651899Swollman	case ALG_CFB:
2661899Swollman		switch(mode) {
2671899Swollman		case MODE_AUTHENTICATE:	/* authenticate using CFB mode */
2681899Swollman			cfbauth();
2691899Swollman			break;
2701899Swollman		case MODE_DECRYPT:	/* decrypt using CFB mode */
2711899Swollman			cfbdec();
2721899Swollman			break;
2731899Swollman		case MODE_ENCRYPT:	/* encrypt using CFB mode */
2741899Swollman			cfbenc();
2751899Swollman			break;
2761899Swollman		}
2771899Swollman		break;
2781899Swollman	case ALG_CFBA:
2791899Swollman		switch(mode) {
2801899Swollman		case MODE_AUTHENTICATE:	/* authenticate using CFBA mode */
281115718Smarkm			errx(1, "can't authenticate with CFBA mode");
2821899Swollman			break;
2831899Swollman		case MODE_DECRYPT:	/* decrypt using CFBA mode */
2841899Swollman			cfbadec();
2851899Swollman			break;
2861899Swollman		case MODE_ENCRYPT:	/* encrypt using CFBA mode */
2871899Swollman			cfbaenc();
2881899Swollman			break;
2891899Swollman		}
2901899Swollman		break;
2911899Swollman	case ALG_ECB:
2921899Swollman		switch(mode) {
2931899Swollman		case MODE_AUTHENTICATE:	/* authenticate using ECB mode */
294115718Smarkm			errx(1, "can't authenticate with ECB mode");
2951899Swollman			break;
2961899Swollman		case MODE_DECRYPT:	/* decrypt using ECB mode */
2971899Swollman			ecbdec();
2981899Swollman			break;
2991899Swollman		case MODE_ENCRYPT:	/* encrypt using ECB mode */
3001899Swollman			ecbenc();
3011899Swollman			break;
3021899Swollman		}
3031899Swollman		break;
3041899Swollman	case ALG_OFB:
3051899Swollman		switch(mode) {
3061899Swollman		case MODE_AUTHENTICATE:	/* authenticate using OFB mode */
307115718Smarkm			errx(1, "can't authenticate with OFB mode");
3081899Swollman			break;
3091899Swollman		case MODE_DECRYPT:	/* decrypt using OFB mode */
3101899Swollman			ofbdec();
3111899Swollman			break;
3121899Swollman		case MODE_ENCRYPT:	/* encrypt using OFB mode */
3131899Swollman			ofbenc();
3141899Swollman			break;
3151899Swollman		}
3161899Swollman		break;
3171899Swollman	}
318115718Smarkm	return (0);
3191899Swollman}
3201899Swollman
3211899Swollman/*
3221899Swollman * map a hex character to an integer
3231899Swollman */
324115718Smarkmstatic int
325115718Smarkmtobinhex(char c, int radix)
3261899Swollman{
3271899Swollman	switch(c) {
3281899Swollman	case '0':		return(0x0);
3291899Swollman	case '1':		return(0x1);
3301899Swollman	case '2':		return(radix > 2 ? 0x2 : -1);
3311899Swollman	case '3':		return(radix > 3 ? 0x3 : -1);
3321899Swollman	case '4':		return(radix > 4 ? 0x4 : -1);
3331899Swollman	case '5':		return(radix > 5 ? 0x5 : -1);
3341899Swollman	case '6':		return(radix > 6 ? 0x6 : -1);
3351899Swollman	case '7':		return(radix > 7 ? 0x7 : -1);
3361899Swollman	case '8':		return(radix > 8 ? 0x8 : -1);
3371899Swollman	case '9':		return(radix > 9 ? 0x9 : -1);
3381899Swollman	case 'A': case 'a':	return(radix > 10 ? 0xa : -1);
3391899Swollman	case 'B': case 'b':	return(radix > 11 ? 0xb : -1);
3401899Swollman	case 'C': case 'c':	return(radix > 12 ? 0xc : -1);
3411899Swollman	case 'D': case 'd':	return(radix > 13 ? 0xd : -1);
3421899Swollman	case 'E': case 'e':	return(radix > 14 ? 0xe : -1);
3431899Swollman	case 'F': case 'f':	return(radix > 15 ? 0xf : -1);
3441899Swollman	}
3451899Swollman	/*
3461899Swollman	 * invalid character
3471899Swollman	 */
3481899Swollman	return(-1);
3491899Swollman}
3501899Swollman
3511899Swollman/*
3521899Swollman * convert the key to a bit pattern
3531899Swollman */
354115718Smarkmstatic void
355115718Smarkmcvtkey(DES_cblock obuf, char *ibuf)
3561899Swollman{
357115718Smarkm	int i, j;			/* counter in a for loop */
3581899Swollman	int nbuf[64];			/* used for hex/key translation */
3591899Swollman
3601899Swollman	/*
3611899Swollman	 * just switch on the key base
3621899Swollman	 */
3631899Swollman	switch(keybase) {
3641899Swollman	case KEY_ASCII:			/* ascii to integer */
3651899Swollman		(void)strncpy(obuf, ibuf, 8);
3661899Swollman		return;
3671899Swollman	case KEY_DEFAULT:		/* tell from context */
3681899Swollman		/*
3691899Swollman		 * leading '0x' or '0X' == hex key
3701899Swollman		 */
3711899Swollman		if (ibuf[0] == '0' && (ibuf[1] == 'x' || ibuf[1] == 'X')) {
3721899Swollman			ibuf = &ibuf[2];
3731899Swollman			/*
3741899Swollman			 * now translate it, bombing on any illegal hex digit
3751899Swollman			 */
3761899Swollman			for (i = 0; ibuf[i] && i < 16; i++)
3771899Swollman				if ((nbuf[i] = tobinhex(ibuf[i], 16)) == -1)
378115718Smarkm					warnx("bad hex digit in key");
3791899Swollman			while (i < 16)
3801899Swollman				nbuf[i++] = 0;
3811899Swollman			for (i = 0; i < 8; i++)
3821899Swollman				obuf[i] =
3831899Swollman				    ((nbuf[2*i]&0xf)<<4) | (nbuf[2*i+1]&0xf);
3841899Swollman			/* preserve parity bits */
3851899Swollman			pflag = 1;
3861899Swollman			return;
3871899Swollman		}
3881899Swollman		/*
3891899Swollman		 * leading '0b' or '0B' == binary key
3901899Swollman		 */
3911899Swollman		if (ibuf[0] == '0' && (ibuf[1] == 'b' || ibuf[1] == 'B')) {
3921899Swollman			ibuf = &ibuf[2];
3931899Swollman			/*
3941899Swollman			 * now translate it, bombing on any illegal binary digit
3951899Swollman			 */
3961899Swollman			for (i = 0; ibuf[i] && i < 16; i++)
3971899Swollman				if ((nbuf[i] = tobinhex(ibuf[i], 2)) == -1)
398115718Smarkm					warnx("bad binary digit in key");
3991899Swollman			while (i < 64)
4001899Swollman				nbuf[i++] = 0;
4011899Swollman			for (i = 0; i < 8; i++)
4021899Swollman				for (j = 0; j < 8; j++)
4031899Swollman					obuf[i] = (obuf[i]<<1)|nbuf[8*i+j];
4041899Swollman			/* preserve parity bits */
4051899Swollman			pflag = 1;
4061899Swollman			return;
4071899Swollman		}
4081899Swollman		/*
4091899Swollman		 * no special leader -- ASCII
4101899Swollman		 */
4111899Swollman		(void)strncpy(obuf, ibuf, 8);
4121899Swollman	}
4131899Swollman}
4141899Swollman
4151899Swollman/*
4161899Swollman * convert an ASCII string into a decimal number:
4171899Swollman * 1. must be between 0 and 64 inclusive
4181899Swollman * 2. must be a valid decimal number
4191899Swollman * 3. must be a multiple of mult
4201899Swollman */
421115718Smarkmstatic int
422115718Smarkmsetbits(char *s, int mult)
4231899Swollman{
424115718Smarkm	char *p;			/* pointer in a for loop */
425115718Smarkm	int n = 0;			/* the integer collected */
4261899Swollman
4271899Swollman	/*
4281899Swollman	 * skip white space
4291899Swollman	 */
4301899Swollman	while (isspace(*s))
4311899Swollman		s++;
4321899Swollman	/*
4331899Swollman	 * get the integer
4341899Swollman	 */
4351899Swollman	for (p = s; *p; p++) {
4361899Swollman		if (isdigit(*p))
4371899Swollman			n = n * 10 + *p - '0';
4381899Swollman		else {
439115718Smarkm			warnx("bad decimal digit in MAC length");
4401899Swollman		}
4411899Swollman	}
4421899Swollman	/*
4431899Swollman	 * be sure it's a multiple of mult
4441899Swollman	 */
4451899Swollman	return((n % mult != 0) ? -1 : n);
4461899Swollman}
4471899Swollman
4481899Swollman/*****************
4491899Swollman * DES FUNCTIONS *
4501899Swollman *****************/
4511899Swollman/*
4521899Swollman * This sets the DES key and (if you're using the deszip version)
4531899Swollman * the direction of the transformation.  This uses the Sun
4541899Swollman * to map the 64-bit key onto the 56 bits that the key schedule
4551899Swollman * generation routines use: the old way, which just uses the user-
4561899Swollman * supplied 64 bits as is, and the new way, which resets the parity
4571899Swollman * bit to be the same as the low-order bit in each character.  The
4581899Swollman * new way generates a greater variety of key schedules, since many
4591899Swollman * systems set the parity (high) bit of each character to 0, and the
4601899Swollman * DES ignores the low order bit of each character.
4611899Swollman */
462115718Smarkmstatic void
463115718Smarkmmakekey(DES_cblock *buf)
4641899Swollman{
465115718Smarkm	int i, j;				/* counter in a for loop */
466115718Smarkm	int par;				/* parity counter */
4671899Swollman
4681899Swollman	/*
4691899Swollman	 * if the parity is not preserved, flip it
4701899Swollman	 */
4711899Swollman	if (!pflag) {
4721899Swollman		for (i = 0; i < 8; i++) {
4731899Swollman			par = 0;
4741899Swollman			for (j = 1; j < 8; j++)
475115718Smarkm				if ((bits[j] & (*buf)[i]) != 0)
4761899Swollman					par++;
477115718Smarkm			if ((par & 0x01) == 0x01)
478115718Smarkm				(*buf)[i] &= 0x7f;
4791899Swollman			else
480115718Smarkm				(*buf)[i] = ((*buf)[i] & 0x7f) | 0x80;
4811899Swollman		}
4821899Swollman	}
4831899Swollman
484115718Smarkm	DES_set_odd_parity(buf);
485115718Smarkm	DES_set_key(buf, &schedule);
4861899Swollman}
4871899Swollman
4881899Swollman/*
4891899Swollman * This encrypts using the Electronic Code Book mode of DES
4901899Swollman */
491115718Smarkmstatic void
492115718Smarkmecbenc(void)
4931899Swollman{
494115718Smarkm	int n;				/* number of bytes actually read */
495115718Smarkm	int bn;				/* block number */
496115718Smarkm	DES_cblock msgbuf;		/* I/O buffer */
4971899Swollman
498115718Smarkm	for (bn = 0; (n = READ(msgbuf,  8)) == 8; bn++) {
4991899Swollman		/*
5001899Swollman		 * do the transformation
5011899Swollman		 */
502115718Smarkm		DES_XFORM(&msgbuf);
503115718Smarkm		WRITE(&msgbuf, 8);
5041899Swollman	}
5051899Swollman	/*
50646064Skris	 * at EOF or last block -- in either case, the last byte contains
5071899Swollman	 * the character representation of the number of bytes in it
5081899Swollman	 */
5091899Swollman	bn++;
510115718Smarkm	MEMZERO(&msgbuf[n], 8 - n);
511115718Smarkm	msgbuf[7] = n;
512115718Smarkm	DES_XFORM(&msgbuf);
513115718Smarkm	WRITE(&msgbuf, 8);
5141899Swollman
5151899Swollman}
5161899Swollman
5171899Swollman/*
5181899Swollman * This decrypts using the Electronic Code Book mode of DES
5191899Swollman */
520115718Smarkmstatic void
521115718Smarkmecbdec(void)
5221899Swollman{
523115718Smarkm	int n;			/* number of bytes actually read */
524115718Smarkm	int c;			/* used to test for EOF */
525115718Smarkm	int bn;			/* block number */
526115718Smarkm	DES_cblock msgbuf;		/* I/O buffer */
5271899Swollman
528115718Smarkm	for (bn = 1; (n = READ(msgbuf, 8)) == 8; bn++) {
5291899Swollman		/*
5301899Swollman		 * do the transformation
5311899Swollman		 */
532115718Smarkm		DES_XFORM(&msgbuf);
5331899Swollman		/*
5341899Swollman		 * if the last one, handle it specially
5351899Swollman		 */
5361899Swollman		if ((c = getchar()) == EOF) {
537115718Smarkm			n = msgbuf[7];
5381899Swollman			if (n < 0 || n > 7)
539115718Smarkm				warnx("decryption failed (block corrupt) at %d",
540115718Smarkm				    bn);
5411899Swollman		}
5421899Swollman		else
5431899Swollman			(void)ungetc(c, stdin);
544115718Smarkm		WRITE(msgbuf, n);
5451899Swollman	}
5461899Swollman	if (n > 0)
547115718Smarkm		warnx("decryption failed (incomplete block) at %d", bn);
5481899Swollman}
5491899Swollman
5501899Swollman/*
5511899Swollman * This encrypts using the Cipher Block Chaining mode of DES
5521899Swollman */
553115718Smarkmstatic void
554115718Smarkmcbcenc(void)
5551899Swollman{
556115718Smarkm	int n;			/* number of bytes actually read */
557115718Smarkm	int bn;			/* block number */
558115718Smarkm	DES_cblock msgbuf;	/* I/O buffer */
5591899Swollman
5601899Swollman	/*
5611899Swollman	 * do the transformation
5621899Swollman	 */
563115718Smarkm	for (bn = 1; (n = READ(msgbuf, 8)) == 8; bn++) {
5641899Swollman		for (n = 0; n < 8; n++)
565115718Smarkm			msgbuf[n] ^= ivec[n];
566115718Smarkm		DES_XFORM(&msgbuf);
567115718Smarkm		MEMCPY(ivec, msgbuf, 8);
568115718Smarkm		WRITE(msgbuf, 8);
5691899Swollman	}
5701899Swollman	/*
5711899Swollman	 * at EOF or last block -- in either case, the last byte contains
5721899Swollman	 * the character representation of the number of bytes in it
5731899Swollman	 */
5741899Swollman	bn++;
575115718Smarkm	MEMZERO(&msgbuf[n], 8 - n);
576115718Smarkm	msgbuf[7] = n;
5771899Swollman	for (n = 0; n < 8; n++)
578115718Smarkm		msgbuf[n] ^= ivec[n];
579115718Smarkm	DES_XFORM(&msgbuf);
580115718Smarkm	WRITE(msgbuf, 8);
5811899Swollman
5821899Swollman}
5831899Swollman
5841899Swollman/*
5851899Swollman * This decrypts using the Cipher Block Chaining mode of DES
5861899Swollman */
587115718Smarkmstatic void
588115718Smarkmcbcdec(void)
5891899Swollman{
590115718Smarkm	int n;			/* number of bytes actually read */
591115718Smarkm	DES_cblock msgbuf;	/* I/O buffer */
592115718Smarkm	DES_cblock ibuf;	/* temp buffer for initialization vector */
593115718Smarkm	int c;			/* used to test for EOF */
594115718Smarkm	int bn;			/* block number */
5951899Swollman
596115718Smarkm	for (bn = 0; (n = READ(msgbuf, 8)) == 8; bn++) {
5971899Swollman		/*
5981899Swollman		 * do the transformation
5991899Swollman		 */
600115718Smarkm		MEMCPY(ibuf, msgbuf, 8);
601115718Smarkm		DES_XFORM(&msgbuf);
6021899Swollman		for (c = 0; c < 8; c++)
603115718Smarkm			msgbuf[c] ^= ivec[c];
604115718Smarkm		MEMCPY(ivec, ibuf, 8);
6051899Swollman		/*
6061899Swollman		 * if the last one, handle it specially
6071899Swollman		 */
6081899Swollman		if ((c = getchar()) == EOF) {
609115718Smarkm			n = msgbuf[7];
6101899Swollman			if (n < 0 || n > 7)
611115718Smarkm				warnx("decryption failed (block corrupt) at %d",
612115718Smarkm				    bn);
6131899Swollman		}
6141899Swollman		else
6151899Swollman			(void)ungetc(c, stdin);
616115718Smarkm		WRITE(msgbuf, n);
6171899Swollman	}
6181899Swollman	if (n > 0)
619115718Smarkm		warnx("decryption failed (incomplete block) at %d", bn);
6201899Swollman}
6211899Swollman
6221899Swollman/*
6231899Swollman * This authenticates using the Cipher Block Chaining mode of DES
6241899Swollman */
625115718Smarkmstatic void
626115718Smarkmcbcauth(void)
6271899Swollman{
628115718Smarkm	int n, j;		/* number of bytes actually read */
629115718Smarkm	DES_cblock msgbuf;		/* I/O buffer */
630115718Smarkm	DES_cblock encbuf;		/* encryption buffer */
6311899Swollman
6321899Swollman	/*
6331899Swollman	 * do the transformation
6341899Swollman	 * note we DISCARD the encrypted block;
6351899Swollman	 * we only care about the last one
6361899Swollman	 */
637115718Smarkm	while ((n = READ(msgbuf, 8)) == 8) {
6381899Swollman		for (n = 0; n < 8; n++)
639115718Smarkm			encbuf[n] = msgbuf[n] ^ ivec[n];
640115718Smarkm		DES_XFORM(&encbuf);
641115718Smarkm		MEMCPY(ivec, encbuf, 8);
6421899Swollman	}
6431899Swollman	/*
6441899Swollman	 * now compute the last one, right padding with '\0' if need be
6451899Swollman	 */
6461899Swollman	if (n > 0) {
647115718Smarkm		MEMZERO(&msgbuf[n], 8 - n);
6481899Swollman		for (n = 0; n < 8; n++)
649115718Smarkm			encbuf[n] = msgbuf[n] ^ ivec[n];
650115718Smarkm		DES_XFORM(&encbuf);
6511899Swollman	}
6521899Swollman	/*
6531899Swollman	 * drop the bits
6541899Swollman	 * we write chars until fewer than 7 bits,
6551899Swollman	 * and then pad the last one with 0 bits
6561899Swollman	 */
6571899Swollman	for (n = 0; macbits > 7; n++, macbits -= 8)
658115718Smarkm		(void)putchar(encbuf[n]);
6591899Swollman	if (macbits > 0) {
660115718Smarkm		msgbuf[0] = 0x00;
6611899Swollman		for (j = 0; j < macbits; j++)
662115718Smarkm			msgbuf[0] |= encbuf[n] & bits[j];
663115718Smarkm		(void)putchar(msgbuf[0]);
6641899Swollman	}
6651899Swollman}
6661899Swollman
6671899Swollman/*
6681899Swollman * This encrypts using the Cipher FeedBack mode of DES
6691899Swollman */
670115718Smarkmstatic void
671115718Smarkmcfbenc(void)
6721899Swollman{
673115718Smarkm	int n;			/* number of bytes actually read */
674115718Smarkm	int nbytes;		/* number of bytes to read */
675115718Smarkm	int bn;			/* block number */
6761899Swollman	char ibuf[8];		/* input buffer */
677115718Smarkm	DES_cblock msgbuf;		/* encryption buffer */
6781899Swollman
6791899Swollman	/*
6801899Swollman	 * do things in bytes, not bits
6811899Swollman	 */
6821899Swollman	nbytes = fbbits / 8;
6831899Swollman	/*
6841899Swollman	 * do the transformation
6851899Swollman	 */
6861899Swollman	for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) {
687115718Smarkm		MEMCPY(msgbuf, ivec, 8);
688115718Smarkm		DES_XFORM(&msgbuf);
6891899Swollman		for (n = 0; n < 8 - nbytes; n++)
690115718Smarkm			ivec[n] = ivec[n+nbytes];
6911899Swollman		for (n = 0; n < nbytes; n++)
692115718Smarkm			ivec[8 - nbytes + n] = ibuf[n] ^ msgbuf[n];
693115718Smarkm		WRITE(&ivec[8 - nbytes], nbytes);
6941899Swollman	}
6951899Swollman	/*
6961899Swollman	 * at EOF or last block -- in either case, the last byte contains
6971899Swollman	 * the character representation of the number of bytes in it
6981899Swollman	 */
6991899Swollman	bn++;
7001899Swollman	MEMZERO(&ibuf[n], nbytes - n);
7011899Swollman	ibuf[nbytes - 1] = n;
702115718Smarkm	MEMCPY(msgbuf, ivec, 8);
703115718Smarkm	DES_XFORM(&msgbuf);
7041899Swollman	for (n = 0; n < nbytes; n++)
705115718Smarkm		ibuf[n] ^= msgbuf[n];
7061899Swollman	WRITE(ibuf, nbytes);
7071899Swollman}
7081899Swollman
7091899Swollman/*
7101899Swollman * This decrypts using the Cipher Block Chaining mode of DES
7111899Swollman */
712115718Smarkmstatic void
713115718Smarkmcfbdec(void)
7141899Swollman{
715115718Smarkm	int n;			/* number of bytes actually read */
716115718Smarkm	int c;			/* used to test for EOF */
717115718Smarkm	int nbytes;		/* number of bytes to read */
718115718Smarkm	int bn;			/* block number */
7191899Swollman	char ibuf[8];		/* input buffer */
7201899Swollman	char obuf[8];		/* output buffer */
721115718Smarkm	DES_cblock msgbuf;		/* encryption buffer */
7221899Swollman
7231899Swollman	/*
7241899Swollman	 * do things in bytes, not bits
7251899Swollman	 */
7261899Swollman	nbytes = fbbits / 8;
7271899Swollman	/*
7281899Swollman	 * do the transformation
7291899Swollman	 */
7301899Swollman	for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) {
731115718Smarkm		MEMCPY(msgbuf, ivec, 8);
732115718Smarkm		DES_XFORM(&msgbuf);
7331899Swollman		for (c = 0; c < 8 - nbytes; c++)
734115718Smarkm			ivec[c] = ivec[c + nbytes];
7351899Swollman		for (c = 0; c < nbytes; c++) {
736115718Smarkm			ivec[8 - nbytes + c] = ibuf[c];
737115718Smarkm			obuf[c] = ibuf[c] ^ msgbuf[c];
7381899Swollman		}
7391899Swollman		/*
7401899Swollman		 * if the last one, handle it specially
7411899Swollman		 */
7421899Swollman		if ((c = getchar()) == EOF) {
7431899Swollman			n = obuf[nbytes-1];
7441899Swollman			if (n < 0 || n > nbytes-1)
745115718Smarkm				warnx("decryption failed (block corrupt) at %d",
746115718Smarkm				    bn);
7471899Swollman		}
7481899Swollman		else
7491899Swollman			(void)ungetc(c, stdin);
7501899Swollman		WRITE(obuf, n);
7511899Swollman	}
7521899Swollman	if (n > 0)
753115718Smarkm		warnx("decryption failed (incomplete block) at %d", bn);
7541899Swollman}
7551899Swollman
7561899Swollman/*
7571899Swollman * This encrypts using the alternative Cipher FeedBack mode of DES
7581899Swollman */
759115718Smarkmstatic void
760115718Smarkmcfbaenc(void)
7611899Swollman{
762115718Smarkm	int n;			/* number of bytes actually read */
763115718Smarkm	int nbytes;		/* number of bytes to read */
764115718Smarkm	int bn;			/* block number */
7651899Swollman	char ibuf[8];		/* input buffer */
7661899Swollman	char obuf[8];		/* output buffer */
767115718Smarkm	DES_cblock msgbuf;		/* encryption buffer */
7681899Swollman
7691899Swollman	/*
7701899Swollman	 * do things in bytes, not bits
7711899Swollman	 */
7721899Swollman	nbytes = fbbits / 7;
7731899Swollman	/*
7741899Swollman	 * do the transformation
7751899Swollman	 */
7761899Swollman	for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) {
777115718Smarkm		MEMCPY(msgbuf, ivec, 8);
778115718Smarkm		DES_XFORM(&msgbuf);
7791899Swollman		for (n = 0; n < 8 - nbytes; n++)
780115718Smarkm			ivec[n] = ivec[n + nbytes];
7811899Swollman		for (n = 0; n < nbytes; n++)
782115718Smarkm			ivec[8 - nbytes + n] = (ibuf[n] ^ msgbuf[n]) | 0x80;
7831899Swollman		for (n = 0; n < nbytes; n++)
784115718Smarkm			obuf[n] = ivec[8 - nbytes + n] & 0x7f;
7851899Swollman		WRITE(obuf, nbytes);
7861899Swollman	}
7871899Swollman	/*
7881899Swollman	 * at EOF or last block -- in either case, the last byte contains
7891899Swollman	 * the character representation of the number of bytes in it
7901899Swollman	 */
7911899Swollman	bn++;
7921899Swollman	MEMZERO(&ibuf[n], nbytes - n);
7931899Swollman	ibuf[nbytes - 1] = ('0' + n)|0200;
794115718Smarkm	MEMCPY(msgbuf, ivec, 8);
795115718Smarkm	DES_XFORM(&msgbuf);
7961899Swollman	for (n = 0; n < nbytes; n++)
797115718Smarkm		ibuf[n] ^= msgbuf[n];
7981899Swollman	WRITE(ibuf, nbytes);
7991899Swollman}
8001899Swollman
8011899Swollman/*
8021899Swollman * This decrypts using the alternative Cipher Block Chaining mode of DES
8031899Swollman */
804115718Smarkmstatic void
805115718Smarkmcfbadec(void)
8061899Swollman{
807115718Smarkm	int n;			/* number of bytes actually read */
808115718Smarkm	int c;			/* used to test for EOF */
809115718Smarkm	int nbytes;		/* number of bytes to read */
810115718Smarkm	int bn;			/* block number */
8111899Swollman	char ibuf[8];		/* input buffer */
8121899Swollman	char obuf[8];		/* output buffer */
813115718Smarkm	DES_cblock msgbuf;		/* encryption buffer */
8141899Swollman
8151899Swollman	/*
8161899Swollman	 * do things in bytes, not bits
8171899Swollman	 */
8181899Swollman	nbytes = fbbits / 7;
8191899Swollman	/*
8201899Swollman	 * do the transformation
8211899Swollman	 */
8221899Swollman	for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) {
823115718Smarkm		MEMCPY(msgbuf, ivec, 8);
824115718Smarkm		DES_XFORM(&msgbuf);
8251899Swollman		for (c = 0; c < 8 - nbytes; c++)
826115718Smarkm			ivec[c] = ivec[c + nbytes];
8271899Swollman		for (c = 0; c < nbytes; c++) {
828115718Smarkm			ivec[8 - nbytes + c] = ibuf[c] | 0x80;
829115718Smarkm			obuf[c] = (ibuf[c] ^ msgbuf[c]) & 0x7f;
8301899Swollman		}
8311899Swollman		/*
8321899Swollman		 * if the last one, handle it specially
8331899Swollman		 */
8341899Swollman		if ((c = getchar()) == EOF) {
8351899Swollman			if ((n = (obuf[nbytes-1] - '0')) < 0
8361899Swollman						|| n > nbytes-1)
837115718Smarkm				warnx("decryption failed (block corrupt) at %d",
838115718Smarkm				    bn);
8391899Swollman		}
8401899Swollman		else
8411899Swollman			(void)ungetc(c, stdin);
8421899Swollman		WRITE(obuf, n);
8431899Swollman	}
8441899Swollman	if (n > 0)
845115718Smarkm		warnx("decryption failed (incomplete block) at %d", bn);
8461899Swollman}
8471899Swollman
8481899Swollman
8491899Swollman/*
8501899Swollman * This encrypts using the Output FeedBack mode of DES
8511899Swollman */
852115718Smarkmstatic void
853115718Smarkmofbenc(void)
8541899Swollman{
855115718Smarkm	int n;			/* number of bytes actually read */
856115718Smarkm	int c;			/* used to test for EOF */
857115718Smarkm	int nbytes;		/* number of bytes to read */
858115718Smarkm	int bn;			/* block number */
8591899Swollman	char ibuf[8];		/* input buffer */
8601899Swollman	char obuf[8];		/* output buffer */
861115718Smarkm	DES_cblock msgbuf;		/* encryption buffer */
8621899Swollman
8631899Swollman	/*
8641899Swollman	 * do things in bytes, not bits
8651899Swollman	 */
8661899Swollman	nbytes = fbbits / 8;
8671899Swollman	/*
8681899Swollman	 * do the transformation
8691899Swollman	 */
8701899Swollman	for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) {
871115718Smarkm		MEMCPY(msgbuf, ivec, 8);
872115718Smarkm		DES_XFORM(&msgbuf);
8731899Swollman		for (n = 0; n < 8 - nbytes; n++)
874115718Smarkm			ivec[n] = ivec[n + nbytes];
8751899Swollman		for (n = 0; n < nbytes; n++) {
876115718Smarkm			ivec[8 - nbytes + n] = msgbuf[n];
877115718Smarkm			obuf[n] = ibuf[n] ^ msgbuf[n];
8781899Swollman		}
8791899Swollman		WRITE(obuf, nbytes);
8801899Swollman	}
8811899Swollman	/*
8821899Swollman	 * at EOF or last block -- in either case, the last byte contains
8831899Swollman	 * the character representation of the number of bytes in it
8841899Swollman	 */
8851899Swollman	bn++;
8861899Swollman	MEMZERO(&ibuf[n], nbytes - n);
8871899Swollman	ibuf[nbytes - 1] = n;
888115718Smarkm	MEMCPY(msgbuf, ivec, 8);
889115718Smarkm	DES_XFORM(&msgbuf);
8901899Swollman	for (c = 0; c < nbytes; c++)
891115718Smarkm		ibuf[c] ^= msgbuf[c];
8921899Swollman	WRITE(ibuf, nbytes);
8931899Swollman}
8941899Swollman
8951899Swollman/*
8961899Swollman * This decrypts using the Output Block Chaining mode of DES
8971899Swollman */
898115718Smarkmstatic void
899115718Smarkmofbdec(void)
9001899Swollman{
901115718Smarkm	int n;			/* number of bytes actually read */
902115718Smarkm	int c;			/* used to test for EOF */
903115718Smarkm	int nbytes;		/* number of bytes to read */
904115718Smarkm	int bn;			/* block number */
9051899Swollman	char ibuf[8];		/* input buffer */
9061899Swollman	char obuf[8];		/* output buffer */
907115718Smarkm	DES_cblock msgbuf;		/* encryption buffer */
9081899Swollman
9091899Swollman	/*
9101899Swollman	 * do things in bytes, not bits
9111899Swollman	 */
9121899Swollman	nbytes = fbbits / 8;
9131899Swollman	/*
9141899Swollman	 * do the transformation
9151899Swollman	 */
9161899Swollman	for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) {
917115718Smarkm		MEMCPY(msgbuf, ivec, 8);
918115718Smarkm		DES_XFORM(&msgbuf);
9191899Swollman		for (c = 0; c < 8 - nbytes; c++)
920115718Smarkm			ivec[c] = ivec[c + nbytes];
9211899Swollman		for (c = 0; c < nbytes; c++) {
922115718Smarkm			ivec[8 - nbytes + c] = msgbuf[c];
923115718Smarkm			obuf[c] = ibuf[c] ^ msgbuf[c];
9241899Swollman		}
9251899Swollman		/*
9261899Swollman		 * if the last one, handle it specially
9271899Swollman		 */
9281899Swollman		if ((c = getchar()) == EOF) {
9291899Swollman			n = obuf[nbytes-1];
9301899Swollman			if (n < 0 || n > nbytes-1)
931115718Smarkm				warnx("decryption failed (block corrupt) at %d",
932115718Smarkm				    bn);
9331899Swollman		}
9341899Swollman		else
9351899Swollman			(void)ungetc(c, stdin);
9361899Swollman		/*
9371899Swollman		 * dump it
9381899Swollman		 */
9391899Swollman		WRITE(obuf, n);
9401899Swollman	}
9411899Swollman	if (n > 0)
942115718Smarkm		warnx("decryption failed (incomplete block) at %d", bn);
9431899Swollman}
9441899Swollman
9451899Swollman/*
9461899Swollman * This authenticates using the Cipher FeedBack mode of DES
9471899Swollman */
948115718Smarkmstatic void
949115718Smarkmcfbauth(void)
9501899Swollman{
951115718Smarkm	int n, j;		/* number of bytes actually read */
952115718Smarkm	int nbytes;		/* number of bytes to read */
9531899Swollman	char ibuf[8];		/* input buffer */
954115718Smarkm	DES_cblock msgbuf;	/* encryption buffer */
9551899Swollman
9561899Swollman	/*
9571899Swollman	 * do things in bytes, not bits
9581899Swollman	 */
9591899Swollman	nbytes = fbbits / 8;
9601899Swollman	/*
9611899Swollman	 * do the transformation
9621899Swollman	 */
9631899Swollman	while ((n = READ(ibuf, nbytes)) == nbytes) {
964115718Smarkm		MEMCPY(msgbuf, ivec, 8);
965115718Smarkm		DES_XFORM(&msgbuf);
9661899Swollman		for (n = 0; n < 8 - nbytes; n++)
967115718Smarkm			ivec[n] = ivec[n + nbytes];
9681899Swollman		for (n = 0; n < nbytes; n++)
969115718Smarkm			ivec[8 - nbytes + n] = ibuf[n] ^ msgbuf[n];
9701899Swollman	}
9711899Swollman	/*
9721899Swollman	 * at EOF or last block -- in either case, the last byte contains
9731899Swollman	 * the character representation of the number of bytes in it
9741899Swollman	 */
9751899Swollman	MEMZERO(&ibuf[n], nbytes - n);
9761899Swollman	ibuf[nbytes - 1] = '0' + n;
977115718Smarkm	MEMCPY(msgbuf, ivec, 8);
978115718Smarkm	DES_XFORM(&msgbuf);
9791899Swollman	for (n = 0; n < nbytes; n++)
980115718Smarkm		ibuf[n] ^= msgbuf[n];
9811899Swollman	/*
9821899Swollman	 * drop the bits
9831899Swollman	 * we write chars until fewer than 7 bits,
9841899Swollman	 * and then pad the last one with 0 bits
9851899Swollman	 */
9861899Swollman	for (n = 0; macbits > 7; n++, macbits -= 8)
987115718Smarkm		(void)putchar(msgbuf[n]);
9881899Swollman	if (macbits > 0) {
989115718Smarkm		msgbuf[0] = 0x00;
9901899Swollman		for (j = 0; j < macbits; j++)
991115718Smarkm			msgbuf[0] |= msgbuf[n] & bits[j];
992115718Smarkm		(void)putchar(msgbuf[0]);
9931899Swollman	}
9941899Swollman}
9951899Swollman
9961899Swollman/*
9971899Swollman * message about usage
9981899Swollman */
999115718Smarkmstatic void
1000115718Smarkmusage(void)
10011899Swollman{
10028871Srgrimes	(void)fprintf(stderr, "%s\n",
1003141651Sru"usage: bdes [-abdp] [-F N] [-f N] [-k key] [-m N] [-o N] [-v vector]");
10041899Swollman	exit(1);
10051899Swollman}
1006