xref: /freebsd/usr.sbin/pkg/hash.c (revision b2654064c2d11a1ee36667b3ff8b0f4d2536af74)
1*b2654064SBaptiste Daroussin /*-
2*b2654064SBaptiste Daroussin  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3*b2654064SBaptiste Daroussin  *
4*b2654064SBaptiste Daroussin  * Copyright (c) 2012-2014 Baptiste Daroussin <bapt@FreeBSD.org>
5*b2654064SBaptiste Daroussin  * Copyright (c) 2013 Bryan Drewery <bdrewery@FreeBSD.org>
6*b2654064SBaptiste Daroussin  * All rights reserved.
7*b2654064SBaptiste Daroussin  *
8*b2654064SBaptiste Daroussin  * Redistribution and use in source and binary forms, with or without
9*b2654064SBaptiste Daroussin  * modification, are permitted provided that the following conditions
10*b2654064SBaptiste Daroussin  * are met:
11*b2654064SBaptiste Daroussin  * 1. Redistributions of source code must retain the above copyright
12*b2654064SBaptiste Daroussin  *    notice, this list of conditions and the following disclaimer.
13*b2654064SBaptiste Daroussin  * 2. Redistributions in binary form must reproduce the above copyright
14*b2654064SBaptiste Daroussin  *    notice, this list of conditions and the following disclaimer in the
15*b2654064SBaptiste Daroussin  *    documentation and/or other materials provided with the distribution.
16*b2654064SBaptiste Daroussin  *
17*b2654064SBaptiste Daroussin  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18*b2654064SBaptiste Daroussin  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19*b2654064SBaptiste Daroussin  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20*b2654064SBaptiste Daroussin  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21*b2654064SBaptiste Daroussin  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22*b2654064SBaptiste Daroussin  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23*b2654064SBaptiste Daroussin  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24*b2654064SBaptiste Daroussin  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25*b2654064SBaptiste Daroussin  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26*b2654064SBaptiste Daroussin  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27*b2654064SBaptiste Daroussin  * SUCH DAMAGE.
28*b2654064SBaptiste Daroussin  */
29*b2654064SBaptiste Daroussin 
30*b2654064SBaptiste Daroussin #include <err.h>
31*b2654064SBaptiste Daroussin #include <sha256.h>
32*b2654064SBaptiste Daroussin #include <stdio.h>
33*b2654064SBaptiste Daroussin #include <unistd.h>
34*b2654064SBaptiste Daroussin 
35*b2654064SBaptiste Daroussin #include "hash.h"
36*b2654064SBaptiste Daroussin 
37*b2654064SBaptiste Daroussin static void
38*b2654064SBaptiste Daroussin sha256_hash(unsigned char hash[SHA256_DIGEST_LENGTH],
39*b2654064SBaptiste Daroussin     char out[SHA256_DIGEST_LENGTH * 2 + 1])
40*b2654064SBaptiste Daroussin {
41*b2654064SBaptiste Daroussin 	int i;
42*b2654064SBaptiste Daroussin 
43*b2654064SBaptiste Daroussin 	for (i = 0; i < SHA256_DIGEST_LENGTH; i++)
44*b2654064SBaptiste Daroussin 		sprintf(out + (i * 2), "%02x", hash[i]);
45*b2654064SBaptiste Daroussin 
46*b2654064SBaptiste Daroussin 	out[SHA256_DIGEST_LENGTH * 2] = '\0';
47*b2654064SBaptiste Daroussin }
48*b2654064SBaptiste Daroussin 
49*b2654064SBaptiste Daroussin void
50*b2654064SBaptiste Daroussin sha256_buf(char *buf, size_t len, char out[SHA256_DIGEST_LENGTH * 2 + 1])
51*b2654064SBaptiste Daroussin {
52*b2654064SBaptiste Daroussin 	unsigned char hash[SHA256_DIGEST_LENGTH];
53*b2654064SBaptiste Daroussin 	SHA256_CTX sha256;
54*b2654064SBaptiste Daroussin 
55*b2654064SBaptiste Daroussin 	out[0] = '\0';
56*b2654064SBaptiste Daroussin 
57*b2654064SBaptiste Daroussin 	SHA256_Init(&sha256);
58*b2654064SBaptiste Daroussin 	SHA256_Update(&sha256, buf, len);
59*b2654064SBaptiste Daroussin 	SHA256_Final(hash, &sha256);
60*b2654064SBaptiste Daroussin 	sha256_hash(hash, out);
61*b2654064SBaptiste Daroussin }
62*b2654064SBaptiste Daroussin 
63*b2654064SBaptiste Daroussin int
64*b2654064SBaptiste Daroussin sha256_fd(int fd, char out[SHA256_DIGEST_LENGTH * 2 + 1])
65*b2654064SBaptiste Daroussin {
66*b2654064SBaptiste Daroussin 	int my_fd;
67*b2654064SBaptiste Daroussin 	FILE *fp;
68*b2654064SBaptiste Daroussin 	char buffer[BUFSIZ];
69*b2654064SBaptiste Daroussin 	unsigned char hash[SHA256_DIGEST_LENGTH];
70*b2654064SBaptiste Daroussin 	size_t r;
71*b2654064SBaptiste Daroussin 	int ret;
72*b2654064SBaptiste Daroussin 	SHA256_CTX sha256;
73*b2654064SBaptiste Daroussin 
74*b2654064SBaptiste Daroussin 	fp = NULL;
75*b2654064SBaptiste Daroussin 	ret = 1;
76*b2654064SBaptiste Daroussin 
77*b2654064SBaptiste Daroussin 	out[0] = '\0';
78*b2654064SBaptiste Daroussin 
79*b2654064SBaptiste Daroussin 	/* Duplicate the fd so that fclose(3) does not close it. */
80*b2654064SBaptiste Daroussin 	if ((my_fd = dup(fd)) == -1) {
81*b2654064SBaptiste Daroussin 		warnx("dup");
82*b2654064SBaptiste Daroussin 		goto cleanup;
83*b2654064SBaptiste Daroussin 	}
84*b2654064SBaptiste Daroussin 
85*b2654064SBaptiste Daroussin 	if ((fp = fdopen(my_fd, "rb")) == NULL) {
86*b2654064SBaptiste Daroussin 		warnx("fdopen");
87*b2654064SBaptiste Daroussin 		goto cleanup;
88*b2654064SBaptiste Daroussin 	}
89*b2654064SBaptiste Daroussin 
90*b2654064SBaptiste Daroussin 	SHA256_Init(&sha256);
91*b2654064SBaptiste Daroussin 
92*b2654064SBaptiste Daroussin 	while ((r = fread(buffer, 1, BUFSIZ, fp)) > 0)
93*b2654064SBaptiste Daroussin 		SHA256_Update(&sha256, buffer, r);
94*b2654064SBaptiste Daroussin 
95*b2654064SBaptiste Daroussin 	if (ferror(fp) != 0) {
96*b2654064SBaptiste Daroussin 		warnx("fread");
97*b2654064SBaptiste Daroussin 		goto cleanup;
98*b2654064SBaptiste Daroussin 	}
99*b2654064SBaptiste Daroussin 
100*b2654064SBaptiste Daroussin 	SHA256_Final(hash, &sha256);
101*b2654064SBaptiste Daroussin 	sha256_hash(hash, out);
102*b2654064SBaptiste Daroussin 	ret = 0;
103*b2654064SBaptiste Daroussin 
104*b2654064SBaptiste Daroussin cleanup:
105*b2654064SBaptiste Daroussin 	if (fp != NULL)
106*b2654064SBaptiste Daroussin 		fclose(fp);
107*b2654064SBaptiste Daroussin 	else if (my_fd != -1)
108*b2654064SBaptiste Daroussin 		close(my_fd);
109*b2654064SBaptiste Daroussin 	(void)lseek(fd, 0, SEEK_SET);
110*b2654064SBaptiste Daroussin 
111*b2654064SBaptiste Daroussin 	return (ret);
112*b2654064SBaptiste Daroussin }
113