• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
dng_fingerprint()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 
IsNull() const37 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 
operator ==(const dng_fingerprint & print) const58 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 
Collapse32() const79 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 
NumToHexChar(unsigned int c)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 
ToUtf8HexString(char resultStr[2* kDNGFingerprintSize+1]) const123 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 
HexCharToNum(char hexChar)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 
FromUtf8HexString(const char inputStr[2* kDNGFingerprintSize+1])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 
dng_md5_printer()221 dng_md5_printer::dng_md5_printer ()
222 
223 	:	final  (false)
224 	,	result ()
225 
226 	{
227 
228 	Reset ();
229 
230 	}
231 
232 /******************************************************************************/
233 
Reset()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 
Process(const void * data,uint32 inputLen)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 
Result()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 
Encode(uint8 * output,const uint32 * input,uint32 len)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 
Decode(uint32 * output,const uint8 * input,uint32 len)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
MD5Transform(uint32 state[4],const uint8 block[64])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