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