1 /*-
2 * Copyright (c) 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Matt Bishop of Dartmouth College.
7 *
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.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
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.
27 *
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
38 * SUCH DAMAGE.
39 */
40
41 #ifndef lint
42 static const char copyright[] =
43 "@(#) Copyright (c) 1991, 1993\n\
44 The Regents of the University of California. All rights reserved.\n";
45 #endif /* not lint */
46
47 #ifndef lint
48 #if 0
49 static char sccsid[] = "@(#)bdes.c 8.1 (Berkeley) 6/6/93";
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@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 <sys/cdefs.h>
84 /* __FBSDID("$FreeBSD: src/secure/usr.bin/bdes/bdes.c,v 1.9 2005/02/10 14:47:06 ru Exp $"); */
85
86 #include <sys/types.h>
87
88 #include <ctype.h>
89 #include <err.h>
90 #include <errno.h>
91 #include <stdio.h>
92 #include <stdlib.h>
93 #include <string.h>
94 #include <unistd.h>
95
96 #include <openssl/des.h>
97
98 /*
99 * BSD and System V systems offer special library calls that do
100 * block moves and fills, so if possible we take advantage of them
101 */
102 #define MEMCPY(dest,src,len) bcopy((src),(dest),(len))
103 #define MEMZERO(dest,len) bzero((dest),(len))
104
105 #define DES_XFORM(buf) \
106 DES_ecb_encrypt(buf, buf, &schedule, \
107 mode == MODE_ENCRYPT ? DES_ENCRYPT : DES_DECRYPT);
108
109 /*
110 * this does an error-checking write
111 */
112 #define READ(buf, n) fread(buf, sizeof(char), n, stdin)
113 #define WRITE(buf,n) \
114 if (fwrite(buf, sizeof(char), n, stdout) != n) \
115 warnx("fwrite error at %d", n);
116
117 /*
118 * global variables and related macros
119 */
120 #define KEY_DEFAULT 0 /* interpret radix of key from key */
121 #define KEY_ASCII 1 /* key is in ASCII characters */
122 int keybase = KEY_DEFAULT; /* how to interpret the key */
123
124 enum { /* encrypt, decrypt, authenticate */
125 MODE_ENCRYPT, MODE_DECRYPT, MODE_AUTHENTICATE
126 } mode = MODE_ENCRYPT;
127
128 enum { /* ecb, cbc, cfb, cfba, ofb? */
129 ALG_ECB, ALG_CBC, ALG_CFB, ALG_OFB, ALG_CFBA
130 } alg = ALG_CBC;
131
132 DES_cblock ivec; /* initialization vector */
133
134 char bits[] = { /* used to extract bits from a char */
135 '\200', '\100', '\040', '\020', '\010', '\004', '\002', '\001'
136 };
137
138 int inverse; /* 0 to encrypt, 1 to decrypt */
139 int macbits = -1; /* number of bits in authentication */
140 int fbbits = -1; /* number of feedback bits */
141 int pflag; /* 1 to preserve parity bits */
142
143 DES_key_schedule schedule; /* expanded DES key */
144
145 static void ecbenc(void);
146 static void ecbdec(void);
147 static void cbcenc(void);
148 static void cbcdec(void);
149 static void cfbenc(void);
150 static void cfbdec(void);
151 static void cfbaenc(void);
152 static void cfbadec(void);
153 static void ofbenc(void);
154 static void ofbdec(void);
155
156 static void cbcauth(void);
157 static void cfbauth(void);
158
159 static void cvtkey(DES_cblock, char *);
160 static int setbits(char *, int);
161 static void makekey(DES_cblock *);
162 static int tobinhex(char, int);
163
164 static void usage(void);
165
166 int
main(int argc,char * argv[])167 main(int argc, char *argv[])
168 {
169 extern char *optarg; /* argument to option if any */
170 int i; /* counter in a for loop */
171 char *p; /* used to obtain the key */
172 DES_cblock msgbuf; /* I/O buffer */
173 int kflag; /* command-line encryptiooon key */
174
175 #ifdef BSD
176 setproctitle("-"); /* Hide command-line arguments */
177 #endif
178
179 /* initialize the initialization vctor */
180 MEMZERO(ivec, 8);
181
182 /* process the argument list */
183 kflag = 0;
184 while ((i = getopt(argc, argv, "abdF:f:k:m:o:pv:")) != EOF)
185 switch(i) {
186 case 'a': /* key is ASCII */
187 keybase = KEY_ASCII;
188 break;
189 case 'b': /* use ECB mode */
190 alg = ALG_ECB;
191 break;
192 case 'd': /* decrypt */
193 mode = MODE_DECRYPT;
194 break;
195 case 'F': /* use alternative CFB mode */
196 alg = ALG_CFBA;
197 if ((fbbits = setbits(optarg, 7)) > 56 || fbbits == 0)
198 errx(1, "-F: number must be 1-56 inclusive");
199 else if (fbbits == -1)
200 errx(1, "-F: number must be a multiple of 7");
201 break;
202 case 'f': /* use CFB mode */
203 alg = ALG_CFB;
204 if ((fbbits = setbits(optarg, 8)) > 64 || fbbits == 0)
205 errx(1, "-f: number must be 1-64 inclusive");
206 else if (fbbits == -1)
207 errx(1, "-f: number must be a multiple of 8");
208 break;
209 case 'k': /* encryption key */
210 kflag = 1;
211 cvtkey(msgbuf, optarg);
212 break;
213 case 'm': /* number of bits for MACing */
214 mode = MODE_AUTHENTICATE;
215 if ((macbits = setbits(optarg, 1)) > 64)
216 errx(1, "-m: number must be 0-64 inclusive");
217 break;
218 case 'o': /* use OFB mode */
219 alg = ALG_OFB;
220 if ((fbbits = setbits(optarg, 8)) > 64 || fbbits == 0)
221 errx(1, "-o: number must be 1-64 inclusive");
222 else if (fbbits == -1)
223 errx(1, "-o: number must be a multiple of 8");
224 break;
225 case 'p': /* preserve parity bits */
226 pflag = 1;
227 break;
228 case 'v': /* set initialization vector */
229 cvtkey(ivec, optarg);
230 break;
231 default: /* error */
232 usage();
233 }
234
235 if (!kflag) {
236 /*
237 * if the key's not ASCII, assume it is
238 */
239 keybase = KEY_ASCII;
240 /*
241 * get the key
242 */
243 p = getpass("Enter key: ");
244 /*
245 * copy it, nul-padded, into the key area
246 */
247 cvtkey(msgbuf, p);
248 }
249
250 makekey(&msgbuf);
251 inverse = (alg == ALG_CBC || alg == ALG_ECB) && mode == MODE_DECRYPT;
252
253 switch(alg) {
254 case ALG_CBC:
255 switch(mode) {
256 case MODE_AUTHENTICATE: /* authenticate using CBC mode */
257 cbcauth();
258 break;
259 case MODE_DECRYPT: /* decrypt using CBC mode */
260 cbcdec();
261 break;
262 case MODE_ENCRYPT: /* encrypt using CBC mode */
263 cbcenc();
264 break;
265 }
266 break;
267 case ALG_CFB:
268 switch(mode) {
269 case MODE_AUTHENTICATE: /* authenticate using CFB mode */
270 cfbauth();
271 break;
272 case MODE_DECRYPT: /* decrypt using CFB mode */
273 cfbdec();
274 break;
275 case MODE_ENCRYPT: /* encrypt using CFB mode */
276 cfbenc();
277 break;
278 }
279 break;
280 case ALG_CFBA:
281 switch(mode) {
282 case MODE_AUTHENTICATE: /* authenticate using CFBA mode */
283 errx(1, "can't authenticate with CFBA mode");
284 break;
285 case MODE_DECRYPT: /* decrypt using CFBA mode */
286 cfbadec();
287 break;
288 case MODE_ENCRYPT: /* encrypt using CFBA mode */
289 cfbaenc();
290 break;
291 }
292 break;
293 case ALG_ECB:
294 switch(mode) {
295 case MODE_AUTHENTICATE: /* authenticate using ECB mode */
296 errx(1, "can't authenticate with ECB mode");
297 break;
298 case MODE_DECRYPT: /* decrypt using ECB mode */
299 ecbdec();
300 break;
301 case MODE_ENCRYPT: /* encrypt using ECB mode */
302 ecbenc();
303 break;
304 }
305 break;
306 case ALG_OFB:
307 switch(mode) {
308 case MODE_AUTHENTICATE: /* authenticate using OFB mode */
309 errx(1, "can't authenticate with OFB mode");
310 break;
311 case MODE_DECRYPT: /* decrypt using OFB mode */
312 ofbdec();
313 break;
314 case MODE_ENCRYPT: /* encrypt using OFB mode */
315 ofbenc();
316 break;
317 }
318 break;
319 }
320 return (0);
321 }
322
323 /*
324 * map a hex character to an integer
325 */
326 static int
tobinhex(char c,int radix)327 tobinhex(char c, int radix)
328 {
329 switch(c) {
330 case '0': return(0x0);
331 case '1': return(0x1);
332 case '2': return(radix > 2 ? 0x2 : -1);
333 case '3': return(radix > 3 ? 0x3 : -1);
334 case '4': return(radix > 4 ? 0x4 : -1);
335 case '5': return(radix > 5 ? 0x5 : -1);
336 case '6': return(radix > 6 ? 0x6 : -1);
337 case '7': return(radix > 7 ? 0x7 : -1);
338 case '8': return(radix > 8 ? 0x8 : -1);
339 case '9': return(radix > 9 ? 0x9 : -1);
340 case 'A': case 'a': return(radix > 10 ? 0xa : -1);
341 case 'B': case 'b': return(radix > 11 ? 0xb : -1);
342 case 'C': case 'c': return(radix > 12 ? 0xc : -1);
343 case 'D': case 'd': return(radix > 13 ? 0xd : -1);
344 case 'E': case 'e': return(radix > 14 ? 0xe : -1);
345 case 'F': case 'f': return(radix > 15 ? 0xf : -1);
346 }
347 /*
348 * invalid character
349 */
350 return(-1);
351 }
352
353 /*
354 * convert the key to a bit pattern
355 */
356 static void
cvtkey(DES_cblock obuf,char * ibuf)357 cvtkey(DES_cblock obuf, char *ibuf)
358 {
359 int i, j; /* counter in a for loop */
360 int nbuf[64]; /* used for hex/key translation */
361
362 /*
363 * just switch on the key base
364 */
365 switch(keybase) {
366 case KEY_ASCII: /* ascii to integer */
367 (void)strncpy(obuf, ibuf, 8);
368 return;
369 case KEY_DEFAULT: /* tell from context */
370 /*
371 * leading '0x' or '0X' == hex key
372 */
373 if (ibuf[0] == '0' && (ibuf[1] == 'x' || ibuf[1] == 'X')) {
374 ibuf = &ibuf[2];
375 /*
376 * now translate it, bombing on any illegal hex digit
377 */
378 for (i = 0; ibuf[i] && i < 16; i++)
379 if ((nbuf[i] = tobinhex(ibuf[i], 16)) == -1)
380 warnx("bad hex digit in key");
381 while (i < 16)
382 nbuf[i++] = 0;
383 for (i = 0; i < 8; i++)
384 obuf[i] =
385 ((nbuf[2*i]&0xf)<<4) | (nbuf[2*i+1]&0xf);
386 /* preserve parity bits */
387 pflag = 1;
388 return;
389 }
390 /*
391 * leading '0b' or '0B' == binary key
392 */
393 if (ibuf[0] == '0' && (ibuf[1] == 'b' || ibuf[1] == 'B')) {
394 ibuf = &ibuf[2];
395 /*
396 * now translate it, bombing on any illegal binary digit
397 */
398 for (i = 0; ibuf[i] && i < 16; i++)
399 if ((nbuf[i] = tobinhex(ibuf[i], 2)) == -1)
400 warnx("bad binary digit in key");
401 while (i < 64)
402 nbuf[i++] = 0;
403 for (i = 0; i < 8; i++)
404 for (j = 0; j < 8; j++)
405 obuf[i] = (obuf[i]<<1)|nbuf[8*i+j];
406 /* preserve parity bits */
407 pflag = 1;
408 return;
409 }
410 /*
411 * no special leader -- ASCII
412 */
413 (void)strncpy(obuf, ibuf, 8);
414 }
415 }
416
417 /*
418 * convert an ASCII string into a decimal number:
419 * 1. must be between 0 and 64 inclusive
420 * 2. must be a valid decimal number
421 * 3. must be a multiple of mult
422 */
423 static int
setbits(char * s,int mult)424 setbits(char *s, int mult)
425 {
426 char *p; /* pointer in a for loop */
427 int n = 0; /* the integer collected */
428
429 /*
430 * skip white space
431 */
432 while (isspace(*s))
433 s++;
434 /*
435 * get the integer
436 */
437 for (p = s; *p; p++) {
438 if (isdigit(*p))
439 n = n * 10 + *p - '0';
440 else {
441 warnx("bad decimal digit in MAC length");
442 }
443 }
444 /*
445 * be sure it's a multiple of mult
446 */
447 return((n % mult != 0) ? -1 : n);
448 }
449
450 /*****************
451 * DES FUNCTIONS *
452 *****************/
453 /*
454 * This sets the DES key and (if you're using the deszip version)
455 * the direction of the transformation. This uses the Sun
456 * to map the 64-bit key onto the 56 bits that the key schedule
457 * generation routines use: the old way, which just uses the user-
458 * supplied 64 bits as is, and the new way, which resets the parity
459 * bit to be the same as the low-order bit in each character. The
460 * new way generates a greater variety of key schedules, since many
461 * systems set the parity (high) bit of each character to 0, and the
462 * DES ignores the low order bit of each character.
463 */
464 static void
makekey(DES_cblock * buf)465 makekey(DES_cblock *buf)
466 {
467 int i, j; /* counter in a for loop */
468 int par; /* parity counter */
469
470 /*
471 * if the parity is not preserved, flip it
472 */
473 if (!pflag) {
474 for (i = 0; i < 8; i++) {
475 par = 0;
476 for (j = 1; j < 8; j++)
477 if ((bits[j] & (*buf)[i]) != 0)
478 par++;
479 if ((par & 0x01) == 0x01)
480 (*buf)[i] &= 0x7f;
481 else
482 (*buf)[i] = ((*buf)[i] & 0x7f) | 0x80;
483 }
484 }
485
486 DES_set_odd_parity(buf);
487 DES_set_key(buf, &schedule);
488 }
489
490 /*
491 * This encrypts using the Electronic Code Book mode of DES
492 */
493 static void
ecbenc(void)494 ecbenc(void)
495 {
496 int n; /* number of bytes actually read */
497 int bn; /* block number */
498 DES_cblock msgbuf; /* I/O buffer */
499
500 for (bn = 0; (n = READ(msgbuf, 8)) == 8; bn++) {
501 /*
502 * do the transformation
503 */
504 DES_XFORM(&msgbuf);
505 WRITE(&msgbuf, 8);
506 }
507 /*
508 * at EOF or last block -- in either case, the last byte contains
509 * the character representation of the number of bytes in it
510 */
511 bn++;
512 MEMZERO(&msgbuf[n], 8 - n);
513 msgbuf[7] = n;
514 DES_XFORM(&msgbuf);
515 WRITE(&msgbuf, 8);
516
517 }
518
519 /*
520 * This decrypts using the Electronic Code Book mode of DES
521 */
522 static void
ecbdec(void)523 ecbdec(void)
524 {
525 int n; /* number of bytes actually read */
526 int c; /* used to test for EOF */
527 int bn; /* block number */
528 DES_cblock msgbuf; /* I/O buffer */
529
530 for (bn = 1; (n = READ(msgbuf, 8)) == 8; bn++) {
531 /*
532 * do the transformation
533 */
534 DES_XFORM(&msgbuf);
535 /*
536 * if the last one, handle it specially
537 */
538 if ((c = getchar()) == EOF) {
539 n = msgbuf[7];
540 if (n < 0 || n > 7)
541 warnx("decryption failed (block corrupt) at %d",
542 bn);
543 }
544 else
545 (void)ungetc(c, stdin);
546 WRITE(msgbuf, n);
547 }
548 if (n > 0)
549 warnx("decryption failed (incomplete block) at %d", bn);
550 }
551
552 /*
553 * This encrypts using the Cipher Block Chaining mode of DES
554 */
555 static void
cbcenc(void)556 cbcenc(void)
557 {
558 int n; /* number of bytes actually read */
559 int bn; /* block number */
560 DES_cblock msgbuf; /* I/O buffer */
561
562 /*
563 * do the transformation
564 */
565 for (bn = 1; (n = READ(msgbuf, 8)) == 8; bn++) {
566 for (n = 0; n < 8; n++)
567 msgbuf[n] ^= ivec[n];
568 DES_XFORM(&msgbuf);
569 MEMCPY(ivec, msgbuf, 8);
570 WRITE(msgbuf, 8);
571 }
572 /*
573 * at EOF or last block -- in either case, the last byte contains
574 * the character representation of the number of bytes in it
575 */
576 bn++;
577 MEMZERO(&msgbuf[n], 8 - n);
578 msgbuf[7] = n;
579 for (n = 0; n < 8; n++)
580 msgbuf[n] ^= ivec[n];
581 DES_XFORM(&msgbuf);
582 WRITE(msgbuf, 8);
583
584 }
585
586 /*
587 * This decrypts using the Cipher Block Chaining mode of DES
588 */
589 static void
cbcdec(void)590 cbcdec(void)
591 {
592 int n; /* number of bytes actually read */
593 DES_cblock msgbuf; /* I/O buffer */
594 DES_cblock ibuf; /* temp buffer for initialization vector */
595 int c; /* used to test for EOF */
596 int bn; /* block number */
597
598 for (bn = 0; (n = READ(msgbuf, 8)) == 8; bn++) {
599 /*
600 * do the transformation
601 */
602 MEMCPY(ibuf, msgbuf, 8);
603 DES_XFORM(&msgbuf);
604 for (c = 0; c < 8; c++)
605 msgbuf[c] ^= ivec[c];
606 MEMCPY(ivec, ibuf, 8);
607 /*
608 * if the last one, handle it specially
609 */
610 if ((c = getchar()) == EOF) {
611 n = msgbuf[7];
612 if (n < 0 || n > 7)
613 warnx("decryption failed (block corrupt) at %d",
614 bn);
615 }
616 else
617 (void)ungetc(c, stdin);
618 WRITE(msgbuf, n);
619 }
620 if (n > 0)
621 warnx("decryption failed (incomplete block) at %d", bn);
622 }
623
624 /*
625 * This authenticates using the Cipher Block Chaining mode of DES
626 */
627 static void
cbcauth(void)628 cbcauth(void)
629 {
630 int n, j; /* number of bytes actually read */
631 DES_cblock msgbuf; /* I/O buffer */
632 DES_cblock encbuf; /* encryption buffer */
633
634 /*
635 * do the transformation
636 * note we DISCARD the encrypted block;
637 * we only care about the last one
638 */
639 while ((n = READ(msgbuf, 8)) == 8) {
640 for (n = 0; n < 8; n++)
641 encbuf[n] = msgbuf[n] ^ ivec[n];
642 DES_XFORM(&encbuf);
643 MEMCPY(ivec, encbuf, 8);
644 }
645 /*
646 * now compute the last one, right padding with '\0' if need be
647 */
648 if (n > 0) {
649 MEMZERO(&msgbuf[n], 8 - n);
650 for (n = 0; n < 8; n++)
651 encbuf[n] = msgbuf[n] ^ ivec[n];
652 DES_XFORM(&encbuf);
653 }
654 /*
655 * drop the bits
656 * we write chars until fewer than 7 bits,
657 * and then pad the last one with 0 bits
658 */
659 for (n = 0; macbits > 7; n++, macbits -= 8)
660 (void)putchar(encbuf[n]);
661 if (macbits > 0) {
662 msgbuf[0] = 0x00;
663 for (j = 0; j < macbits; j++)
664 msgbuf[0] |= encbuf[n] & bits[j];
665 (void)putchar(msgbuf[0]);
666 }
667 }
668
669 /*
670 * This encrypts using the Cipher FeedBack mode of DES
671 */
672 static void
cfbenc(void)673 cfbenc(void)
674 {
675 int n; /* number of bytes actually read */
676 int nbytes; /* number of bytes to read */
677 int bn; /* block number */
678 char ibuf[8]; /* input buffer */
679 DES_cblock msgbuf; /* encryption buffer */
680
681 /*
682 * do things in bytes, not bits
683 */
684 nbytes = fbbits / 8;
685 /*
686 * do the transformation
687 */
688 for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) {
689 MEMCPY(msgbuf, ivec, 8);
690 DES_XFORM(&msgbuf);
691 for (n = 0; n < 8 - nbytes; n++)
692 ivec[n] = ivec[n+nbytes];
693 for (n = 0; n < nbytes; n++)
694 ivec[8 - nbytes + n] = ibuf[n] ^ msgbuf[n];
695 WRITE(&ivec[8 - nbytes], nbytes);
696 }
697 /*
698 * at EOF or last block -- in either case, the last byte contains
699 * the character representation of the number of bytes in it
700 */
701 bn++;
702 MEMZERO(&ibuf[n], nbytes - n);
703 ibuf[nbytes - 1] = n;
704 MEMCPY(msgbuf, ivec, 8);
705 DES_XFORM(&msgbuf);
706 for (n = 0; n < nbytes; n++)
707 ibuf[n] ^= msgbuf[n];
708 WRITE(ibuf, nbytes);
709 }
710
711 /*
712 * This decrypts using the Cipher Block Chaining mode of DES
713 */
714 static void
cfbdec(void)715 cfbdec(void)
716 {
717 int n; /* number of bytes actually read */
718 int c; /* used to test for EOF */
719 int nbytes; /* number of bytes to read */
720 int bn; /* block number */
721 char ibuf[8]; /* input buffer */
722 char obuf[8]; /* output buffer */
723 DES_cblock msgbuf; /* encryption buffer */
724
725 /*
726 * do things in bytes, not bits
727 */
728 nbytes = fbbits / 8;
729 /*
730 * do the transformation
731 */
732 for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) {
733 MEMCPY(msgbuf, ivec, 8);
734 DES_XFORM(&msgbuf);
735 for (c = 0; c < 8 - nbytes; c++)
736 ivec[c] = ivec[c + nbytes];
737 for (c = 0; c < nbytes; c++) {
738 ivec[8 - nbytes + c] = ibuf[c];
739 obuf[c] = ibuf[c] ^ msgbuf[c];
740 }
741 /*
742 * if the last one, handle it specially
743 */
744 if ((c = getchar()) == EOF) {
745 n = obuf[nbytes-1];
746 if (n < 0 || n > nbytes-1)
747 warnx("decryption failed (block corrupt) at %d",
748 bn);
749 }
750 else
751 (void)ungetc(c, stdin);
752 WRITE(obuf, n);
753 }
754 if (n > 0)
755 warnx("decryption failed (incomplete block) at %d", bn);
756 }
757
758 /*
759 * This encrypts using the alternative Cipher FeedBack mode of DES
760 */
761 static void
cfbaenc(void)762 cfbaenc(void)
763 {
764 int n; /* number of bytes actually read */
765 int nbytes; /* number of bytes to read */
766 int bn; /* block number */
767 char ibuf[8]; /* input buffer */
768 char obuf[8]; /* output buffer */
769 DES_cblock msgbuf; /* encryption buffer */
770
771 /*
772 * do things in bytes, not bits
773 */
774 nbytes = fbbits / 7;
775 /*
776 * do the transformation
777 */
778 for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) {
779 MEMCPY(msgbuf, ivec, 8);
780 DES_XFORM(&msgbuf);
781 for (n = 0; n < 8 - nbytes; n++)
782 ivec[n] = ivec[n + nbytes];
783 for (n = 0; n < nbytes; n++)
784 ivec[8 - nbytes + n] = (ibuf[n] ^ msgbuf[n]) | 0x80;
785 for (n = 0; n < nbytes; n++)
786 obuf[n] = ivec[8 - nbytes + n] & 0x7f;
787 WRITE(obuf, nbytes);
788 }
789 /*
790 * at EOF or last block -- in either case, the last byte contains
791 * the character representation of the number of bytes in it
792 */
793 bn++;
794 MEMZERO(&ibuf[n], nbytes - n);
795 ibuf[nbytes - 1] = ('0' + n)|0200;
796 MEMCPY(msgbuf, ivec, 8);
797 DES_XFORM(&msgbuf);
798 for (n = 0; n < nbytes; n++)
799 ibuf[n] ^= msgbuf[n];
800 WRITE(ibuf, nbytes);
801 }
802
803 /*
804 * This decrypts using the alternative Cipher Block Chaining mode of DES
805 */
806 static void
cfbadec(void)807 cfbadec(void)
808 {
809 int n; /* number of bytes actually read */
810 int c; /* used to test for EOF */
811 int nbytes; /* number of bytes to read */
812 int bn; /* block number */
813 char ibuf[8]; /* input buffer */
814 char obuf[8]; /* output buffer */
815 DES_cblock msgbuf; /* encryption buffer */
816
817 /*
818 * do things in bytes, not bits
819 */
820 nbytes = fbbits / 7;
821 /*
822 * do the transformation
823 */
824 for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) {
825 MEMCPY(msgbuf, ivec, 8);
826 DES_XFORM(&msgbuf);
827 for (c = 0; c < 8 - nbytes; c++)
828 ivec[c] = ivec[c + nbytes];
829 for (c = 0; c < nbytes; c++) {
830 ivec[8 - nbytes + c] = ibuf[c] | 0x80;
831 obuf[c] = (ibuf[c] ^ msgbuf[c]) & 0x7f;
832 }
833 /*
834 * if the last one, handle it specially
835 */
836 if ((c = getchar()) == EOF) {
837 if ((n = (obuf[nbytes-1] - '0')) < 0
838 || n > nbytes-1)
839 warnx("decryption failed (block corrupt) at %d",
840 bn);
841 }
842 else
843 (void)ungetc(c, stdin);
844 WRITE(obuf, n);
845 }
846 if (n > 0)
847 warnx("decryption failed (incomplete block) at %d", bn);
848 }
849
850
851 /*
852 * This encrypts using the Output FeedBack mode of DES
853 */
854 static void
ofbenc(void)855 ofbenc(void)
856 {
857 int n; /* number of bytes actually read */
858 int c; /* used to test for EOF */
859 int nbytes; /* number of bytes to read */
860 int bn; /* block number */
861 char ibuf[8]; /* input buffer */
862 char obuf[8]; /* output buffer */
863 DES_cblock msgbuf; /* encryption buffer */
864
865 /*
866 * do things in bytes, not bits
867 */
868 nbytes = fbbits / 8;
869 /*
870 * do the transformation
871 */
872 for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) {
873 MEMCPY(msgbuf, ivec, 8);
874 DES_XFORM(&msgbuf);
875 for (n = 0; n < 8 - nbytes; n++)
876 ivec[n] = ivec[n + nbytes];
877 for (n = 0; n < nbytes; n++) {
878 ivec[8 - nbytes + n] = msgbuf[n];
879 obuf[n] = ibuf[n] ^ msgbuf[n];
880 }
881 WRITE(obuf, nbytes);
882 }
883 /*
884 * at EOF or last block -- in either case, the last byte contains
885 * the character representation of the number of bytes in it
886 */
887 bn++;
888 MEMZERO(&ibuf[n], nbytes - n);
889 ibuf[nbytes - 1] = n;
890 MEMCPY(msgbuf, ivec, 8);
891 DES_XFORM(&msgbuf);
892 for (c = 0; c < nbytes; c++)
893 ibuf[c] ^= msgbuf[c];
894 WRITE(ibuf, nbytes);
895 }
896
897 /*
898 * This decrypts using the Output Block Chaining mode of DES
899 */
900 static void
ofbdec(void)901 ofbdec(void)
902 {
903 int n; /* number of bytes actually read */
904 int c; /* used to test for EOF */
905 int nbytes; /* number of bytes to read */
906 int bn; /* block number */
907 char ibuf[8]; /* input buffer */
908 char obuf[8]; /* output buffer */
909 DES_cblock msgbuf; /* encryption buffer */
910
911 /*
912 * do things in bytes, not bits
913 */
914 nbytes = fbbits / 8;
915 /*
916 * do the transformation
917 */
918 for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) {
919 MEMCPY(msgbuf, ivec, 8);
920 DES_XFORM(&msgbuf);
921 for (c = 0; c < 8 - nbytes; c++)
922 ivec[c] = ivec[c + nbytes];
923 for (c = 0; c < nbytes; c++) {
924 ivec[8 - nbytes + c] = msgbuf[c];
925 obuf[c] = ibuf[c] ^ msgbuf[c];
926 }
927 /*
928 * if the last one, handle it specially
929 */
930 if ((c = getchar()) == EOF) {
931 n = obuf[nbytes-1];
932 if (n < 0 || n > nbytes-1)
933 warnx("decryption failed (block corrupt) at %d",
934 bn);
935 }
936 else
937 (void)ungetc(c, stdin);
938 /*
939 * dump it
940 */
941 WRITE(obuf, n);
942 }
943 if (n > 0)
944 warnx("decryption failed (incomplete block) at %d", bn);
945 }
946
947 /*
948 * This authenticates using the Cipher FeedBack mode of DES
949 */
950 static void
cfbauth(void)951 cfbauth(void)
952 {
953 int n, j; /* number of bytes actually read */
954 int nbytes; /* number of bytes to read */
955 char ibuf[8]; /* input buffer */
956 DES_cblock msgbuf; /* encryption buffer */
957
958 /*
959 * do things in bytes, not bits
960 */
961 nbytes = fbbits / 8;
962 /*
963 * do the transformation
964 */
965 while ((n = READ(ibuf, nbytes)) == nbytes) {
966 MEMCPY(msgbuf, ivec, 8);
967 DES_XFORM(&msgbuf);
968 for (n = 0; n < 8 - nbytes; n++)
969 ivec[n] = ivec[n + nbytes];
970 for (n = 0; n < nbytes; n++)
971 ivec[8 - nbytes + n] = ibuf[n] ^ msgbuf[n];
972 }
973 /*
974 * at EOF or last block -- in either case, the last byte contains
975 * the character representation of the number of bytes in it
976 */
977 MEMZERO(&ibuf[n], nbytes - n);
978 ibuf[nbytes - 1] = '0' + n;
979 MEMCPY(msgbuf, ivec, 8);
980 DES_XFORM(&msgbuf);
981 for (n = 0; n < nbytes; n++)
982 ibuf[n] ^= msgbuf[n];
983 /*
984 * drop the bits
985 * we write chars until fewer than 7 bits,
986 * and then pad the last one with 0 bits
987 */
988 for (n = 0; macbits > 7; n++, macbits -= 8)
989 (void)putchar(msgbuf[n]);
990 if (macbits > 0) {
991 msgbuf[0] = 0x00;
992 for (j = 0; j < macbits; j++)
993 msgbuf[0] |= msgbuf[n] & bits[j];
994 (void)putchar(msgbuf[0]);
995 }
996 }
997
998 /*
999 * message about usage
1000 */
1001 static void
usage(void)1002 usage(void)
1003 {
1004 (void)fprintf(stderr, "%s\n",
1005 "usage: bdes [-abdp] [-F N] [-f N] [-k key] [-m N] [-o N] [-v vector]");
1006 exit(1);
1007 }
1008