1 /* Copyright (C) 2014 InfiniDB, Inc.
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; version 2 of
6 the License.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
16 MA 02110-1301, USA. */
17
18 /****************************************************************************
19 * $Id: func_md5.cpp 3923 2013-06-19 21:43:06Z bwilkinson $
20 *
21 *
22 ****************************************************************************/
23 #include <assert.h>
24 #include <memory.h>
25 #include <stdio.h>
26 #include <string.h>
27
28
29 #include <cstdlib>
30 #include <string>
31 #include <unistd.h>
32 #include <limits.h>
33 using namespace std;
34
35 #include "functor_str.h"
36 #include "functioncolumn.h"
37 using namespace execplan;
38
39 #include "rowgroup.h"
40 using namespace rowgroup;
41
42 namespace
43 {
44 /////////////////////////////////////////////////////////////////////////
45 // MD5.cpp
46 // Implementation file for MD5 class
47 //
48 // This C++ Class implementation of the original RSA Data Security, Inc.
49 // MD5 Message-Digest Algorithm is copyright (c) 2002, Gary McNickle.
50 // All rights reserved. This software is a derivative of the "RSA Data
51 // Security, Inc. MD5 Message-Digest Algorithm"
52 //
53 // You may use this software free of any charge, but without any
54 // warranty or implied warranty, provided that you follow the terms
55 // of the original RSA copyright, listed below.
56 //
57 // Original RSA Data Security, Inc. Copyright notice
58 /////////////////////////////////////////////////////////////////////////
59 //
60 // Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
61 // rights reserved.
62 //
63 // License to copy and use this software is granted provided that it
64 // is identified as the "RSA Data Security, Inc. MD5 Message-Digest
65 // Algorithm" in all material mentioning or referencing this software
66 // or this function.
67 // License is also granted to make and use derivative works provided
68 // that such works are identified as "derived from the RSA Data
69 // Security, Inc. MD5 Message-Digest Algorithm" in all material
70 // mentioning or referencing the derived work.
71 // RSA Data Security, Inc. makes no representations concerning either
72 // the merchantability of this software or the suitability of this
73 // software for any particular purpose. It is provided "as is"
74 // without express or implied warranty of any kind.
75 // These notices must be retained in any copies of any part of this
76 // documentation and/or software.
77 /////////////////////////////////////////////////////////////////////////
78
79 typedef unsigned int uint4;
80 typedef unsigned short int uint2;
81 typedef unsigned char uchar;
82
83 char* PrintMD5(uchar md5Digest[16]);
84 char* MD5String(const char* szString);
85 //char* MD5File(char* szFilename);
86
87 class md5
88 {
89 // Methods
90 public:
md5()91 md5()
92 {
93 Init();
94 }
95 void Init();
96 void Update(uchar* chInput, uint4 nInputLen);
97 void Finalize();
Digest()98 uchar* Digest()
99 {
100 return m_Digest;
101 }
102
103 private:
104
105 void Transform(uchar* block);
106 void Encode(uchar* dest, uint4* src, uint4 nLength);
107 void Decode(uint4* dest, uchar* src, uint4 nLength);
108
109
rotate_left(uint4 x,uint4 n)110 inline uint4 rotate_left(uint4 x, uint4 n)
111 {
112 return ((x << n) | (x >> (32 - n)));
113 }
114
F(uint4 x,uint4 y,uint4 z)115 inline uint4 F(uint4 x, uint4 y, uint4 z)
116 {
117 return ((x & y) | (~x & z));
118 }
119
G(uint4 x,uint4 y,uint4 z)120 inline uint4 G(uint4 x, uint4 y, uint4 z)
121 {
122 return ((x & z) | (y & ~z));
123 }
124
H(uint4 x,uint4 y,uint4 z)125 inline uint4 H(uint4 x, uint4 y, uint4 z)
126 {
127 return (x ^ y ^ z);
128 }
129
I(uint4 x,uint4 y,uint4 z)130 inline uint4 I(uint4 x, uint4 y, uint4 z)
131 {
132 return (y ^ (x | ~z));
133 }
134
FF(uint4 & a,uint4 b,uint4 c,uint4 d,uint4 x,uint4 s,uint4 ac)135 inline void FF(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
136 {
137 a += F(b, c, d) + x + ac;
138 a = rotate_left(a, s);
139 a += b;
140 }
141
GG(uint4 & a,uint4 b,uint4 c,uint4 d,uint4 x,uint4 s,uint4 ac)142 inline void GG(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
143 {
144 a += G(b, c, d) + x + ac;
145 a = rotate_left(a, s);
146 a += b;
147 }
148
HH(uint4 & a,uint4 b,uint4 c,uint4 d,uint4 x,uint4 s,uint4 ac)149 inline void HH(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
150 {
151 a += H(b, c, d) + x + ac;
152 a = rotate_left(a, s);
153 a += b;
154 }
155
II(uint4 & a,uint4 b,uint4 c,uint4 d,uint4 x,uint4 s,uint4 ac)156 inline void II(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
157 {
158 a += I(b, c, d) + x + ac;
159 a = rotate_left(a, s);
160 a += b;
161 }
162
163 // Data
164 private:
165 uint4 m_State[4];
166 uint4 m_Count[2];
167 uchar m_Buffer[64];
168 uchar m_Digest[16];
169 uchar m_Finalized;
170
171 };
172
173 /////////////////////////////////////////////////////////////////////////
174 // MD5.cpp
175 // Implementation file for MD5 class
176 //
177 // This C++ Class implementation of the original RSA Data Security, Inc.
178 // MD5 Message-Digest Algorithm is copyright (c) 2002, Gary McNickle.
179 // All rights reserved. This software is a derivative of the "RSA Data
180 // Security, Inc. MD5 Message-Digest Algorithm"
181 //
182 // You may use this software free of any charge, but without any
183 // warranty or implied warranty, provided that you follow the terms
184 // of the original RSA copyright, listed below.
185 //
186 // Original RSA Data Security, Inc. Copyright notice
187 /////////////////////////////////////////////////////////////////////////
188 //
189 // Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
190 // rights reserved.
191 //
192 // License to copy and use this software is granted provided that it
193 // is identified as the "RSA Data Security, Inc. MD5 Message-Digest
194 // Algorithm" in all material mentioning or referencing this software
195 // or this function.
196 // License is also granted to make and use derivative works provided
197 // that such works are identified as "derived from the RSA Data
198 // Security, Inc. MD5 Message-Digest Algorithm" in all material
199 // mentioning or referencing the derived work.
200 // RSA Data Security, Inc. makes no representations concerning either
201 // the merchantability of this software or the suitability of this
202 // software for any particular purpose. It is provided "as is"
203 // without express or implied warranty of any kind.
204 // These notices must be retained in any copies of any part of this
205 // documentation and/or software.
206 /////////////////////////////////////////////////////////////////////////
207
208 static unsigned char PADDING[64] =
209 {
210 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
211 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
212 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
213 };
214
215 #define S11 7
216 #define S12 12
217 #define S13 17
218 #define S14 22
219 #define S21 5
220 #define S22 9
221 #define S23 14
222 #define S24 20
223 #define S31 4
224 #define S32 11
225 #define S33 16
226 #define S34 23
227 #define S41 6
228 #define S42 10
229 #define S43 15
230 #define S44 21
231
232
233 // PrintMD5: Converts a completed md5 digest into a char* string.
PrintMD5(uchar md5Digest[16])234 char* PrintMD5(uchar md5Digest[16])
235 {
236 char chBuffer[256];
237 char chEach[10];
238 int nCount;
239 size_t chEachSize = 0;
240
241 memset(chBuffer, 0, 256);
242 memset(chEach, 0, 10);
243
244 for (nCount = 0; nCount < 16; nCount++)
245 {
246 sprintf(chEach, "%02x", md5Digest[nCount]);
247 chEachSize = sizeof(chEach);
248 strncat(chBuffer, chEach, chEachSize);
249 }
250
251 return strdup(chBuffer);
252 }
253
254 // MD5String: Performs the MD5 algorithm on a char* string, returning
255 // the results as a char*.
MD5String(const char * szString)256 char* MD5String(const char* szString)
257 {
258 int nLen = strlen(szString);
259 md5 alg;
260
261 alg.Update((unsigned char*)szString, (unsigned int)nLen);
262 alg.Finalize();
263
264 return PrintMD5(alg.Digest());
265
266 }
267
268 // this fcn isn't used, so commenting it
269 #if 0
270 // MD5File: Performs the MD5 algorithm on a file (binary or text),
271 // returning the results as a char*. Returns NULL if it fails.
272 char* MD5File(char* szFilename)
273 {
274 FILE* file;
275 md5 alg;
276 int nLen;
277 unsigned char chBuffer[1024];
278
279 try
280 {
281 memset(chBuffer, 0, 1024);
282
283 if ((file = fopen (szFilename, "rb")) != NULL)
284 {
285 while ((nLen = fread (chBuffer, 1, 1024, file)))
286 alg.Update(chBuffer, nLen);
287
288 alg.Finalize();
289
290 fclose (file);
291
292 return PrintMD5(alg.Digest());
293 }
294 }
295 catch (...)
296 {
297
298 }
299
300 return NULL; // failed
301 }
302 #endif
303
304 // md5::Init
305 // Initializes a new context.
Init()306 void md5::Init()
307 {
308 memset(m_Count, 0, 2 * sizeof(uint4));
309
310 m_State[0] = 0x67452301;
311 m_State[1] = 0xefcdab89;
312 m_State[2] = 0x98badcfe;
313 m_State[3] = 0x10325476;
314 }
315
316 // md5::Update
317 // MD5 block update operation. Continues an MD5 message-digest
318 // operation, processing another message block, and updating the
319 // context.
Update(uchar * chInput,uint4 nInputLen)320 void md5::Update(uchar* chInput, uint4 nInputLen)
321 {
322 uint4 i, index, partLen;
323
324 // Compute number of bytes mod 64
325 index = (unsigned int)((m_Count[0] >> 3) & 0x3F);
326
327 // Update number of bits
328 if ((m_Count[0] += (nInputLen << 3)) < (nInputLen << 3))
329 m_Count[1]++;
330
331 m_Count[1] += (nInputLen >> 29);
332
333 partLen = 64 - index;
334
335 // Transform as many times as possible.
336 if (nInputLen >= partLen)
337 {
338 memcpy( &m_Buffer[index], chInput, partLen );
339 Transform(m_Buffer);
340
341 for (i = partLen; i + 63 < nInputLen; i += 64)
342 Transform(&chInput[i]);
343
344 index = 0;
345 }
346 else
347 i = 0;
348
349 // Buffer remaining input
350 memcpy( &m_Buffer[index], &chInput[i], nInputLen - i );
351 }
352
353 // md5::Finalize
354 // MD5 finalization. Ends an MD5 message-digest operation, writing
355 // the message digest and zeroizing the context.
Finalize()356 void md5::Finalize()
357 {
358 uchar bits[8];
359 uint4 index, padLen;
360
361 // Save number of bits
362 Encode (bits, m_Count, 8);
363
364 // Pad out to 56 mod 64
365 index = (unsigned int)((m_Count[0] >> 3) & 0x3f);
366 padLen = (index < 56) ? (56 - index) : (120 - index);
367 Update(PADDING, padLen);
368
369 // Append length (before padding)
370 Update (bits, 8);
371
372 // Store state in digest
373 Encode (m_Digest, m_State, 16);
374
375 memset(m_Count, 0, 2 * sizeof(uint4));
376 memset(m_State, 0, 4 * sizeof(uint4));
377 memset(m_Buffer, 0, 64 * sizeof(uchar));
378 }
379
380 // md5::Transform
381 // MD5 basic transformation. Transforms state based on block.
Transform(uchar * block)382 void md5::Transform (uchar* block)
383 {
384 uint4 a = m_State[0], b = m_State[1], c = m_State[2], d = m_State[3], x[16];
385
386 Decode (x, block, 64);
387
388 // Round 1
389 FF (a, b, c, d, x[ 0], S11, 0xd76aa478);
390 FF (d, a, b, c, x[ 1], S12, 0xe8c7b756);
391 FF (c, d, a, b, x[ 2], S13, 0x242070db);
392 FF (b, c, d, a, x[ 3], S14, 0xc1bdceee);
393 FF (a, b, c, d, x[ 4], S11, 0xf57c0faf);
394 FF (d, a, b, c, x[ 5], S12, 0x4787c62a);
395 FF (c, d, a, b, x[ 6], S13, 0xa8304613);
396 FF (b, c, d, a, x[ 7], S14, 0xfd469501);
397 FF (a, b, c, d, x[ 8], S11, 0x698098d8);
398 FF (d, a, b, c, x[ 9], S12, 0x8b44f7af);
399 FF (c, d, a, b, x[10], S13, 0xffff5bb1);
400 FF (b, c, d, a, x[11], S14, 0x895cd7be);
401 FF (a, b, c, d, x[12], S11, 0x6b901122);
402 FF (d, a, b, c, x[13], S12, 0xfd987193);
403 FF (c, d, a, b, x[14], S13, 0xa679438e);
404 FF (b, c, d, a, x[15], S14, 0x49b40821);
405
406 // Round 2
407 GG (a, b, c, d, x[ 1], S21, 0xf61e2562);
408 GG (d, a, b, c, x[ 6], S22, 0xc040b340);
409 GG (c, d, a, b, x[11], S23, 0x265e5a51);
410 GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa);
411 GG (a, b, c, d, x[ 5], S21, 0xd62f105d);
412 GG (d, a, b, c, x[10], S22, 0x2441453);
413 GG (c, d, a, b, x[15], S23, 0xd8a1e681);
414 GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8);
415 GG (a, b, c, d, x[ 9], S21, 0x21e1cde6);
416 GG (d, a, b, c, x[14], S22, 0xc33707d6);
417 GG (c, d, a, b, x[ 3], S23, 0xf4d50d87);
418 GG (b, c, d, a, x[ 8], S24, 0x455a14ed);
419 GG (a, b, c, d, x[13], S21, 0xa9e3e905);
420 GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8);
421 GG (c, d, a, b, x[ 7], S23, 0x676f02d9);
422 GG (b, c, d, a, x[12], S24, 0x8d2a4c8a);
423
424 // Round 3
425 HH (a, b, c, d, x[ 5], S31, 0xfffa3942);
426 HH (d, a, b, c, x[ 8], S32, 0x8771f681);
427 HH (c, d, a, b, x[11], S33, 0x6d9d6122);
428 HH (b, c, d, a, x[14], S34, 0xfde5380c);
429 HH (a, b, c, d, x[ 1], S31, 0xa4beea44);
430 HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9);
431 HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60);
432 HH (b, c, d, a, x[10], S34, 0xbebfbc70);
433 HH (a, b, c, d, x[13], S31, 0x289b7ec6);
434 HH (d, a, b, c, x[ 0], S32, 0xeaa127fa);
435 HH (c, d, a, b, x[ 3], S33, 0xd4ef3085);
436 HH (b, c, d, a, x[ 6], S34, 0x4881d05);
437 HH (a, b, c, d, x[ 9], S31, 0xd9d4d039);
438 HH (d, a, b, c, x[12], S32, 0xe6db99e5);
439 HH (c, d, a, b, x[15], S33, 0x1fa27cf8);
440 HH (b, c, d, a, x[ 2], S34, 0xc4ac5665);
441
442 // Round 4
443 II (a, b, c, d, x[ 0], S41, 0xf4292244);
444 II (d, a, b, c, x[ 7], S42, 0x432aff97);
445 II (c, d, a, b, x[14], S43, 0xab9423a7);
446 II (b, c, d, a, x[ 5], S44, 0xfc93a039);
447 II (a, b, c, d, x[12], S41, 0x655b59c3);
448 II (d, a, b, c, x[ 3], S42, 0x8f0ccc92);
449 II (c, d, a, b, x[10], S43, 0xffeff47d);
450 II (b, c, d, a, x[ 1], S44, 0x85845dd1);
451 II (a, b, c, d, x[ 8], S41, 0x6fa87e4f);
452 II (d, a, b, c, x[15], S42, 0xfe2ce6e0);
453 II (c, d, a, b, x[ 6], S43, 0xa3014314);
454 II (b, c, d, a, x[13], S44, 0x4e0811a1);
455 II (a, b, c, d, x[ 4], S41, 0xf7537e82);
456 II (d, a, b, c, x[11], S42, 0xbd3af235);
457 II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb);
458 II (b, c, d, a, x[ 9], S44, 0xeb86d391);
459
460 m_State[0] += a;
461 m_State[1] += b;
462 m_State[2] += c;
463 m_State[3] += d;
464
465 memset(x, 0, sizeof(x));
466 }
467
468 // md5::Encode
469 // Encodes input (uint4) into output (uchar). Assumes nLength is
470 // a multiple of 4.
Encode(uchar * dest,uint4 * src,uint4 nLength)471 void md5::Encode(uchar* dest, uint4* src, uint4 nLength)
472 {
473 uint4 i, j;
474
475 idbassert(nLength % 4 == 0);
476
477 for (i = 0, j = 0; j < nLength; i++, j += 4)
478 {
479 dest[j] = (uchar)(src[i] & 0xff);
480 dest[j + 1] = (uchar)((src[i] >> 8) & 0xff);
481 dest[j + 2] = (uchar)((src[i] >> 16) & 0xff);
482 dest[j + 3] = (uchar)((src[i] >> 24) & 0xff);
483 }
484 }
485
486 // md5::Decode
487 // Decodes input (uchar) into output (uint4). Assumes nLength is
488 // a multiple of 4.
Decode(uint4 * dest,uchar * src,uint4 nLength)489 void md5::Decode(uint4* dest, uchar* src, uint4 nLength)
490 {
491 uint4 i, j;
492
493 idbassert(nLength % 4 == 0);
494
495 for (i = 0, j = 0; j < nLength; i++, j += 4)
496 {
497 dest[i] = ((uint4)src[j]) | (((uint4)src[j + 1]) << 8) |
498 (((uint4)src[j + 2]) << 16) | (((uint4)src[j + 3]) << 24);
499 }
500 }
501
502 }
503
504
505 namespace funcexp
506 {
operationType(FunctionParm & fp,CalpontSystemCatalog::ColType & resultType)507 CalpontSystemCatalog::ColType Func_md5::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
508 {
509 // operation type is not used by this functor
510 return fp[0]->data()->resultType();
511 }
512
513
getStrVal(rowgroup::Row & row,FunctionParm & parm,bool & isNull,CalpontSystemCatalog::ColType & op_ct)514 string Func_md5::getStrVal(rowgroup::Row& row,
515 FunctionParm& parm,
516 bool& isNull,
517 CalpontSystemCatalog::ColType& op_ct)
518 {
519 const string& arg = parm[0]->data()->getStrVal(row, isNull);
520 return MD5String(arg.c_str());
521
522 //return str;
523 }
524
525
526 } // namespace funcexp
527
528
529 // vim:ts=4 sw=4:
530