CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
GenMD5.cc
Go to the documentation of this file.
1 // MD5.CC - source code for the C++/object oriented translation and
2 // modification of MD5.
3 
4 // Translation and modification (c) 1995 by Mordechai T. Abzug
5 
6 // This translation/ modification is provided "as is," without express or
7 // implied warranty of any kind.
8 
9 // The translator/ modifier does not claim (1) that MD5 will do what you think
10 // it does; (2) that this translation/ modification is accurate; or (3) that
11 // this software is "merchantible." (Language for this disclaimer partially
12 // copied from the disclaimer below).
13 
14 /* based on:
15 
16  MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
17  MDDRIVER.C - test driver for MD2, MD4 and MD5
18 
19 
20  Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
21 rights reserved.
22 
23 License to copy and use this software is granted provided that it
24 is identified as the "RSA Data Security, Inc. MD5 Message-Digest
25 Algorithm" in all material mentioning or referencing this software
26 or this function.
27 
28 License is also granted to make and use derivative works provided
29 that such works are identified as "derived from the RSA Data
30 Security, Inc. MD5 Message-Digest Algorithm" in all material
31 mentioning or referencing the derived work.
32 
33 RSA Data Security, Inc. makes no representations concerning either
34 the merchantability of this software or the suitability of this
35 software for any particular purpose. It is provided "as is"
36 without express or implied warranty of any kind.
37 
38 These notices must be retained in any copies of any part of this
39 documentation and/or software.
40 
41 */
42 #include <cassert>
43 #include <string>
44 #include <cstdio>
45 #include <cstring>
46 #include <iostream>
47 
48 using namespace std;
49 
50 // Constants for MD5Transform routine.
51 // Although we could use C++ style constants, defines are actually better,
52 // since they let us easily evade scope clashes.
53 #define S11 7
54 #define S12 12
55 #define S13 17
56 #define S14 22
57 #define S21 5
58 #define S22 9
59 #define S23 14
60 #define S24 20
61 #define S31 4
62 #define S32 11
63 #define S33 16
64 #define S34 23
65 #define S41 6
66 #define S42 10
67 #define S43 15
68 #define S44 21
69 
70 namespace {
71  class MD5 {
72  public:
74  MD5 (unsigned char* buffer, unsigned long len);
76  MD5 ();
78  void update (unsigned char *input, unsigned int input_length);
79  // Finalize MD5 check-sum
80  void finalize ();
81 
83  void raw_digest (unsigned char *buff);
85 
87  string hex_digest ();
89 
90  private:
91  // next, the private data:
92  unsigned int state[4];
93  unsigned int count[2]; // number of *bits*, mod 2^64
94  unsigned char buffer[64]; // input buffer
95  unsigned char digest[16];
96  unsigned char finalized;
97 
98  // last, the private methods, mostly static:
99  void init (); // called by all constructors
100  void transform (unsigned char *buffer); // does the real update work. Note
101  // that length is implied to be 64.
102 
103  static void encode (unsigned char *dest, unsigned int *src, unsigned int length);
104  static void decode (unsigned int *dest, unsigned char *src, unsigned int length);
105 
106  // ROTATE_LEFT rotates x left n bits.
107  static inline unsigned int rotate_left (unsigned int x, unsigned int n)
108  { return (x << n) | (x >> (32-n)); }
109  // F, G, H and I are basic MD5 functions.
110  static inline unsigned int F(unsigned int x, unsigned int y, unsigned int z)
111  { return (x & y) | (~x & z); }
112  static inline unsigned int G(unsigned int x, unsigned int y, unsigned int z)
113  { return (x & z) | (y & ~z); }
114  static inline unsigned int H(unsigned int x, unsigned int y, unsigned int z)
115  { return x ^ y ^ z; }
116  static inline unsigned int I(unsigned int x, unsigned int y, unsigned int z)
117  { return y ^ (x | ~z); }
118 
119  // FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
120  // Rotation is separate from addition to prevent recomputation.
121  static inline void FF (unsigned int& a, unsigned int b, unsigned int c, unsigned int d, unsigned int x, unsigned int s, unsigned int ac)
122  {
123  a += F(b, c, d) + x + ac;
124  a = rotate_left(a, s) + b;
125  }
126  static inline void GG (unsigned int& a, unsigned int b, unsigned int c, unsigned int d, unsigned int x, unsigned int s, unsigned int ac)
127  {
128  a += G(b, c, d) + x + ac;
129  a = rotate_left(a, s) + b;
130  }
131  static inline void HH (unsigned int& a, unsigned int b, unsigned int c, unsigned int d, unsigned int x, unsigned int s, unsigned int ac)
132  {
133  a += H(b, c, d) + x + ac;
134  a = rotate_left(a, s) + b;
135  }
136  static inline void II (unsigned int& a, unsigned int b, unsigned int c, unsigned int d, unsigned int x, unsigned int s, unsigned int ac)
137  {
138  a += I(b, c, d) + x + ac;
139  a = rotate_left(a, s) + b;
140  }
141  };
142 }
143 
144 // MD5 simple initialization method
145 MD5::MD5() {
146  init();
147 }
148 
149 // MD5 simple initialization method
150 MD5::MD5(unsigned char* buffer, unsigned long len) {
151  init();
152  update(buffer, len);
153  finalize();
154 }
155 
156 // MD5 block update operation. Continues an MD5 message-digest
157 // operation, processing another message block, and updating the
158 // context.
159 void MD5::update (unsigned char *input, unsigned int input_length) {
160  unsigned int idx, index, space;
161  if ( finalized ) { // so we can't update!
162  cerr << "MD5::update: Can't update a finalized digest!" << endl;
163  return;
164  }
165  // Compute number of bytes mod 64
166  index = (unsigned int)((count[0] >> 3) & 0x3F);
167  // Update number of bits
168  if ( (count[0] += ((unsigned int) input_length << 3))<((unsigned int) input_length << 3) )
169  count[1]++;
170 
171  count[1] += ((unsigned int)input_length >> 29);
172  space = 64 - index; // how much space is left in buffer
173  // Transform as many times as possible.
174  if (input_length >= space) { // ie. we have enough to fill the buffer
175  // fill the rest of the buffer and transform
176  memcpy (buffer + index, input, space);
177  transform (buffer);
178  // now, transform each 64-byte piece of the input, bypassing the buffer
179  for (idx = space; idx + 63 < input_length; idx += 64)
180  transform (input+idx);
181 
182  index = 0; // so we can buffer remaining
183  }
184  else {
185  idx = 0; // so we can buffer the whole input
186  }
187 
188  // and here we do the buffering:
189  memcpy(buffer+index, input+idx, input_length-idx);
190 }
191 
192 // MD5 finalization. Ends an MD5 message-digest operation, writing the
193 // the message digest and zeroizing the context.
194 void MD5::finalize () {
195  unsigned char bits[8];
196  unsigned int index, padLen;
197  static unsigned char PADDING[64]={
198  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
199  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
201  };
202  if (finalized){
203  cerr << "MD5::finalize: Already finalized this digest!" << endl;
204  return;
205  }
206  // Save number of bits
207  encode (bits, count, 8);
208  // Pad out to 56 mod 64.
209  index = (unsigned int) ((count[0] >> 3) & 0x3f);
210  padLen = (index < 56) ? (56 - index) : (120 - index);
211  update (PADDING, padLen);
212  // Append length (before padding)
213  update (bits, 8);
214  // Store state in digest
215  encode (digest, state, 16);
216  // Zeroize sensitive information
217  memset (buffer, 0, sizeof(*buffer));
218  finalized=1;
219 }
220 
222 void MD5::raw_digest(unsigned char *s){
223  if (finalized){
224  memcpy(s, digest, 16);
225  return;
226  }
227  cerr << "MD5::raw_digest: Can't get digest if you haven't "<<
228  "finalized the digest!" << endl;
229 }
230 
231 string MD5::hex_digest() {
232  char s[33];
233  if (!finalized){
234  cerr << "MD5::hex_digest: Can't get digest if you haven't "<<
235  "finalized the digest!" <<endl;
236  return "";
237  }
238  for (int i=0; i<16; i++)
239  sprintf(s+i*2, "%02x", digest[i]);
240  s[32]='\0';
241  return s;
242 }
243 
244 // PRIVATE METHODS:
245 void MD5::init(){
246  finalized=0; // we just started!
247  // Nothing counted, so count=0
248  count[0] = 0;
249  count[1] = 0;
250  // Load magic initialization constants.
251  state[0] = 0x67452301;
252  state[1] = 0xefcdab89;
253  state[2] = 0x98badcfe;
254  state[3] = 0x10325476;
255 }
256 
257 // MD5 basic transformation. Transforms state based on block.
258 void MD5::transform (unsigned char* block){
259  unsigned int a = state[0], b = state[1], c = state[2], d = state[3], x[16];
260  decode (x, block, 64);
261  assert(!finalized); // not just a user error, since the method is private
262  /* Round 1 */
263  FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
264  FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
265  FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
266  FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
267  FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
268  FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
269  FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
270  FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
271  FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
272  FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
273  FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
274  FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
275  FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
276  FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
277  FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
278  FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
279  /* Round 2 */
280  GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
281  GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
282  GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
283  GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
284  GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
285  GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
286  GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
287  GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
288  GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
289  GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
290  GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
291  GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
292  GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
293  GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
294  GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
295  GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
296  /* Round 3 */
297  HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
298  HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
299  HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
300  HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
301  HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
302  HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
303  HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
304  HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
305  HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
306  HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
307  HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
308  HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
309  HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
310  HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
311  HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
312  HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
313  /* Round 4 */
314  II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
315  II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
316  II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
317  II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
318  II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
319  II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
320  II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
321  II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
322  II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
323  II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
324  II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
325  II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
326  II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
327  II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
328  II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
329  II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
330  state[0] += a;
331  state[1] += b;
332  state[2] += c;
333  state[3] += d;
334  // Zeroize sensitive information.
335  memset ( (unsigned char *) x, 0, sizeof(x));
336 }
337 
338 // Encodes input (unsigned int) into output (unsigned char). Assumes len is
339 // a multiple of 4.
340 void MD5::encode (unsigned char *output, unsigned int *input, unsigned int len) {
341  for (unsigned int i = 0, j = 0; j < len; i++, j += 4) {
342  output[j] = (unsigned char) (input[i] & 0xff);
343  output[j+1] = (unsigned char) ((input[i] >> 8) & 0xff);
344  output[j+2] = (unsigned char) ((input[i] >> 16) & 0xff);
345  output[j+3] = (unsigned char) ((input[i] >> 24) & 0xff);
346  }
347 }
348 
349 // Decodes input (unsigned char) into output (unsigned int). Assumes len is
350 // a multiple of 4.
351 void MD5::decode (unsigned int *output, unsigned char *input, unsigned int len){
352  for (unsigned int i = 0, j = 0; j < len; i++, j += 4)
353  output[i] = ((unsigned int)input[j]) | (((unsigned int)input[j+1]) << 8) |
354  (((unsigned int)input[j+2]) << 16) | (((unsigned int)input[j+3]) << 24);
355 }
356 
357 namespace cond {
358  void* genMD5(void* buffer, unsigned long len, void* code) {
359  MD5 checkSum((unsigned char*)buffer, len);
360  checkSum.raw_digest((unsigned char*)code);
361  return code;
362  }
363  void genMD5(const string& s, void* code) {
364  MD5 checkSum((unsigned char*)s.c_str(), s.length());
365  checkSum.raw_digest((unsigned char*)code);
366  }
367 }
int i
Definition: DBlmapReader.cc:9
#define S14
Definition: GenMD5.cc:56
#define S42
Definition: GenMD5.cc:66
#define S11
Definition: GenMD5.cc:53
#define S31
Definition: GenMD5.cc:61
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision bits
int init
Definition: HydjetWrapper.h:63
#define S32
Definition: GenMD5.cc:62
#define S34
Definition: GenMD5.cc:64
#define S23
Definition: GenMD5.cc:59
Definition: DDAxes.h:10
void * genMD5(void *buffer, unsigned long len, void *code)
Definition: GenMD5.cc:358
#define S44
Definition: GenMD5.cc:68
#define S13
Definition: GenMD5.cc:55
#define S33
Definition: GenMD5.cc:63
bool decode(bool &, std::string const &)
Definition: types.cc:67
int j
Definition: DBlmapReader.cc:9
const std::complex< double > I
Definition: I.h:8
block
Formating index page&#39;s pieces.
Definition: Association.py:187
tuple input
Definition: collect_tpl.py:10
#define S21
Definition: GenMD5.cc:57
double b
Definition: hdecay.h:120
char state
Definition: procUtils.cc:75
#define update(a, b)
double a
Definition: hdecay.h:121
#define S41
Definition: GenMD5.cc:65
#define S24
Definition: GenMD5.cc:60
string s
Definition: asciidump.py:422
#define S12
Definition: GenMD5.cc:54
#define S43
Definition: GenMD5.cc:67
#define S22
Definition: GenMD5.cc:58
tuple src
Definition: align_tpl.py:87