1/*
2 *  md5.c
3 *  Adapted for perf_index from ccmd5_ltc.c in corecrypto
4 *
5 *  Created by Fabrice Gautier on 12/3/10.
6 *  Copyright 2010,2011 Apple Inc. All rights reserved.
7 *
8 */
9
10#include "md5.h"
11
12#include <stdint.h>
13#include <string.h>
14
15#define CCMD5_BLOCK_SIZE 64
16
17#define F(x,y,z)  (z ^ (x & (y ^ z)))
18#define G(x,y,z)  (y ^ (z & (y ^ x)))
19#define H(x,y,z)  (x^y^z)
20#define I(x,y,z)  (y^(x|(~z)))
21
22#define CC_ROLc(X,s) (((X) << (s)) | ((X) >> (32 - (s))))
23
24#define FF(a,b,c,d,M,s,t) \
25a = (a + F(b,c,d) + M + t); a = CC_ROLc(a, s) + b;
26
27#define GG(a,b,c,d,M,s,t) \
28a = (a + G(b,c,d) + M + t); a = CC_ROLc(a, s) + b;
29
30#define HH(a,b,c,d,M,s,t) \
31a = (a + H(b,c,d) + M + t); a = CC_ROLc(a, s) + b;
32
33#define II(a,b,c,d,M,s,t) \
34a = (a + I(b,c,d) + M + t); a = CC_ROLc(a, s) + b;
35
36static void md5_compress(uint32_t *state, unsigned long nblocks, const void *in)
37{
38    uint32_t i, W[16], a, b, c, d;
39    uint32_t *s = state;
40    const unsigned char *buf = in;
41
42    while(nblocks--) {
43
44        /* copy the state into 512-bits into W[0..15] */
45        for (i = 0; i < 16; i++) {
46            W[i] = ((uint32_t*)buf)[i];
47        }
48
49        /* copy state */
50        a = s[0];
51        b = s[1];
52        c = s[2];
53        d = s[3];
54
55        FF(a,b,c,d,W[0],7,0xd76aa478)
56        FF(d,a,b,c,W[1],12,0xe8c7b756)
57        FF(c,d,a,b,W[2],17,0x242070db)
58        FF(b,c,d,a,W[3],22,0xc1bdceee)
59        FF(a,b,c,d,W[4],7,0xf57c0faf)
60        FF(d,a,b,c,W[5],12,0x4787c62a)
61        FF(c,d,a,b,W[6],17,0xa8304613)
62        FF(b,c,d,a,W[7],22,0xfd469501)
63        FF(a,b,c,d,W[8],7,0x698098d8)
64        FF(d,a,b,c,W[9],12,0x8b44f7af)
65        FF(c,d,a,b,W[10],17,0xffff5bb1)
66        FF(b,c,d,a,W[11],22,0x895cd7be)
67        FF(a,b,c,d,W[12],7,0x6b901122)
68        FF(d,a,b,c,W[13],12,0xfd987193)
69        FF(c,d,a,b,W[14],17,0xa679438e)
70        FF(b,c,d,a,W[15],22,0x49b40821)
71        GG(a,b,c,d,W[1],5,0xf61e2562)
72        GG(d,a,b,c,W[6],9,0xc040b340)
73        GG(c,d,a,b,W[11],14,0x265e5a51)
74        GG(b,c,d,a,W[0],20,0xe9b6c7aa)
75        GG(a,b,c,d,W[5],5,0xd62f105d)
76        GG(d,a,b,c,W[10],9,0x02441453)
77        GG(c,d,a,b,W[15],14,0xd8a1e681)
78        GG(b,c,d,a,W[4],20,0xe7d3fbc8)
79        GG(a,b,c,d,W[9],5,0x21e1cde6)
80        GG(d,a,b,c,W[14],9,0xc33707d6)
81        GG(c,d,a,b,W[3],14,0xf4d50d87)
82        GG(b,c,d,a,W[8],20,0x455a14ed)
83        GG(a,b,c,d,W[13],5,0xa9e3e905)
84        GG(d,a,b,c,W[2],9,0xfcefa3f8)
85        GG(c,d,a,b,W[7],14,0x676f02d9)
86        GG(b,c,d,a,W[12],20,0x8d2a4c8a)
87        HH(a,b,c,d,W[5],4,0xfffa3942)
88        HH(d,a,b,c,W[8],11,0x8771f681)
89        HH(c,d,a,b,W[11],16,0x6d9d6122)
90        HH(b,c,d,a,W[14],23,0xfde5380c)
91        HH(a,b,c,d,W[1],4,0xa4beea44)
92        HH(d,a,b,c,W[4],11,0x4bdecfa9)
93        HH(c,d,a,b,W[7],16,0xf6bb4b60)
94        HH(b,c,d,a,W[10],23,0xbebfbc70)
95        HH(a,b,c,d,W[13],4,0x289b7ec6)
96        HH(d,a,b,c,W[0],11,0xeaa127fa)
97        HH(c,d,a,b,W[3],16,0xd4ef3085)
98        HH(b,c,d,a,W[6],23,0x04881d05)
99        HH(a,b,c,d,W[9],4,0xd9d4d039)
100        HH(d,a,b,c,W[12],11,0xe6db99e5)
101        HH(c,d,a,b,W[15],16,0x1fa27cf8)
102        HH(b,c,d,a,W[2],23,0xc4ac5665)
103        II(a,b,c,d,W[0],6,0xf4292244)
104        II(d,a,b,c,W[7],10,0x432aff97)
105        II(c,d,a,b,W[14],15,0xab9423a7)
106        II(b,c,d,a,W[5],21,0xfc93a039)
107        II(a,b,c,d,W[12],6,0x655b59c3)
108        II(d,a,b,c,W[3],10,0x8f0ccc92)
109        II(c,d,a,b,W[10],15,0xffeff47d)
110        II(b,c,d,a,W[1],21,0x85845dd1)
111        II(a,b,c,d,W[8],6,0x6fa87e4f)
112        II(d,a,b,c,W[15],10,0xfe2ce6e0)
113        II(c,d,a,b,W[6],15,0xa3014314)
114        II(b,c,d,a,W[13],21,0x4e0811a1)
115        II(a,b,c,d,W[4],6,0xf7537e82)
116        II(d,a,b,c,W[11],10,0xbd3af235)
117        II(c,d,a,b,W[2],15,0x2ad7d2bb)
118        II(b,c,d,a,W[9],21,0xeb86d391)
119
120        /* store state */
121        s[0] += a;
122        s[1] += b;
123        s[2] += c;
124        s[3] += d;
125
126        buf+=CCMD5_BLOCK_SIZE;
127    }
128}
129
130void md5_hash(uint8_t *message, uint64_t len, uint32_t *hash) {
131	hash[0] = 0x67452301;
132	hash[1] = 0xEFCDAB89;
133	hash[2] = 0x98BADCFE;
134	hash[3] = 0x10325476;
135
136	md5_compress(hash, len/64, message);
137
138	uint32_t blockbuff[16];
139	uint8_t *byteptr = (uint8_t*)blockbuff;
140
141	int left = len % 64;
142	memcpy(byteptr, message + len-left, left);
143
144	byteptr[left] = 0x80;
145	left++;
146	if (64 - left >= 8)
147		bzero(byteptr + left, 56 - left);
148	else {
149		memset(byteptr + left, 0, 64 - left);
150		md5_compress(hash, 1, blockbuff);
151		bzero(blockbuff, 56);
152	}
153	blockbuff[14] = (uint32_t)(len << 3);
154	blockbuff[15] = (uint32_t)(len >> 29);
155	md5_compress(hash, 1, blockbuff);
156}
157