1 /* $NetBSD: bdes.c,v 1.7 2008/07/21 14:19:21 lukem Exp $ */
4 * Copyright (c) 1991, 1993
5 * The Regents of the University of California. All rights reserved.
7 * This code is derived from software contributed to Berkeley by
8 * Matt Bishop of Dartmouth College.
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.
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
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. Neither the name of the University nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39 #include <sys/cdefs.h>
41 __COPYRIGHT("@(#) Copyright (c) 1991, 1993\
42 The Regents of the University of California. All rights reserved.");
47 static char sccsid
[] = "@(#)bdes.c 8.1 (Berkeley) 6/6/93";
49 __RCSID("$NetBSD: bdes.c,v 1.7 2008/07/21 14:19:21 lukem Exp $");
54 * BDES -- DES encryption package for Berkeley Software Distribution 4.4
57 * -b use ECB (electronic code book) mode
58 * -d invert (decrypt) input
59 * -f b use b-bit CFB (cipher feedback) mode
60 * -F b use b-bit CFB (cipher feedback) alternative mode
61 * -k key use key as the cryptographic key
62 * -m b generate a MAC of length b
63 * -o b use b-bit OFB (output feedback) mode
64 * -p don't reset the parity bit
65 * -v v use v as the initialization vector (ignored for ECB)
66 * note: the last character of the last block is the integer indicating
67 * how many characters of that block are to be output
70 * Department of Mathematics and Computer Science
73 * Email: Matt.Bishop@dartmouth.edu
74 * ...!decvax!dartvax!Matt.Bishop
76 * See Technical Report PCS-TR91-158, Department of Mathematics and Computer
77 * Science, Dartmouth College, for a detailed description of the implemen-
78 * tation and differences between it and Sun's. The DES is described in
79 * FIPS PUB 46, and the modes in FIPS PUB 81 (see either the manual page
80 * or the technical report for a complete reference).
91 * BSD and System V systems offer special library calls that do
92 * block moves and fills, so if possible we take advantage of them
94 #define MEMCPY(dest,src,len) bcopy((src),(dest),(len))
95 #define MEMZERO(dest,len) bzero((dest),(len))
97 /* Hide the calls to the primitive encryption routines. */
100 #define DES_KEY(buf) \
101 if (des_setkey(buf)) \
102 bdes_err(0, "des_setkey");
103 #define DES_XFORM(buf) \
104 if (des_cipher(buf, buf, 0L, (inverse ? -1 : 1))) \
105 bdes_err(0, "des_cipher");
107 #define DES_KEY(buf) { \
108 char bits1[64]; /* bits of key */ \
109 expand(buf, bits1); \
111 bdes_err(0, "setkey"); \
113 #define DES_XFORM(buf) { \
114 char bits1[64]; /* bits of message */ \
115 expand(buf, bits1); \
116 if (encrypt(bits1, inverse)) \
117 bdes_err(0, "encrypt"); \
118 compress(bits1, buf); \
123 * this does an error-checking write
125 #define READ(buf, n) fread(buf, sizeof(char), n, stdin)
126 #define WRITE(buf,n) \
127 if (fwrite(buf, sizeof(char), n, stdout) != (size_t)n) \
131 * some things to make references easier
133 typedef char Desbuf
[8];
134 #define CHAR(x,i) (x[i])
135 #define UCHAR(x,i) (x[i])
136 #define BUFFER(x) (x)
137 #define UBUFFER(x) (x)
140 * global variables and related macros
142 #define KEY_DEFAULT 0 /* interpret radix of key from key */
143 #define KEY_ASCII 1 /* key is in ASCII characters */
144 int keybase
= KEY_DEFAULT
; /* how to interpret the key */
146 enum { /* encrypt, decrypt, authenticate */
147 MODE_ENCRYPT
, MODE_DECRYPT
, MODE_AUTHENTICATE
148 } mode
= MODE_ENCRYPT
;
149 enum { /* ecb, cbc, cfb, cfba, ofb? */
150 ALG_ECB
, ALG_CBC
, ALG_CFB
, ALG_OFB
, ALG_CFBA
153 Desbuf ivec
; /* initialization vector */
154 char bits
[] = { /* used to extract bits from a char */
155 '\200', '\100', '\040', '\020', '\010', '\004', '\002', '\001'
157 int inverse
; /* 0 to encrypt, 1 to decrypt */
158 int macbits
= -1; /* number of bits in authentication */
159 int fbbits
= -1; /* number of feedback bits */
160 int pflag
; /* 1 to preserve parity bits */
162 int setbits(char *, int);
163 void bdes_err(int, const char *);
164 int tobinhex(char, int);
165 void cvtkey(char *, char *);
166 void makekey(Desbuf
);
179 void expand(Desbuf
, char *);
180 void compress(char *, Desbuf
);
184 main(int ac
, char *av
[])
186 register int i
; /* counter in a for loop */
187 register char *p
; /* used to obtain the key */
188 Desbuf msgbuf
; /* I/O buffer */
189 int kflag
; /* command-line encryptiooon key */
190 int argc
; /* the real arg count */
191 char **argv
; /* the real argument vector */
194 * Hide the arguments from ps(1) by making private copies of them
195 * and clobbering the global (visible to ps(1)) ones.
199 argv
= malloc((argc
+ 1) * sizeof(char *));
200 for (i
= 0; i
< argc
; ++i
) {
201 argv
[i
] = strdup(av
[i
]);
202 MEMZERO(av
[i
], strlen(av
[i
]));
206 /* initialize the initialization vctor */
209 /* process the argument list */
211 while ((i
= getopt(argc
, argv
, "abdF:f:k:m:o:pv:")) != -1)
213 case 'a': /* key is ASCII */
216 case 'b': /* use ECB mode */
219 case 'd': /* decrypt */
222 case 'F': /* use alternative CFB mode */
224 if ((fbbits
= setbits(optarg
, 7)) > 56 || fbbits
== 0)
226 "-F: number must be 1-56 inclusive");
227 else if (fbbits
== -1)
229 "-F: number must be a multiple of 7");
231 case 'f': /* use CFB mode */
233 if ((fbbits
= setbits(optarg
, 8)) > 64 || fbbits
== 0)
235 "-f: number must be 1-64 inclusive");
236 else if (fbbits
== -1)
238 "-f: number must be a multiple of 8");
240 case 'k': /* encryption key */
242 cvtkey(BUFFER(msgbuf
), optarg
);
244 case 'm': /* number of bits for MACing */
245 mode
= MODE_AUTHENTICATE
;
246 if ((macbits
= setbits(optarg
, 1)) > 64)
248 "-m: number must be 0-64 inclusive");
250 case 'o': /* use OFB mode */
252 if ((fbbits
= setbits(optarg
, 8)) > 64 || fbbits
== 0)
254 "-o: number must be 1-64 inclusive");
255 else if (fbbits
== -1)
257 "-o: number must be a multiple of 8");
259 case 'p': /* preserve parity bits */
262 case 'v': /* set initialization vector */
263 cvtkey(BUFFER(ivec
), optarg
);
271 * if the key's not ASCII, assume it is
277 p
= getpass("Enter key: ");
279 * copy it, nul-padded, into the key area
281 cvtkey(BUFFER(msgbuf
), p
);
285 inverse
= (alg
== ALG_CBC
|| alg
== ALG_ECB
) && mode
== MODE_DECRYPT
;
290 case MODE_AUTHENTICATE
: /* authenticate using CBC mode */
293 case MODE_DECRYPT
: /* decrypt using CBC mode */
296 case MODE_ENCRYPT
: /* encrypt using CBC mode */
303 case MODE_AUTHENTICATE
: /* authenticate using CFB mode */
306 case MODE_DECRYPT
: /* decrypt using CFB mode */
309 case MODE_ENCRYPT
: /* encrypt using CFB mode */
316 case MODE_AUTHENTICATE
: /* authenticate using CFBA mode */
317 bdes_err(-1, "can't authenticate with CFBA mode");
319 case MODE_DECRYPT
: /* decrypt using CFBA mode */
322 case MODE_ENCRYPT
: /* encrypt using CFBA mode */
329 case MODE_AUTHENTICATE
: /* authenticate using ECB mode */
330 bdes_err(-1, "can't authenticate with ECB mode");
332 case MODE_DECRYPT
: /* decrypt using ECB mode */
335 case MODE_ENCRYPT
: /* encrypt using ECB mode */
342 case MODE_AUTHENTICATE
: /* authenticate using OFB mode */
343 bdes_err(-1, "can't authenticate with OFB mode");
345 case MODE_DECRYPT
: /* decrypt using OFB mode */
348 case MODE_ENCRYPT
: /* encrypt using OFB mode */
358 * print a warning message and, possibly, terminate
361 bdes_err(int n
, const char *s
)
364 (void)fprintf(stderr
, "bdes (block %d): ", n
);
366 (void)fprintf(stderr
, "bdes: ");
367 (void)fprintf(stderr
, "%s\n", s
? s
: strerror(errno
));
372 * map a hex character to an integer
375 tobinhex(char c
, int radix
)
378 case '0': return(0x0);
379 case '1': return(0x1);
380 case '2': return(radix
> 2 ? 0x2 : -1);
381 case '3': return(radix
> 3 ? 0x3 : -1);
382 case '4': return(radix
> 4 ? 0x4 : -1);
383 case '5': return(radix
> 5 ? 0x5 : -1);
384 case '6': return(radix
> 6 ? 0x6 : -1);
385 case '7': return(radix
> 7 ? 0x7 : -1);
386 case '8': return(radix
> 8 ? 0x8 : -1);
387 case '9': return(radix
> 9 ? 0x9 : -1);
388 case 'A': case 'a': return(radix
> 10 ? 0xa : -1);
389 case 'B': case 'b': return(radix
> 11 ? 0xb : -1);
390 case 'C': case 'c': return(radix
> 12 ? 0xc : -1);
391 case 'D': case 'd': return(radix
> 13 ? 0xd : -1);
392 case 'E': case 'e': return(radix
> 14 ? 0xe : -1);
393 case 'F': case 'f': return(radix
> 15 ? 0xf : -1);
402 * convert the key to a bit pattern
405 cvtkey(char *obuf
, char *ibuf
)
407 register int i
, j
; /* counter in a for loop */
408 int nbuf
[64]; /* used for hex/key translation */
411 * just switch on the key base
414 case KEY_ASCII
: /* ascii to integer */
415 (void)strncpy(obuf
, ibuf
, 8);
417 case KEY_DEFAULT
: /* tell from context */
419 * leading '0x' or '0X' == hex key
421 if (ibuf
[0] == '0' && (ibuf
[1] == 'x' || ibuf
[1] == 'X')) {
424 * now translate it, bombing on any illegal hex digit
426 for (i
= 0; ibuf
[i
] && i
< 16; i
++)
427 if ((nbuf
[i
] = tobinhex(ibuf
[i
], 16)) == -1)
428 bdes_err(-1, "bad hex digit in key");
431 for (i
= 0; i
< 8; i
++)
433 ((nbuf
[2*i
]&0xf)<<4) | (nbuf
[2*i
+1]&0xf);
434 /* preserve parity bits */
439 * leading '0b' or '0B' == binary key
441 if (ibuf
[0] == '0' && (ibuf
[1] == 'b' || ibuf
[1] == 'B')) {
444 * now translate it, bombing on any illegal binary digit
446 for (i
= 0; ibuf
[i
] && i
< 16; i
++)
447 if ((nbuf
[i
] = tobinhex(ibuf
[i
], 2)) == -1)
448 bdes_err(-1, "bad binary digit in key");
451 for (i
= 0; i
< 8; i
++)
452 for (j
= 0; j
< 8; j
++)
453 obuf
[i
] = (obuf
[i
]<<1)|nbuf
[8*i
+j
];
454 /* preserve parity bits */
459 * no special leader -- ASCII
461 (void)strncpy(obuf
, ibuf
, 8);
466 * convert an ASCII string into a decimal number:
467 * 1. must be between 0 and 64 inclusive (or 56, checked by caller)
468 * 2. must be a valid decimal number
469 * 3. must be a multiple of mult
472 setbits(char *s
, int mult
)
475 int n
; /* the integer collected */
477 n
= strtoul(s
, &p
, 10);
479 bdes_err(-1, "bad decimal digit in MAC length");
481 * be sure it's a multiple of mult
483 return((n
% mult
!= 0) ? -1 : n
);
490 * This sets the DES key and (if you're using the deszip version)
491 * the direction of the transformation. This uses the Sun
492 * to map the 64-bit key onto the 56 bits that the key schedule
493 * generation routines use: the old way, which just uses the user-
494 * supplied 64 bits as is, and the new way, which resets the parity
495 * bit to be the same as the low-order bit in each character. The
496 * new way generates a greater variety of key schedules, since many
497 * systems set the parity (high) bit of each character to 0, and the
498 * DES ignores the low order bit of each character.
503 register int i
, j
; /* counter in a for loop */
504 register int par
; /* parity counter */
507 * if the parity is not preserved, flip it
510 for (i
= 0; i
< 8; i
++) {
512 for (j
= 1; j
< 8; j
++)
513 if ((bits
[j
]&UCHAR(buf
, i
)) != 0)
516 UCHAR(buf
, i
) = UCHAR(buf
, i
)&0177;
518 UCHAR(buf
, i
) = (UCHAR(buf
, i
)&0177)|0200;
522 DES_KEY(UBUFFER(buf
));
526 * This encrypts using the Electronic Code Book mode of DES
531 register int n
; /* number of bytes actually read */
532 register int bn
; /* block number */
533 Desbuf msgbuf
; /* I/O buffer */
535 for (bn
= 0; (n
= READ(BUFFER(msgbuf
), 8)) == 8; bn
++) {
537 * do the transformation
539 DES_XFORM(UBUFFER(msgbuf
));
540 WRITE(BUFFER(msgbuf
), 8);
543 * at EOF or last block -- in either ase, the last byte contains
544 * the character representation of the number of bytes in it
547 MEMZERO(&CHAR(msgbuf
, n
), 8 - n
);
549 DES_XFORM(UBUFFER(msgbuf
));
550 WRITE(BUFFER(msgbuf
), 8);
555 * This decrypts using the Electronic Code Book mode of DES
560 register int n
; /* number of bytes actually read */
561 register int c
; /* used to test for EOF */
562 register int bn
; /* block number */
563 Desbuf msgbuf
; /* I/O buffer */
565 for (bn
= 1; (n
= READ(BUFFER(msgbuf
), 8)) == 8; bn
++) {
567 * do the transformation
569 DES_XFORM(UBUFFER(msgbuf
));
571 * if the last one, handle it specially
573 if ((c
= getchar()) == EOF
) {
577 "decryption failed (block corrupted)");
580 (void)ungetc(c
, stdin
);
581 WRITE(BUFFER(msgbuf
), n
);
584 bdes_err(bn
, "decryption failed (incomplete block)");
588 * This encrypts using the Cipher Block Chaining mode of DES
593 register int n
; /* number of bytes actually read */
594 register int bn
; /* block number */
595 Desbuf msgbuf
; /* I/O buffer */
598 * do the transformation
600 for (bn
= 1; (n
= READ(BUFFER(msgbuf
), 8)) == 8; bn
++) {
601 for (n
= 0; n
< 8; n
++)
602 CHAR(msgbuf
, n
) ^= CHAR(ivec
, n
);
603 DES_XFORM(UBUFFER(msgbuf
));
604 MEMCPY(BUFFER(ivec
), BUFFER(msgbuf
), 8);
605 WRITE(BUFFER(msgbuf
), 8);
608 * at EOF or last block -- in either case, the last byte contains
609 * the character representation of the number of bytes in it
612 MEMZERO(&CHAR(msgbuf
, n
), 8 - n
);
614 for (n
= 0; n
< 8; n
++)
615 CHAR(msgbuf
, n
) ^= CHAR(ivec
, n
);
616 DES_XFORM(UBUFFER(msgbuf
));
617 WRITE(BUFFER(msgbuf
), 8);
622 * This decrypts using the Cipher Block Chaining mode of DES
627 register int n
; /* number of bytes actually read */
628 Desbuf msgbuf
; /* I/O buffer */
629 Desbuf ibuf
; /* temp buffer for initialization vector */
630 register int c
; /* used to test for EOF */
631 register int bn
; /* block number */
633 for (bn
= 0; (n
= READ(BUFFER(msgbuf
), 8)) == 8; bn
++) {
635 * do the transformation
637 MEMCPY(BUFFER(ibuf
), BUFFER(msgbuf
), 8);
638 DES_XFORM(UBUFFER(msgbuf
));
639 for (c
= 0; c
< 8; c
++)
640 UCHAR(msgbuf
, c
) ^= UCHAR(ivec
, c
);
641 MEMCPY(BUFFER(ivec
), BUFFER(ibuf
), 8);
643 * if the last one, handle it specially
645 if ((c
= getchar()) == EOF
) {
649 "decryption failed (block corrupted)");
652 (void)ungetc(c
, stdin
);
653 WRITE(BUFFER(msgbuf
), n
);
656 bdes_err(bn
, "decryption failed (incomplete block)");
660 * This authenticates using the Cipher Block Chaining mode of DES
665 register int n
, j
; /* number of bytes actually read */
666 Desbuf msgbuf
; /* I/O buffer */
667 Desbuf encbuf
; /* encryption buffer */
670 * do the transformation
671 * note we DISCARD the encrypted block;
672 * we only care about the last one
674 while ((n
= READ(BUFFER(msgbuf
), 8)) == 8) {
675 for (n
= 0; n
< 8; n
++)
676 CHAR(encbuf
, n
) = CHAR(msgbuf
, n
) ^ CHAR(ivec
, n
);
677 DES_XFORM(UBUFFER(encbuf
));
678 MEMCPY(BUFFER(ivec
), BUFFER(encbuf
), 8);
681 * now compute the last one, right padding with '\0' if need be
684 MEMZERO(&CHAR(msgbuf
, n
), 8 - n
);
685 for (n
= 0; n
< 8; n
++)
686 CHAR(encbuf
, n
) = CHAR(msgbuf
, n
) ^ CHAR(ivec
, n
);
687 DES_XFORM(UBUFFER(encbuf
));
691 * we write chars until fewer than 7 bits,
692 * and then pad the last one with 0 bits
694 for (n
= 0; macbits
> 7; n
++, macbits
-= 8)
695 (void)putchar(CHAR(encbuf
, n
));
697 CHAR(msgbuf
, 0) = 0x00;
698 for (j
= 0; j
< macbits
; j
++)
699 CHAR(msgbuf
, 0) |= (CHAR(encbuf
, n
)&bits
[j
]);
700 (void)putchar(CHAR(msgbuf
, 0));
705 * This encrypts using the Cipher FeedBack mode of DES
710 register int n
; /* number of bytes actually read */
711 register int nbytes
; /* number of bytes to read */
712 register int bn
; /* block number */
713 char ibuf
[8]; /* input buffer */
714 Desbuf msgbuf
; /* encryption buffer */
717 * do things in bytes, not bits
721 * do the transformation
723 for (bn
= 1; (n
= READ(ibuf
, nbytes
)) == nbytes
; bn
++) {
724 MEMCPY(BUFFER(msgbuf
), BUFFER(ivec
), 8);
725 DES_XFORM(UBUFFER(msgbuf
));
726 for (n
= 0; n
< 8 - nbytes
; n
++)
727 UCHAR(ivec
, n
) = UCHAR(ivec
, n
+nbytes
);
728 for (n
= 0; n
< nbytes
; n
++)
729 UCHAR(ivec
, 8-nbytes
+n
) = ibuf
[n
] ^ UCHAR(msgbuf
, n
);
730 WRITE(&CHAR(ivec
, 8-nbytes
), nbytes
);
733 * at EOF or last block -- in either case, the last byte contains
734 * the character representation of the number of bytes in it
737 MEMZERO(&ibuf
[n
], nbytes
- n
);
738 ibuf
[nbytes
- 1] = n
;
739 MEMCPY(BUFFER(msgbuf
), BUFFER(ivec
), 8);
740 DES_XFORM(UBUFFER(msgbuf
));
741 for (n
= 0; n
< nbytes
; n
++)
742 ibuf
[n
] ^= UCHAR(msgbuf
, n
);
747 * This decrypts using the Cipher Block Chaining mode of DES
752 register int n
; /* number of bytes actually read */
753 register int c
; /* used to test for EOF */
754 register int nbytes
; /* number of bytes to read */
755 register int bn
; /* block number */
756 char ibuf
[8]; /* input buffer */
757 char obuf
[8]; /* output buffer */
758 Desbuf msgbuf
; /* encryption buffer */
761 * do things in bytes, not bits
765 * do the transformation
767 for (bn
= 1; (n
= READ(ibuf
, nbytes
)) == nbytes
; bn
++) {
768 MEMCPY(BUFFER(msgbuf
), BUFFER(ivec
), 8);
769 DES_XFORM(UBUFFER(msgbuf
));
770 for (c
= 0; c
< 8 - nbytes
; c
++)
771 CHAR(ivec
, c
) = CHAR(ivec
, c
+nbytes
);
772 for (c
= 0; c
< nbytes
; c
++) {
773 CHAR(ivec
, 8-nbytes
+c
) = ibuf
[c
];
774 obuf
[c
] = ibuf
[c
] ^ UCHAR(msgbuf
, c
);
777 * if the last one, handle it specially
779 if ((c
= getchar()) == EOF
) {
781 if (n
< 0 || n
> nbytes
-1)
783 "decryption failed (block corrupted)");
786 (void)ungetc(c
, stdin
);
790 bdes_err(bn
, "decryption failed (incomplete block)");
794 * This encrypts using the alternative Cipher FeedBack mode of DES
799 register int n
; /* number of bytes actually read */
800 register int nbytes
; /* number of bytes to read */
801 register int bn
; /* block number */
802 char ibuf
[8]; /* input buffer */
803 char obuf
[8]; /* output buffer */
804 Desbuf msgbuf
; /* encryption buffer */
807 * do things in bytes, not bits
811 * do the transformation
813 for (bn
= 1; (n
= READ(ibuf
, nbytes
)) == nbytes
; bn
++) {
814 MEMCPY(BUFFER(msgbuf
), BUFFER(ivec
), 8);
815 DES_XFORM(UBUFFER(msgbuf
));
816 for (n
= 0; n
< 8 - nbytes
; n
++)
817 UCHAR(ivec
, n
) = UCHAR(ivec
, n
+nbytes
);
818 for (n
= 0; n
< nbytes
; n
++)
819 UCHAR(ivec
, 8-nbytes
+n
) = (ibuf
[n
] ^ UCHAR(msgbuf
, n
))
821 for (n
= 0; n
< nbytes
; n
++)
822 obuf
[n
] = CHAR(ivec
, 8-nbytes
+n
)&0177;
826 * at EOF or last block -- in either case, the last byte contains
827 * the character representation of the number of bytes in it
830 MEMZERO(&ibuf
[n
], nbytes
- n
);
831 ibuf
[nbytes
- 1] = ('0' + n
)|0200;
832 MEMCPY(BUFFER(msgbuf
), BUFFER(ivec
), 8);
833 DES_XFORM(UBUFFER(msgbuf
));
834 for (n
= 0; n
< nbytes
; n
++)
835 ibuf
[n
] ^= UCHAR(msgbuf
, n
);
840 * This decrypts using the alternative Cipher Block Chaining mode of DES
845 register int n
; /* number of bytes actually read */
846 register int c
; /* used to test for EOF */
847 register int nbytes
; /* number of bytes to read */
848 register int bn
; /* block number */
849 char ibuf
[8]; /* input buffer */
850 char obuf
[8]; /* output buffer */
851 Desbuf msgbuf
; /* encryption buffer */
854 * do things in bytes, not bits
858 * do the transformation
860 for (bn
= 1; (n
= READ(ibuf
, nbytes
)) == nbytes
; bn
++) {
861 MEMCPY(BUFFER(msgbuf
), BUFFER(ivec
), 8);
862 DES_XFORM(UBUFFER(msgbuf
));
863 for (c
= 0; c
< 8 - nbytes
; c
++)
864 CHAR(ivec
, c
) = CHAR(ivec
, c
+nbytes
);
865 for (c
= 0; c
< nbytes
; c
++) {
866 CHAR(ivec
, 8-nbytes
+c
) = ibuf
[c
]|0200;
867 obuf
[c
] = (ibuf
[c
] ^ UCHAR(msgbuf
, c
))&0177;
870 * if the last one, handle it specially
872 if ((c
= getchar()) == EOF
) {
873 if ((n
= (obuf
[nbytes
-1] - '0')) < 0
876 "decryption failed (block corrupted)");
879 (void)ungetc(c
, stdin
);
883 bdes_err(bn
, "decryption failed (incomplete block)");
888 * This encrypts using the Output FeedBack mode of DES
893 register int n
; /* number of bytes actually read */
894 register int c
; /* used to test for EOF */
895 register int nbytes
; /* number of bytes to read */
896 register int bn
; /* block number */
897 char ibuf
[8]; /* input buffer */
898 char obuf
[8]; /* output buffer */
899 Desbuf msgbuf
; /* encryption buffer */
902 * do things in bytes, not bits
906 * do the transformation
908 for (bn
= 1; (n
= READ(ibuf
, nbytes
)) == nbytes
; bn
++) {
909 MEMCPY(BUFFER(msgbuf
), BUFFER(ivec
), 8);
910 DES_XFORM(UBUFFER(msgbuf
));
911 for (n
= 0; n
< 8 - nbytes
; n
++)
912 UCHAR(ivec
, n
) = UCHAR(ivec
, n
+nbytes
);
913 for (n
= 0; n
< nbytes
; n
++) {
914 UCHAR(ivec
, 8-nbytes
+n
) = UCHAR(msgbuf
, n
);
915 obuf
[n
] = ibuf
[n
] ^ UCHAR(msgbuf
, n
);
920 * at EOF or last block -- in either case, the last byte contains
921 * the character representation of the number of bytes in it
924 MEMZERO(&ibuf
[n
], nbytes
- n
);
925 ibuf
[nbytes
- 1] = n
;
926 MEMCPY(BUFFER(msgbuf
), BUFFER(ivec
), 8);
927 DES_XFORM(UBUFFER(msgbuf
));
928 for (c
= 0; c
< nbytes
; c
++)
929 ibuf
[c
] ^= UCHAR(msgbuf
, c
);
934 * This decrypts using the Output Block Chaining mode of DES
939 register int n
; /* number of bytes actually read */
940 register int c
; /* used to test for EOF */
941 register int nbytes
; /* number of bytes to read */
942 register int bn
; /* block number */
943 char ibuf
[8]; /* input buffer */
944 char obuf
[8]; /* output buffer */
945 Desbuf msgbuf
; /* encryption buffer */
948 * do things in bytes, not bits
952 * do the transformation
954 for (bn
= 1; (n
= READ(ibuf
, nbytes
)) == nbytes
; bn
++) {
955 MEMCPY(BUFFER(msgbuf
), BUFFER(ivec
), 8);
956 DES_XFORM(UBUFFER(msgbuf
));
957 for (c
= 0; c
< 8 - nbytes
; c
++)
958 CHAR(ivec
, c
) = CHAR(ivec
, c
+nbytes
);
959 for (c
= 0; c
< nbytes
; c
++) {
960 CHAR(ivec
, 8-nbytes
+c
) = UCHAR(msgbuf
, c
);
961 obuf
[c
] = ibuf
[c
] ^ UCHAR(msgbuf
, c
);
964 * if the last one, handle it specially
966 if ((c
= getchar()) == EOF
) {
968 if (n
< 0 || n
> nbytes
-1)
970 "decryption failed (block corrupted)");
973 (void)ungetc(c
, stdin
);
980 bdes_err(bn
, "decryption failed (incomplete block)");
984 * This authenticates using the Cipher FeedBack mode of DES
989 register int n
, j
; /* number of bytes actually read */
990 register int nbytes
; /* number of bytes to read */
991 char ibuf
[8]; /* input buffer */
992 Desbuf msgbuf
; /* encryption buffer */
995 * do things in bytes, not bits
999 * do the transformation
1001 while ((n
= READ(ibuf
, nbytes
)) == nbytes
) {
1002 MEMCPY(BUFFER(msgbuf
), BUFFER(ivec
), 8);
1003 DES_XFORM(UBUFFER(msgbuf
));
1004 for (n
= 0; n
< 8 - nbytes
; n
++)
1005 UCHAR(ivec
, n
) = UCHAR(ivec
, n
+nbytes
);
1006 for (n
= 0; n
< nbytes
; n
++)
1007 UCHAR(ivec
, 8-nbytes
+n
) = ibuf
[n
] ^ UCHAR(msgbuf
, n
);
1010 * at EOF or last block -- in either case, the last byte contains
1011 * the character representation of the number of bytes in it
1013 MEMZERO(&ibuf
[n
], nbytes
- n
);
1014 ibuf
[nbytes
- 1] = '0' + n
;
1015 MEMCPY(BUFFER(msgbuf
), BUFFER(ivec
), 8);
1016 DES_XFORM(UBUFFER(msgbuf
));
1017 for (n
= 0; n
< nbytes
; n
++)
1018 ibuf
[n
] ^= UCHAR(msgbuf
, n
);
1021 * we write chars until fewer than 7 bits,
1022 * and then pad the last one with 0 bits
1024 for (n
= 0; macbits
> 7; n
++, macbits
-= 8)
1025 (void)putchar(CHAR(msgbuf
, n
));
1027 CHAR(msgbuf
, 0) = 0x00;
1028 for (j
= 0; j
< macbits
; j
++)
1029 CHAR(msgbuf
, 0) |= (CHAR(msgbuf
, n
)&bits
[j
]);
1030 (void)putchar(CHAR(msgbuf
, 0));
1036 * change from 8 bits/Uchar to 1 bit/Uchar
1039 expand(Desbuf from
, char *to
)
1041 register int i
, j
; /* counters in for loop */
1043 for (i
= 0; i
< 8; i
++)
1044 for (j
= 0; j
< 8; j
++)
1045 *to
++ = (CHAR(from
, i
)>>(7-j
))&01;
1049 * change from 1 bit/char to 8 bits/Uchar
1052 compress(char *from
, Desbuf to
)
1054 register int i
, j
; /* counters in for loop */
1056 for (i
= 0; i
< 8; i
++) {
1058 for (j
= 0; j
< 8; j
++)
1059 CHAR(to
, i
) = ((*from
++)<<(7-j
))|CHAR(to
, i
);
1065 * message about usage
1071 (void) fprintf(stderr
, "usage: %s %s\n", getprogname(),
1072 "[-abdp] [-F bit] [-f bit] [-k key] [-m bit] [-o bit] [-v vector]");