1 /* $NetBSD: md5c.c,v 1.1 2014/03/09 00:15:45 agc Exp $ */ 2 3 /* 4 * This file is derived from the RSA Data Security, Inc. MD5 Message-Digest 5 * Algorithm and has been modified by Jason R. Thorpe <thorpej@NetBSD.org> 6 * for portability and formatting. 7 */ 8 9 /* 10 * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All 11 * rights reserved. 12 * 13 * License to copy and use this software is granted provided that it 14 * is identified as the "RSA Data Security, Inc. MD5 Message-Digest 15 * Algorithm" in all material mentioning or referencing this software 16 * or this function. 17 * 18 * License is also granted to make and use derivative works provided 19 * that such works are identified as "derived from the RSA Data 20 * Security, Inc. MD5 Message-Digest Algorithm" in all material 21 * mentioning or referencing the derived work. 22 * 23 * RSA Data Security, Inc. makes no representations concerning either 24 * the merchantability of this software or the suitability of this 25 * software for any particular purpose. It is provided "as is" 26 * without express or implied warranty of any kind. 27 * 28 * These notices must be retained in any copies of any part of this 29 * documentation and/or software. 30 */ 31 32 #include <sys/cdefs.h> 33 #include <sys/types.h> 34 #include <assert.h> 35 #include <string.h> 36 37 #include "md5.h" 38 39 #if !HAVE_MD5_H 40 41 #define ZEROIZE(d, l) memset((d), 0, (l)) 42 43 typedef unsigned char *POINTER; 44 typedef uint16_t UINT2; 45 typedef uint32_t UINT4; 46 47 /* 48 * Constants for MD5Transform routine. 49 */ 50 #define S11 7 51 #define S12 12 52 #define S13 17 53 #define S14 22 54 #define S21 5 55 #define S22 9 56 #define S23 14 57 #define S24 20 58 #define S31 4 59 #define S32 11 60 #define S33 16 61 #define S34 23 62 #define S41 6 63 #define S42 10 64 #define S43 15 65 #define S44 21 66 67 static void MD5Transform(UINT4 [4], const unsigned char [64]); 68 69 static void Encode(unsigned char *, UINT4 *, unsigned int); 70 static void Decode(UINT4 *, const unsigned char *, unsigned int); 71 72 /* 73 * Encodes input (UINT4) into output (unsigned char). Assumes len is 74 * a multiple of 4. 75 */ 76 static void 77 Encode (unsigned char *output, 78 UINT4 *input, 79 unsigned int len) 80 { 81 unsigned int i, j; 82 83 for (i = 0, j = 0; j < len; i++, j += 4) { 84 output[j] = (unsigned char)(input[i] & 0xff); 85 output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); 86 output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); 87 output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); 88 } 89 } 90 91 /* 92 * Decodes input (unsigned char) into output (UINT4). Assumes len is 93 * a multiple of 4. 94 */ 95 static void 96 Decode (UINT4 *output, 97 const unsigned char *input, 98 unsigned int len) 99 { 100 unsigned int i, j; 101 102 for (i = 0, j = 0; j < len; i++, j += 4) 103 output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | 104 (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24); 105 } 106 107 static const unsigned char PADDING[64] = { 108 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 111 }; 112 113 /* 114 * F, G, H and I are basic MD5 functions. 115 */ 116 #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) 117 #define G(x, y, z) (((x) & (z)) | ((y) & (~z))) 118 #define H(x, y, z) ((x) ^ (y) ^ (z)) 119 #define I(x, y, z) ((y) ^ ((x) | (~z))) 120 121 /* 122 * ROTATE_LEFT rotates x left n bits. 123 */ 124 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) 125 126 /* 127 * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. 128 * Rotation is separate from addition to prevent recomputation. 129 */ 130 #define FF(a, b, c, d, x, s, ac) { \ 131 (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ 132 (a) = ROTATE_LEFT ((a), (s)); \ 133 (a) += (b); \ 134 } 135 136 #define GG(a, b, c, d, x, s, ac) { \ 137 (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ 138 (a) = ROTATE_LEFT ((a), (s)); \ 139 (a) += (b); \ 140 } 141 142 #define HH(a, b, c, d, x, s, ac) { \ 143 (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ 144 (a) = ROTATE_LEFT ((a), (s)); \ 145 (a) += (b); \ 146 } 147 148 #define II(a, b, c, d, x, s, ac) { \ 149 (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ 150 (a) = ROTATE_LEFT ((a), (s)); \ 151 (a) += (b); \ 152 } 153 154 /* 155 * MD5 initialization. Begins an MD5 operation, writing a new context. 156 */ 157 void 158 MD5Init(MD5_CTX *context) 159 { 160 161 context->count[0] = context->count[1] = 0; 162 163 /* Load magic initialization constants. */ 164 context->state[0] = 0x67452301; 165 context->state[1] = 0xefcdab89; 166 context->state[2] = 0x98badcfe; 167 context->state[3] = 0x10325476; 168 } 169 170 /* 171 * MD5 block update operation. Continues an MD5 message-digest 172 * operation, processing another message block, and updating the 173 * context. 174 */ 175 void 176 MD5Update(MD5_CTX *context, 177 const unsigned char *input, /* input block */ 178 unsigned int inputLen) /* length of input block */ 179 { 180 unsigned int i, idx, partLen; 181 182 /* Compute number of bytes mod 64 */ 183 idx = (unsigned int)((context->count[0] >> 3) & 0x3F); 184 185 /* Update number of bits */ 186 if ((context->count[0] += ((UINT4)inputLen << 3)) 187 < ((UINT4)inputLen << 3)) 188 context->count[1]++; 189 context->count[1] += ((UINT4)inputLen >> 29); 190 191 partLen = 64 - idx; 192 193 /* Transform as many times as possible. */ 194 if (inputLen >= partLen) { 195 memcpy((POINTER)&context->buffer[idx], input, partLen); 196 MD5Transform(context->state, context->buffer); 197 198 for (i = partLen; i + 63 < inputLen; i += 64) 199 MD5Transform(context->state, &input[i]); 200 201 idx = 0; 202 } else 203 i = 0; 204 205 /* Buffer remaining input */ 206 memcpy(&context->buffer[idx], &input[i], inputLen - i); 207 } 208 209 /* 210 * MD5 finalization. Ends an MD5 message-digest operation, writing the 211 * message digest and zeroing the context. 212 */ 213 void 214 MD5Final(unsigned char digest[16], /* message digest */ 215 MD5_CTX *context) /* context */ 216 { 217 unsigned char bits[8]; 218 unsigned int idx, padLen; 219 220 /* Save number of bits */ 221 Encode(bits, context->count, 8); 222 223 /* Pad out to 56 mod 64. */ 224 idx = (unsigned int)((context->count[0] >> 3) & 0x3f); 225 padLen = (idx < 56) ? (56 - idx) : (120 - idx); 226 MD5Update (context, PADDING, padLen); 227 228 /* Append length (before padding) */ 229 MD5Update(context, bits, 8); 230 231 /* Store state in digest */ 232 Encode(digest, context->state, 16); 233 234 /* Zeroize sensitive information. */ 235 ZEROIZE((POINTER)(void *)context, sizeof(*context)); 236 } 237 238 /* 239 * MD5 basic transformation. Transforms state based on block. 240 */ 241 static void 242 MD5Transform(UINT4 state[4], const unsigned char block[64]) 243 { 244 UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; 245 246 Decode(x, block, 64); 247 248 /* Round 1 */ 249 FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ 250 FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ 251 FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ 252 FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ 253 FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ 254 FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ 255 FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ 256 FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ 257 FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ 258 FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ 259 FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ 260 FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ 261 FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ 262 FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ 263 FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ 264 FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ 265 266 /* Round 2 */ 267 GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ 268 GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ 269 GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ 270 GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ 271 GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ 272 GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ 273 GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ 274 GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ 275 GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ 276 GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ 277 GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ 278 GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ 279 GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ 280 GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ 281 GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ 282 GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ 283 284 /* Round 3 */ 285 HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ 286 HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ 287 HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ 288 HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ 289 HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ 290 HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ 291 HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ 292 HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ 293 HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ 294 HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ 295 HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ 296 HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ 297 HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ 298 HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ 299 HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ 300 HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ 301 302 /* Round 4 */ 303 II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ 304 II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ 305 II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ 306 II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ 307 II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ 308 II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ 309 II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ 310 II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ 311 II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ 312 II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ 313 II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ 314 II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ 315 II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ 316 II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ 317 II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ 318 II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ 319 320 state[0] += a; 321 state[1] += b; 322 state[2] += c; 323 state[3] += d; 324 325 /* Zeroize sensitive information. */ 326 ZEROIZE((POINTER)(void *)x, sizeof (x)); 327 } 328 329 #endif /* HAVE_MD5_H */ 330