OLD | NEW |
1 /* | 1 /* |
2 * This code implements the MD5 message-digest algorithm. | 2 * This code implements the MD5 message-digest algorithm. |
3 * The algorithm is due to Ron Rivest. This code was | 3 * The algorithm is due to Ron Rivest. This code was |
4 * written by Colin Plumb in 1993, no copyright is claimed. | 4 * written by Colin Plumb in 1993, no copyright is claimed. |
5 * This code is in the public domain; do with it what you wish. | 5 * This code is in the public domain; do with it what you wish. |
6 * | 6 * |
7 * Equivalent code is available from RSA Data Security, Inc. | 7 * Equivalent code is available from RSA Data Security, Inc. |
8 * This code has been tested against that, and is equivalent, | 8 * This code has been tested against that, and is equivalent, |
9 * except that you don't need to include two pages of legalese | 9 * except that you don't need to include two pages of legalese |
10 * with every copy. | 10 * with every copy. |
(...skipping 12 matching lines...) Expand all Loading... |
23 // TODO: Avoid memcmpy - hash directly from memory. | 23 // TODO: Avoid memcmpy - hash directly from memory. |
24 #include <string.h> // for memcpy(). | 24 #include <string.h> // for memcpy(). |
25 | 25 |
26 #include "webrtc/base/byteorder.h" // for RTC_ARCH_CPU_LITTLE_ENDIAN. | 26 #include "webrtc/base/byteorder.h" // for RTC_ARCH_CPU_LITTLE_ENDIAN. |
27 | 27 |
28 namespace rtc { | 28 namespace rtc { |
29 | 29 |
30 #ifdef RTC_ARCH_CPU_LITTLE_ENDIAN | 30 #ifdef RTC_ARCH_CPU_LITTLE_ENDIAN |
31 #define ByteReverse(buf, len) // Nothing. | 31 #define ByteReverse(buf, len) // Nothing. |
32 #else // RTC_ARCH_CPU_BIG_ENDIAN | 32 #else // RTC_ARCH_CPU_BIG_ENDIAN |
33 static void ByteReverse(uint32* buf, int len) { | 33 static void ByteReverse(uint32_t* buf, int len) { |
34 for (int i = 0; i < len; ++i) { | 34 for (int i = 0; i < len; ++i) { |
35 buf[i] = rtc::GetLE32(&buf[i]); | 35 buf[i] = rtc::GetLE32(&buf[i]); |
36 } | 36 } |
37 } | 37 } |
38 #endif | 38 #endif |
39 | 39 |
40 // Start MD5 accumulation. Set bit count to 0 and buffer to mysterious | 40 // Start MD5 accumulation. Set bit count to 0 and buffer to mysterious |
41 // initialization constants. | 41 // initialization constants. |
42 void MD5Init(MD5Context* ctx) { | 42 void MD5Init(MD5Context* ctx) { |
43 ctx->buf[0] = 0x67452301; | 43 ctx->buf[0] = 0x67452301; |
44 ctx->buf[1] = 0xefcdab89; | 44 ctx->buf[1] = 0xefcdab89; |
45 ctx->buf[2] = 0x98badcfe; | 45 ctx->buf[2] = 0x98badcfe; |
46 ctx->buf[3] = 0x10325476; | 46 ctx->buf[3] = 0x10325476; |
47 ctx->bits[0] = 0; | 47 ctx->bits[0] = 0; |
48 ctx->bits[1] = 0; | 48 ctx->bits[1] = 0; |
49 } | 49 } |
50 | 50 |
51 // Update context to reflect the concatenation of another buffer full of bytes. | 51 // Update context to reflect the concatenation of another buffer full of bytes. |
52 void MD5Update(MD5Context* ctx, const uint8* buf, size_t len) { | 52 void MD5Update(MD5Context* ctx, const uint8_t* buf, size_t len) { |
53 // Update bitcount. | 53 // Update bitcount. |
54 uint32 t = ctx->bits[0]; | 54 uint32_t t = ctx->bits[0]; |
55 if ((ctx->bits[0] = t + (static_cast<uint32>(len) << 3)) < t) { | 55 if ((ctx->bits[0] = t + (static_cast<uint32_t>(len) << 3)) < t) { |
56 ctx->bits[1]++; // Carry from low to high. | 56 ctx->bits[1]++; // Carry from low to high. |
57 } | 57 } |
58 ctx->bits[1] += static_cast<uint32>(len >> 29); | 58 ctx->bits[1] += static_cast<uint32_t>(len >> 29); |
59 t = (t >> 3) & 0x3f; // Bytes already in shsInfo->data. | 59 t = (t >> 3) & 0x3f; // Bytes already in shsInfo->data. |
60 | 60 |
61 // Handle any leading odd-sized chunks. | 61 // Handle any leading odd-sized chunks. |
62 if (t) { | 62 if (t) { |
63 uint8* p = reinterpret_cast<uint8*>(ctx->in) + t; | 63 uint8_t* p = reinterpret_cast<uint8_t*>(ctx->in) + t; |
64 | 64 |
65 t = 64-t; | 65 t = 64-t; |
66 if (len < t) { | 66 if (len < t) { |
67 memcpy(p, buf, len); | 67 memcpy(p, buf, len); |
68 return; | 68 return; |
69 } | 69 } |
70 memcpy(p, buf, t); | 70 memcpy(p, buf, t); |
71 ByteReverse(ctx->in, 16); | 71 ByteReverse(ctx->in, 16); |
72 MD5Transform(ctx->buf, ctx->in); | 72 MD5Transform(ctx->buf, ctx->in); |
73 buf += t; | 73 buf += t; |
74 len -= t; | 74 len -= t; |
75 } | 75 } |
76 | 76 |
77 // Process data in 64-byte chunks. | 77 // Process data in 64-byte chunks. |
78 while (len >= 64) { | 78 while (len >= 64) { |
79 memcpy(ctx->in, buf, 64); | 79 memcpy(ctx->in, buf, 64); |
80 ByteReverse(ctx->in, 16); | 80 ByteReverse(ctx->in, 16); |
81 MD5Transform(ctx->buf, ctx->in); | 81 MD5Transform(ctx->buf, ctx->in); |
82 buf += 64; | 82 buf += 64; |
83 len -= 64; | 83 len -= 64; |
84 } | 84 } |
85 | 85 |
86 // Handle any remaining bytes of data. | 86 // Handle any remaining bytes of data. |
87 memcpy(ctx->in, buf, len); | 87 memcpy(ctx->in, buf, len); |
88 } | 88 } |
89 | 89 |
90 // Final wrapup - pad to 64-byte boundary with the bit pattern. | 90 // Final wrapup - pad to 64-byte boundary with the bit pattern. |
91 // 1 0* (64-bit count of bits processed, MSB-first) | 91 // 1 0* (64-bit count of bits processed, MSB-first) |
92 void MD5Final(MD5Context* ctx, uint8 digest[16]) { | 92 void MD5Final(MD5Context* ctx, uint8_t digest[16]) { |
93 // Compute number of bytes mod 64. | 93 // Compute number of bytes mod 64. |
94 uint32 count = (ctx->bits[0] >> 3) & 0x3F; | 94 uint32_t count = (ctx->bits[0] >> 3) & 0x3F; |
95 | 95 |
96 // Set the first char of padding to 0x80. This is safe since there is | 96 // Set the first char of padding to 0x80. This is safe since there is |
97 // always at least one byte free. | 97 // always at least one byte free. |
98 uint8* p = reinterpret_cast<uint8*>(ctx->in) + count; | 98 uint8_t* p = reinterpret_cast<uint8_t*>(ctx->in) + count; |
99 *p++ = 0x80; | 99 *p++ = 0x80; |
100 | 100 |
101 // Bytes of padding needed to make 64 bytes. | 101 // Bytes of padding needed to make 64 bytes. |
102 count = 64 - 1 - count; | 102 count = 64 - 1 - count; |
103 | 103 |
104 // Pad out to 56 mod 64. | 104 // Pad out to 56 mod 64. |
105 if (count < 8) { | 105 if (count < 8) { |
106 // Two lots of padding: Pad the first block to 64 bytes. | 106 // Two lots of padding: Pad the first block to 64 bytes. |
107 memset(p, 0, count); | 107 memset(p, 0, count); |
108 ByteReverse(ctx->in, 16); | 108 ByteReverse(ctx->in, 16); |
(...skipping 24 matching lines...) Expand all Loading... |
133 #define F3(x, y, z) (x ^ y ^ z) | 133 #define F3(x, y, z) (x ^ y ^ z) |
134 #define F4(x, y, z) (y ^ (x | ~z)) | 134 #define F4(x, y, z) (y ^ (x | ~z)) |
135 | 135 |
136 // This is the central step in the MD5 algorithm. | 136 // This is the central step in the MD5 algorithm. |
137 #define MD5STEP(f, w, x, y, z, data, s) \ | 137 #define MD5STEP(f, w, x, y, z, data, s) \ |
138 (w += f(x, y, z) + data, w = w << s | w >> (32 - s), w += x) | 138 (w += f(x, y, z) + data, w = w << s | w >> (32 - s), w += x) |
139 | 139 |
140 // The core of the MD5 algorithm, this alters an existing MD5 hash to | 140 // The core of the MD5 algorithm, this alters an existing MD5 hash to |
141 // reflect the addition of 16 longwords of new data. MD5Update blocks | 141 // reflect the addition of 16 longwords of new data. MD5Update blocks |
142 // the data and converts bytes into longwords for this routine. | 142 // the data and converts bytes into longwords for this routine. |
143 void MD5Transform(uint32 buf[4], const uint32 in[16]) { | 143 void MD5Transform(uint32_t buf[4], const uint32_t in[16]) { |
144 uint32 a = buf[0]; | 144 uint32_t a = buf[0]; |
145 uint32 b = buf[1]; | 145 uint32_t b = buf[1]; |
146 uint32 c = buf[2]; | 146 uint32_t c = buf[2]; |
147 uint32 d = buf[3]; | 147 uint32_t d = buf[3]; |
148 | 148 |
149 MD5STEP(F1, a, b, c, d, in[ 0] + 0xd76aa478, 7); | 149 MD5STEP(F1, a, b, c, d, in[ 0] + 0xd76aa478, 7); |
150 MD5STEP(F1, d, a, b, c, in[ 1] + 0xe8c7b756, 12); | 150 MD5STEP(F1, d, a, b, c, in[ 1] + 0xe8c7b756, 12); |
151 MD5STEP(F1, c, d, a, b, in[ 2] + 0x242070db, 17); | 151 MD5STEP(F1, c, d, a, b, in[ 2] + 0x242070db, 17); |
152 MD5STEP(F1, b, c, d, a, in[ 3] + 0xc1bdceee, 22); | 152 MD5STEP(F1, b, c, d, a, in[ 3] + 0xc1bdceee, 22); |
153 MD5STEP(F1, a, b, c, d, in[ 4] + 0xf57c0faf, 7); | 153 MD5STEP(F1, a, b, c, d, in[ 4] + 0xf57c0faf, 7); |
154 MD5STEP(F1, d, a, b, c, in[ 5] + 0x4787c62a, 12); | 154 MD5STEP(F1, d, a, b, c, in[ 5] + 0x4787c62a, 12); |
155 MD5STEP(F1, c, d, a, b, in[ 6] + 0xa8304613, 17); | 155 MD5STEP(F1, c, d, a, b, in[ 6] + 0xa8304613, 17); |
156 MD5STEP(F1, b, c, d, a, in[ 7] + 0xfd469501, 22); | 156 MD5STEP(F1, b, c, d, a, in[ 7] + 0xfd469501, 22); |
157 MD5STEP(F1, a, b, c, d, in[ 8] + 0x698098d8, 7); | 157 MD5STEP(F1, a, b, c, d, in[ 8] + 0x698098d8, 7); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
213 MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); | 213 MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); |
214 MD5STEP(F4, c, d, a, b, in[ 2] + 0x2ad7d2bb, 15); | 214 MD5STEP(F4, c, d, a, b, in[ 2] + 0x2ad7d2bb, 15); |
215 MD5STEP(F4, b, c, d, a, in[ 9] + 0xeb86d391, 21); | 215 MD5STEP(F4, b, c, d, a, in[ 9] + 0xeb86d391, 21); |
216 buf[0] += a; | 216 buf[0] += a; |
217 buf[1] += b; | 217 buf[1] += b; |
218 buf[2] += c; | 218 buf[2] += c; |
219 buf[3] += d; | 219 buf[3] += d; |
220 } | 220 } |
221 | 221 |
222 } // namespace rtc | 222 } // namespace rtc |
OLD | NEW |