md5.c revision 145510
1235848Sissyl0/* $NetBSD$ */ 2235848Sissyl0 3235848Sissyl0 4235848Sissyl0 5235848Sissyl0/* 6235848Sissyl0 *********************************************************************** 7235848Sissyl0 ** md5.c -- the source code for MD5 routines ** 8235848Sissyl0 ** RSA Data Security, Inc. MD5 Message-Digest Algorithm ** 9235848Sissyl0 ** Created: 2/17/90 RLR ** 10235848Sissyl0 ** Revised: 1/91 SRD,AJ,BSK,JT Reference C ver., 7/10 constant corr. ** 11235848Sissyl0 *********************************************************************** 12235848Sissyl0 */ 13235848Sissyl0 14235848Sissyl0/* 15235848Sissyl0 *********************************************************************** 16235848Sissyl0 ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** 17235848Sissyl0 ** ** 18235848Sissyl0 ** License to copy and use this software is granted provided that ** 19235848Sissyl0 ** it is identified as the "RSA Data Security, Inc. MD5 Message- ** 20235848Sissyl0 ** Digest Algorithm" in all material mentioning or referencing this ** 21235848Sissyl0 ** software or this function. ** 22235848Sissyl0 ** ** 23235848Sissyl0 ** License is also granted to make and use derivative works ** 24235848Sissyl0 ** provided that such works are identified as "derived from the RSA ** 25235848Sissyl0 ** Data Security, Inc. MD5 Message-Digest Algorithm" in all ** 26235848Sissyl0 ** material mentioning or referencing the derived work. ** 27235848Sissyl0 ** ** 28235848Sissyl0 ** RSA Data Security, Inc. makes no representations concerning ** 29235848Sissyl0 ** either the merchantability of this software or the suitability ** 30235848Sissyl0 ** of this software for any particular purpose. It is provided "as ** 31235848Sissyl0 ** is" without express or implied warranty of any kind. ** 32235848Sissyl0 ** ** 33235848Sissyl0 ** These notices must be retained in any copies of any part of this ** 34235848Sissyl0 ** documentation and/or software. ** 35235848Sissyl0 *********************************************************************** 36235848Sissyl0 */ 37235848Sissyl0 38235848Sissyl0#if defined(_KERNEL) && !defined(__sgi) 39235848Sissyl0# include <sys/systm.h> 40235848Sissyl0#else 41235848Sissyl0# include <string.h> 42258245Seadler#endif 43235848Sissyl0 44235848Sissyl0#include "md5.h" 45235848Sissyl0 46235848Sissyl0/* 47235848Sissyl0 *********************************************************************** 48235848Sissyl0 ** Message-digest routines: ** 49235848Sissyl0 ** To form the message digest for a message M ** 50235848Sissyl0 ** (1) Initialize a context buffer mdContext using MD5Init ** 51235848Sissyl0 ** (2) Call MD5Update on mdContext and M ** 52235848Sissyl0 ** (3) Call MD5Final on mdContext ** 53235848Sissyl0 ** The message digest is now in mdContext->digest[0...15] ** 54235848Sissyl0 *********************************************************************** 55235848Sissyl0 */ 56235848Sissyl0 57235848Sissyl0/* forward declaration */ 58235848Sissyl0static void Transform __P((UINT4 *, UINT4 *)); 59235848Sissyl0 60235848Sissyl0static unsigned char PADDING[64] = { 61240518Seadler 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 62235848Sissyl0 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 63235848Sissyl0 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 64235848Sissyl0 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 65235848Sissyl0 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 66235848Sissyl0 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 67235848Sissyl0 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 68235848Sissyl0 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 69235848Sissyl0}; 70235848Sissyl0 71235848Sissyl0/* F, G, H and I are basic MD5 functions */ 72#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) 73#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) 74#define H(x, y, z) ((x) ^ (y) ^ (z)) 75#define I(x, y, z) ((y) ^ ((x) | (~z))) 76 77/* ROTATE_LEFT rotates x left n bits */ 78#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) 79 80/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */ 81/* Rotation is separate from addition to prevent recomputation */ 82#define FF(a, b, c, d, x, s, ac) \ 83 {(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ 84 (a) = ROTATE_LEFT ((a), (s)); \ 85 (a) += (b); \ 86 } 87#define GG(a, b, c, d, x, s, ac) \ 88 {(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ 89 (a) = ROTATE_LEFT ((a), (s)); \ 90 (a) += (b); \ 91 } 92#define HH(a, b, c, d, x, s, ac) \ 93 {(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ 94 (a) = ROTATE_LEFT ((a), (s)); \ 95 (a) += (b); \ 96 } 97#define II(a, b, c, d, x, s, ac) \ 98 {(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ 99 (a) = ROTATE_LEFT ((a), (s)); \ 100 (a) += (b); \ 101 } 102 103#ifdef __STDC__ 104#define UL(x) x##U 105#else 106#define UL(x) x 107#endif 108 109/* The routine MD5Init initializes the message-digest context 110 mdContext. All fields are set to zero. 111 */ 112void MD5Init (mdContext) 113MD5_CTX *mdContext; 114{ 115 mdContext->i[0] = mdContext->i[1] = (UINT4)0; 116 117 /* Load magic initialization constants. 118 */ 119 mdContext->buf[0] = (UINT4)0x67452301; 120 mdContext->buf[1] = (UINT4)0xefcdab89; 121 mdContext->buf[2] = (UINT4)0x98badcfe; 122 mdContext->buf[3] = (UINT4)0x10325476; 123} 124 125/* The routine MD5Update updates the message-digest context to 126 account for the presence of each of the characters inBuf[0..inLen-1] 127 in the message whose digest is being computed. 128 */ 129void MD5Update (mdContext, inBuf, inLen) 130MD5_CTX *mdContext; 131unsigned char *inBuf; 132unsigned int inLen; 133{ 134 UINT4 in[16]; 135 int mdi; 136 unsigned int i, ii; 137 138 /* compute number of bytes mod 64 */ 139 mdi = (int)((mdContext->i[0] >> 3) & 0x3F); 140 141 /* update number of bits */ 142 if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0]) 143 mdContext->i[1]++; 144 mdContext->i[0] += ((UINT4)inLen << 3); 145 mdContext->i[1] += ((UINT4)inLen >> 29); 146 147 while (inLen--) { 148 /* add new character to buffer, increment mdi */ 149 mdContext->in[mdi++] = *inBuf++; 150 151 /* transform if necessary */ 152 if (mdi == 0x40) { 153 for (i = 0, ii = 0; i < 16; i++, ii += 4) 154 in[i] = (((UINT4)mdContext->in[ii+3]) << 24) | 155 (((UINT4)mdContext->in[ii+2]) << 16) | 156 (((UINT4)mdContext->in[ii+1]) << 8) | 157 ((UINT4)mdContext->in[ii]); 158 Transform (mdContext->buf, in); 159 mdi = 0; 160 } 161 } 162} 163 164/* The routine MD5Final terminates the message-digest computation and 165 ends with the desired message digest in mdContext->digest[0...15]. 166 */ 167void MD5Final (hash, mdContext) 168unsigned char hash[]; 169MD5_CTX *mdContext; 170{ 171 UINT4 in[16]; 172 int mdi; 173 unsigned int i, ii; 174 unsigned int padLen; 175 176 /* save number of bits */ 177 in[14] = mdContext->i[0]; 178 in[15] = mdContext->i[1]; 179 180 /* compute number of bytes mod 64 */ 181 mdi = (int)((mdContext->i[0] >> 3) & 0x3F); 182 183 /* pad out to 56 mod 64 */ 184 padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi); 185 MD5Update (mdContext, PADDING, padLen); 186 187 /* append length in bits and transform */ 188 for (i = 0, ii = 0; i < 14; i++, ii += 4) 189 in[i] = (((UINT4)mdContext->in[ii+3]) << 24) | 190 (((UINT4)mdContext->in[ii+2]) << 16) | 191 (((UINT4)mdContext->in[ii+1]) << 8) | 192 ((UINT4)mdContext->in[ii]); 193 Transform (mdContext->buf, in); 194 195 /* store buffer in digest */ 196 for (i = 0, ii = 0; i < 4; i++, ii += 4) { 197 mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF); 198 mdContext->digest[ii+1] = 199 (unsigned char)((mdContext->buf[i] >> 8) & 0xFF); 200 mdContext->digest[ii+2] = 201 (unsigned char)((mdContext->buf[i] >> 16) & 0xFF); 202 mdContext->digest[ii+3] = 203 (unsigned char)((mdContext->buf[i] >> 24) & 0xFF); 204 } 205 bcopy((char *)mdContext->digest, (char *)hash, 16); 206} 207 208/* Basic MD5 step. Transforms buf based on in. 209 */ 210static void Transform (buf, in) 211UINT4 *buf; 212UINT4 *in; 213{ 214 UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3]; 215 216 /* Round 1 */ 217#define S11 7 218#define S12 12 219#define S13 17 220#define S14 22 221 FF ( a, b, c, d, in[ 0], S11, UL(3614090360)); /* 1 */ 222 FF ( d, a, b, c, in[ 1], S12, UL(3905402710)); /* 2 */ 223 FF ( c, d, a, b, in[ 2], S13, UL( 606105819)); /* 3 */ 224 FF ( b, c, d, a, in[ 3], S14, UL(3250441966)); /* 4 */ 225 FF ( a, b, c, d, in[ 4], S11, UL(4118548399)); /* 5 */ 226 FF ( d, a, b, c, in[ 5], S12, UL(1200080426)); /* 6 */ 227 FF ( c, d, a, b, in[ 6], S13, UL(2821735955)); /* 7 */ 228 FF ( b, c, d, a, in[ 7], S14, UL(4249261313)); /* 8 */ 229 FF ( a, b, c, d, in[ 8], S11, UL(1770035416)); /* 9 */ 230 FF ( d, a, b, c, in[ 9], S12, UL(2336552879)); /* 10 */ 231 FF ( c, d, a, b, in[10], S13, UL(4294925233)); /* 11 */ 232 FF ( b, c, d, a, in[11], S14, UL(2304563134)); /* 12 */ 233 FF ( a, b, c, d, in[12], S11, UL(1804603682)); /* 13 */ 234 FF ( d, a, b, c, in[13], S12, UL(4254626195)); /* 14 */ 235 FF ( c, d, a, b, in[14], S13, UL(2792965006)); /* 15 */ 236 FF ( b, c, d, a, in[15], S14, UL(1236535329)); /* 16 */ 237 238 /* Round 2 */ 239#define S21 5 240#define S22 9 241#define S23 14 242#define S24 20 243 GG ( a, b, c, d, in[ 1], S21, UL(4129170786)); /* 17 */ 244 GG ( d, a, b, c, in[ 6], S22, UL(3225465664)); /* 18 */ 245 GG ( c, d, a, b, in[11], S23, UL( 643717713)); /* 19 */ 246 GG ( b, c, d, a, in[ 0], S24, UL(3921069994)); /* 20 */ 247 GG ( a, b, c, d, in[ 5], S21, UL(3593408605)); /* 21 */ 248 GG ( d, a, b, c, in[10], S22, UL( 38016083)); /* 22 */ 249 GG ( c, d, a, b, in[15], S23, UL(3634488961)); /* 23 */ 250 GG ( b, c, d, a, in[ 4], S24, UL(3889429448)); /* 24 */ 251 GG ( a, b, c, d, in[ 9], S21, UL( 568446438)); /* 25 */ 252 GG ( d, a, b, c, in[14], S22, UL(3275163606)); /* 26 */ 253 GG ( c, d, a, b, in[ 3], S23, UL(4107603335)); /* 27 */ 254 GG ( b, c, d, a, in[ 8], S24, UL(1163531501)); /* 28 */ 255 GG ( a, b, c, d, in[13], S21, UL(2850285829)); /* 29 */ 256 GG ( d, a, b, c, in[ 2], S22, UL(4243563512)); /* 30 */ 257 GG ( c, d, a, b, in[ 7], S23, UL(1735328473)); /* 31 */ 258 GG ( b, c, d, a, in[12], S24, UL(2368359562)); /* 32 */ 259 260 /* Round 3 */ 261#define S31 4 262#define S32 11 263#define S33 16 264#define S34 23 265 HH ( a, b, c, d, in[ 5], S31, UL(4294588738)); /* 33 */ 266 HH ( d, a, b, c, in[ 8], S32, UL(2272392833)); /* 34 */ 267 HH ( c, d, a, b, in[11], S33, UL(1839030562)); /* 35 */ 268 HH ( b, c, d, a, in[14], S34, UL(4259657740)); /* 36 */ 269 HH ( a, b, c, d, in[ 1], S31, UL(2763975236)); /* 37 */ 270 HH ( d, a, b, c, in[ 4], S32, UL(1272893353)); /* 38 */ 271 HH ( c, d, a, b, in[ 7], S33, UL(4139469664)); /* 39 */ 272 HH ( b, c, d, a, in[10], S34, UL(3200236656)); /* 40 */ 273 HH ( a, b, c, d, in[13], S31, UL( 681279174)); /* 41 */ 274 HH ( d, a, b, c, in[ 0], S32, UL(3936430074)); /* 42 */ 275 HH ( c, d, a, b, in[ 3], S33, UL(3572445317)); /* 43 */ 276 HH ( b, c, d, a, in[ 6], S34, UL( 76029189)); /* 44 */ 277 HH ( a, b, c, d, in[ 9], S31, UL(3654602809)); /* 45 */ 278 HH ( d, a, b, c, in[12], S32, UL(3873151461)); /* 46 */ 279 HH ( c, d, a, b, in[15], S33, UL( 530742520)); /* 47 */ 280 HH ( b, c, d, a, in[ 2], S34, UL(3299628645)); /* 48 */ 281 282 /* Round 4 */ 283#define S41 6 284#define S42 10 285#define S43 15 286#define S44 21 287 II ( a, b, c, d, in[ 0], S41, UL(4096336452)); /* 49 */ 288 II ( d, a, b, c, in[ 7], S42, UL(1126891415)); /* 50 */ 289 II ( c, d, a, b, in[14], S43, UL(2878612391)); /* 51 */ 290 II ( b, c, d, a, in[ 5], S44, UL(4237533241)); /* 52 */ 291 II ( a, b, c, d, in[12], S41, UL(1700485571)); /* 53 */ 292 II ( d, a, b, c, in[ 3], S42, UL(2399980690)); /* 54 */ 293 II ( c, d, a, b, in[10], S43, UL(4293915773)); /* 55 */ 294 II ( b, c, d, a, in[ 1], S44, UL(2240044497)); /* 56 */ 295 II ( a, b, c, d, in[ 8], S41, UL(1873313359)); /* 57 */ 296 II ( d, a, b, c, in[15], S42, UL(4264355552)); /* 58 */ 297 II ( c, d, a, b, in[ 6], S43, UL(2734768916)); /* 59 */ 298 II ( b, c, d, a, in[13], S44, UL(1309151649)); /* 60 */ 299 II ( a, b, c, d, in[ 4], S41, UL(4149444226)); /* 61 */ 300 II ( d, a, b, c, in[11], S42, UL(3174756917)); /* 62 */ 301 II ( c, d, a, b, in[ 2], S43, UL( 718787259)); /* 63 */ 302 II ( b, c, d, a, in[ 9], S44, UL(3951481745)); /* 64 */ 303 304 buf[0] += a; 305 buf[1] += b; 306 buf[2] += c; 307 buf[3] += d; 308} 309 310/* 311 *********************************************************************** 312 ** End of md5.c ** 313 ******************************** (cut) ******************************** 314 */ 315