/*
md5.c: Calculates a fingerprint (or checksum) for a string of bits with an optional key

Functions:

void md5_digest(char *data, unsigned int datalen, char digest[16]);
	data is a string of chars.
	datalen is the number of bytes in data to be used in the calculation.
	digest is loaded with the 16-byte fingerprint.

void md5_keyed(char *data, unsigned int datalen, char *key, unsigned int keylen, unsigned char digest[16]);
	data is a string of chars forming the original bitstream.
	datalen is the number of bytes in data to be used in the calculation.
	key is a string of chars used to further modify the fingerprint
	key is the number of bytes in key
	digest is loaded with the 16-byte fingerprint.

void md5_print(char digest[16], char buf[33]);
	digest is an md5 fingerprint
	buf receives the 32-digit hex string representing the digest

Notes:
The algorithm will only work for up to 2^128-1 bits.
Keys for keyed MD5 fingerprints will be truncated at 64 bytes.

History:
19-07-2001: Written by CPL and tested according to RFC1321.
18-08-2004: Extended by RMH to implement CRAM-MD5.
*/

/* Create a digest */
//void md5_digest(char *data, unsigned int datalen, char digest[16]);
void md5_digest(char *data, unsigned int datalen, unsigned char digest[16]);

/* Create a digest using a key */
void md5_keyed(char *data, unsigned int datalen, char *key, unsigned int keylen, unsigned char digest[16]);

// hmac_md5 from rfc...
void hmac_md5(unsigned char *text, int text_len, unsigned char *key, int key_len, char *digest);

/* Create a keyed and storable ipad+opad combination to use with 'md5_hmac' */
void md5_hmac_create(char *key, unsigned int keylen, char *ipad, char *opad, int bfsz);

/* Using previously created ipad+opad combination, create a digest */
void md5_hmac(char *data, unsigned int datalen, char *ipad, char *opad, unsigned char digest[16]);
int md5_file(char *fname,char *md5);

/* Print a digest to a buffer */
void md5_print(unsigned char digest[16], char *buf, int bfsz);
// Same but without 32 char limit on digest. 
void md5_print2(unsigned char digest[], char *buf, int max);

void md5_init(unsigned int state[6]);
void md5_update(unsigned int state[6], char *data, unsigned int datalen, unsigned char *buffer);
void md5_finish(unsigned int state[6], unsigned char buffer[64], unsigned char digest[16]);

/* FOR TESTING */
int md5_main(int argc, char **argv);
//struct MD5Context {unsigned int ctx[6];} ;
