2 * Copyright (c) 1991, 1993
3 * The Regents of the University of California. All rights reserved.
5 * This code is derived from software contributed to Berkeley by
6 * Matt Bishop of Dartmouth College.
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.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. All advertising materials mentioning features or use of this software
21 * must display the following acknowledgement:
22 * This product includes software developed by the University of
23 * California, Berkeley and its contributors.
24 * 4. Neither the name of the University nor the names of its contributors
25 * may be used to endorse or promote products derived from this software
26 * without specific prior written permission.
28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
42 static char copyright[] =
43 "@(#) Copyright (c) 1991, 1993\n\
44 The Regents of the University of California. All rights reserved.\n";
49 static char sccsid[] = "@(#)bdes.c 8.1 (Berkeley) 6/6/93";
51 static const char rcsid[] =
52 "$FreeBSD: src/secure/usr.bin/bdes/bdes.c,v 1.3.2.1 2000/09/22 09:42:03 kris Exp $";
57 * BDES -- DES encryption package for Berkeley Software Distribution 4.4
60 * -b use ECB (electronic code book) mode
61 * -d invert (decrypt) input
62 * -f b use b-bit CFB (cipher feedback) mode
63 * -F b use b-bit CFB (cipher feedback) alternative mode
64 * -k key use key as the cryptographic key
65 * -m b generate a MAC of length b
66 * -o b use b-bit OFB (output feedback) mode
67 * -p don't reset the parity bit
68 * -v v use v as the initialization vector (ignored for ECB)
69 * note: the last character of the last block is the integer indicating
70 * how many characters of that block are to be output
73 * Department of Mathematics and Computer Science
76 * Email: Matt.Bishop@dartmouth.edu
77 * ...!decvax!dartvax!Matt.Bishop
79 * See Technical Report PCS-TR91-158, Department of Mathematics and Computer
80 * Science, Dartmouth College, for a detailed description of the implemen-
81 * tation and differences between it and Sun's. The DES is described in
82 * FIPS PUB 46, and the modes in FIPS PUB 81 (see either the manual page
83 * or the technical report for a complete reference).
94 * BSD and System V systems offer special library calls that do
95 * block moves and fills, so if possible we take advantage of them
97 #define MEMCPY(dest,src,len) bcopy((src),(dest),(len))
98 #define MEMZERO(dest,len) bzero((dest),(len))
100 /* Hide the calls to the primitive encryption routines. */
103 #define DES_KEY(buf) \
104 if (des_setkey(buf)) \
105 err("des_setkey", 0);
106 #define DES_XFORM(buf) \
107 if (des_cipher(buf, buf, 0L, (inverse ? -1 : 1))) \
108 err("des_cipher", 0);
110 #define DES_KEY(buf) { \
111 char bits1[64]; /* bits of key */ \
112 expand(buf, bits1); \
116 #define DES_XFORM(buf) { \
117 char bits1[64]; /* bits of message */ \
118 expand(buf, bits1); \
119 if (encrypt(bits1, inverse)) \
121 compress(bits1, buf); \
126 * this does an error-checking write
128 #define READ(buf, n) fread(buf, sizeof(char), n, stdin)
129 #define WRITE(buf,n) \
130 if (fwrite(buf, sizeof(char), n, stdout) != n) \
134 * some things to make references easier
136 typedef char Desbuf[8];
137 #define CHAR(x,i) (x[i])
138 #define UCHAR(x,i) (x[i])
139 #define BUFFER(x) (x)
140 #define UBUFFER(x) (x)
143 * global variables and related macros
145 #define KEY_DEFAULT 0 /* interpret radix of key from key */
146 #define KEY_ASCII 1 /* key is in ASCII characters */
147 int keybase = KEY_DEFAULT; /* how to interpret the key */
149 enum { /* encrypt, decrypt, authenticate */
150 MODE_ENCRYPT, MODE_DECRYPT, MODE_AUTHENTICATE
151 } mode = MODE_ENCRYPT;
152 enum { /* ecb, cbc, cfb, cfba, ofb? */
153 ALG_ECB, ALG_CBC, ALG_CFB, ALG_OFB, ALG_CFBA
156 Desbuf ivec; /* initialization vector */
157 char bits[] = { /* used to extract bits from a char */
158 '\200', '\100', '\040', '\020', '\010', '\004', '\002', '\001'
160 int inverse; /* 0 to encrypt, 1 to decrypt */
161 int macbits = -1; /* number of bits in authentication */
162 int fbbits = -1; /* number of feedback bits */
163 int pflag; /* 1 to preserve parity bits */
166 int ac; /* arg count */
167 char **av; /* arg vector */
169 extern int optind; /* option (argument) number */
170 extern char *optarg; /* argument to option if any */
171 register int i; /* counter in a for loop */
172 register char *p; /* used to obtain the key */
173 Desbuf msgbuf; /* I/O buffer */
174 int kflag; /* command-line encryptiooon key */
175 int argc; /* the real arg count */
176 char **argv; /* the real argument vector */
179 * Hide the arguments from ps(1) by making private copies of them
180 * and clobbering the global (visible to ps(1)) ones.
184 argv = malloc((argc + 1) * sizeof(char *));
185 for (i = 0; i < argc; ++i) {
186 argv[i] = strdup(av[i]);
187 MEMZERO(av[i], strlen(av[i]));
191 /* initialize the initialization vctor */
194 /* process the argument list */
196 while ((i = getopt(argc, argv, "abdF:f:k:m:o:pv:")) != EOF)
198 case 'a': /* key is ASCII */
201 case 'b': /* use ECB mode */
204 case 'd': /* decrypt */
207 case 'F': /* use alternative CFB mode */
209 if ((fbbits = setbits(optarg, 7)) > 56 || fbbits == 0)
210 err(-1, "-F: number must be 1-56 inclusive");
211 else if (fbbits == -1)
212 err(-1, "-F: number must be a multiple of 7");
214 case 'f': /* use CFB mode */
216 if ((fbbits = setbits(optarg, 8)) > 64 || fbbits == 0)
217 err(-1, "-f: number must be 1-64 inclusive");
218 else if (fbbits == -1)
219 err(-1, "-f: number must be a multiple of 8");
221 case 'k': /* encryption key */
223 cvtkey(BUFFER(msgbuf), optarg);
225 case 'm': /* number of bits for MACing */
226 mode = MODE_AUTHENTICATE;
227 if ((macbits = setbits(optarg, 1)) > 64)
228 err(-1, "-m: number must be 0-64 inclusive");
230 case 'o': /* use OFB mode */
232 if ((fbbits = setbits(optarg, 8)) > 64 || fbbits == 0)
233 err(-1, "-o: number must be 1-64 inclusive");
234 else if (fbbits == -1)
235 err(-1, "-o: number must be a multiple of 8");
237 case 'p': /* preserve parity bits */
240 case 'v': /* set initialization vector */
241 cvtkey(BUFFER(ivec), optarg);
249 * if the key's not ASCII, assume it is
255 p = getpass("Enter key: ");
257 * copy it, nul-padded, into the key area
259 cvtkey(BUFFER(msgbuf), p);
263 inverse = (alg == ALG_CBC || alg == ALG_ECB) && mode == MODE_DECRYPT;
268 case MODE_AUTHENTICATE: /* authenticate using CBC mode */
271 case MODE_DECRYPT: /* decrypt using CBC mode */
274 case MODE_ENCRYPT: /* encrypt using CBC mode */
281 case MODE_AUTHENTICATE: /* authenticate using CFB mode */
284 case MODE_DECRYPT: /* decrypt using CFB mode */
287 case MODE_ENCRYPT: /* encrypt using CFB mode */
294 case MODE_AUTHENTICATE: /* authenticate using CFBA mode */
295 err(-1, "can't authenticate with CFBA mode");
297 case MODE_DECRYPT: /* decrypt using CFBA mode */
300 case MODE_ENCRYPT: /* encrypt using CFBA mode */
307 case MODE_AUTHENTICATE: /* authenticate using ECB mode */
308 err(-1, "can't authenticate with ECB mode");
310 case MODE_DECRYPT: /* decrypt using ECB mode */
313 case MODE_ENCRYPT: /* encrypt using ECB mode */
320 case MODE_AUTHENTICATE: /* authenticate using OFB mode */
321 err(-1, "can't authenticate with OFB mode");
323 case MODE_DECRYPT: /* decrypt using OFB mode */
326 case MODE_ENCRYPT: /* encrypt using OFB mode */
336 * print a warning message and, possibly, terminate
339 int n; /* offending block number */
340 char *s; /* the message */
343 (void)fprintf(stderr, "bdes (block %d): ", n);
345 (void)fprintf(stderr, "bdes: ");
346 (void)fprintf(stderr, "%s\n", s ? s : strerror(errno));
351 * map a hex character to an integer
354 char c; /* char to be converted */
355 int radix; /* base (2 to 16) */
358 case '0': return(0x0);
359 case '1': return(0x1);
360 case '2': return(radix > 2 ? 0x2 : -1);
361 case '3': return(radix > 3 ? 0x3 : -1);
362 case '4': return(radix > 4 ? 0x4 : -1);
363 case '5': return(radix > 5 ? 0x5 : -1);
364 case '6': return(radix > 6 ? 0x6 : -1);
365 case '7': return(radix > 7 ? 0x7 : -1);
366 case '8': return(radix > 8 ? 0x8 : -1);
367 case '9': return(radix > 9 ? 0x9 : -1);
368 case 'A': case 'a': return(radix > 10 ? 0xa : -1);
369 case 'B': case 'b': return(radix > 11 ? 0xb : -1);
370 case 'C': case 'c': return(radix > 12 ? 0xc : -1);
371 case 'D': case 'd': return(radix > 13 ? 0xd : -1);
372 case 'E': case 'e': return(radix > 14 ? 0xe : -1);
373 case 'F': case 'f': return(radix > 15 ? 0xf : -1);
382 * convert the key to a bit pattern
385 char *obuf; /* bit pattern */
386 char *ibuf; /* the key itself */
388 register int i, j; /* counter in a for loop */
389 int nbuf[64]; /* used for hex/key translation */
392 * just switch on the key base
395 case KEY_ASCII: /* ascii to integer */
396 (void)strncpy(obuf, ibuf, 8);
398 case KEY_DEFAULT: /* tell from context */
400 * leading '0x' or '0X' == hex key
402 if (ibuf[0] == '0' && (ibuf[1] == 'x' || ibuf[1] == 'X')) {
405 * now translate it, bombing on any illegal hex digit
407 for (i = 0; ibuf[i] && i < 16; i++)
408 if ((nbuf[i] = tobinhex(ibuf[i], 16)) == -1)
409 err(-1, "bad hex digit in key");
412 for (i = 0; i < 8; i++)
414 ((nbuf[2*i]&0xf)<<4) | (nbuf[2*i+1]&0xf);
415 /* preserve parity bits */
420 * leading '0b' or '0B' == binary key
422 if (ibuf[0] == '0' && (ibuf[1] == 'b' || ibuf[1] == 'B')) {
425 * now translate it, bombing on any illegal binary digit
427 for (i = 0; ibuf[i] && i < 16; i++)
428 if ((nbuf[i] = tobinhex(ibuf[i], 2)) == -1)
429 err(-1, "bad binary digit in key");
432 for (i = 0; i < 8; i++)
433 for (j = 0; j < 8; j++)
434 obuf[i] = (obuf[i]<<1)|nbuf[8*i+j];
435 /* preserve parity bits */
440 * no special leader -- ASCII
442 (void)strncpy(obuf, ibuf, 8);
447 * convert an ASCII string into a decimal number:
448 * 1. must be between 0 and 64 inclusive
449 * 2. must be a valid decimal number
450 * 3. must be a multiple of mult
453 char *s; /* the ASCII string */
454 int mult; /* what it must be a multiple of */
456 register char *p; /* pointer in a for loop */
457 register int n = 0; /* the integer collected */
467 for (p = s; *p; p++) {
469 n = n * 10 + *p - '0';
471 err(-1, "bad decimal digit in MAC length");
475 * be sure it's a multiple of mult
477 return((n % mult != 0) ? -1 : n);
484 * This sets the DES key and (if you're using the deszip version)
485 * the direction of the transformation. This uses the Sun
486 * to map the 64-bit key onto the 56 bits that the key schedule
487 * generation routines use: the old way, which just uses the user-
488 * supplied 64 bits as is, and the new way, which resets the parity
489 * bit to be the same as the low-order bit in each character. The
490 * new way generates a greater variety of key schedules, since many
491 * systems set the parity (high) bit of each character to 0, and the
492 * DES ignores the low order bit of each character.
495 Desbuf buf; /* key block */
497 register int i, j; /* counter in a for loop */
498 register int par; /* parity counter */
501 * if the parity is not preserved, flip it
504 for (i = 0; i < 8; i++) {
506 for (j = 1; j < 8; j++)
507 if ((bits[j]&UCHAR(buf, i)) != 0)
510 UCHAR(buf, i) = UCHAR(buf, i)&0177;
512 UCHAR(buf, i) = (UCHAR(buf, i)&0177)|0200;
516 DES_KEY(UBUFFER(buf));
520 * This encrypts using the Electronic Code Book mode of DES
524 register int n; /* number of bytes actually read */
525 register int bn; /* block number */
526 Desbuf msgbuf; /* I/O buffer */
528 for (bn = 0; (n = READ(BUFFER(msgbuf), 8)) == 8; bn++) {
530 * do the transformation
532 DES_XFORM(UBUFFER(msgbuf));
533 WRITE(BUFFER(msgbuf), 8);
536 * at EOF or last block -- in either case, the last byte contains
537 * the character representation of the number of bytes in it
540 MEMZERO(&CHAR(msgbuf, n), 8 - n);
542 DES_XFORM(UBUFFER(msgbuf));
543 WRITE(BUFFER(msgbuf), 8);
548 * This decrypts using the Electronic Code Book mode of DES
552 register int n; /* number of bytes actually read */
553 register int c; /* used to test for EOF */
554 register int bn; /* block number */
555 Desbuf msgbuf; /* I/O buffer */
557 for (bn = 1; (n = READ(BUFFER(msgbuf), 8)) == 8; bn++) {
559 * do the transformation
561 DES_XFORM(UBUFFER(msgbuf));
563 * if the last one, handle it specially
565 if ((c = getchar()) == EOF) {
568 err(bn, "decryption failed (block corrupted)");
571 (void)ungetc(c, stdin);
572 WRITE(BUFFER(msgbuf), n);
575 err(bn, "decryption failed (incomplete block)");
579 * This encrypts using the Cipher Block Chaining mode of DES
583 register int n; /* number of bytes actually read */
584 register int bn; /* block number */
585 Desbuf msgbuf; /* I/O buffer */
588 * do the transformation
590 for (bn = 1; (n = READ(BUFFER(msgbuf), 8)) == 8; bn++) {
591 for (n = 0; n < 8; n++)
592 CHAR(msgbuf, n) ^= CHAR(ivec, n);
593 DES_XFORM(UBUFFER(msgbuf));
594 MEMCPY(BUFFER(ivec), BUFFER(msgbuf), 8);
595 WRITE(BUFFER(msgbuf), 8);
598 * at EOF or last block -- in either case, the last byte contains
599 * the character representation of the number of bytes in it
602 MEMZERO(&CHAR(msgbuf, n), 8 - n);
604 for (n = 0; n < 8; n++)
605 CHAR(msgbuf, n) ^= CHAR(ivec, n);
606 DES_XFORM(UBUFFER(msgbuf));
607 WRITE(BUFFER(msgbuf), 8);
612 * This decrypts using the Cipher Block Chaining mode of DES
616 register int n; /* number of bytes actually read */
617 Desbuf msgbuf; /* I/O buffer */
618 Desbuf ibuf; /* temp buffer for initialization vector */
619 register int c; /* used to test for EOF */
620 register int bn; /* block number */
622 for (bn = 0; (n = READ(BUFFER(msgbuf), 8)) == 8; bn++) {
624 * do the transformation
626 MEMCPY(BUFFER(ibuf), BUFFER(msgbuf), 8);
627 DES_XFORM(UBUFFER(msgbuf));
628 for (c = 0; c < 8; c++)
629 UCHAR(msgbuf, c) ^= UCHAR(ivec, c);
630 MEMCPY(BUFFER(ivec), BUFFER(ibuf), 8);
632 * if the last one, handle it specially
634 if ((c = getchar()) == EOF) {
637 err(bn, "decryption failed (block corrupted)");
640 (void)ungetc(c, stdin);
641 WRITE(BUFFER(msgbuf), n);
644 err(bn, "decryption failed (incomplete block)");
648 * This authenticates using the Cipher Block Chaining mode of DES
652 register int n, j; /* number of bytes actually read */
653 Desbuf msgbuf; /* I/O buffer */
654 Desbuf encbuf; /* encryption buffer */
657 * do the transformation
658 * note we DISCARD the encrypted block;
659 * we only care about the last one
661 while ((n = READ(BUFFER(msgbuf), 8)) == 8) {
662 for (n = 0; n < 8; n++)
663 CHAR(encbuf, n) = CHAR(msgbuf, n) ^ CHAR(ivec, n);
664 DES_XFORM(UBUFFER(encbuf));
665 MEMCPY(BUFFER(ivec), BUFFER(encbuf), 8);
668 * now compute the last one, right padding with '\0' if need be
671 MEMZERO(&CHAR(msgbuf, n), 8 - n);
672 for (n = 0; n < 8; n++)
673 CHAR(encbuf, n) = CHAR(msgbuf, n) ^ CHAR(ivec, n);
674 DES_XFORM(UBUFFER(encbuf));
678 * we write chars until fewer than 7 bits,
679 * and then pad the last one with 0 bits
681 for (n = 0; macbits > 7; n++, macbits -= 8)
682 (void)putchar(CHAR(encbuf, n));
684 CHAR(msgbuf, 0) = 0x00;
685 for (j = 0; j < macbits; j++)
686 CHAR(msgbuf, 0) |= (CHAR(encbuf, n)&bits[j]);
687 (void)putchar(CHAR(msgbuf, 0));
692 * This encrypts using the Cipher FeedBack mode of DES
696 register int n; /* number of bytes actually read */
697 register int nbytes; /* number of bytes to read */
698 register int bn; /* block number */
699 char ibuf[8]; /* input buffer */
700 Desbuf msgbuf; /* encryption buffer */
703 * do things in bytes, not bits
707 * do the transformation
709 for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) {
710 MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
711 DES_XFORM(UBUFFER(msgbuf));
712 for (n = 0; n < 8 - nbytes; n++)
713 UCHAR(ivec, n) = UCHAR(ivec, n+nbytes);
714 for (n = 0; n < nbytes; n++)
715 UCHAR(ivec, 8-nbytes+n) = ibuf[n] ^ UCHAR(msgbuf, n);
716 WRITE(&CHAR(ivec, 8-nbytes), nbytes);
719 * at EOF or last block -- in either case, the last byte contains
720 * the character representation of the number of bytes in it
723 MEMZERO(&ibuf[n], nbytes - n);
724 ibuf[nbytes - 1] = n;
725 MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
726 DES_XFORM(UBUFFER(msgbuf));
727 for (n = 0; n < nbytes; n++)
728 ibuf[n] ^= UCHAR(msgbuf, n);
733 * This decrypts using the Cipher Block Chaining mode of DES
737 register int n; /* number of bytes actually read */
738 register int c; /* used to test for EOF */
739 register int nbytes; /* number of bytes to read */
740 register int bn; /* block number */
741 char ibuf[8]; /* input buffer */
742 char obuf[8]; /* output buffer */
743 Desbuf msgbuf; /* encryption buffer */
746 * do things in bytes, not bits
750 * do the transformation
752 for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) {
753 MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
754 DES_XFORM(UBUFFER(msgbuf));
755 for (c = 0; c < 8 - nbytes; c++)
756 CHAR(ivec, c) = CHAR(ivec, c+nbytes);
757 for (c = 0; c < nbytes; c++) {
758 CHAR(ivec, 8-nbytes+c) = ibuf[c];
759 obuf[c] = ibuf[c] ^ UCHAR(msgbuf, c);
762 * if the last one, handle it specially
764 if ((c = getchar()) == EOF) {
766 if (n < 0 || n > nbytes-1)
767 err(bn, "decryption failed (block corrupted)");
770 (void)ungetc(c, stdin);
774 err(bn, "decryption failed (incomplete block)");
778 * This encrypts using the alternative Cipher FeedBack mode of DES
782 register int n; /* number of bytes actually read */
783 register int nbytes; /* number of bytes to read */
784 register int bn; /* block number */
785 char ibuf[8]; /* input buffer */
786 char obuf[8]; /* output buffer */
787 Desbuf msgbuf; /* encryption buffer */
790 * do things in bytes, not bits
794 * do the transformation
796 for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) {
797 MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
798 DES_XFORM(UBUFFER(msgbuf));
799 for (n = 0; n < 8 - nbytes; n++)
800 UCHAR(ivec, n) = UCHAR(ivec, n+nbytes);
801 for (n = 0; n < nbytes; n++)
802 UCHAR(ivec, 8-nbytes+n) = (ibuf[n] ^ UCHAR(msgbuf, n))
804 for (n = 0; n < nbytes; n++)
805 obuf[n] = CHAR(ivec, 8-nbytes+n)&0177;
809 * at EOF or last block -- in either case, the last byte contains
810 * the character representation of the number of bytes in it
813 MEMZERO(&ibuf[n], nbytes - n);
814 ibuf[nbytes - 1] = ('0' + n)|0200;
815 MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
816 DES_XFORM(UBUFFER(msgbuf));
817 for (n = 0; n < nbytes; n++)
818 ibuf[n] ^= UCHAR(msgbuf, n);
823 * This decrypts using the alternative Cipher Block Chaining mode of DES
827 register int n; /* number of bytes actually read */
828 register int c; /* used to test for EOF */
829 register int nbytes; /* number of bytes to read */
830 register int bn; /* block number */
831 char ibuf[8]; /* input buffer */
832 char obuf[8]; /* output buffer */
833 Desbuf msgbuf; /* encryption buffer */
836 * do things in bytes, not bits
840 * do the transformation
842 for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) {
843 MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
844 DES_XFORM(UBUFFER(msgbuf));
845 for (c = 0; c < 8 - nbytes; c++)
846 CHAR(ivec, c) = CHAR(ivec, c+nbytes);
847 for (c = 0; c < nbytes; c++) {
848 CHAR(ivec, 8-nbytes+c) = ibuf[c]|0200;
849 obuf[c] = (ibuf[c] ^ UCHAR(msgbuf, c))&0177;
852 * if the last one, handle it specially
854 if ((c = getchar()) == EOF) {
855 if ((n = (obuf[nbytes-1] - '0')) < 0
857 err(bn, "decryption failed (block corrupted)");
860 (void)ungetc(c, stdin);
864 err(bn, "decryption failed (incomplete block)");
869 * This encrypts using the Output FeedBack mode of DES
873 register int n; /* number of bytes actually read */
874 register int c; /* used to test for EOF */
875 register int nbytes; /* number of bytes to read */
876 register int bn; /* block number */
877 char ibuf[8]; /* input buffer */
878 char obuf[8]; /* output buffer */
879 Desbuf msgbuf; /* encryption buffer */
882 * do things in bytes, not bits
886 * do the transformation
888 for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) {
889 MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
890 DES_XFORM(UBUFFER(msgbuf));
891 for (n = 0; n < 8 - nbytes; n++)
892 UCHAR(ivec, n) = UCHAR(ivec, n+nbytes);
893 for (n = 0; n < nbytes; n++) {
894 UCHAR(ivec, 8-nbytes+n) = UCHAR(msgbuf, n);
895 obuf[n] = ibuf[n] ^ UCHAR(msgbuf, n);
900 * at EOF or last block -- in either case, the last byte contains
901 * the character representation of the number of bytes in it
904 MEMZERO(&ibuf[n], nbytes - n);
905 ibuf[nbytes - 1] = n;
906 MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
907 DES_XFORM(UBUFFER(msgbuf));
908 for (c = 0; c < nbytes; c++)
909 ibuf[c] ^= UCHAR(msgbuf, c);
914 * This decrypts using the Output Block Chaining mode of DES
918 register int n; /* number of bytes actually read */
919 register int c; /* used to test for EOF */
920 register int nbytes; /* number of bytes to read */
921 register int bn; /* block number */
922 char ibuf[8]; /* input buffer */
923 char obuf[8]; /* output buffer */
924 Desbuf msgbuf; /* encryption buffer */
927 * do things in bytes, not bits
931 * do the transformation
933 for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) {
934 MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
935 DES_XFORM(UBUFFER(msgbuf));
936 for (c = 0; c < 8 - nbytes; c++)
937 CHAR(ivec, c) = CHAR(ivec, c+nbytes);
938 for (c = 0; c < nbytes; c++) {
939 CHAR(ivec, 8-nbytes+c) = UCHAR(msgbuf, c);
940 obuf[c] = ibuf[c] ^ UCHAR(msgbuf, c);
943 * if the last one, handle it specially
945 if ((c = getchar()) == EOF) {
947 if (n < 0 || n > nbytes-1)
948 err(bn, "decryption failed (block corrupted)");
951 (void)ungetc(c, stdin);
958 err(bn, "decryption failed (incomplete block)");
962 * This authenticates using the Cipher FeedBack mode of DES
966 register int n, j; /* number of bytes actually read */
967 register int nbytes; /* number of bytes to read */
968 char ibuf[8]; /* input buffer */
969 Desbuf msgbuf; /* encryption buffer */
972 * do things in bytes, not bits
976 * do the transformation
978 while ((n = READ(ibuf, nbytes)) == nbytes) {
979 MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
980 DES_XFORM(UBUFFER(msgbuf));
981 for (n = 0; n < 8 - nbytes; n++)
982 UCHAR(ivec, n) = UCHAR(ivec, n+nbytes);
983 for (n = 0; n < nbytes; n++)
984 UCHAR(ivec, 8-nbytes+n) = ibuf[n] ^ UCHAR(msgbuf, n);
987 * at EOF or last block -- in either case, the last byte contains
988 * the character representation of the number of bytes in it
990 MEMZERO(&ibuf[n], nbytes - n);
991 ibuf[nbytes - 1] = '0' + n;
992 MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
993 DES_XFORM(UBUFFER(msgbuf));
994 for (n = 0; n < nbytes; n++)
995 ibuf[n] ^= UCHAR(msgbuf, n);
998 * we write chars until fewer than 7 bits,
999 * and then pad the last one with 0 bits
1001 for (n = 0; macbits > 7; n++, macbits -= 8)
1002 (void)putchar(CHAR(msgbuf, n));
1004 CHAR(msgbuf, 0) = 0x00;
1005 for (j = 0; j < macbits; j++)
1006 CHAR(msgbuf, 0) |= (CHAR(msgbuf, n)&bits[j]);
1007 (void)putchar(CHAR(msgbuf, 0));
1013 * change from 8 bits/Uchar to 1 bit/Uchar
1016 Desbuf from; /* 8bit/unsigned char string */
1017 char *to; /* 1bit/char string */
1019 register int i, j; /* counters in for loop */
1021 for (i = 0; i < 8; i++)
1022 for (j = 0; j < 8; j++)
1023 *to++ = (CHAR(from, i)>>(7-j))&01;
1027 * change from 1 bit/char to 8 bits/Uchar
1030 char *from; /* 1bit/char string */
1031 Desbuf to; /* 8bit/unsigned char string */
1033 register int i, j; /* counters in for loop */
1035 for (i = 0; i < 8; i++) {
1037 for (j = 0; j < 8; j++)
1038 CHAR(to, i) = ((*from++)<<(7-j))|CHAR(to, i);
1044 * message about usage
1048 (void)fprintf(stderr, "%s\n",
1049 "usage: bdes [-abdp] [-F bit] [-f bit] [-k key] [-m bit] [-o bit] [-v vector]");