github.com/ader1990/go@v0.0.0-20140630135419-8c24447fa791/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, uint64 *hi) 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 if(hi != nil) 91 *hi = d->s[2] | ((uint64)d->s[3]<<32); 92 return d->s[0] | ((uint64)d->s[1]<<32); 93 } 94 95 96 // MD5 block step. 97 // In its own file so that a faster assembly or C version 98 // can be substituted easily. 99 100 // table[i] = int((1<<32) * abs(sin(i+1 radians))). 101 static uint32 table[64] = { 102 // round 1 103 0xd76aa478, 104 0xe8c7b756, 105 0x242070db, 106 0xc1bdceee, 107 0xf57c0faf, 108 0x4787c62a, 109 0xa8304613, 110 0xfd469501, 111 0x698098d8, 112 0x8b44f7af, 113 0xffff5bb1, 114 0x895cd7be, 115 0x6b901122, 116 0xfd987193, 117 0xa679438e, 118 0x49b40821, 119 120 // round 2 121 0xf61e2562, 122 0xc040b340, 123 0x265e5a51, 124 0xe9b6c7aa, 125 0xd62f105d, 126 0x2441453, 127 0xd8a1e681, 128 0xe7d3fbc8, 129 0x21e1cde6, 130 0xc33707d6, 131 0xf4d50d87, 132 0x455a14ed, 133 0xa9e3e905, 134 0xfcefa3f8, 135 0x676f02d9, 136 0x8d2a4c8a, 137 138 // round3 139 0xfffa3942, 140 0x8771f681, 141 0x6d9d6122, 142 0xfde5380c, 143 0xa4beea44, 144 0x4bdecfa9, 145 0xf6bb4b60, 146 0xbebfbc70, 147 0x289b7ec6, 148 0xeaa127fa, 149 0xd4ef3085, 150 0x4881d05, 151 0xd9d4d039, 152 0xe6db99e5, 153 0x1fa27cf8, 154 0xc4ac5665, 155 156 // round 4 157 0xf4292244, 158 0x432aff97, 159 0xab9423a7, 160 0xfc93a039, 161 0x655b59c3, 162 0x8f0ccc92, 163 0xffeff47d, 164 0x85845dd1, 165 0x6fa87e4f, 166 0xfe2ce6e0, 167 0xa3014314, 168 0x4e0811a1, 169 0xf7537e82, 170 0xbd3af235, 171 0x2ad7d2bb, 172 0xeb86d391, 173 }; 174 175 static uint32 shift1[] = { 7, 12, 17, 22 }; 176 static uint32 shift2[] = { 5, 9, 14, 20 }; 177 static uint32 shift3[] = { 4, 11, 16, 23 }; 178 static uint32 shift4[] = { 6, 10, 15, 21 }; 179 180 static int 181 md5block(MD5 *dig, uchar *p, int nn) 182 { 183 uint32 a, b, c, d, aa, bb, cc, dd; 184 int i, j, n; 185 uint32 X[16]; 186 187 a = dig->s[0]; 188 b = dig->s[1]; 189 c = dig->s[2]; 190 d = dig->s[3]; 191 n = 0; 192 193 while(nn >= _Chunk) { 194 aa = a; 195 bb = b; 196 cc = c; 197 dd = d; 198 199 for(i=0; i<16; i++) { 200 j = i*4; 201 X[i] = p[j] | (p[j+1]<<8) | (p[j+2]<<16) | ((uint32)p[j+3]<<24); 202 } 203 204 // Round 1. 205 for(i=0; i<16; i++) { 206 uint32 x, t, s, f; 207 x = i; 208 t = i; 209 s = shift1[i%4]; 210 f = ((c ^ d) & b) ^ d; 211 a += f + X[x] + table[t]; 212 a = a<<s | a>>(32-s); 213 a += b; 214 215 t = d; 216 d = c; 217 c = b; 218 b = a; 219 a = t; 220 } 221 222 // Round 2. 223 for(i=0; i<16; i++) { 224 uint32 x, t, s, g; 225 226 x = (1+5*i)%16; 227 t = 16+i; 228 s = shift2[i%4]; 229 g = ((b ^ c) & d) ^ c; 230 a += g + X[x] + table[t]; 231 a = a<<s | a>>(32-s); 232 a += b; 233 234 t = d; 235 d = c; 236 c = b; 237 b = a; 238 a = t; 239 } 240 241 // Round 3. 242 for(i=0; i<16; i++) { 243 uint32 x, t, s, h; 244 245 x = (5+3*i)%16; 246 t = 32+i; 247 s = shift3[i%4]; 248 h = b ^ c ^ d; 249 a += h + X[x] + table[t]; 250 a = a<<s | a>>(32-s); 251 a += b; 252 253 t = d; 254 d = c; 255 c = b; 256 b = a; 257 a = t; 258 } 259 260 // Round 4. 261 for(i=0; i<16; i++) { 262 uint32 x, s, t, ii; 263 264 x = (7*i)%16; 265 s = shift4[i%4]; 266 t = 48+i; 267 ii = c ^ (b | ~d); 268 a += ii + X[x] + table[t]; 269 a = a<<s | a>>(32-s); 270 a += b; 271 272 t = d; 273 d = c; 274 c = b; 275 b = a; 276 a = t; 277 } 278 279 a += aa; 280 b += bb; 281 c += cc; 282 d += dd; 283 284 p += _Chunk; 285 n += _Chunk; 286 nn -= _Chunk; 287 } 288 289 dig->s[0] = a; 290 dig->s[1] = b; 291 dig->s[2] = c; 292 dig->s[3] = d; 293 return n; 294 }