1258945Sroberto/* 2280849Scy * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC") 3258945Sroberto * Copyright (C) 2000, 2001 Internet Software Consortium. 4258945Sroberto * 5258945Sroberto * Permission to use, copy, modify, and/or distribute this software for any 6258945Sroberto * purpose with or without fee is hereby granted, provided that the above 7258945Sroberto * copyright notice and this permission notice appear in all copies. 8258945Sroberto * 9258945Sroberto * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10258945Sroberto * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11258945Sroberto * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12258945Sroberto * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13258945Sroberto * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14258945Sroberto * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15258945Sroberto * PERFORMANCE OF THIS SOFTWARE. 16258945Sroberto */ 17258945Sroberto 18280849Scy/* $Id: md5.c,v 1.16 2009/02/06 23:47:42 tbox Exp $ */ 19258945Sroberto 20258945Sroberto/*! \file 21258945Sroberto * This code implements the MD5 message-digest algorithm. 22258945Sroberto * The algorithm is due to Ron Rivest. This code was 23258945Sroberto * written by Colin Plumb in 1993, no copyright is claimed. 24258945Sroberto * This code is in the public domain; do with it what you wish. 25258945Sroberto * 26258945Sroberto * Equivalent code is available from RSA Data Security, Inc. 27258945Sroberto * This code has been tested against that, and is equivalent, 28258945Sroberto * except that you don't need to include two pages of legalese 29258945Sroberto * with every copy. 30258945Sroberto * 31258945Sroberto * To compute the message digest of a chunk of bytes, declare an 32258945Sroberto * MD5Context structure, pass it to MD5Init, call MD5Update as 33258945Sroberto * needed on buffers full of bytes, and then call MD5Final, which 34258945Sroberto * will fill a supplied 16-byte array with the digest. 35258945Sroberto */ 36258945Sroberto 37258945Sroberto#include "config.h" 38258945Sroberto 39258945Sroberto#include <isc/assertions.h> 40258945Sroberto#include <isc/md5.h> 41280849Scy#include <isc/platform.h> 42258945Sroberto#include <isc/string.h> 43258945Sroberto#include <isc/types.h> 44258945Sroberto#include <isc/util.h> 45258945Sroberto 46280849Scy#ifdef ISC_PLATFORM_OPENSSLHASH 47280849Scy 48280849Scyvoid 49280849Scyisc_md5_init(isc_md5_t *ctx) { 50280849Scy EVP_DigestInit(ctx, EVP_md5()); 51280849Scy} 52280849Scy 53280849Scyvoid 54280849Scyisc_md5_invalidate(isc_md5_t *ctx) { 55280849Scy EVP_MD_CTX_cleanup(ctx); 56280849Scy} 57280849Scy 58280849Scyvoid 59280849Scyisc_md5_update(isc_md5_t *ctx, const unsigned char *buf, unsigned int len) { 60280849Scy EVP_DigestUpdate(ctx, (const void *) buf, (size_t) len); 61280849Scy} 62280849Scy 63280849Scyvoid 64280849Scyisc_md5_final(isc_md5_t *ctx, unsigned char *digest) { 65280849Scy EVP_DigestFinal(ctx, digest, NULL); 66280849Scy} 67280849Scy 68280849Scy#else 69280849Scy 70258945Srobertostatic void 71258945SrobertobyteSwap(isc_uint32_t *buf, unsigned words) 72258945Sroberto{ 73258945Sroberto unsigned char *p = (unsigned char *)buf; 74258945Sroberto 75258945Sroberto do { 76258945Sroberto *buf++ = (isc_uint32_t)((unsigned)p[3] << 8 | p[2]) << 16 | 77258945Sroberto ((unsigned)p[1] << 8 | p[0]); 78258945Sroberto p += 4; 79258945Sroberto } while (--words); 80258945Sroberto} 81258945Sroberto 82258945Sroberto/*! 83258945Sroberto * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious 84258945Sroberto * initialization constants. 85258945Sroberto */ 86258945Srobertovoid 87258945Srobertoisc_md5_init(isc_md5_t *ctx) { 88258945Sroberto ctx->buf[0] = 0x67452301; 89258945Sroberto ctx->buf[1] = 0xefcdab89; 90258945Sroberto ctx->buf[2] = 0x98badcfe; 91258945Sroberto ctx->buf[3] = 0x10325476; 92258945Sroberto 93258945Sroberto ctx->bytes[0] = 0; 94258945Sroberto ctx->bytes[1] = 0; 95258945Sroberto} 96258945Sroberto 97258945Srobertovoid 98258945Srobertoisc_md5_invalidate(isc_md5_t *ctx) { 99258945Sroberto memset(ctx, 0, sizeof(isc_md5_t)); 100258945Sroberto} 101258945Sroberto 102258945Sroberto/*@{*/ 103258945Sroberto/*! The four core functions - F1 is optimized somewhat */ 104258945Sroberto 105258945Sroberto/* #define F1(x, y, z) (x & y | ~x & z) */ 106258945Sroberto#define F1(x, y, z) (z ^ (x & (y ^ z))) 107258945Sroberto#define F2(x, y, z) F1(z, x, y) 108258945Sroberto#define F3(x, y, z) (x ^ y ^ z) 109258945Sroberto#define F4(x, y, z) (y ^ (x | ~z)) 110258945Sroberto/*@}*/ 111258945Sroberto 112258945Sroberto/*! This is the central step in the MD5 algorithm. */ 113258945Sroberto#define MD5STEP(f,w,x,y,z,in,s) \ 114258945Sroberto (w += f(x,y,z) + in, w = (w<<s | w>>(32-s)) + x) 115258945Sroberto 116258945Sroberto/*! 117258945Sroberto * The core of the MD5 algorithm, this alters an existing MD5 hash to 118258945Sroberto * reflect the addition of 16 longwords of new data. MD5Update blocks 119258945Sroberto * the data and converts bytes into longwords for this routine. 120258945Sroberto */ 121258945Srobertostatic void 122258945Srobertotransform(isc_uint32_t buf[4], isc_uint32_t const in[16]) { 123258945Sroberto register isc_uint32_t a, b, c, d; 124258945Sroberto 125258945Sroberto a = buf[0]; 126258945Sroberto b = buf[1]; 127258945Sroberto c = buf[2]; 128258945Sroberto d = buf[3]; 129258945Sroberto 130258945Sroberto MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); 131258945Sroberto MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); 132258945Sroberto MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); 133258945Sroberto MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); 134258945Sroberto MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); 135258945Sroberto MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); 136258945Sroberto MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); 137258945Sroberto MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); 138258945Sroberto MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); 139258945Sroberto MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); 140258945Sroberto MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); 141258945Sroberto MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); 142258945Sroberto MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); 143258945Sroberto MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); 144258945Sroberto MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); 145258945Sroberto MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); 146258945Sroberto 147258945Sroberto MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); 148258945Sroberto MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); 149258945Sroberto MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); 150258945Sroberto MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); 151258945Sroberto MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); 152258945Sroberto MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); 153258945Sroberto MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); 154258945Sroberto MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); 155258945Sroberto MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); 156258945Sroberto MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); 157258945Sroberto MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); 158258945Sroberto MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); 159258945Sroberto MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); 160258945Sroberto MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); 161258945Sroberto MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); 162258945Sroberto MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); 163258945Sroberto 164258945Sroberto MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); 165258945Sroberto MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); 166258945Sroberto MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); 167258945Sroberto MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); 168258945Sroberto MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); 169258945Sroberto MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); 170258945Sroberto MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); 171258945Sroberto MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); 172258945Sroberto MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); 173258945Sroberto MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); 174258945Sroberto MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); 175258945Sroberto MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); 176258945Sroberto MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); 177258945Sroberto MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); 178258945Sroberto MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); 179258945Sroberto MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); 180258945Sroberto 181258945Sroberto MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); 182258945Sroberto MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); 183258945Sroberto MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); 184258945Sroberto MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); 185258945Sroberto MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); 186258945Sroberto MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); 187258945Sroberto MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); 188258945Sroberto MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); 189258945Sroberto MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); 190258945Sroberto MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); 191258945Sroberto MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); 192258945Sroberto MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); 193258945Sroberto MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); 194258945Sroberto MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); 195258945Sroberto MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); 196258945Sroberto MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); 197258945Sroberto 198258945Sroberto buf[0] += a; 199258945Sroberto buf[1] += b; 200258945Sroberto buf[2] += c; 201258945Sroberto buf[3] += d; 202258945Sroberto} 203258945Sroberto 204258945Sroberto/*! 205258945Sroberto * Update context to reflect the concatenation of another buffer full 206258945Sroberto * of bytes. 207258945Sroberto */ 208258945Srobertovoid 209258945Srobertoisc_md5_update(isc_md5_t *ctx, const unsigned char *buf, unsigned int len) { 210258945Sroberto isc_uint32_t t; 211258945Sroberto 212258945Sroberto /* Update byte count */ 213258945Sroberto 214258945Sroberto t = ctx->bytes[0]; 215258945Sroberto if ((ctx->bytes[0] = t + len) < t) 216258945Sroberto ctx->bytes[1]++; /* Carry from low to high */ 217258945Sroberto 218258945Sroberto t = 64 - (t & 0x3f); /* Space available in ctx->in (at least 1) */ 219258945Sroberto if (t > len) { 220258945Sroberto memcpy((unsigned char *)ctx->in + 64 - t, buf, len); 221258945Sroberto return; 222258945Sroberto } 223258945Sroberto /* First chunk is an odd size */ 224258945Sroberto memcpy((unsigned char *)ctx->in + 64 - t, buf, t); 225258945Sroberto byteSwap(ctx->in, 16); 226258945Sroberto transform(ctx->buf, ctx->in); 227258945Sroberto buf += t; 228258945Sroberto len -= t; 229258945Sroberto 230258945Sroberto /* Process data in 64-byte chunks */ 231258945Sroberto while (len >= 64) { 232258945Sroberto memcpy(ctx->in, buf, 64); 233258945Sroberto byteSwap(ctx->in, 16); 234258945Sroberto transform(ctx->buf, ctx->in); 235258945Sroberto buf += 64; 236258945Sroberto len -= 64; 237258945Sroberto } 238258945Sroberto 239258945Sroberto /* Handle any remaining bytes of data. */ 240258945Sroberto memcpy(ctx->in, buf, len); 241258945Sroberto} 242258945Sroberto 243258945Sroberto/*! 244258945Sroberto * Final wrapup - pad to 64-byte boundary with the bit pattern 245258945Sroberto * 1 0* (64-bit count of bits processed, MSB-first) 246258945Sroberto */ 247258945Srobertovoid 248258945Srobertoisc_md5_final(isc_md5_t *ctx, unsigned char *digest) { 249258945Sroberto int count = ctx->bytes[0] & 0x3f; /* Number of bytes in ctx->in */ 250258945Sroberto unsigned char *p = (unsigned char *)ctx->in + count; 251258945Sroberto 252258945Sroberto /* Set the first char of padding to 0x80. There is always room. */ 253258945Sroberto *p++ = 0x80; 254258945Sroberto 255258945Sroberto /* Bytes of padding needed to make 56 bytes (-8..55) */ 256258945Sroberto count = 56 - 1 - count; 257258945Sroberto 258258945Sroberto if (count < 0) { /* Padding forces an extra block */ 259258945Sroberto memset(p, 0, count + 8); 260258945Sroberto byteSwap(ctx->in, 16); 261258945Sroberto transform(ctx->buf, ctx->in); 262258945Sroberto p = (unsigned char *)ctx->in; 263258945Sroberto count = 56; 264258945Sroberto } 265258945Sroberto memset(p, 0, count); 266258945Sroberto byteSwap(ctx->in, 14); 267258945Sroberto 268258945Sroberto /* Append length in bits and transform */ 269258945Sroberto ctx->in[14] = ctx->bytes[0] << 3; 270258945Sroberto ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29; 271258945Sroberto transform(ctx->buf, ctx->in); 272258945Sroberto 273258945Sroberto byteSwap(ctx->buf, 4); 274258945Sroberto memcpy(digest, ctx->buf, 16); 275258945Sroberto memset(ctx, 0, sizeof(isc_md5_t)); /* In case it's sensitive */ 276258945Sroberto} 277280849Scy#endif 278