Annotation of embedaddon/bird/lib/md5.c, revision 1.1.1.1
1.1 misho 1: /*
2: * BIRD Library -- MD5 Hash Function and HMAC-MD5 Function
3: *
4: * (c) 2015 CZ.NIC z.s.p.o.
5: *
6: * The code was written by Colin Plumb in 1993, no copyright is claimed.
7: *
8: * Adapted for BIRD by Martin Mares <mj@ucw.cz>
9: *
10: * Can be freely distributed and used under the terms of the GNU GPL.
11: */
12:
13: #include "lib/md5.h"
14:
15: #ifdef CPU_LITTLE_ENDIAN
16: #define byteReverse(buf, len) /* Nothing */
17: #else
18: void byteReverse(byte *buf, uint longs);
19:
20: /*
21: * Note: this code is harmless on little-endian machines.
22: */
23: void byteReverse(byte *buf, uint longs)
24: {
25: u32 t;
26: do {
27: t = (u32) ((uint) buf[3] << 8 | buf[2]) << 16 |
28: ((uint) buf[1] << 8 | buf[0]);
29: *(u32 *) buf = t;
30: buf += 4;
31: } while (--longs);
32: }
33: #endif
34:
35: static void md5_transform(u32 buf[4], u32 const in[16]);
36:
37: /*
38: * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
39: * initialization constants.
40: */
41: void
42: md5_init(struct hash_context *CTX)
43: {
44: struct md5_context *ctx = (void *) CTX;
45:
46: ctx->buf[0] = 0x67452301;
47: ctx->buf[1] = 0xefcdab89;
48: ctx->buf[2] = 0x98badcfe;
49: ctx->buf[3] = 0x10325476;
50:
51: ctx->bits[0] = 0;
52: ctx->bits[1] = 0;
53: }
54:
55: /*
56: * Update context to reflect the concatenation of another buffer full
57: * of bytes.
58: */
59: void
60: md5_update(struct hash_context *CTX, const byte *buf, uint len)
61: {
62: struct md5_context *ctx = (void *) CTX;
63: u32 t;
64:
65: /* Update bitcount */
66:
67: t = ctx->bits[0];
68: if ((ctx->bits[0] = t + ((u32) len << 3)) < t)
69: ctx->bits[1]++; /* Carry from low to high */
70: ctx->bits[1] += len >> 29;
71:
72: t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
73:
74: /* Handle any leading odd-sized chunks */
75: if (t)
76: {
77: byte *p = (byte *) ctx->in + t;
78:
79: t = 64 - t;
80: if (len < t)
81: {
82: memcpy(p, buf, len);
83: return;
84: }
85: memcpy(p, buf, t);
86: byteReverse(ctx->in, 16);
87: md5_transform(ctx->buf, (u32 *) ctx->in);
88: buf += t;
89: len -= t;
90: }
91:
92: /* Process data in 64-byte chunks */
93: while (len >= 64)
94: {
95: memcpy(ctx->in, buf, 64);
96: byteReverse(ctx->in, 16);
97: md5_transform(ctx->buf, (u32 *) ctx->in);
98: buf += 64;
99: len -= 64;
100: }
101:
102: /* Handle any remaining bytes of data. */
103: memcpy(ctx->in, buf, len);
104: }
105:
106: /*
107: * Final wrapup - pad to 64-byte boundary with the bit pattern
108: * 1 0* (64-bit count of bits processed, MSB-first)
109: */
110: byte *
111: md5_final(struct hash_context *CTX)
112: {
113: struct md5_context *ctx = (void *) CTX;
114: uint count;
115: byte *p;
116:
117: /* Compute number of bytes mod 64 */
118: count = (ctx->bits[0] >> 3) & 0x3F;
119:
120: /* Set the first char of padding to 0x80. This is safe since there is
121: always at least one byte free */
122: p = ctx->in + count;
123: *p++ = 0x80;
124:
125: /* Bytes of padding needed to make 64 bytes */
126: count = 64 - 1 - count;
127:
128: /* Pad out to 56 mod 64 */
129: if (count < 8)
130: {
131: /* Two lots of padding: Pad the first block to 64 bytes */
132: memset(p, 0, count);
133: byteReverse(ctx->in, 16);
134: md5_transform(ctx->buf, (u32 *) ctx->in);
135:
136: /* Now fill the next block with 56 bytes */
137: memset(ctx->in, 0, 56);
138: }
139: else
140: {
141: /* Pad block to 56 bytes */
142: memset(p, 0, count - 8);
143: }
144: byteReverse(ctx->in, 14);
145:
146: /* Append length in bits and transform */
147: ((u32 *) ctx->in)[14] = ctx->bits[0];
148: ((u32 *) ctx->in)[15] = ctx->bits[1];
149:
150: md5_transform(ctx->buf, (u32 *) ctx->in);
151: byteReverse((byte *) ctx->buf, 4);
152:
153: return (byte*) ctx->buf;
154: }
155:
156: /* The four core functions - F1 is optimized somewhat */
157:
158: /* #define F1(x, y, z) (x & y | ~x & z) */
159: #define F1(x, y, z) (z ^ (x & (y ^ z)))
160: #define F2(x, y, z) F1(z, x, y)
161: #define F3(x, y, z) (x ^ y ^ z)
162: #define F4(x, y, z) (y ^ (x | ~z))
163:
164: /* This is the central step in the MD5 algorithm. */
165: #define MD5STEP(f, w, x, y, z, data, s) \
166: ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
167:
168: /*
169: * The core of the MD5 algorithm, this alters an existing MD5 hash to
170: * reflect the addition of 16 longwords of new data. MD5Update blocks
171: * the data and converts bytes into longwords for this routine.
172: */
173: void
174: md5_transform(u32 buf[4], u32 const in[16])
175: {
176: register u32 a, b, c, d;
177:
178: a = buf[0];
179: b = buf[1];
180: c = buf[2];
181: d = buf[3];
182:
183: MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
184: MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
185: MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
186: MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
187: MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
188: MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
189: MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
190: MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
191: MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
192: MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
193: MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
194: MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
195: MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
196: MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
197: MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
198: MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
199:
200: MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
201: MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
202: MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
203: MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
204: MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
205: MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
206: MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
207: MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
208: MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
209: MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
210: MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
211: MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
212: MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
213: MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
214: MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
215: MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
216:
217: MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
218: MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
219: MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
220: MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
221: MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
222: MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
223: MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
224: MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
225: MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
226: MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
227: MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
228: MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
229: MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
230: MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
231: MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
232: MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
233:
234: MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
235: MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
236: MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
237: MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
238: MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
239: MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
240: MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
241: MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
242: MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
243: MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
244: MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
245: MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
246: MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
247: MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
248: MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
249: MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
250:
251: buf[0] += a;
252: buf[1] += b;
253: buf[2] += c;
254: buf[3] += d;
255: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>