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