home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1998 July & August / Pcwk78a98.iso / Wtestowe / Clico / UNIX / SAMBA / SOURCE / SAMBA.TAR / samba-1.9.17 / source / md4.c < prev    next >
C/C++ Source or Header  |  1996-06-04  |  10KB  |  300 lines

  1. #ifdef SMB_PASSWD
  2. /*
  3.    This code is from rfc1186. 
  4. */
  5.  
  6.  /*
  7.  ** ********************************************************************
  8.  ** md4.c -- Implementation of MD4 Message Digest Algorithm           **
  9.  ** Updated: 2/16/90 by Ronald L. Rivest                              **
  10.  ** (C) 1990 RSA Data Security, Inc.                                  **
  11.  ** ********************************************************************
  12.  */
  13.  
  14.  /*
  15.  ** To use MD4:
  16.  **   -- Include md4.h in your program
  17.  **   -- Declare an MDstruct MD to hold the state of the digest
  18.  **          computation.
  19.  **   -- Initialize MD using MDbegin(&MD)
  20.  **   -- For each full block (64 bytes) X you wish to process, call
  21.  **          MDupdate(&MD,X,512)
  22.  **      (512 is the number of bits in a full block.)
  23.  **   -- For the last block (less than 64 bytes) you wish to process,
  24.  **          MDupdate(&MD,X,n)
  25.  **      where n is the number of bits in the partial block. A partial
  26.  **      block terminates the computation, so every MD computation
  27.  **      should terminate by processing a partial block, even if it
  28.  **      has n = 0.
  29.  **   -- The message digest is available in MD.buffer[0] ...
  30.  **      MD.buffer[3].  (Least-significant byte of each word
  31.  **      should be output first.)
  32.  **   -- You can print out the digest using MDprint(&MD)
  33.  */
  34.  
  35.  /* Implementation notes:
  36.  ** This implementation assumes that ints are 32-bit quantities.
  37.  ** If the machine stores the least-significant byte of an int in the
  38.  ** least-addressed byte (e.g., VAX and 8086), then LOWBYTEFIRST
  39.  ** should be set to TRUE.  Otherwise (e.g., SUNS), LOWBYTEFIRST
  40.  ** should be set to FALSE.  Note that on machines with LOWBYTEFIRST
  41.  ** FALSE the routine MDupdate modifies has a side-effect on its input
  42.  ** array (the order of bytes in each word are reversed).  If this is
  43.  ** undesired a call to MDreverse(X) can reverse the bytes of X back
  44.  ** into order after each call to MDupdate.
  45.  */
  46.  
  47. #define TRUE  1
  48. #define FALSE 0
  49.  
  50.  /* Compile-time includes
  51.  */
  52.  
  53. #include <stdio.h>
  54. #include "md4.h"
  55.  
  56. #define uchar unsigned char
  57. #define int16 unsigned short
  58. #define uint32 unsigned int
  59.  
  60. #include "byteorder.h"
  61.  
  62.  /* Compile-time declarations of MD4 "magic constants".
  63.  */
  64. #define I0  0x67452301       /* Initial values for MD buffer */
  65. #define I1  0xefcdab89
  66. #define I2  0x98badcfe
  67. #define I3  0x10325476
  68. #define C2  013240474631     /* round 2 constant = sqrt(2) in octal */
  69. #define C3  015666365641     /* round 3 constant = sqrt(3) in octal */
  70.  /* C2 and C3 are from Knuth, The Art of Programming, Volume 2
  71.  ** (Seminumerical Algorithms), Second Edition (1981), Addison-Wesley.
  72.  ** Table 2, page 660.
  73.  */
  74.  
  75. #define fs1  3               /* round 1 shift amounts */
  76. #define fs2  7
  77. #define fs3 11
  78. #define fs4 19
  79. #define gs1  3               /* round 2 shift amounts */
  80. #define gs2  5
  81. #define gs3  9
  82. #define gs4 13
  83. #define hs1  3               /* round 3 shift amounts */
  84. #define hs2  9
  85. #define hs3 11
  86. #define hs4 15
  87.  
  88.  /* Compile-time macro declarations for MD4.
  89.  ** Note: The "rot" operator uses the variable "tmp".
  90.  ** It assumes tmp is declared as unsigned int, so that the >>
  91.  ** operator will shift in zeros rather than extending the sign bit.
  92.  */
  93. #define f(X,Y,Z)             ((X&Y) | ((~X)&Z))
  94. #define g(X,Y,Z)             ((X&Y) | (X&Z) | (Y&Z))
  95. #define h(X,Y,Z)             (X^Y^Z)
  96. #define rot(X,S)             (tmp=X,(tmp<<S) | (tmp>>(32-S)))
  97. #define ff(A,B,C,D,i,s)      A = rot((A + f(B,C,D) + X[i]),s)
  98. #define gg(A,B,C,D,i,s)      A = rot((A + g(B,C,D) + X[i] + C2),s)
  99. #define hh(A,B,C,D,i,s)      A = rot((A + h(B,C,D) + X[i] + C3),s)
  100.  
  101.  /* MDprint(MDp)
  102.  ** Print message digest buffer MDp as 32 hexadecimal digits.
  103.  ** Order is from low-order byte of buffer[0] to high-order byte of
  104.  ** buffer[3].
  105.  ** Each byte is printed with high-order hexadecimal digit first.
  106.  ** This is a user-callable routine.
  107.  */
  108.  void
  109.  MDprint(MDp)
  110.  MDptr MDp;
  111.  { int i,j;
  112.    for (i=0;i<4;i++)
  113.      for (j=0;j<32;j=j+8)
  114.        printf("%02x",(MDp->buffer[i]>>j) & 0xFF);
  115.  }
  116.  
  117.  /* MDbegin(MDp)
  118.  ** Initialize message digest buffer MDp.
  119.  ** This is a user-callable routine.
  120.  */
  121.  void
  122.  MDbegin(MDp)
  123.  MDptr MDp;
  124.  { int i;
  125.    MDp->buffer[0] = I0;
  126.    MDp->buffer[1] = I1;
  127.    MDp->buffer[2] = I2;
  128.    MDp->buffer[3] = I3;
  129.    for (i=0;i<8;i++) MDp->count[i] = 0;
  130.    MDp->done = 0;
  131.  }
  132.  
  133.  /* MDreverse(X)
  134.  ** Reverse the byte-ordering of every int in X.
  135.  ** Assumes X is an array of 16 ints.
  136.  ** The macro revx reverses the byte-ordering of the next word of X.
  137.  */
  138.  void MDreverse(X)
  139.  unsigned int *X;
  140.  { register unsigned int t;
  141.    register unsigned int i;
  142.  
  143.    for(i = 0; i < 16; i++) {
  144.       t = X[i];
  145.       SIVAL(X,i*4,t);
  146.     }
  147.  }
  148.  
  149.  /* MDblock(MDp,X)
  150.  ** Update message digest buffer MDp->buffer using 16-word data block X.
  151.  ** Assumes all 16 words of X are full of data.
  152.  ** Does not update MDp->count.
  153.  ** This routine is not user-callable.
  154.  */
  155.  static void
  156.  MDblock(MDp,X)
  157.  MDptr MDp;
  158.  unsigned int *X;
  159.  {
  160.    register unsigned int tmp, A, B, C, D;
  161.    MDreverse(X);
  162.    A = MDp->buffer[0];
  163.    B = MDp->buffer[1];
  164.    C = MDp->buffer[2];
  165.    D = MDp->buffer[3];
  166.    /* Update the message digest buffer */
  167.    ff(A , B , C , D ,  0 , fs1); /* Round 1 */
  168.    ff(D , A , B , C ,  1 , fs2);
  169.    ff(C , D , A , B ,  2 , fs3);
  170.    ff(B , C , D , A ,  3 , fs4);
  171.    ff(A , B , C , D ,  4 , fs1);
  172.    ff(D , A , B , C ,  5 , fs2);
  173.    ff(C , D , A , B ,  6 , fs3);
  174.    ff(B , C , D , A ,  7 , fs4);
  175.    ff(A , B , C , D ,  8 , fs1);
  176.    ff(D , A , B , C ,  9 , fs2);
  177.    ff(C , D , A , B , 10 , fs3);
  178.    ff(B , C , D , A , 11 , fs4);
  179.    ff(A , B , C , D , 12 , fs1);
  180.    ff(D , A , B , C , 13 , fs2);
  181.    ff(C , D , A , B , 14 , fs3);
  182.    ff(B , C , D , A , 15 , fs4);
  183.    gg(A , B , C , D ,  0 , gs1); /* Round 2 */
  184.    gg(D , A , B , C ,  4 , gs2);
  185.    gg(C , D , A , B ,  8 , gs3);
  186.    gg(B , C , D , A , 12 , gs4);
  187.    gg(A , B , C , D ,  1 , gs1);
  188.    gg(D , A , B , C ,  5 , gs2);
  189.    gg(C , D , A , B ,  9 , gs3);
  190.    gg(B , C , D , A , 13 , gs4);
  191.    gg(A , B , C , D ,  2 , gs1);
  192.    gg(D , A , B , C ,  6 , gs2);
  193.    gg(C , D , A , B , 10 , gs3);
  194.    gg(B , C , D , A , 14 , gs4);
  195.    gg(A , B , C , D ,  3 , gs1);
  196.    gg(D , A , B , C ,  7 , gs2);
  197.    gg(C , D , A , B , 11 , gs3);
  198.    gg(B , C , D , A , 15 , gs4);
  199.    hh(A , B , C , D ,  0 , hs1); /* Round 3 */
  200.    hh(D , A , B , C ,  8 , hs2);
  201.    hh(C , D , A , B ,  4 , hs3);
  202.    hh(B , C , D , A , 12 , hs4);
  203.    hh(A , B , C , D ,  2 , hs1);
  204.    hh(D , A , B , C , 10 , hs2);
  205.    hh(C , D , A , B ,  6 , hs3);
  206.    hh(B , C , D , A , 14 , hs4);
  207.    hh(A , B , C , D ,  1 , hs1);
  208.    hh(D , A , B , C ,  9 , hs2);
  209.    hh(C , D , A , B ,  5 , hs3);
  210.    hh(B , C , D , A , 13 , hs4);
  211.    hh(A , B , C , D ,  3 , hs1);
  212.    hh(D , A , B , C , 11 , hs2);
  213.    hh(C , D , A , B ,  7 , hs3);
  214.    hh(B , C , D , A , 15 , hs4);
  215.    MDp->buffer[0] += A;
  216.    MDp->buffer[1] += B;
  217.    MDp->buffer[2] += C;
  218.    MDp->buffer[3] += D;
  219.  }
  220.  
  221.  /* MDupdate(MDp,X,count)
  222.  ** Input: MDp -- an MDptr
  223.  **        X -- a pointer to an array of unsigned characters.
  224.  **        count -- the number of bits of X to use.
  225.  **          (if not a multiple of 8, uses high bits of last byte.)
  226.  ** Update MDp using the number of bits of X given by count.
  227.  ** This is the basic input routine for an MD4 user.
  228.  ** The routine completes the MD computation when count < 512, so
  229.  ** every MD computation should end with one call to MDupdate with a
  230.  ** count less than 512.  A call with count 0 will be ignored if the
  231.  ** MD has already been terminated (done != 0), so an extra call with
  232.  ** count 0 can be given as a "courtesy close" to force termination
  233.  ** if desired.
  234.  */
  235.  void
  236.  MDupdate(MDp,X,count)
  237.  MDptr MDp;
  238.  unsigned char *X;
  239.  unsigned int count;
  240.  { unsigned int i, tmp, bit, byte, mask;
  241.    unsigned char XX[64];
  242.    unsigned char *p;
  243.    /* return with no error if this is a courtesy close with count
  244.    ** zero and MDp->done is true.
  245.    */
  246.    if (count == 0 && MDp->done) return;
  247.    /* check to see if MD is already done and report error */
  248.    if (MDp->done)
  249.           { printf("\nError: MDupdate MD already done."); return; }
  250.    /* Add count to MDp->count */
  251.    tmp = count;
  252.    p = MDp->count;
  253.    while (tmp)
  254.      { tmp += *p;
  255.        *p++ = tmp;
  256.        tmp = tmp >> 8;
  257.      }
  258.    /* Process data */
  259.    if (count == 512)
  260.      { /* Full block of data to handle */
  261.        MDblock(MDp,(unsigned int *)X);
  262.      }
  263.    else if (count > 512) /* Check for count too large */
  264.      { printf("\nError: MDupdate called with illegal count value %d."
  265.               ,count);
  266.        return;
  267.      }
  268.    else /* partial block -- must be last block so finish up */
  269.      { /* Find out how many bytes and residual bits there are */
  270.        byte = count >> 3;
  271.        bit =  count & 7;
  272.        /* Copy X into XX since we need to modify it */
  273.        for (i=0;i<=byte;i++)   XX[i] = X[i];
  274.        for (i=byte+1;i<64;i++) XX[i] = 0;
  275.        /* Add padding '1' bit and low-order zeros in last byte */
  276.        mask = 1 << (7 - bit);
  277.        XX[byte] = (XX[byte] | mask) & ~( mask - 1);
  278.        /* If room for bit count, finish up with this block */
  279.        if (byte <= 55)
  280.          { for (i=0;i<8;i++) XX[56+i] = MDp->count[i];
  281.            MDblock(MDp,(unsigned int *)XX);
  282.          }
  283.        else /* need to do two blocks to finish up */
  284.          { MDblock(MDp,(unsigned int *)XX);
  285.            for (i=0;i<56;i++) XX[i] = 0;
  286.            for (i=0;i<8;i++)  XX[56+i] = MDp->count[i];
  287.            MDblock(MDp,(unsigned int *)XX);
  288.          }
  289.        /* Set flag saying we're done with MD computation */
  290.        MDp->done = 1;
  291.      }
  292.  }
  293.  
  294.  /*
  295.  ** End of md4.c
  296.  */
  297. #else
  298.  void md4_dummy() {;}
  299. #endif
  300.