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