home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / HPACK78S.ZIP / crypt / md5.c < prev    next >
C/C++ Source or Header  |  1992-11-12  |  21KB  |  588 lines

  1. /****************************************************************************
  2. *                                                                            *
  3. *                            HPACK Multi-System Archiver                        *
  4. *                            ===========================                        *
  5. *                                                                            *
  6. *                              MD5 Message Digest Code                        *
  7. *                              MD5.C  Updated 02/10/91                        *
  8. *                                                                            *
  9. * This program is protected by copyright and as such any use or copying of    *
  10. *  this code for your own purposes directly or indirectly is highly uncool    *
  11. *                      and if you do so there will be....trubble.                *
  12. *                 And remember: We know where your kids go to school.            *
  13. *                                                                            *
  14. *            Copyright 1991  Peter C.Gutmann.  All rights reserved            *
  15. *                                                                            *
  16. ****************************************************************************/
  17.  
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #ifdef __MAC__
  21.   #include "md5.h"
  22. #else
  23.   #include "crypt/md5.h"
  24. #endif /* __MAC__ */
  25.  
  26. /****************************************************************************
  27. *                                                                            *
  28. *    Implementation RSA Data Security, Inc. MD5 Message-Digest Algorithm        *
  29. *    Created 2/17/90 RLR, revised 1/91 SRD,AJ,BSK,JT Reference C Version        *
  30. *      Copyright (C) 1990, RSA Data Security, Inc. All rights reserved        *
  31. *                                                                            *
  32. ****************************************************************************/
  33.  
  34. /* Define the following to use the assembly-language version of MDTransform().
  35.    This is desirable since MDTransform() uses many rotates which cannot be
  36.    easily represented in C and must be done inefficiently via shifts */
  37.  
  38. #ifdef __MSDOS__
  39.   #define ASM_MD5
  40. #endif /* __MSDOS__ */
  41.  
  42. #ifdef ASM_MD5
  43.   void MD5Transform( LONG *buf, LONG *in );
  44. #endif /* ASM_MD5 */
  45.  
  46. /* To form the message digest for a message M, initialize a context buffer
  47.    mdContext using MD5Init(); call MD5Update() on mdContext and M; and call
  48.    MD5Final() on mdContext.  The message digest is now in
  49.    mdContext->digest[ 0 ... 15 ] */
  50.  
  51. /****************************************************************************
  52. *                                                                            *
  53. *                            The MD5 Transformation                            *
  54. *                                                                            *
  55. ****************************************************************************/
  56.  
  57. /* The Mysterious Constants used in the MD5 transformation */
  58.  
  59. static LONG md5const[] = { 3614090360L, 3905402710L,  606105819L, 3250441966L,
  60.                            4118548399L, 1200080426L, 2821735955L, 4249261313L,
  61.                            1770035416L, 2336552879L, 4294925233L, 2304563134L,
  62.                            1804603682L, 4254626195L, 2792965006L, 1236535329L,
  63.                            4129170786L, 3225465664L,  643717713L, 3921069994L,
  64.                            3593408605L,   38016083L, 3634488961L, 3889429448L,
  65.                             568446438L, 3275163606L, 4107603335L, 1163531501L,
  66.                            2850285829L, 4243563512L, 1735328473L, 2368359562L,
  67.                            4294588738L, 2272392833L, 1839030562L, 4259657740L,
  68.                            2763975236L, 1272893353L, 4139469664L, 3200236656L,
  69.                             681279174L, 3936430074L, 3572445317L,   76029189L,
  70.                            3654602809L, 3873151461L,  530742520L, 3299628645L,
  71.                            4096336452L, 1126891415L, 2878612391L, 4237533241L,
  72.                            1700485571L, 2399980690L, 4293915773L, 2240044497L,
  73.                            1873313359L, 4264355552L, 2734768916L, 1309151649L,
  74.                            4149444226L, 3174756917L,  718787259L, 3951481745L };
  75. /* Storage for the Mysterious Constants (either md5const or user-defined) */
  76.  
  77. LONG mConst[ MD5_ROUNDS ];
  78.  
  79. #ifndef ASM_MD5
  80.  
  81. /* F, G, H and I are basic MD5 functions */
  82.  
  83. #define F(X,Y,Z)    ( ( X & Y ) | ( ~X & Z ) )
  84. #define G(X,Y,Z)    ( ( X & Z ) | ( Y & ~Z ) )
  85. #define H(X,Y,Z)    ( X ^ Y ^ Z )
  86. #define I(X,Y,Z)    ( Y ^ ( X | ~Z ) )
  87.  
  88. /* ROTATE_LEFT rotates x left n bits */
  89.  
  90. #define ROTATE_LEFT(x,n)    ( ( x << n ) | ( x >> ( 32 - n ) ) )
  91.  
  92. /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.  Rotation is
  93.    separate from addition to prevent recomputation */
  94.  
  95. #define FF(A,B,C,D,X,shiftAmt,magicConst) \
  96.     { \
  97.     A += F( B, C, D ) + X + magicConst; \
  98.     A = ROTATE_LEFT( A, shiftAmt ); \
  99.     A += B; \
  100.     }
  101.  
  102. #define GG(A,B,C,D,X,shiftAmt,magicConst) \
  103.     { \
  104.     A += G( B, C, D ) + X + magicConst; \
  105.     A = ROTATE_LEFT( A, shiftAmt ); \
  106.     A += B; \
  107.     }
  108.  
  109. #define HH(A,B,C,D,X,shiftAmt,magicConst) \
  110.     { \
  111.     A += H( B, C, D ) + X + magicConst; \
  112.     A = ROTATE_LEFT( A, shiftAmt ); \
  113.     A += B; \
  114.     }
  115.  
  116. #define II(A,B,C,D,X,shiftAmt,magicConst) \
  117.     { \
  118.     A += I( B, C, D ) + X + magicConst; \
  119.     A = ROTATE_LEFT( A, shiftAmt ); \
  120.     A += B; \
  121.     }
  122.  
  123. /* Round 1 shift amounts */
  124.  
  125. #define S11    7
  126. #define S12    12
  127. #define S13    17
  128. #define S14    22
  129.  
  130. /* Round 2 shift amounts */
  131.  
  132. #define S21 5
  133. #define S22 9
  134. #define S23 14
  135. #define S24 20
  136.  
  137. /* Round 3 shift amounts */
  138.  
  139. #define S31 4
  140. #define S32 11
  141. #define S33 16
  142. #define S34 23
  143.  
  144. /* Round 4 shift amounts */
  145.  
  146. #define S41 6
  147. #define S42 10
  148. #define S43 15
  149. #define S44 21
  150.  
  151. /* Basic MD5 step. Transforms buf based on in.  Note that if the Mysterious
  152.    Constants are arranged backwards in little-endian order and decrypted with
  153.    the DES they produce OCCULT MESSAGES! */
  154.  
  155. #if defined( __ARC__ ) || defined( IRIX ) || defined( __TSC__ ) || defined( VCC )
  156.  
  157. /* MD5Transform is split into its component rounds since many optimizers
  158.    choke on the grand unified version */
  159.  
  160. static void MD5TransformRound1( LONG *A, LONG *B, LONG *C, LONG *D, LONG *in )
  161.     {
  162.     /* Round 1 */
  163.     FF( *A, *B, *C, *D, in[  0 ], S11, mConst[  0 ] );    /*  1 */
  164.     FF( *D, *A, *B, *C, in[  1 ], S12, mConst[  1 ] );    /*  2 */
  165.     FF( *C, *D, *A, *B, in[  2 ], S13, mConst[  2 ] );    /*  3 */
  166.     FF( *B, *C, *D, *A, in[  3 ], S14, mConst[  3 ] );    /*  4 */
  167.     FF( *A, *B, *C, *D, in[  4 ], S11, mConst[  4 ] );    /*  5 */
  168.     FF( *D, *A, *B, *C, in[  5 ], S12, mConst[  5 ] );    /*  6 */
  169.     FF( *C, *D, *A, *B, in[  6 ], S13, mConst[  6 ] );    /*  7 */
  170.     FF( *B, *C, *D, *A, in[  7 ], S14, mConst[  7 ] );    /*  8 */
  171.     FF( *A, *B, *C, *D, in[  8 ], S11, mConst[  8 ] );    /*  9 */
  172.     FF( *D, *A, *B, *C, in[  9 ], S12, mConst[  9 ] );    /* 10 */
  173.     FF( *C, *D, *A, *B, in[ 10 ], S13, mConst[ 10 ] );    /* 11 */
  174.     FF( *B, *C, *D, *A, in[ 11 ], S14, mConst[ 11 ] );    /* 12 */
  175.     FF( *A, *B, *C, *D, in[ 12 ], S11, mConst[ 12 ] );    /* 13 */
  176.     FF( *D, *A, *B, *C, in[ 13 ], S12, mConst[ 13 ] );    /* 14 */
  177.     FF( *C, *D, *A, *B, in[ 14 ], S13, mConst[ 14 ] );    /* 15 */
  178.     FF( *B, *C, *D, *A, in[ 15 ], S14, mConst[ 15 ] );    /* 16 */
  179.     }
  180.  
  181. static void MD5TransformRound2( LONG *A, LONG *B, LONG *C, LONG *D, LONG *in )
  182.     {
  183.     /* Round 2 */
  184.     GG( *A, *B, *C, *D, in[  1 ], S21, mConst[ 16 ] );    /* 17 */
  185.     GG( *D, *A, *B, *C, in[  6 ], S22, mConst[ 17 ] );    /* 18 */
  186.     GG( *C, *D, *A, *B, in[ 11 ], S23, mConst[ 18 ] );    /* 19 */
  187.     GG( *B, *C, *D, *A, in[  0 ], S24, mConst[ 19 ] );    /* 20 */
  188.     GG( *A, *B, *C, *D, in[  5 ], S21, mConst[ 20 ] );    /* 21 */
  189.     GG( *D, *A, *B, *C, in[ 10 ], S22, mConst[ 21 ] );    /* 22 */
  190.     GG( *C, *D, *A, *B, in[ 15 ], S23, mConst[ 22 ] );    /* 23 */
  191.     GG( *B, *C, *D, *A, in[  4 ], S24, mConst[ 23 ] );    /* 24 */
  192.     GG( *A, *B, *C, *D, in[  9 ], S21, mConst[ 24 ] );    /* 25 */
  193.     GG( *D, *A, *B, *C, in[ 14 ], S22, mConst[ 25 ] );    /* 26 */
  194.     GG( *C, *D, *A, *B, in[  3 ], S23, mConst[ 26 ] );    /* 27 */
  195.     GG( *B, *C, *D, *A, in[  8 ], S24, mConst[ 27 ] );    /* 28 */
  196.     GG( *A, *B, *C, *D, in[ 13 ], S21, mConst[ 28 ] );    /* 29 */
  197.     GG( *D, *A, *B, *C, in[  2 ], S22, mConst[ 29 ] );    /* 30 */
  198.     GG( *C, *D, *A, *B, in[  7 ], S23, mConst[ 30 ] );    /* 31 */
  199.     GG( *B, *C, *D, *A, in[ 12 ], S24, mConst[ 31 ] );    /* 32 */
  200.     }
  201.  
  202. static void MD5TransformRound3( LONG *A, LONG *B, LONG *C, LONG *D, LONG *in )
  203.     {
  204.     /* Round 3 */
  205.     HH( *A, *B, *C, *D, in[  5 ], S31, mConst[ 32 ] );    /* 33 */
  206.     HH( *D, *A, *B, *C, in[  8 ], S32, mConst[ 33 ] );    /* 34 */
  207.     HH( *C, *D, *A, *B, in[ 11 ], S33, mConst[ 34 ] );    /* 35 */
  208.     HH( *B, *C, *D, *A, in[ 14 ], S34, mConst[ 35 ] );    /* 36 */
  209.     HH( *A, *B, *C, *D, in[  1 ], S31, mConst[ 36 ] );    /* 37 */
  210.     HH( *D, *A, *B, *C, in[  4 ], S32, mConst[ 37 ] );    /* 38 */
  211.     HH( *C, *D, *A, *B, in[  7 ], S33, mConst[ 38 ] );    /* 39 */
  212.     HH( *B, *C, *D, *A, in[ 10 ], S34, mConst[ 39 ] );    /* 40 */
  213.     HH( *A, *B, *C, *D, in[ 13 ], S31, mConst[ 40 ] );    /* 41 */
  214.     HH( *D, *A, *B, *C, in[  0 ], S32, mConst[ 41 ] );    /* 42 */
  215.     HH( *C, *D, *A, *B, in[  3 ], S33, mConst[ 42 ] );    /* 43 */
  216.     HH( *B, *C, *D, *A, in[  6 ], S34, mConst[ 43 ] );    /* 44 */
  217.     HH( *A, *B, *C, *D, in[  9 ], S31, mConst[ 44 ] );    /* 45 */
  218.     HH( *D, *A, *B, *C, in[ 12 ], S32, mConst[ 45 ] );    /* 46 */
  219.     HH( *C, *D, *A, *B, in[ 15 ], S33, mConst[ 46 ] );    /* 47 */
  220.     HH( *B, *C, *D, *A, in[  2 ], S34, mConst[ 47 ] );    /* 48 */
  221.     }
  222.  
  223. static void MD5TransformRound4( LONG *A, LONG *B, LONG *C, LONG *D, LONG *in )
  224.     {
  225.     /* Round 4 */
  226.     II( *A, *B, *C, *D, in[  0 ], S41, mConst[ 48 ] );    /* 49 */
  227.     II( *D, *A, *B, *C, in[  7 ], S42, mConst[ 49 ] );    /* 50 */
  228.     II( *C, *D, *A, *B, in[ 14 ], S43, mConst[ 50 ] );    /* 51 */
  229.     II( *B, *C, *D, *A, in[  5 ], S44, mConst[ 51 ] );    /* 52 */
  230.     II( *A, *B, *C, *D, in[ 12 ], S41, mConst[ 52 ] );    /* 53 */
  231.     II( *D, *A, *B, *C, in[  3 ], S42, mConst[ 53 ] );    /* 54 */
  232.     II( *C, *D, *A, *B, in[ 10 ], S43, mConst[ 54 ] );    /* 55 */
  233.     II( *B, *C, *D, *A, in[  1 ], S44, mConst[ 55 ] );    /* 56 */
  234.     II( *A, *B, *C, *D, in[  8 ], S41, mConst[ 56 ] );    /* 57 */
  235.     II( *D, *A, *B, *C, in[ 15 ], S42, mConst[ 57 ] );    /* 58 */
  236.     II( *C, *D, *A, *B, in[  6 ], S43, mConst[ 58 ] );    /* 59 */
  237.     II( *B, *C, *D, *A, in[ 13 ], S44, mConst[ 59 ] );    /* 60 */
  238.     II( *A, *B, *C, *D, in[  4 ], S41, mConst[ 60 ] );    /* 61 */
  239.     II( *D, *A, *B, *C, in[ 11 ], S42, mConst[ 61 ] );    /* 62 */
  240.     II( *C, *D, *A, *B, in[  2 ], S43, mConst[ 62 ] );    /* 63 */
  241.     II( *B, *C, *D, *A, in[  9 ], S44, mConst[ 63 ] );    /* 64 */
  242.     }
  243.  
  244. void MD5Transform( LONG *buf, LONG *in )
  245.     {
  246.     LONG A = buf[ 0 ], B = buf[ 1 ], C = buf[ 2 ], D = buf[ 3 ];
  247.  
  248.     MD5TransformRound1 (&A, &B, &C, &D, in);
  249.     MD5TransformRound2 (&A, &B, &C, &D, in);
  250.     MD5TransformRound3 (&A, &B, &C, &D, in);
  251.     MD5TransformRound4 (&A, &B, &C, &D, in);
  252.  
  253.     buf[ 0 ] += A;
  254.     buf[ 1 ] += B;
  255.     buf[ 2 ] += C;
  256.     buf[ 3 ] += D;
  257.     }
  258.  
  259. #else
  260.  
  261. void MD5Transform( LONG *buf, LONG *in )
  262.     {
  263.     LONG A = buf[ 0 ], B = buf[ 1 ], C = buf[ 2 ], D = buf[ 3 ];
  264.  
  265.     /* Round 1 */
  266.     FF( A, B, C, D, in[  0 ], S11, mConst[  0 ] );    /*  1 */
  267.     FF( D, A, B, C, in[  1 ], S12, mConst[  1 ] );    /*  2 */
  268.     FF( C, D, A, B, in[  2 ], S13, mConst[  2 ] );    /*  3 */
  269.     FF( B, C, D, A, in[  3 ], S14, mConst[  3 ] );    /*  4 */
  270.     FF( A, B, C, D, in[  4 ], S11, mConst[  4 ] );    /*  5 */
  271.     FF( D, A, B, C, in[  5 ], S12, mConst[  5 ] );    /*  6 */
  272.     FF( C, D, A, B, in[  6 ], S13, mConst[  6 ] );    /*  7 */
  273.     FF( B, C, D, A, in[  7 ], S14, mConst[  7 ] );    /*  8 */
  274.     FF( A, B, C, D, in[  8 ], S11, mConst[  8 ] );    /*  9 */
  275.     FF( D, A, B, C, in[  9 ], S12, mConst[  9 ] );    /* 10 */
  276.     FF( C, D, A, B, in[ 10 ], S13, mConst[ 10 ] );    /* 11 */
  277.     FF( B, C, D, A, in[ 11 ], S14, mConst[ 11 ] );    /* 12 */
  278.     FF( A, B, C, D, in[ 12 ], S11, mConst[ 12 ] );    /* 13 */
  279.     FF( D, A, B, C, in[ 13 ], S12, mConst[ 13 ] );    /* 14 */
  280.     FF( C, D, A, B, in[ 14 ], S13, mConst[ 14 ] );    /* 15 */
  281.     FF( B, C, D, A, in[ 15 ], S14, mConst[ 15 ] );    /* 16 */
  282.  
  283.     /* Round 2 */
  284.     GG( A, B, C, D, in[  1 ], S21, mConst[ 16 ] );    /* 17 */
  285.     GG( D, A, B, C, in[  6 ], S22, mConst[ 17 ] );    /* 18 */
  286.     GG( C, D, A, B, in[ 11 ], S23, mConst[ 18 ] );    /* 19 */
  287.     GG( B, C, D, A, in[  0 ], S24, mConst[ 19 ] );    /* 20 */
  288.     GG( A, B, C, D, in[  5 ], S21, mConst[ 20 ] );    /* 21 */
  289.     GG( D, A, B, C, in[ 10 ], S22, mConst[ 21 ] );    /* 22 */
  290.     GG( C, D, A, B, in[ 15 ], S23, mConst[ 22 ] );    /* 23 */
  291.     GG( B, C, D, A, in[  4 ], S24, mConst[ 23 ] );    /* 24 */
  292.     GG( A, B, C, D, in[  9 ], S21, mConst[ 24 ] );    /* 25 */
  293.     GG( D, A, B, C, in[ 14 ], S22, mConst[ 25 ] );    /* 26 */
  294.     GG( C, D, A, B, in[  3 ], S23, mConst[ 26 ] );    /* 27 */
  295.     GG( B, C, D, A, in[  8 ], S24, mConst[ 27 ] );    /* 28 */
  296.     GG( A, B, C, D, in[ 13 ], S21, mConst[ 28 ] );    /* 29 */
  297.     GG( D, A, B, C, in[  2 ], S22, mConst[ 29 ] );    /* 30 */
  298.     GG( C, D, A, B, in[  7 ], S23, mConst[ 30 ] );    /* 31 */
  299.     GG( B, C, D, A, in[ 12 ], S24, mConst[ 31 ] );    /* 32 */
  300.  
  301.     /* Round 3 */
  302.     HH( A, B, C, D, in[  5 ], S31, mConst[ 32 ] );    /* 33 */
  303.     HH( D, A, B, C, in[  8 ], S32, mConst[ 33 ] );    /* 34 */
  304.     HH( C, D, A, B, in[ 11 ], S33, mConst[ 34 ] );    /* 35 */
  305.     HH( B, C, D, A, in[ 14 ], S34, mConst[ 35 ] );    /* 36 */
  306.     HH( A, B, C, D, in[  1 ], S31, mConst[ 36 ] );    /* 37 */
  307.     HH( D, A, B, C, in[  4 ], S32, mConst[ 37 ] );    /* 38 */
  308.     HH( C, D, A, B, in[  7 ], S33, mConst[ 38 ] );    /* 39 */
  309.     HH( B, C, D, A, in[ 10 ], S34, mConst[ 39 ] );    /* 40 */
  310.     HH( A, B, C, D, in[ 13 ], S31, mConst[ 40 ] );    /* 41 */
  311.     HH( D, A, B, C, in[  0 ], S32, mConst[ 41 ] );    /* 42 */
  312.     HH( C, D, A, B, in[  3 ], S33, mConst[ 42 ] );    /* 43 */
  313.     HH( B, C, D, A, in[  6 ], S34, mConst[ 43 ] );    /* 44 */
  314.     HH( A, B, C, D, in[  9 ], S31, mConst[ 44 ] );    /* 45 */
  315.     HH( D, A, B, C, in[ 12 ], S32, mConst[ 45 ] );    /* 46 */
  316.     HH( C, D, A, B, in[ 15 ], S33, mConst[ 46 ] );    /* 47 */
  317.     HH( B, C, D, A, in[  2 ], S34, mConst[ 47 ] );    /* 48 */
  318.  
  319.     /* Round 4 */
  320.     II( A, B, C, D, in[  0 ], S41, mConst[ 48 ] );    /* 49 */
  321.     II( D, A, B, C, in[  7 ], S42, mConst[ 49 ] );    /* 50 */
  322.     II( C, D, A, B, in[ 14 ], S43, mConst[ 50 ] );    /* 51 */
  323.     II( B, C, D, A, in[  5 ], S44, mConst[ 51 ] );    /* 52 */
  324.     II( A, B, C, D, in[ 12 ], S41, mConst[ 52 ] );    /* 53 */
  325.     II( D, A, B, C, in[  3 ], S42, mConst[ 53 ] );    /* 54 */
  326.     II( C, D, A, B, in[ 10 ], S43, mConst[ 54 ] );    /* 55 */
  327.     II( B, C, D, A, in[  1 ], S44, mConst[ 55 ] );    /* 56 */
  328.     II( A, B, C, D, in[  8 ], S41, mConst[ 56 ] );    /* 57 */
  329.     II( D, A, B, C, in[ 15 ], S42, mConst[ 57 ] );    /* 58 */
  330.     II( C, D, A, B, in[  6 ], S43, mConst[ 58 ] );    /* 59 */
  331.     II( B, C, D, A, in[ 13 ], S44, mConst[ 59 ] );    /* 60 */
  332.     II( A, B, C, D, in[  4 ], S41, mConst[ 60 ] );    /* 61 */
  333.     II( D, A, B, C, in[ 11 ], S42, mConst[ 61 ] );    /* 62 */
  334.     II( C, D, A, B, in[  2 ], S43, mConst[ 62 ] );    /* 63 */
  335.     II( B, C, D, A, in[  9 ], S44, mConst[ 63 ] );    /* 64 */
  336.  
  337.     buf[ 0 ] += A;
  338.     buf[ 1 ] += B;
  339.     buf[ 2 ] += C;
  340.     buf[ 3 ] += D;
  341.     }
  342. #endif /* __ARC__ || IRIX || __TSC__ || VCC */
  343.  
  344. #endif /* ASM_MD5 */
  345.  
  346. /****************************************************************************
  347. *                                                                            *
  348. *                            MD5 Support Routines                            *
  349. *                                                                            *
  350. ****************************************************************************/
  351.  
  352. #ifdef LITTLE_ENDIAN
  353.  
  354. #ifdef ASM_MD5
  355.   void longReverse( LONG *buffer, int byteCount );
  356. #else
  357.  
  358. /* When run on a little-endian CPU we need to perform byte reversal on an
  359.    array of longwords.  It is possible to make the code endianness-
  360.    independant by fiddling around with data at the byte level, but this
  361.    makes for very slow code, so we rely on the user to sort out endianness
  362.    at compile time */
  363.  
  364. void longReverse( LONG *buffer, int byteCount )
  365.     {
  366.     LONG value;
  367.  
  368.     byteCount /= sizeof( LONG );
  369.     while( byteCount-- )
  370.         {
  371.         value = ( *buffer << 16 ) | ( *buffer >> 16 );
  372.         *buffer++ = ( ( value & 0xFF00FF00L ) >> 8 ) | ( ( value & 0x00FF00FFL ) << 8 );
  373.         }
  374.     }
  375. #endif /* ASM_MD5 */
  376.  
  377. #endif /* LITTLE_ENDIAN */
  378.  
  379. /* The external buffer for saving the Mysterious Constants.  Since the MD5/
  380.    MDC code is dual-use, we need to save the constants whenever we switch
  381.    from MDC to MD5 */
  382.  
  383. extern BYTE *cryptBuffer;
  384.  
  385. /* The routine MD5SetConst sets the Mysterious Constants to either the
  386.    standard MD5 ones or to a user-defined set for MDC */
  387.  
  388. static BOOLEAN isMD5const = FALSE;
  389.  
  390. void MD5SetConst( BYTE *buffer )
  391.     {
  392.     if( buffer == NULL )
  393.         {
  394.         /* If the constants are already set up, don't bother re-setting them */
  395.         if( !isMD5const )
  396.             {
  397.             memcpy( mConst, md5const, MD5_ROUNDS * sizeof( LONG ) );
  398.             isMD5const = TRUE;
  399.             }
  400.         }
  401.     else
  402.         {
  403.         /* Copy the values to the mConst array, with endianness conversion
  404.            if necessary */
  405.         memcpy( mConst, buffer, MD5_ROUNDS * sizeof( LONG ) );
  406. #ifdef LITTLE_ENDIAN
  407.         longReverse( mConst, MD5_ROUNDS * sizeof( LONG ) );
  408. #endif /* LITTLE_ENDIAN */
  409.         isMD5const = FALSE;
  410.         }
  411.     }
  412.  
  413. /* The routine MD5Init initializes the message-digest context mdContext. All
  414.    fields are set to zero */
  415.  
  416. void MD5Init( MD5_CTX *mdContext )
  417.     {
  418.     mdContext->i[ 0 ] = mdContext->i[ 1 ] = 0L;
  419.  
  420.     /* Load magic initialization constants */
  421.     mdContext->buf[ 0 ] = 0x67452301L;
  422.     mdContext->buf[ 1 ] = 0xEFCDAB89L;
  423.     mdContext->buf[ 2 ] = 0x98BADCFEL;
  424.     mdContext->buf[ 3 ] = 0x10325476L;
  425.  
  426.     /* Set up the Mysterious Constants if necessary */
  427.     if( !isMD5const )
  428.         {
  429.         memcpy( cryptBuffer, mConst, MD5_ROUNDS * sizeof( LONG ) );
  430.         MD5SetConst( NULL );
  431.         }
  432.     }
  433.  
  434. /* The routine MD5Update updates the message-digest context to account for
  435.    the presence of each of the characters inBuf[ 0 .. inLen-1 ] in the
  436.    message whose digest is being computed.  This is an optimized version
  437.    which assumes that the buffer is a multiple of MD5_BLOCKSIZE bytes long */
  438.  
  439. #ifdef __MSDOS__
  440.  
  441. void MD5Update( MD5_CTX *mdContext, BYTE *buffer, unsigned int noBytes )
  442.     {
  443.     int bufIndex = 0;
  444.  
  445.     /* Update number of bits */
  446.     if( ( mdContext->i[ 0 ] + ( ( LONG ) noBytes << 3 ) ) < mdContext->i[ 0 ] )
  447.         mdContext->i[ 1 ]++;    /* Carry from low to high bitCount */
  448.     mdContext->i[ 0 ] += ( ( LONG ) noBytes << 3 );
  449.     mdContext->i[ 1 ] += ( ( LONG ) noBytes >> 29 );
  450.  
  451.     /* Process data in MD5_BLOCKSIZE chunks */
  452.     while( noBytes >= MD5_BLOCKSIZE )
  453.         {
  454.         MD5Transform( mdContext->buf, ( LONG * ) ( buffer + bufIndex ) );
  455.         bufIndex += MD5_BLOCKSIZE;
  456.         noBytes -= MD5_BLOCKSIZE;
  457.         }
  458.  
  459.     /* Handle any remaining bytes of data.  This should only happen once
  460.        on the final lot of data */
  461.     memcpy( mdContext->in, buffer + bufIndex, noBytes );
  462.     }
  463.  
  464. /* The routine MD5Final terminates the message-digest computation and ends
  465.    with the desired message digest in mdContext->digest[ 0 ... 15 ] */
  466.  
  467. void MD5Final( MD5_CTX *mdContext )
  468.     {
  469.     int count;
  470.     LONG lowBitcount = mdContext->i[ 0 ], highBitcount = mdContext->i[ 1 ];
  471.  
  472.     /* Compute number of bytes mod 64 */
  473.     count = ( int ) ( ( lowBitcount >> 3 ) & 0x3F );
  474.  
  475.     /* Set the first char of padding to 0x80.  This is safe since there is
  476.        always at least one byte free */
  477.     ( ( BYTE * ) mdContext->in )[ count++ ] = 0x80;
  478.  
  479.     /* Pad out to 56 mod 64 */
  480.     if( count > 56 )
  481.         {
  482.         /* Two lots of padding:  Pad the first block to 64 bytes */
  483.         memset( ( BYTE * ) &mdContext->in + count, 0, 64 - count );
  484.         MD5Transform( mdContext->buf, ( LONG * ) mdContext->in );
  485.  
  486.         /* Now fill the next block with 56 bytes */
  487.         memset( &mdContext->in, 0, 56 );
  488.         }
  489.     else
  490.         /* Pad block to 56 bytes */
  491.         memset( ( BYTE * ) &mdContext->in + count, 0, 56 - count );
  492.  
  493.     /* Append length in bits and transform */
  494.     ( ( LONG * ) mdContext->in )[ 14 ] = lowBitcount;
  495.     ( ( LONG * ) mdContext->in )[ 15 ] = highBitcount;
  496.  
  497.     MD5Transform( mdContext->buf, ( LONG * ) mdContext->in );
  498.  
  499.     /* Store buffer in digest */
  500.     memcpy( mdContext->digest, mdContext->buf, 16 );
  501.  
  502.     /* Restore the previous Mysterious Constants */
  503.     memcpy( mConst, cryptBuffer, MD5_ROUNDS * sizeof( LONG ) );
  504.     isMD5const = FALSE;
  505.     }
  506.  
  507. #else
  508.  
  509. void MD5Update( MD5_CTX *mdContext, BYTE *inBuf, unsigned int inLen )
  510.     {
  511.     int mdi;
  512.     LONG in[ 16 ];
  513.     unsigned int i, ii;
  514.  
  515.     /* Compute number of bytes mod 64 */
  516.     mdi = ( int ) ( ( mdContext->i[ 0 ] >> 3 ) & 0x3F );
  517.  
  518.     /* Update number of bits */
  519.     if( ( mdContext->i[ 0 ] + ( ( LONG ) inLen << 3 ) ) < mdContext->i[ 0 ] )
  520.         mdContext->i[ 1 ]++;    /* Carry from low to high bitCount */
  521.     mdContext->i[ 0 ] += ( ( LONG ) inLen << 3 );
  522.     mdContext->i[ 1 ] += ( ( LONG ) inLen >> 29 );
  523.  
  524.     while( inLen-- )
  525.         {
  526.         /* Add new character to buffer, increment mdi */
  527.         mdContext->in[ mdi++ ] = *inBuf++;
  528.  
  529.         /* Transform if necessary */
  530.         if( mdi == 0x40 )
  531.             {
  532.             for( i = 0, ii = 0; i < 16; i++, ii += 4 )
  533.                 in[ i ] = ( ( ( LONG ) mdContext->in[ ii + 3 ] ) << 24 ) | \
  534.                           ( ( ( LONG ) mdContext->in[ ii + 2 ] ) << 16 ) | \
  535.                           ( ( ( LONG ) mdContext->in[ ii + 1 ] ) << 8 ) | \
  536.                           ( ( LONG ) mdContext->in[ ii ] );
  537.             MD5Transform( mdContext->buf, in );
  538.             mdi = 0;
  539.             }
  540.         }
  541.     }
  542.  
  543. /* The routine MD5Final terminates the message-digest computation and ends
  544.    with the desired message digest in mdContext->digest[ 0 ... 15 ] */
  545.  
  546. void MD5Final( MD5_CTX *mdContext )
  547.     {
  548.     int mdi, padLen;
  549.     BYTE padding[ 64 ];
  550.     unsigned int i, ii;
  551.     LONG in[ 16 ];
  552.  
  553.     /* Save number of bits */
  554.     in[ 14 ] = mdContext->i[ 0 ];
  555.     in[ 15 ] = mdContext->i[ 1 ];
  556.  
  557.     /* Compute number of bytes mod 64 */
  558.     mdi = ( int ) ( ( mdContext->i[ 0 ] >> 3 ) & 0x3F );
  559.  
  560.     /* Pad out to 56 mod 64 */
  561.     padLen = ( mdi < 56 ) ? ( 56 - mdi ) : ( 120 - mdi );
  562.     padding[ 0 ] = 0x80;
  563.     memset( padding + 1, 0, padLen - 1 );
  564.     MD5Update( mdContext, padding, padLen );
  565.  
  566.     /* Append length in bits and transform */
  567.     for( i = 0, ii = 0; i < 14; i++, ii += 4 )
  568.         in[ i ] = ( ( ( LONG ) mdContext->in[ ii + 3 ] ) << 24 ) | \
  569.                   ( ( ( LONG ) mdContext->in[ ii + 2 ] ) << 16 ) | \
  570.                   ( ( ( LONG ) mdContext->in[ ii + 1 ] ) << 8 ) | \
  571.                   ( ( LONG ) mdContext->in[ ii ] );
  572.     MD5Transform( mdContext->buf, in );
  573.  
  574.     /* Store buffer in digest */
  575.     for( i = 0, ii = 0; i < 4; i++, ii += 4 )
  576.         {
  577.         mdContext->digest[ ii ] = ( BYTE ) ( mdContext->buf[ i ] & 0xFF );
  578.         mdContext->digest[ ii + 1 ] = ( BYTE ) ( ( mdContext->buf[ i ] >> 8 ) & 0xFF );
  579.         mdContext->digest[ ii + 2 ] = ( BYTE ) ( ( mdContext->buf[ i ] >> 16 ) & 0xFF );
  580.         mdContext->digest[ ii + 3 ] = ( BYTE ) ( ( mdContext->buf[ i ] >> 24 ) & 0xFF );
  581.         }
  582.  
  583.     /* Restore the previous Mysterious Constants */
  584.     memcpy( mConst, cryptBuffer, MD5_ROUNDS * sizeof( LONG ) );
  585.     isMD5const = FALSE;
  586.     }
  587. #endif /* !__MSDOS__ */
  588.