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