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