mhash(3)
π NAME π
mhash β the Hash Library. That's the whole name, bestie. You'll catch her hanging out in section 3 as mhash(3), and the header up top calls the thing mhash library β same girl, same energy. π
π VERSION π
mhash 0.9.2 β she's vintage, she's iconic, she's literally still serving. β¨
π¦ SYNOPSIS π¦
okay so here's the entire cast list, in order, no edits, no notes, exactly as the source says it π
#include "mhash.h"
Informative Functions
size_t mhash_count(void);
size_t mhash_get_block_size(hashid type);
char *mhash_get_hash_name(hashid type);
size_t mhash_get_hash_pblock(hashid type);
hashid mhash_get_mhash_algo( MHASH);
Key Generation Functions
int mhash_keygen_ext(keygenid algorithm, KEYGEN algorithm_data,
void* keyword, int keysize,
unsigned char* password, int passwordlen);
Initializing Functions
MHASH mhash_init(hashid type);
MHASH mhash_hmac_init(const hashid type, void *key, int keysize, int block);
MHASH mhash_cp( MHASH);
Update Functions
int mhash(MHASH thread, const void *plaintext, size_t size);
Save/Restore Functions
int mhash_save_state_mem(MHASH thread, void *mem, int* mem_size );
MHASH mhash_restore_state_mem(void* mem);
Finalizing Functions
void mhash_deinit(MHASH thread, void *result);
void *mhash_end(MHASH thread);
void *mhash_end_m(MHASH thread, void* (*hash_malloc)(size_t));
void *mhash_hmac_end(MHASH thread);
void *mhash_hmac_end_m(MHASH thread, void* (*hash_malloc)(size_t));
int mhash_hmac_deinit(MHASH thread, void *result);
π Available Hashes π
- CRC32 β the
crc32algorithm is your checksum girl. mhash rolls with two variants:MHASH_CRC32(the ethernet-flavored one) andMHASH_CRC32B(the ZIP-program-flavored one). π - ADLER32 β also a checksum algorithm, and she's faster than CRC32 while being considered just as reliable as CRC32. Defined as
MHASH_ADLER32. ate π - MD5 β the MD5 algorithm, by Ron Rivest and RSA. In mhash it's defined as
MHASH_MD5. - MD4 β the MD4 algorithm, by Ron Rivest and RSA. This one is considered broken, so like... don't use it. fr fr. In mhash it's defined as
MHASH_MD4. - SHA1/SHA256 β the SHA algorithm by US. NIST/NSA. It's specified for use in the NIST's Digital Signature Standard. In mhash these are defined as
MHASH_SHA1andMHASH_SHA256. two queens, one crown π - HAVAL β a one-way hashing algorithm with variable length of output. HAVAL is a modification of MD5. Defined in mhash as:
MHASH_HAVAL256,MHASH_HAVAL192,MHASH_HAVAL160,MHASH_HAVAL128. - RIPEMD160 β RIPEMD-160 is a 160-bit cryptographic hash function, designed by Hans Dobbertin, Antoon Bosselaers, and Bart Preneel. It's intended to be used as a secure replacement for the 128-bit hash functions MD4, MD5, and RIPEMD. MD4 and MD5 were developed by Ron Rivest for RSA Data Security, while RIPEMD was developed in the framework of the EU project RIPE (RACE Integrity Primitives Evaluation, 1988-1992). In mhash this algorithm is defined as
MHASH_RIPEMD160. - TIGER β Tiger is a fast hash function, by Eli Biham and Ross Anderson. Tiger was designed to be very fast on modern computers, and in particular on the state-of-the-art 64-bit computers, while it's still not slower than other suggested hash functions on 32-bit machines. In mhash this algorithm is defined as:
MHASH_TIGER,MHASH_TIGER160,MHASH_TIGER128. - GOST β GOST is a russian standard and it uses the GOST encryption algorithm to produce a 256 bit hash value. This algorithm is specified for use in the Russian Digital Signature Standard. In mhash this algorithm is defined as
MHASH_GOST.
π Available Key Generation algorithms π
- KEYGEN_MCRYPT β the key generator used in mcrypt.
- KEYGEN_ASIS β just returns the password as binary key. no thoughts, head empty, here's your key π
- KEYGEN_HEX β just converts a hex key into a binary one.
- KEYGEN_PKDES β the transformation used in Phil Karn's DES encryption program.
- KEYGEN_S2K_SIMPLE β the OpenPGP (rfc2440) Simple S2K.
- KEYGEN_S2K_SALTED β the OpenPGP Salted S2K.
- KEYGEN_S2K_ISALTED β the OpenPGP Iterated Salted S2K.
πΈ DESCRIPTION πΈ
The mhash library provides an easy to use C interface for several hash algorithms (also known as "one-way" algorithms). You can use them to create checksums, message digests and more. Currently, MD5, SHA1, GOST, TIGER, RIPE-MD160, HAVAL and several other algorithms are supported. mhash supports HMAC generation (a mechanism for message authentication using cryptographic hash functions, and is described in rfc2104). HMAC can be used to create message digests using a secret key, so that these message digests cannot be regenerated (or replaced) by someone else. A key generation mechanism was added to mhash since key generation algorithms usually involve hash algorithms. π§
β¨ API FUNCTIONS β¨
We're gonna walk the whole API of mhash in detail now, bestie. The order follows the one in the SYNOPSIS directly β same lineup, same energy, no skipping. π«Ά
size_t mhash_count(void);
Returns the "hashid" of the last available hash. Hashes are numbered from 0 to "mhash_count()". So like, that's your upper bound, girl. π
size_t mhash_get_block_size(hashid type);
If type exists, this returns the used blocksize of the hash type in bytes. Otherwise, it returns 0. simple as. β¨
char *mhash_get_hash_name(hashid type);
If type exists, this returns the name of the hash type. Otherwise, a "NULL" pointer is returned.
β οΈ bestie, listen β the string is allocated withmalloc(3)separately, so do not forget tofree(3)it. no cap. π
const char *mhash_get_hash_name_static(hashid type);
If type exists, this returns the name of the hash type. Otherwise, a "NULL" pointer is returned. (no malloc drama here, she's chill π)
size_t mhash_get_hash_pblock(hashid type);
It returns the block size that the algorithm operates. This is used in mhash_hmac_init. If the return value is 0 you shouldn't use that algorithm in HMAC. periodt. π«
hashid mhash_get_mhash_algo(MHASH src);
Returns the algorithm used in the state of src. like a little vibe check on your context π
MHASH mhash_init(hashid type);
This setups a context to begin hashing using the algorithm type. It returns a descriptor to that context which will result in leaking memory if you do not call mhash_deinit(3) later. Returns MHASH_FAILED on failure. π
β οΈ leaking memory is not the cute kind of leak. clean up after yourself, queen.
MHASH mhash_hmac_init(const hashid type, void *key, int keysize, int block);
This setups a context to begin hashing using the algorithm type in HMAC mode. key should be a pointer to the key and keysize its len. The block is the block size (in bytes) that the algorithm operates. It should be obtained by mhash_get_hash_pblock(). If its 0 it defaults to 64. After calling it you should use mhash() to update the context. It returns a descriptor to that context which will result in leaking memory if you do not call mhash_hmac_deinit(3) later. Returns MHASH_FAILED on failure. π
MHASH mhash_cp(MHASH src);
This setups a new context using the state of src. it's giving copy-paste but make it cryptographic π
int mhash(MHASH thread, const void *plaintext, size_t size);
This updates the context described by thread with plaintext. size is the length of plaintext which may be binary data. yes, binary data is allowed, she's not picky π¦
int mhash_save_state_mem( MHASH thread, void *mem, int* mem_size);
Saves the state of a hashing algorithm such that it can be restored at some later point in time using mhash_restore_state_mem(). mem_size should contain the size of the given mem pointer. If it is not enough to hold the buffer the required value will be copied there. π
MHASH mhash_restore_state_mem(void* mem);
Restores the state of a hashing algorithm that was saved using mhash_save_state_mem(). Use like mhash_init(). she's back and she remembers everything π
void *mhash_end(MHASH thread);
This frees all resources associated with thread and returns the result of the whole hashing operation (the ``digest``). β¨
void mhash_deinit(MHASH thread, void* digest);
This frees all resources associated with thread and stores the result of the whole hashing operation in memory pointed by digest. digest may be null. πΈ
void *mhash_hmac_end(MHASH thread);
This frees all resources associated with thread and returns the result of the whole hashing operation (the ``mac``). π₯
int mhash_hmac_deinit(MHASH thread, void* digest);
This frees all resources associated with thread and stores the result of the whole hashing operation in memory pointed by digest. Digest may be null. Returns non-zero in case of an error. β οΈ
void *mhash_end_m(MHASH thread, void* (*hash_malloc)(size_t));
This frees all resources associated with thread and returns the result of the whole hashing operation (the ``digest``). The result will be allocated by using the hash_malloc() function provided. π
void *mhash_hmac_end(MHASH thread, void* (*hash_malloc)(size_t));
This frees all resources associated with thread and returns the result of the whole hashing operation (the ``mac``). The result will be allocated by using the hash_malloc() function provided. π«Ά
π yes, bestie, mhash_hmac_end shows up twice in this page with two different signatures β we're just transcribing what's there, no editing, no fixing, that's the assignment.
and that's the end of part 1, babe β part 2 is right there, keep scrolling, we are so not done yet πβ¨
β¨ KEYGEN API FUNCTIONS β¨
okay bestie, now we're diving into the Key Generation API of mhash and it's literally the blueprint for turning passwords into keys πβ¨. Let's get into it, no cap.
int mhash_keygen_ext(keygenid algorithm, KEYGEN algorithm_data, void* keyword, int keysize, unsigned char* password, int passwordlen);
This one generates a key from a password, periodt. The password gets read from password, and its length should be in passwordlen. The key generation algorithm is specified in algorithm, and that algorithm may (internally) use the KEYGEN structure. And what does KEYGEN look like? Say less:
typedef struct keygen {
hashid hash_algorithm[2];
unsigned int count;
void* salt;
int salt_size;
} KEYGEN;
The algorithm(s) specified in algorithm_data.hash_algorithm should be hash algorithms and may be used by the key generation algorithm. Some key generation algorithms may use more than one hash algorithm (peep mhash_keygen_uses_hash_algorithm() too π). If it's desirable (and supported by the algorithm, eg. KEYGEN_S2K_SALTED), a salt may be specified in algorithm_data.salt of size algorithm_data.salt_size, or it may be NULL.
The algorithm may use algorithm_data.count internally (eg. KEYGEN_S2K_ISALTED). The generated keyword is stored in keyword, which should be (at least) keysize bytes long. The generated keyword is a binary one. Returns a negative number on failure. Slay but also be careful π
.
int mhash_keygen_uses_salt( keygenid algorithm);β This function returns1if the specified key generation algorithm needs a salt to be specified. That's it, that's the vibe.int mhash_keygen_uses_count( keygenid algorithm);β This function returns1if the specified key generation algorithm needs thealgorithm_data.countfield inmhash_keygen_ext(). Thecountfield tells the algorithm to hash repeatedly the password and to stop whencountbytes have been processed. So basically it's like "keep going until I say stop" π.int mhash_get_keygen_salt_size( keygenid algorithm);β This function returns the size of the salt size that the specific algorithm will use. If it returns0, then there is no limitation in the size. So0means "go off, any size works" πββοΈ.int mhash_get_keygen_max_key_size( keygenid algorithm);β This function returns the maximum size of the key that the key generation algorithm may produce. If it returns0, then there is no limitation in the size. Again,0= no cap on size, literally.int mhash_keygen_uses_hash_algorithm( keygenid algorithm);β This function returns the number of the hash algorithms the key generation algorithm will use. If it is0then no hash algorithm is used by the key generation algorithm. This is for thealgorithm_data.hash_algorithmfield inmhash_keygen_ext(). Ifsize_t mhash_keygen_count(void);β This returns the"keygenid"of the last available key generation algorithm. Algorithms are numbered from0to"mhash_keygen_count()". So it's like the ultimate index, the final boss of keygen IDs π.char *mhash_get_keygen_name(keygenid type);β Iftypeexists, this returns the name of the keygen type. Otherwise, a"NULL"pointer is returned. The string is allocated withmalloc(3)separately, so do not forget tofree(3)it. Don't leak memory bestie, that's not cute π«π§.const char *mhash_get_keygen_name_static(keygenid type);β Iftypeexists, this returns the name of the keygen type. Otherwise, a"NULL"pointer is returned. No malloc, no free, just static vibes β¨.
π EXAMPLE π
Hashing STDIN until EOF. Iconic behavior honestly.
#include <mhash.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int i;
MHASH td;
unsigned char buffer;
unsigned char hash[16]; /* enough size for MD5 */
td = mhash_init(MHASH_MD5);
if (td == MHASH_FAILED) exit(1);
while (fread(&buffer, 1, 1, stdin) == 1) {
mhash(td, &buffer, 1);
}
mhash_deinit(td, hash);
printf("Hash:");
for (i = 0; i < mhash_get_block_size(MHASH_MD5); i++) {
printf("%.2x", hash[i]);
}
printf("\n");
exit(0);
}
πΈ EXAMPLE πΈ
An example program using HMAC. Secure that message, bestie π.
#include <mhash.h>
#include <stdio.h>
int main()
{
char password[] = "Jefe";
int keylen = 4;
char data[] = "what do ya want for nothing?";
int datalen = 28;
MHASH td;
unsigned char mac[16];
int j;
td = mhash_hmac_init(MHASH_MD5, password, keylen,
mhash_get_hash_pblock(MHASH_MD5));
mhash(td, data, datalen);
mhash_hmac_deinit(td, mac);
/*
* The output should be 0x750c783e6ab0b503eaa86e310a5db738
* according to RFC 2104.
*/
printf("0x");
for (j = 0; j < mhash_get_block_size(MHASH_MD5); j++) {
printf("%.2x", mac[j]);
}
printf("\n");
exit(0);
}
π HISTORY π
This library was originally written by Nikos Mavroyanopoulos <nmav@hellug.gr> who passed the project over to Sascha Schumann <sascha@schumann.cx> in May 1999. Sascha maintained it until March 2000. The library is now maintained by Nikos Mavroyanopoulos. The plot twist? It's giving collaborative legacy π«Ά.
π BUGS π
If you find any, please send a bug report (preferably together with a patch) to the maintainer with a detailed description on how to reproduce the bug. Be a helpful icon, not just a complainer π .
π AUTHORS π
Sascha Schumann <sascha@schumann.cx> Nikos Mavroyanopoulos <nmav@hellug.gr>
mhash 0.9.2, dated 2000/03/23 β that's the whole vibe. Stay secure and stay slay πβ¨
π¦ where this page comes from
- debian bookworm: libmhash-dev 0.9.9.9-9
- debian trixie: libmhash-dev 0.9.9.9-10
- ubuntu jammy: libmhash-dev 0.9.9.9-9build2
- ubuntu noble: libmhash-dev 0.9.9.9-9build3
- ubuntu questing: libmhash-dev 0.9.9.9-10
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms