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