home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / alde_c / misc / util / cipher2 / lucifer.c < prev   
Encoding:
C/C++ Source or Header  |  1985-01-08  |  17.4 KB  |  470 lines

  1. /***************************** lucifer **************************
  2.  * LUCIFER: encrypt/decrypt bytes using IBM's LUCIFER algorithm.
  3.  * Programmed by R.W.Outerbridge
  4.  *
  5.  * Usage: lucifer (+|-)([ecb]|<cbc|cks>) key1 <ivec>
  6.  *                EN/DE    MODES         KEYS
  7.  *
  8.  *      + :     ENcrypt (default if MODE specified)
  9.  *      - :     DEcrypt (presumes encrypted input)
  10.  *
  11.  *      Modes of Operation (choose ONE):
  12.  *
  13.  *      ecb : (default) Electronic Code Book.  Only uses one key.
  14.  *              If simply "+" or "-" is specified, ecb is used.
  15.  *      cbc : Cipher Block Chaining.  Uses two keys.
  16.  *      cks : ChecKSum.  Generates a 128-bit checksum using two keys.
  17.  *
  18.  *      Both keys may be as long as you wish.  The practical limit
  19.  *      on keylength is the size of your system's argument buffer.
  20.  *      WARNING: on some machines all arguments become CAPITALS.
  21.  *      WARNING: non-ascii machines MAY get different results.
  22.  *
  23.  *      Any character may be used in keys - depending on the O/S -
  24.  *      except ASCII NULL (0x00).  The one-letter key '#', when used 
  25.  *      for "key1", will cause lucifer to use a preset default key
  26.  *      (for verification and testing).  Failing to specify "ivec", if
  27.  *      required, will result in "key1" being used for both keys.  It
  28.  *      is an error to omit "key1".  There is no provision for giving
  29.  *      arbitrary, absolute, bit-valued keys.
  30.  *
  31.  *      As painful as they are to use, long keys are MUCH safer;
  32.  *      think up nonsense phrases you can safely remember.
  33.  *
  34.  */
  35.  
  36. #include <stdio.h>
  37. #define toascii(a)      ((a)&0177)
  38. #define EN      0
  39. #define DE      1
  40. #define CKS     2
  41. #define MODS    3
  42. typedef char    BYTE;   /* BYTE = (VAX) ? int : char;   */
  43.         
  44. /* cryptographic declarations   */
  45. void copy16(), xor16(), getkey(), loadkey(), lucifer();
  46. BYTE Block[16], Link[16], Temp[16], IV[16];
  47. BYTE DFLTKY[16] = { 1,35,69,103,137,171,205,239,254,220,186,152,118,84,50,16 };
  48.         /* DO NOT ALTER! => 0x0123456789abcdeffedcba9876543210 <=       */
  49.  
  50. /* I/O declarations     */
  51. void ruderr(), put16(), vraiput(), initio();
  52. int IOedf, End, Once;
  53. BYTE Last[16];
  54.  
  55. int Ecb(), Cbc(), Cks();
  56. struct modes {
  57.         char *name;
  58.         int (*func)();
  59.         };
  60. struct modes ModsOp[MODS] = {   /* CAPS for CP/M - sorry!       */
  61.         { "ECB", Ecb },
  62.         { "CBC", Cbc },
  63.         { "CKS", Cks }  };
  64.  
  65. main(argc, argv)
  66. int argc;
  67. char **argv;
  68.         {
  69.         int (*xeqtr)();
  70.         int step, ende, edio, ok, i;
  71.         BYTE kv[16];
  72.  
  73.         argv++; argc--;
  74.         if(argc > 3 || argc < 2) ruderr();
  75.  
  76.         for(step=0; argc > 0; step++) {
  77.                 switch(step) {
  78.                 case 0: /* set en/de and/or default mode        */
  79.                         if(*argv[0] == '+' || *argv[0] == '-') {
  80.                                 ende = (*argv[0] == '+') ? EN : DE;
  81.                                 *argv[0]++ = NULL;
  82.                                 if(*argv[0] == NULL) {
  83.                                         xeqtr = Ecb;    /* default mode */
  84.                                         edio = ende;
  85.                                         argv++; argc--;
  86.                                         break;
  87.                                         }
  88.                                 }
  89.                         else ende = EN;
  90.  
  91.                         for(i=ok=0; i < MODS && !ok; i++) {
  92.                                 if(strcmp(argv[0], ModsOp[i].name) == 0) {
  93.                                         xeqtr = ModsOp[i].func;
  94.                                         ok = 1;
  95.                                         }
  96.                                 }
  97.                         if(!ok) {
  98.                                 fprintf(stderr, 
  99.                                 "Lucifer: unknown mode >%s<.\n", argv[0]);
  100.                                 ruderr();
  101.                                 }
  102.                         while(*argv[0]) *argv[0]++ = NULL;
  103.                         argv++; argc--;
  104.  
  105.                         /* set appropriate IO modes     */
  106.                         if(xeqtr == Cks) edio = CKS;
  107.                         else edio = ende;
  108.  
  109.                 /* falling through....  */
  110.                 case 1: /* get the key and IV, if needed and present    */
  111.                         if(strcmp(argv[0], "#") == 0) copy16(DFLTKY, kv);
  112.                         else getkey(argv[0], kv);
  113.                         argv++; argc--;
  114.                         
  115.                         /* if nothing left, but an IV needed, use the key    */
  116.                         if(argc == 0) {
  117.                                 if(xeqtr != Ecb) copy16(kv, IV);
  118.                                 break;
  119.                                 }
  120.                         else if(xeqtr == Ecb) {
  121.                                 fprintf(stderr, "Lucifer: ivec ignored.\n");
  122.                                 while(*argv[0]) *argv[0]++ = NULL;
  123.                                 argv++; argc--;
  124.                                 break;
  125.                                 }
  126.  
  127.                         else getkey(argv[0], IV);
  128.                         argv++; argc--;
  129.                         break;
  130.  
  131.                 default:
  132.                         fprintf(stderr, "Lucifer: Programming error!\n");
  133.                         exit(1);
  134.                         break;
  135.                         }       /* switch       */
  136.                 }       /* argument parsing     */
  137.  
  138.         initio(edio);
  139.         loadkey(kv, ende);
  140.         (*xeqtr)(ende); /* ta-da!  Take it away xeqtr!  */
  141.         exit(0);
  142.         }       /* end of main  */
  143.  
  144. void ruderr() {
  145.         fprintf(stderr,
  146.                 "Usage: lucifer (+|-)([ecb]|<cbc|cks>) key1 <ivec>\n");
  147.         exit(1);
  148.         }
  149.  
  150. Cbc(e_d)        /* Cipher Block Chaining                */
  151. int e_d;        /* Ciphertext errors are self-healing.  */
  152.         {
  153.         copy16(IV, Link);
  154.         while(get16(Block) != EOF) {
  155.                 if(e_d == DE) {
  156.                         copy16(Block, Temp);
  157.                         lucifer(Block);
  158.                         xor16(Block, Link);
  159.                         copy16(Temp, Link);
  160.                         }
  161.                 else {
  162.                         xor16(Block, Link);
  163.                         lucifer(Block);
  164.                         copy16(Block, Link);
  165.                         }
  166.                 put16(Block);
  167.                 }
  168.         return;
  169.         }
  170.  
  171. Cks(dummy)      /* CBC authentication checksum generator        */
  172. int dummy;      /* The banks use this for verifications.        */
  173.         {
  174.         int i, j, k;
  175.         long count = 0L;
  176.         copy16(IV, Link);
  177.         while(get16(Block) != EOF) {
  178.                 xor16(Block, Link);
  179.                 lucifer(Block);
  180.                 copy16(Block, Link);
  181.                 count++;
  182.                 }
  183.         fprintf(stdout, ": %0ld bytes\t: ", count<<4);
  184.         for(i=j=0; i < 4; i++) {
  185.                 for(k=0; k < 4; k++, j++)
  186.                         fprintf(stdout, "%02x", Link[j]&0377);
  187.                 putc(' ', stdout);
  188.                 }
  189.         fprintf(stdout, ":\n");
  190.         return;
  191.         }
  192.  
  193. Ecb(dummy)      /* Electronic Code Book : simple substitution   */
  194. int dummy;      /* Yawn.  For static data and random access.    */
  195.         {
  196.         while(get16(Block) != EOF) {
  197.                 lucifer(Block);
  198.                 put16(Block);
  199.                 }
  200.         return;
  201.         }
  202.  
  203. void copy16(from, to)
  204. register BYTE *from, *to;
  205.         {
  206.         register BYTE *ep;
  207.         ep = &to[16];
  208.         while(to < ep) *to++ = *from++;
  209.         return;
  210.         }
  211.  
  212. void xor16(to, with)
  213. register BYTE *to, *with;
  214.         {
  215.         register BYTE *ep;
  216.         ep = &to[16];
  217.         while(to < ep) *to++ ^= *with++;
  218.         return;
  219.         }
  220.  
  221. void put16(block)
  222. register BYTE *block;
  223.         {
  224.         if(IOedf == DE) copy16(block, Last);
  225.         else vraiput(block, &block[16]);
  226.         return;
  227.         }
  228.  
  229. get16(input)
  230. register BYTE *input;
  231.         {
  232.         register int i, j;
  233.         if(End == 1) return(EOF);       /* no more input        */
  234.  
  235.         for(i=0; i < 16 && ((j = getc(stdin)) != EOF); i++) *input++ = j;
  236.  
  237.         if(IOedf == DE) {       /* DECRYPTION   */
  238.                 /* complete block?  pending output?     */
  239.                 if(i == 16 && (Once > 0)) vraiput(Last, &Last[16]);
  240.                 else if(j == EOF) {
  241.                         End = 1;
  242.                         if(Once > 0) {
  243.                                 /* incomplete block means no nulls      */
  244.                                 if(i != 0) i = 0;
  245.                                 else {  
  246.                                         i = Last[15]&0377;
  247.                                         if(i > 16) i = 0;       /* huh? */
  248.                                         }
  249.                                 vraiput(Last, &Last[16-i]);
  250.                                 }
  251.                         return(EOF);
  252.                         }
  253.                 }
  254.         else if(j == EOF) {     /* ENCRYPTION   */
  255.                 End = 1;
  256.                 if(i == 0 && (IOedf == EN || (Once > 0))) {
  257.                         /* if no padding to do, print a kludge  */
  258.                         if(IOedf == EN && (Once > 0)) putc('0', stdout);
  259.                         return(EOF);
  260.                         }
  261.                 for(j=i; j < 15; j++) *input++ = NULL;
  262.                 *input = 16-i;
  263.                 }
  264.         Once = 1;
  265.         return(0);
  266.         }
  267.  
  268. void getkey(aptr, kptr)
  269. register char *aptr;
  270. register BYTE *kptr;
  271.         {
  272.         register BYTE *store;
  273.         register int i, first;
  274.         BYTE hold[16];
  275.         first = 1;
  276.         loadkey(DFLTKY, EN);
  277.         copy16(DFLTKY, hold);
  278.         while(*aptr || first) {
  279.                 store = kptr;
  280.                 for(i=0; i<16 && (*aptr != NULL); i++) {
  281.                         *store++ = toascii(*aptr);
  282.                         *aptr++ = NULL;
  283.                         }
  284.                 while(i++ < 16) *store++ = NULL;
  285.                 xor16(kptr, hold);
  286.                 lucifer(kptr);
  287.                 copy16(kptr, hold);
  288.                 first = 0;
  289.                 }
  290.         return;
  291.         }
  292.  
  293. void vraiput(cp, ep)
  294. register BYTE *cp, *ep;
  295.         {
  296.         while(cp < ep) putc((char)*cp++, stdout);
  297.         return;
  298.         }
  299.  
  300. void initio(edf)
  301. int edf;
  302.         {
  303.         IOedf = edf;
  304.         End = Once = 0;
  305.         return;
  306.         }
  307.  
  308. /* LUCIFER is a cryptographic algorithm developed by IBM in the early
  309.  *      seventies.  It was a predecessor of the DES, and is much simpler
  310.  *      than that algorithm.  In particular, it has only two substitution
  311.  *      boxes.  It does, however, use a 128 bit key and operates on
  312.  *      sixteen byte data blocks...
  313.  *
  314.  *      This implementation of LUCIFER was crafted by Graven Cyphers at the
  315.  *      University of Toronto, Canada, with programming assistance from
  316.  *      Richard Outerbridge.  It is based on the FORTRAN routines which
  317.  *      concluded Arthur Sorkin's article "LUCIFER: A Cryptographic Algorithm",
  318.  *      CRYPTOLOGIA, Volume 8, Number 1, January 1984, pp22-42.  The interested
  319.  *      reader should refer to that article rather than this program for more
  320.  *      details on LUCIFER.
  321.  *
  322.  *      These routines bear little resemblance to the actual LUCIFER algorithm,
  323.  *      which has been severely twisted in the interests of speed.  They do
  324.  *      perform the same transformations, and are believed to be UNIX portable.
  325.  *      The package was developed for use on UNIX-like systems lacking crypto
  326.  *      facilities.  They are not very fast, but the cipher is very strong.
  327.  *      The routines in this file are suitable for use as a subroutine library
  328.  *      after the fashion of crypt(3).  When linked together with applications
  329.  *      routines they can also provide a high-level cryptographic system.
  330.  *
  331.  *      -DENHANCE : modify LUCIFER by changing the key schedule and performing
  332.  *              an "autokeyed" encryption.  These may improve the algorithm.
  333.  */
  334.  
  335. #ifndef DE
  336. #define DE      1       /* for separate compilation     */
  337. #endif
  338.  
  339. static BYTE Dps[64] = { /* Diffusion Pattern schedule   */
  340.         4,16,32,2,1,8,64,128,   128,4,16,32,2,1,8,64,
  341.         64,128,4,16,32,2,1,8,   8,64,128,4,16,32,2,1,
  342.         1,8,64,128,4,16,32,2,   2,1,8,64,128,4,16,32,
  343.         32,2,1,8,64,128,4,16,   16,32,2,1,8,64,128,4    };
  344.  
  345. /* Precomputed S&P Boxes, Two Varieties */
  346. static BYTE TCB0[256] = {
  347.         87, 21,117, 54, 23, 55, 20, 84,116,118, 22, 53, 85,119, 52, 86,
  348.         223,157,253,190,159,191,156,220,252,254,158,189,221,255,188,222,
  349.         207,141,237,174,143,175,140,204,236,238,142,173,205,239,172,206,
  350.         211,145,241,178,147,179,144,208,240,242,146,177,209,243,176,210,
  351.         215,149,245,182,151,183,148,212,244,246,150,181,213,247,180,214,
  352.         95, 29,125, 62, 31, 63, 28, 92,124,126, 30, 61, 93,127, 60, 94,
  353.         219,153,249,186,155,187,152,216,248,250,154,185,217,251,184,218,
  354.         67,  1, 97, 34,  3, 35,  0, 64, 96, 98,  2, 33, 65, 99, 32, 66,
  355.         195,129,225,162,131,163,128,192,224,226,130,161,193,227,160,194,
  356.         199,133,229,166,135,167,132,196,228,230,134,165,197,231,164,198,
  357.         203,137,233,170,139,171,136,200,232,234,138,169,201,235,168,202,
  358.         75,  9,105, 42, 11, 43,  8, 72,104,106, 10, 41, 73,107, 40, 74,
  359.         91, 25,121, 58, 27, 59, 24, 88,120,122, 26, 57, 89,123, 56, 90,
  360.         71,  5,101, 38,  7, 39,  4, 68,100,102,  6, 37, 69,103, 36, 70,
  361.         79, 13,109, 46, 15, 47, 12, 76,108,110, 14, 45, 77,111, 44, 78,
  362.         83, 17,113, 50, 19, 51, 16, 80,112,114, 18, 49, 81,115, 48, 82 };
  363.  
  364. static BYTE TCB1[256] = {
  365.         87,223,207,211,215, 95,219, 67,195,199,203, 75, 91, 71, 79, 83,
  366.         21,157,141,145,149, 29,153,  1,129,133,137,  9, 25,  5, 13, 17,
  367.         117,253,237,241,245,125,249, 97,225,229,233,105,121,101,109,113,
  368.         54,190,174,178,182, 62,186, 34,162,166,170, 42, 58, 38, 46, 50,
  369.         23,159,143,147,151, 31,155,  3,131,135,139, 11, 27,  7, 15, 19,
  370.         55,191,175,179,183, 63,187, 35,163,167,171, 43, 59, 39, 47, 51,
  371.         20,156,140,144,148, 28,152,  0,128,132,136,  8, 24,  4, 12, 16,
  372.         84,220,204,208,212, 92,216, 64,192,196,200, 72, 88, 68, 76, 80,
  373.         116,252,236,240,244,124,248, 96,224,228,232,104,120,100,108,112,
  374.         118,254,238,242,246,126,250, 98,226,230,234,106,122,102,110,114,
  375.         22,158,142,146,150, 30,154,  2,130,134,138, 10, 26,  6, 14, 18,
  376.         53,189,173,177,181, 61,185, 33,161,165,169, 41, 57, 37, 45, 49,
  377.         85,221,205,209,213, 93,217, 65,193,197,201, 73, 89, 69, 77, 81,
  378.         119,255,239,243,247,127,251, 99,227,231,235,107,123,103,111,115,
  379.         52,188,172,176,180, 60,184, 32,160,164,168, 40, 56, 36, 44, 48,
  380.         86,222,206,210,214, 94,218, 66,194,198,202, 74, 90, 70, 78, 82 };
  381.  
  382. static BYTE Key[16], Pkey[128];
  383. static int P[8] = { 3,5,0,4,2,1,7,6 };
  384. static int Smask[16] = { 128,64,32,16,8,4,2,1 };
  385.  
  386. void lucifer(bytes)
  387. BYTE *bytes;    /* points to a 16-byte array    */
  388.         {
  389.         register BYTE *cp, *sp, *dp;
  390.         register int val, *sbs, tcb, j, i;
  391.         BYTE *h0, *h1, *kc, *ks;
  392.  
  393.         h0 = bytes;     /* the "lower" half     */
  394.         h1 = &bytes[8]; /* the "upper" half     */
  395.         kc = Pkey;
  396.         ks = Key;
  397.  
  398.         for(i=0; i<16; i++) {
  399.                 tcb = *ks++;
  400.                 sbs = Smask;
  401.                 dp = Dps;
  402.                 sp = &h0[8];
  403. #ifdef ENHANCE
  404.                 for(j=0, cp=h1; j<8; j++) tcb ^= *cp++;
  405. #endif
  406.                 for(j=0; j<8; j++) {
  407.                         if(tcb&*sbs++) val = TCB1[h1[j]&0377];
  408.                         else val = TCB0[h1[j]&0377];
  409.                         val ^= *kc++;
  410.                         for(cp=h0; cp<sp;) *cp++ ^= (val&*dp++);
  411.                         }
  412.  
  413.                 /* swap (virtual) halves        */
  414.                 cp = h0;
  415.                 h0 = h1;
  416.                 h1 = cp;
  417.                 }
  418.  
  419.         /* REALLY swap halves   */
  420.         dp = bytes;
  421.         cp = &bytes[8];
  422.         for(sp=cp; dp<sp; dp++, cp++) {
  423.                 val = *dp;
  424.                 *dp = *cp;
  425.                 *cp = val;
  426.                 }
  427.         return;
  428.         } 
  429.  
  430. void loadkey(keystr, edf)       /* precomputes the key schedules        */
  431. BYTE *keystr;
  432. register int edf;
  433.         {
  434.         register BYTE *ep, *cp, *pp;
  435.         register int kc, i, j;
  436.         BYTE kk[16], pk[16];
  437.         cp = kk;
  438.         pp = pk;
  439.         ep = &kk[16];
  440.         while(cp < ep) {
  441.                 *cp++ = *keystr;
  442.                 for(*pp=i=0; i<8; i++)
  443.                         if(*keystr&Smask[i]) *pp |= Smask[P[i]];
  444.                 keystr++;
  445.                 pp++;
  446.                 }
  447.         cp = Key;
  448.         pp = Pkey;
  449.         kc = (edf == DE) ? 8 : 0;
  450.         for(i=0; i<16; i++) {
  451.                 if(edf == DE) kc = (++kc)&017;
  452. #ifdef ENHANCE
  453.                 *cp++ = kk[( (kc == 0) ? 15 : (kc - 1) )];
  454. #else
  455.                 *cp++ = kk[kc];
  456. #endif 
  457.                 for(j=0; j<8; j++) {
  458.                         *pp++ = pk[kc];
  459.                         if(j<7 || (edf == DE)) kc = (++kc)&017;
  460.                         }
  461.                 }
  462.         return;
  463.         }
  464.  
  465. /* lucifer cks # < /dev/null 
  466.  *      : 16 bytes      : 32186510 6acf6094 87953eba 196f5a75 :
  467.  *      (-DENHANCE)     : 378cfd5b bd54a07b 28513809 624e6071 :
  468.  *                      (rwo/8412.03.18:10/V5.0)                */
  469. /************************ lucifer *******************************/
  470.