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  }