github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/cmd/gc/md5.c (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // 64-bit MD5 (does full MD5 but returns 64 bits only). 6 // Translation of ../../pkg/crypto/md5/md5*.go. 7 8 #include <u.h> 9 #include <libc.h> 10 #include "go.h" 11 #include "md5.h" 12 13 static int md5block(MD5 *dig, uchar *p, int nn); 14 15 enum { 16 _Chunk = 64 17 }; 18 19 #define _Init0 0x67452301 20 #define _Init1 0xEFCDAB89 21 #define _Init2 0x98BADCFE 22 #define _Init3 0x10325476 23 24 void 25 md5reset(MD5 *d) 26 { 27 d->s[0] = _Init0; 28 d->s[1] = _Init1; 29 d->s[2] = _Init2; 30 d->s[3] = _Init3; 31 d->nx = 0; 32 d->len = 0; 33 } 34 35 void 36 md5write(MD5 *d, uchar *p, int nn) 37 { 38 int i, n; 39 40 d->len += nn; 41 if(d->nx > 0) { 42 n = nn; 43 if(n > _Chunk - d->nx) 44 n = _Chunk - d->nx; 45 for(i=0; i<n; i++) 46 d->x[d->nx+i] = p[i]; 47 d->nx += n; 48 if(d->nx == _Chunk) { 49 md5block(d, d->x, _Chunk); 50 d->nx = 0; 51 } 52 p += n; 53 nn -= n; 54 } 55 n = md5block(d, p, nn); 56 p += n; 57 nn -= n; 58 if(nn > 0) { 59 for(i=0; i<nn; i++) 60 d->x[i] = p[i]; 61 d->nx = nn; 62 } 63 } 64 65 uint64 66 md5sum(MD5 *d) 67 { 68 uchar tmp[64]; 69 int i; 70 uint64 len; 71 72 // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64. 73 len = d->len; 74 memset(tmp, 0, sizeof tmp); 75 tmp[0] = 0x80; 76 if(len%64 < 56) 77 md5write(d, tmp, 56-len%64); 78 else 79 md5write(d, tmp, 64+56-len%64); 80 81 // Length in bits. 82 len <<= 3; 83 for(i=0; i<8; i++) 84 tmp[i] = len>>(8*i); 85 md5write(d, tmp, 8); 86 87 if(d->nx != 0) 88 fatal("md5sum"); 89 90 return d->s[0] | ((uint64)d->s[1]<<32); 91 } 92 93 94 // MD5 block step. 95 // In its own file so that a faster assembly or C version 96 // can be substituted easily. 97 98 // table[i] = int((1<<32) * abs(sin(i+1 radians))). 99 static uint32 table[64] = { 100 // round 1 101 0xd76aa478, 102 0xe8c7b756, 103 0x242070db, 104 0xc1bdceee, 105 0xf57c0faf, 106 0x4787c62a, 107 0xa8304613, 108 0xfd469501, 109 0x698098d8, 110 0x8b44f7af, 111 0xffff5bb1, 112 0x895cd7be, 113 0x6b901122, 114 0xfd987193, 115 0xa679438e, 116 0x49b40821, 117 118 // round 2 119 0xf61e2562, 120 0xc040b340, 121 0x265e5a51, 122 0xe9b6c7aa, 123 0xd62f105d, 124 0x2441453, 125 0xd8a1e681, 126 0xe7d3fbc8, 127 0x21e1cde6, 128 0xc33707d6, 129 0xf4d50d87, 130 0x455a14ed, 131 0xa9e3e905, 132 0xfcefa3f8, 133 0x676f02d9, 134 0x8d2a4c8a, 135 136 // round3 137 0xfffa3942, 138 0x8771f681, 139 0x6d9d6122, 140 0xfde5380c, 141 0xa4beea44, 142 0x4bdecfa9, 143 0xf6bb4b60, 144 0xbebfbc70, 145 0x289b7ec6, 146 0xeaa127fa, 147 0xd4ef3085, 148 0x4881d05, 149 0xd9d4d039, 150 0xe6db99e5, 151 0x1fa27cf8, 152 0xc4ac5665, 153 154 // round 4 155 0xf4292244, 156 0x432aff97, 157 0xab9423a7, 158 0xfc93a039, 159 0x655b59c3, 160 0x8f0ccc92, 161 0xffeff47d, 162 0x85845dd1, 163 0x6fa87e4f, 164 0xfe2ce6e0, 165 0xa3014314, 166 0x4e0811a1, 167 0xf7537e82, 168 0xbd3af235, 169 0x2ad7d2bb, 170 0xeb86d391, 171 }; 172 173 static uint32 shift1[] = { 7, 12, 17, 22 }; 174 static uint32 shift2[] = { 5, 9, 14, 20 }; 175 static uint32 shift3[] = { 4, 11, 16, 23 }; 176 static uint32 shift4[] = { 6, 10, 15, 21 }; 177 178 static int 179 md5block(MD5 *dig, uchar *p, int nn) 180 { 181 uint32 a, b, c, d, aa, bb, cc, dd; 182 int i, j, n; 183 uint32 X[16]; 184 185 a = dig->s[0]; 186 b = dig->s[1]; 187 c = dig->s[2]; 188 d = dig->s[3]; 189 n = 0; 190 191 while(nn >= _Chunk) { 192 aa = a; 193 bb = b; 194 cc = c; 195 dd = d; 196 197 for(i=0; i<16; i++) { 198 j = i*4; 199 X[i] = p[j] | (p[j+1]<<8) | (p[j+2]<<16) | (p[j+3]<<24); 200 } 201 202 // Round 1. 203 for(i=0; i<16; i++) { 204 uint32 x, t, s, f; 205 x = i; 206 t = i; 207 s = shift1[i%4]; 208 f = ((c ^ d) & b) ^ d; 209 a += f + X[x] + table[t]; 210 a = a<<s | a>>(32-s); 211 a += b; 212 213 t = d; 214 d = c; 215 c = b; 216 b = a; 217 a = t; 218 } 219 220 // Round 2. 221 for(i=0; i<16; i++) { 222 uint32 x, t, s, g; 223 224 x = (1+5*i)%16; 225 t = 16+i; 226 s = shift2[i%4]; 227 g = ((b ^ c) & d) ^ c; 228 a += g + X[x] + table[t]; 229 a = a<<s | a>>(32-s); 230 a += b; 231 232 t = d; 233 d = c; 234 c = b; 235 b = a; 236 a = t; 237 } 238 239 // Round 3. 240 for(i=0; i<16; i++) { 241 uint32 x, t, s, h; 242 243 x = (5+3*i)%16; 244 t = 32+i; 245 s = shift3[i%4]; 246 h = b ^ c ^ d; 247 a += h + X[x] + table[t]; 248 a = a<<s | a>>(32-s); 249 a += b; 250 251 t = d; 252 d = c; 253 c = b; 254 b = a; 255 a = t; 256 } 257 258 // Round 4. 259 for(i=0; i<16; i++) { 260 uint32 x, s, t, ii; 261 262 x = (7*i)%16; 263 s = shift4[i%4]; 264 t = 48+i; 265 ii = c ^ (b | ~d); 266 a += ii + X[x] + table[t]; 267 a = a<<s | a>>(32-s); 268 a += b; 269 270 t = d; 271 d = c; 272 c = b; 273 b = a; 274 a = t; 275 } 276 277 a += aa; 278 b += bb; 279 c += cc; 280 d += dd; 281 282 p += _Chunk; 283 n += _Chunk; 284 nn -= _Chunk; 285 } 286 287 dig->s[0] = a; 288 dig->s[1] = b; 289 dig->s[2] = c; 290 dig->s[3] = d; 291 return n; 292 }