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