Home | History | Annotate | Line # | Download | only in isc
      1  1.1  christos /*	$NetBSD: md5.c,v 1.2 2024/08/18 20:47:14 christos Exp $	*/
      2  1.1  christos 
      3  1.1  christos /*
      4  1.1  christos  * Copyright (C) 2004, 2005, 2007, 2009  Internet Systems Consortium, Inc. ("ISC")
      5  1.1  christos  * Copyright (C) 2000, 2001  Internet Software Consortium.
      6  1.1  christos  *
      7  1.1  christos  * Permission to use, copy, modify, and/or distribute this software for any
      8  1.1  christos  * purpose with or without fee is hereby granted, provided that the above
      9  1.1  christos  * copyright notice and this permission notice appear in all copies.
     10  1.1  christos  *
     11  1.1  christos  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
     12  1.1  christos  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
     13  1.1  christos  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
     14  1.1  christos  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
     15  1.1  christos  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
     16  1.1  christos  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
     17  1.1  christos  * PERFORMANCE OF THIS SOFTWARE.
     18  1.1  christos  */
     19  1.1  christos 
     20  1.1  christos /* Id: md5.c,v 1.16 2009/02/06 23:47:42 tbox Exp  */
     21  1.1  christos 
     22  1.1  christos /*! \file
     23  1.1  christos  * This code implements the MD5 message-digest algorithm.
     24  1.1  christos  * The algorithm is due to Ron Rivest.  This code was
     25  1.1  christos  * written by Colin Plumb in 1993, no copyright is claimed.
     26  1.1  christos  * This code is in the public domain; do with it what you wish.
     27  1.1  christos  *
     28  1.1  christos  * Equivalent code is available from RSA Data Security, Inc.
     29  1.1  christos  * This code has been tested against that, and is equivalent,
     30  1.1  christos  * except that you don't need to include two pages of legalese
     31  1.1  christos  * with every copy.
     32  1.1  christos  *
     33  1.1  christos  * To compute the message digest of a chunk of bytes, declare an
     34  1.1  christos  * MD5Context structure, pass it to MD5Init, call MD5Update as
     35  1.1  christos  * needed on buffers full of bytes, and then call MD5Final, which
     36  1.1  christos  * will fill a supplied 16-byte array with the digest.
     37  1.1  christos  */
     38  1.1  christos 
     39  1.1  christos #include "config.h"
     40  1.1  christos 
     41  1.1  christos #include <isc/assertions.h>
     42  1.1  christos #include <isc/md5.h>
     43  1.1  christos #include <isc/platform.h>
     44  1.1  christos #include <isc/string.h>
     45  1.1  christos #include <isc/types.h>
     46  1.1  christos #include <isc/util.h>
     47  1.1  christos 
     48  1.1  christos #ifdef ISC_PLATFORM_OPENSSLHASH
     49  1.1  christos 
     50  1.1  christos void
     51  1.1  christos isc_md5_init(isc_md5_t *ctx) {
     52  1.1  christos 	EVP_DigestInit(ctx, EVP_md5());
     53  1.1  christos }
     54  1.1  christos 
     55  1.1  christos void
     56  1.1  christos isc_md5_invalidate(isc_md5_t *ctx) {
     57  1.1  christos 	EVP_MD_CTX_cleanup(ctx);
     58  1.1  christos }
     59  1.1  christos 
     60  1.1  christos void
     61  1.1  christos isc_md5_update(isc_md5_t *ctx, const unsigned char *buf, unsigned int len) {
     62  1.1  christos 	EVP_DigestUpdate(ctx, (const void *) buf, (size_t) len);
     63  1.1  christos }
     64  1.1  christos 
     65  1.1  christos void
     66  1.1  christos isc_md5_final(isc_md5_t *ctx, unsigned char *digest) {
     67  1.1  christos 	EVP_DigestFinal(ctx, digest, NULL);
     68  1.1  christos }
     69  1.1  christos 
     70  1.1  christos #else
     71  1.1  christos 
     72  1.1  christos static void
     73  1.1  christos byteSwap(isc_uint32_t *buf, unsigned words)
     74  1.1  christos {
     75  1.1  christos 	unsigned char *p = (unsigned char *)buf;
     76  1.1  christos 
     77  1.1  christos 	do {
     78  1.1  christos 		*buf++ = (isc_uint32_t)((unsigned)p[3] << 8 | p[2]) << 16 |
     79  1.1  christos 			((unsigned)p[1] << 8 | p[0]);
     80  1.1  christos 		p += 4;
     81  1.1  christos 	} while (--words);
     82  1.1  christos }
     83  1.1  christos 
     84  1.1  christos /*!
     85  1.1  christos  * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
     86  1.1  christos  * initialization constants.
     87  1.1  christos  */
     88  1.1  christos void
     89  1.1  christos isc_md5_init(isc_md5_t *ctx) {
     90  1.1  christos 	ctx->buf[0] = 0x67452301;
     91  1.1  christos 	ctx->buf[1] = 0xefcdab89;
     92  1.1  christos 	ctx->buf[2] = 0x98badcfe;
     93  1.1  christos 	ctx->buf[3] = 0x10325476;
     94  1.1  christos 
     95  1.1  christos 	ctx->bytes[0] = 0;
     96  1.1  christos 	ctx->bytes[1] = 0;
     97  1.1  christos }
     98  1.1  christos 
     99  1.1  christos void
    100  1.1  christos isc_md5_invalidate(isc_md5_t *ctx) {
    101  1.1  christos 	memset(ctx, 0, sizeof(isc_md5_t));
    102  1.1  christos }
    103  1.1  christos 
    104  1.1  christos /*@{*/
    105  1.1  christos /*! The four core functions - F1 is optimized somewhat */
    106  1.1  christos 
    107  1.1  christos /* #define F1(x, y, z) (x & y | ~x & z) */
    108  1.1  christos #define F1(x, y, z) (z ^ (x & (y ^ z)))
    109  1.1  christos #define F2(x, y, z) F1(z, x, y)
    110  1.1  christos #define F3(x, y, z) (x ^ y ^ z)
    111  1.1  christos #define F4(x, y, z) (y ^ (x | ~z))
    112  1.1  christos /*@}*/
    113  1.1  christos 
    114  1.1  christos /*! This is the central step in the MD5 algorithm. */
    115  1.1  christos #define MD5STEP(f,w,x,y,z,in,s) \
    116  1.1  christos 	 (w += f(x,y,z) + in, w = (w<<s | w>>(32-s)) + x)
    117  1.1  christos 
    118  1.1  christos /*!
    119  1.1  christos  * The core of the MD5 algorithm, this alters an existing MD5 hash to
    120  1.1  christos  * reflect the addition of 16 longwords of new data.  MD5Update blocks
    121  1.1  christos  * the data and converts bytes into longwords for this routine.
    122  1.1  christos  */
    123  1.1  christos static void
    124  1.1  christos transform(isc_uint32_t buf[4], isc_uint32_t const in[16]) {
    125  1.1  christos 	register isc_uint32_t a, b, c, d;
    126  1.1  christos 
    127  1.1  christos 	a = buf[0];
    128  1.1  christos 	b = buf[1];
    129  1.1  christos 	c = buf[2];
    130  1.1  christos 	d = buf[3];
    131  1.1  christos 
    132  1.1  christos 	MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
    133  1.1  christos 	MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
    134  1.1  christos 	MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
    135  1.1  christos 	MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
    136  1.1  christos 	MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
    137  1.1  christos 	MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
    138  1.1  christos 	MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
    139  1.1  christos 	MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
    140  1.1  christos 	MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
    141  1.1  christos 	MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
    142  1.1  christos 	MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
    143  1.1  christos 	MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
    144  1.1  christos 	MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
    145  1.1  christos 	MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
    146  1.1  christos 	MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
    147  1.1  christos 	MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
    148  1.1  christos 
    149  1.1  christos 	MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
    150  1.1  christos 	MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
    151  1.1  christos 	MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
    152  1.1  christos 	MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
    153  1.1  christos 	MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
    154  1.1  christos 	MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
    155  1.1  christos 	MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
    156  1.1  christos 	MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
    157  1.1  christos 	MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
    158  1.1  christos 	MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
    159  1.1  christos 	MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
    160  1.1  christos 	MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
    161  1.1  christos 	MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
    162  1.1  christos 	MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
    163  1.1  christos 	MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
    164  1.1  christos 	MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
    165  1.1  christos 
    166  1.1  christos 	MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
    167  1.1  christos 	MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
    168  1.1  christos 	MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
    169  1.1  christos 	MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
    170  1.1  christos 	MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
    171  1.1  christos 	MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
    172  1.1  christos 	MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
    173  1.1  christos 	MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
    174  1.1  christos 	MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
    175  1.1  christos 	MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
    176  1.1  christos 	MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
    177  1.1  christos 	MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
    178  1.1  christos 	MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
    179  1.1  christos 	MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
    180  1.1  christos 	MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
    181  1.1  christos 	MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
    182  1.1  christos 
    183  1.1  christos 	MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
    184  1.1  christos 	MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
    185  1.1  christos 	MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
    186  1.1  christos 	MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
    187  1.1  christos 	MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
    188  1.1  christos 	MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
    189  1.1  christos 	MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
    190  1.1  christos 	MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
    191  1.1  christos 	MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
    192  1.1  christos 	MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
    193  1.1  christos 	MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
    194  1.1  christos 	MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
    195  1.1  christos 	MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
    196  1.1  christos 	MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
    197  1.1  christos 	MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
    198  1.1  christos 	MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
    199  1.1  christos 
    200  1.1  christos 	buf[0] += a;
    201  1.1  christos 	buf[1] += b;
    202  1.1  christos 	buf[2] += c;
    203  1.1  christos 	buf[3] += d;
    204  1.1  christos }
    205  1.1  christos 
    206  1.1  christos /*!
    207  1.1  christos  * Update context to reflect the concatenation of another buffer full
    208  1.1  christos  * of bytes.
    209  1.1  christos  */
    210  1.1  christos void
    211  1.1  christos isc_md5_update(isc_md5_t *ctx, const unsigned char *buf, unsigned int len) {
    212  1.1  christos 	isc_uint32_t t;
    213  1.1  christos 
    214  1.1  christos 	/* Update byte count */
    215  1.1  christos 
    216  1.1  christos 	t = ctx->bytes[0];
    217  1.1  christos 	if ((ctx->bytes[0] = t + len) < t)
    218  1.1  christos 		ctx->bytes[1]++;	/* Carry from low to high */
    219  1.1  christos 
    220  1.1  christos 	t = 64 - (t & 0x3f);	/* Space available in ctx->in (at least 1) */
    221  1.1  christos 	if (t > len) {
    222  1.1  christos 		memcpy((unsigned char *)ctx->in + 64 - t, buf, len);
    223  1.1  christos 		return;
    224  1.1  christos 	}
    225  1.1  christos 	/* First chunk is an odd size */
    226  1.1  christos 	memcpy((unsigned char *)ctx->in + 64 - t, buf, t);
    227  1.1  christos 	byteSwap(ctx->in, 16);
    228  1.1  christos 	transform(ctx->buf, ctx->in);
    229  1.1  christos 	buf += t;
    230  1.1  christos 	len -= t;
    231  1.1  christos 
    232  1.1  christos 	/* Process data in 64-byte chunks */
    233  1.1  christos 	while (len >= 64) {
    234  1.1  christos 		memcpy(ctx->in, buf, 64);
    235  1.1  christos 		byteSwap(ctx->in, 16);
    236  1.1  christos 		transform(ctx->buf, ctx->in);
    237  1.1  christos 		buf += 64;
    238  1.1  christos 		len -= 64;
    239  1.1  christos 	}
    240  1.1  christos 
    241  1.1  christos 	/* Handle any remaining bytes of data. */
    242  1.1  christos 	memcpy(ctx->in, buf, len);
    243  1.1  christos }
    244  1.1  christos 
    245  1.1  christos /*!
    246  1.1  christos  * Final wrapup - pad to 64-byte boundary with the bit pattern
    247  1.1  christos  * 1 0* (64-bit count of bits processed, MSB-first)
    248  1.1  christos  */
    249  1.1  christos void
    250  1.1  christos isc_md5_final(isc_md5_t *ctx, unsigned char *digest) {
    251  1.1  christos 	int count = ctx->bytes[0] & 0x3f;    /* Number of bytes in ctx->in */
    252  1.1  christos 	unsigned char *p = (unsigned char *)ctx->in + count;
    253  1.1  christos 
    254  1.1  christos 	/* Set the first char of padding to 0x80.  There is always room. */
    255  1.1  christos 	*p++ = 0x80;
    256  1.1  christos 
    257  1.1  christos 	/* Bytes of padding needed to make 56 bytes (-8..55) */
    258  1.1  christos 	count = 56 - 1 - count;
    259  1.1  christos 
    260  1.1  christos 	if (count < 0) {	/* Padding forces an extra block */
    261  1.1  christos 		memset(p, 0, count + 8);
    262  1.1  christos 		byteSwap(ctx->in, 16);
    263  1.1  christos 		transform(ctx->buf, ctx->in);
    264  1.1  christos 		p = (unsigned char *)ctx->in;
    265  1.1  christos 		count = 56;
    266  1.1  christos 	}
    267  1.1  christos 	memset(p, 0, count);
    268  1.1  christos 	byteSwap(ctx->in, 14);
    269  1.1  christos 
    270  1.1  christos 	/* Append length in bits and transform */
    271  1.1  christos 	ctx->in[14] = ctx->bytes[0] << 3;
    272  1.1  christos 	ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29;
    273  1.1  christos 	transform(ctx->buf, ctx->in);
    274  1.1  christos 
    275  1.1  christos 	byteSwap(ctx->buf, 4);
    276  1.1  christos 	memcpy(digest, ctx->buf, 16);
    277  1.1  christos 	memset(ctx, 0, sizeof(isc_md5_t));	/* In case it's sensitive */
    278  1.1  christos }
    279  1.1  christos #endif
    280