home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 1 / ARM_CLUB_CD.iso / contents / apps / clib / progs / utilslib / c / Fcrypt < prev    next >
Encoding:
Text File  |  1991-10-20  |  24.9 KB  |  761 lines

  1. /*
  2.  * This program is copyright (c) Alec Muffett 1991 except for certain
  3.  * portions of code ("crack-fcrypt.c") copyright (c) Robert Baldwin, Icarus
  4.  * Sparry and Alec Muffett.  The author(s) disclaims all responsibility or
  5.  * liability with respect to it's usage or its effect upon hardware or
  6.  * computer systems.  This software is in freely redistributable PROVIDED
  7.  * that this notice remains intact.
  8.  */
  9.  
  10. #include <string.h>
  11. #include "fcrypt.h"
  12.  
  13. /*
  14.  * Configuration options
  15.  */
  16.  
  17. /* The ARM is little-endian */
  18. #undef    BIG_ENDIAN
  19. #define    LITTLE_ENDIAN
  20.  
  21. /* memset() is optimised for high performance */
  22. #undef    BUILTIN_CLEAR
  23. #undef    BZERO
  24. #define    MEMSET
  25.  
  26. /* Optimisations for other machines, which don't help the ARM */
  27. #undef    FDES_4BYTE
  28. #undef    FDES_8BYTE
  29. #undef    BRAINDEAD6
  30.  
  31. /*
  32.  * Misc defs for the fast password transform optimisations.
  33.  */
  34.  
  35. /*
  36.  * Rename the types for greater convenience ? - This is from original code.
  37.  */
  38. #define        reg     register
  39. #define        uns     unsigned
  40. #define        unsb    uns char
  41. #define        unsl    uns long
  42.  
  43. /*
  44.  * Types for the different ways to represent DES bit patterns.  Bits are
  45.  * always right justified within fields.  Bits which have lower indices in
  46.  * the NBS spec are stored in the vax bits with less significance (e.g., Bit
  47.  * 1 of NBS spec is stored in the bit with weight 2 ** 0 to the Vax.
  48.  */
  49.  
  50. #define        obpb1   unsb            /* One bit per byte. */
  51. #define        sbpb6   unsb            /* Six bits per byte, 6 held. */
  52. #define        sbpb6R  unsb            /* Six bits per byte Reversed order, 6 held. */
  53. #define        sbpb24  unsl            /* Six bits per byte, 24 held. */
  54. #define        ebpb24  unsl            /* Eight bits per bit, 24 held. */
  55. #define        fbpb4   unsb            /* Four bits per byte, 4 held. */
  56. #define        fbpb4R  unsb            /* Four bits per byte Reversed order, 4 held. */
  57.  
  58. /*
  59.  * The operation (6 * x) is often better optimised as this (for really
  60.  * braindead compilers) - AEM
  61.  */
  62.  
  63. #ifdef BRAINDEAD6
  64. #define SIX_TIMES(exprn)               (((exprn) << 2) + ((exprn) << 1))
  65. #else
  66. #define SIX_TIMES(exprn)               (6 * (exprn))
  67. #endif                         /* BRAINDEAD6 */
  68.  
  69. /*
  70.  * Data segment gathered into one place - AEM
  71.  */
  72.  
  73. /* Try to keep this stuff long aligned - AEM */
  74. static char iobuf[16];
  75.  
  76. static obpb1 crypt_block[72];  /* 72 is next multiple of 8 bytes after 66 */
  77. static sbpb24 KS[32];
  78. static sbpb24 S0H[64], S1H[64], S2H[64], S3H[64];
  79. static sbpb24 S4H[64], S5H[64], S6H[64], S7H[64];
  80. static sbpb24 S0L[64], S1L[64], S2L[64], S3L[64];
  81. static sbpb24 S4L[64], S5L[64], S6L[64], S7L[64];
  82. static sbpb24 out96[4];
  83.  
  84. /*
  85.  * These used to be rather slow and frequently used functions - AEM
  86.  */
  87.  
  88. #define TF_TO_SIXBIT(tf) \
  89.        (sbpb24)((tf & 077L) | \
  90.                ((tf & 07700L) << 2) | \
  91.                ((tf & 0770000L) << 4) | \
  92.                ((tf & 077000000L) << 6))
  93.  
  94. #define SIXBIT_TO_TF(sb) \
  95.        (ebpb24)((sb & 0x3fL) | \
  96.                ((sb & 0x3f00L) >> 2) | \
  97.                ((sb & 0x3f0000L) >> 4) | \
  98.                ((sb & 0x3f000000L) >> 6))
  99. /*
  100.  * Start of the real thing
  101.  */
  102.  
  103. static void fsetkey (void)
  104. {
  105.     /*
  106.      * This used to be utterly horrendous. It still is, but it's much, much,
  107.      * smaller... AEM.
  108.      */
  109.     static unsb KeyToKS[] =
  110.     {
  111.        9, 50, 33, 59, 48, 16, 32, 56, 1, 8, 18, 41, 2, 34, 25, 24,
  112.        43, 57, 58, 0, 35, 26, 17, 40, 21, 27, 38, 53, 36, 3, 46, 29,
  113.        4, 52, 22, 28, 60, 20, 37, 62, 14, 19, 44, 13, 12, 61, 54, 30,
  114.        1, 42, 25, 51, 40, 8, 24, 48, 58, 0, 10, 33, 59, 26, 17, 16,
  115.        35, 49, 50, 57, 56, 18, 9, 32, 13, 19, 30, 45, 28, 62, 38, 21,
  116.        27, 44, 14, 20, 52, 12, 29, 54, 6, 11, 36, 5, 4, 53, 46, 22,
  117.        50, 26, 9, 35, 24, 57, 8, 32, 42, 49, 59, 17, 43, 10, 1, 0,
  118.        48, 33, 34, 41, 40, 2, 58, 16, 60, 3, 14, 29, 12, 46, 22, 5,
  119.        11, 28, 61, 4, 36, 27, 13, 38, 53, 62, 20, 52, 19, 37, 30, 6,
  120.        34, 10, 58, 48, 8, 41, 57, 16, 26, 33, 43, 1, 56, 59, 50, 49,
  121.        32, 17, 18, 25, 24, 51, 42, 0, 44, 54, 61, 13, 27, 30, 6, 52,
  122.        62, 12, 45, 19, 20, 11, 60, 22, 37, 46, 4, 36, 3, 21, 14, 53,
  123.        18, 59, 42, 32, 57, 25, 41, 0, 10, 17, 56, 50, 40, 43, 34, 33,
  124.        16, 1, 2, 9, 8, 35, 26, 49, 28, 38, 45, 60, 11, 14, 53, 36,
  125.        46, 27, 29, 3, 4, 62, 44, 6, 21, 30, 19, 20, 54, 5, 61, 37,
  126.        2, 43, 26, 16, 41, 9, 25, 49, 59, 1, 40, 34, 24, 56, 18, 17,
  127.        0, 50, 51, 58, 57, 48, 10, 33, 12, 22, 29, 44, 62, 61, 37, 20,
  128.        30, 11, 13, 54, 19, 46, 28, 53, 5, 14, 3, 4, 38, 52, 45, 21,
  129.        51, 56, 10, 0, 25, 58, 9, 33, 43, 50, 24, 18, 8, 40, 2, 1,
  130.        49, 34, 35, 42, 41, 32, 59, 17, 27, 6, 13, 28, 46, 45, 21, 4,
  131.        14, 62, 60, 38, 3, 30, 12, 37, 52, 61, 54, 19, 22, 36, 29, 5,
  132.        35, 40, 59, 49, 9, 42, 58, 17, 56, 34, 8, 2, 57, 24, 51, 50,
  133.        33, 18, 48, 26, 25, 16, 43, 1, 11, 53, 60, 12, 30, 29, 5, 19,
  134.        61, 46, 44, 22, 54, 14, 27, 21, 36, 45, 38, 3, 6, 20, 13, 52,
  135.        56, 32, 51, 41, 1, 34, 50, 9, 48, 26, 0, 59, 49, 16, 43, 42,
  136.        25, 10, 40, 18, 17, 8, 35, 58, 3, 45, 52, 4, 22, 21, 60, 11,
  137.        53, 38, 36, 14, 46, 6, 19, 13, 28, 37, 30, 62, 61, 12, 5, 44,
  138.        40, 16, 35, 25, 50, 18, 34, 58, 32, 10, 49, 43, 33, 0, 56, 26,
  139.        9, 59, 24, 2, 1, 57, 48, 42, 54, 29, 36, 19, 6, 5, 44, 62,
  140.        37, 22, 20, 61, 30, 53, 3, 60, 12, 21, 14, 46, 45, 27, 52, 28,
  141.        24, 0, 48, 9, 34, 2, 18, 42, 16, 59, 33, 56, 17, 49, 40, 10,
  142.        58, 43, 8, 51, 50, 41, 32, 26, 38, 13, 20, 3, 53, 52, 28, 46,
  143.        21, 6, 4, 45, 14, 37, 54, 44, 27, 5, 61, 30, 29, 11, 36, 12,
  144.        8, 49, 32, 58, 18, 51, 2, 26, 0, 43, 17, 40, 1, 33, 24, 59,
  145.        42, 56, 57, 35, 34, 25, 16, 10, 22, 60, 4, 54, 37, 36, 12, 30,
  146.        5, 53, 19, 29, 61, 21, 38, 28, 11, 52, 45, 14, 13, 62, 20, 27,
  147.        57, 33, 16, 42, 2, 35, 51, 10, 49, 56, 1, 24, 50, 17, 8, 43,
  148.        26, 40, 41, 48, 18, 9, 0, 59, 6, 44, 19, 38, 21, 20, 27, 14,
  149.        52, 37, 3, 13, 45, 5, 22, 12, 62, 36, 29, 61, 60, 46, 4, 11,
  150.        41, 17, 0, 26, 51, 48, 35, 59, 33, 40, 50, 8, 34, 1, 57, 56,
  151.        10, 24, 25, 32, 2, 58, 49, 43, 53, 28, 3, 22, 5, 4, 11, 61,
  152.        36, 21, 54, 60, 29, 52, 6, 27, 46, 20, 13, 45, 44, 30, 19, 62,
  153.        25, 1, 49, 10, 35, 32, 48, 43, 17, 24, 34, 57, 18, 50, 41, 40,
  154.        59, 8, 9, 16, 51, 42, 33, 56, 37, 12, 54, 6, 52, 19, 62, 45,
  155.        20, 5, 38, 44, 13, 36, 53, 11, 30, 4, 60, 29, 28, 14, 3, 46,
  156.        17, 58, 41, 2, 56, 24, 40, 35, 9, 16, 26, 49, 10, 42, 33, 32,
  157.        51, 0, 1, 8, 43, 34, 25, 48, 29, 4, 46, 61, 44, 11, 54, 37,
  158.        12, 60, 30, 36, 5, 28, 45, 3, 22, 27, 52, 21, 20, 6, 62, 38
  159.     };
  160.  
  161.     reg int i;
  162.     reg int j;
  163.     reg int r;
  164.     reg unsb *k;
  165.  
  166.     k = KeyToKS;
  167.  
  168.     for (i = 0; i < 32; i++)   /* loops cache better ? - AEM */
  169.     {
  170.        r = 0;
  171.        for (j = 0; j < 24; j++)
  172.        {
  173.            r |= crypt_block[*(k++)] << j;
  174.        }
  175.        KS[i] = TF_TO_SIXBIT (r);
  176.     }
  177. }
  178.  
  179. static void XForm (sbpb24 saltvalue)
  180. {
  181.     union
  182.     {
  183.        sbpb24 b[2];
  184.        sbpb6 c[8];
  185.     } sdata;
  186.  
  187.     /*
  188.      * Icarus Sparry, Bath - mod AEM
  189.      */
  190.  
  191. #ifdef BIG_ENDIAN
  192. #define STEP --
  193. #define START &sdata.c[7]
  194. #define Dl sdata.b[1]
  195. #define Dh sdata.b[0]
  196. #else                          /* LITTLE_ENDIAN */
  197. #define STEP ++
  198. #define START &sdata.c[0]
  199. #define Dl sdata.b[0]
  200. #define Dh sdata.b[1]
  201. #endif
  202.  
  203.     /*
  204.      * Thanks to Matt Bishop for this idea... AEM.
  205.      */
  206.  
  207. #ifndef FDES_4BYTE
  208. #define SIZEFIX                0
  209. #define INDIRECT(a,b)  (a)[b]
  210. #else
  211. #define SIZEFIX                2       /* "n" where 2^n == sizeof(sbpb24) */
  212. #define INDIRECT(a,b)  (*((sbpb24 *)(((unsigned char *) a) + (b))))
  213. #endif
  214.  
  215.     reg sbpb24 Rl;
  216.     reg sbpb24 Rh;
  217.     reg sbpb24 Ll;
  218.     reg sbpb24 Lh;
  219.     reg sbpb6 *dp;
  220.  
  221.     int loop;
  222.     reg sbpb24 k;
  223.     sbpb24 *kp;
  224.     sbpb24 *kend;
  225. #ifdef FDES_8BYTE
  226.     reg sbpb24 tmpi;
  227. #endif /* FDES_8BYTE */
  228.  
  229.     Ll = Lh = Rl = Rh = 0;
  230.  
  231.     kend = &KS[32];
  232.  
  233.     for (loop = 25; loop-- > 0; /* nothing */ )
  234.     {
  235.        for (kp = KS; kp < kend; /* nothing */ )
  236.        {
  237.            /*
  238.             * Oddly enough, direct addressing of dp slows things down, as
  239.             * well as knackering portability - AEM
  240.             */
  241.  
  242.            k = (Rl ^ Rh) & saltvalue;
  243. #ifndef FDES_8BYTE
  244.            Dl = (k ^ Rl ^ *kp++) << SIZEFIX;
  245.            Dh = (k ^ Rh ^ *kp++) << SIZEFIX;
  246. #else
  247.            /* hack to make things work better - matthew kaufman */
  248.            /* I haven't tried any of this - I don't have a cray... AEM */
  249.            tmpi = (k ^ Rl ^ *kp++);
  250.            sdata.c[3] = (tmpi >> 24) & 0x00ff;
  251.            sdata.c[2] = (tmpi >> 16) & 0x00ff;
  252.            sdata.c[1] = (tmpi >> 8) & 0x00ff;
  253.            sdata.c[0] = (tmpi) & 0x00ff;
  254.            tmpi = (k ^ Rh ^ *kp++);
  255.            sdata.c[7] = (tmpi >> 24) & 0x00ff;
  256.            sdata.c[6] = (tmpi >> 16) & 0x00ff;
  257.            sdata.c[5] = (tmpi >> 8) & 0x00ff;
  258.            sdata.c[4] = (tmpi) & 0x00ff;
  259. #endif /* FDES_8BYTE */
  260.  
  261.            dp = START;
  262.            Lh ^= INDIRECT (S0H, *dp);
  263.            Ll ^= INDIRECT (S0L, *dp STEP);
  264.            Lh ^= INDIRECT (S1H, *dp);
  265.            Ll ^= INDIRECT (S1L, *dp STEP);
  266.            Lh ^= INDIRECT (S2H, *dp);
  267.            Ll ^= INDIRECT (S2L, *dp STEP);
  268.            Lh ^= INDIRECT (S3H, *dp);
  269.            Ll ^= INDIRECT (S3L, *dp STEP);
  270.            Lh ^= INDIRECT (S4H, *dp);
  271.            Ll ^= INDIRECT (S4L, *dp STEP);
  272.            Lh ^= INDIRECT (S5H, *dp);
  273.            Ll ^= INDIRECT (S5L, *dp STEP);
  274.            Lh ^= INDIRECT (S6H, *dp);
  275.            Ll ^= INDIRECT (S6L, *dp STEP);
  276.            Lh ^= INDIRECT (S7H, *dp);
  277.            Ll ^= INDIRECT (S7L, *dp STEP);
  278.  
  279.            k = (Ll ^ Lh) & saltvalue;
  280. #ifndef FDES_8BYTE
  281.            Dl = (k ^ Ll ^ *kp++) << SIZEFIX;
  282.            Dh = (k ^ Lh ^ *kp++) << SIZEFIX;
  283. #else
  284.            tmpi = (k ^ Ll ^ *kp++);
  285.            sdata.c[3] = (tmpi >> 24) & 0x00ff;
  286.            sdata.c[2] = (tmpi >> 16) & 0x00ff;
  287.            sdata.c[1] = (tmpi >> 8) & 0x00ff;
  288.            sdata.c[0] = (tmpi) & 0x00ff;
  289.            tmpi = (k ^ Lh ^ *kp++);
  290.            sdata.c[7] = (tmpi >> 24) & 0x00ff;
  291.            sdata.c[6] = (tmpi >> 16) & 0x00ff;
  292.            sdata.c[5] = (tmpi >> 8) & 0x00ff;
  293.            sdata.c[4] = (tmpi) & 0x00ff;
  294. #endif /* FDES_8BYTE */
  295.  
  296.            dp = START;
  297.            Rh ^= INDIRECT (S0H, *dp);
  298.            Rl ^= INDIRECT (S0L, *dp STEP);
  299.            Rh ^= INDIRECT (S1H, *dp);
  300.            Rl ^= INDIRECT (S1L, *dp STEP);
  301.            Rh ^= INDIRECT (S2H, *dp);
  302.            Rl ^= INDIRECT (S2L, *dp STEP);
  303.            Rh ^= INDIRECT (S3H, *dp);
  304.            Rl ^= INDIRECT (S3L, *dp STEP);
  305.            Rh ^= INDIRECT (S4H, *dp);
  306.            Rl ^= INDIRECT (S4L, *dp STEP);
  307.            Rh ^= INDIRECT (S5H, *dp);
  308.            Rl ^= INDIRECT (S5L, *dp STEP);
  309.            Rh ^= INDIRECT (S6H, *dp);
  310.            Rl ^= INDIRECT (S6L, *dp STEP);
  311.            Rh ^= INDIRECT (S7H, *dp);
  312.            Rl ^= INDIRECT (S7L, *dp STEP);
  313.        }
  314.  
  315.        Ll ^= Rl;
  316.        Lh ^= Rh;
  317.        Rl ^= Ll;
  318.        Rh ^= Lh;
  319.        Ll ^= Rl;
  320.        Lh ^= Rh;
  321.     }
  322.  
  323.     /*
  324.      * for reasons that I cannot explain, if I insert the contents of the
  325.      * UnXForm function right HERE, making the tweaks as necessary to avoid
  326.      * using out96[] to pass data, I LOSE 30% of my speed.  I don't know why.
  327.      * Hence, I continue to use out96[]...
  328.      */
  329.     {
  330.        reg sbpb24 *qp;
  331.        qp = out96;
  332.        *qp++ = Ll;
  333.        *qp++ = Lh;
  334.        *qp++ = Rl;
  335.        *qp++ = Rh;
  336.     }
  337. }
  338.  
  339. static void UnXForm (void)
  340. {
  341.     reg obpb1 *ptr;
  342.     reg sbpb24 Rl;
  343.     reg sbpb24 Rh;
  344.     reg sbpb24 Ll;
  345.     reg sbpb24 Lh;
  346.  
  347.     Ll = SIXBIT_TO_TF (out96[0]);
  348.     Lh = SIXBIT_TO_TF (out96[1]);
  349.     Rl = SIXBIT_TO_TF (out96[2]);
  350.     Rh = SIXBIT_TO_TF (out96[3]);
  351.     ptr = crypt_block;
  352.  
  353.     *(ptr++) = Rl & 0x000400L ? 0x01 : 0;
  354.     *(ptr++) = Ll & 0x000400L ? 0x01 : 0;
  355.     *(ptr++) = Rl & 0x400000L ? 0x01 : 0;
  356.     *(ptr++) = Ll & 0x400000L ? 0x01 : 0;
  357.     *(ptr++) = Rh & 0x000400L ? 0x01 : 0;
  358.     *(ptr++) = Lh & 0x000400L ? 0x01 : 0;
  359.     *(ptr++) = Rh & 0x400000L ? 0x01 : 0;
  360.     *(ptr++) = Lh & 0x400000L ? 0x01 : 0;
  361.     *(ptr++) = Rl & 0x000200L ? 0x01 : 0;
  362.     *(ptr++) = Ll & 0x000200L ? 0x01 : 0;
  363.     *(ptr++) = Rl & 0x200000L ? 0x01 : 0;
  364.     *(ptr++) = Ll & 0x200000L ? 0x01 : 0;
  365.     *(ptr++) = Rh & 0x000200L ? 0x01 : 0;
  366.     *(ptr++) = Lh & 0x000200L ? 0x01 : 0;
  367.     *(ptr++) = Rh & 0x200000L ? 0x01 : 0;
  368.     *(ptr++) = Lh & 0x200000L ? 0x01 : 0;
  369.     *(ptr++) = Rl & 0x000100L ? 0x01 : 0;
  370.     *(ptr++) = Ll & 0x000100L ? 0x01 : 0;
  371.     *(ptr++) = Rl & 0x100000L ? 0x01 : 0;
  372.     *(ptr++) = Ll & 0x100000L ? 0x01 : 0;
  373.     *(ptr++) = Rh & 0x000100L ? 0x01 : 0;
  374.     *(ptr++) = Lh & 0x000100L ? 0x01 : 0;
  375.     *(ptr++) = Rh & 0x100000L ? 0x01 : 0;
  376.     *(ptr++) = Lh & 0x100000L ? 0x01 : 0;
  377.     *(ptr++) = Rl & 0x000080L ? 0x01 : 0;
  378.     *(ptr++) = Ll & 0x000080L ? 0x01 : 0;
  379.     *(ptr++) = Rl & 0x080000L ? 0x01 : 0;
  380.     *(ptr++) = Ll & 0x080000L ? 0x01 : 0;
  381.     *(ptr++) = Rh & 0x000080L ? 0x01 : 0;
  382.     *(ptr++) = Lh & 0x000080L ? 0x01 : 0;
  383.     *(ptr++) = Rh & 0x080000L ? 0x01 : 0;
  384.     *(ptr++) = Lh & 0x080000L ? 0x01 : 0;
  385.     *(ptr++) = Rl & 0x000010L ? 0x01 : 0;
  386.     *(ptr++) = Ll & 0x000010L ? 0x01 : 0;
  387.     *(ptr++) = Rl & 0x010000L ? 0x01 : 0;
  388.     *(ptr++) = Ll & 0x010000L ? 0x01 : 0;
  389.     *(ptr++) = Rh & 0x000010L ? 0x01 : 0;
  390.     *(ptr++) = Lh & 0x000010L ? 0x01 : 0;
  391.     *(ptr++) = Rh & 0x010000L ? 0x01 : 0;
  392.     *(ptr++) = Lh & 0x010000L ? 0x01 : 0;
  393.     *(ptr++) = Rl & 0x000008L ? 0x01 : 0;
  394.     *(ptr++) = Ll & 0x000008L ? 0x01 : 0;
  395.     *(ptr++) = Rl & 0x008000L ? 0x01 : 0;
  396.     *(ptr++) = Ll & 0x008000L ? 0x01 : 0;
  397.     *(ptr++) = Rh & 0x000008L ? 0x01 : 0;
  398.     *(ptr++) = Lh & 0x000008L ? 0x01 : 0;
  399.     *(ptr++) = Rh & 0x008000L ? 0x01 : 0;
  400.     *(ptr++) = Lh & 0x008000L ? 0x01 : 0;
  401.     *(ptr++) = Rl & 0x000004L ? 0x01 : 0;
  402.     *(ptr++) = Ll & 0x000004L ? 0x01 : 0;
  403.     *(ptr++) = Rl & 0x004000L ? 0x01 : 0;
  404.     *(ptr++) = Ll & 0x004000L ? 0x01 : 0;
  405.     *(ptr++) = Rh & 0x000004L ? 0x01 : 0;
  406.     *(ptr++) = Lh & 0x000004L ? 0x01 : 0;
  407.     *(ptr++) = Rh & 0x004000L ? 0x01 : 0;
  408.     *(ptr++) = Lh & 0x004000L ? 0x01 : 0;
  409.     *(ptr++) = Rl & 0x000002L ? 0x01 : 0;
  410.     *(ptr++) = Ll & 0x000002L ? 0x01 : 0;
  411.     *(ptr++) = Rl & 0x002000L ? 0x01 : 0;
  412.     *(ptr++) = Ll & 0x002000L ? 0x01 : 0;
  413.     *(ptr++) = Rh & 0x000002L ? 0x01 : 0;
  414.     *(ptr++) = Lh & 0x000002L ? 0x01 : 0;
  415.     *(ptr++) = Rh & 0x002000L ? 0x01 : 0;
  416.     *ptr = Lh & 0x002000L ? 0x01 : 0;
  417. }
  418.  
  419. char *fcrypt (char *pw, char *salt)
  420. {
  421.     /* Table lookups for salts reduce fcrypt() overhead dramatically */
  422.     static sbpb24 salt0[] =
  423.     {
  424.        18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
  425.        34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
  426.        50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 0, 1,
  427.        2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 5, 6, 7, 8, 9, 10,
  428.        11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
  429.        27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 32, 33, 34, 35, 36,
  430.        37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
  431.        53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 0, 1, 2, 3, 4,
  432.        5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
  433.        21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
  434.        37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
  435.        53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 0, 1, 2, 3, 4,
  436.        5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
  437.        21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
  438.        37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
  439.        53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 0, 1, 2, 3, 4
  440.     };
  441.     static sbpb24 salt1[] =
  442.     {
  443.        1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600,
  444.        1664, 1728, 1792, 1856, 1920, 1984, 2048, 2112,
  445.        2176, 2240, 2304, 2368, 2432, 2496, 2560, 2624,
  446.        2688, 2752, 2816, 2880, 2944, 3008, 3072, 3136,
  447.        3200, 3264, 3328, 3392, 3456, 3520, 3584, 3648,
  448.        3712, 3776, 3840, 3904, 3968, 4032, 0, 64,
  449.        128, 192, 256, 320, 384, 448, 512, 576,
  450.        640, 704, 320, 384, 448, 512, 576, 640,
  451.        704, 768, 832, 896, 960, 1024, 1088, 1152,
  452.        1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664,
  453.        1728, 1792, 1856, 1920, 1984, 2048, 2112, 2176,
  454.        2240, 2304, 2368, 2048, 2112, 2176, 2240, 2304,
  455.        2368, 2432, 2496, 2560, 2624, 2688, 2752, 2816,
  456.        2880, 2944, 3008, 3072, 3136, 3200, 3264, 3328,
  457.        3392, 3456, 3520, 3584, 3648, 3712, 3776, 3840,
  458.        3904, 3968, 4032, 0, 64, 128, 192, 256,
  459.        320, 384, 448, 512, 576, 640, 704, 768,
  460.        832, 896, 960, 1024, 1088, 1152, 1216, 1280,
  461.        1344, 1408, 1472, 1536, 1600, 1664, 1728, 1792,
  462.        1856, 1920, 1984, 2048, 2112, 2176, 2240, 2304,
  463.        2368, 2432, 2496, 2560, 2624, 2688, 2752, 2816,
  464.        2880, 2944, 3008, 3072, 3136, 3200, 3264, 3328,
  465.        3392, 3456, 3520, 3584, 3648, 3712, 3776, 3840,
  466.        3904, 3968, 4032, 0, 64, 128, 192, 256,
  467.        320, 384, 448, 512, 576, 640, 704, 768,
  468.        832, 896, 960, 1024, 1088, 1152, 1216, 1280,
  469.        1344, 1408, 1472, 1536, 1600, 1664, 1728, 1792,
  470.        1856, 1920, 1984, 2048, 2112, 2176, 2240, 2304,
  471.        2368, 2432, 2496, 2560, 2624, 2688, 2752, 2816,
  472.        2880, 2944, 3008, 3072, 3136, 3200, 3264, 3328,
  473.        3392, 3456, 3520, 3584, 3648, 3712, 3776, 3840,
  474.        3904, 3968, 4032, 0, 64, 128, 192, 256
  475.     };
  476.  
  477.     /* final perutation desalting */
  478.     static obpb1 final[] =
  479.     {
  480.        46, 47, 48, 49, 50, 51, 52, 53,
  481.        54, 55, 56, 57, 65, 66, 67, 68,
  482.        69, 70, 71, 72, 73, 74, 75, 76,
  483.        77, 78, 79, 80, 81, 82, 83, 84,
  484.        85, 86, 87, 88, 89, 90, 97, 98,
  485.        99, 100, 101, 102, 103, 104, 105, 106,
  486.        107, 108, 109, 110, 111, 112, 113, 114,
  487.        115, 116, 117, 118, 119, 120, 121, 122,
  488.        123, 124, 125, 126, 127, 128, 129, 130,
  489.        131, 132, 133, 134, 135, 136, 137, 138,
  490.        139, 140, 141, 142, 143, 144, 145, 146,
  491.        147, 148, 149, 150, 151, 152, 153, 154,
  492.        155, 156, 157, 158, 159, 160, 161, 162,
  493.        163, 164, 165, 166, 167, 168, 169, 170,
  494.        171, 172, 173, 174, 175, 176, 177, 178,
  495.        179, 180, 181, 182, 183, 184, 185, 186,
  496.        187, 188, 189, 190, 191, 192, 193, 194,
  497.        195, 196, 197, 198, 199, 200, 201, 202,
  498.        203, 204, 205, 206, 207, 208, 209, 210,
  499.        211, 212, 213, 214, 215, 216, 217, 218,
  500.        219, 220, 221, 222, 223, 224, 225, 226,
  501.        227, 228, 229, 230, 231, 232, 233, 234,
  502.        235, 236, 237, 238, 239, 240, 241, 242,
  503.        243, 244, 245, 246, 247, 248, 249, 250,
  504.        251, 252, 253, 254, 255,
  505.     /* Truncate overflow bits at 256 */
  506.        0, 1, 2, 3, 4, 5, 6, 7,
  507.        8, 9, 10, 11, 12, 13, 14, 15,
  508.        16, 17, 18, 19, 20, 21, 22, 23,
  509.        24, 25, 26, 27, 28, 29, 30, 31,
  510.        32, 33, 34, 35, 36, 37, 38, 39,
  511.        40, 41, 42, 43, 44, 45, 46, 47,
  512.        48, 49, 50, 51, 52, 53, 54, 55,
  513.        56, 57, 58
  514.     };
  515.  
  516.     reg int i, j, k;
  517.     sbpb24 saltvalue;
  518.  
  519. #ifdef BUILTIN_CLEAR
  520.     reg long int *lip;
  521.  
  522.     lip = (long int *) crypt_block;
  523.     for (i = (sizeof (crypt_block) / sizeof (long int)); i > 0; i--)
  524.     {
  525.        *(lip++) = 0L;
  526.     }
  527. #else                          /* BUILTIN_CLEAR */
  528. #ifdef BZERO
  529.     bzero (crypt_block, 66);
  530. #else                          /* BZERO */
  531. #ifdef MEMSET
  532.     memset (crypt_block, 0, 66);
  533. #else                          /* MEMSET */
  534.     for (i = 0; i < 66; i++)
  535.     {
  536.        crypt_block[i] = '\0';
  537.     }
  538. #endif                         /* MEMSET */
  539. #endif                         /* BZERO */
  540. #endif                         /* BUILTIN_CLEAR */
  541.  
  542.     for (i = 0; (k = *pw) != 0 && i < 64; pw++)
  543.     {
  544.        crypt_block[i++] = (k >> 6) & 01;
  545.        crypt_block[i++] = (k >> 5) & 01;
  546.        crypt_block[i++] = (k >> 4) & 01;
  547.        crypt_block[i++] = (k >> 3) & 01;
  548.        crypt_block[i++] = (k >> 2) & 01;
  549.        crypt_block[i++] = (k >> 1) & 01;
  550.        crypt_block[i++] = (k >> 0) & 01;
  551.        i++;                    /* have to skip one here (parity bit) */
  552.     }
  553.  
  554.     fsetkey ( /* crypt_block */ );
  555.  
  556. #ifdef BUILTIN_CLEAR
  557.     lip = (long int *) crypt_block;
  558.     for (i = (sizeof (crypt_block) / sizeof (long int)); i > 0; i--)
  559.     {
  560.        *(lip++) = 0L;
  561.     }
  562. #else                          /* BUILTIN_CLEAR */
  563. #ifdef BZERO
  564.     bzero (crypt_block, 66);
  565. #else                          /* BZERO */
  566. #ifdef MEMSET
  567.     memset (crypt_block, 0, 66);
  568. #else                          /* MEMSET */
  569.     for (i = 0; i < 66; i++)
  570.     {
  571.        crypt_block[i] = '\0';
  572.     }
  573. #endif                         /* MEMSET */
  574. #endif                         /* BZERO */
  575. #endif                         /* BUILTIN_CLEAR */
  576.  
  577.     iobuf[0] = salt[0];
  578.     iobuf[1] = salt[1];
  579.  
  580.     saltvalue = salt0[iobuf[0]] | salt1[iobuf[1]];
  581.     saltvalue = TF_TO_SIXBIT (saltvalue);
  582.  
  583.     XForm (saltvalue);
  584.     UnXForm ();
  585.  
  586.     for (i = 0; i < 11; i++)
  587.     {
  588.        k = 0;
  589.  
  590.        for (j = 0; j < 6; j++)
  591.        {
  592.            k = (k << 1) | crypt_block[SIX_TIMES (i) + j];
  593.        }
  594.        iobuf[i + 2] = final[k];
  595.     }
  596.  
  597.     iobuf[i + 2] = 0;
  598.  
  599.     if (iobuf[1] == 0)
  600.     {
  601.        iobuf[1] = iobuf[0];
  602.     }
  603.     return (iobuf);
  604. }
  605. /********* INITIALISATION ROUTINES *********/
  606.  
  607. static fbpb4 lookupS (unsl tableno, sbpb6R t6bits)
  608. {
  609.     static fbpb4R S[8][64] =
  610.     {
  611.        14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
  612.        0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
  613.        4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
  614.        15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,
  615.  
  616.        15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
  617.        3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
  618.        0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
  619.        13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,
  620.  
  621.        10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
  622.        13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
  623.        13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
  624.        1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,
  625.  
  626.        7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
  627.        13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
  628.        10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
  629.        3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,
  630.  
  631.        2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
  632.        14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
  633.        4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
  634.        11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,
  635.  
  636.        12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
  637.        10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
  638.        9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
  639.        4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,
  640.  
  641.        4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
  642.        13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
  643.        1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
  644.        6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,
  645.  
  646.        13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
  647.        1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
  648.        7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
  649.        2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11,
  650.     };
  651.     sbpb6 fixed6bits;
  652.     fbpb4R r;
  653.     fbpb4 fixedr;
  654.  
  655.     fixed6bits = (((t6bits >> 0) & 01) << 5) +
  656.        (((t6bits >> 1) & 01) << 3) +
  657.        (((t6bits >> 2) & 01) << 2) +
  658.        (((t6bits >> 3) & 01) << 1) +
  659.        (((t6bits >> 4) & 01) << 0) +
  660.        (((t6bits >> 5) & 01) << 4);
  661.  
  662.     r = S[tableno][fixed6bits];
  663.  
  664.     fixedr = (((r >> 3) & 01) << 0) +
  665.        (((r >> 2) & 01) << 1) +
  666.        (((r >> 1) & 01) << 2) +
  667.        (((r >> 0) & 01) << 3);
  668.  
  669.     return (fixedr);
  670. }
  671.  
  672. static void init (unsl tableno, sbpb24 *lowptr, sbpb24 *highptr)
  673. {
  674.  
  675.     static unsb P[] =
  676.     {
  677.        15, 6, 19, 20,
  678.        28, 11, 27, 16,
  679.        0, 14, 22, 25,
  680.        4, 17, 30, 9,
  681.        1, 7, 23, 13,
  682.        31, 26, 2, 8,
  683.        18, 12, 29, 5,
  684.        21, 10, 3, 24,
  685.     };
  686.  
  687.     static unsb E[] =
  688.     {
  689.        31, 0, 1, 2, 3, 4,
  690.        3, 4, 5, 6, 7, 8,
  691.        7, 8, 9, 10, 11, 12,
  692.        11, 12, 13, 14, 15, 16,
  693.        15, 16, 17, 18, 19, 20,
  694.        19, 20, 21, 22, 23, 24,
  695.        23, 24, 25, 26, 27, 28,
  696.        27, 28, 29, 30, 31, 0,
  697.     };
  698.  
  699.     static obpb1 tmp32[32];
  700.     static obpb1 tmpP32[32];
  701.     static obpb1 tmpE[48];
  702.  
  703.     int j, k, i;
  704.     int tablenoX4;
  705.     reg sbpb24 spare24;
  706.  
  707.     tablenoX4 = (int)(tableno * 4);
  708.  
  709.     for (j = 0; j < 64; j++)
  710.     {
  711.        k = lookupS (tableno, j);
  712.  
  713.        for (i = 0; i < 32; i++)
  714.        {
  715.            tmp32[i] = 0;
  716.        }
  717.        for (i = 0; i < 4; i++)
  718.        {
  719.            tmp32[tablenoX4 + i] = (k >> i) & 01;
  720.        }
  721.        for (i = 0; i < 32; i++)
  722.        {
  723.            tmpP32[i] = tmp32[P[i]];
  724.        }
  725.        for (i = 0; i < 48; i++)
  726.        {
  727.            tmpE[i] = tmpP32[E[i]];
  728.        }
  729.  
  730.        lowptr[j] = 0;
  731.        highptr[j] = 0;
  732.  
  733.        for (i = 0; i < 24; i++)
  734.        {
  735.            lowptr[j] |= (sbpb24)(tmpE[i]) << i;
  736.        }
  737.        for (k = 0, i = 24; i < 48; i++, k++)
  738.        {
  739.            highptr[j] |= (sbpb24)(tmpE[i]) << k;
  740.        }
  741.  
  742.        spare24 = lowptr[j];    /* to allow for macro expansion */
  743.        lowptr[j] = TF_TO_SIXBIT (spare24);
  744.        spare24 = highptr[j];   /* to allow for macro expansion */
  745.        highptr[j] = TF_TO_SIXBIT (spare24);
  746.     }
  747. }
  748.  
  749. void init_des (void)
  750. {
  751.     init (0, S0L, S0H);
  752.     init (1, S1L, S1H);
  753.     init (2, S2L, S2H);
  754.     init (3, S3L, S3H);
  755.     init (4, S4L, S4H);
  756.     init (5, S5L, S5H);
  757.     init (6, S6L, S6H);
  758.     init (7, S7L, S7H);
  759. }
  760.  
  761.