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