Blender V5.0
md5.cpp
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 1999, 2002 Aladdin Enterprises. All rights reserved.
2 *
3 * SPDX-License-Identifier: Zlib
4 *
5 * By `L. Peter Deutsch <ghost@aladdin.com>`. */
6
7/* Minor modifications done to remove some code and change style. */
8
9#include "util/md5.h"
10#include "util/log.h"
11#include "util/path.h"
12
13#include <cstdio>
14#include <cstring>
15
17
18// NOLINTBEGIN
19#define T_MASK ((uint32_t)~0)
20#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
21#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
22#define T3 0x242070db
23#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
24#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
25#define T6 0x4787c62a
26#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
27#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
28#define T9 0x698098d8
29#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
30#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
31#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
32#define T13 0x6b901122
33#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
34#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
35#define T16 0x49b40821
36#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
37#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
38#define T19 0x265e5a51
39#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
40#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
41#define T22 0x02441453
42#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
43#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
44#define T25 0x21e1cde6
45#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
46#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
47#define T28 0x455a14ed
48#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
49#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
50#define T31 0x676f02d9
51#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
52#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
53#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
54#define T35 0x6d9d6122
55#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
56#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
57#define T38 0x4bdecfa9
58#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
59#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
60#define T41 0x289b7ec6
61#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
62#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
63#define T44 0x04881d05
64#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
65#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
66#define T47 0x1fa27cf8
67#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
68#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
69#define T50 0x432aff97
70#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
71#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
72#define T53 0x655b59c3
73#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
74#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
75#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
76#define T57 0x6fa87e4f
77#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
78#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
79#define T60 0x4e0811a1
80#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
81#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
82#define T63 0x2ad7d2bb
83#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
84// NOLINTEND
85
86void MD5Hash::process(const uint8_t *data /*[64]*/)
87{
88 uint32_t a = abcd[0];
89 uint32_t b = abcd[1];
90 uint32_t c = abcd[2];
91 uint32_t d = abcd[3];
92 uint32_t t;
93 /* Define storage for little-endian or both types of CPUs. */
94 uint32_t xbuf[16];
95 const uint32_t *X;
96
97 {
98 /*
99 * Determine dynamically whether this is a big-endian or
100 * little-endian machine, since we can use a more efficient
101 * algorithm on the latter.
102 */
103 static const int w = 1;
104
105 if (*((const uint8_t *)&w)) /* dynamic little-endian */ {
106#if defined(__GNUC__) && defined(__clang__)
107# pragma clang diagnostic push
108# pragma clang diagnostic ignored "-Wnull-pointer-subtraction"
109#endif
110 /*
111 * On little-endian machines, we can process properly aligned
112 * data without copying it.
113 */
114 if (!((data - (const uint8_t *)nullptr) & 3)) {
115 /* data are properly aligned */
116 X = (const uint32_t *)data;
117 }
118 else {
119 /* not aligned */
120 memcpy(xbuf, data, 64);
121 X = xbuf;
122 }
123#if defined(__GNUC__) && defined(__clang__)
124# pragma clang diagnostic pop
125#endif
126 }
127 else { /* dynamic big-endian */
128 /*
129 * On big-endian machines, we must arrange the bytes in the
130 * right order.
131 */
132 const uint8_t *xp = data;
133 int i;
134
135 X = xbuf; /* (dynamic only) */
136 for (i = 0; i < 16; ++i, xp += 4) {
137 xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
138 }
139 }
140 }
141
142#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
143
144 /* Round 1. */
145 /* Let [abcd k s i] denote the operation
146 * a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
147#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
148#define SET(a, b, c, d, k, s, Ti) \
149 t = a + F(b, c, d) + X[k] + Ti; \
150 a = ROTATE_LEFT(t, s) + b
151 /* Do the following 16 operations. */
152 SET(a, b, c, d, 0, 7, T1);
153 SET(d, a, b, c, 1, 12, T2);
154 SET(c, d, a, b, 2, 17, T3);
155 SET(b, c, d, a, 3, 22, T4);
156 SET(a, b, c, d, 4, 7, T5);
157 SET(d, a, b, c, 5, 12, T6);
158 SET(c, d, a, b, 6, 17, T7);
159 SET(b, c, d, a, 7, 22, T8);
160 SET(a, b, c, d, 8, 7, T9);
161 SET(d, a, b, c, 9, 12, T10);
162 SET(c, d, a, b, 10, 17, T11);
163 SET(b, c, d, a, 11, 22, T12);
164 SET(a, b, c, d, 12, 7, T13);
165 SET(d, a, b, c, 13, 12, T14);
166 SET(c, d, a, b, 14, 17, T15);
167 SET(b, c, d, a, 15, 22, T16);
168#undef SET
169
170 /* Round 2. */
171 /* Let [abcd k s i] denote the operation
172 * a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
173#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
174#define SET(a, b, c, d, k, s, Ti) \
175 t = a + G(b, c, d) + X[k] + Ti; \
176 a = ROTATE_LEFT(t, s) + b
177 /* Do the following 16 operations. */
178 SET(a, b, c, d, 1, 5, T17);
179 SET(d, a, b, c, 6, 9, T18);
180 SET(c, d, a, b, 11, 14, T19);
181 SET(b, c, d, a, 0, 20, T20);
182 SET(a, b, c, d, 5, 5, T21);
183 SET(d, a, b, c, 10, 9, T22);
184 SET(c, d, a, b, 15, 14, T23);
185 SET(b, c, d, a, 4, 20, T24);
186 SET(a, b, c, d, 9, 5, T25);
187 SET(d, a, b, c, 14, 9, T26);
188 SET(c, d, a, b, 3, 14, T27);
189 SET(b, c, d, a, 8, 20, T28);
190 SET(a, b, c, d, 13, 5, T29);
191 SET(d, a, b, c, 2, 9, T30);
192 SET(c, d, a, b, 7, 14, T31);
193 SET(b, c, d, a, 12, 20, T32);
194#undef SET
195
196 /* Round 3. */
197 /* Let [abcd k s t] denote the operation
198 * a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
199#define H(x, y, z) ((x) ^ (y) ^ (z))
200#define SET(a, b, c, d, k, s, Ti) \
201 t = a + H(b, c, d) + X[k] + Ti; \
202 a = ROTATE_LEFT(t, s) + b
203 /* Do the following 16 operations. */
204 SET(a, b, c, d, 5, 4, T33);
205 SET(d, a, b, c, 8, 11, T34);
206 SET(c, d, a, b, 11, 16, T35);
207 SET(b, c, d, a, 14, 23, T36);
208 SET(a, b, c, d, 1, 4, T37);
209 SET(d, a, b, c, 4, 11, T38);
210 SET(c, d, a, b, 7, 16, T39);
211 SET(b, c, d, a, 10, 23, T40);
212 SET(a, b, c, d, 13, 4, T41);
213 SET(d, a, b, c, 0, 11, T42);
214 SET(c, d, a, b, 3, 16, T43);
215 SET(b, c, d, a, 6, 23, T44);
216 SET(a, b, c, d, 9, 4, T45);
217 SET(d, a, b, c, 12, 11, T46);
218 SET(c, d, a, b, 15, 16, T47);
219 SET(b, c, d, a, 2, 23, T48);
220#undef SET
221
222 /* Round 4. */
223 /* Let [abcd k s t] denote the operation
224 * a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
225#define I(x, y, z) ((y) ^ ((x) | ~(z)))
226#define SET(a, b, c, d, k, s, Ti) \
227 t = a + I(b, c, d) + X[k] + Ti; \
228 a = ROTATE_LEFT(t, s) + b
229 /* Do the following 16 operations. */
230 SET(a, b, c, d, 0, 6, T49);
231 SET(d, a, b, c, 7, 10, T50);
232 SET(c, d, a, b, 14, 15, T51);
233 SET(b, c, d, a, 5, 21, T52);
234 SET(a, b, c, d, 12, 6, T53);
235 SET(d, a, b, c, 3, 10, T54);
236 SET(c, d, a, b, 10, 15, T55);
237 SET(b, c, d, a, 1, 21, T56);
238 SET(a, b, c, d, 8, 6, T57);
239 SET(d, a, b, c, 15, 10, T58);
240 SET(c, d, a, b, 6, 15, T59);
241 SET(b, c, d, a, 13, 21, T60);
242 SET(a, b, c, d, 4, 6, T61);
243 SET(d, a, b, c, 11, 10, T62);
244 SET(c, d, a, b, 2, 15, T63);
245 SET(b, c, d, a, 9, 21, T64);
246#undef SET
247
248 /* Then perform the following additions. (That is increment each
249 * of the four registers by the value it had before this block
250 * was started.) */
251 abcd[0] += a;
252 abcd[1] += b;
253 abcd[2] += c;
254 abcd[3] += d;
255}
256
258{
259 count[0] = count[1] = 0;
260 abcd[0] = 0x67452301;
261 abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
262 abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
263 abcd[3] = 0x10325476;
264}
265
266MD5Hash::~MD5Hash() = default;
267
268void MD5Hash::append(const uint8_t *data, const int nbytes)
269{
270 const uint8_t *p = data;
271 int left = nbytes;
272 const int offset = (count[0] >> 3) & 63;
273 const uint32_t nbits = (uint32_t)(nbytes << 3);
274
275 if (nbytes <= 0) {
276 return;
277 }
278
279 /* Update the message length. */
280 count[1] += nbytes >> 29;
281 count[0] += nbits;
282 if (count[0] < nbits) {
283 count[1]++;
284 }
285
286 /* Process an initial partial block. */
287 if (offset) {
288 const int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
289
290 memcpy(buf + offset, p, copy);
291 if (offset + copy < 64) {
292 return;
293 }
294 p += copy;
295 left -= copy;
296 process(buf);
297 }
298
299 /* Process full blocks. */
300 for (; left >= 64; p += 64, left -= 64) {
301 process(p);
302 }
303
304 /* Process a final partial block. */
305 if (left) {
306 memcpy(buf, p, left);
307 }
308}
309
310void MD5Hash::append(const string &str)
311{
312 if (!str.empty()) {
313 append((const uint8_t *)str.c_str(), str.size());
314 }
315}
316
317bool MD5Hash::append_file(const string &filepath)
318{
319 FILE *f = path_fopen(filepath, "rb");
320
321 if (!f) {
322 LOG_ERROR << "MD5: failed to open file " << filepath;
323 return false;
324 }
325
326 const size_t buffer_size = 1024;
327 uint8_t buffer[buffer_size];
328 size_t n;
329
330 do {
331 n = fread(buffer, 1, buffer_size, f);
332 append(buffer, n);
333 } while (n == buffer_size);
334
335 const bool success = (ferror(f) == 0);
336
337 fclose(f);
338
339 return success;
340}
341
342void MD5Hash::finish(uint8_t digest[16])
343{
344 static const uint8_t pad[64] = {0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
345 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
346 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
347 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
348
349 uint8_t data[8];
350 int i;
351
352 /* Save the length before padding. */
353 for (i = 0; i < 8; ++i) {
354 data[i] = (uint8_t)(count[i >> 2] >> ((i & 3) << 3));
355 }
356
357 /* Pad to 56 bytes mod 64. */
358 append(pad, ((55 - (count[0] >> 3)) & 63) + 1);
359 /* Append the length. */
360 append(data, 8);
361
362 for (i = 0; i < 16; ++i) {
363 digest[i] = (uint8_t)(abcd[i >> 2] >> ((i & 3) << 3));
364 }
365}
366
368{
369 constexpr char kHexDigits[] = {
370 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
371
372 uint8_t digest[16];
373 char buf[16 * 2 + 1];
374
375 finish(digest);
376
377 for (int i = 0; i < 16; i++) {
378 buf[i * 2 + 0] = kHexDigits[digest[i] / 0x10];
379 buf[i * 2 + 1] = kHexDigits[digest[i] % 0x10];
380 }
381 buf[sizeof(buf) - 1] = '\0';
382
383 return string(buf);
384}
385
386string util_md5_string(const string &str)
387{
388 MD5Hash md5;
389 md5.append((uint8_t *)str.c_str(), str.size());
390 return md5.get_hex();
391}
392
#define X
int pad[32 - sizeof(int)]
BMesh const char void * data
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition btQuadWord.h:119
Definition md5.h:19
bool append_file(const string &filepath)
Definition md5.cpp:317
void append(const uint8_t *data, const int nbytes)
Definition md5.cpp:268
string get_hex()
Definition md5.cpp:367
uint8_t buf[64]
Definition md5.h:35
void finish(uint8_t digest[16])
Definition md5.cpp:342
MD5Hash()
Definition md5.cpp:257
void process(const uint8_t *data)
Definition md5.cpp:86
uint32_t abcd[4]
Definition md5.h:34
uint32_t count[2]
Definition md5.h:33
#define CCL_NAMESPACE_END
#define str(s)
#define LOG_ERROR
Definition log.h:101
static int left
#define T51
Definition md5.cpp:70
#define T46
Definition md5.cpp:65
#define T50
Definition md5.cpp:69
#define T45
Definition md5.cpp:64
#define T56
Definition md5.cpp:75
#define T17
Definition md5.cpp:36
#define T54
Definition md5.cpp:73
#define T20
Definition md5.cpp:39
#define T43
Definition md5.cpp:62
#define T9
Definition md5.cpp:28
#define T14
Definition md5.cpp:33
#define T57
Definition md5.cpp:76
#define T37
Definition md5.cpp:56
#define T2
Definition md5.cpp:21
#define T_MASK
Definition md5.cpp:19
#define T7
Definition md5.cpp:26
#define T61
Definition md5.cpp:80
#define T10
Definition md5.cpp:29
#define T31
Definition md5.cpp:50
#define T62
Definition md5.cpp:81
#define T26
Definition md5.cpp:45
#define T24
Definition md5.cpp:43
#define T44
Definition md5.cpp:63
#define T25
Definition md5.cpp:44
#define T36
Definition md5.cpp:55
#define T18
Definition md5.cpp:37
#define T21
Definition md5.cpp:40
#define T6
Definition md5.cpp:25
#define T3
Definition md5.cpp:22
#define T58
Definition md5.cpp:77
#define SET(a, b, c, d, k, s, Ti)
#define T29
Definition md5.cpp:48
#define T60
Definition md5.cpp:79
#define T59
Definition md5.cpp:78
#define T5
Definition md5.cpp:24
#define T53
Definition md5.cpp:72
#define T39
Definition md5.cpp:58
#define T38
Definition md5.cpp:57
#define T19
Definition md5.cpp:38
#define T33
Definition md5.cpp:52
#define T49
Definition md5.cpp:68
#define T16
Definition md5.cpp:35
#define T22
Definition md5.cpp:41
#define T55
Definition md5.cpp:74
#define T41
Definition md5.cpp:60
#define T48
Definition md5.cpp:67
#define T4
Definition md5.cpp:23
#define T64
Definition md5.cpp:83
#define T40
Definition md5.cpp:59
#define T47
Definition md5.cpp:66
#define T13
Definition md5.cpp:32
#define T30
Definition md5.cpp:49
#define T11
Definition md5.cpp:30
#define T63
Definition md5.cpp:82
#define T1
Definition md5.cpp:20
#define T35
Definition md5.cpp:54
string util_md5_string(const string &str)
Definition md5.cpp:386
#define T8
Definition md5.cpp:27
#define T23
Definition md5.cpp:42
#define T42
Definition md5.cpp:61
#define T15
Definition md5.cpp:34
#define T34
Definition md5.cpp:53
#define T27
Definition md5.cpp:46
#define T28
Definition md5.cpp:47
#define T52
Definition md5.cpp:71
#define T32
Definition md5.cpp:51
#define T12
Definition md5.cpp:31
static void copy(bNodeTree *dest_ntree, bNode *dest_node, const bNode *src_node)
FILE * path_fopen(const string &path, const string &mode)
Definition path.cpp:975
i
Definition text_draw.cc:230