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