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
23dng_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
37bool 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
58bool 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
79uint32 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
106static 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
123void 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
142static 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
166bool 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
221dng_md5_printer::dng_md5_printer ()
222
223	:	final  (false)
224	,	result ()
225
226	{
227
228	Reset ();
229
230	}
231
232/******************************************************************************/
233
234void 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
257void 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
314const 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
364void 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
386void 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
456void 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