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