File indexing completed on 2025-01-19 03:54:57
0001 /*****************************************************************************/ 0002 // Copyright 2006-2019 Adobe Systems Incorporated 0003 // All Rights Reserved. 0004 // 0005 // NOTICE: Adobe permits you to use, modify, and distribute this file in 0006 // accordance with the terms of the Adobe license agreement accompanying it. 0007 /*****************************************************************************/ 0008 0009 #include "dng_fingerprint.h" 0010 0011 #include "dng_assertions.h" 0012 #include "dng_flags.h" 0013 0014 /*****************************************************************************/ 0015 0016 dng_fingerprint::dng_fingerprint () 0017 { 0018 0019 for (uint32 j = 0; j < kDNGFingerprintSize; j++) 0020 { 0021 0022 data [j] = 0; 0023 0024 } 0025 0026 } 0027 0028 /*****************************************************************************/ 0029 0030 dng_fingerprint::dng_fingerprint (const char *hex) 0031 { 0032 0033 if (!hex || strlen (hex) != kDNGFingerprintSize * 2 || !FromUtf8HexString (hex)) 0034 { 0035 0036 Clear (); 0037 0038 } 0039 0040 } 0041 0042 /*****************************************************************************/ 0043 0044 bool dng_fingerprint::IsNull () const 0045 { 0046 0047 for (uint32 j = 0; j < kDNGFingerprintSize; j++) 0048 { 0049 0050 if (data [j] != 0) 0051 { 0052 0053 return false; 0054 0055 } 0056 0057 } 0058 0059 return true; 0060 0061 } 0062 0063 /*****************************************************************************/ 0064 0065 bool dng_fingerprint::operator== (const dng_fingerprint &print) const 0066 { 0067 0068 for (uint32 j = 0; j < kDNGFingerprintSize; j++) 0069 { 0070 0071 if (data [j] != print.data [j]) 0072 { 0073 0074 return false; 0075 0076 } 0077 0078 } 0079 0080 return true; 0081 0082 } 0083 0084 /******************************************************************************/ 0085 0086 bool dng_fingerprint::operator< (const dng_fingerprint &print) const 0087 { 0088 0089 for (uint32 j = 0; j < kDNGFingerprintSize; j++) 0090 { 0091 0092 if (data [j] != print.data [j]) 0093 { 0094 0095 return data [j] < print.data [j]; 0096 0097 } 0098 0099 } 0100 0101 return false; 0102 0103 } 0104 0105 /******************************************************************************/ 0106 0107 uint32 dng_fingerprint::Collapse32 () const 0108 { 0109 0110 uint32 x = 0; 0111 0112 for (uint32 j = 0; j < 4; j++) 0113 { 0114 0115 uint32 y = 0; 0116 0117 for (uint32 k = 0; k < 4; k++) 0118 { 0119 0120 y = (y << 8) + (uint32) data [j * 4 + k]; 0121 0122 } 0123 0124 x = x ^ y; 0125 0126 } 0127 0128 return x; 0129 0130 } 0131 0132 /******************************************************************************/ 0133 0134 static char NumToHexChar (unsigned int c) 0135 { 0136 0137 if (c < 10) 0138 { 0139 return (char) ('0' + c); 0140 } 0141 0142 else 0143 { 0144 return (char) ('A' + c - 10); 0145 } 0146 0147 } 0148 0149 /*****************************************************************************/ 0150 0151 void dng_fingerprint::ToUtf8HexString (char resultStr [2 * kDNGFingerprintSize + 1]) const 0152 { 0153 0154 for (size_t i = 0; i < kDNGFingerprintSize; i++) 0155 { 0156 0157 unsigned char c = data [i]; 0158 0159 resultStr [i * 2 ] = NumToHexChar (c >> 4); 0160 resultStr [i * 2 + 1] = NumToHexChar (c & 15); 0161 0162 } 0163 0164 resultStr [kDNGFingerprintSize * 2] = '\0'; 0165 0166 } 0167 0168 /******************************************************************************/ 0169 0170 static int HexCharToNum (char hexChar) 0171 { 0172 0173 if (hexChar >= '0' && hexChar <= '9') 0174 { 0175 return hexChar - '0'; 0176 } 0177 0178 else if (hexChar >= 'A' && hexChar <= 'F') 0179 { 0180 return hexChar - 'A' + 10; 0181 } 0182 0183 else if (hexChar >= 'a' && hexChar <= 'f') 0184 { 0185 return hexChar - 'a' + 10; 0186 } 0187 0188 return -1; 0189 0190 } 0191 0192 /*****************************************************************************/ 0193 0194 bool dng_fingerprint::FromUtf8HexString (const char inputStr [2 * kDNGFingerprintSize + 1]) 0195 { 0196 0197 for (size_t i = 0; i < kDNGFingerprintSize; i++) 0198 { 0199 0200 int highNibble = HexCharToNum (inputStr [i * 2]); 0201 0202 if (highNibble < 0) 0203 { 0204 return false; 0205 } 0206 0207 int lowNibble = HexCharToNum (inputStr [i * 2 + 1]); 0208 0209 if (lowNibble < 0) 0210 { 0211 return false; 0212 } 0213 0214 data [i] = (uint8) ((highNibble << 4) + lowNibble); 0215 0216 } 0217 0218 return true; 0219 0220 } 0221 0222 /******************************************************************************/ 0223 0224 // Derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm 0225 0226 // Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All 0227 // rights reserved. 0228 // 0229 // License to copy and use this software is granted provided that it 0230 // is identified as the "RSA Data Security, Inc. MD5 Message-Digest 0231 // Algorithm" in all material mentioning or referencing this software 0232 // or this function. 0233 // 0234 // License is also granted to make and use derivative works provided 0235 // that such works are identified as "derived from the RSA Data 0236 // Security, Inc. MD5 Message-Digest Algorithm" in all material 0237 // mentioning or referencing the derived work. 0238 // 0239 // RSA Data Security, Inc. makes no representations concerning either 0240 // the merchantability of this software or the suitability of this 0241 // software for any particular purpose. It is provided "as is" 0242 // without express or implied warranty of any kind. 0243 // 0244 // These notices must be retained in any copies of any part of this 0245 // documentation and/or software. 0246 0247 /******************************************************************************/ 0248 0249 dng_md5_printer::dng_md5_printer () 0250 0251 : final (false) 0252 , result () 0253 0254 { 0255 0256 Reset (); 0257 0258 } 0259 0260 /******************************************************************************/ 0261 0262 void dng_md5_printer::Reset () 0263 { 0264 0265 // No bits processed yet. 0266 0267 count [0] = 0; 0268 count [1] = 0; 0269 0270 // Load magic initialization constants. 0271 0272 state [0] = 0x67452301; 0273 state [1] = 0xefcdab89; 0274 state [2] = 0x98badcfe; 0275 state [3] = 0x10325476; 0276 0277 // Not finalized yet. 0278 0279 final = false; 0280 0281 } 0282 0283 /******************************************************************************/ 0284 0285 void dng_md5_printer::Process (const void *data, 0286 uint32 inputLen) 0287 { 0288 0289 DNG_ASSERT (!final, "Fingerprint already finalized!"); 0290 0291 const uint8 *input = (const uint8 *) data; 0292 0293 // Compute number of bytes mod 64 0294 0295 uint32 index = (count [0] >> 3) & 0x3F; 0296 0297 // Update number of bits 0298 0299 if ((count [0] += inputLen << 3) < (inputLen << 3)) 0300 { 0301 count [1]++; 0302 } 0303 0304 count [1] += inputLen >> 29; 0305 0306 // Transform as many times as possible. 0307 0308 uint32 i = 0; 0309 0310 uint32 partLen = 64 - index; 0311 0312 if (inputLen >= partLen) 0313 { 0314 0315 memcpy (&buffer [index], 0316 input, 0317 partLen); 0318 0319 MD5Transform (state, buffer); 0320 0321 for (i = partLen; i + 63 < inputLen; i += 64) 0322 { 0323 0324 MD5Transform (state, &input [i]); 0325 0326 } 0327 0328 index = 0; 0329 0330 } 0331 0332 // Buffer remaining input 0333 0334 memcpy (&buffer [index], 0335 &input [i], 0336 inputLen - i); 0337 0338 } 0339 0340 /******************************************************************************/ 0341 0342 const dng_fingerprint & dng_md5_printer::Result () 0343 { 0344 0345 if (!final) 0346 { 0347 0348 static uint8 PADDING [64] = 0349 { 0350 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0351 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0352 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 0353 }; 0354 0355 // Save number of bits 0356 0357 uint8 bits [8]; 0358 0359 Encode (bits, count, 8); 0360 0361 // Pad out to 56 mod 64. 0362 0363 uint32 index = (count [0] >> 3) & 0x3f; 0364 0365 uint32 padLen = (index < 56) ? (56 - index) : (120 - index); 0366 0367 Process (PADDING, padLen); 0368 0369 // Append length (before padding) 0370 0371 Process (bits, 8); 0372 0373 // Store state in digest 0374 0375 Encode (result.data, state, 16); 0376 0377 // We are now finalized. 0378 0379 final = true; 0380 0381 } 0382 0383 return result; 0384 0385 } 0386 0387 /******************************************************************************/ 0388 0389 // Encodes input (uint32) into output (uint8). Assumes len is 0390 // a multiple of 4. 0391 0392 void dng_md5_printer::Encode (uint8 *output, 0393 const uint32 *input, 0394 uint32 len) 0395 { 0396 0397 uint32 i, j; 0398 0399 for (i = 0, j = 0; j < len; i++, j += 4) 0400 { 0401 output [j ] = (uint8) ((input [i] ) & 0xff); 0402 output [j+1] = (uint8) ((input [i] >> 8) & 0xff); 0403 output [j+2] = (uint8) ((input [i] >> 16) & 0xff); 0404 output [j+3] = (uint8) ((input [i] >> 24) & 0xff); 0405 } 0406 0407 } 0408 0409 /******************************************************************************/ 0410 0411 // Decodes input (uint8) into output (uint32). Assumes len is 0412 // a multiple of 4. 0413 0414 void dng_md5_printer::Decode (uint32 *output, 0415 const uint8 *input, 0416 uint32 len) 0417 { 0418 0419 // Check for non-aligned case. 0420 0421 if (((uintptr) input) & 3) 0422 { 0423 0424 uint32 i, j; 0425 0426 for (i = 0, j = 0; j < len; i++, j += 4) 0427 { 0428 0429 output [i] = (((uint32) input [j ]) ) | 0430 (((uint32) input [j+1]) << 8) | 0431 (((uint32) input [j+2]) << 16) | 0432 (((uint32) input [j+3]) << 24); 0433 0434 } 0435 0436 } 0437 0438 // Else use optimized code for aligned case. 0439 0440 else 0441 { 0442 0443 len = len >> 2; 0444 0445 const uint32 *sPtr = (const uint32 *) input; 0446 0447 uint32 *dPtr = output; 0448 0449 while (len--) 0450 { 0451 0452 #if qDNGBigEndian 0453 0454 uint32 data = *(sPtr++); 0455 0456 data = (data >> 24) | 0457 ((data >> 8) & 0x0000FF00) | 0458 ((data << 8) & 0x00FF0000) | 0459 (data << 24); 0460 0461 *(dPtr++) = data; 0462 0463 #else 0464 0465 *(dPtr++) = *(sPtr++); 0466 0467 #endif 0468 0469 } 0470 0471 } 0472 0473 } 0474 0475 /******************************************************************************/ 0476 0477 // MD5 basic transformation. Transforms state based on block. 0478 0479 DNG_ATTRIB_NO_SANITIZE("unsigned-integer-overflow") 0480 void dng_md5_printer::MD5Transform (uint32 state [4], 0481 const uint8 block [64]) 0482 { 0483 0484 enum 0485 { 0486 S11 = 7, 0487 S12 = 12, 0488 S13 = 17, 0489 S14 = 22, 0490 S21 = 5, 0491 S22 = 9, 0492 S23 = 14, 0493 S24 = 20, 0494 S31 = 4, 0495 S32 = 11, 0496 S33 = 16, 0497 S34 = 23, 0498 S41 = 6, 0499 S42 = 10, 0500 S43 = 15, 0501 S44 = 21 0502 }; 0503 0504 #if qDNGBigEndian 0505 0506 uint32 x [16]; 0507 0508 Decode (x, block, 64); 0509 0510 #else 0511 0512 uint32 temp [16]; 0513 0514 const uint32 *x; 0515 0516 if (((uintptr) block) & 3) 0517 { 0518 0519 Decode (temp, block, 64); 0520 0521 x = temp; 0522 0523 } 0524 0525 else 0526 x = (const uint32 *) block; 0527 0528 #endif 0529 0530 uint32 a = state [0]; 0531 uint32 b = state [1]; 0532 uint32 c = state [2]; 0533 uint32 d = state [3]; 0534 0535 /* Round 1 */ 0536 FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ 0537 FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ 0538 FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ 0539 FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ 0540 FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ 0541 FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ 0542 FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ 0543 FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ 0544 FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ 0545 FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ 0546 FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ 0547 FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ 0548 FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ 0549 FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ 0550 FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ 0551 FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ 0552 0553 /* Round 2 */ 0554 GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ 0555 GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ 0556 GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ 0557 GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ 0558 GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ 0559 GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ 0560 GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ 0561 GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ 0562 GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ 0563 GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ 0564 GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ 0565 GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ 0566 GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ 0567 GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ 0568 GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ 0569 GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ 0570 0571 /* Round 3 */ 0572 HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ 0573 HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ 0574 HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ 0575 HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ 0576 HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ 0577 HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ 0578 HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ 0579 HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ 0580 HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ 0581 HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ 0582 HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ 0583 HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ 0584 HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ 0585 HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ 0586 HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ 0587 HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ 0588 0589 /* Round 4 */ 0590 II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ 0591 II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ 0592 II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ 0593 II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ 0594 II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ 0595 II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ 0596 II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ 0597 II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ 0598 II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ 0599 II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ 0600 II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ 0601 II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ 0602 II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ 0603 II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ 0604 II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ 0605 II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ 0606 0607 state [0] += a; 0608 state [1] += b; 0609 state [2] += c; 0610 state [3] += d; 0611 0612 } 0613 0614 /*****************************************************************************/ 0615 0616 // End of RSA Data Security, Inc. derived code. 0617 0618 /*****************************************************************************/