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