Home | History | Annotate | Download | only in source
      1 /*****************************************************************************/
      2 // Copyright 2006-2007 Adobe Systems Incorporated
      3 // All Rights Reserved.
      4 //
      5 // NOTICE:  Adobe permits you to use, modify, and distribute this file in
      6 // accordance with the terms of the Adobe license agreement accompanying it.
      7 /*****************************************************************************/
      8 
      9 /* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_fingerprint.cpp#3 $ */
     10 /* $DateTime: 2012/07/11 10:36:56 $ */
     11 /* $Change: 838485 $ */
     12 /* $Author: tknoll $ */
     13 
     14 /*****************************************************************************/
     15 
     16 #include "dng_fingerprint.h"
     17 
     18 #include "dng_assertions.h"
     19 #include "dng_flags.h"
     20 
     21 /*****************************************************************************/
     22 
     23 dng_fingerprint::dng_fingerprint ()
     24 	{
     25 
     26 	for (uint32 j = 0; j < 16; j++)
     27 		{
     28 
     29 		data [j] = 0;
     30 
     31 		}
     32 
     33 	}
     34 
     35 /*****************************************************************************/
     36 
     37 bool dng_fingerprint::IsNull () const
     38 	{
     39 
     40 	for (uint32 j = 0; j < 16; j++)
     41 		{
     42 
     43 		if (data [j] != 0)
     44 			{
     45 
     46 			return false;
     47 
     48 			}
     49 
     50 		}
     51 
     52 	return true;
     53 
     54 	}
     55 
     56 /*****************************************************************************/
     57 
     58 bool dng_fingerprint::operator== (const dng_fingerprint &print) const
     59 	{
     60 
     61 	for (uint32 j = 0; j < 16; j++)
     62 		{
     63 
     64 		if (data [j] != print.data [j])
     65 			{
     66 
     67 			return false;
     68 
     69 			}
     70 
     71 		}
     72 
     73 	return true;
     74 
     75 	}
     76 
     77 /******************************************************************************/
     78 
     79 uint32 dng_fingerprint::Collapse32 () const
     80 	{
     81 
     82 	uint32 x = 0;
     83 
     84 	for (uint32 j = 0; j < 4; j++)
     85 		{
     86 
     87 		uint32 y = 0;
     88 
     89 		for (uint32 k = 0; k < 4; k++)
     90 			{
     91 
     92 			y = (y << 8) + (uint32) data [j * 4 + k];
     93 
     94 			}
     95 
     96 		x = x ^ y;
     97 
     98 		}
     99 
    100 	return x;
    101 
    102 	}
    103 
    104 /******************************************************************************/
    105 
    106 static char NumToHexChar (unsigned int c)
    107 	{
    108 
    109 	if (c < 10)
    110 		{
    111 		return (char) ('0' + c);
    112 		}
    113 
    114 	else
    115 		{
    116 		return (char) ('A' + c - 10);
    117 		}
    118 
    119 	}
    120 
    121 /*****************************************************************************/
    122 
    123 void dng_fingerprint::ToUtf8HexString (char resultStr [2 * kDNGFingerprintSize + 1]) const
    124 	{
    125 
    126 	for (size_t i = 0; i < kDNGFingerprintSize; i++)
    127 		{
    128 
    129 		unsigned char c = data [i];
    130 
    131 		resultStr [i * 2] = NumToHexChar (c >> 4);
    132 		resultStr [i * 2 + 1] = NumToHexChar (c & 15);
    133 
    134 		}
    135 
    136 	resultStr [kDNGFingerprintSize * 2] = '\0';
    137 
    138 	}
    139 
    140 /******************************************************************************/
    141 
    142 static int HexCharToNum (char hexChar)
    143 	{
    144 
    145 	if (hexChar >= '0' && hexChar <= '9')
    146 		{
    147 		return hexChar - '0';
    148 		}
    149 
    150 	else if (hexChar >= 'A' && hexChar <= 'F')
    151 		{
    152 		return hexChar - 'A' + 10;
    153 		}
    154 
    155 	else if (hexChar >= 'a' && hexChar <= 'f')
    156 		{
    157 		return hexChar - 'a' + 10;
    158 		}
    159 
    160 	return -1;
    161 
    162 	}
    163 
    164 /*****************************************************************************/
    165 
    166 bool dng_fingerprint::FromUtf8HexString (const char inputStr [2 * kDNGFingerprintSize + 1])
    167 	{
    168 
    169 	for (size_t i = 0; i < kDNGFingerprintSize; i++)
    170 		{
    171 
    172 		int highNibble = HexCharToNum (inputStr [i * 2]);
    173 
    174 		if (highNibble < 0)
    175 			{
    176 			return false;
    177 			}
    178 
    179 		int lowNibble = HexCharToNum (inputStr [i * 2 + 1]);
    180 
    181 		if (lowNibble < 0)
    182 			{
    183 			return false;
    184 			}
    185 
    186 		data [i] = (uint8) ((highNibble << 4) + lowNibble);
    187 
    188 		}
    189 
    190 	return true;
    191 
    192 	}
    193 
    194 /******************************************************************************/
    195 
    196 // Derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm
    197 
    198 // Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
    199 // rights reserved.
    200 //
    201 // License to copy and use this software is granted provided that it
    202 // is identified as the "RSA Data Security, Inc. MD5 Message-Digest
    203 // Algorithm" in all material mentioning or referencing this software
    204 // or this function.
    205 //
    206 // License is also granted to make and use derivative works provided
    207 // that such works are identified as "derived from the RSA Data
    208 // Security, Inc. MD5 Message-Digest Algorithm" in all material
    209 // mentioning or referencing the derived work.
    210 //
    211 // RSA Data Security, Inc. makes no representations concerning either
    212 // the merchantability of this software or the suitability of this
    213 // software for any particular purpose. It is provided "as is"
    214 // without express or implied warranty of any kind.
    215 //
    216 // These notices must be retained in any copies of any part of this
    217 // documentation and/or software.
    218 
    219 /******************************************************************************/
    220 
    221 dng_md5_printer::dng_md5_printer ()
    222 
    223 	:	final  (false)
    224 	,	result ()
    225 
    226 	{
    227 
    228 	Reset ();
    229 
    230 	}
    231 
    232 /******************************************************************************/
    233 
    234 void dng_md5_printer::Reset ()
    235 	{
    236 
    237 	// No bits processed yet.
    238 
    239 	count [0] = 0;
    240 	count [1] = 0;
    241 
    242 	// Load magic initialization constants.
    243 
    244 	state [0] = 0x67452301;
    245 	state [1] = 0xefcdab89;
    246 	state [2] = 0x98badcfe;
    247 	state [3] = 0x10325476;
    248 
    249 	// Not finalized yet.
    250 
    251 	final = false;
    252 
    253 	}
    254 
    255 /******************************************************************************/
    256 
    257 void dng_md5_printer::Process (const void *data,
    258 					  		   uint32 inputLen)
    259 	{
    260 
    261 	DNG_ASSERT (!final, "Fingerprint already finalized!");
    262 
    263 	const uint8 *input = (const uint8 *) data;
    264 
    265 	// Compute number of bytes mod 64
    266 
    267 	uint32 index = (count [0] >> 3) & 0x3F;
    268 
    269 	// Update number of bits
    270 
    271 	if ((count [0] += inputLen << 3) < (inputLen << 3))
    272 		{
    273 		count [1]++;
    274 		}
    275 
    276 	count [1] += inputLen >> 29;
    277 
    278 	// Transform as many times as possible.
    279 
    280 	uint32 i = 0;
    281 
    282 	uint32 partLen = 64 - index;
    283 
    284 	if (inputLen >= partLen)
    285 		{
    286 
    287 		memcpy (&buffer [index],
    288 				input,
    289 				partLen);
    290 
    291 		MD5Transform (state, buffer);
    292 
    293 		for (i = partLen; i + 63 < inputLen; i += 64)
    294 			{
    295 
    296 			MD5Transform (state, &input [i]);
    297 
    298 			}
    299 
    300 		index = 0;
    301 
    302 		}
    303 
    304 	// Buffer remaining input
    305 
    306 	memcpy (&buffer [index],
    307 			&input [i],
    308 			inputLen - i);
    309 
    310 	}
    311 
    312 /******************************************************************************/
    313 
    314 const dng_fingerprint & dng_md5_printer::Result ()
    315 	{
    316 
    317 	if (!final)
    318 		{
    319 
    320 		static uint8 PADDING [64] =
    321 			{
    322 			0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    323 			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    324 			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    325 			};
    326 
    327 		// Save number of bits
    328 
    329 		uint8 bits [8];
    330 
    331 		Encode (bits, count, 8);
    332 
    333 		// Pad out to 56 mod 64.
    334 
    335 		uint32 index = (count [0] >> 3) & 0x3f;
    336 
    337 		uint32 padLen = (index < 56) ? (56 - index) : (120 - index);
    338 
    339 		Process (PADDING, padLen);
    340 
    341 		// Append length (before padding)
    342 
    343 		Process (bits, 8);
    344 
    345 		// Store state in digest
    346 
    347 		Encode (result.data, state, 16);
    348 
    349 		// We are now finalized.
    350 
    351 		final = true;
    352 
    353 		}
    354 
    355 	return result;
    356 
    357 	}
    358 
    359 /******************************************************************************/
    360 
    361 // Encodes input (uint32) into output (uint8). Assumes len is
    362 // a multiple of 4.
    363 
    364 void dng_md5_printer::Encode (uint8 *output,
    365 							  const uint32 *input,
    366 							  uint32 len)
    367 	{
    368 
    369 	uint32 i, j;
    370 
    371 	for (i = 0, j = 0; j < len; i++, j += 4)
    372 		{
    373 		output [j  ] = (uint8) ((input [i]      ) & 0xff);
    374 		output [j+1] = (uint8) ((input [i] >>  8) & 0xff);
    375 		output [j+2] = (uint8) ((input [i] >> 16) & 0xff);
    376 		output [j+3] = (uint8) ((input [i] >> 24) & 0xff);
    377 		}
    378 
    379 	}
    380 
    381 /******************************************************************************/
    382 
    383 // Decodes input (uint8) into output (uint32). Assumes len is
    384 // a multiple of 4.
    385 
    386 void dng_md5_printer::Decode (uint32 *output,
    387 							  const uint8 *input,
    388 							  uint32 len)
    389 	{
    390 
    391 	// Check for non-aligned case.
    392 
    393 	if (((uintptr) input) & 3)
    394 		{
    395 
    396 		uint32 i, j;
    397 
    398 		for (i = 0, j = 0; j < len; i++, j += 4)
    399 			{
    400 
    401 	 		output [i] = (((uint32) input [j  ])      ) |
    402 	 					 (((uint32) input [j+1]) <<  8) |
    403 	   					 (((uint32) input [j+2]) << 16) |
    404 	   					 (((uint32) input [j+3]) << 24);
    405 
    406 	   		}
    407 
    408 	   	}
    409 
    410 	// Else use optimized code for aligned case.
    411 
    412 	else
    413 		{
    414 
    415 		len = len >> 2;
    416 
    417 		const uint32 *sPtr = (const uint32 *) input;
    418 
    419 		uint32 *dPtr = output;
    420 
    421 		while (len--)
    422 			{
    423 
    424 			#if qDNGBigEndian
    425 
    426 			uint32 data = *(sPtr++);
    427 
    428 			data = (data >> 24) |
    429 				   ((data >> 8) & 0x0000FF00) |
    430 				   ((data << 8) & 0x00FF0000) |
    431 				   (data << 24);
    432 
    433 			*(dPtr++) = data;
    434 
    435 			#else
    436 
    437 			*(dPtr++) = *(sPtr++);
    438 
    439 			#endif
    440 
    441 			}
    442 
    443 		}
    444 
    445 	}
    446 
    447 /******************************************************************************/
    448 
    449 // MD5 basic transformation. Transforms state based on block.
    450 
    451 #if defined(__clang__) && defined(__has_attribute)
    452 #if __has_attribute(no_sanitize)
    453 __attribute__((no_sanitize("unsigned-integer-overflow")))
    454 #endif
    455 #endif
    456 void dng_md5_printer::MD5Transform (uint32 state [4],
    457 								    const uint8 block [64])
    458 	{
    459 
    460 	enum
    461 		{
    462 		S11 = 7,
    463 		S12 = 12,
    464 		S13 = 17,
    465 		S14 = 22,
    466 		S21 = 5,
    467 		S22 = 9,
    468 		S23 = 14,
    469 		S24 = 20,
    470 		S31 = 4,
    471 		S32 = 11,
    472 		S33 = 16,
    473 		S34 = 23,
    474 		S41 = 6,
    475 		S42 = 10,
    476 		S43 = 15,
    477 		S44 = 21
    478 		};
    479 
    480 	#if qDNGBigEndian
    481 
    482 	uint32 x [16];
    483 
    484 	Decode (x, block, 64);
    485 
    486 	#else
    487 
    488 	uint32 temp [16];
    489 
    490 	const uint32 *x;
    491 
    492 	if (((uintptr) block) & 3)
    493 		{
    494 
    495 		Decode (temp, block, 64);
    496 
    497 		x = temp;
    498 
    499 		}
    500 
    501 	else
    502 		x = (const uint32 *) block;
    503 
    504 	#endif
    505 
    506 	uint32 a = state [0];
    507 	uint32 b = state [1];
    508 	uint32 c = state [2];
    509 	uint32 d = state [3];
    510 
    511 	/* Round 1 */
    512 	FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
    513 	FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
    514 	FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
    515 	FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
    516 	FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
    517 	FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
    518 	FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
    519 	FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
    520 	FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
    521 	FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
    522 	FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
    523 	FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
    524 	FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
    525 	FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
    526 	FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
    527 	FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
    528 
    529 	/* Round 2 */
    530 	GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
    531 	GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
    532 	GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
    533 	GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
    534 	GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
    535 	GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
    536 	GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
    537 	GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
    538 	GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
    539 	GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
    540 	GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
    541 	GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
    542 	GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
    543 	GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
    544 	GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
    545 	GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
    546 
    547 	/* Round 3 */
    548 	HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
    549 	HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
    550 	HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
    551 	HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
    552 	HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
    553 	HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
    554 	HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
    555 	HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
    556 	HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
    557 	HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
    558 	HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
    559 	HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
    560 	HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
    561 	HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
    562 	HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
    563 	HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
    564 
    565 	/* Round 4 */
    566 	II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
    567 	II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
    568 	II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
    569 	II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
    570 	II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
    571 	II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
    572 	II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
    573 	II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
    574 	II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
    575 	II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
    576 	II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
    577 	II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
    578 	II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
    579 	II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
    580 	II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
    581 	II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
    582 
    583 	state [0] += a;
    584 	state [1] += b;
    585 	state [2] += c;
    586 	state [3] += d;
    587 
    588 	}
    589 
    590 /*****************************************************************************/
    591 
    592 // End of RSA Data Security, Inc. derived code.
    593 
    594 /*****************************************************************************/
    595