2
* This code is derived from (original license follows):
4
* This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
5
* MD5 Message-Digest Algorithm (RFC 1321).
8
* http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
11
* Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
13
* This software was written by Alexander Peslyak in 2001. No copyright is
14
* claimed, and the software is hereby placed in the public domain.
15
* In case this attempt to disclaim copyright and place the software in the
16
* public domain is deemed null and void, then the software is
17
* Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
18
* general public under the following terms:
20
* Redistribution and use in source and binary forms, with or without
21
* modification, are permitted.
23
* There's ABSOLUTELY NO WARRANTY, express or implied.
25
* (This is a heavily cut-down "BSD license".)
27
* This differs from Colin Plumb's older public domain implementation in that
28
* no exactly 32-bit integer data type is required (any 32-bit or wider
29
* unsigned integer data type will do), there's no compile-time endianness
30
* configuration, and the function prototypes match OpenSSL's. No code from
31
* Colin Plumb's implementation has been reused; this comment merely compares
32
* the properties of the two independent implementations.
34
* The primary goals of this implementation are portability and ease of use.
35
* It is meant to be fast, but not as fast as possible. Some known
36
* optimizations are not included to reduce source code size and avoid
37
* compile-time configuration.
40
#include "llvm/ADT/ArrayRef.h"
41
#include "llvm/Support/Format.h"
42
#include "llvm/Support/MD5.h"
43
#include "llvm/Support/raw_ostream.h"
46
// The basic MD5 functions.
48
// F and G are optimized compared to their RFC 1321 definitions for
49
// architectures that lack an AND-NOT instruction, just like in Colin Plumb's
51
#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
52
#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y))))
53
#define H(x, y, z) ((x) ^ (y) ^ (z))
54
#define I(x, y, z) ((y) ^ ((x) | ~(z)))
56
// The MD5 transformation for all four rounds.
57
#define STEP(f, a, b, c, d, x, t, s) \
58
(a) += f((b), (c), (d)) + (x) + (t); \
59
(a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
62
// SET reads 4 input bytes in little-endian byte order and stores them
63
// in a properly aligned word in host byte order.
66
(MD5_u32plus) ptr[(n) * 4] | ((MD5_u32plus) ptr[(n) * 4 + 1] << 8) | \
67
((MD5_u32plus) ptr[(n) * 4 + 2] << 16) | \
68
((MD5_u32plus) ptr[(n) * 4 + 3] << 24))
69
#define GET(n) (block[(n)])
73
/// \brief This processes one or more 64-byte data blocks, but does NOT update
74
///the bit counters. There are no alignment requirements.
75
const unsigned char *MD5::body(ArrayRef<unsigned char> Data) {
76
const unsigned char *ptr;
77
MD5_u32plus a, b, c, d;
78
MD5_u32plus saved_a, saved_b, saved_c, saved_d;
79
unsigned long Size = Data.size();
95
STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
96
STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
97
STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
98
STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
99
STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
100
STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
101
STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
102
STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
103
STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
104
STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
105
STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
106
STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
107
STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
108
STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
109
STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
110
STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
113
STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
114
STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
115
STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
116
STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
117
STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
118
STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
119
STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
120
STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
121
STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
122
STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
123
STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
124
STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
125
STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
126
STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
127
STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
128
STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
131
STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
132
STEP(H, d, a, b, c, GET(8), 0x8771f681, 11)
133
STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
134
STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23)
135
STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
136
STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11)
137
STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
138
STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23)
139
STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
140
STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11)
141
STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
142
STEP(H, b, c, d, a, GET(6), 0x04881d05, 23)
143
STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
144
STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11)
145
STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
146
STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23)
149
STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
150
STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
151
STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
152
STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
153
STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
154
STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
155
STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
156
STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
157
STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
158
STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
159
STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
160
STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
161
STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
162
STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
163
STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
164
STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
172
} while (Size -= 64);
183
: a(0x67452301), b(0xefcdab89), c(0x98badcfe), d(0x10325476), hi(0), lo(0) {
186
/// Incrementally add \p size of \p data to the hash.
187
void MD5::update(ArrayRef<unsigned char> Data) {
188
MD5_u32plus saved_lo;
189
unsigned long used, free;
190
const unsigned char *Ptr = Data.data();
191
unsigned long Size = Data.size();
194
if ((lo = (saved_lo + Size) & 0x1fffffff) < saved_lo)
198
used = saved_lo & 0x3f;
204
memcpy(&buffer[used], Ptr, Size);
208
memcpy(&buffer[used], Ptr, free);
211
body(ArrayRef<unsigned char>(buffer, 64));
215
Ptr = body(ArrayRef<unsigned char>(Ptr, Size & ~(unsigned long) 0x3f));
219
memcpy(buffer, Ptr, Size);
222
/// \brief Finish the hash and place the resulting hash into \p result.
223
/// \param result is assumed to be a minimum of 16-bytes in size.
224
void MD5::final(MD5Result &result) {
225
unsigned long used, free;
229
buffer[used++] = 0x80;
234
memset(&buffer[used], 0, free);
235
body(ArrayRef<unsigned char>(buffer, 64));
240
memset(&buffer[used], 0, free - 8);
244
buffer[57] = lo >> 8;
245
buffer[58] = lo >> 16;
246
buffer[59] = lo >> 24;
248
buffer[61] = hi >> 8;
249
buffer[62] = hi >> 16;
250
buffer[63] = hi >> 24;
252
body(ArrayRef<unsigned char>(buffer, 64));
264
result[10] = c >> 16;
265
result[11] = c >> 24;
268
result[14] = d >> 16;
269
result[15] = d >> 24;
272
void MD5::stringifyResult(MD5Result &result, SmallString<32> &Str) {
273
raw_svector_ostream Res(Str);
274
for (int i = 0; i < 16; ++i)
275
Res << format("%.2x", result[i]);