Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygencrypt_md4.c
Go to the documentation of this file.
00001 /* 00002 * Copyright (C) 2001 Nikos Mavroyanopoulos 00003 * Copyright (C) 2004 Hans Leidekker 00004 * 00005 * This library is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU Lesser General Public 00007 * License as published by the Free Software Foundation; either 00008 * version 2.1 of the License, or (at your option) any later version. 00009 * 00010 * This library is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Lesser General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Lesser General Public 00016 * License along with this library; if not, write to the Free Software 00017 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00018 */ 00019 00020 /* 00021 * This code implements the MD4 message-digest algorithm. 00022 * It is based on code in the public domain written by Colin 00023 * Plumb in 1993. The algorithm is due to Ron Rivest. 00024 * 00025 * Equivalent code is available from RSA Data Security, Inc. 00026 * This code has been tested against that, and is equivalent, 00027 * except that you don't need to include two pages of legalese 00028 * with every copy. 00029 * 00030 * To compute the message digest of a chunk of bytes, declare an 00031 * MD4_CTX structure, pass it to MD4Init, call MD4Update as 00032 * needed on buffers full of bytes, and then call MD4Final, which 00033 * will fill a supplied 16-byte array with the digest. 00034 */ 00035 00036 #include <advapi32.h> 00037 00038 /* The three core functions */ 00039 00040 #define rotl32(x,n) (((x) << ((unsigned int)(n))) | ((x) >> (32 - (unsigned int)(n)))) 00041 00042 #define F( x, y, z ) (((x) & (y)) | ((~x) & (z))) 00043 #define G( x, y, z ) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) 00044 #define H( x, y, z ) ((x) ^ (y) ^ (z)) 00045 00046 #define FF( a, b, c, d, x, s ) { \ 00047 (a) += F( (b), (c), (d) ) + (x); \ 00048 (a) = rotl32( (a), (s) ); \ 00049 } 00050 #define GG( a, b, c, d, x, s ) { \ 00051 (a) += G( (b), (c), (d) ) + (x) + (unsigned int)0x5a827999; \ 00052 (a) = rotl32( (a), (s) ); \ 00053 } 00054 #define HH( a, b, c, d, x, s ) { \ 00055 (a) += H( (b), (c), (d) ) + (x) + (unsigned int)0x6ed9eba1; \ 00056 (a) = rotl32( (a), (s) ); \ 00057 } 00058 00059 /* 00060 * The core of the MD4 algorithm 00061 */ 00062 static void MD4Transform( unsigned int buf[4], const unsigned int in[16] ) 00063 { 00064 register unsigned int a, b, c, d; 00065 00066 a = buf[0]; 00067 b = buf[1]; 00068 c = buf[2]; 00069 d = buf[3]; 00070 00071 FF( a, b, c, d, in[0], 3 ); 00072 FF( d, a, b, c, in[1], 7 ); 00073 FF( c, d, a, b, in[2], 11 ); 00074 FF( b, c, d, a, in[3], 19 ); 00075 FF( a, b, c, d, in[4], 3 ); 00076 FF( d, a, b, c, in[5], 7 ); 00077 FF( c, d, a, b, in[6], 11 ); 00078 FF( b, c, d, a, in[7], 19 ); 00079 FF( a, b, c, d, in[8], 3 ); 00080 FF( d, a, b, c, in[9], 7 ); 00081 FF( c, d, a, b, in[10], 11 ); 00082 FF( b, c, d, a, in[11], 19 ); 00083 FF( a, b, c, d, in[12], 3 ); 00084 FF( d, a, b, c, in[13], 7 ); 00085 FF( c, d, a, b, in[14], 11 ); 00086 FF( b, c, d, a, in[15], 19 ); 00087 00088 GG( a, b, c, d, in[0], 3 ); 00089 GG( d, a, b, c, in[4], 5 ); 00090 GG( c, d, a, b, in[8], 9 ); 00091 GG( b, c, d, a, in[12], 13 ); 00092 GG( a, b, c, d, in[1], 3 ); 00093 GG( d, a, b, c, in[5], 5 ); 00094 GG( c, d, a, b, in[9], 9 ); 00095 GG( b, c, d, a, in[13], 13 ); 00096 GG( a, b, c, d, in[2], 3 ); 00097 GG( d, a, b, c, in[6], 5 ); 00098 GG( c, d, a, b, in[10], 9 ); 00099 GG( b, c, d, a, in[14], 13 ); 00100 GG( a, b, c, d, in[3], 3 ); 00101 GG( d, a, b, c, in[7], 5 ); 00102 GG( c, d, a, b, in[11], 9 ); 00103 GG( b, c, d, a, in[15], 13 ); 00104 00105 HH( a, b, c, d, in[0], 3 ); 00106 HH( d, a, b, c, in[8], 9 ); 00107 HH( c, d, a, b, in[4], 11 ); 00108 HH( b, c, d, a, in[12], 15 ); 00109 HH( a, b, c, d, in[2], 3 ); 00110 HH( d, a, b, c, in[10], 9 ); 00111 HH( c, d, a, b, in[6], 11 ); 00112 HH( b, c, d, a, in[14], 15 ); 00113 HH( a, b, c, d, in[1], 3 ); 00114 HH( d, a, b, c, in[9], 9 ); 00115 HH( c, d, a, b, in[5], 11 ); 00116 HH( b, c, d, a, in[13], 15 ); 00117 HH( a, b, c, d, in[3], 3 ); 00118 HH( d, a, b, c, in[11], 9 ); 00119 HH( c, d, a, b, in[7], 11 ); 00120 HH( b, c, d, a, in[15], 15 ); 00121 00122 buf[0] += a; 00123 buf[1] += b; 00124 buf[2] += c; 00125 buf[3] += d; 00126 } 00127 00128 /* 00129 * Start MD4 accumulation. Set bit count to 0 and buffer to mysterious 00130 * initialization constants. 00131 */ 00132 VOID WINAPI MD4Init( MD4_CTX *ctx ) 00133 { 00134 ctx->buf[0] = 0x67452301; 00135 ctx->buf[1] = 0xefcdab89; 00136 ctx->buf[2] = 0x98badcfe; 00137 ctx->buf[3] = 0x10325476; 00138 00139 ctx->i[0] = ctx->i[1] = 0; 00140 } 00141 00142 /* 00143 * Update context to reflect the concatenation of another buffer full 00144 * of bytes. 00145 */ 00146 VOID WINAPI MD4Update( MD4_CTX *ctx, const unsigned char *buf, unsigned int len ) 00147 { 00148 register unsigned int t; 00149 00150 /* Update bitcount */ 00151 t = ctx->i[0]; 00152 00153 if ((ctx->i[0] = t + (len << 3)) < t) 00154 ctx->i[1]++; /* Carry from low to high */ 00155 00156 ctx->i[1] += len >> 29; 00157 t = (t >> 3) & 0x3f; 00158 00159 /* Handle any leading odd-sized chunks */ 00160 if (t) 00161 { 00162 unsigned char *p = (unsigned char *)ctx->in + t; 00163 t = 64 - t; 00164 00165 if (len < t) 00166 { 00167 memcpy( p, buf, len ); 00168 return; 00169 } 00170 00171 memcpy( p, buf, t ); 00172 byteReverse( ctx->in, 16 ); 00173 00174 MD4Transform( ctx->buf, (unsigned int *)ctx->in ); 00175 00176 buf += t; 00177 len -= t; 00178 } 00179 00180 /* Process data in 64-byte chunks */ 00181 while (len >= 64) 00182 { 00183 memcpy( ctx->in, buf, 64 ); 00184 byteReverse( ctx->in, 16 ); 00185 00186 MD4Transform( ctx->buf, (unsigned int *)ctx->in ); 00187 00188 buf += 64; 00189 len -= 64; 00190 } 00191 00192 /* Handle any remaining bytes of data. */ 00193 memcpy( ctx->in, buf, len ); 00194 } 00195 00196 /* 00197 * Final wrapup - pad to 64-byte boundary with the bit pattern 00198 * 1 0* (64-bit count of bits processed, MSB-first) 00199 */ 00200 VOID WINAPI MD4Final( MD4_CTX *ctx ) 00201 { 00202 unsigned int count; 00203 unsigned char *p; 00204 00205 /* Compute number of bytes mod 64 */ 00206 count = (ctx->i[0] >> 3) & 0x3F; 00207 00208 /* Set the first char of padding to 0x80. This is safe since there is 00209 always at least one byte free */ 00210 p = ctx->in + count; 00211 *p++ = 0x80; 00212 00213 /* Bytes of padding needed to make 64 bytes */ 00214 count = 64 - 1 - count; 00215 00216 /* Pad out to 56 mod 64 */ 00217 if (count < 8) 00218 { 00219 /* Two lots of padding: Pad the first block to 64 bytes */ 00220 memset( p, 0, count ); 00221 byteReverse( ctx->in, 16 ); 00222 MD4Transform( ctx->buf, (unsigned int *)ctx->in ); 00223 00224 /* Now fill the next block with 56 bytes */ 00225 memset( ctx->in, 0, 56 ); 00226 } 00227 else 00228 { 00229 /* Pad block to 56 bytes */ 00230 memset( p, 0, count - 8 ); 00231 } 00232 00233 byteReverse( ctx->in, 14 ); 00234 00235 /* Append length in bits and transform */ 00236 ((unsigned int *)ctx->in)[14] = ctx->i[0]; 00237 ((unsigned int *)ctx->in)[15] = ctx->i[1]; 00238 00239 MD4Transform( ctx->buf, (unsigned int *)ctx->in ); 00240 byteReverse( (unsigned char *)ctx->buf, 4 ); 00241 memcpy( ctx->digest, ctx->buf, 16 ); 00242 } Generated on Sat May 26 2012 04:21:08 for ReactOS by
1.7.6.1
|