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