wbemdisp: Implement GetObjectText_().
[wine/zf.git] / dlls / ntdll / crypt.c
blob8f1849814cba5e4e947102be0a2f4aeeb0d9afe9
1 /*
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
21 #include <stdarg.h>
22 #include "windef.h"
24 /* SHA1 algorithm
26 * Based on public domain SHA code by Steve Reid <steve@edmweb.com>
29 typedef struct {
30 ULONG Unknown[6];
31 ULONG State[5];
32 ULONG Count[2];
33 UCHAR Buffer[64];
34 } SHA_CTX, *PSHA_CTX;
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])
56 ULONG a, b, c, d, e;
57 ULONG *Block;
59 Block = (ULONG*)Buffer;
61 /* Copy Context->State[] to working variables */
62 a = State[0];
63 b = State[1];
64 c = State[2];
65 d = State[3];
66 e = State[4];
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[] */
91 State[0] += a;
92 State[1] += b;
93 State[2] += c;
94 State[3] += d;
95 State[4] += e;
97 /* Wipe variables */
98 a = b = c = d = e = 0;
102 /******************************************************************************
103 * A_SHAInit (ntdll.@)
105 * Initialize a SHA context structure.
107 * PARAMS
108 * Context [O] SHA context
110 * RETURNS
111 * Nothing
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;
121 Context->Count[0] =
122 Context->Count[1] = 0;
125 /******************************************************************************
126 * A_SHAUpdate (ntdll.@)
128 * Update a SHA context with a hashed data from supplied buffer.
130 * PARAMS
131 * Context [O] SHA context
132 * Buffer [I] hashed data
133 * BufferSize [I] hashed data size
135 * RETURNS
136 * Nothing
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)
145 Context->Count[0]++;
146 Context->Count[0] += (BufferSize >> 29);
148 if (BufferContentSize + BufferSize < 64)
150 RtlCopyMemory(&Context->Buffer[BufferContentSize], Buffer,
151 BufferSize);
153 else
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.
173 * PARAMS
174 * Context [I/O] SHA context
175 * Result [O] resulting hash
177 * RETURNS
178 * Nothing
180 void WINAPI A_SHAFinal(PSHA_CTX Context, PULONG Result)
182 INT Pad, Index;
183 UCHAR Buffer[72];
184 ULONG *Count;
185 ULONG BufferContentSize, LengthHi, LengthLo;
187 BufferContentSize = Context->Count[1] & 63;
188 if (BufferContentSize >= 56)
189 Pad = 56 + 64 - BufferContentSize;
190 else
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);
197 Buffer[0] = 0x80;
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]);
206 A_SHAInit(Context);
210 /* MD4 algorithm
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
219 * with every copy.
222 typedef struct
224 unsigned int buf[4];
225 unsigned int i[2];
226 unsigned char in[64];
227 unsigned char digest[16];
228 } MD4_CTX;
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;
252 a = buf[0];
253 b = buf[1];
254 c = buf[2];
255 d = buf[3];
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 );
308 buf[0] += a;
309 buf[1] += b;
310 buf[2] += c;
311 buf[3] += d;
315 * Note: this code is harmless on little-endian machines.
317 static void byteReverse( unsigned char *buf, unsigned longs )
319 unsigned int t;
321 do {
322 t = ((unsigned)buf[3] << 8 | buf[2]) << 16 |
323 ((unsigned)buf[1] << 8 | buf[0]);
324 *(unsigned int *)buf = t;
325 buf += 4;
326 } while (--longs);
329 /******************************************************************************
330 * MD4Init (ntdll.@)
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
349 * of bytes.
351 void WINAPI MD4Update( MD4_CTX *ctx, const unsigned char *buf, unsigned int len )
353 unsigned int t;
355 /* Update bitcount */
356 t = ctx->i[0];
358 if ((ctx->i[0] = t + (len << 3)) < t)
359 ctx->i[1]++; /* Carry from low to high */
361 ctx->i[1] += len >> 29;
362 t = (t >> 3) & 0x3f;
364 /* Handle any leading odd-sized chunks */
365 if (t)
367 unsigned char *p = (unsigned char *)ctx->in + t;
368 t = 64 - t;
370 if (len < t)
372 memcpy( p, buf, len );
373 return;
376 memcpy( p, buf, t );
377 byteReverse( ctx->in, 16 );
379 MD4Transform( ctx->buf, (unsigned int *)ctx->in );
381 buf += t;
382 len -= t;
385 /* Process data in 64-byte chunks */
386 while (len >= 64)
388 memcpy( ctx->in, buf, 64 );
389 byteReverse( ctx->in, 16 );
391 MD4Transform( ctx->buf, (unsigned int *)ctx->in );
393 buf += 64;
394 len -= 64;
397 /* Handle any remaining bytes of data. */
398 memcpy( ctx->in, buf, len );
401 /******************************************************************************
402 * MD4Final (ntdll.@)
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 )
409 unsigned int count;
410 unsigned char *p;
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 */
417 p = ctx->in + count;
418 *p++ = 0x80;
420 /* Bytes of padding needed to make 64 bytes */
421 count = 64 - 1 - count;
423 /* Pad out to 56 mod 64 */
424 if (count < 8)
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 );
434 else
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 );
452 /* MD5 algorithm
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
461 * with every copy.
464 typedef struct
466 unsigned int i[2];
467 unsigned int buf[4];
468 unsigned char in[64];
469 unsigned char digest[16];
470 } MD5_CTX;
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;
491 a = buf[0];
492 b = buf[1];
493 c = buf[2];
494 d = buf[3];
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 );
564 buf[0] += a;
565 buf[1] += b;
566 buf[2] += c;
567 buf[3] += d;
570 /******************************************************************************
571 * MD5Init (ntdll.@)
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
590 * of bytes.
592 void WINAPI MD5Update( MD5_CTX *ctx, const unsigned char *buf, unsigned int len )
594 register unsigned int t;
596 /* Update bitcount */
597 t = ctx->i[0];
599 if ((ctx->i[0] = t + (len << 3)) < t)
600 ctx->i[1]++; /* Carry from low to high */
602 ctx->i[1] += len >> 29;
603 t = (t >> 3) & 0x3f;
605 /* Handle any leading odd-sized chunks */
606 if (t)
608 unsigned char *p = (unsigned char *)ctx->in + t;
609 t = 64 - t;
611 if (len < t)
613 memcpy( p, buf, len );
614 return;
617 memcpy( p, buf, t );
618 byteReverse( ctx->in, 16 );
620 MD5Transform( ctx->buf, (unsigned int *)ctx->in );
622 buf += t;
623 len -= t;
626 /* Process data in 64-byte chunks */
627 while (len >= 64)
629 memcpy( ctx->in, buf, 64 );
630 byteReverse( ctx->in, 16 );
632 MD5Transform( ctx->buf, (unsigned int *)ctx->in );
634 buf += 64;
635 len -= 64;
638 /* Handle any remaining bytes of data. */
639 memcpy( ctx->in, buf, len );
642 /******************************************************************************
643 * MD5Final (ntdll.@)
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 )
650 unsigned int count;
651 unsigned char *p;
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 */
658 p = ctx->in + count;
659 *p++ = 0x80;
661 /* Bytes of padding needed to make 64 bytes */
662 count = 64 - 1 - count;
664 /* Pad out to 56 mod 64 */
665 if (count < 8)
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 );
675 else
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 );