Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
7643 views
1
/*
2
MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
3
4
Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991.
5
All rights reserved.
6
7
License to copy and use this software is granted provided that it
8
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
9
Algorithm" in all material mentioning or referencing this software
10
or this function.
11
12
License is also granted to make and use derivative works provided
13
that such works are identified as "derived from the RSA Data
14
Security, Inc. MD5 Message-Digest Algorithm" in all material
15
mentioning or referencing the derived work.
16
17
RSA Data Security, Inc. makes no representations concerning either
18
the merchantability of this software or the suitability of this
19
software for any particular purpose. It is provided "as is"
20
without express or implied warranty of any kind.
21
22
These notices must be retained in any copies of any part of this
23
documentation and/or software.
24
*/
25
26
#include "mupdf/fitz.h"
27
28
/* Constants for MD5Transform routine */
29
enum
30
{
31
S11 = 7, S12 = 12, S13 = 17, S14 = 22,
32
S21 = 5, S22 = 9, S23 = 14, S24 = 20,
33
S31 = 4, S32 = 11, S33 = 16, S34 = 23,
34
S41 = 6, S42 = 10, S43 = 15, S44 = 21
35
};
36
37
static void encode(unsigned char *, const unsigned int *, const unsigned);
38
static void decode(unsigned int *, const unsigned char *, const unsigned);
39
static void transform(unsigned int state[4], const unsigned char block[64]);
40
41
static unsigned char padding[64] =
42
{
43
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
44
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
45
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
46
};
47
48
/* F, G, H and I are basic MD5 functions */
49
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
50
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
51
#define H(x, y, z) ((x) ^ (y) ^ (z))
52
#define I(x, y, z) ((y) ^ ((x) | (~z)))
53
54
/* ROTATE rotates x left n bits */
55
#define ROTATE(x, n) (((x) << (n)) | ((x) >> (32-(n))))
56
57
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
58
* Rotation is separate from addition to prevent recomputation.
59
*/
60
#define FF(a, b, c, d, x, s, ac) { \
61
(a) += F ((b), (c), (d)) + (x) + (unsigned int)(ac); \
62
(a) = ROTATE ((a), (s)); \
63
(a) += (b); \
64
}
65
#define GG(a, b, c, d, x, s, ac) { \
66
(a) += G ((b), (c), (d)) + (x) + (unsigned int)(ac); \
67
(a) = ROTATE ((a), (s)); \
68
(a) += (b); \
69
}
70
#define HH(a, b, c, d, x, s, ac) { \
71
(a) += H ((b), (c), (d)) + (x) + (unsigned int)(ac); \
72
(a) = ROTATE ((a), (s)); \
73
(a) += (b); \
74
}
75
#define II(a, b, c, d, x, s, ac) { \
76
(a) += I ((b), (c), (d)) + (x) + (unsigned int)(ac); \
77
(a) = ROTATE ((a), (s)); \
78
(a) += (b); \
79
}
80
81
static void encode(unsigned char *output, const unsigned int *input, const unsigned len)
82
{
83
unsigned i, j;
84
85
for (i = 0, j = 0; j < len; i++, j += 4)
86
{
87
output[j] = (unsigned char)(input[i] & 0xff);
88
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
89
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
90
output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
91
}
92
}
93
94
static void decode(unsigned int *output, const unsigned char *input, const unsigned len)
95
{
96
unsigned i, j;
97
98
for (i = 0, j = 0; j < len; i++, j += 4)
99
{
100
output[i] = ((unsigned int)input[j]) |
101
(((unsigned int)input[j+1]) << 8) |
102
(((unsigned int)input[j+2]) << 16) |
103
(((unsigned int)input[j+3]) << 24);
104
}
105
}
106
107
static void transform(unsigned int state[4], const unsigned char block[64])
108
{
109
unsigned int a = state[0];
110
unsigned int b = state[1];
111
unsigned int c = state[2];
112
unsigned int d = state[3];
113
unsigned int x[16];
114
115
decode(x, block, 64);
116
117
/* Round 1 */
118
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
119
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
120
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
121
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
122
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
123
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
124
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
125
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
126
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
127
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
128
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
129
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
130
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
131
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
132
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
133
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
134
135
/* Round 2 */
136
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
137
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
138
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
139
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
140
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
141
GG (d, a, b, c, x[10], S22, 0x02441453); /* 22 */
142
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
143
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
144
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
145
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
146
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
147
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
148
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
149
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
150
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
151
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
152
153
/* Round 3 */
154
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
155
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
156
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
157
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
158
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
159
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
160
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
161
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
162
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
163
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
164
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
165
HH (b, c, d, a, x[ 6], S34, 0x04881d05); /* 44 */
166
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
167
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
168
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
169
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
170
171
/* Round 4 */
172
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
173
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
174
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
175
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
176
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
177
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
178
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
179
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
180
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
181
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
182
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
183
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
184
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
185
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
186
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
187
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
188
189
state[0] += a;
190
state[1] += b;
191
state[2] += c;
192
state[3] += d;
193
194
/* Zeroize sensitive information */
195
memset(x, 0, sizeof (x));
196
}
197
198
/* MD5 initialization. Begins an MD5 operation, writing a new context. */
199
void fz_md5_init(fz_md5 *context)
200
{
201
context->count[0] = context->count[1] = 0;
202
203
/* Load magic initialization constants */
204
context->state[0] = 0x67452301;
205
context->state[1] = 0xefcdab89;
206
context->state[2] = 0x98badcfe;
207
context->state[3] = 0x10325476;
208
}
209
210
/* MD5 block update operation. Continues an MD5 message-digest operation,
211
* processing another message block, and updating the context.
212
*/
213
void fz_md5_update(fz_md5 *context, const unsigned char *input, unsigned inlen)
214
{
215
unsigned i, index, partlen;
216
217
/* Compute number of bytes mod 64 */
218
index = (unsigned)((context->count[0] >> 3) & 0x3F);
219
220
/* Update number of bits */
221
context->count[0] += (unsigned int) inlen << 3;
222
if (context->count[0] < (unsigned int) inlen << 3)
223
context->count[1] ++;
224
context->count[1] += (unsigned int) inlen >> 29;
225
226
partlen = 64 - index;
227
228
/* Transform as many times as possible. */
229
if (inlen >= partlen)
230
{
231
memcpy(context->buffer + index, input, partlen);
232
transform(context->state, context->buffer);
233
234
for (i = partlen; i + 63 < inlen; i += 64)
235
transform(context->state, input + i);
236
237
index = 0;
238
}
239
else
240
{
241
i = 0;
242
}
243
244
/* Buffer remaining input */
245
memcpy(context->buffer + index, input + i, inlen - i);
246
}
247
248
/* MD5 finalization. Ends an MD5 message-digest operation, writing the
249
* the message digest and zeroizing the context.
250
*/
251
void fz_md5_final(fz_md5 *context, unsigned char digest[16])
252
{
253
unsigned char bits[8];
254
unsigned index, padlen;
255
256
/* Save number of bits */
257
encode(bits, context->count, 8);
258
259
/* Pad out to 56 mod 64 */
260
index = (unsigned)((context->count[0] >> 3) & 0x3f);
261
padlen = index < 56 ? 56 - index : 120 - index;
262
fz_md5_update(context, padding, padlen);
263
264
/* Append length (before padding) */
265
fz_md5_update(context, bits, 8);
266
267
/* Store state in digest */
268
encode(digest, context->state, 16);
269
270
/* Zeroize sensitive information */
271
memset(context, 0, sizeof(fz_md5));
272
}
273
274