source: XMLIO_V2/external/src/POCO/Foundation/MD5Engine.cpp @ 80

Last change on this file since 80 was 80, checked in by ymipsl, 14 years ago

ajout lib externe

  • Property svn:eol-style set to native
File size: 10.2 KB
Line 
1//
2// MD5Engine.cpp
3//
4// $Id: //poco/1.3/Foundation/src/MD5Engine.cpp#2 $
5//
6// Library: Foundation
7// Package: Crypt
8// Module:  MD5Engine
9//
10// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
11// and Contributors.
12//
13// Permission is hereby granted, free of charge, to any person or organization
14// obtaining a copy of the software and accompanying documentation covered by
15// this license (the "Software") to use, reproduce, display, distribute,
16// execute, and transmit the Software, and to prepare derivative works of the
17// Software, and to permit third-parties to whom the Software is furnished to
18// do so, all subject to the following:
19//
20// The copyright notices in the Software and this entire statement, including
21// the above license grant, this restriction and the following disclaimer,
22// must be included in all copies of the Software, in whole or in part, and
23// all derivative works of the Software, unless such copies or derivative
24// works are solely in the form of machine-executable object code generated by
25// a source language processor.
26//
27// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
30// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
31// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
32// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
33// DEALINGS IN THE SOFTWARE.
34//
35//
36// MD5 (RFC 1321) algorithm:
37// Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
38// rights reserved.
39//
40// License to copy and use this software is granted provided that it
41// is identified as the "RSA Data Security, Inc. MD5 Message-Digest
42// Algorithm" in all material mentioning or referencing this software
43// or this function.
44//
45// License is also granted to make and use derivative works provided
46// that such works are identified as "derived from the RSA Data
47// Security, Inc. MD5 Message-Digest Algorithm" in all material
48// mentioning or referencing the derived work.
49//
50// RSA Data Security, Inc. makes no representations concerning either
51// the merchantability of this software or the suitability of this
52// software for any particular purpose. It is provided "as is"
53// without express or implied warranty of any kind.
54//
55// These notices must be retained in any copies of any part of this
56// documentation and/or software.
57//
58
59
60#include <Poco/MD5Engine.h>
61#include <cstring>
62
63
64namespace Poco {
65
66
67MD5Engine::MD5Engine()
68{
69        _digest.reserve(16);
70        reset();
71}
72
73
74MD5Engine::~MD5Engine()
75{
76        reset();
77}
78
79       
80void MD5Engine::updateImpl(const void* input_, unsigned inputLen)
81{
82        const unsigned char* input = (const unsigned char*) input_;
83        unsigned int i, index, partLen;
84
85        /* Compute number of bytes mod 64 */
86        index = (unsigned int)((_context.count[0] >> 3) & 0x3F);
87
88        /* Update number of bits */
89        if ((_context.count[0] += ((UInt32) inputLen << 3)) < ((UInt32) inputLen << 3))
90                _context.count[1]++;
91        _context.count[1] += ((UInt32) inputLen >> 29);
92
93        partLen = 64 - index;
94
95        /* Transform as many times as possible. */
96        if (inputLen >= partLen) 
97        {
98                std::memcpy(&_context.buffer[index], input, partLen);
99                transform(_context.state, _context.buffer);
100
101                for (i = partLen; i + 63 < inputLen; i += 64)
102                        transform(_context.state, &input[i]);
103
104                index = 0;
105        }
106        else i = 0;
107
108        /* Buffer remaining input */
109        std::memcpy(&_context.buffer[index], &input[i],inputLen-i);
110}
111
112
113unsigned MD5Engine::digestLength() const
114{
115        return DIGEST_SIZE;
116}
117
118
119void MD5Engine::reset()
120{
121        std::memset(&_context, 0, sizeof(_context));
122        _context.count[0] = _context.count[1] = 0;
123        _context.state[0] = 0x67452301;
124        _context.state[1] = 0xefcdab89;
125        _context.state[2] = 0x98badcfe;
126        _context.state[3] = 0x10325476;
127}
128
129
130const DigestEngine::Digest& MD5Engine::digest()
131{
132        static const unsigned char PADDING[64] = 
133        {
134                0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
135                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
136                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
137        };
138        unsigned char bits[8];
139        unsigned int index, padLen;
140
141        /* Save number of bits */
142        encode(bits, _context.count, 8);
143
144        /* Pad out to 56 mod 64. */
145        index = (unsigned int)((_context.count[0] >> 3) & 0x3f);
146        padLen = (index < 56) ? (56 - index) : (120 - index);
147        update(PADDING, padLen);
148
149        /* Append length (before padding) */
150        update(bits, 8);
151
152        /* Store state in digest */
153        unsigned char digest[16];
154        encode(digest, _context.state, 16);
155        _digest.clear();
156        _digest.insert(_digest.begin(), digest, digest + sizeof(digest));
157
158        /* Zeroize sensitive information. */
159        std::memset(&_context, 0, sizeof (_context));
160        reset();
161        return _digest;
162}
163
164
165/* Constants for MD5Transform routine. */
166#define S11 7
167#define S12 12
168#define S13 17
169#define S14 22
170#define S21 5
171#define S22 9
172#define S23 14
173#define S24 20
174#define S31 4
175#define S32 11
176#define S33 16
177#define S34 23
178#define S41 6
179#define S42 10
180#define S43 15
181#define S44 21
182
183
184/* F, G, H and I are basic MD5 functions. */
185#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
186#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
187#define H(x, y, z) ((x) ^ (y) ^ (z))
188#define I(x, y, z) ((y) ^ ((x) | (~z)))
189
190
191/* ROTATE_LEFT rotates x left n bits. */
192#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
193
194
195/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
196   Rotation is separate from addition to prevent recomputation. */
197#define FF(a, b, c, d, x, s, ac) { \
198 (a) += F ((b), (c), (d)) + (x) + (UInt32)(ac); \
199 (a) = ROTATE_LEFT ((a), (s)); \
200 (a) += (b); \
201  }
202#define GG(a, b, c, d, x, s, ac) { \
203 (a) += G ((b), (c), (d)) + (x) + (UInt32)(ac); \
204 (a) = ROTATE_LEFT ((a), (s)); \
205 (a) += (b); \
206  }
207#define HH(a, b, c, d, x, s, ac) { \
208 (a) += H ((b), (c), (d)) + (x) + (UInt32)(ac); \
209 (a) = ROTATE_LEFT ((a), (s)); \
210 (a) += (b); \
211  }
212#define II(a, b, c, d, x, s, ac) { \
213 (a) += I ((b), (c), (d)) + (x) + (UInt32)(ac); \
214 (a) = ROTATE_LEFT ((a), (s)); \
215 (a) += (b); \
216  }
217
218
219void MD5Engine::transform (UInt32 state[4], const unsigned char block[64])
220{
221        UInt32 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
222
223        decode(x, block, 64);
224
225        /* Round 1 */
226        FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
227        FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
228        FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
229        FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
230        FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
231        FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
232        FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
233        FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
234        FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
235        FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
236        FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
237        FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
238        FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
239        FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
240        FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
241        FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
242
243        /* Round 2 */
244        GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
245        GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
246        GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
247        GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
248        GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
249        GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
250        GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
251        GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
252        GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
253        GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
254        GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
255        GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
256        GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
257        GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
258        GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
259        GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
260
261        /* Round 3 */
262        HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
263        HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
264        HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
265        HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
266        HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
267        HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
268        HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
269        HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
270        HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
271        HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
272        HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
273        HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
274        HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
275        HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
276        HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
277        HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
278
279        /* Round 4 */
280        II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
281        II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
282        II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
283        II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
284        II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
285        II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
286        II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
287        II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
288        II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
289        II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
290        II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
291        II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
292        II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
293        II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
294        II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
295        II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
296
297        state[0] += a;
298        state[1] += b;
299        state[2] += c;
300        state[3] += d;
301
302        /* Zeroize sensitive information. */
303        std::memset(x, 0, sizeof(x));
304}
305
306
307void MD5Engine::encode(unsigned char* output, const UInt32* input, unsigned int len)
308{
309        unsigned int i, j;
310
311        for (i = 0, j = 0; j < len; i++, j += 4) 
312        {
313                output[j]   = (unsigned char)(input[i] & 0xff);
314                output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
315                output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
316                output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
317        }
318}
319
320
321void MD5Engine::decode(UInt32* output, const unsigned char* input, unsigned int len)
322{
323        unsigned int i, j;
324
325        for (i = 0, j = 0; j < len; i++, j += 4)
326                output[i] = ((UInt32)input[j]) | (((UInt32)input[j+1]) << 8) |
327                            (((UInt32)input[j+2]) << 16) | (((UInt32)input[j+3]) << 24);
328}
329
330
331} // namespace Poco
Note: See TracBrowser for help on using the repository browser.