~ubuntu-branches/ubuntu/natty/museek+/natty

« back to all changes in this revision

Viewing changes to museeq/Mucipher/md5.c

  • Committer: Bazaar Package Importer
  • Author(s): Adam Cécile (Le_Vert)
  • Date: 2007-09-07 22:44:15 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20070907224415-lpwy5zdp45pljd8i
Tags: 1:0.1.13+svn.20070907.r741-1
* New upstream release: fix implicitly converted pointers (FTBFS on ia64).
* Add an epoch to hijack old murmur package.
* Fix debian/watch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * This is an OpenSSL-compatible implementation of the RSA Data Security,
 
3
 * Inc. MD5 Message-Digest Algorithm.
 
4
 *
 
5
 * Written by Solar Designer <solar@openwall.com> in 2001, and placed in
 
6
 * the public domain.  There's absolutely no warranty.
 
7
 *
 
8
 * This differs from Colin Plumb's older public domain implementation in
 
9
 * that no 32-bit integer data type is required, there's no compile-time
 
10
 * endianness configuration, and the function prototypes match OpenSSL's.
 
11
 * The primary goals are portability and ease of use.
 
12
 *
 
13
 * This implementation is meant to be fast, but not as fast as possible.
 
14
 * Some known optimizations are not included to reduce source code size
 
15
 * and avoid compile-time configuration.
 
16
 */
 
17
 
 
18
#ifndef lint
 
19
static const char rcsid[] = "$Id: md5.c,v 1.4 2003/12/17 07:39:14 wcc Exp $";
 
20
#endif
 
21
 
 
22
#include <system.h>
 
23
#include "mucipher.h"
 
24
 
 
25
/* Any 32-bit or wider integer data type will do */
 
26
typedef unsigned long MD5_u32plus;
 
27
 
 
28
typedef struct {
 
29
        MD5_u32plus lo, hi;
 
30
        MD5_u32plus a, b, c, d;
 
31
        unsigned char buffer[64];
 
32
        MD5_u32plus block[16];
 
33
} MD5_CTX;
 
34
 
 
35
/*
 
36
 * The basic MD5 functions.
 
37
 *
 
38
 * F is optimized compared to its RFC 1321 definition just like in Colin
 
39
 * Plumb's implementation.
 
40
 */
 
41
#define F(x, y, z)                      ((z) ^ ((x) & ((y) ^ (z))))
 
42
#define G(x, y, z)                      ((y) ^ ((z) & ((x) ^ (y))))
 
43
#define H(x, y, z)                      ((x) ^ (y) ^ (z))
 
44
#define I(x, y, z)                      ((y) ^ ((x) | ~(z)))
 
45
 
 
46
/*
 
47
 * The MD5 transformation for all four rounds.
 
48
 */
 
49
#define STEP(f, a, b, c, d, x, t, s) \
 
50
        (a) += f((b), (c), (d)) + (x) + (t); \
 
51
        (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
 
52
        (a) += (b);
 
53
 
 
54
/*
 
55
 * SET reads 4 input bytes in little-endian byte order and stores them
 
56
 * in a properly aligned word in host byte order.
 
57
 *
 
58
 * The check for little-endian architectures which tolerate unaligned
 
59
 * memory accesses is just an optimization.  Nothing will break if it
 
60
 * doesn't work.
 
61
 */
 
62
#if defined(__i386__) || defined(__vax__)
 
63
#define SET(n) \
 
64
        (*(MD5_u32plus *)&ptr[(n) * 4])
 
65
#define GET(n) \
 
66
        SET(n)
 
67
#else
 
68
#define SET(n) \
 
69
        (ctx->block[(n)] = \
 
70
        (MD5_u32plus)ptr[(n) * 4] | \
 
71
        ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \
 
72
        ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \
 
73
        ((MD5_u32plus)ptr[(n) * 4 + 3] << 24))
 
74
#define GET(n) \
 
75
        (ctx->block[(n)])
 
76
#endif
 
77
 
 
78
/*
 
79
 * This processes one or more 64-byte data blocks, but does NOT update
 
80
 * the bit counters.  There're no alignment requirements.
 
81
 */
 
82
static const void *body(MD5_CTX *ctx, const void *data, unsigned long size)
 
83
{
 
84
        const unsigned char *ptr;
 
85
        MD5_u32plus a, b, c, d;
 
86
        MD5_u32plus saved_a, saved_b, saved_c, saved_d;
 
87
 
 
88
        ptr = data;
 
89
 
 
90
        a = ctx->a;
 
91
        b = ctx->b;
 
92
        c = ctx->c;
 
93
        d = ctx->d;
 
94
 
 
95
        do {
 
96
                saved_a = a;
 
97
                saved_b = b;
 
98
                saved_c = c;
 
99
                saved_d = d;
 
100
 
 
101
/* Round 1 */
 
102
                STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
 
103
                STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
 
104
                STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
 
105
                STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
 
106
                STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
 
107
                STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
 
108
                STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
 
109
                STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
 
110
                STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
 
111
                STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
 
112
                STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
 
113
                STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
 
114
                STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
 
115
                STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
 
116
                STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
 
117
                STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
 
118
 
 
119
/* Round 2 */
 
120
                STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
 
121
                STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
 
122
                STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
 
123
                STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
 
124
                STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
 
125
                STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
 
126
                STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
 
127
                STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
 
128
                STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
 
129
                STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
 
130
                STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
 
131
                STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
 
132
                STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
 
133
                STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
 
134
                STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
 
135
                STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
 
136
 
 
137
/* Round 3 */
 
138
                STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
 
139
                STEP(H, d, a, b, c, GET(8), 0x8771f681, 11)
 
140
                STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
 
141
                STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23)
 
142
                STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
 
143
                STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11)
 
144
                STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
 
145
                STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23)
 
146
                STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
 
147
                STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11)
 
148
                STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
 
149
                STEP(H, b, c, d, a, GET(6), 0x04881d05, 23)
 
150
                STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
 
151
                STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11)
 
152
                STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
 
153
                STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23)
 
154
 
 
155
/* Round 4 */
 
156
                STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
 
157
                STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
 
158
                STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
 
159
                STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
 
160
                STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
 
161
                STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
 
162
                STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
 
163
                STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
 
164
                STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
 
165
                STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
 
166
                STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
 
167
                STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
 
168
                STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
 
169
                STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
 
170
                STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
 
171
                STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
 
172
 
 
173
                a += saved_a;
 
174
                b += saved_b;
 
175
                c += saved_c;
 
176
                d += saved_d;
 
177
 
 
178
                ptr += 64;
 
179
        } while (size -= 64);
 
180
 
 
181
        ctx->a = a;
 
182
        ctx->b = b;
 
183
        ctx->c = c;
 
184
        ctx->d = d;
 
185
 
 
186
        return ptr;
 
187
}
 
188
 
 
189
static void MD5_Init(MD5_CTX *ctx)
 
190
{
 
191
        ctx->a = 0x67452301;
 
192
        ctx->b = 0xefcdab89;
 
193
        ctx->c = 0x98badcfe;
 
194
        ctx->d = 0x10325476;
 
195
 
 
196
        ctx->lo = 0;
 
197
        ctx->hi = 0;
 
198
}
 
199
 
 
200
static void MD5_Update(MD5_CTX *ctx, const void *_data, unsigned long size)
 
201
{
 
202
        MD5_u32plus saved_lo;
 
203
        unsigned long used, free;
 
204
        const unsigned char *data = _data;
 
205
        
 
206
        saved_lo = ctx->lo;
 
207
        if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo) ctx->hi++;
 
208
        ctx->hi += size >> 29;
 
209
 
 
210
        used = saved_lo & 0x3f;
 
211
 
 
212
        if (used) {
 
213
                free = 64 - used;
 
214
 
 
215
                if (size < free) {
 
216
                        memcpy(&ctx->buffer[used], data, size);
 
217
                        return;
 
218
                }
 
219
 
 
220
                memcpy(&ctx->buffer[used], data, free);
 
221
                data += free;
 
222
                size -= free;
 
223
                body(ctx, ctx->buffer, 64);
 
224
        }
 
225
 
 
226
        if (size >= 64) {
 
227
                data = body(ctx, data, size & ~(unsigned long)0x3f);
 
228
                size &= 0x3f;
 
229
        }
 
230
 
 
231
        memcpy(ctx->buffer, data, size);
 
232
}
 
233
 
 
234
static void MD5_Final(unsigned char *result, MD5_CTX *ctx)
 
235
{
 
236
        unsigned long used, free;
 
237
 
 
238
        used = ctx->lo & 0x3f;
 
239
 
 
240
        ctx->buffer[used++] = 0x80;
 
241
 
 
242
        free = 64 - used;
 
243
 
 
244
        if (free < 8) {
 
245
                memset(&ctx->buffer[used], 0, free);
 
246
                body(ctx, ctx->buffer, 64);
 
247
                used = 0;
 
248
                free = 64;
 
249
        }
 
250
 
 
251
        memset(&ctx->buffer[used], 0, free - 8);
 
252
 
 
253
        ctx->lo <<= 3;
 
254
        ctx->buffer[56] = ctx->lo;
 
255
        ctx->buffer[57] = ctx->lo >> 8;
 
256
        ctx->buffer[58] = ctx->lo >> 16;
 
257
        ctx->buffer[59] = ctx->lo >> 24;
 
258
        ctx->buffer[60] = ctx->hi;
 
259
        ctx->buffer[61] = ctx->hi >> 8;
 
260
        ctx->buffer[62] = ctx->hi >> 16;
 
261
        ctx->buffer[63] = ctx->hi >> 24;
 
262
 
 
263
        body(ctx, ctx->buffer, 64);
 
264
 
 
265
        result[0] = ctx->a;
 
266
        result[1] = ctx->a >> 8;
 
267
        result[2] = ctx->a >> 16;
 
268
        result[3] = ctx->a >> 24;
 
269
        result[4] = ctx->b;
 
270
        result[5] = ctx->b >> 8;
 
271
        result[6] = ctx->b >> 16;
 
272
        result[7] = ctx->b >> 24;
 
273
        result[8] = ctx->c;
 
274
        result[9] = ctx->c >> 8;
 
275
        result[10] = ctx->c >> 16;
 
276
        result[11] = ctx->c >> 24;
 
277
        result[12] = ctx->d;
 
278
        result[13] = ctx->d >> 8;
 
279
        result[14] = ctx->d >> 16;
 
280
        result[15] = ctx->d >> 24;
 
281
 
 
282
        memset(ctx, 0, sizeof(ctx));
 
283
}
 
284
 
 
285
void md5Block(unsigned char *dataIn, int len, unsigned char hashout[16]) {
 
286
  MD5_CTX ctx;
 
287
 
 
288
  MD5_Init(&ctx);
 
289
  MD5_Update(&ctx, dataIn, len);
 
290
  MD5_Final(hashout, &ctx);
 
291
}