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