1 /* $NetBSD: bdes.c,v 1.9 2013/08/15 20:48:56 joerg 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.9 2013/08/15 20:48:56 joerg 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 static int keybase
= KEY_DEFAULT
; /* how to interpret the key */
146 static enum { /* encrypt, decrypt, authenticate */
147 MODE_ENCRYPT
, MODE_DECRYPT
, MODE_AUTHENTICATE
148 } mode
= MODE_ENCRYPT
;
149 static enum { /* ecb, cbc, cfb, cfba, ofb? */
150 ALG_ECB
, ALG_CBC
, ALG_CFB
, ALG_OFB
, ALG_CFBA
153 static Desbuf ivec
; /* initialization vector */
154 static const char bits
[] = { /* used to extract bits from a char */
155 '\200', '\100', '\040', '\020', '\010', '\004', '\002', '\001'
157 static int inverse
; /* 0 to encrypt, 1 to decrypt */
158 static int macbits
= -1; /* number of bits in authentication */
159 static int fbbits
= -1; /* number of feedback bits */
160 static int pflag
; /* 1 to preserve parity bits */
162 static int setbits(char *, int);
163 static void bdes_err(int, const char *) __dead
;
164 static int tobinhex(char, int);
165 static void cvtkey(char *, char *);
166 static void makekey(Desbuf
);
167 static void ecbenc(void);
168 static void ecbdec(void);
169 static void cbcenc(void);
170 static void cbcdec(void);
171 static void cbcauth(void);
172 static void cfbenc(void);
173 static void cfbdec(void);
174 static void cfbaenc(void);
175 static void cfbadec(void);
176 static void ofbenc(void);
177 static void ofbdec(void);
178 static void cfbauth(void);
180 static void expand(Desbuf
, char *);
181 static void compress(char *, Desbuf
);
183 static void usage(void) __dead
;
186 main(int ac
, char *av
[])
188 register int i
; /* counter in a for loop */
189 register char *p
; /* used to obtain the key */
190 Desbuf msgbuf
; /* I/O buffer */
191 int kflag
; /* command-line encryptiooon key */
192 int argc
; /* the real arg count */
193 char **argv
; /* the real argument vector */
196 * Hide the arguments from ps(1) by making private copies of them
197 * and clobbering the global (visible to ps(1)) ones.
201 argv
= malloc((argc
+ 1) * sizeof(char *));
202 for (i
= 0; i
< argc
; ++i
) {
203 argv
[i
] = strdup(av
[i
]);
204 MEMZERO(av
[i
], strlen(av
[i
]));
208 /* initialize the initialization vctor */
211 /* process the argument list */
213 while ((i
= getopt(argc
, argv
, "abdF:f:k:m:o:pv:")) != -1)
215 case 'a': /* key is ASCII */
218 case 'b': /* use ECB mode */
221 case 'd': /* decrypt */
224 case 'F': /* use alternative CFB mode */
226 if ((fbbits
= setbits(optarg
, 7)) > 56 || fbbits
== 0)
228 "-F: number must be 1-56 inclusive");
229 else if (fbbits
== -1)
231 "-F: number must be a multiple of 7");
233 case 'f': /* use CFB mode */
235 if ((fbbits
= setbits(optarg
, 8)) > 64 || fbbits
== 0)
237 "-f: number must be 1-64 inclusive");
238 else if (fbbits
== -1)
240 "-f: number must be a multiple of 8");
242 case 'k': /* encryption key */
244 cvtkey(BUFFER(msgbuf
), optarg
);
246 case 'm': /* number of bits for MACing */
247 mode
= MODE_AUTHENTICATE
;
248 if ((macbits
= setbits(optarg
, 1)) > 64)
250 "-m: number must be 0-64 inclusive");
252 case 'o': /* use OFB mode */
254 if ((fbbits
= setbits(optarg
, 8)) > 64 || fbbits
== 0)
256 "-o: number must be 1-64 inclusive");
257 else if (fbbits
== -1)
259 "-o: number must be a multiple of 8");
261 case 'p': /* preserve parity bits */
264 case 'v': /* set initialization vector */
265 cvtkey(BUFFER(ivec
), optarg
);
273 * if the key's not ASCII, assume it is
279 p
= getpass("Enter key: ");
281 * copy it, nul-padded, into the key area
283 cvtkey(BUFFER(msgbuf
), p
);
287 inverse
= (alg
== ALG_CBC
|| alg
== ALG_ECB
) && mode
== MODE_DECRYPT
;
292 case MODE_AUTHENTICATE
: /* authenticate using CBC mode */
295 case MODE_DECRYPT
: /* decrypt using CBC mode */
298 case MODE_ENCRYPT
: /* encrypt using CBC mode */
305 case MODE_AUTHENTICATE
: /* authenticate using CFB mode */
308 case MODE_DECRYPT
: /* decrypt using CFB mode */
311 case MODE_ENCRYPT
: /* encrypt using CFB mode */
318 case MODE_AUTHENTICATE
: /* authenticate using CFBA mode */
319 bdes_err(-1, "can't authenticate with CFBA mode");
321 case MODE_DECRYPT
: /* decrypt using CFBA mode */
324 case MODE_ENCRYPT
: /* encrypt using CFBA mode */
331 case MODE_AUTHENTICATE
: /* authenticate using ECB mode */
332 bdes_err(-1, "can't authenticate with ECB mode");
334 case MODE_DECRYPT
: /* decrypt using ECB mode */
337 case MODE_ENCRYPT
: /* encrypt using ECB mode */
344 case MODE_AUTHENTICATE
: /* authenticate using OFB mode */
345 bdes_err(-1, "can't authenticate with OFB mode");
347 case MODE_DECRYPT
: /* decrypt using OFB mode */
350 case MODE_ENCRYPT
: /* encrypt using OFB mode */
360 * print a warning message and, possibly, terminate
363 bdes_err(int n
, const char *s
)
366 (void)fprintf(stderr
, "bdes (block %d): ", n
);
368 (void)fprintf(stderr
, "bdes: ");
369 (void)fprintf(stderr
, "%s\n", s
? s
: strerror(errno
));
374 * map a hex character to an integer
377 tobinhex(char c
, int radix
)
380 case '0': return(0x0);
381 case '1': return(0x1);
382 case '2': return(radix
> 2 ? 0x2 : -1);
383 case '3': return(radix
> 3 ? 0x3 : -1);
384 case '4': return(radix
> 4 ? 0x4 : -1);
385 case '5': return(radix
> 5 ? 0x5 : -1);
386 case '6': return(radix
> 6 ? 0x6 : -1);
387 case '7': return(radix
> 7 ? 0x7 : -1);
388 case '8': return(radix
> 8 ? 0x8 : -1);
389 case '9': return(radix
> 9 ? 0x9 : -1);
390 case 'A': case 'a': return(radix
> 10 ? 0xa : -1);
391 case 'B': case 'b': return(radix
> 11 ? 0xb : -1);
392 case 'C': case 'c': return(radix
> 12 ? 0xc : -1);
393 case 'D': case 'd': return(radix
> 13 ? 0xd : -1);
394 case 'E': case 'e': return(radix
> 14 ? 0xe : -1);
395 case 'F': case 'f': return(radix
> 15 ? 0xf : -1);
404 * convert the key to a bit pattern
407 cvtkey(char *obuf
, char *ibuf
)
409 register int i
, j
; /* counter in a for loop */
410 int nbuf
[64]; /* used for hex/key translation */
413 * just switch on the key base
416 case KEY_ASCII
: /* ascii to integer */
417 (void)strncpy(obuf
, ibuf
, 8);
419 case KEY_DEFAULT
: /* tell from context */
421 * leading '0x' or '0X' == hex key
423 if (ibuf
[0] == '0' && (ibuf
[1] == 'x' || ibuf
[1] == 'X')) {
426 * now translate it, bombing on any illegal hex digit
428 for (i
= 0; ibuf
[i
] && i
< 16; i
++)
429 if ((nbuf
[i
] = tobinhex(ibuf
[i
], 16)) == -1)
430 bdes_err(-1, "bad hex digit in key");
433 for (i
= 0; i
< 8; i
++)
435 ((nbuf
[2*i
]&0xf)<<4) | (nbuf
[2*i
+1]&0xf);
436 /* preserve parity bits */
441 * leading '0b' or '0B' == binary key
443 if (ibuf
[0] == '0' && (ibuf
[1] == 'b' || ibuf
[1] == 'B')) {
446 * now translate it, bombing on any illegal binary digit
448 for (i
= 0; ibuf
[i
] && i
< 16; i
++)
449 if ((nbuf
[i
] = tobinhex(ibuf
[i
], 2)) == -1)
450 bdes_err(-1, "bad binary digit in key");
453 for (i
= 0; i
< 8; i
++)
454 for (j
= 0; j
< 8; j
++)
455 obuf
[i
] = (obuf
[i
]<<1)|nbuf
[8*i
+j
];
456 /* preserve parity bits */
461 * no special leader -- ASCII
463 (void)strncpy(obuf
, ibuf
, 8);
468 * convert an ASCII string into a decimal number:
469 * 1. must be between 0 and 64 inclusive (or 56, checked by caller)
470 * 2. must be a valid decimal number
471 * 3. must be a multiple of mult
474 setbits(char *s
, int mult
)
477 int n
; /* the integer collected */
479 n
= strtoul(s
, &p
, 10);
481 bdes_err(-1, "bad decimal digit in MAC length");
483 * be sure it's a multiple of mult
485 return((n
% mult
!= 0) ? -1 : n
);
492 * This sets the DES key and (if you're using the deszip version)
493 * the direction of the transformation. This uses the Sun
494 * to map the 64-bit key onto the 56 bits that the key schedule
495 * generation routines use: the old way, which just uses the user-
496 * supplied 64 bits as is, and the new way, which resets the parity
497 * bit to be the same as the low-order bit in each character. The
498 * new way generates a greater variety of key schedules, since many
499 * systems set the parity (high) bit of each character to 0, and the
500 * DES ignores the low order bit of each character.
505 register int i
, j
; /* counter in a for loop */
506 register int par
; /* parity counter */
509 * if the parity is not preserved, flip it
512 for (i
= 0; i
< 8; i
++) {
514 for (j
= 1; j
< 8; j
++)
515 if ((bits
[j
]&UCHAR(buf
, i
)) != 0)
518 UCHAR(buf
, i
) = UCHAR(buf
, i
)&0177;
520 UCHAR(buf
, i
) = (UCHAR(buf
, i
)&0177)|0200;
524 DES_KEY(UBUFFER(buf
));
528 * This encrypts using the Electronic Code Book mode of DES
533 register int n
; /* number of bytes actually read */
534 register int bn
; /* block number */
535 Desbuf msgbuf
; /* I/O buffer */
537 for (bn
= 0; (n
= READ(BUFFER(msgbuf
), 8)) == 8; bn
++) {
539 * do the transformation
541 DES_XFORM(UBUFFER(msgbuf
));
542 WRITE(BUFFER(msgbuf
), 8);
545 * at EOF or last block -- in either ase, the last byte contains
546 * the character representation of the number of bytes in it
549 MEMZERO(&CHAR(msgbuf
, n
), 8 - n
);
551 DES_XFORM(UBUFFER(msgbuf
));
552 WRITE(BUFFER(msgbuf
), 8);
557 * This decrypts using the Electronic Code Book mode of DES
562 register int n
; /* number of bytes actually read */
563 register int c
; /* used to test for EOF */
564 register int bn
; /* block number */
565 Desbuf msgbuf
; /* I/O buffer */
567 for (bn
= 1; (n
= READ(BUFFER(msgbuf
), 8)) == 8; bn
++) {
569 * do the transformation
571 DES_XFORM(UBUFFER(msgbuf
));
573 * if the last one, handle it specially
575 if ((c
= getchar()) == EOF
) {
579 "decryption failed (block corrupted)");
582 (void)ungetc(c
, stdin
);
583 WRITE(BUFFER(msgbuf
), n
);
586 bdes_err(bn
, "decryption failed (incomplete block)");
590 * This encrypts using the Cipher Block Chaining mode of DES
595 register int n
; /* number of bytes actually read */
596 register int bn
; /* block number */
597 Desbuf msgbuf
; /* I/O buffer */
600 * do the transformation
602 for (bn
= 1; (n
= READ(BUFFER(msgbuf
), 8)) == 8; bn
++) {
603 for (n
= 0; n
< 8; n
++)
604 CHAR(msgbuf
, n
) ^= CHAR(ivec
, n
);
605 DES_XFORM(UBUFFER(msgbuf
));
606 MEMCPY(BUFFER(ivec
), BUFFER(msgbuf
), 8);
607 WRITE(BUFFER(msgbuf
), 8);
610 * at EOF or last block -- in either case, the last byte contains
611 * the character representation of the number of bytes in it
614 MEMZERO(&CHAR(msgbuf
, n
), 8 - n
);
616 for (n
= 0; n
< 8; n
++)
617 CHAR(msgbuf
, n
) ^= CHAR(ivec
, n
);
618 DES_XFORM(UBUFFER(msgbuf
));
619 WRITE(BUFFER(msgbuf
), 8);
624 * This decrypts using the Cipher Block Chaining mode of DES
629 register int n
; /* number of bytes actually read */
630 Desbuf msgbuf
; /* I/O buffer */
631 Desbuf ibuf
; /* temp buffer for initialization vector */
632 register int c
; /* used to test for EOF */
633 register int bn
; /* block number */
635 for (bn
= 0; (n
= READ(BUFFER(msgbuf
), 8)) == 8; bn
++) {
637 * do the transformation
639 MEMCPY(BUFFER(ibuf
), BUFFER(msgbuf
), 8);
640 DES_XFORM(UBUFFER(msgbuf
));
641 for (c
= 0; c
< 8; c
++)
642 UCHAR(msgbuf
, c
) ^= UCHAR(ivec
, c
);
643 MEMCPY(BUFFER(ivec
), BUFFER(ibuf
), 8);
645 * if the last one, handle it specially
647 if ((c
= getchar()) == EOF
) {
651 "decryption failed (block corrupted)");
654 (void)ungetc(c
, stdin
);
655 WRITE(BUFFER(msgbuf
), n
);
658 bdes_err(bn
, "decryption failed (incomplete block)");
662 * This authenticates using the Cipher Block Chaining mode of DES
667 register int n
, j
; /* number of bytes actually read */
668 Desbuf msgbuf
; /* I/O buffer */
669 Desbuf encbuf
; /* encryption buffer */
672 * do the transformation
673 * note we DISCARD the encrypted block;
674 * we only care about the last one
676 while ((n
= READ(BUFFER(msgbuf
), 8)) == 8) {
677 for (n
= 0; n
< 8; n
++)
678 CHAR(encbuf
, n
) = CHAR(msgbuf
, n
) ^ CHAR(ivec
, n
);
679 DES_XFORM(UBUFFER(encbuf
));
680 MEMCPY(BUFFER(ivec
), BUFFER(encbuf
), 8);
683 * now compute the last one, right padding with '\0' if need be
686 MEMZERO(&CHAR(msgbuf
, n
), 8 - n
);
687 for (n
= 0; n
< 8; n
++)
688 CHAR(encbuf
, n
) = CHAR(msgbuf
, n
) ^ CHAR(ivec
, n
);
689 DES_XFORM(UBUFFER(encbuf
));
693 * we write chars until fewer than 7 bits,
694 * and then pad the last one with 0 bits
696 for (n
= 0; macbits
> 7; n
++, macbits
-= 8)
697 (void)putchar(CHAR(encbuf
, n
));
699 CHAR(msgbuf
, 0) = 0x00;
700 for (j
= 0; j
< macbits
; j
++)
701 CHAR(msgbuf
, 0) |= (CHAR(encbuf
, n
)&bits
[j
]);
702 (void)putchar(CHAR(msgbuf
, 0));
707 * This encrypts using the Cipher FeedBack mode of DES
712 register int n
; /* number of bytes actually read */
713 register int nbytes
; /* number of bytes to read */
714 register int bn
; /* block number */
715 char ibuf
[8]; /* input buffer */
716 Desbuf msgbuf
; /* encryption buffer */
719 * do things in bytes, not bits
723 * do the transformation
725 for (bn
= 1; (n
= READ(ibuf
, nbytes
)) == nbytes
; bn
++) {
726 MEMCPY(BUFFER(msgbuf
), BUFFER(ivec
), 8);
727 DES_XFORM(UBUFFER(msgbuf
));
728 for (n
= 0; n
< 8 - nbytes
; n
++)
729 UCHAR(ivec
, n
) = UCHAR(ivec
, n
+nbytes
);
730 for (n
= 0; n
< nbytes
; n
++)
731 UCHAR(ivec
, 8-nbytes
+n
) = ibuf
[n
] ^ UCHAR(msgbuf
, n
);
732 WRITE(&CHAR(ivec
, 8-nbytes
), nbytes
);
735 * at EOF or last block -- in either case, the last byte contains
736 * the character representation of the number of bytes in it
739 MEMZERO(&ibuf
[n
], nbytes
- n
);
740 ibuf
[nbytes
- 1] = n
;
741 MEMCPY(BUFFER(msgbuf
), BUFFER(ivec
), 8);
742 DES_XFORM(UBUFFER(msgbuf
));
743 for (n
= 0; n
< nbytes
; n
++)
744 ibuf
[n
] ^= UCHAR(msgbuf
, n
);
749 * This decrypts using the Cipher Block Chaining mode of DES
754 register int n
; /* number of bytes actually read */
755 register int c
; /* used to test for EOF */
756 register int nbytes
; /* number of bytes to read */
757 register int bn
; /* block number */
758 char ibuf
[8]; /* input buffer */
759 char obuf
[8]; /* output buffer */
760 Desbuf msgbuf
; /* encryption buffer */
763 * do things in bytes, not bits
767 * do the transformation
769 for (bn
= 1; (n
= READ(ibuf
, nbytes
)) == nbytes
; bn
++) {
770 MEMCPY(BUFFER(msgbuf
), BUFFER(ivec
), 8);
771 DES_XFORM(UBUFFER(msgbuf
));
772 for (c
= 0; c
< 8 - nbytes
; c
++)
773 CHAR(ivec
, c
) = CHAR(ivec
, c
+nbytes
);
774 for (c
= 0; c
< nbytes
; c
++) {
775 CHAR(ivec
, 8-nbytes
+c
) = ibuf
[c
];
776 obuf
[c
] = ibuf
[c
] ^ UCHAR(msgbuf
, c
);
779 * if the last one, handle it specially
781 if ((c
= getchar()) == EOF
) {
783 if (n
< 0 || n
> nbytes
-1)
785 "decryption failed (block corrupted)");
788 (void)ungetc(c
, stdin
);
792 bdes_err(bn
, "decryption failed (incomplete block)");
796 * This encrypts using the alternative Cipher FeedBack mode of DES
801 register int n
; /* number of bytes actually read */
802 register int nbytes
; /* number of bytes to read */
803 register int bn
; /* block number */
804 char ibuf
[8]; /* input buffer */
805 char obuf
[8]; /* output buffer */
806 Desbuf msgbuf
; /* encryption buffer */
809 * do things in bytes, not bits
813 * do the transformation
815 for (bn
= 1; (n
= READ(ibuf
, nbytes
)) == nbytes
; bn
++) {
816 MEMCPY(BUFFER(msgbuf
), BUFFER(ivec
), 8);
817 DES_XFORM(UBUFFER(msgbuf
));
818 for (n
= 0; n
< 8 - nbytes
; n
++)
819 UCHAR(ivec
, n
) = UCHAR(ivec
, n
+nbytes
);
820 for (n
= 0; n
< nbytes
; n
++)
821 UCHAR(ivec
, 8-nbytes
+n
) = (ibuf
[n
] ^ UCHAR(msgbuf
, n
))
823 for (n
= 0; n
< nbytes
; n
++)
824 obuf
[n
] = CHAR(ivec
, 8-nbytes
+n
)&0177;
828 * at EOF or last block -- in either case, the last byte contains
829 * the character representation of the number of bytes in it
832 MEMZERO(&ibuf
[n
], nbytes
- n
);
833 ibuf
[nbytes
- 1] = ('0' + n
)|0200;
834 MEMCPY(BUFFER(msgbuf
), BUFFER(ivec
), 8);
835 DES_XFORM(UBUFFER(msgbuf
));
836 for (n
= 0; n
< nbytes
; n
++)
837 ibuf
[n
] ^= UCHAR(msgbuf
, n
);
842 * This decrypts using the alternative Cipher Block Chaining mode of DES
847 register int n
; /* number of bytes actually read */
848 register int c
; /* used to test for EOF */
849 register int nbytes
; /* number of bytes to read */
850 register int bn
; /* block number */
851 char ibuf
[8]; /* input buffer */
852 char obuf
[8]; /* output buffer */
853 Desbuf msgbuf
; /* encryption buffer */
856 * do things in bytes, not bits
860 * do the transformation
862 for (bn
= 1; (n
= READ(ibuf
, nbytes
)) == nbytes
; bn
++) {
863 MEMCPY(BUFFER(msgbuf
), BUFFER(ivec
), 8);
864 DES_XFORM(UBUFFER(msgbuf
));
865 for (c
= 0; c
< 8 - nbytes
; c
++)
866 CHAR(ivec
, c
) = CHAR(ivec
, c
+nbytes
);
867 for (c
= 0; c
< nbytes
; c
++) {
868 CHAR(ivec
, 8-nbytes
+c
) = ibuf
[c
]|0200;
869 obuf
[c
] = (ibuf
[c
] ^ UCHAR(msgbuf
, c
))&0177;
872 * if the last one, handle it specially
874 if ((c
= getchar()) == EOF
) {
875 if ((n
= (obuf
[nbytes
-1] - '0')) < 0
878 "decryption failed (block corrupted)");
881 (void)ungetc(c
, stdin
);
885 bdes_err(bn
, "decryption failed (incomplete block)");
890 * This encrypts using the Output FeedBack mode of DES
895 register int n
; /* number of bytes actually read */
896 register int c
; /* used to test for EOF */
897 register int nbytes
; /* number of bytes to read */
898 register int bn
; /* block number */
899 char ibuf
[8]; /* input buffer */
900 char obuf
[8]; /* output buffer */
901 Desbuf msgbuf
; /* encryption buffer */
904 * do things in bytes, not bits
908 * do the transformation
910 for (bn
= 1; (n
= READ(ibuf
, nbytes
)) == nbytes
; bn
++) {
911 MEMCPY(BUFFER(msgbuf
), BUFFER(ivec
), 8);
912 DES_XFORM(UBUFFER(msgbuf
));
913 for (n
= 0; n
< 8 - nbytes
; n
++)
914 UCHAR(ivec
, n
) = UCHAR(ivec
, n
+nbytes
);
915 for (n
= 0; n
< nbytes
; n
++) {
916 UCHAR(ivec
, 8-nbytes
+n
) = UCHAR(msgbuf
, n
);
917 obuf
[n
] = ibuf
[n
] ^ UCHAR(msgbuf
, n
);
922 * at EOF or last block -- in either case, the last byte contains
923 * the character representation of the number of bytes in it
926 MEMZERO(&ibuf
[n
], nbytes
- n
);
927 ibuf
[nbytes
- 1] = n
;
928 MEMCPY(BUFFER(msgbuf
), BUFFER(ivec
), 8);
929 DES_XFORM(UBUFFER(msgbuf
));
930 for (c
= 0; c
< nbytes
; c
++)
931 ibuf
[c
] ^= UCHAR(msgbuf
, c
);
936 * This decrypts using the Output Block Chaining mode of DES
941 register int n
; /* number of bytes actually read */
942 register int c
; /* used to test for EOF */
943 register int nbytes
; /* number of bytes to read */
944 register int bn
; /* block number */
945 char ibuf
[8]; /* input buffer */
946 char obuf
[8]; /* output buffer */
947 Desbuf msgbuf
; /* encryption buffer */
950 * do things in bytes, not bits
954 * do the transformation
956 for (bn
= 1; (n
= READ(ibuf
, nbytes
)) == nbytes
; bn
++) {
957 MEMCPY(BUFFER(msgbuf
), BUFFER(ivec
), 8);
958 DES_XFORM(UBUFFER(msgbuf
));
959 for (c
= 0; c
< 8 - nbytes
; c
++)
960 CHAR(ivec
, c
) = CHAR(ivec
, c
+nbytes
);
961 for (c
= 0; c
< nbytes
; c
++) {
962 CHAR(ivec
, 8-nbytes
+c
) = UCHAR(msgbuf
, c
);
963 obuf
[c
] = ibuf
[c
] ^ UCHAR(msgbuf
, c
);
966 * if the last one, handle it specially
968 if ((c
= getchar()) == EOF
) {
970 if (n
< 0 || n
> nbytes
-1)
972 "decryption failed (block corrupted)");
975 (void)ungetc(c
, stdin
);
982 bdes_err(bn
, "decryption failed (incomplete block)");
986 * This authenticates using the Cipher FeedBack mode of DES
991 register int n
, j
; /* number of bytes actually read */
992 register int nbytes
; /* number of bytes to read */
993 char ibuf
[8]; /* input buffer */
994 Desbuf msgbuf
; /* encryption buffer */
997 * do things in bytes, not bits
1001 * do the transformation
1003 while ((n
= READ(ibuf
, nbytes
)) == nbytes
) {
1004 MEMCPY(BUFFER(msgbuf
), BUFFER(ivec
), 8);
1005 DES_XFORM(UBUFFER(msgbuf
));
1006 for (n
= 0; n
< 8 - nbytes
; n
++)
1007 UCHAR(ivec
, n
) = UCHAR(ivec
, n
+nbytes
);
1008 for (n
= 0; n
< nbytes
; n
++)
1009 UCHAR(ivec
, 8-nbytes
+n
) = ibuf
[n
] ^ UCHAR(msgbuf
, n
);
1012 * at EOF or last block -- in either case, the last byte contains
1013 * the character representation of the number of bytes in it
1015 MEMZERO(&ibuf
[n
], nbytes
- n
);
1016 ibuf
[nbytes
- 1] = '0' + n
;
1017 MEMCPY(BUFFER(msgbuf
), BUFFER(ivec
), 8);
1018 DES_XFORM(UBUFFER(msgbuf
));
1019 for (n
= 0; n
< nbytes
; n
++)
1020 ibuf
[n
] ^= UCHAR(msgbuf
, n
);
1023 * we write chars until fewer than 7 bits,
1024 * and then pad the last one with 0 bits
1026 for (n
= 0; macbits
> 7; n
++, macbits
-= 8)
1027 (void)putchar(CHAR(msgbuf
, n
));
1029 CHAR(msgbuf
, 0) = 0x00;
1030 for (j
= 0; j
< macbits
; j
++)
1031 CHAR(msgbuf
, 0) |= (CHAR(msgbuf
, n
)&bits
[j
]);
1032 (void)putchar(CHAR(msgbuf
, 0));
1038 * change from 8 bits/Uchar to 1 bit/Uchar
1041 expand(Desbuf from
, char *to
)
1043 register int i
, j
; /* counters in for loop */
1045 for (i
= 0; i
< 8; i
++)
1046 for (j
= 0; j
< 8; j
++)
1047 *to
++ = (CHAR(from
, i
)>>(7-j
))&01;
1051 * change from 1 bit/char to 8 bits/Uchar
1054 compress(char *from
, Desbuf to
)
1056 register int i
, j
; /* counters in for loop */
1058 for (i
= 0; i
< 8; i
++) {
1060 for (j
= 0; j
< 8; j
++)
1061 CHAR(to
, i
) = ((*from
++)<<(7-j
))|CHAR(to
, i
);
1067 * message about usage
1073 (void) fprintf(stderr
, "usage: %s %s\n", getprogname(),
1074 "[-abdp] [-F bit] [-f bit] [-k key] [-m bit] [-o bit] [-v vector]");