]> git.stg.codes - ssmd.git/blob - 3rdparty/snmp++/src/md5c.cpp
Initial adding
[ssmd.git] / 3rdparty / snmp++ / src / md5c.cpp
1 /*_############################################################################
2   _## 
3   _##  md5c.cpp  
4   _##
5   _##  SNMP++v3.2.25
6   _##  -----------------------------------------------
7   _##  Copyright (c) 2001-2010 Jochen Katz, Frank Fock
8   _##
9   _##  This software is based on SNMP++2.6 from Hewlett Packard:
10   _##  
11   _##    Copyright (c) 1996
12   _##    Hewlett-Packard Company
13   _##  
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. 
25   _##  
26   _##  Stuttgart, Germany, Thu Sep  2 00:07:47 CEST 2010 
27   _##  
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 */
31
32 /* Copyright (C) 1991, RSA Data Security, Inc. All rights reserved.
33
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
37    or this function.
38
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.
43
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.
48
49    These notices must be retained in any copies of any part of this
50    documentation and/or software.
51  */
52
53 #include "snmp_pp/md5.h"
54
55 #if !defined(_USE_LIBTOMCRYPT) && !defined(_USE_OPENSSL)
56
57 #include <string.h>
58
59 #ifdef __cplusplus
60 extern "C" {
61 #endif
62
63 #ifdef SNMP_PP_NAMESPACE
64 namespace Snmp_pp {
65 #endif
66
67 /* Constants for MD5Transform routine.
68  */
69 #define S11 7
70 #define S12 12
71 #define S13 17
72 #define S14 22
73 #define S21 5
74 #define S22 9
75 #define S23 14
76 #define S24 20
77 #define S31 4
78 #define S32 11
79 #define S33 16
80 #define S34 23
81 #define S41 6
82 #define S42 10
83 #define S43 15
84 #define S44 21
85
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));
91
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
96 };
97
98 /* F, G, H and I are basic MD5 functions.
99  */
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)))
104
105 /* ROTATE_LEFT rotates x left n bits.
106  */
107 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
108
109 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
110    Rotation is separate from addition to prevent recomputation.
111  */
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)); \
115     (a) += (b); \
116   }
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)); \
120     (a) += (b); \
121   }
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)); \
125     (a) += (b); \
126   }
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)); \
130     (a) += (b); \
131   }
132
133 /* MD5 initialization. Begins an MD5 operation, writing a new context.
134  */
135 void MD5Init (MD5_CTX *context)
136 {
137   context->count[0] = context->count[1] = 0;
138
139   /* Load magic initialization constants.
140    */
141   context->state[0] = 0x67452301;
142   context->state[1] = 0xefcdab89;
143   context->state[2] = 0x98badcfe;
144   context->state[3] = 0x10325476;
145 }
146
147 /* MD5 block update operation. Continues an MD5 message-digest operation,
148      processing another message block, and updating the context.
149  */
150 void MD5Update (MD5_CTX *context,                /* context */
151                 const unsigned char *input,      /* input block */
152                 const unsigned int inputLen)     /* length of input block */
153 {
154   unsigned int i, index, partLen;
155
156   /* Compute number of bytes mod 64 */
157   index = (unsigned int)((context->count[0] >> 3) & 0x3F);
158
159   /* Update number of bits */
160   if ((context->count[0] += ((UINT4)inputLen << 3)) < ((UINT4)inputLen << 3))
161     context->count[1]++;
162   context->count[1] += ((UINT4)inputLen >> 29);
163
164   partLen = 64 - index;
165
166   /* Transform as many times as possible.
167    */
168   if (inputLen >= partLen) {
169     MD5_memcpy ((POINTER)&context->buffer[index], (POINTER)input, partLen);
170     MD5Transform (context->state, context->buffer);
171
172     for (i = partLen; i + 63 < inputLen; i += 64)
173       MD5Transform (context->state, &input[i]);
174
175     index = 0;
176   }
177   else
178     i = 0;
179
180   /* Buffer remaining input */
181   MD5_memcpy
182     ((POINTER)&context->buffer[index], (POINTER)&input[i], inputLen-i);
183 }
184
185 /* MD5 finalization. Ends an MD5 message-digest operation, writing the
186      the message digest and zeroizing the context.
187  */
188 void MD5Final (
189 unsigned char digest[16],                                 /* message digest */
190 MD5_CTX *context)                                                /* context */
191 {
192   unsigned char bits[8];
193   unsigned int index, padLen;
194
195   /* Save number of bits */
196   Encode (bits, context->count, 8);
197
198   /* Pad out to 56 mod 64.
199    */
200   index = (unsigned int)((context->count[0] >> 3) & 0x3f);
201   padLen = (index < 56) ? (56 - index) : (120 - index);
202   MD5Update (context, PADDING, padLen);
203
204   /* Append length (before padding) */
205   MD5Update (context, bits, 8);
206
207   /* Store state in digest */
208   Encode (digest, context->state, 16);
209
210   /* Zeroize sensitive information.
211    */
212   MD5_memset ((POINTER)context, 0, sizeof (*context));
213 }
214
215 /* MD5 basic transformation. Transforms state based on block.
216  */
217 static void MD5Transform (
218 UINT4 state[4],
219 const unsigned char block[64])
220 {
221   UINT4 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    */
304   MD5_memset ((POINTER)x, 0, sizeof (x));
305 }
306
307 /* Encodes input (UINT4) into output (unsigned char). Assumes len is
308      a multiple of 4.
309  */
310 static void Encode (
311                     unsigned char *output,
312                     UINT4 *input,
313                     unsigned int len)
314 {
315   unsigned int i, j;
316
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);
322   }
323 }
324
325 /* Decodes input (unsigned char) into output (UINT4). Assumes len is
326      a multiple of 4.
327  */
328 static void Decode (
329                     UINT4 *output,
330                     const unsigned char *input,
331                     unsigned int len)
332 {
333   unsigned int i, j;
334
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);
338 }
339
340 static void MD5_memcpy (
341                         POINTER output,
342                         POINTER input,
343                         unsigned int len)
344 {
345   memcpy(output, input, len);
346 }
347
348 static void MD5_memset (
349                         POINTER output,
350                         int value,
351                         unsigned int len)
352 {
353   memset(output, value, len);
354 }
355
356 #ifdef SNMP_PP_NAMESPACE
357 }; // end of namespace Snmp_pp
358 #endif 
359
360 #ifdef __cplusplus
361 }
362 #endif
363
364 #endif // !defined(_USE_LIBTOMCRYPT) && !defined(_USE_OPENSSL)