1*f6dc9357SAndroid Build Coastguard Worker /* Md5.c -- MD5 Hash
2*f6dc9357SAndroid Build Coastguard Worker : Igor Pavlov : Public domain
3*f6dc9357SAndroid Build Coastguard Worker This code is based on Colin Plumb's public domain md5.c code */
4*f6dc9357SAndroid Build Coastguard Worker
5*f6dc9357SAndroid Build Coastguard Worker #include "Precomp.h"
6*f6dc9357SAndroid Build Coastguard Worker
7*f6dc9357SAndroid Build Coastguard Worker #include <string.h>
8*f6dc9357SAndroid Build Coastguard Worker
9*f6dc9357SAndroid Build Coastguard Worker #include "Md5.h"
10*f6dc9357SAndroid Build Coastguard Worker #include "RotateDefs.h"
11*f6dc9357SAndroid Build Coastguard Worker #include "CpuArch.h"
12*f6dc9357SAndroid Build Coastguard Worker
13*f6dc9357SAndroid Build Coastguard Worker #define MD5_UPDATE_BLOCKS(p) Md5_UpdateBlocks
14*f6dc9357SAndroid Build Coastguard Worker
15*f6dc9357SAndroid Build Coastguard Worker Z7_NO_INLINE
Md5_Init(CMd5 * p)16*f6dc9357SAndroid Build Coastguard Worker void Md5_Init(CMd5 *p)
17*f6dc9357SAndroid Build Coastguard Worker {
18*f6dc9357SAndroid Build Coastguard Worker p->count = 0;
19*f6dc9357SAndroid Build Coastguard Worker p->state[0] = 0x67452301;
20*f6dc9357SAndroid Build Coastguard Worker p->state[1] = 0xefcdab89;
21*f6dc9357SAndroid Build Coastguard Worker p->state[2] = 0x98badcfe;
22*f6dc9357SAndroid Build Coastguard Worker p->state[3] = 0x10325476;
23*f6dc9357SAndroid Build Coastguard Worker }
24*f6dc9357SAndroid Build Coastguard Worker
25*f6dc9357SAndroid Build Coastguard Worker #if 0 && !defined(MY_CPU_LE_UNALIGN)
26*f6dc9357SAndroid Build Coastguard Worker // optional optimization for Big-endian processors or processors without unaligned access:
27*f6dc9357SAndroid Build Coastguard Worker // it is intended to reduce the number of complex LE32 memory reading from 64 to 16.
28*f6dc9357SAndroid Build Coastguard Worker // But some compilers (sparc, armt) are better without this optimization.
29*f6dc9357SAndroid Build Coastguard Worker #define Z7_MD5_USE_DATA32_ARRAY
30*f6dc9357SAndroid Build Coastguard Worker #endif
31*f6dc9357SAndroid Build Coastguard Worker
32*f6dc9357SAndroid Build Coastguard Worker #define LOAD_DATA(i) GetUi32((const UInt32 *)(const void *)data + (i))
33*f6dc9357SAndroid Build Coastguard Worker
34*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_MD5_USE_DATA32_ARRAY
35*f6dc9357SAndroid Build Coastguard Worker #define D(i) data32[i]
36*f6dc9357SAndroid Build Coastguard Worker #else
37*f6dc9357SAndroid Build Coastguard Worker #define D(i) LOAD_DATA(i)
38*f6dc9357SAndroid Build Coastguard Worker #endif
39*f6dc9357SAndroid Build Coastguard Worker
40*f6dc9357SAndroid Build Coastguard Worker #define F1(x, y, z) (z ^ (x & (y ^ z)))
41*f6dc9357SAndroid Build Coastguard Worker #define F2(x, y, z) F1(z, x, y)
42*f6dc9357SAndroid Build Coastguard Worker #define F3(x, y, z) (x ^ y ^ z)
43*f6dc9357SAndroid Build Coastguard Worker #define F4(x, y, z) (y ^ (x | ~z))
44*f6dc9357SAndroid Build Coastguard Worker
45*f6dc9357SAndroid Build Coastguard Worker #define R1(i, f, start, step, w, x, y, z, s, k) \
46*f6dc9357SAndroid Build Coastguard Worker w += D((start + step * (i)) % 16) + k; \
47*f6dc9357SAndroid Build Coastguard Worker w += f(x, y, z); \
48*f6dc9357SAndroid Build Coastguard Worker w = rotlFixed(w, s) + x; \
49*f6dc9357SAndroid Build Coastguard Worker
50*f6dc9357SAndroid Build Coastguard Worker #define R4(i4, f, start, step, s0,s1,s2,s3, k0,k1,k2,k3) \
51*f6dc9357SAndroid Build Coastguard Worker R1 (i4*4+0, f, start, step, a,b,c,d, s0, k0) \
52*f6dc9357SAndroid Build Coastguard Worker R1 (i4*4+1, f, start, step, d,a,b,c, s1, k1) \
53*f6dc9357SAndroid Build Coastguard Worker R1 (i4*4+2, f, start, step, c,d,a,b, s2, k2) \
54*f6dc9357SAndroid Build Coastguard Worker R1 (i4*4+3, f, start, step, b,c,d,a, s3, k3) \
55*f6dc9357SAndroid Build Coastguard Worker
56*f6dc9357SAndroid Build Coastguard Worker #define R16(f, start, step, s0,s1,s2,s3, k00,k01,k02,k03, k10,k11,k12,k13, k20,k21,k22,k23, k30,k31,k32,k33) \
57*f6dc9357SAndroid Build Coastguard Worker R4 (0, f, start, step, s0,s1,s2,s3, k00,k01,k02,k03) \
58*f6dc9357SAndroid Build Coastguard Worker R4 (1, f, start, step, s0,s1,s2,s3, k10,k11,k12,k13) \
59*f6dc9357SAndroid Build Coastguard Worker R4 (2, f, start, step, s0,s1,s2,s3, k20,k21,k22,k23) \
60*f6dc9357SAndroid Build Coastguard Worker R4 (3, f, start, step, s0,s1,s2,s3, k30,k31,k32,k33) \
61*f6dc9357SAndroid Build Coastguard Worker
62*f6dc9357SAndroid Build Coastguard Worker static
63*f6dc9357SAndroid Build Coastguard Worker Z7_NO_INLINE
Md5_UpdateBlocks(UInt32 state[4],const Byte * data,size_t numBlocks)64*f6dc9357SAndroid Build Coastguard Worker void Z7_FASTCALL Md5_UpdateBlocks(UInt32 state[4], const Byte *data, size_t numBlocks)
65*f6dc9357SAndroid Build Coastguard Worker {
66*f6dc9357SAndroid Build Coastguard Worker UInt32 a, b, c, d;
67*f6dc9357SAndroid Build Coastguard Worker // if (numBlocks == 0) return;
68*f6dc9357SAndroid Build Coastguard Worker a = state[0];
69*f6dc9357SAndroid Build Coastguard Worker b = state[1];
70*f6dc9357SAndroid Build Coastguard Worker c = state[2];
71*f6dc9357SAndroid Build Coastguard Worker d = state[3];
72*f6dc9357SAndroid Build Coastguard Worker do
73*f6dc9357SAndroid Build Coastguard Worker {
74*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_MD5_USE_DATA32_ARRAY
75*f6dc9357SAndroid Build Coastguard Worker UInt32 data32[MD5_NUM_BLOCK_WORDS];
76*f6dc9357SAndroid Build Coastguard Worker {
77*f6dc9357SAndroid Build Coastguard Worker #define LOAD_data32_x4(i) { \
78*f6dc9357SAndroid Build Coastguard Worker data32[i ] = LOAD_DATA(i ); \
79*f6dc9357SAndroid Build Coastguard Worker data32[i + 1] = LOAD_DATA(i + 1); \
80*f6dc9357SAndroid Build Coastguard Worker data32[i + 2] = LOAD_DATA(i + 2); \
81*f6dc9357SAndroid Build Coastguard Worker data32[i + 3] = LOAD_DATA(i + 3); }
82*f6dc9357SAndroid Build Coastguard Worker #if 1
83*f6dc9357SAndroid Build Coastguard Worker LOAD_data32_x4 (0 * 4)
84*f6dc9357SAndroid Build Coastguard Worker LOAD_data32_x4 (1 * 4)
85*f6dc9357SAndroid Build Coastguard Worker LOAD_data32_x4 (2 * 4)
86*f6dc9357SAndroid Build Coastguard Worker LOAD_data32_x4 (3 * 4)
87*f6dc9357SAndroid Build Coastguard Worker #else
88*f6dc9357SAndroid Build Coastguard Worker unsigned i;
89*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < MD5_NUM_BLOCK_WORDS; i += 4)
90*f6dc9357SAndroid Build Coastguard Worker {
91*f6dc9357SAndroid Build Coastguard Worker LOAD_data32_x4(i)
92*f6dc9357SAndroid Build Coastguard Worker }
93*f6dc9357SAndroid Build Coastguard Worker #endif
94*f6dc9357SAndroid Build Coastguard Worker }
95*f6dc9357SAndroid Build Coastguard Worker #endif
96*f6dc9357SAndroid Build Coastguard Worker
97*f6dc9357SAndroid Build Coastguard Worker R16 (F1, 0, 1, 7,12,17,22, 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
98*f6dc9357SAndroid Build Coastguard Worker 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
99*f6dc9357SAndroid Build Coastguard Worker 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
100*f6dc9357SAndroid Build Coastguard Worker 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821)
101*f6dc9357SAndroid Build Coastguard Worker R16 (F2, 1, 5, 5, 9,14,20, 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
102*f6dc9357SAndroid Build Coastguard Worker 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
103*f6dc9357SAndroid Build Coastguard Worker 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
104*f6dc9357SAndroid Build Coastguard Worker 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a)
105*f6dc9357SAndroid Build Coastguard Worker R16 (F3, 5, 3, 4,11,16,23, 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
106*f6dc9357SAndroid Build Coastguard Worker 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
107*f6dc9357SAndroid Build Coastguard Worker 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
108*f6dc9357SAndroid Build Coastguard Worker 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665)
109*f6dc9357SAndroid Build Coastguard Worker R16 (F4, 0, 7, 6,10,15,21, 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
110*f6dc9357SAndroid Build Coastguard Worker 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
111*f6dc9357SAndroid Build Coastguard Worker 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
112*f6dc9357SAndroid Build Coastguard Worker 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391)
113*f6dc9357SAndroid Build Coastguard Worker
114*f6dc9357SAndroid Build Coastguard Worker a += state[0];
115*f6dc9357SAndroid Build Coastguard Worker b += state[1];
116*f6dc9357SAndroid Build Coastguard Worker c += state[2];
117*f6dc9357SAndroid Build Coastguard Worker d += state[3];
118*f6dc9357SAndroid Build Coastguard Worker
119*f6dc9357SAndroid Build Coastguard Worker state[0] = a;
120*f6dc9357SAndroid Build Coastguard Worker state[1] = b;
121*f6dc9357SAndroid Build Coastguard Worker state[2] = c;
122*f6dc9357SAndroid Build Coastguard Worker state[3] = d;
123*f6dc9357SAndroid Build Coastguard Worker
124*f6dc9357SAndroid Build Coastguard Worker data += MD5_BLOCK_SIZE;
125*f6dc9357SAndroid Build Coastguard Worker }
126*f6dc9357SAndroid Build Coastguard Worker while (--numBlocks);
127*f6dc9357SAndroid Build Coastguard Worker }
128*f6dc9357SAndroid Build Coastguard Worker
129*f6dc9357SAndroid Build Coastguard Worker
130*f6dc9357SAndroid Build Coastguard Worker #define Md5_UpdateBlock(p) MD5_UPDATE_BLOCKS(p)(p->state, p->buffer, 1)
131*f6dc9357SAndroid Build Coastguard Worker
Md5_Update(CMd5 * p,const Byte * data,size_t size)132*f6dc9357SAndroid Build Coastguard Worker void Md5_Update(CMd5 *p, const Byte *data, size_t size)
133*f6dc9357SAndroid Build Coastguard Worker {
134*f6dc9357SAndroid Build Coastguard Worker if (size == 0)
135*f6dc9357SAndroid Build Coastguard Worker return;
136*f6dc9357SAndroid Build Coastguard Worker {
137*f6dc9357SAndroid Build Coastguard Worker const unsigned pos = (unsigned)p->count & (MD5_BLOCK_SIZE - 1);
138*f6dc9357SAndroid Build Coastguard Worker const unsigned num = MD5_BLOCK_SIZE - pos;
139*f6dc9357SAndroid Build Coastguard Worker p->count += size;
140*f6dc9357SAndroid Build Coastguard Worker if (num > size)
141*f6dc9357SAndroid Build Coastguard Worker {
142*f6dc9357SAndroid Build Coastguard Worker memcpy(p->buffer + pos, data, size);
143*f6dc9357SAndroid Build Coastguard Worker return;
144*f6dc9357SAndroid Build Coastguard Worker }
145*f6dc9357SAndroid Build Coastguard Worker if (pos != 0)
146*f6dc9357SAndroid Build Coastguard Worker {
147*f6dc9357SAndroid Build Coastguard Worker size -= num;
148*f6dc9357SAndroid Build Coastguard Worker memcpy(p->buffer + pos, data, num);
149*f6dc9357SAndroid Build Coastguard Worker data += num;
150*f6dc9357SAndroid Build Coastguard Worker Md5_UpdateBlock(p);
151*f6dc9357SAndroid Build Coastguard Worker }
152*f6dc9357SAndroid Build Coastguard Worker }
153*f6dc9357SAndroid Build Coastguard Worker {
154*f6dc9357SAndroid Build Coastguard Worker const size_t numBlocks = size >> 6;
155*f6dc9357SAndroid Build Coastguard Worker if (numBlocks)
156*f6dc9357SAndroid Build Coastguard Worker MD5_UPDATE_BLOCKS(p)(p->state, data, numBlocks);
157*f6dc9357SAndroid Build Coastguard Worker size &= MD5_BLOCK_SIZE - 1;
158*f6dc9357SAndroid Build Coastguard Worker if (size == 0)
159*f6dc9357SAndroid Build Coastguard Worker return;
160*f6dc9357SAndroid Build Coastguard Worker data += (numBlocks << 6);
161*f6dc9357SAndroid Build Coastguard Worker memcpy(p->buffer, data, size);
162*f6dc9357SAndroid Build Coastguard Worker }
163*f6dc9357SAndroid Build Coastguard Worker }
164*f6dc9357SAndroid Build Coastguard Worker
165*f6dc9357SAndroid Build Coastguard Worker
Md5_Final(CMd5 * p,Byte * digest)166*f6dc9357SAndroid Build Coastguard Worker void Md5_Final(CMd5 *p, Byte *digest)
167*f6dc9357SAndroid Build Coastguard Worker {
168*f6dc9357SAndroid Build Coastguard Worker unsigned pos = (unsigned)p->count & (MD5_BLOCK_SIZE - 1);
169*f6dc9357SAndroid Build Coastguard Worker p->buffer[pos++] = 0x80;
170*f6dc9357SAndroid Build Coastguard Worker if (pos > (MD5_BLOCK_SIZE - 4 * 2))
171*f6dc9357SAndroid Build Coastguard Worker {
172*f6dc9357SAndroid Build Coastguard Worker while (pos != MD5_BLOCK_SIZE) { p->buffer[pos++] = 0; }
173*f6dc9357SAndroid Build Coastguard Worker // memset(&p->buf.buffer[pos], 0, MD5_BLOCK_SIZE - pos);
174*f6dc9357SAndroid Build Coastguard Worker Md5_UpdateBlock(p);
175*f6dc9357SAndroid Build Coastguard Worker pos = 0;
176*f6dc9357SAndroid Build Coastguard Worker }
177*f6dc9357SAndroid Build Coastguard Worker memset(&p->buffer[pos], 0, (MD5_BLOCK_SIZE - 4 * 2) - pos);
178*f6dc9357SAndroid Build Coastguard Worker {
179*f6dc9357SAndroid Build Coastguard Worker const UInt64 numBits = p->count << 3;
180*f6dc9357SAndroid Build Coastguard Worker #if defined(MY_CPU_LE_UNALIGN)
181*f6dc9357SAndroid Build Coastguard Worker SetUi64 (p->buffer + MD5_BLOCK_SIZE - 4 * 2, numBits)
182*f6dc9357SAndroid Build Coastguard Worker #else
183*f6dc9357SAndroid Build Coastguard Worker SetUi32a(p->buffer + MD5_BLOCK_SIZE - 4 * 2, (UInt32)(numBits))
184*f6dc9357SAndroid Build Coastguard Worker SetUi32a(p->buffer + MD5_BLOCK_SIZE - 4 * 1, (UInt32)(numBits >> 32))
185*f6dc9357SAndroid Build Coastguard Worker #endif
186*f6dc9357SAndroid Build Coastguard Worker }
187*f6dc9357SAndroid Build Coastguard Worker Md5_UpdateBlock(p);
188*f6dc9357SAndroid Build Coastguard Worker
189*f6dc9357SAndroid Build Coastguard Worker SetUi32(digest, p->state[0])
190*f6dc9357SAndroid Build Coastguard Worker SetUi32(digest + 4, p->state[1])
191*f6dc9357SAndroid Build Coastguard Worker SetUi32(digest + 8, p->state[2])
192*f6dc9357SAndroid Build Coastguard Worker SetUi32(digest + 12, p->state[3])
193*f6dc9357SAndroid Build Coastguard Worker
194*f6dc9357SAndroid Build Coastguard Worker Md5_Init(p);
195*f6dc9357SAndroid Build Coastguard Worker }
196*f6dc9357SAndroid Build Coastguard Worker
197*f6dc9357SAndroid Build Coastguard Worker #undef R1
198*f6dc9357SAndroid Build Coastguard Worker #undef R4
199*f6dc9357SAndroid Build Coastguard Worker #undef R16
200*f6dc9357SAndroid Build Coastguard Worker #undef D
201*f6dc9357SAndroid Build Coastguard Worker #undef LOAD_DATA
202*f6dc9357SAndroid Build Coastguard Worker #undef LOAD_data32_x4
203*f6dc9357SAndroid Build Coastguard Worker #undef F1
204*f6dc9357SAndroid Build Coastguard Worker #undef F2
205*f6dc9357SAndroid Build Coastguard Worker #undef F3
206*f6dc9357SAndroid Build Coastguard Worker #undef F4
207