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