idirt-1.82d/
idirt-1.82d/bin/
idirt-1.82d/data/LOGS/
idirt-1.82d/data/POLICY/
idirt-1.82d/data/WIZ_ZONES/
idirt-1.82d/doc/
idirt-1.82d/doc/info/
idirt-1.82d/doc/manual/
idirt-1.82d/src/Ident/
idirt-1.82d/src/utils/
idirt-1.82d/utils/
/*
 *
 * Copyright (C) 1991, 1992, 1993 Michael Glad.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 * 
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * Very basic crypt(3) implementation straight after
 * das buch.
 *
 */

/* #define DEBUG      */
/* #define BENCHMARK  */
/* #define STANDALONE */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// char *strcpy();

static unsigned char keys[16][48];

static unsigned char bytemask[8] =
  { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };

static unsigned char ip[64] = 
  { 58, 50, 42, 34, 26, 18, 10,  2, 60, 52, 44, 36, 28, 20, 12, 4,
    62, 54, 46, 38, 30, 22, 14,  6, 64, 56, 48, 40, 32, 24, 16, 8,
    57, 49, 41, 33, 25, 17,  9,  1, 59, 51, 43, 35, 27, 19, 11, 3,
    61, 53, 45, 37, 29, 21, 13,  5, 63, 55, 47, 39, 31, 23, 15, 7
  };

static unsigned char ip_1[64] =
  { 40,  8, 48, 16, 56, 24, 64, 32, 39,  7, 47, 15, 55, 23, 63, 31,
    38,  6, 46, 14, 54, 22, 62, 30, 37,  5, 45, 13, 53, 21, 61, 29,
    36,  4, 44, 12, 52, 20, 60, 28, 35,  3, 43, 11, 51, 19, 59, 27,
    34,  2, 42, 10, 50, 18, 58, 26, 33,  1, 41,  9, 49, 17, 57, 25
  };

static unsigned char pc_1[56] =
  { 57, 49, 41, 33, 25, 17,  9,  1, 58, 50, 42, 34, 26, 18,
    10,  2, 59, 51, 43, 35, 27, 19, 11,  3, 60, 52, 44, 36,
    63, 55, 47, 39, 31, 23, 15,  7, 62, 54, 46, 38, 30, 22,
    14,  6, 61, 53, 45, 37, 29, 21, 13,  5, 28, 20, 12,  4
  };

static unsigned char pc_2[48] =
  { 14, 17, 11, 24,  1,  5,  3, 28, 15,  6, 21, 10,
    23, 19, 12,  4, 26,  8, 16,  7, 27, 20, 13,  2,
    41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
    44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32
  };

static unsigned char ls[16] =
  { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };

static unsigned char eref[48] =
  { 32,  1,  2,  3,  4,  5,  4,  5,  6,  7,  8,  9,
     8,  9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17,
    16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25,
    24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32,  1
  };
static unsigned char e[48];

static unsigned char p[32] = 
  { 16,  7, 20, 21, 29, 12, 28, 17,  1, 15, 23, 26,  5, 18, 31, 10,
     2,  8, 24, 14, 32, 27,  3,  9, 19, 13, 30,  6, 22, 11,  4, 25
  };

static unsigned char sel[8][4][16]=
      { { { 14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7 },
          {  0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8 },
          {  4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0 },
          { 15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13 }
        },

        { { 15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10 },
          {  3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5 },
          {  0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15 },
          { 13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9 }
        },

        { { 10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8 },
          { 13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1 },
          { 13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7 },
          {  1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12 }
        },

        { {  7,  13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15 },
          { 13,  8,  11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9 },
          { 10,  6,   9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4 },
          {  3, 15,   0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14 }
        },

        { {  2, 12,   4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9 },
          { 14, 11,   2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6 },
          {  4,  2,    1, 11, 10, 13,  7,  8, 15, 9, 12,  5,  6,  3,  0, 14 },
          { 11,  8,  12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3 }
        },

        { { 12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11 },
          { 10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8 },
          {  9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6 },
          {  4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13 }
        },

        { {  4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1 },
          { 13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6 },
          {  1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2 },
          {  6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12 }
        },

        { { 13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7 },
          {  1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2 },
          {  7, 11, 4,   1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8 },
          {  2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11 }
        }
      };

#define ascii_to_bin(c) (c>='a'?(c-59):c>='A'?(c-53):c-'.')
#define bin_to_ascii(c) (c>=38?(c-38+'a'):c>=12?(c-12+'A'):c+'.')

static void pr_bits(v,n)
  unsigned char *v;
  int n;
  { int i,j;
    n/=8;
    for(i = 0; i < n; i++)
      { int outp = 0;
        for(j = 0; j < 8; j++)
          outp |= v[8 * i+j]?bytemask[j%8]:0;
        printf("%02x ",outp);
      }
  }

static void pre_bits(v,n)
  unsigned char *v;
  int n;
  { int i,j;
    n/=8;
    for(i = 0; i < n; i++)
      { int outp = 0;
        for(j = 0; j < 8; j++)
          outp |= v[eref[8 * i+j] - 1]?bytemask[j%8]:0;
        printf("%02x ",outp);
      }
  }

void encrypt(),setkey();
static void f(),s(),permute(),xor();

char *crypt(k,salt)
  char *k,*salt;
  { int i,j;
    char c/*,key_c[9]*/;
    unsigned char key[64];
    unsigned char bits[66];
    static char outbuf[14];

    bzero(key,sizeof key);
    for(i = 0; (c = k[i] << 1) && i < 8; i++)
      for(j = 8; j--;)
        key[i * 8+j] = (c & bytemask[j])?1:0;
    setkey((char*)key);

    for(i = 0; i < 2; i++)
      { c = ascii_to_bin(salt[i]);
        for(j = 0; j < 6; j++)
          if((c >> j) & 0x1)
            { unsigned char t;
              t = e[6 * i+j];
              e[6*i+j] = e[6*i+j+24];
              e[6*i+j+24] = t;
            }
      }

    bzero((char*)bits,sizeof(bits));
    for(i = 25; i--;)
      encrypt((char*)bits,0);

#ifdef DEBUG
    pr_bits(bits,64); printf("\n");
#endif

    outbuf[0] = salt[0];
    outbuf[1] = salt[1];
    for(i = 0; i < 11; i++)
      { unsigned char tmp = 0;
        for(j = 0; j < 6; j++)
          tmp |= bits[6*i+j] << (5 - j);
        outbuf[i+2] = bin_to_ascii(tmp);
      }
    outbuf[i+2] = 0;

    return outbuf;

  }

#ifdef STANDALONE

main()
  { char *s;
    char buf[64];

#ifdef BENCHMARK
    int i;
    for(i = 1000; i--;)
#endif
      s = crypt("ABC$#","zI");
    printf("%s\n",s);

#ifdef DEBUG
    bcopy(eref,e,sizeof(eref));
    bzero(buf,64);
    encrypt(buf,0);
    pr_bits(buf,64); printf("\n");
#endif

  }

#endif
  
void encrypt(inbit,direction)
  char *inbit;
  int direction;
  { unsigned char temp[64];
    unsigned char lr[32*19];
    int i,j;

    permute(64,ip,(unsigned char*)inbit,lr);
    for(i = 0; i < 16; i++)
      { f(lr+(i+1)*32,keys[direction?15 - i:i],temp);
#ifdef DEBUG
        pr_bits(lr+(i+1)*32,32); printf("-> "); pr_bits(temp,32); printf("\n");
#endif
        xor(32,lr+i*32,temp,lr+(i+2)*32);
      }
    for(j = 0; j < 32; j++)
      lr[18*32+j] = lr[16*32+j];
    permute(64,ip_1,lr+17*32,(unsigned char*)inbit);
  }

void setkey(key)
  char *key;
  { int i,j;
    unsigned char key_halves[17][56];

    permute(56,pc_1,(unsigned char*)key,key_halves[0]);
    for(i = 1; i<= 16; i++)
      { for(j = 0; j < 28; j++)
          { key_halves[i][j]    = key_halves[i - 1][(j+ls[i - 1])%28];
            key_halves[i][j+28] = key_halves[i - 1][(j+28+ls[i - 1])%28+28];
          }
        permute(48,pc_2,key_halves[i],keys[i - 1]);
      }
    bcopy((char*)eref,(char*)e,sizeof(eref));
  }

static void f(r,key,out)
  unsigned char *r,*key,*out;
  { unsigned char e_r[48],bs[48],sbs[32];
    int i;
     permute(48,e,r,e_r);
     xor(48,e_r,key,bs);
     for(i = 0; i < 8; i++) 
       s(bs+i*6,sbs+i*4,i);
     permute(32,p,sbs,out);
   }

static void s(b,ps,i)
  unsigned char *b,*ps;
  int i;
  { int val,j;

    val = sel[i][b[0]*2+b[5]][b[1]*8+b[2]*4+b[3]*2+b[4]];
    for(j = 4; j--; )
      { ps[j] = val&0x1;
        val >>= 1;
      }
  }

static void permute(count,perm,in,out)
  int count;
  unsigned char *perm;
  unsigned char *in,*out;
  { int i;
    for(i = 0; i < count; i++)
      out[i] = in[perm[i] - 1];
  }

static void xor(count,in1,in2,out)
  int count;
  unsigned char *in1,*in2,*out;
  { int i;
    for(i = 0; i < count; i++) 
      out[i] = (in1[i] ^ in2[i]) & 0x1;
  }