1 /*	$OpenBSD: md5.c,v 1.32 2004/12/29 17:32:44 millert Exp $	*/
2 /*	$OpenBSD: crc.c,v 1.2 2004/05/10 19:48:07 deraadt Exp $	*/
3 /*	$OpenBSD: crc.h,v 1.1 2004/05/02 17:53:29 millert Exp $	*/
4 
5 /*
6  * Copyright (c) 2001, 2003, 2004 Todd C. Miller <Todd.Miller@courtesan.com>
7  *
8  * Permission to use, copy, modify, and distribute this software for any
9  * purpose with or without fee is hereby granted, provided that the above
10  * copyright notice and this permission notice appear in all copies.
11  *
12  * Sponsored in part by the Defense Advanced Research Projects
13  * Agency (DARPA) and Air Force Research Laboratory, Air Force
14  * Materiel Command, USAF, under agreement number F39502-99-1-0512.
15  */
16 
17 /*-
18  * Copyright (c) 2007, 2009, 2011, 2014
19  *	Thorsten Glaser <tg@mirbsd.org>
20  *
21  * Provided that these terms and disclaimer and all copyright notices
22  * are retained or reproduced in an accompanying document, permission
23  * is granted to deal in this work without restriction, including un-
24  * limited rights to use, publicly perform, distribute, sell, modify,
25  * merge, give away, or sublicence.
26  *
27  * This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to
28  * the utmost extent permitted by applicable law, neither express nor
29  * implied; without malicious intent or gross negligence. In no event
30  * may a licensor, author or contributor be held liable for indirect,
31  * direct, other damage, loss, or other issues arising in any way out
32  * of dealing in the work, even if advised of the possibility of such
33  * damage or existence of a defect, except proven that it results out
34  * of said person's immediate fault when using the work as intended.
35  */
36 
37 #include <sys/param.h>
38 #include <sys/time.h>
39 #include <ctype.h>
40 #include <err.h>
41 #include <errno.h>
42 #include <fcntl.h>
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <time.h>
47 #include <unistd.h>
48 
49 #include <adler32.h>
50 #include <md4.h>
51 #include <md5.h>
52 #include <rmd160.h>
53 #include <sfv.h>
54 #include <sha1.h>
55 #include <sha2.h>
56 #include <suma.h>
57 #include <tiger.h>
58 #include <whirlpool.h>
59 
60 #ifdef __MirBSD__
61 /* for OAAT1S; XXX drop this long-term */
62 extern const uint8_t RFC1321_padding[64];
63 #endif
64 
65 __RCSID("$MirOS: src/bin/md5/cksum.c,v 1.18 2014/02/19 17:15:10 tg Exp $");
66 
67 #define MAX_DIGEST_LEN			128
68 
69 #define	CKSUM_DIGEST_LENGTH		4
70 #define	CKSUM_DIGEST_STRING_LENGTH	(10 + 1 + 19)
71 
72 typedef struct CKSUMContext {
73 	uint32_t crc;
74 	off_t len;
75 } CKSUM_CTX;
76 
77 #define	SUM_DIGEST_LENGTH		4
78 typedef CKSUM_CTX SUM_CTX;
79 
80 #define	SYSVSUM_DIGEST_LENGTH		4
81 typedef CKSUM_CTX SYSVSUM_CTX;
82 
83 typedef uint32_t BAFH_CTX;
84 typedef uint32_t CDB_CTX;
85 typedef uint32_t NZAT_CTX;
86 typedef uint64_t SIZE_CTX;
87 
88 typedef CKSUM_CTX OAATS_CTX;
89 
90 union ANY_CTX {
91 	CKSUM_CTX cksum;
92 	MD4_CTX md4;
93 	MD5_CTX md5;
94 	RMD160_CTX rmd160;
95 	SHA1_CTX sha1;
96 	SHA256_CTX sha256;
97 	SHA384_CTX sha384;
98 	SHA512_CTX sha512;
99 	SUM_CTX sum;
100 	SYSVSUM_CTX sysvsum;
101 	SUMA_CTX suma;
102 	ADLER32_CTX adler32;
103 	SFV_CTX sfv;
104 	TIGER_CTX tiger;
105 	WHIRLPOOL_CTX whirlpool;
106 	SIZE_CTX size;
107 	CDB_CTX cdb;
108 	OAATS_CTX oaats;
109 	NZAT_CTX nzat;
110 	BAFH_CTX bafh;
111 };
112 
113 void digest_print(const char *, const char *, const char *);
114 void digest_print_short(const char *, const char *, const char *);
115 void digest_print_string(const char *, const char *, const char *);
116 void digest_print_sfv(const char *, const char *, const char *);
117 void digest_printbin_pad(const char *);
118 void digest_printbin_string(const char *);
119 void digest_printbin_stringle(const char *);
120 void cksum_addpool(const char *) __attribute__((__nonnull__(1)));
121 
122 char *ucase_End(uint32_t *, char *);
123 char *ulld_End(CKSUM_CTX *, char *);
124 
125 void SIZE_Init(SIZE_CTX *);
126 void SIZE_Update(SIZE_CTX *, const uint8_t *, size_t);
127 char *SIZE_End(SIZE_CTX *, char *);
128 
129 void CDB_Init(CDB_CTX *);
130 void CDB_Update(CDB_CTX *, const uint8_t *, size_t);
131 #define CDB_End ucase_End
132 
133 #define CKSUM_Init OAAT_Init
134 void CKSUM_Update(CKSUM_CTX *, const u_int8_t *, size_t);
135 void CKSUM_Final(CKSUM_CTX *);
136 char *CKSUM_End(CKSUM_CTX *, char *);
137 char *CKSUM_Data(const u_int8_t *, size_t, char *);
138 
139 void OAAT_Init(OAATS_CTX *);
140 void OAAT1_Init(OAATS_CTX *);
141 void OAAT_Update(OAATS_CTX *, const uint8_t *, size_t);
142 void OAAT_Final(OAATS_CTX *);
143 char *OAAT_End(OAATS_CTX *, char *);
144 #ifdef __MirBSD__
145 char *OAAT1S_End(OAATS_CTX *, char *);
146 #endif
147 
148 void NZAT_Init(NZAT_CTX *);
149 void NZAT_Update(NZAT_CTX *, const uint8_t *, size_t);
150 void NZAT_Final(NZAT_CTX *);
151 void NZAAT_Final(NZAT_CTX *);
152 char *NZAT_End(NZAT_CTX *, char *);
153 char *NZAAT_End(NZAT_CTX *, char *);
154 
155 #define BAFH_Init NZAT_Init
156 #define BAFH_Update NZAT_Update
157 char *BAFH_End(BAFH_CTX *, char *);
158 
159 #define SUM_Init OAAT_Init
160 void SUM_Update(SUM_CTX *, const u_int8_t *, size_t);
161 void SUM_Final(SUM_CTX *);
162 char *SUM_End(SUM_CTX *, char *);
163 char *SUM_Data(const u_int8_t *, size_t, char *);
164 
165 #define SYSVSUM_Init OAAT_Init
166 void SYSVSUM_Update(SYSVSUM_CTX *, const u_int8_t *, size_t);
167 void SYSVSUM_Final(SYSVSUM_CTX *);
168 char *SYSVSUM_End(SYSVSUM_CTX *, char *);
169 char *SYSVSUM_Data(const u_int8_t *, size_t, char *);
170 
171 /* when adding, change lines with context matching NHASHMOD */
172 
173 /* NHASHMOD: total number of hash functions */
174 #ifdef __MirBSD__
175 #define NHASHES	23
176 #else
177 #define NHASHES	22
178 #endif
179 struct hash_functions {
180 	const char *name;
181 	size_t digestlen;
182 	void *ctx;	/* XXX - only used by digest_file() */
183 	void (*init)(void *);
184 	void (*update)(void *, const unsigned char *, unsigned int);
185 	char * (*end)(void *, char *);
186 	void (*printbin)(const char *);
187 	void (*print)(const char *, const char *, const char *);
188 	void (*printstr)(const char *, const char *, const char *);
189 } functions[NHASHES + 1] = {
190 	{
191 		"CKSUM",
192 		CKSUM_DIGEST_LENGTH * 2,
193 		NULL,
194 		(void (*)(void *))CKSUM_Init,
195 		(void (*)(void *, const unsigned char *, unsigned int))CKSUM_Update,
196 		(char *(*)(void *, char *))CKSUM_End,
197 		digest_printbin_pad,
198 		digest_print_short,
199 		digest_print_short
200 	}, {
201 		"SUM",
202 		SUM_DIGEST_LENGTH * 2,
203 		NULL,
204 		(void (*)(void *))SUM_Init,
205 		(void (*)(void *, const unsigned char *, unsigned int))SUM_Update,
206 		(char *(*)(void *, char *))SUM_End,
207 		digest_printbin_pad,
208 		digest_print_short,
209 		digest_print_short
210 	}, {
211 		"SYSVSUM",
212 		SYSVSUM_DIGEST_LENGTH * 2,
213 		NULL,
214 		(void (*)(void *))SYSVSUM_Init,
215 		(void (*)(void *, const unsigned char *, unsigned int))SYSVSUM_Update,
216 		(char *(*)(void *, char *))SYSVSUM_End,
217 		digest_printbin_pad,
218 		digest_print_short,
219 		digest_print_short
220 	}, {
221 		"ADLER32",
222 		ADLER32_DIGEST_LENGTH * 2,
223 		NULL,
224 		(void (*)(void *))ADLER32Init,
225 		(void (*)(void *, const unsigned char *, unsigned int))ADLER32Update,
226 		(char *(*)(void *, char *))ADLER32End,
227 		digest_printbin_string,
228 		digest_print,
229 		digest_print_string
230 	}, {
231 		"BAFH",
232 		8,
233 		NULL,
234 		(void (*)(void *))BAFH_Init,
235 		(void (*)(void *, const unsigned char *, unsigned int))BAFH_Update,
236 		(char *(*)(void *, char *))BAFH_End,
237 		digest_printbin_stringle,
238 		digest_print,
239 		digest_print_string
240 	}, {
241 		"CDB",
242 		8,
243 		NULL,
244 		(void (*)(void *))CDB_Init,
245 		(void (*)(void *, const unsigned char *, unsigned int))CDB_Update,
246 		(char *(*)(void *, char *))CDB_End,
247 		digest_printbin_stringle,
248 		digest_print,
249 		digest_print_string
250 	}, {
251 		"NZAT",
252 		8,
253 		NULL,
254 		(void (*)(void *))NZAT_Init,
255 		(void (*)(void *, const unsigned char *, unsigned int))NZAT_Update,
256 		(char *(*)(void *, char *))NZAT_End,
257 		digest_printbin_stringle,
258 		digest_print,
259 		digest_print_string
260 	}, {
261 		"NZAAT",
262 		8,
263 		NULL,
264 		(void (*)(void *))NZAT_Init,
265 		(void (*)(void *, const unsigned char *, unsigned int))NZAT_Update,
266 		(char *(*)(void *, char *))NZAAT_End,
267 		digest_printbin_stringle,
268 		digest_print,
269 		digest_print_string
270 	}, {
271 		"OAAT",
272 		8,
273 		NULL,
274 		(void (*)(void *))OAAT_Init,
275 		(void (*)(void *, const unsigned char *, unsigned int))OAAT_Update,
276 		(char *(*)(void *, char *))OAAT_End,
277 		digest_printbin_stringle,
278 		digest_print,
279 		digest_print_string
280 	}, {
281 		"OAAT1",
282 		8,
283 		NULL,
284 		(void (*)(void *))OAAT1_Init,
285 		(void (*)(void *, const unsigned char *, unsigned int))OAAT_Update,
286 		(char *(*)(void *, char *))OAAT_End,
287 		digest_printbin_stringle,
288 		digest_print,
289 		digest_print_string
290 	}, {
291 #ifdef __MirBSD__
292 		"OAAT1S",
293 		8,
294 		NULL,
295 		(void (*)(void *))OAAT1_Init,
296 		(void (*)(void *, const unsigned char *, unsigned int))OAAT_Update,
297 		(char *(*)(void *, char *))OAAT1S_End,
298 		digest_printbin_stringle,
299 		digest_print,
300 		digest_print_string
301 	}, {
302 #endif
303 		"SUMA",
304 		SUMA_DIGEST_LENGTH * 2,
305 		NULL,
306 		(void (*)(void *))SUMAInit,
307 		(void (*)(void *, const unsigned char *, unsigned int))SUMAUpdate,
308 		(char *(*)(void *, char *))SUMAEnd,
309 		digest_printbin_stringle,
310 		digest_print,
311 		digest_print_string
312 	}, {
313 		"SFV",
314 		SFV_DIGEST_LENGTH * 2,
315 		NULL,
316 		(void (*)(void *))SFVInit,
317 		(void (*)(void *, const unsigned char *, unsigned int))SFVUpdate,
318 		(char *(*)(void *, char *))SFVEnd,
319 		digest_printbin_stringle,
320 		digest_print_sfv,
321 		digest_print_sfv
322 	}, {
323 		"SIZE",
324 		16,
325 		NULL,
326 		(void (*)(void *))SIZE_Init,
327 		(void (*)(void *, const unsigned char *, unsigned int))SIZE_Update,
328 		(char *(*)(void *, char *))SIZE_End,
329 		digest_printbin_pad,
330 		digest_print,
331 		digest_print_string
332 	},
333 	/* NHASHMOD: non-GNU functions above, GNU functions below */
334 #ifdef __MirBSD__
335 #define NHASHES_NONGNU	14
336 #else
337 #define NHASHES_NONGNU	13
338 #endif
339 
340 	{
341 		"MD4",
342 		MD4_DIGEST_LENGTH * 2,
343 		NULL,
344 		(void (*)(void *))MD4Init,
345 		(void (*)(void *, const unsigned char *, unsigned int))MD4Update,
346 		(char *(*)(void *, char *))MD4End,
347 		digest_printbin_string,
348 		digest_print,
349 		digest_print_string
350 	}, {
351 		"MD5",
352 		MD5_DIGEST_LENGTH * 2,
353 		NULL,
354 		(void (*)(void *))MD5Init,
355 		(void (*)(void *, const unsigned char *, unsigned int))MD5Update,
356 		(char *(*)(void *, char *))MD5End,
357 		digest_printbin_string,
358 		digest_print,
359 		digest_print_string
360 	}, {
361 		"RMD160",
362 		RMD160_DIGEST_LENGTH * 2,
363 		NULL,
364 		(void (*)(void *))RMD160Init,
365 		(void (*)(void *, const unsigned char *, unsigned int))RMD160Update,
366 		(char *(*)(void *, char *))RMD160End,
367 		digest_printbin_string,
368 		digest_print,
369 		digest_print_string
370 	}, {
371 		"SHA1",
372 		SHA1_DIGEST_LENGTH * 2,
373 		NULL,
374 		(void (*)(void *))SHA1Init,
375 		(void (*)(void *, const unsigned char *, unsigned int))SHA1Update,
376 		(char *(*)(void *, char *))SHA1End,
377 		digest_printbin_string,
378 		digest_print,
379 		digest_print_string
380 	}, {
381 		"SHA256",
382 		SHA256_DIGEST_LENGTH * 2,
383 		NULL,
384 		(void (*)(void *))SHA256_Init,
385 		(void (*)(void *, const unsigned char *, unsigned int))SHA256_Update,
386 		(char *(*)(void *, char *))SHA256_End,
387 		digest_printbin_string,
388 		digest_print,
389 		digest_print_string
390 	}, {
391 		"SHA384",
392 		SHA384_DIGEST_LENGTH * 2,
393 		NULL,
394 		(void (*)(void *))SHA384_Init,
395 		(void (*)(void *, const unsigned char *, unsigned int))SHA384_Update,
396 		(char *(*)(void *, char *))SHA384_End,
397 		digest_printbin_string,
398 		digest_print,
399 		digest_print_string
400 	}, {
401 		"SHA512",
402 		SHA512_DIGEST_LENGTH * 2,
403 		NULL,
404 		(void (*)(void *))SHA512_Init,
405 		(void (*)(void *, const unsigned char *, unsigned int))SHA512_Update,
406 		(char *(*)(void *, char *))SHA512_End,
407 		digest_printbin_string,
408 		digest_print,
409 		digest_print_string
410 	}, {
411 		"TIGER",
412 		TIGER_DIGEST_LENGTH * 2,
413 		NULL,
414 		(void (*)(void *))TIGERInit,
415 		(void (*)(void *, const unsigned char *, unsigned int))TIGERUpdate,
416 		(char *(*)(void *, char *))TIGEREnd,
417 		digest_printbin_string,
418 		digest_print,
419 		digest_print_string
420 	}, {
421 		"WHIRLPOOL",
422 		WHIRLPOOL_DIGEST_LENGTH * 2,
423 		NULL,
424 		(void (*)(void *))WHIRLPOOLInit,
425 		(void (*)(void *, const unsigned char *, unsigned int))WHIRLPOOLUpdate,
426 		(char *(*)(void *, char *))WHIRLPOOLEnd,
427 		digest_printbin_string,
428 		digest_print,
429 		digest_print_string
430 	}, {
431 		NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL
432 	},
433 };
434 
435 __dead void usage(void);
436 void digest_file(const char *, struct hash_functions **, int, int, int);
437 int digest_filelist(const char *, struct hash_functions *);
438 void digest_string(char *, struct hash_functions **, int);
439 void digest_test(struct hash_functions **);
440 void digest_time(struct hash_functions **);
441 
442 extern const char *__progname;
443 
444 int
main(int argc,char ** argv)445 main(int argc, char **argv)
446 {
447 	struct hash_functions *hf = NULL, *hashes[NHASHES + 1];
448 	int fl, i, error;
449 	int cflag, pflag, tflag, xflag, bflag, gnuflag;
450 	char *cp, *input_string;
451 
452 	input_string = NULL;
453 	error = cflag = pflag = tflag = xflag = bflag = gnuflag = 0;
454 	memset(hashes, 0, sizeof(hashes));
455 	while ((fl = getopt(argc, argv, "a:bcGo:ps:tx")) != -1) {
456 		switch (fl) {
457 		case 'a':
458 			while ((cp = strsep(&optarg, " \t,")) != NULL) {
459 				if (*cp == '\0')
460 					continue;
461 				for (hf = functions; hf->name != NULL; hf++)
462 					if (strcasecmp(hf->name, cp) == 0)
463 						break;
464 				if (hf->name == NULL) {
465 					warnx("unknown algorithm \"%s\"", cp);
466 					usage();
467 				}
468 				for (i = 0; i < NHASHES && hashes[i] != hf; i++)
469 					if (hashes[i] == NULL) {
470 						hashes[i] = hf;
471 						break;
472 					}
473 			}
474 			break;
475 		case 'b':
476 			bflag = 1;
477 			break;
478 		case 'c':
479 			cflag = 1;
480 			break;
481 		case 'G':
482 			gnuflag = 1;
483 			break;
484 		case 'o':
485 			if (strcmp(optarg, "1") == 0)
486 				hf = &functions[1];
487 			else if (strcmp(optarg, "2") == 0)
488 				hf = &functions[2];
489 			else {
490 				warnx("illegal argument to -o option");
491 				usage();
492 			}
493 			for (i = 0; i < NHASHES && hashes[i] != hf; i++) {
494 				if (hashes[i] == NULL) {
495 					hashes[i] = hf;
496 					break;
497 				}
498 			}
499 			break;
500 		case 'p':
501 			pflag = 1;
502 			break;
503 		case 's':
504 			input_string = optarg;
505 			break;
506 		case 't':
507 			tflag = 1;
508 			break;
509 		case 'x':
510 			xflag = 1;
511 			break;
512 		default:
513 			usage();
514 		}
515 	}
516 	argc -= optind;
517 	argv += optind;
518 
519 	/* Most arguments are mutually exclusive */
520 	fl = pflag + tflag + xflag + cflag + (input_string != NULL) +
521 	    bflag - (bflag & (pflag || input_string != NULL));
522 	if (fl > 1 || (fl && argc && cflag == 0 && bflag == 0) ||
523 	    (gnuflag && fl))
524 		usage();
525 	if (cflag != 0 && hashes[1] != NULL)
526 		errx(1, "only a single algorithm may be specified in -c mode");
527 
528 	/* No algorithm specified, check the name we were called as. */
529 	if (hashes[0] == NULL) {
530 		char *progname2;
531 
532 		if ((progname2 = strdup(__progname)) == NULL)
533 			err(1, "out of memory");
534 		if (strlen(progname2) > 3) {
535 			cp = progname2 + strlen(progname2) - 3;
536 			if (strcasecmp(cp, "sum") == 0) {
537 				gnuflag |= 2;
538 				*cp = '\0';
539 			}
540 		}
541 
542 		for (hf = functions; hf->name != NULL; hf++) {
543 			if ((gnuflag & 2) &&
544 			    strcasecmp(hf->name, __progname) == 0) {
545 				gnuflag &= ~2;
546 				hashes[0] = hf;
547 				break;
548 			} else if (strcasecmp(hf->name, progname2) == 0) {
549 				hashes[0] = hf;
550 				break;
551 			}
552 		}
553 		if (hashes[0] == NULL)
554 			hashes[0] = &functions[0];	/* default to cksum */
555 		if (gnuflag & 2) {
556 			if (cflag || pflag || input_string || xflag) {
557 				fprintf(stderr,
558 				    "usage: %s [-b] [-t] [file ...]\n"
559 				    "note: GNU syntax -c and -w are not supported.\n",
560 				    __progname);
561 				__progname = progname2;
562 				usage();
563 			}
564 			bflag = 0;
565 			tflag = 0;
566 		}
567 		free(progname2);
568 	}
569 
570 	if (tflag)
571 		digest_time(hashes);
572 	else if (xflag)
573 		digest_test(hashes);
574 	else if (input_string)
575 		digest_string(input_string, hashes, bflag);
576 	else if (cflag) {
577 		if (argc == 0)
578 			error = digest_filelist("-", hashes[0]);
579 		else
580 			while (argc--)
581 				error += digest_filelist(*argv++, hashes[0]);
582 	} else if (pflag || argc == 0)
583 		digest_file("-", hashes, pflag, bflag, gnuflag);
584 	else
585 		while (argc--)
586 			digest_file(*argv++, hashes, 0, bflag, gnuflag);
587 
588 	return(error ? EXIT_FAILURE : EXIT_SUCCESS);
589 }
590 
591 void
digest_string(char * string,struct hash_functions ** hashes,int dobin)592 digest_string(char *string, struct hash_functions **hashes, int dobin)
593 {
594 	struct hash_functions *hf;
595 	char digest[MAX_DIGEST_LEN + 1];
596 	union ANY_CTX context;
597 
598 	while (*hashes != NULL) {
599 		hf = *hashes++;
600 		hf->init(&context);
601 		hf->update(&context, (const unsigned char *)string,
602 		    (unsigned int)strlen(string));
603 		(void)hf->end(&context, digest);
604 		cksum_addpool(digest);
605 		if (dobin)
606 			hf->printbin(digest);
607 		else
608 			hf->printstr(hf->name, string, digest);
609 	}
610 }
611 
612 void
digest_print(const char * name,const char * what,const char * digest)613 digest_print(const char *name, const char *what, const char *digest)
614 {
615 	(void)printf("%s (%s) = %s\n", name, what, digest);
616 }
617 
618 void
digest_print_string(const char * name,const char * what,const char * digest)619 digest_print_string(const char *name, const char *what, const char *digest)
620 {
621 	(void)printf("%s (\"%s\") = %s\n", name, what, digest);
622 }
623 
624 void
digest_print_short(const char * name,const char * what,const char * digest)625 digest_print_short(const char *name __attribute__((__unused__)),
626     const char *what, const char *digest)
627 {
628 	(void)printf("%s %s\n", digest, what);
629 }
630 
631 void
digest_print_sfv(const char * name,const char * what,const char * digest)632 digest_print_sfv(const char *name __attribute__((__unused__)),
633     const char *what, const char *digest)
634 
635 {
636 	(void)printf("%s %s\n", what, digest);
637 }
638 
639 void
digest_file(const char * file,struct hash_functions ** hashes,int echo,int dobin,int dognu)640 digest_file(const char *file, struct hash_functions **hashes, int echo,
641     int dobin, int dognu)
642 {
643 	struct hash_functions **hfp;
644 	int fd;
645 	ssize_t nread;
646 	u_char data[BUFSIZ];
647 	char digest[MAX_DIGEST_LEN + 1];
648 
649 	if (strcmp(file, "-") == 0)
650 		fd = STDIN_FILENO;
651 	else if ((fd = open(file, O_RDONLY, 0)) == -1) {
652 		warn("cannot open %s", file);
653 		return;
654 	}
655 
656 	if (echo)
657 		fflush(stdout);
658 
659 	for (hfp = hashes; *hfp != NULL; hfp++) {
660 		if (((*hfp)->ctx = malloc(sizeof(union ANY_CTX))) == NULL)
661 			err(1, NULL);
662 		(*hfp)->init((*hfp)->ctx);
663 	}
664 	while ((nread = read(fd, data, sizeof(data))) > 0) {
665 		if (echo)
666 			write(STDOUT_FILENO, data, (size_t)nread);
667 		for (hfp = hashes; *hfp != NULL; hfp++)
668 			(*hfp)->update((*hfp)->ctx, data, (unsigned int)nread);
669 	}
670 	if (nread == -1) {
671 		warn("%s: read error", file);
672 		if (fd != STDIN_FILENO)
673 			close(fd);
674 		return;
675 	}
676 	if (fd != STDIN_FILENO)
677 		close(fd);
678 	for (hfp = hashes; *hfp != NULL; hfp++) {
679 		(void)(*hfp)->end((*hfp)->ctx, digest);
680 		free((*hfp)->ctx);
681 		cksum_addpool(digest);
682 		if (dobin)
683 			(*hfp)->printbin(digest);
684 		else if (dognu)
685 			printf("%s  %s\n", digest,
686 			    fd == STDIN_FILENO ? "-" : file);
687 		else if (fd == STDIN_FILENO)
688 			(void)puts(digest);
689 		else
690 			(*hfp)->print((*hfp)->name, file, digest);
691 	}
692 }
693 
694 /*
695  * Parse through the input file looking for valid lines.
696  * If one is found, use this checksum and file as a reference and
697  * generate a new checksum against the file on the filesystem.
698  * Print out the result of each comparison.
699  */
700 int
digest_filelist(const char * file,struct hash_functions * defhash)701 digest_filelist(const char *file, struct hash_functions *defhash)
702 {
703 	int fd, found, error;
704 	unsigned int algorithm_max, algorithm_min;
705 	const char *algorithm;
706 	char *filename, *checksum, *buf, *p;
707 	char digest[MAX_DIGEST_LEN + 1];
708 	char *lbuf = NULL;
709 	FILE *fp;
710 	ssize_t nread;
711 	size_t len;
712 	u_char data[BUFSIZ];
713 	union ANY_CTX context;
714 	struct hash_functions *hf;
715 
716 	if (strcmp(file, "-") == 0) {
717 		fp = stdin;
718 	} else if ((fp = fopen(file, "r")) == NULL) {
719 		warn("cannot open %s", file);
720 		return(1);
721 	}
722 
723 	/* NHASHMOD: first GNU style function (and list below) */
724 	if (defhash < &functions[NHASHES_NONGNU])
725 		/*
726 		 * no GNU format for cksum, sum, sysvsum, adler32, cdb,
727 		 * bafh, nzat, nzaat, oaat, oaat1, oaat1s, suma, sfv, size
728 		 */
729 		defhash = NULL;
730 
731 	algorithm_max = algorithm_min = strlen(functions[0].name);
732 	for (hf = &functions[1]; hf->name != NULL; hf++) {
733 		len = strlen(hf->name);
734 		algorithm_max = MAX(algorithm_max, len);
735 		algorithm_min = MIN(algorithm_min, len);
736 	}
737 
738 	error = found = 0;
739 	while ((buf = fgetln(fp, &len))) {
740 		if (buf[len - 1] == '\n')
741 			buf[len - 1] = '\0';
742 		else {
743 			if ((lbuf = malloc(len + 1)) == NULL)
744 				err(1, NULL);
745 
746 			(void)memcpy(lbuf, buf, len);
747 			lbuf[len] = '\0';
748 			buf = lbuf;
749 		}
750 		while (isspace(*buf))
751 			buf++;
752 
753 		/*
754 		 * Crack the line into an algorithm, filename, and checksum.
755 		 * Lines are of the form:
756 		 *  ALGORITHM (FILENAME) = CHECKSUM
757 		 *
758 		 * Fallback on GNU form:
759 		 *  CHECKSUM  FILENAME
760 		 */
761 		p = strchr(buf, ' ');
762 		if (p != NULL && *(p + 1) == '(') {
763 			/* BSD form */
764 			*p = '\0';
765 			algorithm = buf;
766 			len = strlen(algorithm);
767 			if (len > algorithm_max || len < algorithm_min)
768 				continue;
769 
770 			filename = p + 2;
771 			p = strrchr(filename, ')');
772 			if (p == NULL || strncmp(p + 1, " = ", (size_t)3) != 0)
773 				continue;
774 			*p = '\0';
775 
776 			checksum = p + 4;
777 			p = strpbrk(checksum, " \t\r");
778 			if (p != NULL)
779 				*p = '\0';
780 
781 			/*
782 			 * Check that the algorithm is one we recognize.
783 			 */
784 			for (hf = functions; hf->name != NULL; hf++) {
785 				if (strcmp(algorithm, hf->name) == 0)
786 					break;
787 			}
788 			if (hf->name == NULL ||
789 			    strlen(checksum) != hf->digestlen)
790 				continue;
791 		} else {
792 			/* could be GNU form */
793 			if ((hf = defhash) == NULL)
794 				continue;
795 			algorithm = hf->name;
796 			checksum = buf;
797 			if ((p = strchr(checksum, ' ')) == NULL)
798 				continue;
799 			*p++ = '\0';
800 			while (isspace(*p))
801 				p++;
802 			if (*p == '\0')
803 				continue;
804 			filename = p;
805 			p = strpbrk(filename, "\t\r");
806 			if (p != NULL)
807 				*p = '\0';
808 		}
809 
810 		if ((fd = open(filename, O_RDONLY, 0)) == -1) {
811 			warn("cannot open %s", filename);
812 			(void)printf("(%s) %s: FAILED\n", algorithm, filename);
813 			error = 1;
814 			continue;
815 		}
816 
817 		found = 1;
818 		hf->init(&context);
819 		while ((nread = read(fd, data, sizeof(data))) > 0)
820 			hf->update(&context, data, (unsigned int)nread);
821 		if (nread == -1) {
822 			warn("%s: read error", file);
823 			error = 1;
824 			close(fd);
825 			continue;
826 		}
827 		close(fd);
828 		(void)hf->end(&context, digest);
829 		cksum_addpool(digest);
830 
831 		if (strcmp(checksum, digest) == 0)
832 			(void)printf("(%s) %s: OK\n", algorithm, filename);
833 		else
834 			(void)printf("(%s) %s: FAILED\n", algorithm, filename);
835 	}
836 	if (fp != stdin)
837 		fclose(fp);
838 	if (!found)
839 		warnx("%s: no properly formatted checksum lines found", file);
840 	if (lbuf != NULL)
841 		free(lbuf);
842 	return(error || !found);
843 }
844 
845 #define TEST_BLOCK_LEN 10000
846 #define TEST_BLOCK_COUNT 10000
847 
848 #ifndef timersub
849 #define timersub(tvp, uvp, vvp)                                         \
850         do {                                                            \
851                 (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec;          \
852                 (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec;       \
853                 if ((vvp)->tv_usec < 0) {                               \
854                         (vvp)->tv_sec--;                                \
855                         (vvp)->tv_usec += 1000000;                      \
856                 }                                                       \
857         } while (0)
858 #endif
859 
860 void
digest_time(struct hash_functions ** hashes)861 digest_time(struct hash_functions **hashes)
862 {
863 	struct hash_functions *hf;
864 	struct timeval start, stop, res;
865 	union ANY_CTX context;
866 	unsigned i;
867 	u_char data[TEST_BLOCK_LEN];
868 	char digest[MAX_DIGEST_LEN + 1];
869 	double elapsed;
870 
871 	while (*hashes != NULL) {
872 		hf = *hashes++;
873 		(void)printf("%s time trial.  Processing %d %d-byte blocks...",
874 		    hf->name, TEST_BLOCK_COUNT, TEST_BLOCK_LEN);
875 		fflush(stdout);
876 
877 		/* Initialize data based on block number. */
878 		for (i = 0; i < TEST_BLOCK_LEN; i++)
879 			data[i] = (u_char)(i & 0xff);
880 
881 		gettimeofday(&start, NULL);
882 		hf->init(&context);
883 		for (i = 0; i < TEST_BLOCK_COUNT; i++)
884 			hf->update(&context, data, TEST_BLOCK_LEN);
885 		(void)hf->end(&context, digest);
886 		gettimeofday(&stop, NULL);
887 		timersub(&stop, &start, &res);
888 		elapsed = res.tv_sec + res.tv_usec / 1000000.0;
889 
890 		(void)printf("\nDigest = %s\n", digest);
891 		(void)printf("Time   = %f seconds\n", elapsed);
892 		(void)printf("Speed  = %f bytes/second\n",
893 		    TEST_BLOCK_LEN * TEST_BLOCK_COUNT / elapsed);
894 	}
895 }
896 
897 void
digest_test(struct hash_functions ** hashes)898 digest_test(struct hash_functions **hashes)
899 {
900 	struct hash_functions *hf;
901 	union ANY_CTX context;
902 	int i;
903 	char digest[MAX_DIGEST_LEN + 1];
904 	unsigned char buf[1000];
905 	const char *test_strings[] = {
906 		"",
907 		"a",
908 		"abc",
909 		"message digest",
910 		"abcdefghijklmnopqrstuvwxyz",
911 		"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
912 		"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
913 		    "0123456789",
914 		"12345678901234567890123456789012345678901234567890123456789"
915 		    "012345678901234567890",
916 	};
917 
918 	while (*hashes != NULL) {
919 		hf = *hashes++;
920 		(void)printf("%s test suite:\n", hf->name);
921 
922 		for (i = 0; i < 8; i++) {
923 			hf->init(&context);
924 			hf->update((void *)&context,
925 			    (unsigned const char *)test_strings[i],
926 			    (unsigned int)strlen(test_strings[i]));
927 			(void)hf->end(&context, digest);
928 			hf->printstr(hf->name, test_strings[i], digest);
929 		}
930 
931 		/* Now simulate a string of a million 'a' characters. */
932 		memset(buf, 'a', sizeof(buf));
933 		hf->init(&context);
934 		for (i = 0; i < 1000; i++)
935 			hf->update(&context, buf,
936 			    (unsigned int)sizeof(buf));
937 		(void)hf->end(&context, digest);
938 		hf->print(hf->name, "one million 'a' characters",
939 		    digest);
940 	}
941 }
942 
943 void
usage(void)944 usage(void)
945 {
946 	fprintf(stderr, "usage: %s [-[b]p | -t | -x | -c [cklst ...] | "
947 	    "-[b]s string | [-bG] file ...]\n", __progname);
948 	if (strcmp(__progname, "cksum") == 0)
949 		fprintf(stderr, "             [-a algorithms]] [-o 1 | 2]\n");
950 
951 	exit(EXIT_FAILURE);
952 }
953 
954 void
digest_printbin_pad(const char * digest)955 digest_printbin_pad(const char *digest)
956 {
957 	uint64_t one, two;
958 	char *c;
959 
960 	one = strtoll(digest, &c, 10);
961 	if (*c) {
962 		two = strtoll(++c, NULL, 10);
963 		if (asprintf(&c, "%016llX%016llX", one, two) == -1)
964 			return;
965 	} else if (asprintf(&c, "%016llX", one) == -1)
966 		return;
967 	digest_printbin_string(c);
968 	free(c);
969 }
970 
971 void
digest_printbin_string(const char * digest)972 digest_printbin_string(const char *digest)
973 {
974 	int i, j, k;
975 
976 	for (i = 0; i < (ssize_t)(strlen(digest)/2); ++i) {
977 		j = digest[i * 2] - 0x30;
978 		k = digest[i * 2 + 1] - 0x30;
979 		if ((j < 0) || (k < 0))
980 			break;
981 		j = (j > 9) ? (((j - 7) > 15) ? (j - 0x27) : (j - 7)) : j;
982 		k = (k > 9) ? (((k - 7) > 15) ? (k - 0x27) : (k - 7)) : k;
983 		if ((j < 0) || (k < 0) || (j > 15) || (k > 15))
984 			break;
985 		putchar((j << 4) | k);
986 	}
987 }
988 
989 void
digest_printbin_stringle(const char * digest)990 digest_printbin_stringle(const char *digest)
991 {
992 	uint32_t dgst;
993 	char *c;
994 
995 	dgst = strtoul(digest, NULL, 16);
996 	if (asprintf(&c, "%02X%02X%02X%02X",
997 	    dgst & 0xff, (dgst >> 8) & 0xff,
998 	    (dgst >> 16) & 0xff, dgst >> 24) == -1)
999 		return;
1000 	digest_printbin_string(c);
1001 	free(c);
1002 }
1003 
1004 void
SIZE_Init(SIZE_CTX * ctx)1005 SIZE_Init(SIZE_CTX *ctx)
1006 {
1007 	*ctx = 0;
1008 }
1009 
1010 void
SIZE_Update(SIZE_CTX * ctx,const uint8_t * buf,size_t n)1011 SIZE_Update(SIZE_CTX *ctx, const uint8_t *buf __attribute__((__unused__)), size_t n)
1012 {
1013 	*ctx += n;
1014 }
1015 
1016 char *
SIZE_End(SIZE_CTX * ctx,char * digest)1017 SIZE_End(SIZE_CTX *ctx, char *digest)
1018 {
1019 	if (digest == NULL) {
1020 		if (asprintf(&digest, "%llu", *ctx) == -1)
1021 			return (NULL);
1022 	} else
1023 		snprintf(digest, 21, "%llu", *ctx);
1024 
1025 	return (digest);
1026 }
1027 
1028 void
CDB_Init(CDB_CTX * ctx)1029 CDB_Init(CDB_CTX *ctx)
1030 {
1031 	*ctx = 5381;
1032 }
1033 
1034 void
CDB_Update(CDB_CTX * ctx,const uint8_t * buf,size_t n)1035 CDB_Update(CDB_CTX *ctx, const uint8_t *buf, size_t n)
1036 {
1037 	register uint32_t h;
1038 
1039 	h = *ctx;
1040 	while (n--)
1041 		h = ((h << 5) + h) ^ *buf++;
1042 	*ctx = h;
1043 }
1044 
1045 char *
ucase_End(CDB_CTX * ctx,char * digest)1046 ucase_End(CDB_CTX *ctx, char *digest)
1047 {
1048 	if (digest == NULL) {
1049 		if (asprintf(&digest, "%08X", *ctx) == -1)
1050 			return (NULL);
1051 	} else
1052 		snprintf(digest, 17, "%08X", *ctx);
1053 
1054 	return (digest);
1055 }
1056 
1057 void
OAAT_Init(OAATS_CTX * ctx)1058 OAAT_Init(OAATS_CTX *ctx)
1059 {
1060 	ctx->crc = 0;
1061 	ctx->len = 0;
1062 }
1063 
1064 void
OAAT1_Init(OAATS_CTX * ctx)1065 OAAT1_Init(OAATS_CTX *ctx)
1066 {
1067 	ctx->crc = 0x100;
1068 	ctx->len = 0;
1069 }
1070 
1071 void
OAAT_Update(OAATS_CTX * ctx,const uint8_t * buf,size_t n)1072 OAAT_Update(OAATS_CTX *ctx, const uint8_t *buf, size_t n)
1073 {
1074 	register uint32_t h;
1075 
1076 	ctx->len += n;
1077 	h = ctx->crc;
1078 	while (n--) {
1079 		h += *buf++;
1080 		h += h << 10;
1081 		h ^= h >> 6;
1082 	}
1083 	ctx->crc = h;
1084 }
1085 
1086 void
OAAT_Final(OAATS_CTX * ctx)1087 OAAT_Final(OAATS_CTX *ctx)
1088 {
1089 	register uint32_t h;
1090 
1091 	h = ctx->crc;
1092 	h += h << 3;
1093 	h ^= h >> 11;
1094 	h += h << 15;
1095 	ctx->crc = h;
1096 }
1097 
1098 #ifdef __MirBSD__
1099 char *
OAAT1S_End(OAATS_CTX * ctx,char * digest)1100 OAAT1S_End(OAATS_CTX *ctx, char *digest)
1101 {
1102 	uint8_t le_len[8];
1103 	uint64_t bits;
1104 
1105 	bits = ctx->len << 3;
1106 	le_len[0] = bits & 0xFF; bits >>= 8;
1107 	le_len[1] = bits & 0xFF; bits >>= 8;
1108 	le_len[2] = bits & 0xFF; bits >>= 8;
1109 	le_len[3] = bits & 0xFF; bits >>= 8;
1110 	le_len[4] = bits & 0xFF; bits >>= 8;
1111 	le_len[5] = bits & 0xFF; bits >>= 8;
1112 	le_len[6] = bits & 0xFF; bits >>= 8;
1113 	le_len[7] = bits;
1114 
1115 	/* look, ma! mirabilos can do nicer formulas than Markus Friedl */
1116 	OAAT_Update(ctx, RFC1321_padding, 64 - ((ctx->len + 8) & 63));
1117 	OAAT_Update(ctx, le_len, 8);
1118 
1119 	return (OAAT_End(ctx, digest));
1120 }
1121 #endif
1122 
1123 char *
OAAT_End(OAATS_CTX * ctx,char * digest)1124 OAAT_End(OAATS_CTX *ctx, char *digest)
1125 {
1126 	OAAT_Final(ctx);
1127 	return (ucase_End(&ctx->crc, digest));
1128 }
1129 
1130 void
NZAT_Init(NZAT_CTX * ctx)1131 NZAT_Init(NZAT_CTX *ctx)
1132 {
1133 	*ctx = 0;
1134 }
1135 
1136 void
NZAT_Update(NZAT_CTX * ctx,const uint8_t * buf,size_t n)1137 NZAT_Update(NZAT_CTX *ctx, const uint8_t *buf, size_t n)
1138 {
1139 	register uint32_t h;
1140 
1141 	h = *ctx;
1142 	while (n--) {
1143 		h += (uint8_t)(*buf++);
1144 		++h;
1145 		h += h << 10;
1146 		h ^= h >> 6;
1147 	}
1148 	*ctx = h;
1149 }
1150 
1151 void
NZAT_Final(NZAT_CTX * ctx)1152 NZAT_Final(NZAT_CTX *ctx)
1153 {
1154 	register uint32_t h;
1155 
1156 	h = *ctx;
1157 	if (h == 0) {
1158 		++h;
1159 	} else {
1160 		h += h << 10;
1161 		h ^= h >> 6;
1162 		h += h << 3;
1163 		h ^= h >> 11;
1164 		h += h << 15;
1165 	}
1166 	*ctx = h;
1167 }
1168 
1169 void
NZAAT_Final(NZAT_CTX * ctx)1170 NZAAT_Final(NZAT_CTX *ctx)
1171 {
1172 	register uint32_t h;
1173 
1174 	h = *ctx;
1175 	h += h << 10;
1176 	h ^= h >> 6;
1177 	h += h << 3;
1178 	h ^= h >> 11;
1179 	h += h << 15;
1180 	*ctx = h;
1181 }
1182 
1183 char *
NZAT_End(NZAT_CTX * ctx,char * digest)1184 NZAT_End(NZAT_CTX *ctx, char *digest)
1185 {
1186 	NZAT_Final(ctx);
1187 	return (ucase_End(ctx, digest));
1188 }
1189 
1190 char *
NZAAT_End(NZAT_CTX * ctx,char * digest)1191 NZAAT_End(NZAT_CTX *ctx, char *digest)
1192 {
1193 	NZAAT_Final(ctx);
1194 	return (ucase_End(ctx, digest));
1195 }
1196 
1197 #define BAFHror_md5(eax,cl) (((eax) >> (cl)) | ((eax) << (32 - (cl))))
1198 
1199 #define BAFHFinish_md5(h) do {					\
1200 	register uint32_t BAFHFinish_v;				\
1201 								\
1202 	BAFHFinish_v = ((h) >> 7) & 0x01010101U;		\
1203 	BAFHFinish_v += BAFHFinish_v << 1;			\
1204 	BAFHFinish_v += BAFHFinish_v << 3;			\
1205 	BAFHFinish_v ^= ((h) << 1) & 0xFEFEFEFEU;		\
1206 								\
1207 	BAFHFinish_v ^= BAFHror_md5(BAFHFinish_v, 8);		\
1208 	BAFHFinish_v ^= ((h) = BAFHror_md5((h), 8));		\
1209 	BAFHFinish_v ^= ((h) = BAFHror_md5((h), 8));		\
1210 	(h) = BAFHror_md5((h), 8) ^ BAFHFinish_v;		\
1211 } while (/* CONSTCOND */ 0)
1212 
1213 char *
BAFH_End(BAFH_CTX * ctx,char * digest)1214 BAFH_End(BAFH_CTX *ctx, char *digest)
1215 {
1216 	register uint32_t h;
1217 
1218 	h = *ctx;
1219 	BAFHFinish_md5(h);
1220 	*ctx = h;
1221 	return (ucase_End(ctx, digest));
1222 }
1223 
1224 /*
1225  * Table-driven version of the following polynomial from POSIX 1003.2:
1226  *  G(x) = x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 +
1227  *	   x^7 + x^5 + x^4 + x^2 + x + 1
1228  */
1229 static const uint32_t crc32tab[] = {
1230 	0x00000000U,
1231 	0x04c11db7U, 0x09823b6eU, 0x0d4326d9U, 0x130476dcU, 0x17c56b6bU,
1232 	0x1a864db2U, 0x1e475005U, 0x2608edb8U, 0x22c9f00fU, 0x2f8ad6d6U,
1233 	0x2b4bcb61U, 0x350c9b64U, 0x31cd86d3U, 0x3c8ea00aU, 0x384fbdbdU,
1234 	0x4c11db70U, 0x48d0c6c7U, 0x4593e01eU, 0x4152fda9U, 0x5f15adacU,
1235 	0x5bd4b01bU, 0x569796c2U, 0x52568b75U, 0x6a1936c8U, 0x6ed82b7fU,
1236 	0x639b0da6U, 0x675a1011U, 0x791d4014U, 0x7ddc5da3U, 0x709f7b7aU,
1237 	0x745e66cdU, 0x9823b6e0U, 0x9ce2ab57U, 0x91a18d8eU, 0x95609039U,
1238 	0x8b27c03cU, 0x8fe6dd8bU, 0x82a5fb52U, 0x8664e6e5U, 0xbe2b5b58U,
1239 	0xbaea46efU, 0xb7a96036U, 0xb3687d81U, 0xad2f2d84U, 0xa9ee3033U,
1240 	0xa4ad16eaU, 0xa06c0b5dU, 0xd4326d90U, 0xd0f37027U, 0xddb056feU,
1241 	0xd9714b49U, 0xc7361b4cU, 0xc3f706fbU, 0xceb42022U, 0xca753d95U,
1242 	0xf23a8028U, 0xf6fb9d9fU, 0xfbb8bb46U, 0xff79a6f1U, 0xe13ef6f4U,
1243 	0xe5ffeb43U, 0xe8bccd9aU, 0xec7dd02dU, 0x34867077U, 0x30476dc0U,
1244 	0x3d044b19U, 0x39c556aeU, 0x278206abU, 0x23431b1cU, 0x2e003dc5U,
1245 	0x2ac12072U, 0x128e9dcfU, 0x164f8078U, 0x1b0ca6a1U, 0x1fcdbb16U,
1246 	0x018aeb13U, 0x054bf6a4U, 0x0808d07dU, 0x0cc9cdcaU, 0x7897ab07U,
1247 	0x7c56b6b0U, 0x71159069U, 0x75d48ddeU, 0x6b93dddbU, 0x6f52c06cU,
1248 	0x6211e6b5U, 0x66d0fb02U, 0x5e9f46bfU, 0x5a5e5b08U, 0x571d7dd1U,
1249 	0x53dc6066U, 0x4d9b3063U, 0x495a2dd4U, 0x44190b0dU, 0x40d816baU,
1250 	0xaca5c697U, 0xa864db20U, 0xa527fdf9U, 0xa1e6e04eU, 0xbfa1b04bU,
1251 	0xbb60adfcU, 0xb6238b25U, 0xb2e29692U, 0x8aad2b2fU, 0x8e6c3698U,
1252 	0x832f1041U, 0x87ee0df6U, 0x99a95df3U, 0x9d684044U, 0x902b669dU,
1253 	0x94ea7b2aU, 0xe0b41de7U, 0xe4750050U, 0xe9362689U, 0xedf73b3eU,
1254 	0xf3b06b3bU, 0xf771768cU, 0xfa325055U, 0xfef34de2U, 0xc6bcf05fU,
1255 	0xc27dede8U, 0xcf3ecb31U, 0xcbffd686U, 0xd5b88683U, 0xd1799b34U,
1256 	0xdc3abdedU, 0xd8fba05aU, 0x690ce0eeU, 0x6dcdfd59U, 0x608edb80U,
1257 	0x644fc637U, 0x7a089632U, 0x7ec98b85U, 0x738aad5cU, 0x774bb0ebU,
1258 	0x4f040d56U, 0x4bc510e1U, 0x46863638U, 0x42472b8fU, 0x5c007b8aU,
1259 	0x58c1663dU, 0x558240e4U, 0x51435d53U, 0x251d3b9eU, 0x21dc2629U,
1260 	0x2c9f00f0U, 0x285e1d47U, 0x36194d42U, 0x32d850f5U, 0x3f9b762cU,
1261 	0x3b5a6b9bU, 0x0315d626U, 0x07d4cb91U, 0x0a97ed48U, 0x0e56f0ffU,
1262 	0x1011a0faU, 0x14d0bd4dU, 0x19939b94U, 0x1d528623U, 0xf12f560eU,
1263 	0xf5ee4bb9U, 0xf8ad6d60U, 0xfc6c70d7U, 0xe22b20d2U, 0xe6ea3d65U,
1264 	0xeba91bbcU, 0xef68060bU, 0xd727bbb6U, 0xd3e6a601U, 0xdea580d8U,
1265 	0xda649d6fU, 0xc423cd6aU, 0xc0e2d0ddU, 0xcda1f604U, 0xc960ebb3U,
1266 	0xbd3e8d7eU, 0xb9ff90c9U, 0xb4bcb610U, 0xb07daba7U, 0xae3afba2U,
1267 	0xaafbe615U, 0xa7b8c0ccU, 0xa379dd7bU, 0x9b3660c6U, 0x9ff77d71U,
1268 	0x92b45ba8U, 0x9675461fU, 0x8832161aU, 0x8cf30badU, 0x81b02d74U,
1269 	0x857130c3U, 0x5d8a9099U, 0x594b8d2eU, 0x5408abf7U, 0x50c9b640U,
1270 	0x4e8ee645U, 0x4a4ffbf2U, 0x470cdd2bU, 0x43cdc09cU, 0x7b827d21U,
1271 	0x7f436096U, 0x7200464fU, 0x76c15bf8U, 0x68860bfdU, 0x6c47164aU,
1272 	0x61043093U, 0x65c52d24U, 0x119b4be9U, 0x155a565eU, 0x18197087U,
1273 	0x1cd86d30U, 0x029f3d35U, 0x065e2082U, 0x0b1d065bU, 0x0fdc1becU,
1274 	0x3793a651U, 0x3352bbe6U, 0x3e119d3fU, 0x3ad08088U, 0x2497d08dU,
1275 	0x2056cd3aU, 0x2d15ebe3U, 0x29d4f654U, 0xc5a92679U, 0xc1683bceU,
1276 	0xcc2b1d17U, 0xc8ea00a0U, 0xd6ad50a5U, 0xd26c4d12U, 0xdf2f6bcbU,
1277 	0xdbee767cU, 0xe3a1cbc1U, 0xe760d676U, 0xea23f0afU, 0xeee2ed18U,
1278 	0xf0a5bd1dU, 0xf464a0aaU, 0xf9278673U, 0xfde69bc4U, 0x89b8fd09U,
1279 	0x8d79e0beU, 0x803ac667U, 0x84fbdbd0U, 0x9abc8bd5U, 0x9e7d9662U,
1280 	0x933eb0bbU, 0x97ffad0cU, 0xafb010b1U, 0xab710d06U, 0xa6322bdfU,
1281 	0xa2f33668U, 0xbcb4666dU, 0xb8757bdaU, 0xb5365d03U, 0xb1f740b4U
1282 };
1283 
1284 #define	UPDATE(crc, byte) do {						\
1285 	(crc) = ((crc) << 8) ^ crc32tab[((crc) >> 24) ^ (byte)];	\
1286 } while(/* CONSTCOND */ 0)
1287 
1288 void
CKSUM_Update(CKSUM_CTX * ctx,const unsigned char * buf,size_t len)1289 CKSUM_Update(CKSUM_CTX *ctx, const unsigned char *buf, size_t len)
1290 {
1291 	size_t i;
1292 
1293 	for (i = 0; i < len; i++)
1294 		UPDATE(ctx->crc, buf[i]);
1295 	ctx->len += len;
1296 }
1297 
1298 void
CKSUM_Final(CKSUM_CTX * ctx)1299 CKSUM_Final(CKSUM_CTX *ctx)
1300 {
1301 	off_t len = ctx->len;
1302 
1303 	/* add in number of bytes read and finish */
1304 	while (len != 0) {
1305 		UPDATE(ctx->crc, len & 0xff);
1306 		len >>= 8;
1307 	}
1308 	ctx->crc = ~ctx->crc;
1309 }
1310 #undef UPDATE
1311 
1312 char *
CKSUM_End(CKSUM_CTX * ctx,char * outstr)1313 CKSUM_End(CKSUM_CTX *ctx, char *outstr)
1314 {
1315 	CKSUM_Final(ctx);
1316 	return (ulld_End(ctx, outstr));
1317 }
1318 
1319 char *
ulld_End(CKSUM_CTX * ctx,char * outstr)1320 ulld_End(CKSUM_CTX *ctx, char *outstr)
1321 {
1322 	if (outstr == NULL) {
1323 		if (asprintf(&outstr, "%u %lld", ctx->crc,
1324 		    (int64_t)ctx->len) == -1)
1325 			return (NULL);
1326 	} else {
1327 		(void)snprintf(outstr, (size_t)CKSUM_DIGEST_STRING_LENGTH,
1328 		    "%u %lld", ctx->crc, (int64_t)ctx->len);
1329 	}
1330 
1331 	return (outstr);
1332 }
1333 
1334 void
SUM_Update(SUM_CTX * ctx,const unsigned char * buf,size_t len)1335 SUM_Update(SUM_CTX *ctx, const unsigned char *buf, size_t len)
1336 {
1337 	size_t i;
1338 
1339 	for (i = 0; i < len; i++) {
1340 		ctx->crc = ((ctx->crc >> 1) + ((ctx->crc & 1) << 15) + buf[i]);
1341 		ctx->crc &= 0xffff;
1342 	}
1343 	ctx->len += len;
1344 }
1345 
1346 void
SUM_Final(SUM_CTX * ctx)1347 SUM_Final(SUM_CTX *ctx)
1348 {
1349 	ctx->len = (ctx->len + 1023) / 1024;	/* convert to 1 KiB blocks */
1350 }
1351 
1352 char *
SUM_End(SUM_CTX * ctx,char * outstr)1353 SUM_End(SUM_CTX *ctx, char *outstr)
1354 {
1355 	SUM_Final(ctx);
1356 	return (ulld_End(ctx, outstr));
1357 }
1358 
1359 void
SYSVSUM_Update(SYSVSUM_CTX * ctx,const unsigned char * buf,size_t len)1360 SYSVSUM_Update(SYSVSUM_CTX *ctx, const unsigned char *buf, size_t len)
1361 {
1362 	size_t i;
1363 
1364 	for (i = 0; i < len; i++)
1365 		ctx->crc += buf[i];
1366 	ctx->len += len;
1367 }
1368 
1369 void
SYSVSUM_Final(SYSVSUM_CTX * ctx)1370 SYSVSUM_Final(SYSVSUM_CTX *ctx)
1371 {
1372 	ctx->crc = (ctx->crc & 0xffff) + (ctx->crc >> 16);
1373 	ctx->crc = (ctx->crc & 0xffff) + (ctx->crc >> 16);
1374 	ctx->len = (ctx->len + 511) / 512;	/* convert to 512 byte blocks */
1375 }
1376 
1377 char *
SYSVSUM_End(SYSVSUM_CTX * ctx,char * outstr)1378 SYSVSUM_End(SYSVSUM_CTX *ctx, char *outstr)
1379 {
1380 	SYSVSUM_Final(ctx);
1381 	return (ulld_End(ctx, outstr));
1382 }
1383 
1384 void
cksum_addpool(const char * s)1385 cksum_addpool(const char *s)
1386 {
1387 #if defined(arc4random_pushb_fast)
1388 	arc4random_pushb_fast(s, strlen(s) + 1);
1389 #else
1390 	ADLER32_CTX tmp;
1391 
1392 	ADLER32Update(&tmp, (const uint8_t *)s, strlen(s));
1393 #if defined(arc4random_pushk)
1394 	arc4random_pushk(&tmp, sizeof (ADLER32_CTX));
1395 #elif defined(MirBSD) && (MirBSD > 0x09A1)
1396 	arc4random_pushb(&tmp, sizeof (ADLER32_CTX));
1397 #endif
1398 #endif
1399 }
1400