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 <sys/types.h>
26 #include <sys/stat.h>
27 #include <sys/param.h>
28 #include <sys/syslog.h>
29 
30 #ifdef _KERNEL
31 # include <sys/md5.h>
32 # include <sys/sha1.h>
33 # include <sys/sha2.h>
34 # include <sys/rmd160.h>
35 # include <sys/kmem.h>
36 #else
37 # include <arpa/inet.h>
38 # include <ctype.h>
39 # include <inttypes.h>
40 # include <md5.h>
41 # include <rmd160.h>
42 # include <sha1.h>
43 # include <sha2.h>
44 # include <stdarg.h>
45 # include <stdio.h>
46 # include <stdlib.h>
47 # include <string.h>
48 # include <time.h>
49 # include <unistd.h>
50 #endif
51 
52 #include "digest.h"
53 
54 static uint8_t prefix_md5[] = {
55 	0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86,
56 	0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10
57 };
58 
59 static uint8_t prefix_sha1[] = {
60 	0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0E, 0x03, 0x02,
61 	0x1A, 0x05, 0x00, 0x04, 0x14
62 };
63 
64 static uint8_t prefix_sha256[] = {
65 	0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
66 	0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
67 };
68 
69 static uint64_t	prefix_tiger[] = {
70 	0x0123456789ABCDEFLL,
71 	0xFEDCBA9876543210LL,
72 	0xF096A5B4C3B2E187LL
73 };
74 
75 static uint8_t prefix_rmd160[] = {
76 	0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x24,
77 	0x03, 0x02, 0x01, 0x05, 0x00, 0x04, 0x14
78 };
79 
80 static uint8_t prefix_sha512[] = {
81 	0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
82 	0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40
83 };
84 
85 #define V4_SIGNATURE		4
86 
87 /*************************************************************************/
88 
89 void
90 MD5_Init(MD5_CTX *context)
91 {
92 	if (context) {
93 		MD5Init(context);
94 	}
95 }
96 
97 void
98 MD5_Update(MD5_CTX *context, const unsigned char *data, unsigned int len)
99 {
100 	if (context && data) {
101 		MD5Update(context, data, len);
102 	}
103 }
104 
105 void
106 MD5_Final(unsigned char digest[16], MD5_CTX *context)
107 {
108 	if (digest && context) {
109 		MD5Final(digest, context);
110 	}
111 }
112 
113 void
114 SHA1_Init(SHA1_CTX *context)
115 {
116 	if (context) {
117 		SHA1Init(context);
118 	}
119 }
120 
121 void
122 SHA1_Update(SHA1_CTX *context, const unsigned char *data, unsigned int len)
123 {
124 	if (context && data) {
125 		SHA1Update(context, data, len);
126 	}
127 }
128 
129 void
130 SHA1_Final(unsigned char digest[20], SHA1_CTX *context)
131 {
132 	if (digest && context) {
133 		SHA1Final(digest, context);
134 	}
135 }
136 
137 void
138 RMD160_Init(RMD160_CTX *context)
139 {
140 	if (context) {
141 		RMD160Init(context);
142 	}
143 }
144 
145 void
146 RMD160_Update(RMD160_CTX *context, const unsigned char *data, unsigned int len)
147 {
148 	if (context && data) {
149 		RMD160Update(context, data, len);
150 	}
151 }
152 
153 void
154 RMD160_Final(unsigned char digest[20], RMD160_CTX *context)
155 {
156 	if (context && digest) {
157 		RMD160Final(digest, context);
158 	}
159 }
160 
161 
162 /* algorithm size (raw) */
163 int
164 digest_alg_size(unsigned alg)
165 {
166 	switch(alg) {
167 	case MD5_HASH_ALG:
168 		return 16;
169 	case SHA1_HASH_ALG:
170 		return 20;
171 	case RIPEMD_HASH_ALG:
172 		return RMD160_DIGEST_LENGTH;
173 	case SHA256_HASH_ALG:
174 		return 32;
175 	case SHA512_HASH_ALG:
176 		return 64;
177 	case TIGER_HASH_ALG:
178 	case TIGER2_HASH_ALG:
179 		return TIGER_DIGEST_LENGTH;
180 	default:
181 		printf("hash_any: bad algorithm\n");
182 		return 0;
183 	}
184 }
185 
186 /* initialise the hash structure */
187 int
188 digest_init(digest_t *hash, const uint32_t hashalg)
189 {
190 	if (hash == NULL) {
191 		return 0;
192 	}
193 	switch(hash->alg = hashalg) {
194 	case MD5_HASH_ALG:
195 		MD5Init(&hash->u.md5ctx);
196 		hash->size = 16;
197 		hash->prefix = prefix_md5;
198 		hash->len = sizeof(prefix_md5);
199 		hash->ctx = &hash->u.md5ctx;
200 		return 1;
201 	case SHA1_HASH_ALG:
202 		SHA1Init(&hash->u.sha1ctx);
203 		hash->size = 20;
204 		hash->prefix = prefix_sha1;
205 		hash->len = sizeof(prefix_sha1);
206 		hash->ctx = &hash->u.sha1ctx;
207 		return 1;
208 	case RIPEMD_HASH_ALG:
209 		RMD160Init(&hash->u.rmd160ctx);
210 		hash->size = 20;
211 		hash->prefix = prefix_rmd160;
212 		hash->len = sizeof(prefix_rmd160);
213 		hash->ctx = &hash->u.rmd160ctx;
214 		return 1;
215 	case SHA256_HASH_ALG:
216 		SHA256_Init(&hash->u.sha256ctx);
217 		hash->size = 32;
218 		hash->prefix = prefix_sha256;
219 		hash->len = sizeof(prefix_sha256);
220 		hash->ctx = &hash->u.sha256ctx;
221 		return 1;
222 	case SHA512_HASH_ALG:
223 		SHA512_Init(&hash->u.sha512ctx);
224 		hash->size = 64;
225 		hash->prefix = prefix_sha512;
226 		hash->len = sizeof(prefix_sha512);
227 		hash->ctx = &hash->u.sha512ctx;
228 		return 1;
229 	case TIGER_HASH_ALG:
230 		TIGER_Init(&hash->u.tigerctx);
231 		hash->size = TIGER_DIGEST_LENGTH;
232 		hash->prefix = prefix_tiger;
233 		hash->len = sizeof(prefix_tiger);
234 		hash->ctx = &hash->u.tigerctx;
235 		return 1;
236 	case TIGER2_HASH_ALG:
237 		TIGER2_Init(&hash->u.tigerctx);
238 		hash->size = TIGER_DIGEST_LENGTH;
239 		hash->prefix = prefix_tiger;
240 		hash->len = sizeof(prefix_tiger);
241 		hash->ctx = &hash->u.tigerctx;
242 		return 1;
243 	default:
244 		printf("hash_any: bad algorithm\n");
245 		return 0;
246 	}
247 }
248 
249 typedef struct rec_t {
250 	const char	*s;
251 	const unsigned	 alg;
252 } rec_t;
253 
254 static rec_t	hashalgs[] = {
255 	{	"md5",		MD5_HASH_ALG	},
256 	{	"sha1",		SHA1_HASH_ALG	},
257 	{	"ripemd",	RIPEMD_HASH_ALG	},
258 	{	"sha256",	SHA256_HASH_ALG	},
259 	{	"sha512",	SHA512_HASH_ALG	},
260 	{	"tiger",	TIGER_HASH_ALG	},
261 	{	"tiger2",	TIGER2_HASH_ALG	},
262 	{	NULL,		0		}
263 };
264 
265 /* initialise by string alg name */
266 unsigned
267 digest_get_alg(const char *hashalg)
268 {
269 	rec_t	*r;
270 
271 	for (r = hashalgs ; hashalg && r->s ; r++) {
272 		if (strcasecmp(r->s, hashalg) == 0) {
273 			return r->alg;
274 		}
275 	}
276 	return 0;
277 }
278 
279 int
280 digest_update(digest_t *hash, const uint8_t *data, size_t length)
281 {
282 	if (hash == NULL || data == NULL) {
283 		return 0;
284 	}
285 	switch(hash->alg) {
286 	case MD5_HASH_ALG:
287 		MD5Update(hash->ctx, data, (unsigned)length);
288 		return 1;
289 	case SHA1_HASH_ALG:
290 		SHA1Update(hash->ctx, data, (unsigned)length);
291 		return 1;
292 	case RIPEMD_HASH_ALG:
293 		RMD160Update(hash->ctx, data, (unsigned)length);
294 		return 1;
295 	case SHA256_HASH_ALG:
296 		SHA256_Update(hash->ctx, data, length);
297 		return 1;
298 	case SHA512_HASH_ALG:
299 		SHA512_Update(hash->ctx, data, length);
300 		return 1;
301 	case TIGER_HASH_ALG:
302 	case TIGER2_HASH_ALG:
303 		TIGER_Update(hash->ctx, data, length);
304 		return 1;
305 	default:
306 		printf("hash_any: bad algorithm\n");
307 		return 0;
308 	}
309 }
310 
311 unsigned
312 digest_final(uint8_t *out, digest_t *hash)
313 {
314 	if (hash == NULL || out == NULL) {
315 		return 0;
316 	}
317 	switch(hash->alg) {
318 	case MD5_HASH_ALG:
319 		MD5Final(out, hash->ctx);
320 		break;
321 	case SHA1_HASH_ALG:
322 		SHA1Final(out, hash->ctx);
323 		break;
324 	case RIPEMD_HASH_ALG:
325 		RMD160Final(out, hash->ctx);
326 		break;
327 	case SHA256_HASH_ALG:
328 		SHA256_Final(out, hash->ctx);
329 		break;
330 	case SHA512_HASH_ALG:
331 		SHA512_Final(out, hash->ctx);
332 		break;
333 	case TIGER_HASH_ALG:
334 		TIGER_Final(out, hash->ctx);
335 		break;
336 	default:
337 		printf("hash_any: bad algorithm\n");
338 		return 0;
339 	}
340 	(void) memset(hash->ctx, 0x0, hash->size);
341 	return (unsigned)hash->size;
342 }
343 
344 int
345 digest_length(digest_t *hash, unsigned hashedlen)
346 {
347 	uint8_t		 trailer[6];
348 
349 	if (hash == NULL) {
350 		return 0;
351 	}
352 	trailer[0] = V4_SIGNATURE;
353 	trailer[1] = 0xFF;
354 	trailer[2] = (uint8_t)((hashedlen >> 24) & 0xff);
355 	trailer[3] = (uint8_t)((hashedlen >> 16) & 0xff);
356 	trailer[4] = (uint8_t)((hashedlen >> 8) & 0xff);
357 	trailer[5] = (uint8_t)(hashedlen & 0xff);
358 	digest_update(hash, trailer, sizeof(trailer));
359 	return 1;
360 }
361 
362 unsigned
363 digest_get_prefix(unsigned hashalg, uint8_t *prefix, size_t size)
364 {
365 	if (prefix == NULL) {
366 		return 0;
367 	}
368 	switch (hashalg) {
369 	case MD5_HASH_ALG:
370 		memcpy(prefix, prefix_md5, sizeof(prefix_md5));
371 		return sizeof(prefix_md5);
372 	case SHA1_HASH_ALG:
373 		memcpy(prefix, prefix_sha1, sizeof(prefix_sha1));
374 		return sizeof(prefix_sha1);
375 	case SHA256_HASH_ALG:
376 		memcpy(prefix, prefix_sha256, sizeof(prefix_sha256));
377 		return sizeof(prefix_sha256);
378 	default:
379 		printf("digest_get_prefix: unknown hash algorithm: %d\n", hashalg);
380 		return 0;
381 	}
382 }
383 
384