1 /** @file rhash.h LibRHash interface */ 2 #ifndef RHASH_H 3 #define RHASH_H 4 5 #include <stdio.h> 6 7 #ifdef __cplusplus 8 extern "C" { 9 #endif 10 11 #ifndef RHASH_API 12 /** 13 * Modifier for LibRHash functions 14 */ 15 # define RHASH_API 16 #endif 17 18 /** 19 * Identifiers of supported hash functions. 20 * The rhash_init() function allows mixing several ids using 21 * binary OR, to calculate several hash functions for one message. 22 */ 23 enum rhash_ids 24 { 25 #if 0 26 RHASH_CRC32 = 0x01, 27 RHASH_MD4 = 0x02, 28 RHASH_MD5 = 0x04, 29 RHASH_SHA1 = 0x08, 30 RHASH_TIGER = 0x10, 31 RHASH_TTH = 0x20, 32 RHASH_BTIH = 0x40, 33 RHASH_ED2K = 0x80, 34 RHASH_AICH = 0x100, 35 RHASH_WHIRLPOOL = 0x200, 36 RHASH_RIPEMD160 = 0x400, 37 RHASH_GOST94 = 0x800, 38 RHASH_GOST94_CRYPTOPRO = 0x1000, 39 RHASH_HAS160 = 0x2000, 40 RHASH_GOST12_256 = 0x4000, 41 RHASH_GOST12_512 = 0x8000, 42 RHASH_SHA224 = 0x10000, 43 RHASH_SHA256 = 0x20000, 44 RHASH_SHA384 = 0x40000, 45 RHASH_SHA512 = 0x80000, 46 RHASH_EDONR256 = 0x0100000, 47 RHASH_EDONR512 = 0x0200000, 48 RHASH_SHA3_224 = 0x0400000, 49 RHASH_SHA3_256 = 0x0800000, 50 RHASH_SHA3_384 = 0x1000000, 51 RHASH_SHA3_512 = 0x2000000, 52 RHASH_CRC32C = 0x4000000, 53 RHASH_SNEFRU128 = 0x8000000, 54 RHASH_SNEFRU256 = 0x10000000, 55 56 /** 57 * The bit-mask containing all supported hashe functions. 58 */ 59 RHASH_ALL_HASHES = RHASH_CRC32 | RHASH_CRC32C | RHASH_MD4 | RHASH_MD5 | 60 RHASH_ED2K | RHASH_SHA1 |RHASH_TIGER | RHASH_TTH | 61 RHASH_GOST94 | RHASH_GOST94_CRYPTOPRO | RHASH_GOST12_256 | RHASH_GOST12_512 | 62 RHASH_BTIH | RHASH_AICH | RHASH_WHIRLPOOL | RHASH_RIPEMD160 | 63 RHASH_HAS160 | RHASH_SNEFRU128 | RHASH_SNEFRU256 | 64 RHASH_SHA224 | RHASH_SHA256 | RHASH_SHA384 | RHASH_SHA512 | 65 RHASH_SHA3_224 | RHASH_SHA3_256 | RHASH_SHA3_384 | RHASH_SHA3_512 | 66 RHASH_EDONR256 | RHASH_EDONR512, 67 68 RHASH_GOST = RHASH_GOST94, /* deprecated constant name */ 69 RHASH_GOST_CRYPTOPRO = RHASH_GOST94_CRYPTOPRO, /* deprecated constant name */ 70 /** 71 * The number of supported hash functions. 72 */ 73 RHASH_HASH_COUNT = 29 74 #else 75 RHASH_MD5 = 0x01, 76 RHASH_SHA1 = 0x02, 77 RHASH_SHA224 = 0x04, 78 RHASH_SHA256 = 0x08, 79 RHASH_SHA384 = 0x10, 80 RHASH_SHA512 = 0x20, 81 RHASH_SHA3_224 = 0x40, 82 RHASH_SHA3_256 = 0x80, 83 RHASH_SHA3_384 = 0x100, 84 RHASH_SHA3_512 = 0x200, 85 RHASH_ALL_HASHES = 86 RHASH_MD5 | 87 RHASH_SHA1 | 88 RHASH_SHA224 | 89 RHASH_SHA256 | 90 RHASH_SHA384 | 91 RHASH_SHA512 | 92 RHASH_SHA3_224 | 93 RHASH_SHA3_256 | 94 RHASH_SHA3_384 | 95 RHASH_SHA3_512, 96 RHASH_HASH_COUNT = 10 97 #endif 98 }; 99 100 /** 101 * The rhash context structure contains contexts for several hash functions. 102 */ 103 typedef struct rhash_context 104 { 105 /** 106 * The size of the hashed message. 107 */ 108 unsigned long long msg_size; 109 110 /** 111 * The bit-mask containing identifiers of the hashes being calculated. 112 */ 113 unsigned hash_id; 114 } rhash_context; 115 116 #ifndef LIBRHASH_RHASH_CTX_DEFINED 117 #define LIBRHASH_RHASH_CTX_DEFINED 118 /** 119 * Hashing context. 120 */ 121 typedef struct rhash_context* rhash; 122 #endif /* LIBRHASH_RHASH_CTX_DEFINED */ 123 124 /** 125 * Type of a callback to be called periodically while hashing a file. 126 */ 127 typedef void (*rhash_callback_t)(void* data, unsigned long long offset); 128 129 /** 130 * Initialize static data of rhash algorithms 131 */ 132 RHASH_API void rhash_library_init(void); 133 134 135 /* HIGH-LEVEL LIBRHASH INTERFACE */ 136 137 /** 138 * Compute a hash of the given message. 139 * 140 * @param hash_id id of hash sum to compute 141 * @param message the message to process 142 * @param length message length 143 * @param result buffer to receive binary hash string 144 * @return 0 on success, -1 on error 145 */ 146 RHASH_API int rhash_msg(unsigned hash_id, const void* message, size_t length, unsigned char* result); 147 148 /** 149 * Compute a single hash for given file. 150 * 151 * @param hash_id id of hash sum to compute 152 * @param filepath path to the file to hash 153 * @param result buffer to receive hash value with the lowest requested id 154 * @return 0 on success, -1 on error and errno is set 155 */ 156 RHASH_API int rhash_file(unsigned hash_id, const char* filepath, unsigned char* result); 157 158 #ifdef _WIN32 159 /** 160 * Compute a single hash for given file (Windows-specific function). 161 * 162 * @param hash_id id of hash sum to compute 163 * @param filepath path to the file to hash 164 * @param result buffer to receive hash value with the lowest requested id 165 * @return 0 on success, -1 on error, -1 on error and errno is set 166 */ 167 RHASH_API int rhash_wfile(unsigned hash_id, const wchar_t* filepath, unsigned char* result); 168 #endif 169 170 171 /* LOW-LEVEL LIBRHASH INTERFACE */ 172 173 /** 174 * Allocate and initialize RHash context for calculating hash(es). 175 * After initializing rhash_update()/rhash_final() functions should be used. 176 * Then the context must be freed by calling rhash_free(). 177 * 178 * @param hash_id union of bit flags, containing ids of hashes to calculate. 179 * @return initialized rhash context, NULL on error and errno is set 180 */ 181 RHASH_API rhash rhash_init(unsigned hash_id); 182 183 /** 184 * Calculate hashes of message. 185 * Can be called repeatedly with chunks of the message to be hashed. 186 * 187 * @param ctx the rhash context 188 * @param message message chunk 189 * @param length length of the message chunk 190 * @return 0 on success; On fail return -1 and set errno 191 */ 192 RHASH_API int rhash_update(rhash ctx, const void* message, size_t length); 193 194 /** 195 * Hash a file or stream. Multiple hashes can be computed. 196 * First, inintialize ctx parameter with rhash_init() before calling 197 * rhash_file_update(). Then use rhash_final() and rhash_print() 198 * to retrive hash values. Finaly call rhash_free() on ctx 199 * to free allocated memory or call rhash_reset() to reuse ctx. 200 * 201 * @param ctx rhash context 202 * @param fd descriptor of the file to hash 203 * @return 0 on success, -1 on error and errno is set 204 */ 205 RHASH_API int rhash_file_update(rhash ctx, FILE* fd); 206 207 /** 208 * Finalize hash calculation and optionally store the first hash. 209 * 210 * @param ctx the rhash context 211 * @param first_result optional buffer to store a calculated hash with the lowest available id 212 * @return 0 on success; On fail return -1 and set errno 213 */ 214 RHASH_API int rhash_final(rhash ctx, unsigned char* first_result); 215 216 /** 217 * Re-initialize RHash context to reuse it. 218 * Useful to speed up processing of many small messages. 219 * 220 * @param ctx context to reinitialize 221 */ 222 RHASH_API void rhash_reset(rhash ctx); 223 224 /** 225 * Free RHash context memory. 226 * 227 * @param ctx the context to free. 228 */ 229 RHASH_API void rhash_free(rhash ctx); 230 231 /** 232 * Set the callback function to be called from the 233 * rhash_file() and rhash_file_update() functions 234 * on processing every file block. The file block 235 * size is set internally by rhash and now is 8 KiB. 236 * 237 * @param ctx rhash context 238 * @param callback pointer to the callback function 239 * @param callback_data pointer to data passed to the callback 240 */ 241 RHASH_API void rhash_set_callback(rhash ctx, rhash_callback_t callback, void* callback_data); 242 243 244 /* INFORMATION FUNCTIONS */ 245 246 /** 247 * Returns the number of supported hash algorithms. 248 * 249 * @return the number of supported hash functions 250 */ 251 RHASH_API int rhash_count(void); /* number of supported hashes */ 252 253 /** 254 * Returns size of binary digest for given hash algorithm. 255 * 256 * @param hash_id the id of hash algorithm 257 * @return digest size in bytes 258 */ 259 RHASH_API int rhash_get_digest_size(unsigned hash_id); /* size of binary message digest */ 260 261 /** 262 * Returns length of digest hash string in default output format. 263 * 264 * @param hash_id the id of hash algorithm 265 * @return the length of hash string 266 */ 267 RHASH_API int rhash_get_hash_length(unsigned hash_id); /* length of formatted hash string */ 268 269 /** 270 * Detect default digest output format for given hash algorithm. 271 * 272 * @param hash_id the id of hash algorithm 273 * @return 1 for base32 format, 0 for hexadecimal 274 */ 275 RHASH_API int rhash_is_base32(unsigned hash_id); /* default digest output format */ 276 277 /** 278 * Returns a name of given hash algorithm. 279 * 280 * @param hash_id the id of hash algorithm 281 * @return algorithm name 282 */ 283 RHASH_API const char* rhash_get_name(unsigned hash_id); /* get hash function name */ 284 285 /** 286 * Returns a name part of magnet urn of the given hash algorithm. 287 * Such magnet_name is used to generate a magnet link of the form 288 * urn:<magnet_name>=<hash_value>. 289 * 290 * @param hash_id the id of hash algorithm 291 * @return name 292 */ 293 RHASH_API const char* rhash_get_magnet_name(unsigned hash_id); /* get name part of magnet urn */ 294 295 /* HASH SUM OUTPUT INTERFACE */ 296 297 #if 0 298 /** 299 * Flags for printing a hash sum. 300 */ 301 enum rhash_print_sum_flags 302 { 303 /* 304 * Print in a default format 305 */ 306 RHPR_DEFAULT = 0x0, 307 /* 308 * Output as binary message digest 309 */ 310 RHPR_RAW = 0x1, 311 /* 312 * Print as a hexadecimal string 313 */ 314 RHPR_HEX = 0x2, 315 /* 316 * Print as a base32-encoded string 317 */ 318 RHPR_BASE32 = 0x3, 319 /* 320 * Print as a base64-encoded string 321 */ 322 RHPR_BASE64 = 0x4, 323 /* 324 * Print as an uppercase string. Can be used 325 * for base32 or hexadecimal format only. 326 */ 327 RHPR_UPPERCASE = 0x8, 328 /* 329 * Reverse hash bytes. Can be used for GOST hash. 330 */ 331 RHPR_REVERSE = 0x10, 332 /* 333 * Don't print 'magnet:?' prefix in rhash_print_magnet 334 */ 335 RHPR_NO_MAGNET = 0x20, 336 /* 337 * Print file size in rhash_print_magnet 338 */ 339 RHPR_FILESIZE = 0x40, 340 /* 341 * Print as URL-encoded string 342 */ 343 RHPR_URLENCODE = 0x80 344 }; 345 #endif 346 347 348 /** 349 * Print a text presentation of a given hash sum to the specified buffer. 350 * 351 * @param output a buffer to print the hash to 352 * @param bytes a hash sum to print 353 * @param size a size of hash sum in bytes 354 * @param flags a bit-mask controlling how to format the hash sum, 355 * can be a mix of the flags: RHPR_RAW, RHPR_HEX, RHPR_BASE32, 356 * RHPR_BASE64, RHPR_URLENCODE, RHPR_UPPERCASE, RHPR_REVERSE 357 * @return the number of written characters 358 */ 359 RHASH_API size_t rhash_print_bytes(char* output, 360 const unsigned char* bytes, size_t size, int flags); 361 362 /** 363 * Print text presentation of a hash sum with given hash_id to the specified 364 * output buffer. If the hash_id is zero, then print the hash sum with 365 * the lowest id stored in the hash context. 366 * The function call fails if the context doesn't include a hash with the 367 * given hash_id. 368 * 369 * @param output a buffer to print the hash to 370 * @param ctx algorithms state 371 * @param hash_id id of the hash sum to print or 0 to print the first hash 372 * saved in the context. 373 * @param flags a bitmask controlling how to print the hash. Can contain flags 374 * RHPR_UPPERCASE, RHPR_HEX, RHPR_BASE32, RHPR_BASE64, etc. 375 * @return the number of written characters on success or 0 on fail 376 */ 377 RHASH_API size_t rhash_print(char* output, rhash ctx, unsigned hash_id, 378 int flags); 379 380 /** 381 * Print magnet link with given filepath and calculated hash sums into the 382 * output buffer. The hash_mask can limit which hash values will be printed. 383 * The function returns the size of the required buffer. 384 * If output is NULL the . 385 * 386 * @param output a string buffer to receive the magnet link or NULL 387 * @param filepath the file path to be printed or NULL 388 * @param context algorithms state 389 * @param hash_mask bit mask of the hash sums to add to the link 390 * @param flags can be combination of bits RHPR_UPPERCASE, RHPR_NO_MAGNET, 391 * RHPR_FILESIZE 392 * @return number of written characters, including terminating '\0' on success, 0 on fail 393 */ 394 RHASH_API size_t rhash_print_magnet(char* output, const char* filepath, 395 rhash context, unsigned hash_mask, int flags); 396 397 398 /* MESSAGE API */ 399 400 /** 401 * The type of an unsigned integer large enough to hold a pointer. 402 */ 403 #if defined(UINTPTR_MAX) 404 typedef uintptr_t rhash_uptr_t; 405 #elif defined(_LP64) || defined(__LP64__) || defined(__x86_64) || \ 406 defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64) 407 typedef unsigned long long rhash_uptr_t; 408 #else 409 typedef unsigned long rhash_uptr_t; 410 #endif 411 412 /** 413 * The value returned by rhash_transmit on error. 414 */ 415 #define RHASH_ERROR ((rhash_uptr_t)-1) 416 /** 417 * Convert a pointer to rhash_uptr_t. 418 */ 419 #define RHASH_STR2UPTR(str) ((rhash_uptr_t)(char*)(str)) 420 /** 421 * Convert a rhash_uptr_t to a void* pointer. 422 */ 423 #define RHASH_UPTR2PVOID(u) ((void*)((u) + 0)) 424 425 /** 426 * Process a rhash message. 427 * 428 * @param msg_id message identifier 429 * @param dst message destination (can be NULL for generic messages) 430 * @param ldata data depending on message 431 * @param rdata data depending on message 432 * @return message-specific data 433 */ 434 RHASH_API rhash_uptr_t rhash_transmit( 435 unsigned msg_id, void* dst, rhash_uptr_t ldata, rhash_uptr_t rdata); 436 437 /* rhash message constants */ 438 439 #define RMSG_GET_CONTEXT 1 440 #define RMSG_CANCEL 2 441 #define RMSG_IS_CANCELED 3 442 #define RMSG_GET_FINALIZED 4 443 #define RMSG_SET_AUTOFINAL 5 444 #define RMSG_SET_OPENSSL_MASK 10 445 #define RMSG_GET_OPENSSL_MASK 11 446 #define RMSG_GET_OPENSSL_SUPPORTED_MASK 12 447 #define RMSG_GET_OPENSSL_AVAILABLE_MASK 13 448 449 /* HELPER MACROS */ 450 451 /** 452 * Get a pointer to context of the specified hash function. 453 */ 454 #define rhash_get_context_ptr(ctx, hash_id) RHASH_UPTR2PVOID(rhash_transmit(RMSG_GET_CONTEXT, ctx, hash_id, 0)) 455 /** 456 * Cancel hash calculation of a file. 457 */ 458 #define rhash_cancel(ctx) rhash_transmit(RMSG_CANCEL, ctx, 0, 0) 459 /** 460 * Return non-zero if hash calculation was canceled, zero otherwise. 461 */ 462 #define rhash_is_canceled(ctx) rhash_transmit(RMSG_IS_CANCELED, ctx, 0, 0) 463 /** 464 * Return non-zero if rhash_final was called for rhash_context. 465 */ 466 #define rhash_get_finalized(ctx) rhash_transmit(RMSG_GET_FINALIZED, ctx, 0, 0) 467 468 /** 469 * Turn on/off the auto-final flag for the given rhash_context. By default 470 * auto-final is on, which means rhash_final is called automatically, if 471 * needed when a hash value is retrieved by rhash_print call. 472 */ 473 #define rhash_set_autofinal(ctx, on) rhash_transmit(RMSG_SET_AUTOFINAL, ctx, on, 0) 474 475 /** 476 * Set the bit-mask of hash algorithms to be calculated by OpenSSL library. 477 * The call rhash_set_openssl_mask(0) made before rhash_library_init(), 478 * turns off loading of the OpenSSL dynamic library. 479 * This call works if the LibRHash was compiled with OpenSSL support. 480 */ 481 #define rhash_set_openssl_mask(mask) rhash_transmit(RMSG_SET_OPENSSL_MASK, NULL, mask, 0) 482 483 /** 484 * Return current bit-mask of hash algorithms selected to be calculated by OpenSSL 485 * library. Return RHASH_ERROR if LibRHash is compiled without OpenSSL support. 486 */ 487 #define rhash_get_openssl_mask() rhash_transmit(RMSG_GET_OPENSSL_MASK, NULL, 0, 0) 488 489 /** 490 * Return the bit-mask of algorithms that can be provided by the OpenSSL plugin, 491 * if the library is compiled with OpenSSL support, 0 otherwise. This bit-mask is 492 * a constant value computed at compile-time. 493 */ 494 #define rhash_get_openssl_supported_mask() rhash_transmit(RMSG_GET_OPENSSL_SUPPORTED_MASK, NULL, 0, 0) 495 496 /** 497 * Return the bit-mask of algorithms that are successfully loaded from 498 * OpenSSL library. If the library is not loaded or not supported by LibRHash, 499 * then return 0. 500 */ 501 #define rhash_get_openssl_available_mask() rhash_transmit(RMSG_GET_OPENSSL_AVAILABLE_MASK, NULL, 0, 0) 502 503 504 /** 505 * Return non-zero if LibRHash hash been compiled with OpenSSL support, 506 * and zero otherwise. 507 */ 508 #define rhash_is_openssl_supported() (rhash_get_openssl_mask() != RHASH_ERROR) 509 510 /** 511 * Legacy macro. The bit mask of hash algorithms implemented by OpenSSL. 512 */ 513 # define RHASH_OPENSSL_SUPPORTED_HASHES (rhash_get_openssl_supported_mask()) 514 515 #ifdef __cplusplus 516 } /* extern "C" */ 517 #endif /* __cplusplus */ 518 519 #endif /* RHASH_H */ 520