1285031Sdes/* $OpenBSD: md5.c,v 1.9 2014/01/08 06:14:57 tedu Exp $ */ 2285031Sdes 3285031Sdes/* 4285031Sdes * This code implements the MD5 message-digest algorithm. 5285031Sdes * The algorithm is due to Ron Rivest. This code was 6285031Sdes * written by Colin Plumb in 1993, no copyright is claimed. 7285031Sdes * This code is in the public domain; do with it what you wish. 8285031Sdes * 9285031Sdes * Equivalent code is available from RSA Data Security, Inc. 10285031Sdes * This code has been tested against that, and is equivalent, 11285031Sdes * except that you don't need to include two pages of legalese 12285031Sdes * with every copy. 13285031Sdes * 14285031Sdes * To compute the message digest of a chunk of bytes, declare an 15285031Sdes * MD5Context structure, pass it to MD5Init, call MD5Update as 16285031Sdes * needed on buffers full of bytes, and then call MD5Final, which 17285031Sdes * will fill a supplied 16-byte array with the digest. 18285031Sdes */ 19285031Sdes 20285031Sdes#include "includes.h" 21285031Sdes 22285031Sdes#ifndef WITH_OPENSSL 23285031Sdes 24285031Sdes#include <sys/types.h> 25285031Sdes#include <string.h> 26285031Sdes#include "md5.h" 27285031Sdes 28285031Sdes#define PUT_64BIT_LE(cp, value) do { \ 29285031Sdes (cp)[7] = (value) >> 56; \ 30285031Sdes (cp)[6] = (value) >> 48; \ 31285031Sdes (cp)[5] = (value) >> 40; \ 32285031Sdes (cp)[4] = (value) >> 32; \ 33285031Sdes (cp)[3] = (value) >> 24; \ 34285031Sdes (cp)[2] = (value) >> 16; \ 35285031Sdes (cp)[1] = (value) >> 8; \ 36285031Sdes (cp)[0] = (value); } while (0) 37285031Sdes 38285031Sdes#define PUT_32BIT_LE(cp, value) do { \ 39285031Sdes (cp)[3] = (value) >> 24; \ 40285031Sdes (cp)[2] = (value) >> 16; \ 41285031Sdes (cp)[1] = (value) >> 8; \ 42285031Sdes (cp)[0] = (value); } while (0) 43285031Sdes 44285031Sdesstatic u_int8_t PADDING[MD5_BLOCK_LENGTH] = { 45285031Sdes 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46285031Sdes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47285031Sdes 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 48285031Sdes}; 49285031Sdes 50285031Sdes/* 51285031Sdes * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious 52285031Sdes * initialization constants. 53285031Sdes */ 54285031Sdesvoid 55285031SdesMD5Init(MD5_CTX *ctx) 56285031Sdes{ 57285031Sdes ctx->count = 0; 58285031Sdes ctx->state[0] = 0x67452301; 59285031Sdes ctx->state[1] = 0xefcdab89; 60285031Sdes ctx->state[2] = 0x98badcfe; 61285031Sdes ctx->state[3] = 0x10325476; 62285031Sdes} 63285031Sdes 64285031Sdes/* 65285031Sdes * Update context to reflect the concatenation of another buffer full 66285031Sdes * of bytes. 67285031Sdes */ 68285031Sdesvoid 69285031SdesMD5Update(MD5_CTX *ctx, const unsigned char *input, size_t len) 70285031Sdes{ 71285031Sdes size_t have, need; 72285031Sdes 73285031Sdes /* Check how many bytes we already have and how many more we need. */ 74285031Sdes have = (size_t)((ctx->count >> 3) & (MD5_BLOCK_LENGTH - 1)); 75285031Sdes need = MD5_BLOCK_LENGTH - have; 76285031Sdes 77285031Sdes /* Update bitcount */ 78285031Sdes ctx->count += (u_int64_t)len << 3; 79285031Sdes 80285031Sdes if (len >= need) { 81285031Sdes if (have != 0) { 82285031Sdes memcpy(ctx->buffer + have, input, need); 83285031Sdes MD5Transform(ctx->state, ctx->buffer); 84285031Sdes input += need; 85285031Sdes len -= need; 86285031Sdes have = 0; 87285031Sdes } 88285031Sdes 89285031Sdes /* Process data in MD5_BLOCK_LENGTH-byte chunks. */ 90285031Sdes while (len >= MD5_BLOCK_LENGTH) { 91285031Sdes MD5Transform(ctx->state, input); 92285031Sdes input += MD5_BLOCK_LENGTH; 93285031Sdes len -= MD5_BLOCK_LENGTH; 94285031Sdes } 95285031Sdes } 96285031Sdes 97285031Sdes /* Handle any remaining bytes of data. */ 98285031Sdes if (len != 0) 99285031Sdes memcpy(ctx->buffer + have, input, len); 100285031Sdes} 101285031Sdes 102285031Sdes/* 103285031Sdes * Pad pad to 64-byte boundary with the bit pattern 104285031Sdes * 1 0* (64-bit count of bits processed, MSB-first) 105285031Sdes */ 106285031Sdesvoid 107285031SdesMD5Pad(MD5_CTX *ctx) 108285031Sdes{ 109285031Sdes u_int8_t count[8]; 110285031Sdes size_t padlen; 111285031Sdes 112285031Sdes /* Convert count to 8 bytes in little endian order. */ 113285031Sdes PUT_64BIT_LE(count, ctx->count); 114285031Sdes 115285031Sdes /* Pad out to 56 mod 64. */ 116285031Sdes padlen = MD5_BLOCK_LENGTH - 117285031Sdes ((ctx->count >> 3) & (MD5_BLOCK_LENGTH - 1)); 118285031Sdes if (padlen < 1 + 8) 119285031Sdes padlen += MD5_BLOCK_LENGTH; 120285031Sdes MD5Update(ctx, PADDING, padlen - 8); /* padlen - 8 <= 64 */ 121285031Sdes MD5Update(ctx, count, 8); 122285031Sdes} 123285031Sdes 124285031Sdes/* 125285031Sdes * Final wrapup--call MD5Pad, fill in digest and zero out ctx. 126285031Sdes */ 127285031Sdesvoid 128285031SdesMD5Final(unsigned char digest[MD5_DIGEST_LENGTH], MD5_CTX *ctx) 129285031Sdes{ 130285031Sdes int i; 131285031Sdes 132285031Sdes MD5Pad(ctx); 133285031Sdes for (i = 0; i < 4; i++) 134285031Sdes PUT_32BIT_LE(digest + i * 4, ctx->state[i]); 135285031Sdes memset(ctx, 0, sizeof(*ctx)); 136285031Sdes} 137285031Sdes 138285031Sdes 139285031Sdes/* The four core functions - F1 is optimized somewhat */ 140285031Sdes 141285031Sdes/* #define F1(x, y, z) (x & y | ~x & z) */ 142285031Sdes#define F1(x, y, z) (z ^ (x & (y ^ z))) 143285031Sdes#define F2(x, y, z) F1(z, x, y) 144285031Sdes#define F3(x, y, z) (x ^ y ^ z) 145285031Sdes#define F4(x, y, z) (y ^ (x | ~z)) 146285031Sdes 147285031Sdes/* This is the central step in the MD5 algorithm. */ 148285031Sdes#define MD5STEP(f, w, x, y, z, data, s) \ 149285031Sdes ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x ) 150285031Sdes 151285031Sdes/* 152285031Sdes * The core of the MD5 algorithm, this alters an existing MD5 hash to 153285031Sdes * reflect the addition of 16 longwords of new data. MD5Update blocks 154285031Sdes * the data and converts bytes into longwords for this routine. 155285031Sdes */ 156285031Sdesvoid 157285031SdesMD5Transform(u_int32_t state[4], const u_int8_t block[MD5_BLOCK_LENGTH]) 158285031Sdes{ 159285031Sdes u_int32_t a, b, c, d, in[MD5_BLOCK_LENGTH / 4]; 160285031Sdes 161285031Sdes#if BYTE_ORDER == LITTLE_ENDIAN 162285031Sdes memcpy(in, block, sizeof(in)); 163285031Sdes#else 164285031Sdes for (a = 0; a < MD5_BLOCK_LENGTH / 4; a++) { 165285031Sdes in[a] = (u_int32_t)( 166285031Sdes (u_int32_t)(block[a * 4 + 0]) | 167285031Sdes (u_int32_t)(block[a * 4 + 1]) << 8 | 168285031Sdes (u_int32_t)(block[a * 4 + 2]) << 16 | 169285031Sdes (u_int32_t)(block[a * 4 + 3]) << 24); 170285031Sdes } 171285031Sdes#endif 172285031Sdes 173285031Sdes a = state[0]; 174285031Sdes b = state[1]; 175285031Sdes c = state[2]; 176285031Sdes d = state[3]; 177285031Sdes 178285031Sdes MD5STEP(F1, a, b, c, d, in[ 0] + 0xd76aa478, 7); 179285031Sdes MD5STEP(F1, d, a, b, c, in[ 1] + 0xe8c7b756, 12); 180285031Sdes MD5STEP(F1, c, d, a, b, in[ 2] + 0x242070db, 17); 181285031Sdes MD5STEP(F1, b, c, d, a, in[ 3] + 0xc1bdceee, 22); 182285031Sdes MD5STEP(F1, a, b, c, d, in[ 4] + 0xf57c0faf, 7); 183285031Sdes MD5STEP(F1, d, a, b, c, in[ 5] + 0x4787c62a, 12); 184285031Sdes MD5STEP(F1, c, d, a, b, in[ 6] + 0xa8304613, 17); 185285031Sdes MD5STEP(F1, b, c, d, a, in[ 7] + 0xfd469501, 22); 186285031Sdes MD5STEP(F1, a, b, c, d, in[ 8] + 0x698098d8, 7); 187285031Sdes MD5STEP(F1, d, a, b, c, in[ 9] + 0x8b44f7af, 12); 188285031Sdes MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); 189285031Sdes MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); 190285031Sdes MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); 191285031Sdes MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); 192285031Sdes MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); 193285031Sdes MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); 194285031Sdes 195285031Sdes MD5STEP(F2, a, b, c, d, in[ 1] + 0xf61e2562, 5); 196285031Sdes MD5STEP(F2, d, a, b, c, in[ 6] + 0xc040b340, 9); 197285031Sdes MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); 198285031Sdes MD5STEP(F2, b, c, d, a, in[ 0] + 0xe9b6c7aa, 20); 199285031Sdes MD5STEP(F2, a, b, c, d, in[ 5] + 0xd62f105d, 5); 200285031Sdes MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); 201285031Sdes MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); 202285031Sdes MD5STEP(F2, b, c, d, a, in[ 4] + 0xe7d3fbc8, 20); 203285031Sdes MD5STEP(F2, a, b, c, d, in[ 9] + 0x21e1cde6, 5); 204285031Sdes MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); 205285031Sdes MD5STEP(F2, c, d, a, b, in[ 3] + 0xf4d50d87, 14); 206285031Sdes MD5STEP(F2, b, c, d, a, in[ 8] + 0x455a14ed, 20); 207285031Sdes MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); 208285031Sdes MD5STEP(F2, d, a, b, c, in[ 2] + 0xfcefa3f8, 9); 209285031Sdes MD5STEP(F2, c, d, a, b, in[ 7] + 0x676f02d9, 14); 210285031Sdes MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); 211285031Sdes 212285031Sdes MD5STEP(F3, a, b, c, d, in[ 5] + 0xfffa3942, 4); 213285031Sdes MD5STEP(F3, d, a, b, c, in[ 8] + 0x8771f681, 11); 214285031Sdes MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); 215285031Sdes MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); 216285031Sdes MD5STEP(F3, a, b, c, d, in[ 1] + 0xa4beea44, 4); 217285031Sdes MD5STEP(F3, d, a, b, c, in[ 4] + 0x4bdecfa9, 11); 218285031Sdes MD5STEP(F3, c, d, a, b, in[ 7] + 0xf6bb4b60, 16); 219285031Sdes MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); 220285031Sdes MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); 221285031Sdes MD5STEP(F3, d, a, b, c, in[ 0] + 0xeaa127fa, 11); 222285031Sdes MD5STEP(F3, c, d, a, b, in[ 3] + 0xd4ef3085, 16); 223285031Sdes MD5STEP(F3, b, c, d, a, in[ 6] + 0x04881d05, 23); 224285031Sdes MD5STEP(F3, a, b, c, d, in[ 9] + 0xd9d4d039, 4); 225285031Sdes MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); 226285031Sdes MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); 227285031Sdes MD5STEP(F3, b, c, d, a, in[2 ] + 0xc4ac5665, 23); 228285031Sdes 229285031Sdes MD5STEP(F4, a, b, c, d, in[ 0] + 0xf4292244, 6); 230285031Sdes MD5STEP(F4, d, a, b, c, in[7 ] + 0x432aff97, 10); 231285031Sdes MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); 232285031Sdes MD5STEP(F4, b, c, d, a, in[5 ] + 0xfc93a039, 21); 233285031Sdes MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); 234285031Sdes MD5STEP(F4, d, a, b, c, in[3 ] + 0x8f0ccc92, 10); 235285031Sdes MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); 236285031Sdes MD5STEP(F4, b, c, d, a, in[1 ] + 0x85845dd1, 21); 237285031Sdes MD5STEP(F4, a, b, c, d, in[8 ] + 0x6fa87e4f, 6); 238285031Sdes MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); 239285031Sdes MD5STEP(F4, c, d, a, b, in[6 ] + 0xa3014314, 15); 240285031Sdes MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); 241285031Sdes MD5STEP(F4, a, b, c, d, in[4 ] + 0xf7537e82, 6); 242285031Sdes MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); 243285031Sdes MD5STEP(F4, c, d, a, b, in[2 ] + 0x2ad7d2bb, 15); 244285031Sdes MD5STEP(F4, b, c, d, a, in[9 ] + 0xeb86d391, 21); 245285031Sdes 246285031Sdes state[0] += a; 247285031Sdes state[1] += b; 248285031Sdes state[2] += c; 249285031Sdes state[3] += d; 250285031Sdes} 251285031Sdes#endif /* !WITH_OPENSSL */ 252