xref: /netbsd-src/crypto/external/bsd/netpgp/dist/src/libdigest/digest.c (revision 640eb22bcb3eb4227a4cc2648891b207ab6a658c)
1*640eb22bSagc /*-
2*640eb22bSagc  * Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org>
3*640eb22bSagc  * All rights reserved.
4*640eb22bSagc  *
5*640eb22bSagc  * Redistribution and use in source and binary forms, with or without
6*640eb22bSagc  * modification, are permitted provided that the following conditions
7*640eb22bSagc  * are met:
8*640eb22bSagc  * 1. Redistributions of source code must retain the above copyright
9*640eb22bSagc  *    notice, this list of conditions and the following disclaimer.
10*640eb22bSagc  * 2. Redistributions in binary form must reproduce the above copyright
11*640eb22bSagc  *    notice, this list of conditions and the following disclaimer in the
12*640eb22bSagc  *    documentation and/or other materials provided with the distribution.
13*640eb22bSagc  *
14*640eb22bSagc  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15*640eb22bSagc  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16*640eb22bSagc  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17*640eb22bSagc  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18*640eb22bSagc  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19*640eb22bSagc  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20*640eb22bSagc  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21*640eb22bSagc  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22*640eb22bSagc  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23*640eb22bSagc  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24*640eb22bSagc  */
25*640eb22bSagc #include <sys/types.h>
26*640eb22bSagc #include <sys/stat.h>
27*640eb22bSagc #include <sys/param.h>
28*640eb22bSagc #include <sys/syslog.h>
29*640eb22bSagc 
30*640eb22bSagc #ifdef _KERNEL
31*640eb22bSagc # include <sys/md5.h>
32*640eb22bSagc # include <sys/sha1.h>
33*640eb22bSagc # include <sys/sha2.h>
34*640eb22bSagc # include <sys/rmd160.h>
35*640eb22bSagc # include <sys/kmem.h>
36*640eb22bSagc #else
37*640eb22bSagc # include <arpa/inet.h>
38*640eb22bSagc # include <ctype.h>
39*640eb22bSagc # include <inttypes.h>
40*640eb22bSagc # include <md5.h>
41*640eb22bSagc # include <rmd160.h>
42*640eb22bSagc # include <sha1.h>
43*640eb22bSagc # include <sha2.h>
44*640eb22bSagc # include <stdarg.h>
45*640eb22bSagc # include <stdio.h>
46*640eb22bSagc # include <stdlib.h>
47*640eb22bSagc # include <string.h>
48*640eb22bSagc # include <time.h>
49*640eb22bSagc # include <unistd.h>
50*640eb22bSagc #endif
51*640eb22bSagc 
52*640eb22bSagc #include "digest.h"
53*640eb22bSagc 
54*640eb22bSagc static uint8_t prefix_md5[] = {
55*640eb22bSagc 	0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86,
56*640eb22bSagc 	0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10
57*640eb22bSagc };
58*640eb22bSagc 
59*640eb22bSagc static uint8_t prefix_sha1[] = {
60*640eb22bSagc 	0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0E, 0x03, 0x02,
61*640eb22bSagc 	0x1A, 0x05, 0x00, 0x04, 0x14
62*640eb22bSagc };
63*640eb22bSagc 
64*640eb22bSagc static uint8_t prefix_sha256[] = {
65*640eb22bSagc 	0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
66*640eb22bSagc 	0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
67*640eb22bSagc };
68*640eb22bSagc 
69*640eb22bSagc static uint64_t	prefix_tiger[] = {
70*640eb22bSagc 	0x0123456789ABCDEFLL,
71*640eb22bSagc 	0xFEDCBA9876543210LL,
72*640eb22bSagc 	0xF096A5B4C3B2E187LL
73*640eb22bSagc };
74*640eb22bSagc 
75*640eb22bSagc static uint8_t prefix_rmd160[] = {
76*640eb22bSagc 	0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x24,
77*640eb22bSagc 	0x03, 0x02, 0x01, 0x05, 0x00, 0x04, 0x14
78*640eb22bSagc };
79*640eb22bSagc 
80*640eb22bSagc static uint8_t prefix_sha512[] = {
81*640eb22bSagc 	0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
82*640eb22bSagc 	0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40
83*640eb22bSagc };
84*640eb22bSagc 
85*640eb22bSagc #define V4_SIGNATURE		4
86*640eb22bSagc 
87*640eb22bSagc /*************************************************************************/
88*640eb22bSagc 
89*640eb22bSagc void
MD5_Init(MD5_CTX * context)90*640eb22bSagc MD5_Init(MD5_CTX *context)
91*640eb22bSagc {
92*640eb22bSagc 	if (context) {
93*640eb22bSagc 		MD5Init(context);
94*640eb22bSagc 	}
95*640eb22bSagc }
96*640eb22bSagc 
97*640eb22bSagc void
MD5_Update(MD5_CTX * context,const unsigned char * data,unsigned int len)98*640eb22bSagc MD5_Update(MD5_CTX *context, const unsigned char *data, unsigned int len)
99*640eb22bSagc {
100*640eb22bSagc 	if (context && data) {
101*640eb22bSagc 		MD5Update(context, data, len);
102*640eb22bSagc 	}
103*640eb22bSagc }
104*640eb22bSagc 
105*640eb22bSagc void
MD5_Final(unsigned char digest[16],MD5_CTX * context)106*640eb22bSagc MD5_Final(unsigned char digest[16], MD5_CTX *context)
107*640eb22bSagc {
108*640eb22bSagc 	if (digest && context) {
109*640eb22bSagc 		MD5Final(digest, context);
110*640eb22bSagc 	}
111*640eb22bSagc }
112*640eb22bSagc 
113*640eb22bSagc void
SHA1_Init(SHA1_CTX * context)114*640eb22bSagc SHA1_Init(SHA1_CTX *context)
115*640eb22bSagc {
116*640eb22bSagc 	if (context) {
117*640eb22bSagc 		SHA1Init(context);
118*640eb22bSagc 	}
119*640eb22bSagc }
120*640eb22bSagc 
121*640eb22bSagc void
SHA1_Update(SHA1_CTX * context,const unsigned char * data,unsigned int len)122*640eb22bSagc SHA1_Update(SHA1_CTX *context, const unsigned char *data, unsigned int len)
123*640eb22bSagc {
124*640eb22bSagc 	if (context && data) {
125*640eb22bSagc 		SHA1Update(context, data, len);
126*640eb22bSagc 	}
127*640eb22bSagc }
128*640eb22bSagc 
129*640eb22bSagc void
SHA1_Final(unsigned char digest[20],SHA1_CTX * context)130*640eb22bSagc SHA1_Final(unsigned char digest[20], SHA1_CTX *context)
131*640eb22bSagc {
132*640eb22bSagc 	if (digest && context) {
133*640eb22bSagc 		SHA1Final(digest, context);
134*640eb22bSagc 	}
135*640eb22bSagc }
136*640eb22bSagc 
137*640eb22bSagc void
RMD160_Init(RMD160_CTX * context)138*640eb22bSagc RMD160_Init(RMD160_CTX *context)
139*640eb22bSagc {
140*640eb22bSagc 	if (context) {
141*640eb22bSagc 		RMD160Init(context);
142*640eb22bSagc 	}
143*640eb22bSagc }
144*640eb22bSagc 
145*640eb22bSagc void
RMD160_Update(RMD160_CTX * context,const unsigned char * data,unsigned int len)146*640eb22bSagc RMD160_Update(RMD160_CTX *context, const unsigned char *data, unsigned int len)
147*640eb22bSagc {
148*640eb22bSagc 	if (context && data) {
149*640eb22bSagc 		RMD160Update(context, data, len);
150*640eb22bSagc 	}
151*640eb22bSagc }
152*640eb22bSagc 
153*640eb22bSagc void
RMD160_Final(unsigned char digest[20],RMD160_CTX * context)154*640eb22bSagc RMD160_Final(unsigned char digest[20], RMD160_CTX *context)
155*640eb22bSagc {
156*640eb22bSagc 	if (context && digest) {
157*640eb22bSagc 		RMD160Final(digest, context);
158*640eb22bSagc 	}
159*640eb22bSagc }
160*640eb22bSagc 
161*640eb22bSagc 
162*640eb22bSagc /* algorithm size (raw) */
163*640eb22bSagc int
digest_alg_size(unsigned alg)164*640eb22bSagc digest_alg_size(unsigned alg)
165*640eb22bSagc {
166*640eb22bSagc 	switch(alg) {
167*640eb22bSagc 	case MD5_HASH_ALG:
168*640eb22bSagc 		return 16;
169*640eb22bSagc 	case SHA1_HASH_ALG:
170*640eb22bSagc 		return 20;
171*640eb22bSagc 	case RIPEMD_HASH_ALG:
172*640eb22bSagc 		return RMD160_DIGEST_LENGTH;
173*640eb22bSagc 	case SHA256_HASH_ALG:
174*640eb22bSagc 		return 32;
175*640eb22bSagc 	case SHA512_HASH_ALG:
176*640eb22bSagc 		return 64;
177*640eb22bSagc 	case TIGER_HASH_ALG:
178*640eb22bSagc 	case TIGER2_HASH_ALG:
179*640eb22bSagc 		return TIGER_DIGEST_LENGTH;
180*640eb22bSagc 	default:
181*640eb22bSagc 		printf("hash_any: bad algorithm\n");
182*640eb22bSagc 		return 0;
183*640eb22bSagc 	}
184*640eb22bSagc }
185*640eb22bSagc 
186*640eb22bSagc /* initialise the hash structure */
187*640eb22bSagc int
digest_init(digest_t * hash,const uint32_t hashalg)188*640eb22bSagc digest_init(digest_t *hash, const uint32_t hashalg)
189*640eb22bSagc {
190*640eb22bSagc 	if (hash == NULL) {
191*640eb22bSagc 		return 0;
192*640eb22bSagc 	}
193*640eb22bSagc 	switch(hash->alg = hashalg) {
194*640eb22bSagc 	case MD5_HASH_ALG:
195*640eb22bSagc 		MD5Init(&hash->u.md5ctx);
196*640eb22bSagc 		hash->size = 16;
197*640eb22bSagc 		hash->prefix = prefix_md5;
198*640eb22bSagc 		hash->len = sizeof(prefix_md5);
199*640eb22bSagc 		hash->ctx = &hash->u.md5ctx;
200*640eb22bSagc 		return 1;
201*640eb22bSagc 	case SHA1_HASH_ALG:
202*640eb22bSagc 		SHA1Init(&hash->u.sha1ctx);
203*640eb22bSagc 		hash->size = 20;
204*640eb22bSagc 		hash->prefix = prefix_sha1;
205*640eb22bSagc 		hash->len = sizeof(prefix_sha1);
206*640eb22bSagc 		hash->ctx = &hash->u.sha1ctx;
207*640eb22bSagc 		return 1;
208*640eb22bSagc 	case RIPEMD_HASH_ALG:
209*640eb22bSagc 		RMD160Init(&hash->u.rmd160ctx);
210*640eb22bSagc 		hash->size = 20;
211*640eb22bSagc 		hash->prefix = prefix_rmd160;
212*640eb22bSagc 		hash->len = sizeof(prefix_rmd160);
213*640eb22bSagc 		hash->ctx = &hash->u.rmd160ctx;
214*640eb22bSagc 		return 1;
215*640eb22bSagc 	case SHA256_HASH_ALG:
216*640eb22bSagc 		SHA256_Init(&hash->u.sha256ctx);
217*640eb22bSagc 		hash->size = 32;
218*640eb22bSagc 		hash->prefix = prefix_sha256;
219*640eb22bSagc 		hash->len = sizeof(prefix_sha256);
220*640eb22bSagc 		hash->ctx = &hash->u.sha256ctx;
221*640eb22bSagc 		return 1;
222*640eb22bSagc 	case SHA512_HASH_ALG:
223*640eb22bSagc 		SHA512_Init(&hash->u.sha512ctx);
224*640eb22bSagc 		hash->size = 64;
225*640eb22bSagc 		hash->prefix = prefix_sha512;
226*640eb22bSagc 		hash->len = sizeof(prefix_sha512);
227*640eb22bSagc 		hash->ctx = &hash->u.sha512ctx;
228*640eb22bSagc 		return 1;
229*640eb22bSagc 	case TIGER_HASH_ALG:
230*640eb22bSagc 		TIGER_Init(&hash->u.tigerctx);
231*640eb22bSagc 		hash->size = TIGER_DIGEST_LENGTH;
232*640eb22bSagc 		hash->prefix = prefix_tiger;
233*640eb22bSagc 		hash->len = sizeof(prefix_tiger);
234*640eb22bSagc 		hash->ctx = &hash->u.tigerctx;
235*640eb22bSagc 		return 1;
236*640eb22bSagc 	case TIGER2_HASH_ALG:
237*640eb22bSagc 		TIGER2_Init(&hash->u.tigerctx);
238*640eb22bSagc 		hash->size = TIGER_DIGEST_LENGTH;
239*640eb22bSagc 		hash->prefix = prefix_tiger;
240*640eb22bSagc 		hash->len = sizeof(prefix_tiger);
241*640eb22bSagc 		hash->ctx = &hash->u.tigerctx;
242*640eb22bSagc 		return 1;
243*640eb22bSagc 	default:
244*640eb22bSagc 		printf("hash_any: bad algorithm\n");
245*640eb22bSagc 		return 0;
246*640eb22bSagc 	}
247*640eb22bSagc }
248*640eb22bSagc 
249*640eb22bSagc typedef struct rec_t {
250*640eb22bSagc 	const char	*s;
251*640eb22bSagc 	const unsigned	 alg;
252*640eb22bSagc } rec_t;
253*640eb22bSagc 
254*640eb22bSagc static rec_t	hashalgs[] = {
255*640eb22bSagc 	{	"md5",		MD5_HASH_ALG	},
256*640eb22bSagc 	{	"sha1",		SHA1_HASH_ALG	},
257*640eb22bSagc 	{	"ripemd",	RIPEMD_HASH_ALG	},
258*640eb22bSagc 	{	"sha256",	SHA256_HASH_ALG	},
259*640eb22bSagc 	{	"sha512",	SHA512_HASH_ALG	},
260*640eb22bSagc 	{	"tiger",	TIGER_HASH_ALG	},
261*640eb22bSagc 	{	"tiger2",	TIGER2_HASH_ALG	},
262*640eb22bSagc 	{	NULL,		0		}
263*640eb22bSagc };
264*640eb22bSagc 
265*640eb22bSagc /* initialise by string alg name */
266*640eb22bSagc unsigned
digest_get_alg(const char * hashalg)267*640eb22bSagc digest_get_alg(const char *hashalg)
268*640eb22bSagc {
269*640eb22bSagc 	rec_t	*r;
270*640eb22bSagc 
271*640eb22bSagc 	for (r = hashalgs ; hashalg && r->s ; r++) {
272*640eb22bSagc 		if (strcasecmp(r->s, hashalg) == 0) {
273*640eb22bSagc 			return r->alg;
274*640eb22bSagc 		}
275*640eb22bSagc 	}
276*640eb22bSagc 	return 0;
277*640eb22bSagc }
278*640eb22bSagc 
279*640eb22bSagc int
digest_update(digest_t * hash,const uint8_t * data,size_t length)280*640eb22bSagc digest_update(digest_t *hash, const uint8_t *data, size_t length)
281*640eb22bSagc {
282*640eb22bSagc 	if (hash == NULL || data == NULL) {
283*640eb22bSagc 		return 0;
284*640eb22bSagc 	}
285*640eb22bSagc 	switch(hash->alg) {
286*640eb22bSagc 	case MD5_HASH_ALG:
287*640eb22bSagc 		MD5Update(hash->ctx, data, (unsigned)length);
288*640eb22bSagc 		return 1;
289*640eb22bSagc 	case SHA1_HASH_ALG:
290*640eb22bSagc 		SHA1Update(hash->ctx, data, (unsigned)length);
291*640eb22bSagc 		return 1;
292*640eb22bSagc 	case RIPEMD_HASH_ALG:
293*640eb22bSagc 		RMD160Update(hash->ctx, data, (unsigned)length);
294*640eb22bSagc 		return 1;
295*640eb22bSagc 	case SHA256_HASH_ALG:
296*640eb22bSagc 		SHA256_Update(hash->ctx, data, length);
297*640eb22bSagc 		return 1;
298*640eb22bSagc 	case SHA512_HASH_ALG:
299*640eb22bSagc 		SHA512_Update(hash->ctx, data, length);
300*640eb22bSagc 		return 1;
301*640eb22bSagc 	case TIGER_HASH_ALG:
302*640eb22bSagc 	case TIGER2_HASH_ALG:
303*640eb22bSagc 		TIGER_Update(hash->ctx, data, length);
304*640eb22bSagc 		return 1;
305*640eb22bSagc 	default:
306*640eb22bSagc 		printf("hash_any: bad algorithm\n");
307*640eb22bSagc 		return 0;
308*640eb22bSagc 	}
309*640eb22bSagc }
310*640eb22bSagc 
311*640eb22bSagc unsigned
digest_final(uint8_t * out,digest_t * hash)312*640eb22bSagc digest_final(uint8_t *out, digest_t *hash)
313*640eb22bSagc {
314*640eb22bSagc 	if (hash == NULL || out == NULL) {
315*640eb22bSagc 		return 0;
316*640eb22bSagc 	}
317*640eb22bSagc 	switch(hash->alg) {
318*640eb22bSagc 	case MD5_HASH_ALG:
319*640eb22bSagc 		MD5Final(out, hash->ctx);
320*640eb22bSagc 		break;
321*640eb22bSagc 	case SHA1_HASH_ALG:
322*640eb22bSagc 		SHA1Final(out, hash->ctx);
323*640eb22bSagc 		break;
324*640eb22bSagc 	case RIPEMD_HASH_ALG:
325*640eb22bSagc 		RMD160Final(out, hash->ctx);
326*640eb22bSagc 		break;
327*640eb22bSagc 	case SHA256_HASH_ALG:
328*640eb22bSagc 		SHA256_Final(out, hash->ctx);
329*640eb22bSagc 		break;
330*640eb22bSagc 	case SHA512_HASH_ALG:
331*640eb22bSagc 		SHA512_Final(out, hash->ctx);
332*640eb22bSagc 		break;
333*640eb22bSagc 	case TIGER_HASH_ALG:
334*640eb22bSagc 		TIGER_Final(out, hash->ctx);
335*640eb22bSagc 		break;
336*640eb22bSagc 	default:
337*640eb22bSagc 		printf("hash_any: bad algorithm\n");
338*640eb22bSagc 		return 0;
339*640eb22bSagc 	}
340*640eb22bSagc 	(void) memset(hash->ctx, 0x0, hash->size);
341*640eb22bSagc 	return (unsigned)hash->size;
342*640eb22bSagc }
343*640eb22bSagc 
344*640eb22bSagc int
digest_length(digest_t * hash,unsigned hashedlen)345*640eb22bSagc digest_length(digest_t *hash, unsigned hashedlen)
346*640eb22bSagc {
347*640eb22bSagc 	uint8_t		 trailer[6];
348*640eb22bSagc 
349*640eb22bSagc 	if (hash == NULL) {
350*640eb22bSagc 		return 0;
351*640eb22bSagc 	}
352*640eb22bSagc 	trailer[0] = V4_SIGNATURE;
353*640eb22bSagc 	trailer[1] = 0xFF;
354*640eb22bSagc 	trailer[2] = (uint8_t)((hashedlen >> 24) & 0xff);
355*640eb22bSagc 	trailer[3] = (uint8_t)((hashedlen >> 16) & 0xff);
356*640eb22bSagc 	trailer[4] = (uint8_t)((hashedlen >> 8) & 0xff);
357*640eb22bSagc 	trailer[5] = (uint8_t)(hashedlen & 0xff);
358*640eb22bSagc 	digest_update(hash, trailer, sizeof(trailer));
359*640eb22bSagc 	return 1;
360*640eb22bSagc }
361*640eb22bSagc 
362*640eb22bSagc unsigned
digest_get_prefix(unsigned hashalg,uint8_t * prefix,size_t size)363*640eb22bSagc digest_get_prefix(unsigned hashalg, uint8_t *prefix, size_t size)
364*640eb22bSagc {
365*640eb22bSagc 	if (prefix == NULL) {
366*640eb22bSagc 		return 0;
367*640eb22bSagc 	}
368*640eb22bSagc 	switch (hashalg) {
369*640eb22bSagc 	case MD5_HASH_ALG:
370*640eb22bSagc 		memcpy(prefix, prefix_md5, sizeof(prefix_md5));
371*640eb22bSagc 		return sizeof(prefix_md5);
372*640eb22bSagc 	case SHA1_HASH_ALG:
373*640eb22bSagc 		memcpy(prefix, prefix_sha1, sizeof(prefix_sha1));
374*640eb22bSagc 		return sizeof(prefix_sha1);
375*640eb22bSagc 	case SHA256_HASH_ALG:
376*640eb22bSagc 		memcpy(prefix, prefix_sha256, sizeof(prefix_sha256));
377*640eb22bSagc 		return sizeof(prefix_sha256);
378*640eb22bSagc 	default:
379*640eb22bSagc 		printf("digest_get_prefix: unknown hash algorithm: %d\n", hashalg);
380*640eb22bSagc 		return 0;
381*640eb22bSagc 	}
382*640eb22bSagc }
383*640eb22bSagc 
384