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