home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.bin / bdes / bdes.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-27  |  27.0 KB  |  1,047 lines

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