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
MD5_Init(MD5_CTX * context)90 MD5_Init(MD5_CTX *context)
91 {
92 if (context) {
93 MD5Init(context);
94 }
95 }
96
97 void
MD5_Update(MD5_CTX * context,const unsigned char * data,unsigned int len)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
MD5_Final(unsigned char digest[16],MD5_CTX * context)106 MD5_Final(unsigned char digest[16], MD5_CTX *context)
107 {
108 if (digest && context) {
109 MD5Final(digest, context);
110 }
111 }
112
113 void
SHA1_Init(SHA1_CTX * context)114 SHA1_Init(SHA1_CTX *context)
115 {
116 if (context) {
117 SHA1Init(context);
118 }
119 }
120
121 void
SHA1_Update(SHA1_CTX * context,const unsigned char * data,unsigned int len)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
SHA1_Final(unsigned char digest[20],SHA1_CTX * context)130 SHA1_Final(unsigned char digest[20], SHA1_CTX *context)
131 {
132 if (digest && context) {
133 SHA1Final(digest, context);
134 }
135 }
136
137 void
RMD160_Init(RMD160_CTX * context)138 RMD160_Init(RMD160_CTX *context)
139 {
140 if (context) {
141 RMD160Init(context);
142 }
143 }
144
145 void
RMD160_Update(RMD160_CTX * context,const unsigned char * data,unsigned int len)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
RMD160_Final(unsigned char digest[20],RMD160_CTX * context)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
digest_alg_size(unsigned alg)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
digest_init(digest_t * hash,const uint32_t hashalg)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
digest_get_alg(const char * hashalg)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
digest_update(digest_t * hash,const uint8_t * data,size_t length)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
digest_final(uint8_t * out,digest_t * hash)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
digest_length(digest_t * hash,unsigned hashedlen)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
digest_get_prefix(unsigned hashalg,uint8_t * prefix,size_t size)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