1e1dc3c45SEric Christopher /*
2e1dc3c45SEric Christopher  * This code is derived from (original license follows):
3e1dc3c45SEric Christopher  *
4e1dc3c45SEric Christopher  * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
5e1dc3c45SEric Christopher  * MD5 Message-Digest Algorithm (RFC 1321).
6e1dc3c45SEric Christopher  *
7e1dc3c45SEric Christopher  * Homepage:
8e1dc3c45SEric Christopher  * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
9e1dc3c45SEric Christopher  *
10e1dc3c45SEric Christopher  * Author:
11e1dc3c45SEric Christopher  * Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
12e1dc3c45SEric Christopher  *
13e1dc3c45SEric Christopher  * This software was written by Alexander Peslyak in 2001.  No copyright is
14e1dc3c45SEric Christopher  * claimed, and the software is hereby placed in the public domain.
15e1dc3c45SEric Christopher  * In case this attempt to disclaim copyright and place the software in the
16e1dc3c45SEric Christopher  * public domain is deemed null and void, then the software is
17e1dc3c45SEric Christopher  * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
18e1dc3c45SEric Christopher  * general public under the following terms:
19e1dc3c45SEric Christopher  *
20e1dc3c45SEric Christopher  * Redistribution and use in source and binary forms, with or without
21e1dc3c45SEric Christopher  * modification, are permitted.
22e1dc3c45SEric Christopher  *
23e1dc3c45SEric Christopher  * There's ABSOLUTELY NO WARRANTY, express or implied.
24e1dc3c45SEric Christopher  *
25e1dc3c45SEric Christopher  * (This is a heavily cut-down "BSD license".)
26e1dc3c45SEric Christopher  *
27e1dc3c45SEric Christopher  * This differs from Colin Plumb's older public domain implementation in that
28e1dc3c45SEric Christopher  * no exactly 32-bit integer data type is required (any 32-bit or wider
29e1dc3c45SEric Christopher  * unsigned integer data type will do), there's no compile-time endianness
30e1dc3c45SEric Christopher  * configuration, and the function prototypes match OpenSSL's.  No code from
31e1dc3c45SEric Christopher  * Colin Plumb's implementation has been reused; this comment merely compares
32e1dc3c45SEric Christopher  * the properties of the two independent implementations.
33e1dc3c45SEric Christopher  *
34e1dc3c45SEric Christopher  * The primary goals of this implementation are portability and ease of use.
35e1dc3c45SEric Christopher  * It is meant to be fast, but not as fast as possible.  Some known
36e1dc3c45SEric Christopher  * optimizations are not included to reduce source code size and avoid
37e1dc3c45SEric Christopher  * compile-time configuration.
38e1dc3c45SEric Christopher  */
39e1dc3c45SEric Christopher 
406bda14b3SChandler Carruth #include "llvm/Support/MD5.h"
41fcee6f0aSEric Christopher #include "llvm/ADT/ArrayRef.h"
42465dca79SReid Kleckner #include "llvm/ADT/SmallString.h"
430b48d0feSHans Wennborg #include "llvm/ADT/StringExtras.h"
44454d0ceaSEugene Zelenko #include "llvm/ADT/StringRef.h"
45454d0ceaSEugene Zelenko #include "llvm/Support/Endian.h"
46454d0ceaSEugene Zelenko #include <array>
47454d0ceaSEugene Zelenko #include <cstdint>
48e1dc3c45SEric Christopher #include <cstring>
49e1dc3c45SEric Christopher 
50e1dc3c45SEric Christopher // The basic MD5 functions.
51e1dc3c45SEric Christopher 
52e1dc3c45SEric Christopher // F and G are optimized compared to their RFC 1321 definitions for
53e1dc3c45SEric Christopher // architectures that lack an AND-NOT instruction, just like in Colin Plumb's
54e1dc3c45SEric Christopher // implementation.
55e1dc3c45SEric Christopher #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
56e1dc3c45SEric Christopher #define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y))))
57e1dc3c45SEric Christopher #define H(x, y, z) ((x) ^ (y) ^ (z))
58e1dc3c45SEric Christopher #define I(x, y, z) ((y) ^ ((x) | ~(z)))
59e1dc3c45SEric Christopher 
60e1dc3c45SEric Christopher // The MD5 transformation for all four rounds.
61e1dc3c45SEric Christopher #define STEP(f, a, b, c, d, x, t, s)                                           \
62e1dc3c45SEric Christopher   (a) += f((b), (c), (d)) + (x) + (t);                                         \
63e1dc3c45SEric Christopher   (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s))));                   \
64e1dc3c45SEric Christopher   (a) += (b);
65e1dc3c45SEric Christopher 
66e1dc3c45SEric Christopher // SET reads 4 input bytes in little-endian byte order and stores them
67e1dc3c45SEric Christopher // in a properly aligned word in host byte order.
68e1dc3c45SEric Christopher #define SET(n)                                                                 \
6910a12632SAlexandre Rames   (InternalState.block[(n)] = (MD5_u32plus)ptr[(n)*4] |                        \
7010a12632SAlexandre Rames                               ((MD5_u32plus)ptr[(n)*4 + 1] << 8) |             \
71e1dc3c45SEric Christopher                               ((MD5_u32plus)ptr[(n)*4 + 2] << 16) |            \
72e1dc3c45SEric Christopher                               ((MD5_u32plus)ptr[(n)*4 + 3] << 24))
7310a12632SAlexandre Rames #define GET(n) (InternalState.block[(n)])
74e1dc3c45SEric Christopher 
75454d0ceaSEugene Zelenko using namespace llvm;
76e1dc3c45SEric Christopher 
775f8f34e4SAdrian Prantl /// This processes one or more 64-byte data blocks, but does NOT update
78e1dc3c45SEric Christopher ///the bit counters.  There are no alignment requirements.
body(ArrayRef<uint8_t> Data)79606ecda4SEric Christopher const uint8_t *MD5::body(ArrayRef<uint8_t> Data) {
80606ecda4SEric Christopher   const uint8_t *ptr;
81e1dc3c45SEric Christopher   MD5_u32plus a, b, c, d;
82e1dc3c45SEric Christopher   MD5_u32plus saved_a, saved_b, saved_c, saved_d;
83fcee6f0aSEric Christopher   unsigned long Size = Data.size();
84e1dc3c45SEric Christopher 
85fcee6f0aSEric Christopher   ptr = Data.data();
86e1dc3c45SEric Christopher 
8710a12632SAlexandre Rames   a = InternalState.a;
8810a12632SAlexandre Rames   b = InternalState.b;
8910a12632SAlexandre Rames   c = InternalState.c;
9010a12632SAlexandre Rames   d = InternalState.d;
91e1dc3c45SEric Christopher 
92e1dc3c45SEric Christopher   do {
93e1dc3c45SEric Christopher     saved_a = a;
94e1dc3c45SEric Christopher     saved_b = b;
95e1dc3c45SEric Christopher     saved_c = c;
96e1dc3c45SEric Christopher     saved_d = d;
97e1dc3c45SEric Christopher 
98e1dc3c45SEric Christopher     // Round 1
99e1dc3c45SEric Christopher     STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
100e1dc3c45SEric Christopher     STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
101e1dc3c45SEric Christopher     STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
102e1dc3c45SEric Christopher     STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
103e1dc3c45SEric Christopher     STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
104e1dc3c45SEric Christopher     STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
105e1dc3c45SEric Christopher     STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
106e1dc3c45SEric Christopher     STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
107e1dc3c45SEric Christopher     STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
108e1dc3c45SEric Christopher     STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
109e1dc3c45SEric Christopher     STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
110e1dc3c45SEric Christopher     STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
111e1dc3c45SEric Christopher     STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
112e1dc3c45SEric Christopher     STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
113e1dc3c45SEric Christopher     STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
114e1dc3c45SEric Christopher     STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
115e1dc3c45SEric Christopher 
116e1dc3c45SEric Christopher     // Round 2
117e1dc3c45SEric Christopher     STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
118e1dc3c45SEric Christopher     STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
119e1dc3c45SEric Christopher     STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
120e1dc3c45SEric Christopher     STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
121e1dc3c45SEric Christopher     STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
122e1dc3c45SEric Christopher     STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
123e1dc3c45SEric Christopher     STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
124e1dc3c45SEric Christopher     STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
125e1dc3c45SEric Christopher     STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
126e1dc3c45SEric Christopher     STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
127e1dc3c45SEric Christopher     STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
128e1dc3c45SEric Christopher     STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
129e1dc3c45SEric Christopher     STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
130e1dc3c45SEric Christopher     STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
131e1dc3c45SEric Christopher     STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
132e1dc3c45SEric Christopher     STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
133e1dc3c45SEric Christopher 
134e1dc3c45SEric Christopher     // Round 3
135e1dc3c45SEric Christopher     STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
136e1dc3c45SEric Christopher     STEP(H, d, a, b, c, GET(8), 0x8771f681, 11)
137e1dc3c45SEric Christopher     STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
138e1dc3c45SEric Christopher     STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23)
139e1dc3c45SEric Christopher     STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
140e1dc3c45SEric Christopher     STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11)
141e1dc3c45SEric Christopher     STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
142e1dc3c45SEric Christopher     STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23)
143e1dc3c45SEric Christopher     STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
144e1dc3c45SEric Christopher     STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11)
145e1dc3c45SEric Christopher     STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
146e1dc3c45SEric Christopher     STEP(H, b, c, d, a, GET(6), 0x04881d05, 23)
147e1dc3c45SEric Christopher     STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
148e1dc3c45SEric Christopher     STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11)
149e1dc3c45SEric Christopher     STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
150e1dc3c45SEric Christopher     STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23)
151e1dc3c45SEric Christopher 
152e1dc3c45SEric Christopher     // Round 4
153e1dc3c45SEric Christopher     STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
154e1dc3c45SEric Christopher     STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
155e1dc3c45SEric Christopher     STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
156e1dc3c45SEric Christopher     STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
157e1dc3c45SEric Christopher     STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
158e1dc3c45SEric Christopher     STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
159e1dc3c45SEric Christopher     STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
160e1dc3c45SEric Christopher     STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
161e1dc3c45SEric Christopher     STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
162e1dc3c45SEric Christopher     STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
163e1dc3c45SEric Christopher     STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
164e1dc3c45SEric Christopher     STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
165e1dc3c45SEric Christopher     STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
166e1dc3c45SEric Christopher     STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
167e1dc3c45SEric Christopher     STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
168e1dc3c45SEric Christopher     STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
169e1dc3c45SEric Christopher 
170e1dc3c45SEric Christopher     a += saved_a;
171e1dc3c45SEric Christopher     b += saved_b;
172e1dc3c45SEric Christopher     c += saved_c;
173e1dc3c45SEric Christopher     d += saved_d;
174e1dc3c45SEric Christopher 
175e1dc3c45SEric Christopher     ptr += 64;
176fcee6f0aSEric Christopher   } while (Size -= 64);
177e1dc3c45SEric Christopher 
17810a12632SAlexandre Rames   InternalState.a = a;
17910a12632SAlexandre Rames   InternalState.b = b;
18010a12632SAlexandre Rames   InternalState.c = c;
18110a12632SAlexandre Rames   InternalState.d = d;
182e1dc3c45SEric Christopher 
183e1dc3c45SEric Christopher   return ptr;
184e1dc3c45SEric Christopher }
185e1dc3c45SEric Christopher 
186454d0ceaSEugene Zelenko MD5::MD5() = default;
187e1dc3c45SEric Christopher 
18885bd745eSEric Christopher /// Incrementally add the bytes in \p Data to the hash.
update(ArrayRef<uint8_t> Data)189606ecda4SEric Christopher void MD5::update(ArrayRef<uint8_t> Data) {
190e1dc3c45SEric Christopher   MD5_u32plus saved_lo;
191e1dc3c45SEric Christopher   unsigned long used, free;
192606ecda4SEric Christopher   const uint8_t *Ptr = Data.data();
193fcee6f0aSEric Christopher   unsigned long Size = Data.size();
194e1dc3c45SEric Christopher 
19510a12632SAlexandre Rames   saved_lo = InternalState.lo;
19610a12632SAlexandre Rames   if ((InternalState.lo = (saved_lo + Size) & 0x1fffffff) < saved_lo)
19710a12632SAlexandre Rames     InternalState.hi++;
19810a12632SAlexandre Rames   InternalState.hi += Size >> 29;
199e1dc3c45SEric Christopher 
200e1dc3c45SEric Christopher   used = saved_lo & 0x3f;
201e1dc3c45SEric Christopher 
202e1dc3c45SEric Christopher   if (used) {
203e1dc3c45SEric Christopher     free = 64 - used;
204e1dc3c45SEric Christopher 
205fcee6f0aSEric Christopher     if (Size < free) {
20610a12632SAlexandre Rames       memcpy(&InternalState.buffer[used], Ptr, Size);
207e1dc3c45SEric Christopher       return;
208e1dc3c45SEric Christopher     }
209e1dc3c45SEric Christopher 
21010a12632SAlexandre Rames     memcpy(&InternalState.buffer[used], Ptr, free);
211fcee6f0aSEric Christopher     Ptr = Ptr + free;
212fcee6f0aSEric Christopher     Size -= free;
21310a12632SAlexandre Rames     body(makeArrayRef(InternalState.buffer, 64));
214e1dc3c45SEric Christopher   }
215e1dc3c45SEric Christopher 
216fcee6f0aSEric Christopher   if (Size >= 64) {
217e1d12948SCraig Topper     Ptr = body(makeArrayRef(Ptr, Size & ~(unsigned long) 0x3f));
218fcee6f0aSEric Christopher     Size &= 0x3f;
219e1dc3c45SEric Christopher   }
220e1dc3c45SEric Christopher 
22110a12632SAlexandre Rames   memcpy(InternalState.buffer, Ptr, Size);
222e1dc3c45SEric Christopher }
223e1dc3c45SEric Christopher 
2241ec87e8bSEric Christopher /// Add the bytes in the StringRef \p Str to the hash.
2251ec87e8bSEric Christopher // Note that this isn't a string and so this won't include any trailing NULL
2261ec87e8bSEric Christopher // bytes.
update(StringRef Str)2271ec87e8bSEric Christopher void MD5::update(StringRef Str) {
2281ec87e8bSEric Christopher   ArrayRef<uint8_t> SVal((const uint8_t *)Str.data(), Str.size());
2291ec87e8bSEric Christopher   update(SVal);
2301ec87e8bSEric Christopher }
2311ec87e8bSEric Christopher 
2325f8f34e4SAdrian Prantl /// Finish the hash and place the resulting hash into \p result.
23312ab07e0SNAKAMURA Takumi /// \param Result is assumed to be a minimum of 16-bytes in size.
final(MD5Result & Result)234c8514a34SYaron Keren void MD5::final(MD5Result &Result) {
235e1dc3c45SEric Christopher   unsigned long used, free;
236e1dc3c45SEric Christopher 
23710a12632SAlexandre Rames   used = InternalState.lo & 0x3f;
238e1dc3c45SEric Christopher 
23910a12632SAlexandre Rames   InternalState.buffer[used++] = 0x80;
240e1dc3c45SEric Christopher 
241e1dc3c45SEric Christopher   free = 64 - used;
242e1dc3c45SEric Christopher 
243e1dc3c45SEric Christopher   if (free < 8) {
24410a12632SAlexandre Rames     memset(&InternalState.buffer[used], 0, free);
24510a12632SAlexandre Rames     body(makeArrayRef(InternalState.buffer, 64));
246e1dc3c45SEric Christopher     used = 0;
247e1dc3c45SEric Christopher     free = 64;
248e1dc3c45SEric Christopher   }
249e1dc3c45SEric Christopher 
25010a12632SAlexandre Rames   memset(&InternalState.buffer[used], 0, free - 8);
251e1dc3c45SEric Christopher 
25210a12632SAlexandre Rames   InternalState.lo <<= 3;
25310a12632SAlexandre Rames   support::endian::write32le(&InternalState.buffer[56], InternalState.lo);
25410a12632SAlexandre Rames   support::endian::write32le(&InternalState.buffer[60], InternalState.hi);
255e1dc3c45SEric Christopher 
25610a12632SAlexandre Rames   body(makeArrayRef(InternalState.buffer, 64));
257e1dc3c45SEric Christopher 
25810a12632SAlexandre Rames   support::endian::write32le(&Result[0], InternalState.a);
25910a12632SAlexandre Rames   support::endian::write32le(&Result[4], InternalState.b);
26010a12632SAlexandre Rames   support::endian::write32le(&Result[8], InternalState.c);
26110a12632SAlexandre Rames   support::endian::write32le(&Result[12], InternalState.d);
262e1dc3c45SEric Christopher }
263e1dc3c45SEric Christopher 
final()264*330268baSArgyrios Kyrtzidis MD5::MD5Result MD5::final() {
265*330268baSArgyrios Kyrtzidis   MD5Result Result;
266cd280033SAlexandre Rames   final(Result);
267*330268baSArgyrios Kyrtzidis   return Result;
268cd280033SAlexandre Rames }
269cd280033SAlexandre Rames 
result()270*330268baSArgyrios Kyrtzidis MD5::MD5Result MD5::result() {
271cd280033SAlexandre Rames   auto StateToRestore = InternalState;
272cd280033SAlexandre Rames 
273cd280033SAlexandre Rames   auto Hash = final();
274cd280033SAlexandre Rames 
275cd280033SAlexandre Rames   // Restore the state
276cd280033SAlexandre Rames   InternalState = StateToRestore;
277cd280033SAlexandre Rames 
278cd280033SAlexandre Rames   return Hash;
279cd280033SAlexandre Rames }
280cd280033SAlexandre Rames 
digest() const28182a0c97bSZachary Turner SmallString<32> MD5::MD5Result::digest() const {
28282a0c97bSZachary Turner   SmallString<32> Str;
283*330268baSArgyrios Kyrtzidis   toHex(*this, /*LowerCase*/ true, Str);
28482a0c97bSZachary Turner   return Str;
28582a0c97bSZachary Turner }
28682a0c97bSZachary Turner 
stringifyResult(MD5Result & Result,SmallVectorImpl<char> & Str)2870b48d0feSHans Wennborg void MD5::stringifyResult(MD5Result &Result, SmallVectorImpl<char> &Str) {
288*330268baSArgyrios Kyrtzidis   toHex(Result, /*LowerCase*/ true, Str);
289fcee6f0aSEric Christopher }
290fcee6f0aSEric Christopher 
hash(ArrayRef<uint8_t> Data)291*330268baSArgyrios Kyrtzidis MD5::MD5Result MD5::hash(ArrayRef<uint8_t> Data) {
292877c26c8SRui Ueyama   MD5 Hash;
293877c26c8SRui Ueyama   Hash.update(Data);
294877c26c8SRui Ueyama   MD5::MD5Result Res;
295877c26c8SRui Ueyama   Hash.final(Res);
296877c26c8SRui Ueyama 
29782a0c97bSZachary Turner   return Res;
298877c26c8SRui Ueyama }
299