From 38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 Mon Sep 17 00:00:00 2001 From: Jacek Antonelli Date: Fri, 15 Aug 2008 23:44:46 -0500 Subject: Second Life viewer sources 1.13.2.12 --- linden/indra/llmath/llmd5.cpp | 574 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 574 insertions(+) create mode 100644 linden/indra/llmath/llmd5.cpp (limited to 'linden/indra/llmath/llmd5.cpp') diff --git a/linden/indra/llmath/llmd5.cpp b/linden/indra/llmath/llmd5.cpp new file mode 100644 index 0000000..19174af --- /dev/null +++ b/linden/indra/llmath/llmd5.cpp @@ -0,0 +1,574 @@ +/** + * @file llmd5.cpp + * + * Copyright (c) 2001-2007, Linden Research, Inc. + * + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + */ + +// llMD5.CC - source code for the C++/object oriented translation and +// modification of MD5. +// +// Adapted to Linden Lab by Frank Filipanits, 6/25/2002 +// Fixed potential memory leak, James Cook, 6/27/2002 + +// Translation and modification (c) 1995 by Mordechai T. Abzug + +// This translation/ modification is provided "as is," without express or +// implied warranty of any kind. + +// The translator/ modifier does not claim (1) that MD5 will do what you think +// it does; (2) that this translation/ modification is accurate; or (3) that +// this software is "merchantible." (Language for this disclaimer partially +// copied from the disclaimer below). + +/* based on: + + MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm + MDDRIVER.C - test driver for MD2, MD4 and MD5 + + + Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All +rights reserved. + +License to copy and use this software is granted provided that it +is identified as the "RSA Data Security, Inc. MD5 Message-Digest +Algorithm" in all material mentioning or referencing this software +or this function. + +License is also granted to make and use derivative works provided +that such works are identified as "derived from the RSA Data +Security, Inc. MD5 Message-Digest Algorithm" in all material +mentioning or referencing the derived work. + +RSA Data Security, Inc. makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. + +These notices must be retained in any copies of any part of this +documentation and/or software. + + */ + + + + + +#include "linden_common.h" + +#include "llmd5.h" + +#include +#include +#include +#include + + +// LLMD5 simple initialization method + +LLMD5::LLMD5() +{ + init(); +} + + + + +// MD5 block update operation. Continues an MD5 message-digest +// operation, processing another message block, and updating the +// context. + +void LLMD5::update (const uint1 *input, const uint4 input_length) { + + uint4 input_index, buffer_index; + uint4 buffer_space; // how much space is left in buffer + + if (finalized){ // so we can't update! + std::cerr << "LLMD5::update: Can't update a finalized digest!" << std::endl; + return; + } + + // Compute number of bytes mod 64 + buffer_index = (unsigned int)((count[0] >> 3) & 0x3F); + + // Update number of bits + if ( (count[0] += ((uint4) input_length << 3))<((uint4) input_length << 3) ) + count[1]++; + + count[1] += ((uint4)input_length >> 29); + + + buffer_space = 64 - buffer_index; // how much space is left in buffer + + // Transform as many times as possible. + if (input_length >= buffer_space) { // ie. we have enough to fill the buffer + // fill the rest of the buffer and transform + memcpy (buffer + buffer_index, input, buffer_space); + transform (buffer); + + // now, transform each 64-byte piece of the input, bypassing the buffer + for (input_index = buffer_space; input_index + 63 < input_length; + input_index += 64) + transform (input+input_index); + + buffer_index = 0; // so we can buffer remaining + } + else + input_index=0; // so we can buffer the whole input + + + // and here we do the buffering: + memcpy(buffer+buffer_index, input+input_index, input_length-input_index); +} + + + +// MD5 update for files. +// Like above, except that it works on files (and uses above as a primitive.) + +void LLMD5::update(FILE *file){ + + unsigned char buffer[1024]; + int len; + + while ( (len=(int)fread(buffer, 1, 1024, file)) ) + update(buffer, len); + + fclose (file); + +} + + + + + + +// MD5 update for istreams. +// Like update for files; see above. + +void LLMD5::update(std::istream& stream){ + + unsigned char buffer[1024]; + int len; + + while (stream.good()){ + stream.read( (char*)buffer, 1024); // note that return value of read is unusable. + len=stream.gcount(); + update(buffer, len); + } + +} + + + + + + +// MD5 update for ifstreams. +// Like update for files; see above. + +void LLMD5::update(llifstream& stream){ + + unsigned char buffer[1024]; + int len; + + while (stream.good()){ + stream.read( (char*)buffer, 1024); // note that return value of read is unusable. + len=stream.gcount(); + update(buffer, len); + } + +} + + + + + + +// MD5 finalization. Ends an MD5 message-digest operation, writing the +// the message digest and zeroizing the context. + + +void LLMD5::finalize (){ + + unsigned char bits[8]; + unsigned int index, padLen; + static uint1 PADDING[64]={ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + + if (finalized){ + std::cerr << "LLMD5::finalize: Already finalized this digest!" << std::endl; + return; + } + + // Save number of bits + encode (bits, count, 8); + + // Pad out to 56 mod 64. + index = (uint4) ((count[0] >> 3) & 0x3f); + padLen = (index < 56) ? (56 - index) : (120 - index); + update (PADDING, padLen); + + // Append length (before padding) + update (bits, 8); + + // Store state in digest + encode (digest, state, 16); + + // Zeroize sensitive information + memset (buffer, 0, sizeof(*buffer)); + + finalized=1; + +} + + + + +LLMD5::LLMD5(FILE *file){ + + init(); // must be called be all constructors + update(file); + finalize (); +} + + + + +LLMD5::LLMD5(std::istream& stream){ + + init(); // must called by all constructors + update (stream); + finalize(); +} + + + +LLMD5::LLMD5(llifstream& stream) +{ + init(); // must called by all constructors + update (stream); + finalize(); +} + +// Digest a string of the format ("%s:%i" % (s, number)) +LLMD5::LLMD5(const unsigned char *string, const unsigned int number) +{ + const char *colon = ":"; + char tbuf[16]; + init(); + update(string, (U32)strlen((const char *) string)); + update((const unsigned char *) colon, (U32)strlen(colon)); + sprintf(tbuf, "%i", number); + update((const unsigned char *) tbuf, (U32)strlen(tbuf)); + finalize(); +} + +// Digest a string +LLMD5::LLMD5(const unsigned char *s) +{ + init(); + update(s, (U32)strlen((const char *) s)); + finalize(); +} + +void LLMD5::raw_digest(unsigned char *s) +{ + if (!finalized) + { + std::cerr << "LLMD5::raw_digest: Can't get digest if you haven't "<< + "finalized the digest!" << std::endl; + s[0] = '\0'; + return; + } + + memcpy(s, digest, 16); + return; +} + + + +void LLMD5::hex_digest(char *s) +{ + int i; + + if (!finalized) + { + std::cerr << "LLMD5::hex_digest: Can't get digest if you haven't "<< + "finalized the digest!" <> 8) & 0xff); + output[j+2] = (uint1) ((input[i] >> 16) & 0xff); + output[j+3] = (uint1) ((input[i] >> 24) & 0xff); + } +} + + + + +// Decodes input (unsigned char) into output (UINT4). Assumes len is +// a multiple of 4. +void LLMD5::decode (uint4 *output, const uint1 *input, const uint4 len){ + + unsigned int i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) + output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) | + (((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24); +} + + + + + +// ROTATE_LEFT rotates x left n bits. + +inline unsigned int LLMD5::rotate_left (uint4 x, uint4 n){ + return (x << n) | (x >> (32-n)) ; +} + + + + +// F, G, H and I are basic MD5 functions. + +inline unsigned int LLMD5::F (uint4 x, uint4 y, uint4 z){ + return (x & y) | (~x & z); +} + +inline unsigned int LLMD5::G (uint4 x, uint4 y, uint4 z){ + return (x & z) | (y & ~z); +} + +inline unsigned int LLMD5::H (uint4 x, uint4 y, uint4 z){ + return x ^ y ^ z; +} + +inline unsigned int LLMD5::I (uint4 x, uint4 y, uint4 z){ + return y ^ (x | ~z); +} + + + +// FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. +// Rotation is separate from addition to prevent recomputation. + + +inline void LLMD5::FF(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, + uint4 s, uint4 ac){ + a += F(b, c, d) + x + ac; + a = rotate_left (a, s) +b; +} + +inline void LLMD5::GG(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, + uint4 s, uint4 ac){ + a += G(b, c, d) + x + ac; + a = rotate_left (a, s) +b; +} + +inline void LLMD5::HH(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, + uint4 s, uint4 ac){ + a += H(b, c, d) + x + ac; + a = rotate_left (a, s) +b; +} + +inline void LLMD5::II(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, + uint4 s, uint4 ac){ + a += I(b, c, d) + x + ac; + a = rotate_left (a, s) +b; +} -- cgit v1.1