/** @file rhash.h LibRHash interface */1#ifndef RHASH_H2#define RHASH_H34#include <stdio.h>56#ifdef __cplusplus7extern "C" {8#endif910#ifndef RHASH_API11/**12* Modifier for LibRHash functions13*/14# define RHASH_API15#endif1617/**18* Identifiers of supported hash functions.19* The rhash_init() function allows mixing several ids using20* binary OR, to calculate several hash functions for one message.21*/22enum rhash_ids23{24#if 025RHASH_CRC32 = 0x01,26RHASH_MD4 = 0x02,27RHASH_MD5 = 0x04,28RHASH_SHA1 = 0x08,29RHASH_TIGER = 0x10,30RHASH_TTH = 0x20,31RHASH_BTIH = 0x40,32RHASH_ED2K = 0x80,33RHASH_AICH = 0x100,34RHASH_WHIRLPOOL = 0x200,35RHASH_RIPEMD160 = 0x400,36RHASH_GOST94 = 0x800,37RHASH_GOST94_CRYPTOPRO = 0x1000,38RHASH_HAS160 = 0x2000,39RHASH_GOST12_256 = 0x4000,40RHASH_GOST12_512 = 0x8000,41RHASH_SHA224 = 0x10000,42RHASH_SHA256 = 0x20000,43RHASH_SHA384 = 0x40000,44RHASH_SHA512 = 0x80000,45RHASH_EDONR256 = 0x0100000,46RHASH_EDONR512 = 0x0200000,47RHASH_SHA3_224 = 0x0400000,48RHASH_SHA3_256 = 0x0800000,49RHASH_SHA3_384 = 0x1000000,50RHASH_SHA3_512 = 0x2000000,51RHASH_CRC32C = 0x4000000,52RHASH_SNEFRU128 = 0x8000000,53RHASH_SNEFRU256 = 0x10000000,54RHASH_BLAKE2S = 0x20000000,55RHASH_BLAKE2B = 0x40000000,5657/**58* The bit-mask containing all supported hash functions.59*/60RHASH_ALL_HASHES = RHASH_CRC32 | RHASH_CRC32C | RHASH_MD4 | RHASH_MD5 |61RHASH_ED2K | RHASH_SHA1 |RHASH_TIGER | RHASH_TTH |62RHASH_GOST94 | RHASH_GOST94_CRYPTOPRO | RHASH_GOST12_256 | RHASH_GOST12_512 |63RHASH_BTIH | RHASH_AICH | RHASH_WHIRLPOOL | RHASH_RIPEMD160 |64RHASH_HAS160 | RHASH_SNEFRU128 | RHASH_SNEFRU256 |65RHASH_SHA224 | RHASH_SHA256 | RHASH_SHA384 | RHASH_SHA512 |66RHASH_SHA3_224 | RHASH_SHA3_256 | RHASH_SHA3_384 | RHASH_SHA3_512 |67RHASH_EDONR256 | RHASH_EDONR512 | RHASH_BLAKE2S | RHASH_BLAKE2B,6869RHASH_GOST = RHASH_GOST94, /* deprecated constant name */70RHASH_GOST_CRYPTOPRO = RHASH_GOST94_CRYPTOPRO, /* deprecated constant name */7172/* bit-flag for extra hash identifiers */73RHASH_EXTENDED_BIT = (int)0x80000000,7475/**76* The number of supported hash functions.77*/78RHASH_HASH_COUNT = 3179#else80RHASH_MD5 = 0x01,81RHASH_SHA1 = 0x02,82RHASH_SHA224 = 0x04,83RHASH_SHA256 = 0x08,84RHASH_SHA384 = 0x10,85RHASH_SHA512 = 0x20,86RHASH_SHA3_224 = 0x40,87RHASH_SHA3_256 = 0x80,88RHASH_SHA3_384 = 0x100,89RHASH_SHA3_512 = 0x200,90RHASH_ALL_HASHES =91RHASH_MD5 |92RHASH_SHA1 |93RHASH_SHA224 |94RHASH_SHA256 |95RHASH_SHA384 |96RHASH_SHA512 |97RHASH_SHA3_224 |98RHASH_SHA3_256 |99RHASH_SHA3_384 |100RHASH_SHA3_512,101RHASH_HASH_COUNT = 10102#endif103};104105/**106* The rhash context structure contains contexts for several hash functions.107*/108struct rhash_context109{110/**111* The size of the hashed message.112*/113unsigned long long msg_size;114115/**116* The bit-mask containing identifiers of the hash functions being calculated.117*/118unsigned hash_id;119};120121#ifndef LIBRHASH_RHASH_CTX_DEFINED122#define LIBRHASH_RHASH_CTX_DEFINED123/**124* Hashing context.125*/126typedef struct rhash_context* rhash;127#endif /* LIBRHASH_RHASH_CTX_DEFINED */128129/**130* Type of a callback to be called periodically while hashing a file.131*/132typedef void (*rhash_callback_t)(void* data, unsigned long long offset);133134/**135* Initialize static data of rhash algorithms136*/137RHASH_API void rhash_library_init(void);138139140/* HIGH-LEVEL LIBRHASH INTERFACE */141142/**143* Compute a message digest of the given message.144*145* @param hash_id id of message digest to compute146* @param message the message to process147* @param length message length148* @param result buffer to receive the binary message digest value149* @return 0 on success, -1 on error150*/151RHASH_API int rhash_msg(unsigned hash_id, const void* message, size_t length, unsigned char* result);152153/**154* Compute a single message digest for the given file.155*156* @param hash_id id of hash function to compute157* @param filepath path to the file to process158* @param result buffer to receive message digest159* @return 0 on success, -1 on fail with error code stored in errno160*/161RHASH_API int rhash_file(unsigned hash_id, const char* filepath, unsigned char* result);162163#ifdef _WIN32164/**165* Compute a single message digest for the given file (Windows-specific function).166*167* @param hash_id id of hash function to compute168* @param filepath path to the file to process169* @param result buffer to receive the binary message digest value170* @return 0 on success, -1 on fail with error code stored in errno171*/172RHASH_API int rhash_wfile(unsigned hash_id, const wchar_t* filepath, unsigned char* result);173#endif174175176/* LOW-LEVEL LIBRHASH INTERFACE */177178/**179* Allocate and initialize RHash context for calculating a single or multiple hash functions.180* The context after usage must be freed by calling rhash_free().181*182* @param count the size of the hash_ids array, the count must be greater than zero183* @param hash_ids array of identifiers of hash functions. Each element must184* be an identifier of one hash function185* @return initialized rhash context, NULL on fail with error code stored in errno186*/187RHASH_API rhash rhash_init_multi(size_t count, const unsigned hash_ids[]);188189/**190* Allocate and initialize RHash context for calculating a single hash function.191*192* This function also supports a depricated way to initialize rhash context193* for multiple hash functions, by passing a bitwise union of several hash194* identifiers. Only single-bit identifiers (not greater than RHASH_SNEFRU256)195* can be used in such bitwise union.196*197* @param hash_id identifier of a hash function198* @return initialized rhash context, NULL on fail with error code stored in errno199*/200RHASH_API rhash rhash_init(unsigned hash_id);201202/**203* Calculate message digests of message.204* Can be called repeatedly with chunks of the message to be hashed.205*206* @param ctx the rhash context207* @param message message chunk208* @param length length of the message chunk209* @return 0 on success, -1 on fail with error code stored in errno210*/211RHASH_API int rhash_update(rhash ctx, const void* message, size_t length);212213/**214* Process a file or stream. Multiple message digests can be computed.215* First, inintialize ctx parameter with rhash_init() before calling216* rhash_file_update(). Then use rhash_final() and rhash_print()217* to retrive message digests. Finaly call rhash_free() on ctx218* to free allocated memory or call rhash_reset() to reuse ctx.219*220* @param ctx rhash context221* @param fd descriptor of the file to hash222* @return 0 on success, -1 on fail with error code stored in errno223*/224RHASH_API int rhash_file_update(rhash ctx, FILE* fd);225226/**227* Finalize message digest calculation and optionally store the first message digest.228*229* @param ctx the rhash context230* @param first_result optional buffer to store a calculated message digest with the lowest available id231* @return 0 on success, -1 on fail with error code stored in errno232*/233RHASH_API int rhash_final(rhash ctx, unsigned char* first_result);234235/**236* Re-initialize RHash context to reuse it.237* Useful to speed up processing of many small messages.238*239* @param ctx context to reinitialize240*/241RHASH_API void rhash_reset(rhash ctx);242243/**244* Free RHash context memory.245*246* @param ctx the context to free247*/248RHASH_API void rhash_free(rhash ctx);249250/**251* Set the callback function to be called from the252* rhash_file() and rhash_file_update() functions253* on processing every file block. The file block254* size is set internally by rhash and now is 8 KiB.255*256* @param ctx rhash context257* @param callback pointer to the callback function258* @param callback_data pointer to data passed to the callback259*/260RHASH_API void rhash_set_callback(rhash ctx, rhash_callback_t callback, void* callback_data);261262/**263* Export RHash context data to a memory region.264* The size of the memory required for export265* is returned by rhash_export(ctx, NULL, 0).266*267* @param ctx the rhash context to export268* @param out pointer to a memory region, or NULL269* @param size the size of a memory region270* @return the size of exported data on success export.271* The size of memory required for export if out is NULL.272* 0 on fail with error code stored in errno273*/274RHASH_API size_t rhash_export(rhash ctx, void* out, size_t size);275276/**277* Import rhash context from a memory region.278* The returned rhash context must be released after usage279* by rhash_free().280*281* @param in pointer to a memory region282* @param size the size of a memory region283* @return imported rhash context on success,284* NULL on fail with error code stored in errno285*/286RHASH_API rhash rhash_import(const void* in, size_t size);287288/* INFORMATION FUNCTIONS */289290/**291* Returns the number of supported hash algorithms.292*293* @return the number of supported hash functions294*/295RHASH_API int rhash_count(void);296297/**298* Returns the size of binary message digest for given hash function.299*300* @param hash_id the id of the hash function301* @return the size of the message digest in bytes302*/303RHASH_API int rhash_get_digest_size(unsigned hash_id);304305/**306* Returns the length of message digest string in its default output format.307*308* @param hash_id the id of the hash function309* @return the length of the message digest310*/311RHASH_API int rhash_get_hash_length(unsigned hash_id);312313/**314* Detect default message digest output format for the given hash algorithm.315*316* @param hash_id the id of hash algorithm317* @return 1 for base32 format, 0 for hexadecimal318*/319RHASH_API int rhash_is_base32(unsigned hash_id);320321/**322* Returns the name of the given hash function.323*324* @param hash_id id of the hash function325* @return hash function name326*/327RHASH_API const char* rhash_get_name(unsigned hash_id); /* get hash function name */328329/**330* Returns a name part of magnet urn of the given hash algorithm.331* Such magnet_name is used to generate a magnet link of the form332* urn:<magnet_name>=<hash_value>.333*334* @param hash_id id of the hash algorithm335* @return name336*/337RHASH_API const char* rhash_get_magnet_name(unsigned hash_id); /* get name part of magnet urn */338339/* HASH SUM OUTPUT INTERFACE */340341#if 0342/**343* Flags for printing a message digest.344*/345enum rhash_print_sum_flags346{347/*348* Print in a default format349*/350RHPR_DEFAULT = 0x0,351/*352* Output as binary message digest353*/354RHPR_RAW = 0x1,355/*356* Print as a hexadecimal string357*/358RHPR_HEX = 0x2,359/*360* Print as a base32-encoded string361*/362RHPR_BASE32 = 0x3,363/*364* Print as a base64-encoded string365*/366RHPR_BASE64 = 0x4,367/*368* Print as an uppercase string. Can be used369* for base32 or hexadecimal format only.370*/371RHPR_UPPERCASE = 0x8,372/*373* Reverse message digest bytes. Can be used for GOST hash functions.374*/375RHPR_REVERSE = 0x10,376/*377* Don't print 'magnet:?' prefix in rhash_print_magnet378*/379RHPR_NO_MAGNET = 0x20,380/*381* Print file size in rhash_print_magnet382*/383RHPR_FILESIZE = 0x40,384/*385* Print as URL-encoded string386*/387RHPR_URLENCODE = 0x80388};389#endif390391392/**393* Print to the specified buffer the text representation of the given message digest.394*395* @param output a buffer to print the message digest to396* @param bytes a binary message digest to print397* @param size a size of the message digest in bytes398* @param flags a bit-mask controlling how to format the message digest,399* can be a mix of the flags: RHPR_RAW, RHPR_HEX, RHPR_BASE32,400* RHPR_BASE64, RHPR_URLENCODE, RHPR_UPPERCASE, RHPR_REVERSE401* @return the number of written characters402*/403RHASH_API size_t rhash_print_bytes(char* output,404const unsigned char* bytes, size_t size, int flags);405406/**407* Print to the specified output buffer the text representation of the message digest408* with the given hash_id. If the hash_id is zero, then print the message digest with409* the lowest hash_id calculated by the hash context.410* The function call fails if the context doesn't include the message digest with the411* given hash_id.412*413* @param output a buffer to print the message digest to414* @param ctx algorithms state415* @param hash_id id of the message digest to print or 0 to print the first416* message digest saved in the context.417* @param flags a bitmask controlling how to print the message digest. Can contain418* flags RHPR_UPPERCASE, RHPR_HEX, RHPR_BASE32, RHPR_BASE64, etc.419* @return the number of written characters on success or 0 on fail420*/421RHASH_API size_t rhash_print(char* output, rhash ctx, unsigned hash_id,422int flags);423424/**425* Print magnet link with given filepath and calculated message digest into the426* output buffer. The hash_mask can limit which message digests will be printed.427* The function returns the size of the required buffer.428* If output is NULL the .429*430* @param output a string buffer to receive the magnet link or NULL431* @param filepath the file path to be printed or NULL432* @param context algorithms state433* @param hash_mask bit mask of the message digest to add to the link434* @param flags can be combination of bits RHPR_UPPERCASE, RHPR_NO_MAGNET,435* RHPR_FILESIZE436* @return number of written characters, including terminating '\0' on success, 0 on fail437*/438RHASH_API size_t rhash_print_magnet(char* output, const char* filepath,439rhash context, unsigned hash_mask, int flags);440441442/* MESSAGE API */443444/**445* The type of an unsigned integer large enough to hold a pointer.446*/447#if defined(UINTPTR_MAX)448typedef uintptr_t rhash_uptr_t;449#elif defined(_LP64) || defined(__LP64__) || defined(__x86_64) || \450defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)451typedef unsigned long long rhash_uptr_t;452#else453typedef unsigned long rhash_uptr_t;454#endif455456/**457* The value returned by rhash_transmit on error.458*/459#define RHASH_ERROR ((rhash_uptr_t)-1)460/**461* Convert a pointer to rhash_uptr_t.462*/463#define RHASH_STR2UPTR(str) ((rhash_uptr_t)(char*)(str))464/**465* Convert a rhash_uptr_t to a void* pointer.466*/467#define RHASH_UPTR2PVOID(u) ((void*)((u) + 0))468469/**470* Process a rhash message.471*472* @param msg_id message identifier473* @param dst message destination (can be NULL for generic messages)474* @param ldata data depending on message475* @param rdata data depending on message476* @return message-specific data477*/478RHASH_API rhash_uptr_t rhash_transmit(479unsigned msg_id, void* dst, rhash_uptr_t ldata, rhash_uptr_t rdata);480481/* rhash message constants */482483#define RMSG_GET_CONTEXT 1484#define RMSG_CANCEL 2485#define RMSG_IS_CANCELED 3486#define RMSG_GET_FINALIZED 4487#define RMSG_SET_AUTOFINAL 5488#define RMSG_SET_OPENSSL_MASK 10489#define RMSG_GET_OPENSSL_MASK 11490#define RMSG_GET_OPENSSL_SUPPORTED_MASK 12491#define RMSG_GET_OPENSSL_AVAILABLE_MASK 13492#define RMSG_GET_LIBRHASH_VERSION 20493494/* HELPER MACROS */495496/**497* Get a pointer to the context of the specified hash function.498*/499#define rhash_get_context_ptr(ctx, hash_id) RHASH_UPTR2PVOID(rhash_transmit(RMSG_GET_CONTEXT, ctx, hash_id, 0))500/**501* Cancel file processing.502*/503#define rhash_cancel(ctx) rhash_transmit(RMSG_CANCEL, ctx, 0, 0)504/**505* Return non-zero if a message digest calculation was canceled, zero otherwise.506*/507#define rhash_is_canceled(ctx) rhash_transmit(RMSG_IS_CANCELED, ctx, 0, 0)508/**509* Return non-zero if rhash_final was called for rhash_context.510*/511#define rhash_get_finalized(ctx) rhash_transmit(RMSG_GET_FINALIZED, ctx, 0, 0)512513/**514* Turn on/off the auto-final flag for the given rhash_context. By default515* auto-final is on, which means rhash_final is called automatically, if516* needed when a message digest is retrieved by rhash_print call.517*/518#define rhash_set_autofinal(ctx, on) rhash_transmit(RMSG_SET_AUTOFINAL, ctx, on, 0)519520/**521* Set the bit-mask of hash algorithms to be calculated by OpenSSL library.522* The call rhash_set_openssl_mask(0) made before rhash_library_init(),523* turns off loading of the OpenSSL dynamic library.524* This call works if the LibRHash was compiled with OpenSSL support.525*/526#define rhash_set_openssl_mask(mask) rhash_transmit(RMSG_SET_OPENSSL_MASK, NULL, mask, 0)527528/**529* Return current bit-mask of hash algorithms selected to be calculated by OpenSSL530* library. Return RHASH_ERROR if LibRHash is compiled without OpenSSL support.531*/532#define rhash_get_openssl_mask() rhash_transmit(RMSG_GET_OPENSSL_MASK, NULL, 0, 0)533534/**535* Return the bit-mask of algorithms that can be provided by the OpenSSL plugin,536* if the library is compiled with OpenSSL support, 0 otherwise. This bit-mask is537* a constant value computed at compile-time.538*/539#define rhash_get_openssl_supported_mask() rhash_transmit(RMSG_GET_OPENSSL_SUPPORTED_MASK, NULL, 0, 0)540541/**542* Return the bit-mask of algorithms that are successfully loaded from543* OpenSSL library. If the library is not loaded or not supported by LibRHash,544* then return 0.545*/546#define rhash_get_openssl_available_mask() rhash_transmit(RMSG_GET_OPENSSL_AVAILABLE_MASK, NULL, 0, 0)547548/**549* Return librhash version.550*/551#define rhash_get_version() rhash_transmit(RMSG_GET_LIBRHASH_VERSION, NULL, 0, 0)552553/**554* Return non-zero if LibRHash has been compiled with OpenSSL support,555* and zero otherwise.556*/557#define rhash_is_openssl_supported() (rhash_get_openssl_mask() != RHASH_ERROR)558559/**560* Legacy macro. The bit mask of hash algorithms implemented by OpenSSL.561*/562# define RHASH_OPENSSL_SUPPORTED_HASHES (rhash_get_openssl_supported_mask())563564#ifdef __cplusplus565} /* extern "C" */566#endif /* __cplusplus */567568#endif /* RHASH_H */569570571