2 * Copyright 2001 Nikos Mavroyanopoulos
3 * Copyright 2004 Hans Leidekker
4 * Copyright 2004 Filip Navara
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26 * Based on public domain SHA code by Steve Reid <steve@edmweb.com>
36 #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
37 /* FIXME: This definition of DWORD2BE is little endian specific! */
38 #define DWORD2BE(x) (((x) >> 24) & 0xff) | (((x) >> 8) & 0xff00) | (((x) << 8) & 0xff0000) | (((x) << 24) & 0xff000000);
39 /* FIXME: This definition of blk0 is little endian specific! */
40 #define blk0(i) (Block[i] = (rol(Block[i],24)&0xFF00FF00)|(rol(Block[i],8)&0x00FF00FF))
41 #define blk1(i) (Block[i&15] = rol(Block[(i+13)&15]^Block[(i+8)&15]^Block[(i+2)&15]^Block[i&15],1))
42 #define f1(x,y,z) (z^(x&(y^z)))
43 #define f2(x,y,z) (x^y^z)
44 #define f3(x,y,z) ((x&y)|(z&(x|y)))
45 #define f4(x,y,z) (x^y^z)
46 /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
47 #define R0(v,w,x,y,z,i) z+=f1(w,x,y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
48 #define R1(v,w,x,y,z,i) z+=f1(w,x,y)+blk1(i)+0x5A827999+rol(v,5);w=rol(w,30);
49 #define R2(v,w,x,y,z,i) z+=f2(w,x,y)+blk1(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
50 #define R3(v,w,x,y,z,i) z+=f3(w,x,y)+blk1(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
51 #define R4(v,w,x,y,z,i) z+=f4(w,x,y)+blk1(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
53 /* Hash a single 512-bit block. This is the core of the algorithm. */
54 static void SHA1Transform(ULONG State
[5], UCHAR Buffer
[64])
59 Block
= (ULONG
*)Buffer
;
61 /* Copy Context->State[] to working variables */
68 /* 4 rounds of 20 operations each. Loop unrolled. */
69 R0(a
,b
,c
,d
,e
, 0); R0(e
,a
,b
,c
,d
, 1); R0(d
,e
,a
,b
,c
, 2); R0(c
,d
,e
,a
,b
, 3);
70 R0(b
,c
,d
,e
,a
, 4); R0(a
,b
,c
,d
,e
, 5); R0(e
,a
,b
,c
,d
, 6); R0(d
,e
,a
,b
,c
, 7);
71 R0(c
,d
,e
,a
,b
, 8); R0(b
,c
,d
,e
,a
, 9); R0(a
,b
,c
,d
,e
,10); R0(e
,a
,b
,c
,d
,11);
72 R0(d
,e
,a
,b
,c
,12); R0(c
,d
,e
,a
,b
,13); R0(b
,c
,d
,e
,a
,14); R0(a
,b
,c
,d
,e
,15);
73 R1(e
,a
,b
,c
,d
,16); R1(d
,e
,a
,b
,c
,17); R1(c
,d
,e
,a
,b
,18); R1(b
,c
,d
,e
,a
,19);
74 R2(a
,b
,c
,d
,e
,20); R2(e
,a
,b
,c
,d
,21); R2(d
,e
,a
,b
,c
,22); R2(c
,d
,e
,a
,b
,23);
75 R2(b
,c
,d
,e
,a
,24); R2(a
,b
,c
,d
,e
,25); R2(e
,a
,b
,c
,d
,26); R2(d
,e
,a
,b
,c
,27);
76 R2(c
,d
,e
,a
,b
,28); R2(b
,c
,d
,e
,a
,29); R2(a
,b
,c
,d
,e
,30); R2(e
,a
,b
,c
,d
,31);
77 R2(d
,e
,a
,b
,c
,32); R2(c
,d
,e
,a
,b
,33); R2(b
,c
,d
,e
,a
,34); R2(a
,b
,c
,d
,e
,35);
78 R2(e
,a
,b
,c
,d
,36); R2(d
,e
,a
,b
,c
,37); R2(c
,d
,e
,a
,b
,38); R2(b
,c
,d
,e
,a
,39);
79 R3(a
,b
,c
,d
,e
,40); R3(e
,a
,b
,c
,d
,41); R3(d
,e
,a
,b
,c
,42); R3(c
,d
,e
,a
,b
,43);
80 R3(b
,c
,d
,e
,a
,44); R3(a
,b
,c
,d
,e
,45); R3(e
,a
,b
,c
,d
,46); R3(d
,e
,a
,b
,c
,47);
81 R3(c
,d
,e
,a
,b
,48); R3(b
,c
,d
,e
,a
,49); R3(a
,b
,c
,d
,e
,50); R3(e
,a
,b
,c
,d
,51);
82 R3(d
,e
,a
,b
,c
,52); R3(c
,d
,e
,a
,b
,53); R3(b
,c
,d
,e
,a
,54); R3(a
,b
,c
,d
,e
,55);
83 R3(e
,a
,b
,c
,d
,56); R3(d
,e
,a
,b
,c
,57); R3(c
,d
,e
,a
,b
,58); R3(b
,c
,d
,e
,a
,59);
84 R4(a
,b
,c
,d
,e
,60); R4(e
,a
,b
,c
,d
,61); R4(d
,e
,a
,b
,c
,62); R4(c
,d
,e
,a
,b
,63);
85 R4(b
,c
,d
,e
,a
,64); R4(a
,b
,c
,d
,e
,65); R4(e
,a
,b
,c
,d
,66); R4(d
,e
,a
,b
,c
,67);
86 R4(c
,d
,e
,a
,b
,68); R4(b
,c
,d
,e
,a
,69); R4(a
,b
,c
,d
,e
,70); R4(e
,a
,b
,c
,d
,71);
87 R4(d
,e
,a
,b
,c
,72); R4(c
,d
,e
,a
,b
,73); R4(b
,c
,d
,e
,a
,74); R4(a
,b
,c
,d
,e
,75);
88 R4(e
,a
,b
,c
,d
,76); R4(d
,e
,a
,b
,c
,77); R4(c
,d
,e
,a
,b
,78); R4(b
,c
,d
,e
,a
,79);
90 /* Add the working variables back into Context->State[] */
98 a
= b
= c
= d
= e
= 0;
102 /******************************************************************************
103 * A_SHAInit (ntdll.@)
105 * Initialize a SHA context structure.
108 * Context [O] SHA context
113 void WINAPI
A_SHAInit(PSHA_CTX Context
)
115 /* SHA1 initialization constants */
116 Context
->State
[0] = 0x67452301;
117 Context
->State
[1] = 0xEFCDAB89;
118 Context
->State
[2] = 0x98BADCFE;
119 Context
->State
[3] = 0x10325476;
120 Context
->State
[4] = 0xC3D2E1F0;
122 Context
->Count
[1] = 0;
125 /******************************************************************************
126 * A_SHAUpdate (ntdll.@)
128 * Update a SHA context with a hashed data from supplied buffer.
131 * Context [O] SHA context
132 * Buffer [I] hashed data
133 * BufferSize [I] hashed data size
138 void WINAPI
A_SHAUpdate(PSHA_CTX Context
, const unsigned char *Buffer
, UINT BufferSize
)
140 ULONG BufferContentSize
;
142 BufferContentSize
= Context
->Count
[1] & 63;
143 Context
->Count
[1] += BufferSize
;
144 if (Context
->Count
[1] < BufferSize
)
146 Context
->Count
[0] += (BufferSize
>> 29);
148 if (BufferContentSize
+ BufferSize
< 64)
150 RtlCopyMemory(&Context
->Buffer
[BufferContentSize
], Buffer
,
155 while (BufferContentSize
+ BufferSize
>= 64)
157 RtlCopyMemory(Context
->Buffer
+ BufferContentSize
, Buffer
,
158 64 - BufferContentSize
);
159 Buffer
+= 64 - BufferContentSize
;
160 BufferSize
-= 64 - BufferContentSize
;
161 SHA1Transform(Context
->State
, Context
->Buffer
);
162 BufferContentSize
= 0;
164 RtlCopyMemory(Context
->Buffer
+ BufferContentSize
, Buffer
, BufferSize
);
168 /******************************************************************************
169 * A_SHAFinal (ntdll.@)
171 * Finalize SHA context and return the resulting hash.
174 * Context [I/O] SHA context
175 * Result [O] resulting hash
180 void WINAPI
A_SHAFinal(PSHA_CTX Context
, PULONG Result
)
185 ULONG BufferContentSize
, LengthHi
, LengthLo
;
187 BufferContentSize
= Context
->Count
[1] & 63;
188 if (BufferContentSize
>= 56)
189 Pad
= 56 + 64 - BufferContentSize
;
191 Pad
= 56 - BufferContentSize
;
193 LengthHi
= (Context
->Count
[0] << 3) | (Context
->Count
[1] >> (32 - 3));
194 LengthLo
= (Context
->Count
[1] << 3);
196 RtlZeroMemory(Buffer
+ 1, Pad
- 1);
198 Count
= (ULONG
*)(Buffer
+ Pad
);
199 Count
[0] = DWORD2BE(LengthHi
);
200 Count
[1] = DWORD2BE(LengthLo
);
201 A_SHAUpdate(Context
, Buffer
, Pad
+ 8);
203 for (Index
= 0; Index
< 5; Index
++)
204 Result
[Index
] = DWORD2BE(Context
->State
[Index
]);
212 * This code implements the MD4 message-digest algorithm.
213 * It is based on code in the public domain written by Colin
214 * Plumb in 1993. The algorithm is due to Ron Rivest.
216 * Equivalent code is available from RSA Data Security, Inc.
217 * This code has been tested against that, and is equivalent,
218 * except that you don't need to include two pages of legalese
226 unsigned char in
[64];
227 unsigned char digest
[16];
231 #define F( x, y, z ) (((x) & (y)) | ((~x) & (z)))
232 #define G( x, y, z ) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
233 #define H( x, y, z ) ((x) ^ (y) ^ (z))
235 #define FF( a, b, c, d, x, s ) { \
236 (a) += F( (b), (c), (d) ) + (x); \
237 (a) = rol( (a), (s) ); \
239 #define GG( a, b, c, d, x, s ) { \
240 (a) += G( (b), (c), (d) ) + (x) + (unsigned int)0x5a827999; \
241 (a) = rol( (a), (s) ); \
243 #define HH( a, b, c, d, x, s ) { \
244 (a) += H( (b), (c), (d) ) + (x) + (unsigned int)0x6ed9eba1; \
245 (a) = rol( (a), (s) ); \
248 static void MD4Transform( unsigned int buf
[4], const unsigned int in
[16] )
250 unsigned int a
, b
, c
, d
;
257 FF( a
, b
, c
, d
, in
[0], 3 );
258 FF( d
, a
, b
, c
, in
[1], 7 );
259 FF( c
, d
, a
, b
, in
[2], 11 );
260 FF( b
, c
, d
, a
, in
[3], 19 );
261 FF( a
, b
, c
, d
, in
[4], 3 );
262 FF( d
, a
, b
, c
, in
[5], 7 );
263 FF( c
, d
, a
, b
, in
[6], 11 );
264 FF( b
, c
, d
, a
, in
[7], 19 );
265 FF( a
, b
, c
, d
, in
[8], 3 );
266 FF( d
, a
, b
, c
, in
[9], 7 );
267 FF( c
, d
, a
, b
, in
[10], 11 );
268 FF( b
, c
, d
, a
, in
[11], 19 );
269 FF( a
, b
, c
, d
, in
[12], 3 );
270 FF( d
, a
, b
, c
, in
[13], 7 );
271 FF( c
, d
, a
, b
, in
[14], 11 );
272 FF( b
, c
, d
, a
, in
[15], 19 );
274 GG( a
, b
, c
, d
, in
[0], 3 );
275 GG( d
, a
, b
, c
, in
[4], 5 );
276 GG( c
, d
, a
, b
, in
[8], 9 );
277 GG( b
, c
, d
, a
, in
[12], 13 );
278 GG( a
, b
, c
, d
, in
[1], 3 );
279 GG( d
, a
, b
, c
, in
[5], 5 );
280 GG( c
, d
, a
, b
, in
[9], 9 );
281 GG( b
, c
, d
, a
, in
[13], 13 );
282 GG( a
, b
, c
, d
, in
[2], 3 );
283 GG( d
, a
, b
, c
, in
[6], 5 );
284 GG( c
, d
, a
, b
, in
[10], 9 );
285 GG( b
, c
, d
, a
, in
[14], 13 );
286 GG( a
, b
, c
, d
, in
[3], 3 );
287 GG( d
, a
, b
, c
, in
[7], 5 );
288 GG( c
, d
, a
, b
, in
[11], 9 );
289 GG( b
, c
, d
, a
, in
[15], 13 );
291 HH( a
, b
, c
, d
, in
[0], 3 );
292 HH( d
, a
, b
, c
, in
[8], 9 );
293 HH( c
, d
, a
, b
, in
[4], 11 );
294 HH( b
, c
, d
, a
, in
[12], 15 );
295 HH( a
, b
, c
, d
, in
[2], 3 );
296 HH( d
, a
, b
, c
, in
[10], 9 );
297 HH( c
, d
, a
, b
, in
[6], 11 );
298 HH( b
, c
, d
, a
, in
[14], 15 );
299 HH( a
, b
, c
, d
, in
[1], 3 );
300 HH( d
, a
, b
, c
, in
[9], 9 );
301 HH( c
, d
, a
, b
, in
[5], 11 );
302 HH( b
, c
, d
, a
, in
[13], 15 );
303 HH( a
, b
, c
, d
, in
[3], 3 );
304 HH( d
, a
, b
, c
, in
[11], 9 );
305 HH( c
, d
, a
, b
, in
[7], 11 );
306 HH( b
, c
, d
, a
, in
[15], 15 );
315 * Note: this code is harmless on little-endian machines.
317 static void byteReverse( unsigned char *buf
, unsigned longs
)
322 t
= ((unsigned)buf
[3] << 8 | buf
[2]) << 16 |
323 ((unsigned)buf
[1] << 8 | buf
[0]);
324 *(unsigned int *)buf
= t
;
329 /******************************************************************************
332 * Start MD4 accumulation. Set bit count to 0 and buffer to mysterious
333 * initialization constants.
335 void WINAPI
MD4Init( MD4_CTX
*ctx
)
337 ctx
->buf
[0] = 0x67452301;
338 ctx
->buf
[1] = 0xefcdab89;
339 ctx
->buf
[2] = 0x98badcfe;
340 ctx
->buf
[3] = 0x10325476;
342 ctx
->i
[0] = ctx
->i
[1] = 0;
345 /******************************************************************************
346 * MD4Update (ntdll.@)
348 * Update context to reflect the concatenation of another buffer full
351 void WINAPI
MD4Update( MD4_CTX
*ctx
, const unsigned char *buf
, unsigned int len
)
355 /* Update bitcount */
358 if ((ctx
->i
[0] = t
+ (len
<< 3)) < t
)
359 ctx
->i
[1]++; /* Carry from low to high */
361 ctx
->i
[1] += len
>> 29;
364 /* Handle any leading odd-sized chunks */
367 unsigned char *p
= (unsigned char *)ctx
->in
+ t
;
372 memcpy( p
, buf
, len
);
377 byteReverse( ctx
->in
, 16 );
379 MD4Transform( ctx
->buf
, (unsigned int *)ctx
->in
);
385 /* Process data in 64-byte chunks */
388 memcpy( ctx
->in
, buf
, 64 );
389 byteReverse( ctx
->in
, 16 );
391 MD4Transform( ctx
->buf
, (unsigned int *)ctx
->in
);
397 /* Handle any remaining bytes of data. */
398 memcpy( ctx
->in
, buf
, len
);
401 /******************************************************************************
404 * Final wrapup - pad to 64-byte boundary with the bit pattern
405 * 1 0* (64-bit count of bits processed, MSB-first)
407 void WINAPI
MD4Final( MD4_CTX
*ctx
)
412 /* Compute number of bytes mod 64 */
413 count
= (ctx
->i
[0] >> 3) & 0x3F;
415 /* Set the first char of padding to 0x80. This is safe since there is
416 always at least one byte free */
420 /* Bytes of padding needed to make 64 bytes */
421 count
= 64 - 1 - count
;
423 /* Pad out to 56 mod 64 */
426 /* Two lots of padding: Pad the first block to 64 bytes */
427 memset( p
, 0, count
);
428 byteReverse( ctx
->in
, 16 );
429 MD4Transform( ctx
->buf
, (unsigned int *)ctx
->in
);
431 /* Now fill the next block with 56 bytes */
432 memset( ctx
->in
, 0, 56 );
436 /* Pad block to 56 bytes */
437 memset( p
, 0, count
- 8 );
440 byteReverse( ctx
->in
, 14 );
442 /* Append length in bits and transform */
443 ((unsigned int *)ctx
->in
)[14] = ctx
->i
[0];
444 ((unsigned int *)ctx
->in
)[15] = ctx
->i
[1];
446 MD4Transform( ctx
->buf
, (unsigned int *)ctx
->in
);
447 byteReverse( (unsigned char *)ctx
->buf
, 4 );
448 memcpy( ctx
->digest
, ctx
->buf
, 16 );
454 * This code implements the MD5 message-digest algorithm.
455 * It is based on code in the public domain written by Colin
456 * Plumb in 1993. The algorithm is due to Ron Rivest.
458 * Equivalent code is available from RSA Data Security, Inc.
459 * This code has been tested against that, and is equivalent,
460 * except that you don't need to include two pages of legalese
468 unsigned char in
[64];
469 unsigned char digest
[16];
472 /* #define F1( x, y, z ) (x & y | ~x & z) */
473 #define F1( x, y, z ) (z ^ (x & (y ^ z)))
474 #define F2( x, y, z ) F1( z, x, y )
475 #define F3( x, y, z ) (x ^ y ^ z)
476 #define F4( x, y, z ) (y ^ (x | ~z))
478 /* This is the central step in the MD5 algorithm. */
479 #define MD5STEP( f, w, x, y, z, data, s ) \
480 ( w += f( x, y, z ) + data, w = w << s | w >> (32 - s), w += x )
483 * The core of the MD5 algorithm, this alters an existing MD5 hash to
484 * reflect the addition of 16 longwords of new data. MD5Update blocks
485 * the data and converts bytes into longwords for this routine.
487 static void MD5Transform( unsigned int buf
[4], const unsigned int in
[16] )
489 unsigned int a
, b
, c
, d
;
496 MD5STEP( F1
, a
, b
, c
, d
, in
[0] + 0xd76aa478, 7 );
497 MD5STEP( F1
, d
, a
, b
, c
, in
[1] + 0xe8c7b756, 12 );
498 MD5STEP( F1
, c
, d
, a
, b
, in
[2] + 0x242070db, 17 );
499 MD5STEP( F1
, b
, c
, d
, a
, in
[3] + 0xc1bdceee, 22 );
500 MD5STEP( F1
, a
, b
, c
, d
, in
[4] + 0xf57c0faf, 7 );
501 MD5STEP( F1
, d
, a
, b
, c
, in
[5] + 0x4787c62a, 12 );
502 MD5STEP( F1
, c
, d
, a
, b
, in
[6] + 0xa8304613, 17 );
503 MD5STEP( F1
, b
, c
, d
, a
, in
[7] + 0xfd469501, 22 );
504 MD5STEP( F1
, a
, b
, c
, d
, in
[8] + 0x698098d8, 7 );
505 MD5STEP( F1
, d
, a
, b
, c
, in
[9] + 0x8b44f7af, 12 );
506 MD5STEP( F1
, c
, d
, a
, b
, in
[10] + 0xffff5bb1, 17 );
507 MD5STEP( F1
, b
, c
, d
, a
, in
[11] + 0x895cd7be, 22 );
508 MD5STEP( F1
, a
, b
, c
, d
, in
[12] + 0x6b901122, 7 );
509 MD5STEP( F1
, d
, a
, b
, c
, in
[13] + 0xfd987193, 12 );
510 MD5STEP( F1
, c
, d
, a
, b
, in
[14] + 0xa679438e, 17 );
511 MD5STEP( F1
, b
, c
, d
, a
, in
[15] + 0x49b40821, 22 );
513 MD5STEP( F2
, a
, b
, c
, d
, in
[1] + 0xf61e2562, 5 );
514 MD5STEP( F2
, d
, a
, b
, c
, in
[6] + 0xc040b340, 9 );
515 MD5STEP( F2
, c
, d
, a
, b
, in
[11] + 0x265e5a51, 14 );
516 MD5STEP( F2
, b
, c
, d
, a
, in
[0] + 0xe9b6c7aa, 20 );
517 MD5STEP( F2
, a
, b
, c
, d
, in
[5] + 0xd62f105d, 5 );
518 MD5STEP( F2
, d
, a
, b
, c
, in
[10] + 0x02441453, 9 );
519 MD5STEP( F2
, c
, d
, a
, b
, in
[15] + 0xd8a1e681, 14 );
520 MD5STEP( F2
, b
, c
, d
, a
, in
[4] + 0xe7d3fbc8, 20 );
521 MD5STEP( F2
, a
, b
, c
, d
, in
[9] + 0x21e1cde6, 5 );
522 MD5STEP( F2
, d
, a
, b
, c
, in
[14] + 0xc33707d6, 9 );
523 MD5STEP( F2
, c
, d
, a
, b
, in
[3] + 0xf4d50d87, 14 );
524 MD5STEP( F2
, b
, c
, d
, a
, in
[8] + 0x455a14ed, 20 );
525 MD5STEP( F2
, a
, b
, c
, d
, in
[13] + 0xa9e3e905, 5 );
526 MD5STEP( F2
, d
, a
, b
, c
, in
[2] + 0xfcefa3f8, 9 );
527 MD5STEP( F2
, c
, d
, a
, b
, in
[7] + 0x676f02d9, 14 );
528 MD5STEP( F2
, b
, c
, d
, a
, in
[12] + 0x8d2a4c8a, 20 );
530 MD5STEP( F3
, a
, b
, c
, d
, in
[5] + 0xfffa3942, 4 );
531 MD5STEP( F3
, d
, a
, b
, c
, in
[8] + 0x8771f681, 11 );
532 MD5STEP( F3
, c
, d
, a
, b
, in
[11] + 0x6d9d6122, 16 );
533 MD5STEP( F3
, b
, c
, d
, a
, in
[14] + 0xfde5380c, 23 );
534 MD5STEP( F3
, a
, b
, c
, d
, in
[1] + 0xa4beea44, 4 );
535 MD5STEP( F3
, d
, a
, b
, c
, in
[4] + 0x4bdecfa9, 11 );
536 MD5STEP( F3
, c
, d
, a
, b
, in
[7] + 0xf6bb4b60, 16 );
537 MD5STEP( F3
, b
, c
, d
, a
, in
[10] + 0xbebfbc70, 23 );
538 MD5STEP( F3
, a
, b
, c
, d
, in
[13] + 0x289b7ec6, 4 );
539 MD5STEP( F3
, d
, a
, b
, c
, in
[0] + 0xeaa127fa, 11 );
540 MD5STEP( F3
, c
, d
, a
, b
, in
[3] + 0xd4ef3085, 16 );
541 MD5STEP( F3
, b
, c
, d
, a
, in
[6] + 0x04881d05, 23 );
542 MD5STEP( F3
, a
, b
, c
, d
, in
[9] + 0xd9d4d039, 4 );
543 MD5STEP( F3
, d
, a
, b
, c
, in
[12] + 0xe6db99e5, 11 );
544 MD5STEP( F3
, c
, d
, a
, b
, in
[15] + 0x1fa27cf8, 16 );
545 MD5STEP( F3
, b
, c
, d
, a
, in
[2] + 0xc4ac5665, 23 );
547 MD5STEP( F4
, a
, b
, c
, d
, in
[0] + 0xf4292244, 6 );
548 MD5STEP( F4
, d
, a
, b
, c
, in
[7] + 0x432aff97, 10 );
549 MD5STEP( F4
, c
, d
, a
, b
, in
[14] + 0xab9423a7, 15 );
550 MD5STEP( F4
, b
, c
, d
, a
, in
[5] + 0xfc93a039, 21 );
551 MD5STEP( F4
, a
, b
, c
, d
, in
[12] + 0x655b59c3, 6 );
552 MD5STEP( F4
, d
, a
, b
, c
, in
[3] + 0x8f0ccc92, 10 );
553 MD5STEP( F4
, c
, d
, a
, b
, in
[10] + 0xffeff47d, 15 );
554 MD5STEP( F4
, b
, c
, d
, a
, in
[1] + 0x85845dd1, 21 );
555 MD5STEP( F4
, a
, b
, c
, d
, in
[8] + 0x6fa87e4f, 6 );
556 MD5STEP( F4
, d
, a
, b
, c
, in
[15] + 0xfe2ce6e0, 10 );
557 MD5STEP( F4
, c
, d
, a
, b
, in
[6] + 0xa3014314, 15 );
558 MD5STEP( F4
, b
, c
, d
, a
, in
[13] + 0x4e0811a1, 21 );
559 MD5STEP( F4
, a
, b
, c
, d
, in
[4] + 0xf7537e82, 6 );
560 MD5STEP( F4
, d
, a
, b
, c
, in
[11] + 0xbd3af235, 10 );
561 MD5STEP( F4
, c
, d
, a
, b
, in
[2] + 0x2ad7d2bb, 15 );
562 MD5STEP( F4
, b
, c
, d
, a
, in
[9] + 0xeb86d391, 21 );
570 /******************************************************************************
573 * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
574 * initialization constants.
576 void WINAPI
MD5Init( MD5_CTX
*ctx
)
578 ctx
->buf
[0] = 0x67452301;
579 ctx
->buf
[1] = 0xefcdab89;
580 ctx
->buf
[2] = 0x98badcfe;
581 ctx
->buf
[3] = 0x10325476;
583 ctx
->i
[0] = ctx
->i
[1] = 0;
586 /******************************************************************************
587 * MD5Update (ntdll.@)
589 * Update context to reflect the concatenation of another buffer full
592 void WINAPI
MD5Update( MD5_CTX
*ctx
, const unsigned char *buf
, unsigned int len
)
594 register unsigned int t
;
596 /* Update bitcount */
599 if ((ctx
->i
[0] = t
+ (len
<< 3)) < t
)
600 ctx
->i
[1]++; /* Carry from low to high */
602 ctx
->i
[1] += len
>> 29;
605 /* Handle any leading odd-sized chunks */
608 unsigned char *p
= (unsigned char *)ctx
->in
+ t
;
613 memcpy( p
, buf
, len
);
618 byteReverse( ctx
->in
, 16 );
620 MD5Transform( ctx
->buf
, (unsigned int *)ctx
->in
);
626 /* Process data in 64-byte chunks */
629 memcpy( ctx
->in
, buf
, 64 );
630 byteReverse( ctx
->in
, 16 );
632 MD5Transform( ctx
->buf
, (unsigned int *)ctx
->in
);
638 /* Handle any remaining bytes of data. */
639 memcpy( ctx
->in
, buf
, len
);
642 /******************************************************************************
645 * Final wrapup - pad to 64-byte boundary with the bit pattern
646 * 1 0* (64-bit count of bits processed, MSB-first)
648 void WINAPI
MD5Final( MD5_CTX
*ctx
)
653 /* Compute number of bytes mod 64 */
654 count
= (ctx
->i
[0] >> 3) & 0x3F;
656 /* Set the first char of padding to 0x80. This is safe since there is
657 always at least one byte free */
661 /* Bytes of padding needed to make 64 bytes */
662 count
= 64 - 1 - count
;
664 /* Pad out to 56 mod 64 */
667 /* Two lots of padding: Pad the first block to 64 bytes */
668 memset( p
, 0, count
);
669 byteReverse( ctx
->in
, 16 );
670 MD5Transform( ctx
->buf
, (unsigned int *)ctx
->in
);
672 /* Now fill the next block with 56 bytes */
673 memset( ctx
->in
, 0, 56 );
677 /* Pad block to 56 bytes */
678 memset( p
, 0, count
- 8 );
681 byteReverse( ctx
->in
, 14 );
683 /* Append length in bits and transform */
684 ((unsigned int *)ctx
->in
)[14] = ctx
->i
[0];
685 ((unsigned int *)ctx
->in
)[15] = ctx
->i
[1];
687 MD5Transform( ctx
->buf
, (unsigned int *)ctx
->in
);
688 byteReverse( (unsigned char *)ctx
->buf
, 4 );
689 memcpy( ctx
->digest
, ctx
->buf
, 16 );