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