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