embox

Форк
0
389 строк · 12.1 Кб
1
/*
2
  Copyright (C) 1999, 2000, 2002 Aladdin Enterprises.  All rights reserved.
3

4
  This software is provided 'as-is', without any express or implied
5
  warranty.  In no event will the authors be held liable for any damages
6
  arising from the use of this software.
7

8
  Permission is granted to anyone to use this software for any purpose,
9
  including commercial applications, and to alter it and redistribute it
10
  freely, subject to the following restrictions:
11

12
  1. The origin of this software must not be misrepresented; you must not
13
     claim that you wrote the original software. If you use this software
14
     in a product, an acknowledgment in the product documentation would be
15
     appreciated but is not required.
16
  2. Altered source versions must be plainly marked as such, and must not be
17
     misrepresented as being the original software.
18
  3. This notice may not be removed or altered from any source distribution.
19

20
  L. Peter Deutsch
21
  ghost@aladdin.com
22

23
 */
24
/* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */
25
/*
26
  Independent implementation of MD5 (RFC 1321).
27

28
  This code implements the MD5 Algorithm defined in RFC 1321, whose
29
  text is available at
30
	http://www.ietf.org/rfc/rfc1321.txt
31
  The code is derived from the text of the RFC, including the test suite
32
  (section A.5) but excluding the rest of Appendix A.  It does not include
33
  any code or documentation that is identified in the RFC as being
34
  copyrighted.
35

36
  The original and principal author of md5.c is L. Peter Deutsch
37
  <ghost@aladdin.com>.  Other authors are noted in the change history
38
  that follows (in reverse chronological order):
39

40
  2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order
41
	either statically or dynamically; added missing #include <string.h>
42
	in library.
43
  2002-03-11 lpd Corrected argument list for main(), and added int return
44
	type, in test program and T value program.
45
  2002-02-21 lpd Added missing #include <stdio.h> in test program.
46
  2000-07-03 lpd Patched to eliminate warnings about "constant is
47
	unsigned in ANSI C, signed in traditional"; made test program
48
	self-checking.
49
  1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
50
  1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
51
  1999-05-03 lpd Original version.
52
 */
53

54
#include <string.h>
55
#include <endian.h>
56

57
#include <lib/crypt/md5.h>
58

59
/* 1 = big-endian, -1 = little-endian, 0 = unknown */
60
#if  __BYTE_ORDER == __BIG_ENDIAN
61
#  define MD5_BYTE_ORDER 1
62
#elif  __BYTE_ORDER == __LITTLE_ENDIAN
63
#  define MD5_BYTE_ORDER -1
64
#else
65
#  define MD5_BYTE_ORDER 0
66
#endif
67

68
#define T_MASK ((md5_word_t)~0)
69
#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
70
#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
71
#define T3    0x242070db
72
#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
73
#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
74
#define T6    0x4787c62a
75
#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
76
#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
77
#define T9    0x698098d8
78
#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
79
#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
80
#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
81
#define T13    0x6b901122
82
#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
83
#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
84
#define T16    0x49b40821
85
#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
86
#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
87
#define T19    0x265e5a51
88
#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
89
#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
90
#define T22    0x02441453
91
#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
92
#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
93
#define T25    0x21e1cde6
94
#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
95
#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
96
#define T28    0x455a14ed
97
#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
98
#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
99
#define T31    0x676f02d9
100
#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
101
#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
102
#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
103
#define T35    0x6d9d6122
104
#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
105
#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
106
#define T38    0x4bdecfa9
107
#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
108
#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
109
#define T41    0x289b7ec6
110
#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
111
#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
112
#define T44    0x04881d05
113
#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
114
#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
115
#define T47    0x1fa27cf8
116
#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
117
#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
118
#define T50    0x432aff97
119
#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
120
#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
121
#define T53    0x655b59c3
122
#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
123
#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
124
#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
125
#define T57    0x6fa87e4f
126
#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
127
#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
128
#define T60    0x4e0811a1
129
#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
130
#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
131
#define T63    0x2ad7d2bb
132
#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
133

134
md5_byte_t *md5_count(const md5_byte_t *ptr, size_t n, md5_byte_t digest[16]) {
135
	md5_state_t state;
136
	md5_init(&state);
137
	md5_append(&state, ptr, n);
138
	md5_finish(&state, digest);
139
	return digest;
140
}
141

142
static void md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/) {
143
	md5_word_t a = pms->abcd[0], b = pms->abcd[1], c = pms->abcd[2], d =
144
			pms->abcd[3];
145
	md5_word_t t;
146
#if MD5_BYTE_ORDER > 0
147
	/* Define storage only for big-endian CPUs. */
148
	md5_word_t X[16];
149
#else
150
	/* Define storage for little-endian or both types of CPUs. */
151
	md5_word_t xbuf[16];
152
	const md5_word_t *X;
153
#endif
154

155
	{
156
#if MD5_BYTE_ORDER == 0
157
		/*
158
		 * Determine dynamically whether this is a big-endian or
159
		 * little-endian machine, since we can use a more efficient
160
		 * algorithm on the latter.
161
		 */
162
		static const int w = 1;
163

164
		if (*((const md5_byte_t *)&w)) /* dynamic little-endian */
165
#endif
166
#if MD5_BYTE_ORDER <= 0		/* little-endian */
167
		{
168
			/*
169
			 * On little-endian machines, we can process properly aligned
170
			 * data without copying it.
171
			 */
172
			if (!((data - (const md5_byte_t *) 0) & 3)) {
173
				/* data are properly aligned */
174
				X = (const md5_word_t *) data;
175
			} else {
176
				/* not aligned */
177
				memcpy(xbuf, data, 64);
178
				X = xbuf;
179
			}
180
		}
181
#endif
182
#if MD5_BYTE_ORDER == 0
183
		else /* dynamic big-endian */
184
#endif
185
#if MD5_BYTE_ORDER >= 0		/* big-endian */
186
		{
187
			/*
188
			 * On big-endian machines, we must arrange the bytes in the
189
			 * right order.
190
			 */
191
			const md5_byte_t *xp = data;
192
			int i;
193

194
#  if MD5_BYTE_ORDER == 0
195
			X = xbuf; /* (dynamic only) */
196
#  else
197
#    define xbuf X		/* (static only) */
198
#  endif
199
			for (i = 0; i < 16; ++i, xp += 4)
200
			xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
201
		}
202
#endif
203
	}
204

205
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
206

207
	/* Round 1. */
208
	/* Let [abcd k s i] denote the operation
209
	 * a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
210
#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
211
#define SET(a, b, c, d, k, s, Ti)\
212
	t = a + F(b,c,d) + X[k] + Ti;\
213
	a = ROTATE_LEFT(t, s) + b
214
	/* Do the following 16 operations. */
215
	SET(a, b, c, d,  0,  7,  T1);
216
	SET(d, a, b, c,  1, 12,  T2);
217
	SET(c, d, a, b,  2, 17,  T3);
218
	SET(b, c, d, a,  3, 22,  T4);
219
	SET(a, b, c, d,  4,  7,  T5);
220
	SET(d, a, b, c,  5, 12,  T6);
221
	SET(c, d, a, b,  6, 17,  T7);
222
	SET(b, c, d, a,  7, 22,  T8);
223
	SET(a, b, c, d,  8,  7,  T9);
224
	SET(d, a, b, c,  9, 12, T10);
225
	SET(c, d, a, b, 10, 17, T11);
226
	SET(b, c, d, a, 11, 22, T12);
227
	SET(a, b, c, d, 12,  7, T13);
228
	SET(d, a, b, c, 13, 12, T14);
229
	SET(c, d, a, b, 14, 17, T15);
230
	SET(b, c, d, a, 15, 22, T16);
231
#undef SET
232

233
	/* Round 2. */
234
	/* Let [abcd k s i] denote the operation
235
	 * a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
236
#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
237
#define SET(a, b, c, d, k, s, Ti)\
238
	t = a + G(b,c,d) + X[k] + Ti;\
239
	a = ROTATE_LEFT(t, s) + b
240
	/* Do the following 16 operations. */
241
	SET(a, b, c, d,  1,  5, T17);
242
	SET(d, a, b, c,  6,  9, T18);
243
	SET(c, d, a, b, 11, 14, T19);
244
	SET(b, c, d, a,  0, 20, T20);
245
	SET(a, b, c, d,  5,  5, T21);
246
	SET(d, a, b, c, 10,  9, T22);
247
	SET(c, d, a, b, 15, 14, T23);
248
	SET(b, c, d, a,  4, 20, T24);
249
	SET(a, b, c, d,  9,  5, T25);
250
	SET(d, a, b, c, 14,  9, T26);
251
	SET(c, d, a, b,  3, 14, T27);
252
	SET(b, c, d, a,  8, 20, T28);
253
	SET(a, b, c, d, 13,  5, T29);
254
	SET(d, a, b, c,  2,  9, T30);
255
	SET(c, d, a, b,  7, 14, T31);
256
	SET(b, c, d, a, 12, 20, T32);
257
#undef SET
258

259
	/* Round 3. */
260
	/* Let [abcd k s t] denote the operation
261
	 * a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
262
#define H(x, y, z) ((x) ^ (y) ^ (z))
263
#define SET(a, b, c, d, k, s, Ti)\
264
	t = a + H(b,c,d) + X[k] + Ti;\
265
	a = ROTATE_LEFT(t, s) + b
266
	/* Do the following 16 operations. */
267
	SET(a, b, c, d,  5,  4, T33);
268
	SET(d, a, b, c,  8, 11, T34);
269
	SET(c, d, a, b, 11, 16, T35);
270
	SET(b, c, d, a, 14, 23, T36);
271
	SET(a, b, c, d,  1,  4, T37);
272
	SET(d, a, b, c,  4, 11, T38);
273
	SET(c, d, a, b,  7, 16, T39);
274
	SET(b, c, d, a, 10, 23, T40);
275
	SET(a, b, c, d, 13,  4, T41);
276
	SET(d, a, b, c,  0, 11, T42);
277
	SET(c, d, a, b,  3, 16, T43);
278
	SET(b, c, d, a,  6, 23, T44);
279
	SET(a, b, c, d,  9,  4, T45);
280
	SET(d, a, b, c, 12, 11, T46);
281
	SET(c, d, a, b, 15, 16, T47);
282
	SET(b, c, d, a,  2, 23, T48);
283
#undef SET
284

285
	/* Round 4. */
286
	/* Let [abcd k s t] denote the operation
287
	 * a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
288
#define I(x, y, z) ((y) ^ ((x) | ~(z)))
289
#define SET(a, b, c, d, k, s, Ti)\
290
	t = a + I(b,c,d) + X[k] + Ti;\
291
	a = ROTATE_LEFT(t, s) + b
292
	/* Do the following 16 operations. */
293
	SET(a, b, c, d,  0,  6, T49);
294
	SET(d, a, b, c,  7, 10, T50);
295
	SET(c, d, a, b, 14, 15, T51);
296
	SET(b, c, d, a,  5, 21, T52);
297
	SET(a, b, c, d, 12,  6, T53);
298
	SET(d, a, b, c,  3, 10, T54);
299
	SET(c, d, a, b, 10, 15, T55);
300
	SET(b, c, d, a,  1, 21, T56);
301
	SET(a, b, c, d,  8,  6, T57);
302
	SET(d, a, b, c, 15, 10, T58);
303
	SET(c, d, a, b,  6, 15, T59);
304
	SET(b, c, d, a, 13, 21, T60);
305
	SET(a, b, c, d,  4,  6, T61);
306
	SET(d, a, b, c, 11, 10, T62);
307
	SET(c, d, a, b,  2, 15, T63);
308
	SET(b, c, d, a,  9, 21, T64);
309
#undef SET
310

311
	/* Then perform the following additions. (That is increment each
312
	 * of the four registers by the value it had before this block
313
	 * was started.) */
314
	pms->abcd[0] += a;
315
	pms->abcd[1] += b;
316
	pms->abcd[2] += c;
317
	pms->abcd[3] += d;
318
}
319

320
void md5_init(md5_state_t *pms) {
321
	pms->count[0] = pms->count[1] = 0;
322
	pms->abcd[0] = 0x67452301;
323
	pms->abcd[1] = T_MASK ^ 0x10325476; /*0xefcdab89*/
324
	pms->abcd[2] = T_MASK ^ 0x67452301; /*0x98badcfe*/
325
	pms->abcd[3] = 0x10325476;
326
}
327

328
void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes) {
329
	const md5_byte_t *p = data;
330
	int left = nbytes;
331
	int offset = (pms->count[0] >> 3) & 63;
332
	md5_word_t nbits = (md5_word_t) (nbytes << 3);
333

334
	if (nbytes <= 0) {
335
		return;
336
	}
337

338
	/* Update the message length. */
339
	pms->count[1] += nbytes >> 29;
340
	pms->count[0] += nbits;
341
	if (pms->count[0] < nbits) {
342
		pms->count[1]++;
343
	}
344

345
	/* Process an initial partial block. */
346
	if (offset) {
347
		int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
348

349
		memcpy(pms->buf + offset, p, copy);
350
		if (offset + copy < 64)
351
			return;
352
		p += copy;
353
		left -= copy;
354
		md5_process(pms, pms->buf);
355
	}
356

357
	/* Process full blocks. */
358
	for (; left >= 64; p += 64, left -= 64) {
359
		md5_process(pms, p);
360
	}
361

362
	/* Process a final partial block. */
363
	if (left) {
364
		memcpy(pms->buf, p, left);
365
	}
366
}
367

368
void md5_finish(md5_state_t *pms, md5_byte_t digest[16]) {
369
	static const md5_byte_t pad[64] = {
370
			0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
371
			   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
372
			   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
373
			   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
374
		};
375
	md5_byte_t data[8];
376
	int i;
377

378
	/* Save the length before padding. */
379
	for (i = 0; i < 8; ++i) {
380
		data[i] = (md5_byte_t) (pms->count[i >> 2] >> ((i & 3) << 3));
381
	}
382
	/* Pad to 56 bytes mod 64. */
383
	md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
384
	/* Append the length. */
385
	md5_append(pms, data, 8);
386
	for (i = 0; i < 16; ++i) {
387
		digest[i] = (md5_byte_t) (pms->abcd[i >> 2] >> ((i & 3) << 3));
388
	}
389
}
390

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.