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