Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Support/MD5.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * This code is derived from (original license follows):
3
 *
4
 * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
5
 * MD5 Message-Digest Algorithm (RFC 1321).
6
 *
7
 * Homepage:
8
 * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
9
 *
10
 * Author:
11
 * Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
12
 *
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:
19
 *
20
 * Redistribution and use in source and binary forms, with or without
21
 * modification, are permitted.
22
 *
23
 * There's ABSOLUTELY NO WARRANTY, express or implied.
24
 *
25
 * (This is a heavily cut-down "BSD license".)
26
 *
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.
33
 *
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.
38
 */
39
40
#include "llvm/Support/MD5.h"
41
#include "llvm/ADT/ArrayRef.h"
42
#include "llvm/ADT/StringRef.h"
43
#include "llvm/Support/Endian.h"
44
#include "llvm/Support/Format.h"
45
#include "llvm/Support/raw_ostream.h"
46
#include <array>
47
#include <cstdint>
48
#include <cstring>
49
50
// The basic MD5 functions.
51
52
// F and G are optimized compared to their RFC 1321 definitions for
53
// architectures that lack an AND-NOT instruction, just like in Colin Plumb's
54
// implementation.
55
720k
#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
56
720k
#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y))))
57
720k
#define H(x, y, z) ((x) ^ (y) ^ (z))
58
720k
#define I(x, y, z) ((y) ^ ((x) | ~(z)))
59
60
// The MD5 transformation for all four rounds.
61
#define STEP(f, a, b, c, d, x, t, s)                                           \
62
2.88M
  (a) += f((b), (c), (d)) + (x) + (t);                                         \
63
2.88M
  (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s))));                   \
64
2.88M
  (a) += (b);
65
66
// SET reads 4 input bytes in little-endian byte order and stores them
67
// in a properly aligned word in host byte order.
68
#define SET(n)                                                                 \
69
  (block[(n)] =                                                                \
70
       (MD5_u32plus) ptr[(n) * 4] | ((MD5_u32plus) ptr[(n) * 4 + 1] << 8) |    \
71
       ((MD5_u32plus) ptr[(n) * 4 + 2] << 16) |                                \
72
       ((MD5_u32plus) ptr[(n) * 4 + 3] << 24))
73
#define GET(n) (block[(n)])
74
75
using namespace llvm;
76
77
/// This processes one or more 64-byte data blocks, but does NOT update
78
///the bit counters.  There are no alignment requirements.
79
32.4k
const uint8_t *MD5::body(ArrayRef<uint8_t> Data) {
80
32.4k
  const uint8_t *ptr;
81
32.4k
  MD5_u32plus a, b, c, d;
82
32.4k
  MD5_u32plus saved_a, saved_b, saved_c, saved_d;
83
32.4k
  unsigned long Size = Data.size();
84
32.4k
85
32.4k
  ptr = Data.data();
86
32.4k
87
32.4k
  a = this->a;
88
32.4k
  b = this->b;
89
32.4k
  c = this->c;
90
32.4k
  d = this->d;
91
32.4k
92
45.0k
  do {
93
45.0k
    saved_a = a;
94
45.0k
    saved_b = b;
95
45.0k
    saved_c = c;
96
45.0k
    saved_d = d;
97
45.0k
98
45.0k
    // Round 1
99
45.0k
    STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
100
45.0k
    STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
101
45.0k
    STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
102
45.0k
    STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
103
45.0k
    STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
104
45.0k
    STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
105
45.0k
    STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
106
45.0k
    STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
107
45.0k
    STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
108
45.0k
    STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
109
45.0k
    STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
110
45.0k
    STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
111
45.0k
    STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
112
45.0k
    STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
113
45.0k
    STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
114
45.0k
    STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
115
45.0k
116
45.0k
    // Round 2
117
45.0k
    STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
118
45.0k
    STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
119
45.0k
    STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
120
45.0k
    STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
121
45.0k
    STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
122
45.0k
    STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
123
45.0k
    STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
124
45.0k
    STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
125
45.0k
    STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
126
45.0k
    STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
127
45.0k
    STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
128
45.0k
    STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
129
45.0k
    STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
130
45.0k
    STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
131
45.0k
    STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
132
45.0k
    STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
133
45.0k
134
45.0k
    // Round 3
135
45.0k
    STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
136
45.0k
    STEP(H, d, a, b, c, GET(8), 0x8771f681, 11)
137
45.0k
    STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
138
45.0k
    STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23)
139
45.0k
    STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
140
45.0k
    STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11)
141
45.0k
    STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
142
45.0k
    STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23)
143
45.0k
    STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
144
45.0k
    STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11)
145
45.0k
    STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
146
45.0k
    STEP(H, b, c, d, a, GET(6), 0x04881d05, 23)
147
45.0k
    STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
148
45.0k
    STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11)
149
45.0k
    STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
150
45.0k
    STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23)
151
45.0k
152
45.0k
    // Round 4
153
45.0k
    STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
154
45.0k
    STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
155
45.0k
    STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
156
45.0k
    STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
157
45.0k
    STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
158
45.0k
    STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
159
45.0k
    STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
160
45.0k
    STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
161
45.0k
    STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
162
45.0k
    STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
163
45.0k
    STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
164
45.0k
    STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
165
45.0k
    STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
166
45.0k
    STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
167
45.0k
    STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
168
45.0k
    STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
169
45.0k
170
45.0k
    a += saved_a;
171
45.0k
    b += saved_b;
172
45.0k
    c += saved_c;
173
45.0k
    d += saved_d;
174
45.0k
175
45.0k
    ptr += 64;
176
45.0k
  } while (Size -= 64);
177
32.4k
178
32.4k
  this->a = a;
179
32.4k
  this->b = b;
180
32.4k
  this->c = c;
181
32.4k
  this->d = d;
182
32.4k
183
32.4k
  return ptr;
184
32.4k
}
185
186
30.7k
MD5::MD5() = default;
187
188
/// Incrementally add the bytes in \p Data to the hash.
189
42.6k
void MD5::update(ArrayRef<uint8_t> Data) {
190
42.6k
  MD5_u32plus saved_lo;
191
42.6k
  unsigned long used, free;
192
42.6k
  const uint8_t *Ptr = Data.data();
193
42.6k
  unsigned long Size = Data.size();
194
42.6k
195
42.6k
  saved_lo = lo;
196
42.6k
  if ((lo = (saved_lo + Size) & 0x1fffffff) < saved_lo)
197
0
    hi++;
198
42.6k
  hi += Size >> 29;
199
42.6k
200
42.6k
  used = saved_lo & 0x3f;
201
42.6k
202
42.6k
  if (used) {
203
12.2k
    free = 64 - used;
204
12.2k
205
12.2k
    if (Size < free) {
206
12.1k
      memcpy(&buffer[used], Ptr, Size);
207
12.1k
      return;
208
12.1k
    }
209
143
210
143
    memcpy(&buffer[used], Ptr, free);
211
143
    Ptr = Ptr + free;
212
143
    Size -= free;
213
143
    body(makeArrayRef(buffer, 64));
214
143
  }
215
42.6k
216
42.6k
  
if (30.4k
Size >= 6430.4k
) {
217
1.72k
    Ptr = body(makeArrayRef(Ptr, Size & ~(unsigned long) 0x3f));
218
1.72k
    Size &= 0x3f;
219
1.72k
  }
220
30.4k
221
30.4k
  memcpy(buffer, Ptr, Size);
222
30.4k
}
223
224
/// Add the bytes in the StringRef \p Str to the hash.
225
// Note that this isn't a string and so this won't include any trailing NULL
226
// bytes.
227
38.9k
void MD5::update(StringRef Str) {
228
38.9k
  ArrayRef<uint8_t> SVal((const uint8_t *)Str.data(), Str.size());
229
38.9k
  update(SVal);
230
38.9k
}
231
232
/// Finish the hash and place the resulting hash into \p result.
233
/// \param Result is assumed to be a minimum of 16-bytes in size.
234
30.3k
void MD5::final(MD5Result &Result) {
235
30.3k
  unsigned long used, free;
236
30.3k
237
30.3k
  used = lo & 0x3f;
238
30.3k
239
30.3k
  buffer[used++] = 0x80;
240
30.3k
241
30.3k
  free = 64 - used;
242
30.3k
243
30.3k
  if (free < 8) {
244
274
    memset(&buffer[used], 0, free);
245
274
    body(makeArrayRef(buffer, 64));
246
274
    used = 0;
247
274
    free = 64;
248
274
  }
249
30.3k
250
30.3k
  memset(&buffer[used], 0, free - 8);
251
30.3k
252
30.3k
  lo <<= 3;
253
30.3k
  support::endian::write32le(&buffer[56], lo);
254
30.3k
  support::endian::write32le(&buffer[60], hi);
255
30.3k
256
30.3k
  body(makeArrayRef(buffer, 64));
257
30.3k
258
30.3k
  support::endian::write32le(&Result[0], a);
259
30.3k
  support::endian::write32le(&Result[4], b);
260
30.3k
  support::endian::write32le(&Result[8], c);
261
30.3k
  support::endian::write32le(&Result[12], d);
262
30.3k
}
263
264
1.09k
SmallString<32> MD5::MD5Result::digest() const {
265
1.09k
  SmallString<32> Str;
266
1.09k
  raw_svector_ostream Res(Str);
267
18.6k
  for (int i = 0; i < 16; 
++i17.5k
)
268
17.5k
    Res << format("%.2x", Bytes[i]);
269
1.09k
  return Str;
270
1.09k
}
271
272
1.04k
void MD5::stringifyResult(MD5Result &Result, SmallString<32> &Str) {
273
1.04k
  Str = Result.digest();
274
1.04k
}
275
276
7
std::array<uint8_t, 16> MD5::hash(ArrayRef<uint8_t> Data) {
277
7
  MD5 Hash;
278
7
  Hash.update(Data);
279
7
  MD5::MD5Result Res;
280
7
  Hash.final(Res);
281
7
282
7
  return Res;
283
7
}