LLVM API Documentation
00001 /* 00002 * This code is derived from (original license follows): 00003 * 00004 * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. 00005 * MD5 Message-Digest Algorithm (RFC 1321). 00006 * 00007 * Homepage: 00008 * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 00009 * 00010 * Author: 00011 * Alexander Peslyak, better known as Solar Designer <solar at openwall.com> 00012 * 00013 * This software was written by Alexander Peslyak in 2001. No copyright is 00014 * claimed, and the software is hereby placed in the public domain. 00015 * In case this attempt to disclaim copyright and place the software in the 00016 * public domain is deemed null and void, then the software is 00017 * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the 00018 * general public under the following terms: 00019 * 00020 * Redistribution and use in source and binary forms, with or without 00021 * modification, are permitted. 00022 * 00023 * There's ABSOLUTELY NO WARRANTY, express or implied. 00024 * 00025 * (This is a heavily cut-down "BSD license".) 00026 * 00027 * This differs from Colin Plumb's older public domain implementation in that 00028 * no exactly 32-bit integer data type is required (any 32-bit or wider 00029 * unsigned integer data type will do), there's no compile-time endianness 00030 * configuration, and the function prototypes match OpenSSL's. No code from 00031 * Colin Plumb's implementation has been reused; this comment merely compares 00032 * the properties of the two independent implementations. 00033 * 00034 * The primary goals of this implementation are portability and ease of use. 00035 * It is meant to be fast, but not as fast as possible. Some known 00036 * optimizations are not included to reduce source code size and avoid 00037 * compile-time configuration. 00038 */ 00039 00040 #include "llvm/ADT/ArrayRef.h" 00041 #include "llvm/Support/Format.h" 00042 #include "llvm/Support/MD5.h" 00043 #include "llvm/Support/raw_ostream.h" 00044 #include <cstring> 00045 00046 // The basic MD5 functions. 00047 00048 // F and G are optimized compared to their RFC 1321 definitions for 00049 // architectures that lack an AND-NOT instruction, just like in Colin Plumb's 00050 // implementation. 00051 #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) 00052 #define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) 00053 #define H(x, y, z) ((x) ^ (y) ^ (z)) 00054 #define I(x, y, z) ((y) ^ ((x) | ~(z))) 00055 00056 // The MD5 transformation for all four rounds. 00057 #define STEP(f, a, b, c, d, x, t, s) \ 00058 (a) += f((b), (c), (d)) + (x) + (t); \ 00059 (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ 00060 (a) += (b); 00061 00062 // SET reads 4 input bytes in little-endian byte order and stores them 00063 // in a properly aligned word in host byte order. 00064 #define SET(n) \ 00065 (block[(n)] = \ 00066 (MD5_u32plus) ptr[(n) * 4] | ((MD5_u32plus) ptr[(n) * 4 + 1] << 8) | \ 00067 ((MD5_u32plus) ptr[(n) * 4 + 2] << 16) | \ 00068 ((MD5_u32plus) ptr[(n) * 4 + 3] << 24)) 00069 #define GET(n) (block[(n)]) 00070 00071 namespace llvm { 00072 00073 /// \brief This processes one or more 64-byte data blocks, but does NOT update 00074 ///the bit counters. There are no alignment requirements. 00075 const uint8_t *MD5::body(ArrayRef<uint8_t> Data) { 00076 const uint8_t *ptr; 00077 MD5_u32plus a, b, c, d; 00078 MD5_u32plus saved_a, saved_b, saved_c, saved_d; 00079 unsigned long Size = Data.size(); 00080 00081 ptr = Data.data(); 00082 00083 a = this->a; 00084 b = this->b; 00085 c = this->c; 00086 d = this->d; 00087 00088 do { 00089 saved_a = a; 00090 saved_b = b; 00091 saved_c = c; 00092 saved_d = d; 00093 00094 // Round 1 00095 STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7) 00096 STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12) 00097 STEP(F, c, d, a, b, SET(2), 0x242070db, 17) 00098 STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22) 00099 STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7) 00100 STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12) 00101 STEP(F, c, d, a, b, SET(6), 0xa8304613, 17) 00102 STEP(F, b, c, d, a, SET(7), 0xfd469501, 22) 00103 STEP(F, a, b, c, d, SET(8), 0x698098d8, 7) 00104 STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12) 00105 STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17) 00106 STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22) 00107 STEP(F, a, b, c, d, SET(12), 0x6b901122, 7) 00108 STEP(F, d, a, b, c, SET(13), 0xfd987193, 12) 00109 STEP(F, c, d, a, b, SET(14), 0xa679438e, 17) 00110 STEP(F, b, c, d, a, SET(15), 0x49b40821, 22) 00111 00112 // Round 2 00113 STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5) 00114 STEP(G, d, a, b, c, GET(6), 0xc040b340, 9) 00115 STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14) 00116 STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20) 00117 STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5) 00118 STEP(G, d, a, b, c, GET(10), 0x02441453, 9) 00119 STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14) 00120 STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20) 00121 STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5) 00122 STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9) 00123 STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14) 00124 STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20) 00125 STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5) 00126 STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9) 00127 STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14) 00128 STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20) 00129 00130 // Round 3 00131 STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4) 00132 STEP(H, d, a, b, c, GET(8), 0x8771f681, 11) 00133 STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16) 00134 STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23) 00135 STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4) 00136 STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11) 00137 STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16) 00138 STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23) 00139 STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4) 00140 STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11) 00141 STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16) 00142 STEP(H, b, c, d, a, GET(6), 0x04881d05, 23) 00143 STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4) 00144 STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11) 00145 STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16) 00146 STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23) 00147 00148 // Round 4 00149 STEP(I, a, b, c, d, GET(0), 0xf4292244, 6) 00150 STEP(I, d, a, b, c, GET(7), 0x432aff97, 10) 00151 STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15) 00152 STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21) 00153 STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6) 00154 STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10) 00155 STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15) 00156 STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21) 00157 STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6) 00158 STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10) 00159 STEP(I, c, d, a, b, GET(6), 0xa3014314, 15) 00160 STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21) 00161 STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6) 00162 STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10) 00163 STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15) 00164 STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21) 00165 00166 a += saved_a; 00167 b += saved_b; 00168 c += saved_c; 00169 d += saved_d; 00170 00171 ptr += 64; 00172 } while (Size -= 64); 00173 00174 this->a = a; 00175 this->b = b; 00176 this->c = c; 00177 this->d = d; 00178 00179 return ptr; 00180 } 00181 00182 MD5::MD5() 00183 : a(0x67452301), b(0xefcdab89), c(0x98badcfe), d(0x10325476), hi(0), lo(0) { 00184 } 00185 00186 /// Incrementally add the bytes in \p Data to the hash. 00187 void MD5::update(ArrayRef<uint8_t> Data) { 00188 MD5_u32plus saved_lo; 00189 unsigned long used, free; 00190 const uint8_t *Ptr = Data.data(); 00191 unsigned long Size = Data.size(); 00192 00193 saved_lo = lo; 00194 if ((lo = (saved_lo + Size) & 0x1fffffff) < saved_lo) 00195 hi++; 00196 hi += Size >> 29; 00197 00198 used = saved_lo & 0x3f; 00199 00200 if (used) { 00201 free = 64 - used; 00202 00203 if (Size < free) { 00204 memcpy(&buffer[used], Ptr, Size); 00205 return; 00206 } 00207 00208 memcpy(&buffer[used], Ptr, free); 00209 Ptr = Ptr + free; 00210 Size -= free; 00211 body(makeArrayRef(buffer, 64)); 00212 } 00213 00214 if (Size >= 64) { 00215 Ptr = body(makeArrayRef(Ptr, Size & ~(unsigned long) 0x3f)); 00216 Size &= 0x3f; 00217 } 00218 00219 memcpy(buffer, Ptr, Size); 00220 } 00221 00222 /// Add the bytes in the StringRef \p Str to the hash. 00223 // Note that this isn't a string and so this won't include any trailing NULL 00224 // bytes. 00225 void MD5::update(StringRef Str) { 00226 ArrayRef<uint8_t> SVal((const uint8_t *)Str.data(), Str.size()); 00227 update(SVal); 00228 } 00229 00230 /// \brief Finish the hash and place the resulting hash into \p result. 00231 /// \param result is assumed to be a minimum of 16-bytes in size. 00232 void MD5::final(MD5Result &result) { 00233 unsigned long used, free; 00234 00235 used = lo & 0x3f; 00236 00237 buffer[used++] = 0x80; 00238 00239 free = 64 - used; 00240 00241 if (free < 8) { 00242 memset(&buffer[used], 0, free); 00243 body(makeArrayRef(buffer, 64)); 00244 used = 0; 00245 free = 64; 00246 } 00247 00248 memset(&buffer[used], 0, free - 8); 00249 00250 lo <<= 3; 00251 buffer[56] = lo; 00252 buffer[57] = lo >> 8; 00253 buffer[58] = lo >> 16; 00254 buffer[59] = lo >> 24; 00255 buffer[60] = hi; 00256 buffer[61] = hi >> 8; 00257 buffer[62] = hi >> 16; 00258 buffer[63] = hi >> 24; 00259 00260 body(makeArrayRef(buffer, 64)); 00261 00262 result[0] = a; 00263 result[1] = a >> 8; 00264 result[2] = a >> 16; 00265 result[3] = a >> 24; 00266 result[4] = b; 00267 result[5] = b >> 8; 00268 result[6] = b >> 16; 00269 result[7] = b >> 24; 00270 result[8] = c; 00271 result[9] = c >> 8; 00272 result[10] = c >> 16; 00273 result[11] = c >> 24; 00274 result[12] = d; 00275 result[13] = d >> 8; 00276 result[14] = d >> 16; 00277 result[15] = d >> 24; 00278 } 00279 00280 void MD5::stringifyResult(MD5Result &result, SmallString<32> &Str) { 00281 raw_svector_ostream Res(Str); 00282 for (int i = 0; i < 16; ++i) 00283 Res << format("%.2x", result[i]); 00284 } 00285 00286 }