aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llmath/llmd5.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:46 -0500
committerJacek Antonelli2008-08-15 23:44:46 -0500
commit38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch)
treeadca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/llmath/llmd5.cpp
parentREADME.txt (diff)
downloadmeta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz
Second Life viewer sources 1.13.2.12
Diffstat (limited to 'linden/indra/llmath/llmd5.cpp')
-rw-r--r--linden/indra/llmath/llmd5.cpp574
1 files changed, 574 insertions, 0 deletions
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 @@
1/**
2 * @file llmd5.cpp
3 *
4 * Copyright (c) 2001-2007, Linden Research, Inc.
5 *
6 * The source code in this file ("Source Code") is provided by Linden Lab
7 * to you under the terms of the GNU General Public License, version 2.0
8 * ("GPL"), unless you have obtained a separate licensing agreement
9 * ("Other License"), formally executed by you and Linden Lab. Terms of
10 * the GPL can be found in doc/GPL-license.txt in this distribution, or
11 * online at http://secondlife.com/developers/opensource/gplv2
12 *
13 * There are special exceptions to the terms and conditions of the GPL as
14 * it is applied to this Source Code. View the full text of the exception
15 * in the file doc/FLOSS-exception.txt in this software distribution, or
16 * online at http://secondlife.com/developers/opensource/flossexception
17 *
18 * By copying, modifying or distributing this software, you acknowledge
19 * that you have read and understood your obligations described above,
20 * and agree to abide by those obligations.
21 *
22 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
23 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
24 * COMPLETENESS OR PERFORMANCE.
25 */
26
27// llMD5.CC - source code for the C++/object oriented translation and
28// modification of MD5.
29//
30// Adapted to Linden Lab by Frank Filipanits, 6/25/2002
31// Fixed potential memory leak, James Cook, 6/27/2002
32
33// Translation and modification (c) 1995 by Mordechai T. Abzug
34
35// This translation/ modification is provided "as is," without express or
36// implied warranty of any kind.
37
38// The translator/ modifier does not claim (1) that MD5 will do what you think
39// it does; (2) that this translation/ modification is accurate; or (3) that
40// this software is "merchantible." (Language for this disclaimer partially
41// copied from the disclaimer below).
42
43/* based on:
44
45 MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
46 MDDRIVER.C - test driver for MD2, MD4 and MD5
47
48
49 Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
50rights reserved.
51
52License to copy and use this software is granted provided that it
53is identified as the "RSA Data Security, Inc. MD5 Message-Digest
54Algorithm" in all material mentioning or referencing this software
55or this function.
56
57License is also granted to make and use derivative works provided
58that such works are identified as "derived from the RSA Data
59Security, Inc. MD5 Message-Digest Algorithm" in all material
60mentioning or referencing the derived work.
61
62RSA Data Security, Inc. makes no representations concerning either
63the merchantability of this software or the suitability of this
64software for any particular purpose. It is provided "as is"
65without express or implied warranty of any kind.
66
67These notices must be retained in any copies of any part of this
68documentation and/or software.
69
70 */
71
72
73
74
75
76#include "linden_common.h"
77
78#include "llmd5.h"
79
80#include <assert.h>
81#include <string.h>
82#include <fstream>
83#include <iostream>
84
85
86// LLMD5 simple initialization method
87
88LLMD5::LLMD5()
89{
90 init();
91}
92
93
94
95
96// MD5 block update operation. Continues an MD5 message-digest
97// operation, processing another message block, and updating the
98// context.
99
100void LLMD5::update (const uint1 *input, const uint4 input_length) {
101
102 uint4 input_index, buffer_index;
103 uint4 buffer_space; // how much space is left in buffer
104
105 if (finalized){ // so we can't update!
106 std::cerr << "LLMD5::update: Can't update a finalized digest!" << std::endl;
107 return;
108 }
109
110 // Compute number of bytes mod 64
111 buffer_index = (unsigned int)((count[0] >> 3) & 0x3F);
112
113 // Update number of bits
114 if ( (count[0] += ((uint4) input_length << 3))<((uint4) input_length << 3) )
115 count[1]++;
116
117 count[1] += ((uint4)input_length >> 29);
118
119
120 buffer_space = 64 - buffer_index; // how much space is left in buffer
121
122 // Transform as many times as possible.
123 if (input_length >= buffer_space) { // ie. we have enough to fill the buffer
124 // fill the rest of the buffer and transform
125 memcpy (buffer + buffer_index, input, buffer_space);
126 transform (buffer);
127
128 // now, transform each 64-byte piece of the input, bypassing the buffer
129 for (input_index = buffer_space; input_index + 63 < input_length;
130 input_index += 64)
131 transform (input+input_index);
132
133 buffer_index = 0; // so we can buffer remaining
134 }
135 else
136 input_index=0; // so we can buffer the whole input
137
138
139 // and here we do the buffering:
140 memcpy(buffer+buffer_index, input+input_index, input_length-input_index);
141}
142
143
144
145// MD5 update for files.
146// Like above, except that it works on files (and uses above as a primitive.)
147
148void LLMD5::update(FILE *file){
149
150 unsigned char buffer[1024];
151 int len;
152
153 while ( (len=(int)fread(buffer, 1, 1024, file)) )
154 update(buffer, len);
155
156 fclose (file);
157
158}
159
160
161
162
163
164
165// MD5 update for istreams.
166// Like update for files; see above.
167
168void LLMD5::update(std::istream& stream){
169
170 unsigned char buffer[1024];
171 int len;
172
173 while (stream.good()){
174 stream.read( (char*)buffer, 1024); // note that return value of read is unusable.
175 len=stream.gcount();
176 update(buffer, len);
177 }
178
179}
180
181
182
183
184
185
186// MD5 update for ifstreams.
187// Like update for files; see above.
188
189void LLMD5::update(llifstream& stream){
190
191 unsigned char buffer[1024];
192 int len;
193
194 while (stream.good()){
195 stream.read( (char*)buffer, 1024); // note that return value of read is unusable.
196 len=stream.gcount();
197 update(buffer, len);
198 }
199
200}
201
202
203
204
205
206
207// MD5 finalization. Ends an MD5 message-digest operation, writing the
208// the message digest and zeroizing the context.
209
210
211void LLMD5::finalize (){
212
213 unsigned char bits[8];
214 unsigned int index, padLen;
215 static uint1 PADDING[64]={
216 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
217 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
218 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
219 };
220
221 if (finalized){
222 std::cerr << "LLMD5::finalize: Already finalized this digest!" << std::endl;
223 return;
224 }
225
226 // Save number of bits
227 encode (bits, count, 8);
228
229 // Pad out to 56 mod 64.
230 index = (uint4) ((count[0] >> 3) & 0x3f);
231 padLen = (index < 56) ? (56 - index) : (120 - index);
232 update (PADDING, padLen);
233
234 // Append length (before padding)
235 update (bits, 8);
236
237 // Store state in digest
238 encode (digest, state, 16);
239
240 // Zeroize sensitive information
241 memset (buffer, 0, sizeof(*buffer));
242
243 finalized=1;
244
245}
246
247
248
249
250LLMD5::LLMD5(FILE *file){
251
252 init(); // must be called be all constructors
253 update(file);
254 finalize ();
255}
256
257
258
259
260LLMD5::LLMD5(std::istream& stream){
261
262 init(); // must called by all constructors
263 update (stream);
264 finalize();
265}
266
267
268
269LLMD5::LLMD5(llifstream& stream)
270{
271 init(); // must called by all constructors
272 update (stream);
273 finalize();
274}
275
276// Digest a string of the format ("%s:%i" % (s, number))
277LLMD5::LLMD5(const unsigned char *string, const unsigned int number)
278{
279 const char *colon = ":";
280 char tbuf[16];
281 init();
282 update(string, (U32)strlen((const char *) string));
283 update((const unsigned char *) colon, (U32)strlen(colon));
284 sprintf(tbuf, "%i", number);
285 update((const unsigned char *) tbuf, (U32)strlen(tbuf));
286 finalize();
287}
288
289// Digest a string
290LLMD5::LLMD5(const unsigned char *s)
291{
292 init();
293 update(s, (U32)strlen((const char *) s));
294 finalize();
295}
296
297void LLMD5::raw_digest(unsigned char *s)
298{
299 if (!finalized)
300 {
301 std::cerr << "LLMD5::raw_digest: Can't get digest if you haven't "<<
302 "finalized the digest!" << std::endl;
303 s[0] = '\0';
304 return;
305 }
306
307 memcpy(s, digest, 16);
308 return;
309}
310
311
312
313void LLMD5::hex_digest(char *s)
314{
315 int i;
316
317 if (!finalized)
318 {
319 std::cerr << "LLMD5::hex_digest: Can't get digest if you haven't "<<
320 "finalized the digest!" <<std::endl;
321 s[0] = '\0';
322 return;
323 }
324
325 for (i=0; i<16; i++)
326 {
327 sprintf(s+i*2, "%02x", digest[i]);
328 }
329
330 s[32]='\0';
331
332 return;
333}
334
335
336
337
338
339std::ostream& operator<<(std::ostream &stream, LLMD5 context)
340{
341 char s[33];
342 context.hex_digest(s);
343 stream << s;
344 return stream;
345}
346
347
348
349
350// PRIVATE METHODS:
351
352
353
354void LLMD5::init(){
355 finalized=0; // we just started!
356
357 // Nothing counted, so count=0
358 count[0] = 0;
359 count[1] = 0;
360
361 // Load magic initialization constants.
362 state[0] = 0x67452301;
363 state[1] = 0xefcdab89;
364 state[2] = 0x98badcfe;
365 state[3] = 0x10325476;
366}
367
368
369
370// Constants for MD5Transform routine.
371// Although we could use C++ style constants, defines are actually better,
372// since they let us easily evade scope clashes.
373
374#define S11 7
375#define S12 12
376#define S13 17
377#define S14 22
378#define S21 5
379#define S22 9
380#define S23 14
381#define S24 20
382#define S31 4
383#define S32 11
384#define S33 16
385#define S34 23
386#define S41 6
387#define S42 10
388#define S43 15
389#define S44 21
390
391
392
393
394// LLMD5 basic transformation. Transforms state based on block.
395void LLMD5::transform (const uint1 block[64]){
396
397 uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
398
399 decode (x, block, 64);
400
401 assert(!finalized); // not just a user error, since the method is private
402
403 /* Round 1 */
404 FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
405 FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
406 FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
407 FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
408 FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
409 FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
410 FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
411 FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
412 FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
413 FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
414 FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
415 FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
416 FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
417 FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
418 FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
419 FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
420
421 /* Round 2 */
422 GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
423 GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
424 GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
425 GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
426 GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
427 GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
428 GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
429 GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
430 GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
431 GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
432 GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
433 GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
434 GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
435 GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
436 GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
437 GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
438
439 /* Round 3 */
440 HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
441 HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
442 HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
443 HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
444 HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
445 HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
446 HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
447 HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
448 HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
449 HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
450 HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
451 HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
452 HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
453 HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
454 HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
455 HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
456
457 /* Round 4 */
458 II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
459 II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
460 II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
461 II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
462 II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
463 II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
464 II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
465 II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
466 II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
467 II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
468 II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
469 II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
470 II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
471 II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
472 II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
473 II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
474
475 state[0] += a;
476 state[1] += b;
477 state[2] += c;
478 state[3] += d;
479
480 // Zeroize sensitive information.
481 memset ( (uint1 *) x, 0, sizeof(x));
482
483}
484
485
486
487// Encodes input (UINT4) into output (unsigned char). Assumes len is
488// a multiple of 4.
489void LLMD5::encode (uint1 *output, const uint4 *input, const uint4 len) {
490
491 unsigned int i, j;
492
493 for (i = 0, j = 0; j < len; i++, j += 4) {
494 output[j] = (uint1) (input[i] & 0xff);
495 output[j+1] = (uint1) ((input[i] >> 8) & 0xff);
496 output[j+2] = (uint1) ((input[i] >> 16) & 0xff);
497 output[j+3] = (uint1) ((input[i] >> 24) & 0xff);
498 }
499}
500
501
502
503
504// Decodes input (unsigned char) into output (UINT4). Assumes len is
505// a multiple of 4.
506void LLMD5::decode (uint4 *output, const uint1 *input, const uint4 len){
507
508 unsigned int i, j;
509
510 for (i = 0, j = 0; j < len; i++, j += 4)
511 output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) |
512 (((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24);
513}
514
515
516
517
518
519// ROTATE_LEFT rotates x left n bits.
520
521inline unsigned int LLMD5::rotate_left (uint4 x, uint4 n){
522 return (x << n) | (x >> (32-n)) ;
523}
524
525
526
527
528// F, G, H and I are basic MD5 functions.
529
530inline unsigned int LLMD5::F (uint4 x, uint4 y, uint4 z){
531 return (x & y) | (~x & z);
532}
533
534inline unsigned int LLMD5::G (uint4 x, uint4 y, uint4 z){
535 return (x & z) | (y & ~z);
536}
537
538inline unsigned int LLMD5::H (uint4 x, uint4 y, uint4 z){
539 return x ^ y ^ z;
540}
541
542inline unsigned int LLMD5::I (uint4 x, uint4 y, uint4 z){
543 return y ^ (x | ~z);
544}
545
546
547
548// FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
549// Rotation is separate from addition to prevent recomputation.
550
551
552inline void LLMD5::FF(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
553 uint4 s, uint4 ac){
554 a += F(b, c, d) + x + ac;
555 a = rotate_left (a, s) +b;
556}
557
558inline void LLMD5::GG(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
559 uint4 s, uint4 ac){
560 a += G(b, c, d) + x + ac;
561 a = rotate_left (a, s) +b;
562}
563
564inline void LLMD5::HH(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
565 uint4 s, uint4 ac){
566 a += H(b, c, d) + x + ac;
567 a = rotate_left (a, s) +b;
568}
569
570inline void LLMD5::II(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
571 uint4 s, uint4 ac){
572 a += I(b, c, d) + x + ac;
573 a = rotate_left (a, s) +b;
574}