Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libsum/sum-md5.c
1808 views
1
#pragma prototyped
2
3
/*
4
* md5
5
*/
6
7
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
8
rights reserved.
9
10
License to copy and use this software is granted provided that it
11
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
12
Method" in all material mentioning or referencing this software
13
or this function.
14
15
License is also granted to make and use derivative works provided
16
that such works are identified as "derived from the RSA Data
17
Security, Inc. MD5 Message-Digest Method" in all material
18
mentioning or referencing the derived work.
19
20
RSA Data Security, Inc. makes no representations concerning either
21
the merchantability of this software or the suitability of this
22
software for any particular purpose. It is provided "as is"
23
without express or implied warranty of any kind.
24
25
These notices must be retained in any copies of any part of this
26
documentation and/or software.
27
*/
28
29
#define md5_description \
30
"The RSA Data Security, Inc. MD5 Message-Digest Method, 1991-2, \
31
used with permission. The block count is not printed."
32
#define md5_options "[+(version)?md5 (RSA Data Security, Inc. MD5 Message-Digest, 1991-2) 1996-02-29]"
33
#define md5_match "md5|MD5"
34
#define md5_scale 0
35
36
typedef uint32_t UINT4;
37
38
typedef struct Md5_s
39
{
40
_SUM_PUBLIC_
41
_SUM_PRIVATE_
42
UINT4 state[4]; /* state (ABCD) */
43
UINT4 count[2]; /* # bits handled mod 2^64 (lsb)*/
44
unsigned char buffer[64]; /* input buffer */
45
unsigned char digest[16]; /* final digest */
46
unsigned char digest_sum[16]; /* sum of all digests */
47
} Md5_t;
48
49
static const unsigned char md5_pad[] =
50
{
51
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
52
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
53
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
54
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
55
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
56
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
57
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
59
};
60
61
/*
62
* encode input into output
63
* len must be a multiple of 4
64
*/
65
66
static void
67
md5_encode(register unsigned char* output, register UINT4* input, unsigned int len)
68
{
69
register unsigned int i;
70
register unsigned int j;
71
72
for (i = j = 0; j < len; i++, j += 4)
73
{
74
output[j] = (unsigned char)(input[i] & 0xff);
75
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
76
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
77
output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
78
}
79
}
80
81
/*
82
* decode input into output
83
* len must be a multiple of 4
84
*/
85
86
static void
87
md5_decode(register UINT4* output, register unsigned char* input, unsigned int len)
88
{
89
unsigned int i;
90
unsigned int j;
91
92
for (i = j = 0; j < len; i++, j += 4)
93
output[i] = ((UINT4)input[j]) |
94
(((UINT4)input[j+1]) << 8) |
95
(((UINT4)input[j+2]) << 16) |
96
(((UINT4)input[j+3]) << 24);
97
}
98
99
static int
100
md5_init(Sum_t* p)
101
{
102
register Md5_t* context = (Md5_t*)p;
103
104
context->count[0] = context->count[1] = 0;
105
context->state[0] = 0x67452301;
106
context->state[1] = 0xefcdab89;
107
context->state[2] = 0x98badcfe;
108
context->state[3] = 0x10325476;
109
return 0;
110
}
111
112
static Sum_t*
113
md5_open(const Method_t* method, const char* name)
114
{
115
Md5_t* p;
116
117
if (p = newof(0, Md5_t, 1, 0))
118
{
119
p->method = (Method_t*)method;
120
p->name = name;
121
md5_init((Sum_t*)p);
122
}
123
return (Sum_t*)p;
124
}
125
126
/*
127
* basic MD5 step -- transforms buf based on in
128
*/
129
130
#define S11 7
131
#define S12 12
132
#define S13 17
133
#define S14 22
134
#define S21 5
135
#define S22 9
136
#define S23 14
137
#define S24 20
138
#define S31 4
139
#define S32 11
140
#define S33 16
141
#define S34 23
142
#define S41 6
143
#define S42 10
144
#define S43 15
145
#define S44 21
146
147
/* F, G, H and I are basic MD5 functions */
148
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
149
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
150
#define H(x, y, z) ((x) ^ (y) ^ (z))
151
#define I(x, y, z) ((y) ^ ((x) | (~z)))
152
153
/* ROTATE_LEFT rotates x left n bits */
154
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
155
156
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */
157
/* Rotation is separate from addition to prevent recomputation */
158
#define FF(a, b, c, d, x, s, ac) { \
159
(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
160
(a) = ROTATE_LEFT ((a), (s)); \
161
(a) += (b); \
162
}
163
#define GG(a, b, c, d, x, s, ac) { \
164
(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
165
(a) = ROTATE_LEFT ((a), (s)); \
166
(a) += (b); \
167
}
168
#define HH(a, b, c, d, x, s, ac) { \
169
(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
170
(a) = ROTATE_LEFT ((a), (s)); \
171
(a) += (b); \
172
}
173
#define II(a, b, c, d, x, s, ac) { \
174
(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
175
(a) = ROTATE_LEFT ((a), (s)); \
176
(a) += (b); \
177
}
178
179
static void
180
md5_transform(UINT4 state[4], unsigned char block[64])
181
{
182
UINT4 a = state[0];
183
UINT4 b = state[1];
184
UINT4 c = state[2];
185
UINT4 d = state[3];
186
UINT4 x[16];
187
188
md5_decode(x, block, 64);
189
190
/* round 1 */
191
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
192
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
193
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
194
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
195
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
196
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
197
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
198
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
199
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
200
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
201
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
202
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
203
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
204
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
205
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
206
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
207
208
/* round 2 */
209
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
210
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
211
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
212
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
213
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
214
GG (d, a, b, c, x[10], S22, 0x02441453); /* 22 */
215
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
216
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
217
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
218
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
219
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
220
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
221
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
222
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
223
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
224
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
225
226
/* round 3 */
227
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
228
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
229
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
230
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
231
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
232
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
233
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
234
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
235
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
236
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
237
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
238
HH (b, c, d, a, x[ 6], S34, 0x04881d05); /* 44 */
239
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
240
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
241
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
242
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
243
244
/* round 4 */
245
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
246
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
247
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
248
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
249
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
250
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
251
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
252
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
253
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
254
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
255
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
256
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
257
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
258
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
259
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
260
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
261
262
state[0] += a;
263
state[1] += b;
264
state[2] += c;
265
state[3] += d;
266
}
267
268
static int
269
md5_block(Sum_t* p, const void* s, size_t inputLen)
270
{
271
register Md5_t* context = (Md5_t*)p;
272
unsigned char* input = (unsigned char*)s;
273
unsigned int i;
274
unsigned int index;
275
unsigned int partLen;
276
277
/* compute number of bytes mod 64 */
278
index = (unsigned int)((context->count[0] >> 3) & 0x3f);
279
280
/* update number of bits */
281
if ((context->count[0] += ((UINT4)inputLen << 3)) < ((UINT4)inputLen << 3))
282
context->count[1]++;
283
context->count[1] += ((UINT4)inputLen >> 29);
284
partLen = 64 - index;
285
286
/* transform as many times as possible */
287
if (inputLen >= partLen)
288
{
289
memcpy(&context->buffer[index], input, partLen);
290
md5_transform(context->state, context->buffer);
291
for (i = partLen; i + 63 < inputLen; i += 64)
292
md5_transform(context->state, &input[i]);
293
index = 0;
294
}
295
else
296
i = 0;
297
298
/* buffer remaining input */
299
memcpy(&context->buffer[index], &input[i], inputLen - i);
300
301
return 0;
302
}
303
304
static int
305
md5_done(Sum_t* p)
306
{
307
register Md5_t* context = (Md5_t*)p;
308
unsigned char bits[8];
309
unsigned int index;
310
unsigned int padLen;
311
312
/* save number of bits */
313
md5_encode(bits, context->count, sizeof(bits));
314
315
/* pad out to 56 mod 64 */
316
index = (unsigned int)((context->count[0] >> 3) & 0x3f);
317
padLen = (index < 56) ? (56 - index) : (120 - index);
318
md5_block(p, md5_pad, padLen);
319
320
/* append length (before padding) */
321
md5_block(p, bits, sizeof(bits));
322
323
/* store state in digest */
324
md5_encode(context->digest, context->state, sizeof(context->digest));
325
326
/* accumulate the digests */
327
for (index = 0; index < elementsof(context->digest); index++)
328
context->digest_sum[index] ^= context->digest[index];
329
330
return 0;
331
}
332
333
static int
334
md5_print(Sum_t* p, Sfio_t* sp, register int flags, size_t scale)
335
{
336
register Md5_t* x = (Md5_t*)p;
337
register unsigned char* d;
338
register int n;
339
340
d = (flags & SUM_TOTAL) ? x->digest_sum : x->digest;
341
for (n = 0; n < elementsof(x->digest); n++)
342
sfprintf(sp, "%02x", d[n]);
343
return 0;
344
}
345
346
static int
347
md5_data(Sum_t* p, Sumdata_t* data)
348
{
349
register Md5_t* x = (Md5_t*)p;
350
351
data->size = elementsof(x->digest);
352
data->num = 0;
353
data->buf = x->digest;
354
return 0;
355
}
356
357