llmd5.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:14k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llmd5.cpp
  3.  *
  4.  * $LicenseInfo:firstyear=2001&license=viewergpl$
  5.  * 
  6.  * Copyright (c) 2001-2010, Linden Research, Inc.
  7.  * 
  8.  * Second Life Viewer Source Code
  9.  * The source code in this file ("Source Code") is provided by Linden Lab
  10.  * to you under the terms of the GNU General Public License, version 2.0
  11.  * ("GPL"), unless you have obtained a separate licensing agreement
  12.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  13.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  14.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  15.  * 
  16.  * There are special exceptions to the terms and conditions of the GPL as
  17.  * it is applied to this Source Code. View the full text of the exception
  18.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  19.  * online at
  20.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  21.  * 
  22.  * By copying, modifying or distributing this software, you acknowledge
  23.  * that you have read and understood your obligations described above,
  24.  * and agree to abide by those obligations.
  25.  * 
  26.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  27.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  28.  * COMPLETENESS OR PERFORMANCE.
  29.  * $/LicenseInfo$
  30.  */
  31. // llMD5.CC - source code for the C++/object oriented translation and 
  32. //          modification of MD5.
  33. //
  34. // Adapted to Linden Lab by Frank Filipanits, 6/25/2002
  35. // Fixed potential memory leak, James Cook, 6/27/2002
  36. // Translation and modification (c) 1995 by Mordechai T. Abzug 
  37. // This translation/ modification is provided "as is," without express or 
  38. // implied warranty of any kind.
  39. // The translator/ modifier does not claim (1) that MD5 will do what you think 
  40. // it does; (2) that this translation/ modification is accurate; or (3) that 
  41. // this software is "merchantible."  (Language for this disclaimer partially 
  42. // copied from the disclaimer below).
  43. /* based on:
  44.    MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
  45.    MDDRIVER.C - test driver for MD2, MD4 and MD5
  46.    Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
  47. rights reserved.
  48. License to copy and use this software is granted provided that it
  49. is identified as the "RSA Data Security, Inc. MD5 Message-Digest
  50. Algorithm" in all material mentioning or referencing this software
  51. or this function.
  52. License is also granted to make and use derivative works provided
  53. that such works are identified as "derived from the RSA Data
  54. Security, Inc. MD5 Message-Digest Algorithm" in all material
  55. mentioning or referencing the derived work.
  56. RSA Data Security, Inc. makes no representations concerning either
  57. the merchantability of this software or the suitability of this
  58. software for any particular purpose. It is provided "as is"
  59. without express or implied warranty of any kind.
  60. These notices must be retained in any copies of any part of this
  61. documentation and/or software.
  62.  */
  63. #include "linden_common.h"
  64. #include "llmd5.h"
  65. #include <cassert>
  66. #include <iostream> // cerr
  67. // how many bytes to grab at a time when checking files
  68. const int LLMD5::BLOCK_LEN = 4096;
  69. // LLMD5 simple initialization method
  70. LLMD5::LLMD5()
  71. {
  72.   init();
  73. }
  74. // MD5 block update operation. Continues an MD5 message-digest
  75. // operation, processing another message block, and updating the
  76. // context.
  77. void LLMD5::update (const uint1 *input, const uint4 input_length) {
  78.   uint4 input_index, buffer_index;
  79.   uint4 buffer_space;                // how much space is left in buffer
  80.   if (finalized){  // so we can't update!
  81.   std::cerr << "LLMD5::update:  Can't update a finalized digest!" << std::endl;
  82.     return;
  83.   }
  84.   // Compute number of bytes mod 64
  85.   buffer_index = (unsigned int)((count[0] >> 3) & 0x3F);
  86.   // Update number of bits
  87.   if (  (count[0] += ((uint4) input_length << 3))<((uint4) input_length << 3) )
  88.     count[1]++;
  89.   count[1] += ((uint4)input_length >> 29);
  90.   buffer_space = 64 - buffer_index;  // how much space is left in buffer
  91.   // Transform as many times as possible.
  92.   if (input_length >= buffer_space) { // ie. we have enough to fill the buffer
  93.     // fill the rest of the buffer and transform
  94.     memcpy( /* Flawfinder: ignore */
  95. buffer + buffer_index,
  96. input,
  97. buffer_space);
  98.     transform (buffer);
  99.     // now, transform each 64-byte piece of the input, bypassing the buffer
  100.   if (input == NULL || input_length == 0){
  101. std::cerr << "LLMD5::update:  Invalid input!" << std::endl;
  102. return;
  103.   }
  104.     for (input_index = buffer_space; input_index + 63 < input_length; 
  105.  input_index += 64)
  106.       transform (input+input_index);
  107.     buffer_index = 0;  // so we can buffer remaining
  108.   }
  109.   else
  110.     input_index=0;     // so we can buffer the whole input
  111.   // and here we do the buffering:
  112.   memcpy(buffer+buffer_index, input+input_index, input_length-input_index); /* Flawfinder: ignore */
  113. }
  114. // MD5 update for files.
  115. // Like above, except that it works on files (and uses above as a primitive.)
  116. void LLMD5::update(FILE* file){
  117.   unsigned char buffer[BLOCK_LEN]; /* Flawfinder: ignore */
  118.   int len;
  119.   while ( (len=(int)fread(buffer, 1, BLOCK_LEN, file)) )
  120.     update(buffer, len);
  121.   fclose (file);
  122. }
  123. // MD5 update for istreams.
  124. // Like update for files; see above.
  125. void LLMD5::update(std::istream& stream){
  126.   unsigned char buffer[BLOCK_LEN]; /* Flawfinder: ignore */
  127.   int len;
  128.   while (stream.good()){
  129.     stream.read( (char*)buffer, BLOCK_LEN);  /* Flawfinder: ignore */ // note that return value of read is unusable.
  130.     len=stream.gcount();
  131.     update(buffer, len);
  132.   }
  133. }
  134. // MD5 finalization. Ends an MD5 message-digest operation, writing the
  135. // the message digest and zeroizing the context.
  136. void LLMD5::finalize (){
  137.   unsigned char bits[8]; /* Flawfinder: ignore */
  138.   unsigned int index, padLen;
  139.   static uint1 PADDING[64]={
  140.     0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  141.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  142.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  143.     };
  144.   if (finalized){
  145.     std::cerr << "LLMD5::finalize:  Already finalized this digest!" << std::endl;
  146.     return;
  147.   }
  148.   // Save number of bits
  149.   encode (bits, count, 8);
  150.   // Pad out to 56 mod 64.
  151.   index = (uint4) ((count[0] >> 3) & 0x3f);
  152.   padLen = (index < 56) ? (56 - index) : (120 - index);
  153.   update (PADDING, padLen);
  154.   // Append length (before padding)
  155.   update (bits, 8);
  156.   // Store state in digest
  157.   encode (digest, state, 16);
  158.   // Zeroize sensitive information
  159.   memset (buffer, 0, sizeof(*buffer));
  160.   finalized=1;
  161. }
  162. LLMD5::LLMD5(FILE *file){
  163.   init();  // must be called be all constructors
  164.   update(file);
  165.   finalize ();
  166. }
  167. LLMD5::LLMD5(std::istream& stream){
  168.   init();  // must called by all constructors
  169.   update (stream);
  170.   finalize();
  171. }
  172. // Digest a string of the format ("%s:%i" % (s, number))
  173. LLMD5::LLMD5(const unsigned char *string, const unsigned int number)
  174. {
  175. const char *colon = ":";
  176. char tbuf[16]; /* Flawfinder: ignore */
  177. init();
  178. update(string, (U32)strlen((const char *) string)); /* Flawfinder: ignore */
  179. update((const unsigned char *) colon, (U32)strlen(colon)); /* Flawfinder: ignore */
  180. snprintf(tbuf, sizeof(tbuf), "%i", number); /* Flawfinder: ignore */
  181. update((const unsigned char *) tbuf, (U32)strlen(tbuf)); /* Flawfinder: ignore */
  182. finalize();
  183. }
  184. // Digest a string
  185. LLMD5::LLMD5(const unsigned char *s)
  186. {
  187. init();
  188. update(s, (U32)strlen((const char *) s)); /* Flawfinder: ignore */
  189. finalize();
  190. }
  191. void LLMD5::raw_digest(unsigned char *s)
  192. {
  193. if (!finalized)
  194. {
  195. std::cerr << "LLMD5::raw_digest:  Can't get digest if you haven't "<<
  196. "finalized the digest!" << std::endl;
  197. s[0] = '';
  198. return;
  199. }
  200. memcpy(s, digest, 16); /* Flawfinder: ignore */
  201. return;
  202. }
  203. void LLMD5::hex_digest(char *s)
  204. {
  205. int i;
  206. if (!finalized)
  207. {
  208. std::cerr << "LLMD5::hex_digest:  Can't get digest if you haven't "<<
  209.   "finalized the digest!" <<std::endl;
  210. s[0] = '';
  211. return;
  212. }
  213. for (i=0; i<16; i++)
  214. {
  215. sprintf(s+i*2, "%02x", digest[i]); /* Flawfinder: ignore */
  216. }
  217. s[32]='';
  218. return;
  219. }
  220. std::ostream& operator<<(std::ostream &stream, LLMD5 context)
  221. {
  222. char s[33]; /* Flawfinder: ignore */
  223. context.hex_digest(s);
  224. stream << s;
  225. return stream;
  226. }
  227. // PRIVATE METHODS:
  228. void LLMD5::init(){
  229.   finalized=0;  // we just started!
  230.   // Nothing counted, so count=0
  231.   count[0] = 0;
  232.   count[1] = 0;
  233.   // Load magic initialization constants.
  234.   state[0] = 0x67452301;
  235.   state[1] = 0xefcdab89;
  236.   state[2] = 0x98badcfe;
  237.   state[3] = 0x10325476;
  238. }
  239. // Constants for MD5Transform routine.
  240. // Although we could use C++ style constants, defines are actually better,
  241. // since they let us easily evade scope clashes.
  242. #define S11 7
  243. #define S12 12
  244. #define S13 17
  245. #define S14 22
  246. #define S21 5
  247. #define S22 9
  248. #define S23 14
  249. #define S24 20
  250. #define S31 4
  251. #define S32 11
  252. #define S33 16
  253. #define S34 23
  254. #define S41 6
  255. #define S42 10
  256. #define S43 15
  257. #define S44 21
  258. // #defines are faster then inline, etc because the compiler is not required to inline.
  259. // Timing tests prove that this works ~40% faster on win with msvc++2k3 over using static inline.
  260. /* F, G, H and I are basic MD5 functions.
  261.  */
  262. #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
  263. #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
  264. #define H(x, y, z) ((x) ^ (y) ^ (z))
  265. #define I(x, y, z) ((y) ^ ((x) | (~z)))
  266. /* ROTATE_LEFT rotates x left n bits.
  267.  */
  268. #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
  269. /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
  270. Rotation is separate from addition to prevent recomputation.
  271.  */
  272. #define FF(a, b, c, d, x, s, ac) { 
  273.  (a) += F ((b), (c), (d)) + (x) + (U32)(ac); 
  274.  (a) = ROTATE_LEFT ((a), (s)); 
  275.  (a) += (b); 
  276.   }
  277. #define GG(a, b, c, d, x, s, ac) { 
  278.  (a) += G ((b), (c), (d)) + (x) + (U32)(ac); 
  279.  (a) = ROTATE_LEFT ((a), (s)); 
  280.  (a) += (b); 
  281.   }
  282. #define HH(a, b, c, d, x, s, ac) { 
  283.  (a) += H ((b), (c), (d)) + (x) + (U32)(ac); 
  284.  (a) = ROTATE_LEFT ((a), (s)); 
  285.  (a) += (b); 
  286.   }
  287. #define II(a, b, c, d, x, s, ac) { 
  288.  (a) += I ((b), (c), (d)) + (x) + (U32)(ac); 
  289.  (a) = ROTATE_LEFT ((a), (s)); 
  290.  (a) += (b); 
  291.   }
  292. // LLMD5 basic transformation. Transforms state based on block.
  293. void LLMD5::transform (const U8 block[64]){
  294.   uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
  295.   decode (x, block, 64);
  296.   assert(!finalized);  // not just a user error, since the method is private
  297.   /* Round 1 */
  298.   FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
  299.   FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
  300.   FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
  301.   FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
  302.   FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
  303.   FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
  304.   FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
  305.   FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
  306.   FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
  307.   FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
  308.   FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
  309.   FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
  310.   FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
  311.   FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
  312.   FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
  313.   FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
  314.  /* Round 2 */
  315.   GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
  316.   GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
  317.   GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
  318.   GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
  319.   GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
  320.   GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
  321.   GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
  322.   GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
  323.   GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
  324.   GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
  325.   GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
  326.   GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
  327.   GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
  328.   GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
  329.   GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
  330.   GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
  331.   /* Round 3 */
  332.   HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
  333.   HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
  334.   HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
  335.   HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
  336.   HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
  337.   HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
  338.   HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
  339.   HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
  340.   HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
  341.   HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
  342.   HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
  343.   HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
  344.   HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
  345.   HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
  346.   HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
  347.   HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
  348.   /* Round 4 */
  349.   II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
  350.   II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
  351.   II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
  352.   II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
  353.   II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
  354.   II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
  355.   II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
  356.   II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
  357.   II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
  358.   II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
  359.   II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
  360.   II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
  361.   II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
  362.   II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
  363.   II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
  364.   II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
  365.   state[0] += a;
  366.   state[1] += b;
  367.   state[2] += c;
  368.   state[3] += d;
  369.   // Zeroize sensitive information.
  370.   memset ( (uint1 *) x, 0, sizeof(x));
  371. }
  372. // Encodes input (UINT4) into output (unsigned char). Assumes len is
  373. // a multiple of 4.
  374. void LLMD5::encode (uint1 *output, const uint4 *input, const uint4 len) {
  375.   unsigned int i, j;
  376.   for (i = 0, j = 0; j < len; i++, j += 4) {
  377.     output[j]   = (uint1)  (input[i] & 0xff);
  378.     output[j+1] = (uint1) ((input[i] >> 8) & 0xff);
  379.     output[j+2] = (uint1) ((input[i] >> 16) & 0xff);
  380.     output[j+3] = (uint1) ((input[i] >> 24) & 0xff);
  381.   }
  382. }
  383. // Decodes input (unsigned char) into output (UINT4). Assumes len is
  384. // a multiple of 4.
  385. void LLMD5::decode (uint4 *output, const uint1 *input, const uint4 len){
  386.   unsigned int i, j;
  387.   for (i = 0, j = 0; j < len; i++, j += 4)
  388.     output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) |
  389.       (((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24);
  390. }