xref: /netbsd-src/crypto/external/bsd/netpgp/dist/src/netpgpverify/digest.c (revision 32d959bfe02e9d3b89de38473374c06cf0ea0ac2)
1 /*-
2  * Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 #include "config.h"
26 
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <sys/param.h>
30 
31 #include <arpa/inet.h>
32 #include <ctype.h>
33 #include <inttypes.h>
34 #include <stdarg.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <time.h>
39 #include <unistd.h>
40 
41 #include "md5.h"
42 #include "rmd160.h"
43 #include "sha1.h"
44 #include "sha2.h"
45 
46 #include "digest.h"
47 
48 #ifndef USE_ARG
49 #define	USE_ARG(x)	/*LINTED*/(void)&(x)
50 #endif
51 
52 static uint8_t prefix_md5[] = {
53 	0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86,
54 	0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10
55 };
56 
57 static uint8_t prefix_sha1[] = {
58 	0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0E, 0x03, 0x02,
59 	0x1A, 0x05, 0x00, 0x04, 0x14
60 };
61 
62 static uint8_t prefix_sha256[] = {
63 	0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
64 	0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
65 };
66 
67 static uint8_t prefix_rmd160[] = {
68 	0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x24,
69 	0x03, 0x02, 0x01, 0x05, 0x00, 0x04, 0x14
70 };
71 
72 static uint8_t prefix_sha512[] = {
73 	0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
74 	0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40
75 };
76 
77 #define V4_SIGNATURE		4
78 
79 /*************************************************************************/
80 
81 /* algorithm size (raw) */
82 int
digest_alg_size(unsigned alg)83 digest_alg_size(unsigned alg)
84 {
85 	switch(alg) {
86 	case MD5_HASH_ALG:
87 		return 16;
88 	case SHA1_HASH_ALG:
89 		return 20;
90 	case RIPEMD_HASH_ALG:
91 		return RMD160_DIGEST_LENGTH;
92 	case SHA256_HASH_ALG:
93 		return 32;
94 	case SHA512_HASH_ALG:
95 		return 64;
96 	default:
97 		printf("hash_any: bad algorithm\n");
98 		return 0;
99 	}
100 }
101 
102 /* initialise the hash structure */
103 int
digest_init(digest_t * hash,const uint32_t hashalg)104 digest_init(digest_t *hash, const uint32_t hashalg)
105 {
106 	if (hash == NULL) {
107 		return 0;
108 	}
109 	switch(hash->alg = hashalg) {
110 	case MD5_HASH_ALG:
111 		netpgpv_MD5Init(&hash->u.md5ctx);
112 		hash->size = 16;
113 		hash->prefix = prefix_md5;
114 		hash->len = sizeof(prefix_md5);
115 		hash->ctx = &hash->u.md5ctx;
116 		return 1;
117 	case SHA1_HASH_ALG:
118 		netpgpv_SHA1Init(&hash->u.sha1ctx);
119 		hash->size = 20;
120 		hash->prefix = prefix_sha1;
121 		hash->len = sizeof(prefix_sha1);
122 		hash->ctx = &hash->u.sha1ctx;
123 		return 1;
124 	case RIPEMD_HASH_ALG:
125 		netpgpv_RMD160Init(&hash->u.rmd160ctx);
126 		hash->size = 20;
127 		hash->prefix = prefix_rmd160;
128 		hash->len = sizeof(prefix_rmd160);
129 		hash->ctx = &hash->u.rmd160ctx;
130 		return 1;
131 	case SHA256_HASH_ALG:
132 		netpgpv_SHA256_Init(&hash->u.sha256ctx);
133 		hash->size = 32;
134 		hash->prefix = prefix_sha256;
135 		hash->len = sizeof(prefix_sha256);
136 		hash->ctx = &hash->u.sha256ctx;
137 		return 1;
138 	case SHA512_HASH_ALG:
139 		netpgpv_SHA512_Init(&hash->u.sha512ctx);
140 		hash->size = 64;
141 		hash->prefix = prefix_sha512;
142 		hash->len = sizeof(prefix_sha512);
143 		hash->ctx = &hash->u.sha512ctx;
144 		return 1;
145 	default:
146 		printf("hash_any: bad algorithm\n");
147 		return 0;
148 	}
149 }
150 
151 typedef struct rec_t {
152 	const char	*s;
153 	const unsigned	 alg;
154 } rec_t;
155 
156 static rec_t	hashalgs[] = {
157 	{	"md5",		MD5_HASH_ALG	},
158 	{	"sha1",		SHA1_HASH_ALG	},
159 	{	"ripemd",	RIPEMD_HASH_ALG	},
160 	{	"sha256",	SHA256_HASH_ALG	},
161 	{	"sha512",	SHA512_HASH_ALG	},
162 	{	NULL,		0		}
163 };
164 
165 /* initialise by string alg name */
166 unsigned
digest_get_alg(const char * hashalg)167 digest_get_alg(const char *hashalg)
168 {
169 	rec_t	*r;
170 
171 	for (r = hashalgs ; hashalg && r->s ; r++) {
172 		if (strcasecmp(r->s, hashalg) == 0) {
173 			return r->alg;
174 		}
175 	}
176 	return 0;
177 }
178 
179 int
digest_update(digest_t * hash,const uint8_t * data,size_t length)180 digest_update(digest_t *hash, const uint8_t *data, size_t length)
181 {
182 	if (hash == NULL || data == NULL) {
183 		return 0;
184 	}
185 	switch(hash->alg) {
186 	case MD5_HASH_ALG:
187 		netpgpv_MD5Update(hash->ctx, data, (unsigned)length);
188 		return 1;
189 	case SHA1_HASH_ALG:
190 		netpgpv_SHA1Update(hash->ctx, data, (unsigned)length);
191 		return 1;
192 	case RIPEMD_HASH_ALG:
193 		netpgpv_RMD160Update(hash->ctx, data, (unsigned)length);
194 		return 1;
195 	case SHA256_HASH_ALG:
196 		netpgpv_SHA256_Update(hash->ctx, data, length);
197 		return 1;
198 	case SHA512_HASH_ALG:
199 		netpgpv_SHA512_Update(hash->ctx, data, length);
200 		return 1;
201 	default:
202 		printf("hash_any: bad algorithm\n");
203 		return 0;
204 	}
205 }
206 
207 unsigned
digest_final(uint8_t * out,digest_t * hash)208 digest_final(uint8_t *out, digest_t *hash)
209 {
210 	if (hash == NULL || out == NULL) {
211 		return 0;
212 	}
213 	switch(hash->alg) {
214 	case MD5_HASH_ALG:
215 		netpgpv_MD5Final(out, hash->ctx);
216 		break;
217 	case SHA1_HASH_ALG:
218 		netpgpv_SHA1Final(out, hash->ctx);
219 		break;
220 	case RIPEMD_HASH_ALG:
221 		netpgpv_RMD160Final(out, hash->ctx);
222 		break;
223 	case SHA256_HASH_ALG:
224 		netpgpv_SHA256_Final(out, hash->ctx);
225 		break;
226 	case SHA512_HASH_ALG:
227 		netpgpv_SHA512_Final(out, hash->ctx);
228 		break;
229 	default:
230 		printf("hash_any: bad algorithm\n");
231 		return 0;
232 	}
233 	(void) memset(hash->ctx, 0x0, hash->size);
234 	return (unsigned)hash->size;
235 }
236 
237 int
digest_length(digest_t * hash,unsigned hashedlen)238 digest_length(digest_t *hash, unsigned hashedlen)
239 {
240 	uint8_t		 trailer[6];
241 
242 	if (hash == NULL) {
243 		return 0;
244 	}
245 	trailer[0] = V4_SIGNATURE;
246 	trailer[1] = 0xFF;
247 	trailer[2] = (uint8_t)((hashedlen >> 24) & 0xff);
248 	trailer[3] = (uint8_t)((hashedlen >> 16) & 0xff);
249 	trailer[4] = (uint8_t)((hashedlen >> 8) & 0xff);
250 	trailer[5] = (uint8_t)(hashedlen & 0xff);
251 	digest_update(hash, trailer, sizeof(trailer));
252 	return 1;
253 }
254 
255 unsigned
digest_get_prefix(unsigned hashalg,uint8_t * prefix,size_t size)256 digest_get_prefix(unsigned hashalg, uint8_t *prefix, size_t size)
257 {
258 	USE_ARG(size);
259 	if (prefix == NULL) {
260 		return 0;
261 	}
262 	switch (hashalg) {
263 	case MD5_HASH_ALG:
264 		memcpy(prefix, prefix_md5, sizeof(prefix_md5));
265 		return sizeof(prefix_md5);
266 	case SHA1_HASH_ALG:
267 		memcpy(prefix, prefix_sha1, sizeof(prefix_sha1));
268 		return sizeof(prefix_sha1);
269 	case SHA256_HASH_ALG:
270 		memcpy(prefix, prefix_sha256, sizeof(prefix_sha256));
271 		return sizeof(prefix_sha256);
272 	case SHA512_HASH_ALG:
273 		memcpy(prefix, prefix_sha512, sizeof(prefix_sha512));
274 		return sizeof(prefix_sha512);
275 	default:
276 		printf("digest_get_prefix: unknown hash algorithm: %d\n", hashalg);
277 		return 0;
278 	}
279 }
280 
281