| /** @file rhash.h LibRHash interface */ |
| #ifndef RHASH_H |
| #define RHASH_H |
| |
| #include <stdio.h> |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| #ifndef RHASH_API |
| /* modifier for LibRHash functions */ |
| # define RHASH_API |
| #endif |
| |
| /** |
| * Identifiers of supported hash functions. |
| * The rhash_init() function allows mixing several ids using |
| * binary OR, to calculate several hash functions for one message. |
| */ |
| enum rhash_ids |
| { |
| #if 0 |
| RHASH_CRC32 = 0x01, |
| RHASH_MD4 = 0x02, |
| RHASH_MD5 = 0x04, |
| RHASH_SHA1 = 0x08, |
| RHASH_TIGER = 0x10, |
| RHASH_TTH = 0x20, |
| RHASH_BTIH = 0x40, |
| RHASH_ED2K = 0x80, |
| RHASH_AICH = 0x100, |
| RHASH_WHIRLPOOL = 0x200, |
| RHASH_RIPEMD160 = 0x400, |
| RHASH_GOST = 0x800, |
| RHASH_GOST_CRYPTOPRO = 0x1000, |
| RHASH_HAS160 = 0x2000, |
| RHASH_SNEFRU128 = 0x4000, |
| RHASH_SNEFRU256 = 0x8000, |
| RHASH_SHA224 = 0x10000, |
| RHASH_SHA256 = 0x20000, |
| RHASH_SHA384 = 0x40000, |
| RHASH_SHA512 = 0x80000, |
| RHASH_EDONR256 = 0x0100000, |
| RHASH_EDONR512 = 0x0200000, |
| RHASH_SHA3_224 = 0x0400000, |
| RHASH_SHA3_256 = 0x0800000, |
| RHASH_SHA3_384 = 0x1000000, |
| RHASH_SHA3_512 = 0x2000000, |
| |
| /** The bit-mask containing all supported hashe functions */ |
| RHASH_ALL_HASHES = RHASH_CRC32 | RHASH_MD4 | RHASH_MD5 | RHASH_ED2K | RHASH_SHA1 | |
| RHASH_TIGER | RHASH_TTH | RHASH_GOST | RHASH_GOST_CRYPTOPRO | |
| RHASH_BTIH | RHASH_AICH | RHASH_WHIRLPOOL | RHASH_RIPEMD160 | |
| RHASH_HAS160 | RHASH_SNEFRU128 | RHASH_SNEFRU256 | |
| RHASH_SHA224 | RHASH_SHA256 | RHASH_SHA384 | RHASH_SHA512 | |
| RHASH_SHA3_224 | RHASH_SHA3_256 | RHASH_SHA3_384 | RHASH_SHA3_512 | |
| RHASH_EDONR256 | RHASH_EDONR512, |
| |
| /** The number of supported hash functions */ |
| RHASH_HASH_COUNT = 26 |
| #else |
| RHASH_MD5 = 0x01, |
| RHASH_SHA1 = 0x02, |
| RHASH_SHA224 = 0x04, |
| RHASH_SHA256 = 0x08, |
| RHASH_SHA384 = 0x10, |
| RHASH_SHA512 = 0x20, |
| RHASH_SHA3_224 = 0x40, |
| RHASH_SHA3_256 = 0x80, |
| RHASH_SHA3_384 = 0x100, |
| RHASH_SHA3_512 = 0x200, |
| RHASH_ALL_HASHES = |
| RHASH_MD5 | |
| RHASH_SHA1 | |
| RHASH_SHA224 | |
| RHASH_SHA256 | |
| RHASH_SHA384 | |
| RHASH_SHA512 | |
| RHASH_SHA3_224 | |
| RHASH_SHA3_256 | |
| RHASH_SHA3_384 | |
| RHASH_SHA3_512, |
| RHASH_HASH_COUNT = 10 |
| #endif |
| }; |
| |
| /** |
| * The rhash context structure contains contexts for several hash functions |
| */ |
| typedef struct rhash_context |
| { |
| /** The size of the hashed message */ |
| unsigned long long msg_size; |
| |
| /** |
| * The bit-mask containing identifiers of the hashes being calculated |
| */ |
| unsigned hash_id; |
| } rhash_context; |
| |
| #ifndef LIBRHASH_RHASH_CTX_DEFINED |
| #define LIBRHASH_RHASH_CTX_DEFINED |
| /** |
| * Hashing context. |
| */ |
| typedef struct rhash_context* rhash; |
| #endif /* LIBRHASH_RHASH_CTX_DEFINED */ |
| |
| /** type of a callback to be called periodically while hashing a file */ |
| typedef void (*rhash_callback_t)(void* data, unsigned long long offset); |
| |
| RHASH_API void rhash_library_init(void); /* initialize static data */ |
| |
| /* hi-level hashing functions */ |
| RHASH_API int rhash_msg(unsigned hash_id, const void* message, size_t length, unsigned char* result); |
| RHASH_API int rhash_file(unsigned hash_id, const char* filepath, unsigned char* result); |
| RHASH_API int rhash_file_update(rhash ctx, FILE* fd); |
| |
| #ifdef _WIN32 /* windows only function */ |
| RHASH_API int rhash_wfile(unsigned hash_id, const wchar_t* filepath, unsigned char* result); |
| #endif |
| |
| /* lo-level interface */ |
| RHASH_API rhash rhash_init(unsigned hash_id); |
| /*RHASH_API rhash rhash_init_by_ids(unsigned hash_ids[], unsigned count);*/ |
| RHASH_API int rhash_update(rhash ctx, const void* message, size_t length); |
| RHASH_API int rhash_final(rhash ctx, unsigned char* first_result); |
| RHASH_API void rhash_reset(rhash ctx); /* reinitialize the context */ |
| RHASH_API void rhash_free(rhash ctx); |
| |
| /* additional lo-level functions */ |
| RHASH_API void rhash_set_callback(rhash ctx, rhash_callback_t callback, void* callback_data); |
| |
| /** bit-flag: default hash output format is base32 */ |
| #define RHASH_INFO_BASE32 1 |
| |
| /** |
| * Information about a hash function. |
| */ |
| typedef struct rhash_info |
| { |
| /** hash function indentifier */ |
| unsigned hash_id; |
| /** flags bit-mask, including RHASH_INFO_BASE32 bit */ |
| unsigned flags; |
| /** size of binary message digest in bytes */ |
| size_t digest_size; |
| const char* name; |
| const char* magnet_name; |
| } rhash_info; |
| |
| /* information functions */ |
| RHASH_API int rhash_count(void); /* number of supported hashes */ |
| RHASH_API int rhash_get_digest_size(unsigned hash_id); /* size of binary message digest */ |
| RHASH_API int rhash_get_hash_length(unsigned hash_id); /* length of formatted hash string */ |
| RHASH_API int rhash_is_base32(unsigned hash_id); /* default digest output format */ |
| RHASH_API const char* rhash_get_name(unsigned hash_id); /* get hash function name */ |
| RHASH_API const char* rhash_get_magnet_name(unsigned hash_id); /* get name part of magnet urn */ |
| |
| /* note, that rhash_info_by_id() is not exported to a shared library or DLL */ |
| const rhash_info* rhash_info_by_id(unsigned hash_id); /* get hash sum info by hash id */ |
| |
| #if 0 |
| /** |
| * Flags for printing a hash sum |
| */ |
| enum rhash_print_sum_flags |
| { |
| /** print in a default format */ |
| RHPR_DEFAULT = 0x0, |
| /** output as binary message digest */ |
| RHPR_RAW = 0x1, |
| /** print as a hexadecimal string */ |
| RHPR_HEX = 0x2, |
| /** print as a base32-encoded string */ |
| RHPR_BASE32 = 0x3, |
| /** print as a base64-encoded string */ |
| RHPR_BASE64 = 0x4, |
| |
| /** |
| * Print as an uppercase string. Can be used |
| * for base32 or hexadecimal format only. |
| */ |
| RHPR_UPPERCASE = 0x8, |
| |
| /** |
| * Reverse hash bytes. Can be used for GOST hash. |
| */ |
| RHPR_REVERSE = 0x10, |
| |
| /** don't print 'magnet:?' prefix in rhash_print_magnet */ |
| RHPR_NO_MAGNET = 0x20, |
| /** print file size in rhash_print_magnet */ |
| RHPR_FILESIZE = 0x40, |
| }; |
| #endif |
| |
| /* output hash into the given buffer */ |
| RHASH_API size_t rhash_print_bytes(char* output, |
| const unsigned char* bytes, size_t size, int flags); |
| |
| RHASH_API size_t rhash_print(char* output, rhash ctx, unsigned hash_id, |
| int flags); |
| |
| /* output magnet URL into the given buffer */ |
| RHASH_API size_t rhash_print_magnet(char* output, const char* filepath, |
| rhash context, unsigned hash_mask, int flags); |
| |
| /* macros for message API */ |
| |
| /** The type of an unsigned integer large enough to hold a pointer */ |
| #if defined(UINTPTR_MAX) |
| typedef uintptr_t rhash_uptr_t; |
| #elif defined(_LP64) || defined(__LP64__) || defined(__x86_64) || \ |
| defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64) |
| typedef unsigned long long rhash_uptr_t; |
| #else |
| typedef unsigned long rhash_uptr_t; |
| #endif |
| |
| /** The value returned by rhash_transmit on error */ |
| #define RHASH_ERROR ((rhash_uptr_t)-1) |
| /** Convert a pointer to rhash_uptr_t */ |
| #define RHASH_STR2UPTR(str) ((rhash_uptr_t)(char*)(str)) |
| /** Convert a rhash_uptr_t to a void* pointer */ |
| #define RHASH_UPTR2PVOID(u) ((void*)((char*)0 + (u))) |
| |
| /* rhash API to set/get data via messages */ |
| RHASH_API rhash_uptr_t rhash_transmit( |
| unsigned msg_id, void* dst, rhash_uptr_t ldata, rhash_uptr_t rdata); |
| |
| /* rhash message constants */ |
| |
| #define RMSG_GET_CONTEXT 1 |
| #define RMSG_CANCEL 2 |
| #define RMSG_IS_CANCELED 3 |
| #define RMSG_GET_FINALIZED 4 |
| #define RMSG_SET_AUTOFINAL 5 |
| #define RMSG_SET_OPENSSL_MASK 10 |
| #define RMSG_GET_OPENSSL_MASK 11 |
| |
| /* helper macros */ |
| |
| /** Get a pointer to context of the specified hash function */ |
| #define rhash_get_context_ptr(ctx, hash_id) RHASH_UPTR2PVOID(rhash_transmit(RMSG_GET_CONTEXT, ctx, hash_id, 0)) |
| /** Cancel hash calculation of a file */ |
| #define rhash_cancel(ctx) rhash_transmit(RMSG_CANCEL, ctx, 0, 0) |
| /** Return non-zero if hash calculation was canceled, zero otherwise */ |
| #define rhash_is_canceled(ctx) rhash_transmit(RMSG_IS_CANCELED, ctx, 0, 0) |
| /** Return non-zero if rhash_final was called for rhash_context */ |
| #define rhash_get_finalized(ctx) rhash_transmit(RMSG_GET_FINALIZED, ctx, 0, 0) |
| |
| /** |
| * Turn on/off the auto-final flag for the given rhash_context. By default |
| * auto-final is on, which means rhash_final is called automatically, if |
| * needed when a hash value is retrived by rhash_print call. |
| */ |
| #define rhash_set_autofinal(ctx, on) rhash_transmit(RMSG_SET_AUTOFINAL, ctx, on, 0) |
| |
| /** |
| * Set the bit-mask of hash algorithms to be calculated by OpenSSL library. |
| * The call rhash_set_openssl_mask(0) made before rhash_library_init(), |
| * turns off loading of the OpenSSL dynamic library. |
| * This call works if the LibRHash was compiled with OpenSSL support. |
| */ |
| #define rhash_set_openssl_mask(mask) rhash_transmit(RMSG_SET_OPENSSL_MASK, NULL, mask, 0) |
| |
| /** |
| * Return current bit-mask of hash algorithms selected to be calculated |
| * by OpenSSL library. |
| */ |
| #define rhash_get_openssl_mask() rhash_transmit(RMSG_GET_OPENSSL_MASK, NULL, 0, 0) |
| |
| /** The bit mask of hash algorithms implemented by OpenSSL */ |
| #if defined(USE_OPENSSL) || defined(OPENSSL_RUNTIME) |
| # define RHASH_OPENSSL_SUPPORTED_HASHES (RHASH_MD4 | RHASH_MD5 | \ |
| RHASH_SHA1 | RHASH_SHA224 | RHASH_SHA256 | RHASH_SHA384 | \ |
| RHASH_SHA512 | RHASH_RIPEMD160 | RHASH_WHIRLPOOL) |
| #else |
| # define RHASH_OPENSSL_SUPPORTED_HASHES 0 |
| #endif |
| |
| #ifdef __cplusplus |
| } /* extern "C" */ |
| #endif /* __cplusplus */ |
| |
| #endif /* RHASH_H */ |