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
main(ac,av)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 */
err(n,s)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 */
tobinhex(c,radix)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 */
cvtkey(obuf,ibuf)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 */
setbits(s,mult)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 */
makekey(buf)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 */
ecbenc()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 */
ecbdec()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 */
cbcenc()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 */
cbcdec()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 */
cbcauth()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 */
cfbenc()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 */
cfbdec()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 */
cfbaenc()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 */
cfbadec()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 */
ofbenc()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 */
ofbdec()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 */
cfbauth()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 */
expand(from,to)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 */
compress(from,to)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 */
usage()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