]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/md5.c
update version
[bacula/bacula] / bacula / src / lib / md5.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2000-2011 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from
7    many others, a complete list can be found in the file AUTHORS.
8    This program is Free Software; you can redistribute it and/or
9    modify it under the terms of version three of the GNU Affero General Public
10    License as published by the Free Software Foundation and included
11    in the file LICENSE.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU Affero General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23    Bacula® is a registered trademark of Kern Sibbald.
24    The licensor of Bacula is the Free Software Foundation Europe
25    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26    Switzerland, email:ftf@fsfeurope.org.
27 */
28 /*
29  * This code implements the MD5 message-digest algorithm.
30  * The algorithm is due to Ron Rivest.  This code was
31  * written by Colin Plumb in 1993, no copyright is claimed.
32  * This code is in the public domain; do with it what you wish.
33  *
34  * Equivalent code is available from RSA Data Security, Inc.
35  * This code has been tested against that, and is equivalent,
36  * except that you don't need to include two pages of legalese
37  * with every copy.
38  *
39  * To compute the message digest of a chunk of bytes, declare an
40  * MD5Context structure, pass it to MD5Init, call MD5Update as
41  * needed on buffers full of bytes, and then call MD5Final, which
42  * will fill a supplied 16-byte array with the digest.
43  *
44  */
45
46 /* Brutally hacked by John Walker back from ANSI C to K&R (no
47    prototypes) to maintain the tradition that Netfone will compile
48    with Sun's original "cc". */
49
50
51
52 #include "bacula.h"
53
54 /*
55  * Note: this code is harmless on little-endian machines. We'll swap the bytes
56  * on big-endian machines.
57  */
58 void byteReverse(unsigned char *buf, unsigned longs)
59 {
60     uint32_t t;
61     if (bigendian()) {
62         do {
63             t = (uint32_t) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
64                 ((unsigned) buf[1] << 8 | buf[0]);
65             *(uint32_t *) buf = t;
66             buf += 4;
67         } while (--longs);
68     }
69 }
70
71 /*
72  * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
73  * initialization constants.
74  */
75 void MD5Init(struct MD5Context *ctx)
76 {
77     ctx->buf[0] = 0x67452301;
78     ctx->buf[1] = 0xefcdab89;
79     ctx->buf[2] = 0x98badcfe;
80     ctx->buf[3] = 0x10325476;
81
82     ctx->bits[0] = 0;
83     ctx->bits[1] = 0;
84 }
85
86 /*
87  * Update context to reflect the concatenation of another buffer full
88  * of bytes.
89  */
90 void MD5Update(struct MD5Context *ctx, unsigned char *buf, unsigned len)
91 {
92     uint32_t t;
93
94     /* Update bitcount */
95
96     t = ctx->bits[0];
97     if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t)
98         ctx->bits[1]++;         /* Carry from low to high */
99     ctx->bits[1] += len >> 29;
100
101     t = (t >> 3) & 0x3f;        /* Bytes already in shsInfo->data */
102
103     /* Handle any leading odd-sized chunks */
104
105     if (t) {
106         unsigned char *p = (unsigned char *) ctx->in + t;
107
108         t = 64 - t;
109         if (len < t) {
110             memcpy(p, buf, len);
111             return;
112         }
113         memcpy(p, buf, t);
114         byteReverse(ctx->in, 16);
115         MD5Transform(ctx->buf, (uint32_t *) ctx->in);
116         buf += t;
117         len -= t;
118     }
119     /* Process data in 64-byte chunks */
120
121     while (len >= 64) {
122         memcpy(ctx->in, buf, 64);
123         byteReverse(ctx->in, 16);
124         MD5Transform(ctx->buf, (uint32_t *) ctx->in);
125         buf += 64;
126         len -= 64;
127     }
128
129     /* Handle any remaining bytes of data. */
130
131     memcpy(ctx->in, buf, len);
132 }
133
134 /*
135  * Final wrapup - pad to 64-byte boundary with the bit pattern 
136  * 1 0* (64-bit count of bits processed, MSB-first)
137  */
138 void MD5Final(unsigned char digest[16], struct MD5Context *ctx)
139 {
140     unsigned count;
141     unsigned char *p;
142
143     /* Compute number of bytes mod 64 */
144     count = (ctx->bits[0] >> 3) & 0x3F;
145
146     /* Set the first char of padding to 0x80.  This is safe since there is
147        always at least one byte free */
148     p = ctx->in + count;
149     *p++ = 0x80;
150
151     /* Bytes of padding needed to make 64 bytes */
152     count = 64 - 1 - count;
153
154     /* Pad out to 56 mod 64 */
155     if (count < 8) {
156         /* Two lots of padding:  Pad the first block to 64 bytes */
157         memset(p, 0, count);
158         byteReverse(ctx->in, 16);
159         MD5Transform(ctx->buf, (uint32_t *) ctx->in);
160
161         /* Now fill the next block with 56 bytes */
162         memset(ctx->in, 0, 56);
163     } else {
164         /* Pad block to 56 bytes */
165         memset(p, 0, count - 8);
166     }
167     byteReverse(ctx->in, 14);
168
169     /* Append length in bits and transform */
170     ((uint32_t *) ctx->in)[14] = ctx->bits[0];
171     ((uint32_t *) ctx->in)[15] = ctx->bits[1];
172
173     MD5Transform(ctx->buf, (uint32_t *) ctx->in);
174     byteReverse((unsigned char *) ctx->buf, 4);
175     memcpy(digest, ctx->buf, 16);
176     memset(ctx, 0, sizeof(ctx));        /* In case it's sensitive */
177 }
178
179
180 /* The four core functions - F1 is optimized somewhat */
181
182 /* #define F1(x, y, z) (x & y | ~x & z) */
183 #define F1(x, y, z) (z ^ (x & (y ^ z)))
184 #define F2(x, y, z) F1(z, x, y)
185 #define F3(x, y, z) (x ^ y ^ z)
186 #define F4(x, y, z) (y ^ (x | ~z))
187
188 /* This is the central step in the MD5 algorithm. */
189 #define MD5STEP(f, w, x, y, z, data, s) \
190         ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
191
192 /*
193  * The core of the MD5 algorithm, this alters an existing MD5 hash to
194  * reflect the addition of 16 longwords of new data.  MD5Update blocks
195  * the data and converts bytes into longwords for this routine.
196  */
197 void MD5Transform(uint32_t buf[4], uint32_t in[16])
198 {
199     register uint32_t a, b, c, d;
200
201     a = buf[0];
202     b = buf[1];
203     c = buf[2];
204     d = buf[3];
205
206     MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
207     MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
208     MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
209     MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
210     MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
211     MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
212     MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
213     MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
214     MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
215     MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
216     MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
217     MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
218     MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
219     MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
220     MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
221     MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
222
223     MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
224     MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
225     MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
226     MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
227     MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
228     MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
229     MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
230     MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
231     MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
232     MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
233     MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
234     MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
235     MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
236     MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
237     MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
238     MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
239
240     MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
241     MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
242     MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
243     MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
244     MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
245     MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
246     MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
247     MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
248     MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
249     MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
250     MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
251     MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
252     MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
253     MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
254     MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
255     MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
256
257     MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
258     MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
259     MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
260     MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
261     MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
262     MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
263     MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
264     MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
265     MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
266     MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
267     MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
268     MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
269     MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
270     MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
271     MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
272     MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
273
274     buf[0] += a;
275     buf[1] += b;
276     buf[2] += c;
277     buf[3] += d;
278 }
279
280 #ifdef MD5_SUM
281 #define OUTPUT_BASE64 1
282
283 static void usage()
284 {
285    fprintf(stderr,
286 "\n"
287 "Usage: md5sum [-d decode] <data-file>\n"
288 "       -d          decode the data file\n"
289 "       -?          print this message.\n"
290 "\n\n");
291
292    exit(1);
293 }
294
295 static bool decode = false;
296
297 /*
298  * Reads a single ASCII file and prints the HEX md5 sum.
299  */
300 #include <stdio.h>
301 int main(int argc, char *argv[]) 
302 {
303    FILE *fd;
304    MD5Context ctx;
305    char buf[5000];
306    char signature[20];
307    int ch;
308
309    while ((ch = getopt(argc, argv, "d?")) != -1) {
310       switch (ch) {
311       case 'd':
312          decode = true;                
313          break;
314       case '?':
315       default:
316          usage();
317       }
318    }
319
320    argc -= optind;
321    argv += optind;
322
323    if (argc < 1) {
324       printf("Must have filename\n");
325       exit(1);
326    }
327
328    fd = fopen(argv[0], "rb");
329    if (!fd) {
330       printf("Could not open %s: ERR=%s\n", argv[0], strerror(errno));
331       exit(1);
332    }
333    if (decode) {
334       goto decode_it;
335    }
336    MD5Init(&ctx);
337    while (fgets(buf, sizeof(buf), fd)) {
338       MD5Update(&ctx, (unsigned char *)buf, strlen(buf));
339    }
340    MD5Final((unsigned char *)signature, &ctx);
341    for (int i=0; i < 16; i++) {
342       printf("%02x", signature[i]& 0xFF); 
343    }
344 #ifdef OUTPUT_BASE64
345    char MD5buf[40];                 /* 24 should do */ 
346    memset(MD5buf, 0, 40);
347    bin_to_base64(MD5buf, sizeof(MD5buf), (char *)signature, 16, true); /* encode 16 bytes */
348    printf("  %s", MD5buf);
349 #endif
350    printf("  %s\n", argv[0]);
351    exit(0);
352
353 decode_it:
354    while (fgets(buf, sizeof(buf), fd)) {
355       char bin[40];
356       unsigned char *p = (unsigned char *)buf;
357       unsigned char ch;
358       int val;
359       for (int i=0; i < 16; i++) {
360          if (*p <= '9') {
361             val = *p - '0';
362          } else {
363             val = *p - 'a' + 10;
364          }
365          ch = val << 4;
366          p++;
367          if (*p <= '9') {
368             val = *p - '0';
369          } else {
370             val = *p - 'a' + 10;
371          }
372          signature[i] = ch + val;
373          p++;
374       }
375       signature[16] = 0;
376       printf("%s", buf);
377       bin_to_base64(bin, sizeof(bin), (char *)signature, 16, true);
378       printf("%s\n", bin);
379    }
380    fclose(fd);
381 }
382 #endif