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 /*****************************************************************************/