bdes.c revision 1.5 1 /* $NetBSD: bdes.c,v 1.5 2003/08/07 11:13:11 agc 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. 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.
25 *
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
36 * SUCH DAMAGE.
37 */
38
39 #include <sys/cdefs.h>
40 #ifndef lint
41 __COPYRIGHT("@(#) Copyright (c) 1991, 1993\n\
42 The Regents of the University of California. All rights reserved.\n");
43 #endif /* not lint */
44
45 #ifndef lint
46 #if 0
47 static char sccsid[] = "@(#)bdes.c 8.1 (Berkeley) 6/6/93";
48 #else
49 __RCSID("$NetBSD: bdes.c,v 1.5 2003/08/07 11:13:11 agc Exp $");
50 #endif
51 #endif /* not lint */
52
53 /*
54 * BDES -- DES encryption package for Berkeley Software Distribution 4.4
55 * options:
56 * -a key is in ASCII
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
68 *
69 * Author: Matt Bishop
70 * Department of Mathematics and Computer Science
71 * Dartmouth College
72 * Hanover, NH 03755
73 * Email: Matt.Bishop (at) dartmouth.edu
74 * ...!decvax!dartvax!Matt.Bishop
75 *
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).
81 */
82
83 #include <errno.h>
84 #include <unistd.h>
85 #include <stdio.h>
86 #include <ctype.h>
87 #include <stdlib.h>
88 #include <string.h>
89
90 /*
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
93 */
94 #define MEMCPY(dest,src,len) bcopy((src),(dest),(len))
95 #define MEMZERO(dest,len) bzero((dest),(len))
96
97 /* Hide the calls to the primitive encryption routines. */
98 #define FASTWAY
99 #ifdef FASTWAY
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");
106 #else
107 #define DES_KEY(buf) { \
108 char bits1[64]; /* bits of key */ \
109 expand(buf, bits1); \
110 if (setkey(bits1)) \
111 bdes_err(0, "setkey"); \
112 }
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); \
119 }
120 #endif
121
122 /*
123 * this does an error-checking write
124 */
125 #define READ(buf, n) fread(buf, sizeof(char), n, stdin)
126 #define WRITE(buf,n) \
127 if (fwrite(buf, sizeof(char), n, stdout) != n) \
128 bdes_err(bn, NULL);
129
130 /*
131 * some things to make references easier
132 */
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)
138
139 /*
140 * global variables and related macros
141 */
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 */
145
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
151 } alg = ALG_CBC;
152
153 Desbuf ivec; /* initialization vector */
154 char bits[] = { /* used to extract bits from a char */
155 '\200', '\100', '\040', '\020', '\010', '\004', '\002', '\001'
156 };
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 */
161
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);
167 void ecbenc(void);
168 void ecbdec(void);
169 void cbcenc(void);
170 void cbcdec(void);
171 void cbcauth(void);
172 void cfbenc(void);
173 void cfbdec(void);
174 void cfbaenc(void);
175 void cfbadec(void);
176 void ofbenc(void);
177 void ofbdec(void);
178 void cfbauth(void);
179 void expand(Desbuf, char *);
180 void compress(char *, Desbuf);
181 void usage(void);
182
183 int
184 main(int ac, char *av[])
185 {
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 */
192
193 /*
194 * Hide the arguments from ps(1) by making private copies of them
195 * and clobbering the global (visible to ps(1)) ones.
196 */
197 argc = ac;
198 ac = 1;
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]));
203 }
204 argv[argc] = NULL;
205
206 /* initialize the initialization vctor */
207 MEMZERO(ivec, 8);
208
209 /* process the argument list */
210 kflag = 0;
211 while ((i = getopt(argc, argv, "abdF:f:k:m:o:pv:")) != -1)
212 switch(i) {
213 case 'a': /* key is ASCII */
214 keybase = KEY_ASCII;
215 break;
216 case 'b': /* use ECB mode */
217 alg = ALG_ECB;
218 break;
219 case 'd': /* decrypt */
220 mode = MODE_DECRYPT;
221 break;
222 case 'F': /* use alternative CFB mode */
223 alg = ALG_CFBA;
224 if ((fbbits = setbits(optarg, 7)) > 56 || fbbits == 0)
225 bdes_err(-1,
226 "-F: number must be 1-56 inclusive");
227 else if (fbbits == -1)
228 bdes_err(-1,
229 "-F: number must be a multiple of 7");
230 break;
231 case 'f': /* use CFB mode */
232 alg = ALG_CFB;
233 if ((fbbits = setbits(optarg, 8)) > 64 || fbbits == 0)
234 bdes_err(-1,
235 "-f: number must be 1-64 inclusive");
236 else if (fbbits == -1)
237 bdes_err(-1,
238 "-f: number must be a multiple of 8");
239 break;
240 case 'k': /* encryption key */
241 kflag = 1;
242 cvtkey(BUFFER(msgbuf), optarg);
243 break;
244 case 'm': /* number of bits for MACing */
245 mode = MODE_AUTHENTICATE;
246 if ((macbits = setbits(optarg, 1)) > 64)
247 bdes_err(-1,
248 "-m: number must be 0-64 inclusive");
249 break;
250 case 'o': /* use OFB mode */
251 alg = ALG_OFB;
252 if ((fbbits = setbits(optarg, 8)) > 64 || fbbits == 0)
253 bdes_err(-1,
254 "-o: number must be 1-64 inclusive");
255 else if (fbbits == -1)
256 bdes_err(-1,
257 "-o: number must be a multiple of 8");
258 break;
259 case 'p': /* preserve parity bits */
260 pflag = 1;
261 break;
262 case 'v': /* set initialization vector */
263 cvtkey(BUFFER(ivec), optarg);
264 break;
265 default: /* error */
266 usage();
267 }
268
269 if (!kflag) {
270 /*
271 * if the key's not ASCII, assume it is
272 */
273 keybase = KEY_ASCII;
274 /*
275 * get the key
276 */
277 p = getpass("Enter key: ");
278 /*
279 * copy it, nul-padded, into the key area
280 */
281 cvtkey(BUFFER(msgbuf), p);
282 }
283
284 makekey(msgbuf);
285 inverse = (alg == ALG_CBC || alg == ALG_ECB) && mode == MODE_DECRYPT;
286
287 switch(alg) {
288 case ALG_CBC:
289 switch(mode) {
290 case MODE_AUTHENTICATE: /* authenticate using CBC mode */
291 cbcauth();
292 break;
293 case MODE_DECRYPT: /* decrypt using CBC mode */
294 cbcdec();
295 break;
296 case MODE_ENCRYPT: /* encrypt using CBC mode */
297 cbcenc();
298 break;
299 }
300 break;
301 case ALG_CFB:
302 switch(mode) {
303 case MODE_AUTHENTICATE: /* authenticate using CFB mode */
304 cfbauth();
305 break;
306 case MODE_DECRYPT: /* decrypt using CFB mode */
307 cfbdec();
308 break;
309 case MODE_ENCRYPT: /* encrypt using CFB mode */
310 cfbenc();
311 break;
312 }
313 break;
314 case ALG_CFBA:
315 switch(mode) {
316 case MODE_AUTHENTICATE: /* authenticate using CFBA mode */
317 bdes_err(-1, "can't authenticate with CFBA mode");
318 break;
319 case MODE_DECRYPT: /* decrypt using CFBA mode */
320 cfbadec();
321 break;
322 case MODE_ENCRYPT: /* encrypt using CFBA mode */
323 cfbaenc();
324 break;
325 }
326 break;
327 case ALG_ECB:
328 switch(mode) {
329 case MODE_AUTHENTICATE: /* authenticate using ECB mode */
330 bdes_err(-1, "can't authenticate with ECB mode");
331 break;
332 case MODE_DECRYPT: /* decrypt using ECB mode */
333 ecbdec();
334 break;
335 case MODE_ENCRYPT: /* encrypt using ECB mode */
336 ecbenc();
337 break;
338 }
339 break;
340 case ALG_OFB:
341 switch(mode) {
342 case MODE_AUTHENTICATE: /* authenticate using OFB mode */
343 bdes_err(-1, "can't authenticate with OFB mode");
344 break;
345 case MODE_DECRYPT: /* decrypt using OFB mode */
346 ofbdec();
347 break;
348 case MODE_ENCRYPT: /* encrypt using OFB mode */
349 ofbenc();
350 break;
351 }
352 break;
353 }
354 exit(0);
355 }
356
357 /*
358 * print a warning message and, possibly, terminate
359 */
360 void
361 bdes_err(int n, const char *s)
362 {
363 if (n > 0)
364 (void)fprintf(stderr, "bdes (block %d): ", n);
365 else
366 (void)fprintf(stderr, "bdes: ");
367 (void)fprintf(stderr, "%s\n", s ? s : strerror(errno));
368 exit(1);
369 }
370
371 /*
372 * map a hex character to an integer
373 */
374 int
375 tobinhex(char c, int radix)
376 {
377 switch(c) {
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);
394 }
395 /*
396 * invalid character
397 */
398 return(-1);
399 }
400
401 /*
402 * convert the key to a bit pattern
403 */
404 void
405 cvtkey(char *obuf, char *ibuf)
406 {
407 register int i, j; /* counter in a for loop */
408 int nbuf[64]; /* used for hex/key translation */
409
410 /*
411 * just switch on the key base
412 */
413 switch(keybase) {
414 case KEY_ASCII: /* ascii to integer */
415 (void)strncpy(obuf, ibuf, 8);
416 return;
417 case KEY_DEFAULT: /* tell from context */
418 /*
419 * leading '0x' or '0X' == hex key
420 */
421 if (ibuf[0] == '0' && (ibuf[1] == 'x' || ibuf[1] == 'X')) {
422 ibuf = &ibuf[2];
423 /*
424 * now translate it, bombing on any illegal hex digit
425 */
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");
429 while (i < 16)
430 nbuf[i++] = 0;
431 for (i = 0; i < 8; i++)
432 obuf[i] =
433 ((nbuf[2*i]&0xf)<<4) | (nbuf[2*i+1]&0xf);
434 /* preserve parity bits */
435 pflag = 1;
436 return;
437 }
438 /*
439 * leading '0b' or '0B' == binary key
440 */
441 if (ibuf[0] == '0' && (ibuf[1] == 'b' || ibuf[1] == 'B')) {
442 ibuf = &ibuf[2];
443 /*
444 * now translate it, bombing on any illegal binary digit
445 */
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");
449 while (i < 64)
450 nbuf[i++] = 0;
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 */
455 pflag = 1;
456 return;
457 }
458 /*
459 * no special leader -- ASCII
460 */
461 (void)strncpy(obuf, ibuf, 8);
462 }
463 }
464
465 /*
466 * convert an ASCII string into a decimal number:
467 * 1. must be between 0 and 64 inclusive
468 * 2. must be a valid decimal number
469 * 3. must be a multiple of mult
470 */
471 int
472 setbits(char *s, int mult)
473 {
474 register char *p; /* pointer in a for loop */
475 register int n = 0; /* the integer collected */
476
477 /*
478 * skip white space
479 */
480 while (isspace(*s))
481 s++;
482 /*
483 * get the integer
484 */
485 for (p = s; *p; p++) {
486 if (isdigit(*p))
487 n = n * 10 + *p - '0';
488 else {
489 bdes_err(-1, "bad decimal digit in MAC length");
490 }
491 }
492 /*
493 * be sure it's a multiple of mult
494 */
495 return((n % mult != 0) ? -1 : n);
496 }
497
498 /*****************
499 * DES FUNCTIONS *
500 *****************/
501 /*
502 * This sets the DES key and (if you're using the deszip version)
503 * the direction of the transformation. This uses the Sun
504 * to map the 64-bit key onto the 56 bits that the key schedule
505 * generation routines use: the old way, which just uses the user-
506 * supplied 64 bits as is, and the new way, which resets the parity
507 * bit to be the same as the low-order bit in each character. The
508 * new way generates a greater variety of key schedules, since many
509 * systems set the parity (high) bit of each character to 0, and the
510 * DES ignores the low order bit of each character.
511 */
512 void
513 makekey(Desbuf buf)
514 {
515 register int i, j; /* counter in a for loop */
516 register int par; /* parity counter */
517
518 /*
519 * if the parity is not preserved, flip it
520 */
521 if (!pflag) {
522 for (i = 0; i < 8; i++) {
523 par = 0;
524 for (j = 1; j < 8; j++)
525 if ((bits[j]&UCHAR(buf, i)) != 0)
526 par++;
527 if ((par&01) == 01)
528 UCHAR(buf, i) = UCHAR(buf, i)&0177;
529 else
530 UCHAR(buf, i) = (UCHAR(buf, i)&0177)|0200;
531 }
532 }
533
534 DES_KEY(UBUFFER(buf));
535 }
536
537 /*
538 * This encrypts using the Electronic Code Book mode of DES
539 */
540 void
541 ecbenc(void)
542 {
543 register int n; /* number of bytes actually read */
544 register int bn; /* block number */
545 Desbuf msgbuf; /* I/O buffer */
546
547 for (bn = 0; (n = READ(BUFFER(msgbuf), 8)) == 8; bn++) {
548 /*
549 * do the transformation
550 */
551 DES_XFORM(UBUFFER(msgbuf));
552 WRITE(BUFFER(msgbuf), 8);
553 }
554 /*
555 * at EOF or last block -- in either ase, the last byte contains
556 * the character representation of the number of bytes in it
557 */
558 bn++;
559 MEMZERO(&CHAR(msgbuf, n), 8 - n);
560 CHAR(msgbuf, 7) = n;
561 DES_XFORM(UBUFFER(msgbuf));
562 WRITE(BUFFER(msgbuf), 8);
563
564 }
565
566 /*
567 * This decrypts using the Electronic Code Book mode of DES
568 */
569 void
570 ecbdec(void)
571 {
572 register int n; /* number of bytes actually read */
573 register int c; /* used to test for EOF */
574 register int bn; /* block number */
575 Desbuf msgbuf; /* I/O buffer */
576
577 for (bn = 1; (n = READ(BUFFER(msgbuf), 8)) == 8; bn++) {
578 /*
579 * do the transformation
580 */
581 DES_XFORM(UBUFFER(msgbuf));
582 /*
583 * if the last one, handle it specially
584 */
585 if ((c = getchar()) == EOF) {
586 n = CHAR(msgbuf, 7);
587 if (n < 0 || n > 7)
588 bdes_err(bn,
589 "decryption failed (block corrupted)");
590 }
591 else
592 (void)ungetc(c, stdin);
593 WRITE(BUFFER(msgbuf), n);
594 }
595 if (n > 0)
596 bdes_err(bn, "decryption failed (incomplete block)");
597 }
598
599 /*
600 * This encrypts using the Cipher Block Chaining mode of DES
601 */
602 void
603 cbcenc(void)
604 {
605 register int n; /* number of bytes actually read */
606 register int bn; /* block number */
607 Desbuf msgbuf; /* I/O buffer */
608
609 /*
610 * do the transformation
611 */
612 for (bn = 1; (n = READ(BUFFER(msgbuf), 8)) == 8; bn++) {
613 for (n = 0; n < 8; n++)
614 CHAR(msgbuf, n) ^= CHAR(ivec, n);
615 DES_XFORM(UBUFFER(msgbuf));
616 MEMCPY(BUFFER(ivec), BUFFER(msgbuf), 8);
617 WRITE(BUFFER(msgbuf), 8);
618 }
619 /*
620 * at EOF or last block -- in either case, the last byte contains
621 * the character representation of the number of bytes in it
622 */
623 bn++;
624 MEMZERO(&CHAR(msgbuf, n), 8 - n);
625 CHAR(msgbuf, 7) = n;
626 for (n = 0; n < 8; n++)
627 CHAR(msgbuf, n) ^= CHAR(ivec, n);
628 DES_XFORM(UBUFFER(msgbuf));
629 WRITE(BUFFER(msgbuf), 8);
630
631 }
632
633 /*
634 * This decrypts using the Cipher Block Chaining mode of DES
635 */
636 void
637 cbcdec(void)
638 {
639 register int n; /* number of bytes actually read */
640 Desbuf msgbuf; /* I/O buffer */
641 Desbuf ibuf; /* temp buffer for initialization vector */
642 register int c; /* used to test for EOF */
643 register int bn; /* block number */
644
645 for (bn = 0; (n = READ(BUFFER(msgbuf), 8)) == 8; bn++) {
646 /*
647 * do the transformation
648 */
649 MEMCPY(BUFFER(ibuf), BUFFER(msgbuf), 8);
650 DES_XFORM(UBUFFER(msgbuf));
651 for (c = 0; c < 8; c++)
652 UCHAR(msgbuf, c) ^= UCHAR(ivec, c);
653 MEMCPY(BUFFER(ivec), BUFFER(ibuf), 8);
654 /*
655 * if the last one, handle it specially
656 */
657 if ((c = getchar()) == EOF) {
658 n = CHAR(msgbuf, 7);
659 if (n < 0 || n > 7)
660 bdes_err(bn,
661 "decryption failed (block corrupted)");
662 }
663 else
664 (void)ungetc(c, stdin);
665 WRITE(BUFFER(msgbuf), n);
666 }
667 if (n > 0)
668 bdes_err(bn, "decryption failed (incomplete block)");
669 }
670
671 /*
672 * This authenticates using the Cipher Block Chaining mode of DES
673 */
674 void
675 cbcauth(void)
676 {
677 register int n, j; /* number of bytes actually read */
678 Desbuf msgbuf; /* I/O buffer */
679 Desbuf encbuf; /* encryption buffer */
680
681 /*
682 * do the transformation
683 * note we DISCARD the encrypted block;
684 * we only care about the last one
685 */
686 while ((n = READ(BUFFER(msgbuf), 8)) == 8) {
687 for (n = 0; n < 8; n++)
688 CHAR(encbuf, n) = CHAR(msgbuf, n) ^ CHAR(ivec, n);
689 DES_XFORM(UBUFFER(encbuf));
690 MEMCPY(BUFFER(ivec), BUFFER(encbuf), 8);
691 }
692 /*
693 * now compute the last one, right padding with '\0' if need be
694 */
695 if (n > 0) {
696 MEMZERO(&CHAR(msgbuf, n), 8 - n);
697 for (n = 0; n < 8; n++)
698 CHAR(encbuf, n) = CHAR(msgbuf, n) ^ CHAR(ivec, n);
699 DES_XFORM(UBUFFER(encbuf));
700 }
701 /*
702 * drop the bits
703 * we write chars until fewer than 7 bits,
704 * and then pad the last one with 0 bits
705 */
706 for (n = 0; macbits > 7; n++, macbits -= 8)
707 (void)putchar(CHAR(encbuf, n));
708 if (macbits > 0) {
709 CHAR(msgbuf, 0) = 0x00;
710 for (j = 0; j < macbits; j++)
711 CHAR(msgbuf, 0) |= (CHAR(encbuf, n)&bits[j]);
712 (void)putchar(CHAR(msgbuf, 0));
713 }
714 }
715
716 /*
717 * This encrypts using the Cipher FeedBack mode of DES
718 */
719 void
720 cfbenc(void)
721 {
722 register int n; /* number of bytes actually read */
723 register int nbytes; /* number of bytes to read */
724 register int bn; /* block number */
725 char ibuf[8]; /* input buffer */
726 Desbuf msgbuf; /* encryption buffer */
727
728 /*
729 * do things in bytes, not bits
730 */
731 nbytes = fbbits / 8;
732 /*
733 * do the transformation
734 */
735 for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) {
736 MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
737 DES_XFORM(UBUFFER(msgbuf));
738 for (n = 0; n < 8 - nbytes; n++)
739 UCHAR(ivec, n) = UCHAR(ivec, n+nbytes);
740 for (n = 0; n < nbytes; n++)
741 UCHAR(ivec, 8-nbytes+n) = ibuf[n] ^ UCHAR(msgbuf, n);
742 WRITE(&CHAR(ivec, 8-nbytes), nbytes);
743 }
744 /*
745 * at EOF or last block -- in either case, the last byte contains
746 * the character representation of the number of bytes in it
747 */
748 bn++;
749 MEMZERO(&ibuf[n], nbytes - n);
750 ibuf[nbytes - 1] = n;
751 MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
752 DES_XFORM(UBUFFER(msgbuf));
753 for (n = 0; n < nbytes; n++)
754 ibuf[n] ^= UCHAR(msgbuf, n);
755 WRITE(ibuf, nbytes);
756 }
757
758 /*
759 * This decrypts using the Cipher Block Chaining mode of DES
760 */
761 void
762 cfbdec(void)
763 {
764 register int n; /* number of bytes actually read */
765 register int c; /* used to test for EOF */
766 register int nbytes; /* number of bytes to read */
767 register int bn; /* block number */
768 char ibuf[8]; /* input buffer */
769 char obuf[8]; /* output buffer */
770 Desbuf msgbuf; /* encryption buffer */
771
772 /*
773 * do things in bytes, not bits
774 */
775 nbytes = fbbits / 8;
776 /*
777 * do the transformation
778 */
779 for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) {
780 MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
781 DES_XFORM(UBUFFER(msgbuf));
782 for (c = 0; c < 8 - nbytes; c++)
783 CHAR(ivec, c) = CHAR(ivec, c+nbytes);
784 for (c = 0; c < nbytes; c++) {
785 CHAR(ivec, 8-nbytes+c) = ibuf[c];
786 obuf[c] = ibuf[c] ^ UCHAR(msgbuf, c);
787 }
788 /*
789 * if the last one, handle it specially
790 */
791 if ((c = getchar()) == EOF) {
792 n = obuf[nbytes-1];
793 if (n < 0 || n > nbytes-1)
794 bdes_err(bn,
795 "decryption failed (block corrupted)");
796 }
797 else
798 (void)ungetc(c, stdin);
799 WRITE(obuf, n);
800 }
801 if (n > 0)
802 bdes_err(bn, "decryption failed (incomplete block)");
803 }
804
805 /*
806 * This encrypts using the alternative Cipher FeedBack mode of DES
807 */
808 void
809 cfbaenc(void)
810 {
811 register int n; /* number of bytes actually read */
812 register int nbytes; /* number of bytes to read */
813 register int bn; /* block number */
814 char ibuf[8]; /* input buffer */
815 char obuf[8]; /* output buffer */
816 Desbuf msgbuf; /* encryption buffer */
817
818 /*
819 * do things in bytes, not bits
820 */
821 nbytes = fbbits / 7;
822 /*
823 * do the transformation
824 */
825 for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) {
826 MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
827 DES_XFORM(UBUFFER(msgbuf));
828 for (n = 0; n < 8 - nbytes; n++)
829 UCHAR(ivec, n) = UCHAR(ivec, n+nbytes);
830 for (n = 0; n < nbytes; n++)
831 UCHAR(ivec, 8-nbytes+n) = (ibuf[n] ^ UCHAR(msgbuf, n))
832 |0200;
833 for (n = 0; n < nbytes; n++)
834 obuf[n] = CHAR(ivec, 8-nbytes+n)&0177;
835 WRITE(obuf, nbytes);
836 }
837 /*
838 * at EOF or last block -- in either case, the last byte contains
839 * the character representation of the number of bytes in it
840 */
841 bn++;
842 MEMZERO(&ibuf[n], nbytes - n);
843 ibuf[nbytes - 1] = ('0' + n)|0200;
844 MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
845 DES_XFORM(UBUFFER(msgbuf));
846 for (n = 0; n < nbytes; n++)
847 ibuf[n] ^= UCHAR(msgbuf, n);
848 WRITE(ibuf, nbytes);
849 }
850
851 /*
852 * This decrypts using the alternative Cipher Block Chaining mode of DES
853 */
854 void
855 cfbadec(void)
856 {
857 register int n; /* number of bytes actually read */
858 register int c; /* used to test for EOF */
859 register int nbytes; /* number of bytes to read */
860 register int bn; /* block number */
861 char ibuf[8]; /* input buffer */
862 char obuf[8]; /* output buffer */
863 Desbuf msgbuf; /* encryption buffer */
864
865 /*
866 * do things in bytes, not bits
867 */
868 nbytes = fbbits / 7;
869 /*
870 * do the transformation
871 */
872 for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) {
873 MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
874 DES_XFORM(UBUFFER(msgbuf));
875 for (c = 0; c < 8 - nbytes; c++)
876 CHAR(ivec, c) = CHAR(ivec, c+nbytes);
877 for (c = 0; c < nbytes; c++) {
878 CHAR(ivec, 8-nbytes+c) = ibuf[c]|0200;
879 obuf[c] = (ibuf[c] ^ UCHAR(msgbuf, c))&0177;
880 }
881 /*
882 * if the last one, handle it specially
883 */
884 if ((c = getchar()) == EOF) {
885 if ((n = (obuf[nbytes-1] - '0')) < 0
886 || n > nbytes-1)
887 bdes_err(bn,
888 "decryption failed (block corrupted)");
889 }
890 else
891 (void)ungetc(c, stdin);
892 WRITE(obuf, n);
893 }
894 if (n > 0)
895 bdes_err(bn, "decryption failed (incomplete block)");
896 }
897
898
899 /*
900 * This encrypts using the Output FeedBack mode of DES
901 */
902 void
903 ofbenc(void)
904 {
905 register int n; /* number of bytes actually read */
906 register int c; /* used to test for EOF */
907 register int nbytes; /* number of bytes to read */
908 register int bn; /* block number */
909 char ibuf[8]; /* input buffer */
910 char obuf[8]; /* output buffer */
911 Desbuf msgbuf; /* encryption buffer */
912
913 /*
914 * do things in bytes, not bits
915 */
916 nbytes = fbbits / 8;
917 /*
918 * do the transformation
919 */
920 for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) {
921 MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
922 DES_XFORM(UBUFFER(msgbuf));
923 for (n = 0; n < 8 - nbytes; n++)
924 UCHAR(ivec, n) = UCHAR(ivec, n+nbytes);
925 for (n = 0; n < nbytes; n++) {
926 UCHAR(ivec, 8-nbytes+n) = UCHAR(msgbuf, n);
927 obuf[n] = ibuf[n] ^ UCHAR(msgbuf, n);
928 }
929 WRITE(obuf, nbytes);
930 }
931 /*
932 * at EOF or last block -- in either case, the last byte contains
933 * the character representation of the number of bytes in it
934 */
935 bn++;
936 MEMZERO(&ibuf[n], nbytes - n);
937 ibuf[nbytes - 1] = n;
938 MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
939 DES_XFORM(UBUFFER(msgbuf));
940 for (c = 0; c < nbytes; c++)
941 ibuf[c] ^= UCHAR(msgbuf, c);
942 WRITE(ibuf, nbytes);
943 }
944
945 /*
946 * This decrypts using the Output Block Chaining mode of DES
947 */
948 void
949 ofbdec(void)
950 {
951 register int n; /* number of bytes actually read */
952 register int c; /* used to test for EOF */
953 register int nbytes; /* number of bytes to read */
954 register int bn; /* block number */
955 char ibuf[8]; /* input buffer */
956 char obuf[8]; /* output buffer */
957 Desbuf msgbuf; /* encryption buffer */
958
959 /*
960 * do things in bytes, not bits
961 */
962 nbytes = fbbits / 8;
963 /*
964 * do the transformation
965 */
966 for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) {
967 MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
968 DES_XFORM(UBUFFER(msgbuf));
969 for (c = 0; c < 8 - nbytes; c++)
970 CHAR(ivec, c) = CHAR(ivec, c+nbytes);
971 for (c = 0; c < nbytes; c++) {
972 CHAR(ivec, 8-nbytes+c) = UCHAR(msgbuf, c);
973 obuf[c] = ibuf[c] ^ UCHAR(msgbuf, c);
974 }
975 /*
976 * if the last one, handle it specially
977 */
978 if ((c = getchar()) == EOF) {
979 n = obuf[nbytes-1];
980 if (n < 0 || n > nbytes-1)
981 bdes_err(bn,
982 "decryption failed (block corrupted)");
983 }
984 else
985 (void)ungetc(c, stdin);
986 /*
987 * dump it
988 */
989 WRITE(obuf, n);
990 }
991 if (n > 0)
992 bdes_err(bn, "decryption failed (incomplete block)");
993 }
994
995 /*
996 * This authenticates using the Cipher FeedBack mode of DES
997 */
998 void
999 cfbauth(void)
1000 {
1001 register int n, j; /* number of bytes actually read */
1002 register int nbytes; /* number of bytes to read */
1003 char ibuf[8]; /* input buffer */
1004 Desbuf msgbuf; /* encryption buffer */
1005
1006 /*
1007 * do things in bytes, not bits
1008 */
1009 nbytes = fbbits / 8;
1010 /*
1011 * do the transformation
1012 */
1013 while ((n = READ(ibuf, nbytes)) == nbytes) {
1014 MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
1015 DES_XFORM(UBUFFER(msgbuf));
1016 for (n = 0; n < 8 - nbytes; n++)
1017 UCHAR(ivec, n) = UCHAR(ivec, n+nbytes);
1018 for (n = 0; n < nbytes; n++)
1019 UCHAR(ivec, 8-nbytes+n) = ibuf[n] ^ UCHAR(msgbuf, n);
1020 }
1021 /*
1022 * at EOF or last block -- in either case, the last byte contains
1023 * the character representation of the number of bytes in it
1024 */
1025 MEMZERO(&ibuf[n], nbytes - n);
1026 ibuf[nbytes - 1] = '0' + n;
1027 MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
1028 DES_XFORM(UBUFFER(msgbuf));
1029 for (n = 0; n < nbytes; n++)
1030 ibuf[n] ^= UCHAR(msgbuf, n);
1031 /*
1032 * drop the bits
1033 * we write chars until fewer than 7 bits,
1034 * and then pad the last one with 0 bits
1035 */
1036 for (n = 0; macbits > 7; n++, macbits -= 8)
1037 (void)putchar(CHAR(msgbuf, n));
1038 if (macbits > 0) {
1039 CHAR(msgbuf, 0) = 0x00;
1040 for (j = 0; j < macbits; j++)
1041 CHAR(msgbuf, 0) |= (CHAR(msgbuf, n)&bits[j]);
1042 (void)putchar(CHAR(msgbuf, 0));
1043 }
1044 }
1045
1046 #ifndef FASTWAY
1047 /*
1048 * change from 8 bits/Uchar to 1 bit/Uchar
1049 */
1050 void
1051 expand(Desbuf from, char *to)
1052 {
1053 register int i, j; /* counters in for loop */
1054
1055 for (i = 0; i < 8; i++)
1056 for (j = 0; j < 8; j++)
1057 *to++ = (CHAR(from, i)>>(7-j))&01;
1058 }
1059
1060 /*
1061 * change from 1 bit/char to 8 bits/Uchar
1062 */
1063 void
1064 compress(char *from, Desbuf to)
1065 {
1066 register int i, j; /* counters in for loop */
1067
1068 for (i = 0; i < 8; i++) {
1069 CHAR(to, i) = 0;
1070 for (j = 0; j < 8; j++)
1071 CHAR(to, i) = ((*from++)<<(7-j))|CHAR(to, i);
1072 }
1073 }
1074 #endif
1075
1076 /*
1077 * message about usage
1078 */
1079 void
1080 usage(void)
1081 {
1082
1083 (void) fprintf(stderr, "usage: %s %s\n", getprogname(),
1084 "[-abdp] [-F bit] [-f bit] [-k key] [-m bit] [-o bit] [-v vector]");
1085 exit(1);
1086 }
1087