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