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