1 /*_############################################################################
6 _## -----------------------------------------------
7 _## Copyright (c) 2001-2010 Jochen Katz, Frank Fock
9 _## This software is based on SNMP++2.6 from Hewlett Packard:
11 _## Copyright (c) 1996
12 _## Hewlett-Packard Company
14 _## ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
15 _## Permission to use, copy, modify, distribute and/or sell this software
16 _## and/or its documentation is hereby granted without fee. User agrees
17 _## to display the above copyright notice and this license notice in all
18 _## copies of the software and any documentation of the software. User
19 _## agrees to assume all liability for the use of the software;
20 _## Hewlett-Packard and Jochen Katz make no representations about the
21 _## suitability of this software for any purpose. It is provided
22 _## "AS-IS" without warranty of any kind, either express or implied. User
23 _## hereby grants a royalty-free license to any and all derivatives based
24 _## upon this software code base.
26 _## Stuttgart, Germany, Thu Sep 2 00:07:47 CEST 2010
28 _##########################################################################*/
29 char md5c_cpp_version[]="#(@) SNMP++ $Id: md5c.cpp 43 2004-03-03 23:11:21Z katz $";
30 /* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm */
32 /* Copyright (C) 1991, RSA Data Security, Inc. All rights reserved.
34 License to copy and use this software is granted provided that it
35 is identified as the "RSA Data Security, Inc. MD5 Message-Digest
36 Algorithm" in all material mentioning or referencing this software
39 License is also granted to make and use derivative works provided
40 that such works are identified as "derived from the RSA Data
41 Security, Inc. MD5 Message-Digest Algorithm" in all material
42 mentioning or referencing the derived work.
44 RSA Data Security, Inc. makes no representations concerning either
45 the merchantability of this software or the suitability of this
46 software for any particular purpose. It is provided "as is"
47 without express or implied warranty of any kind.
49 These notices must be retained in any copies of any part of this
50 documentation and/or software.
53 #include "snmp_pp/md5.h"
55 #if !defined(_USE_LIBTOMCRYPT) && !defined(_USE_OPENSSL)
63 #ifdef SNMP_PP_NAMESPACE
67 /* Constants for MD5Transform routine.
86 static void MD5Transform PROTO_LIST ((UINT4 [4], const unsigned char [64]));
87 static void Encode PROTO_LIST ((unsigned char *, UINT4 *, unsigned int));
88 static void Decode PROTO_LIST ((UINT4 *, const unsigned char *, unsigned int));
89 static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
90 static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
92 static unsigned char PADDING[64] = {
93 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
94 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
95 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
98 /* F, G, H and I are basic MD5 functions.
100 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
101 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
102 #define H(x, y, z) ((x) ^ (y) ^ (z))
103 #define I(x, y, z) ((y) ^ ((x) | (~z)))
105 /* ROTATE_LEFT rotates x left n bits.
107 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
109 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
110 Rotation is separate from addition to prevent recomputation.
112 #define FF(a, b, c, d, x, s, ac) { \
113 (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
114 (a) = ROTATE_LEFT ((a), (s)); \
117 #define GG(a, b, c, d, x, s, ac) { \
118 (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
119 (a) = ROTATE_LEFT ((a), (s)); \
122 #define HH(a, b, c, d, x, s, ac) { \
123 (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
124 (a) = ROTATE_LEFT ((a), (s)); \
127 #define II(a, b, c, d, x, s, ac) { \
128 (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
129 (a) = ROTATE_LEFT ((a), (s)); \
133 /* MD5 initialization. Begins an MD5 operation, writing a new context.
135 void MD5Init (MD5_CTX *context)
137 context->count[0] = context->count[1] = 0;
139 /* Load magic initialization constants.
141 context->state[0] = 0x67452301;
142 context->state[1] = 0xefcdab89;
143 context->state[2] = 0x98badcfe;
144 context->state[3] = 0x10325476;
147 /* MD5 block update operation. Continues an MD5 message-digest operation,
148 processing another message block, and updating the context.
150 void MD5Update (MD5_CTX *context, /* context */
151 const unsigned char *input, /* input block */
152 const unsigned int inputLen) /* length of input block */
154 unsigned int i, index, partLen;
156 /* Compute number of bytes mod 64 */
157 index = (unsigned int)((context->count[0] >> 3) & 0x3F);
159 /* Update number of bits */
160 if ((context->count[0] += ((UINT4)inputLen << 3)) < ((UINT4)inputLen << 3))
162 context->count[1] += ((UINT4)inputLen >> 29);
164 partLen = 64 - index;
166 /* Transform as many times as possible.
168 if (inputLen >= partLen) {
169 MD5_memcpy ((POINTER)&context->buffer[index], (POINTER)input, partLen);
170 MD5Transform (context->state, context->buffer);
172 for (i = partLen; i + 63 < inputLen; i += 64)
173 MD5Transform (context->state, &input[i]);
180 /* Buffer remaining input */
182 ((POINTER)&context->buffer[index], (POINTER)&input[i], inputLen-i);
185 /* MD5 finalization. Ends an MD5 message-digest operation, writing the
186 the message digest and zeroizing the context.
189 unsigned char digest[16], /* message digest */
190 MD5_CTX *context) /* context */
192 unsigned char bits[8];
193 unsigned int index, padLen;
195 /* Save number of bits */
196 Encode (bits, context->count, 8);
198 /* Pad out to 56 mod 64.
200 index = (unsigned int)((context->count[0] >> 3) & 0x3f);
201 padLen = (index < 56) ? (56 - index) : (120 - index);
202 MD5Update (context, PADDING, padLen);
204 /* Append length (before padding) */
205 MD5Update (context, bits, 8);
207 /* Store state in digest */
208 Encode (digest, context->state, 16);
210 /* Zeroize sensitive information.
212 MD5_memset ((POINTER)context, 0, sizeof (*context));
215 /* MD5 basic transformation. Transforms state based on block.
217 static void MD5Transform (
219 const unsigned char block[64])
221 UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
223 Decode (x, block, 64);
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 */
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 */
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 */
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 */
302 /* Zeroize sensitive information.
304 MD5_memset ((POINTER)x, 0, sizeof (x));
307 /* Encodes input (UINT4) into output (unsigned char). Assumes len is
311 unsigned char *output,
317 for (i = 0, j = 0; j < len; i++, j += 4) {
318 output[j] = (unsigned char)(input[i] & 0xff);
319 output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
320 output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
321 output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
325 /* Decodes input (unsigned char) into output (UINT4). Assumes len is
330 const unsigned char *input,
335 for (i = 0, j = 0; j < len; i++, j += 4)
336 output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
337 (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
340 static void MD5_memcpy (
345 memcpy(output, input, len);
348 static void MD5_memset (
353 memset(output, value, len);
356 #ifdef SNMP_PP_NAMESPACE
357 }; // end of namespace Snmp_pp
364 #endif // !defined(_USE_LIBTOMCRYPT) && !defined(_USE_OPENSSL)