From 1ac0074ba074457f7910c3ed97f5bd73bd547582 Mon Sep 17 00:00:00 2001 From: Michal Vaner Date: Thu, 11 Sep 2008 17:57:37 +0200 Subject: [PATCH] ucw docs: Hash routines MD5 and SHA1 hashes. --- ucw/doc/Makefile | 2 +- ucw/doc/hash.txt | 50 +++++++++++++++++++++++++++++++++++++++++++++++ ucw/doc/index.txt | 1 + ucw/md5.h | 43 +++++++++++++++++++++++++++++++++++----- ucw/sha1.h | 42 +++++++++++++++++++++++++++++++++------ 5 files changed, 126 insertions(+), 12 deletions(-) create mode 100644 ucw/doc/hash.txt diff --git a/ucw/doc/Makefile b/ucw/doc/Makefile index 3b9216ac..e88c0f5a 100644 --- a/ucw/doc/Makefile +++ b/ucw/doc/Makefile @@ -2,7 +2,7 @@ DIRS+=ucw/doc -UCW_DOCS=fastbuf index basecode +UCW_DOCS=fastbuf index basecode hash UCW_INDEX=$(o)/ucw/doc/def_index.html $(UCW_INDEX): DOC_HEAD=$(s)/ucw/doc/def_index.txt diff --git a/ucw/doc/hash.txt b/ucw/doc/hash.txt new file mode 100644 index 00000000..b28c42a7 --- /dev/null +++ b/ucw/doc/hash.txt @@ -0,0 +1,50 @@ +Hashing routines +================ + +Libucw contains two hash algorithms, MD5 (RFC 1321) and SHA1 (RFC +3174). + +- <> +- <> +- <> + +[[md5]] +MD5 +--- +!!ucw/md5.h + +[[sha1]] +SHA1 +---- +!!ucw/sha1.h + +[[usage]] +Usage +----- + +There are two ways you can use the hashing routines. + +- Single-shot interface. If you have an in-memory buffer of the whole + message you want to hash, you can use this. + + char *message = "Hello world"; + byte output[MD5_SIZE]; + md5_hash_buffer(output, message, strlen(message)); + +- Multi-shot interface. If you have the message scattered in many + buffers or you get it by parts, you do not need to concatenate the + parts together. + + byte buffer[MAX_BUFFER]; + uns buffer_len; + md5_context c; + md5_init(&c); + while(buffer_len = get_chunk(buffer, MAX_BUFFER)) { + md5_update(&c, buffer, buffer_len); + } + byte output[MD5_SIZE]; + memcpy(output, md5_final(&c), MD5_SIZE); + +SHA1 has the same interface, so both ways work to it as well. + +See also <>. diff --git a/ucw/doc/index.txt b/ucw/doc/index.txt index aeccb034..5e780bf9 100644 --- a/ucw/doc/index.txt +++ b/ucw/doc/index.txt @@ -11,3 +11,4 @@ Modules ------- - <> - <> +- <> diff --git a/ucw/md5.h b/ucw/md5.h index 1ee97cfa..20dafb4d 100644 --- a/ucw/md5.h +++ b/ucw/md5.h @@ -7,23 +7,56 @@ #ifndef _UCW_MD5_H #define _UCW_MD5_H +/** + * Internal MD5 hash state. + * You can use it just as a opaque handle. + */ typedef struct { u32 buf[4]; u32 bits[2]; byte in[64]; } md5_context; -void md5_init(md5_context *context); +void md5_init(md5_context *context); /** Initialize the MD5 hashing algorithm in @context. **/ +/** + * Push another @len bytes of data from @buf to the MD5 hash + * represented by @context. You can call it multiple time on the same + * @context without reinitializing it and the result will be the same + * as you concatenated all the data together and fed them here all at + * once. + */ void md5_update(md5_context *context, const byte *buf, uns len); -/* The data are stored inside the context */ +/** + * Call this after the last md5_update(). It will terminate the + * algorithm and return pointer to the result. + * + * Note that the data it points to are stored inside the @context, so + * if you use it to compute another hash or it ceases to exist, the + * pointer becomes invalid. + */ byte *md5_final(md5_context *context); +/** + * This is the core routine of MD5 algorithm. It takes 16 longwords of + * data in @in and transforms the hash in @buf according to them. + * + * You probably do not want to call this one directly. + */ void md5_transform(u32 buf[4], const u32 in[16]); -/* One-shot interface */ +/** + * MD5 one-shot convenience method. It takes @length bytes from + * @buffer, creates the hash from them and returns it in @output. + * + * It is equivalent to this code: + * md5_context c; + * md5_init(&c); + * md5_update(&c, buffer, length); + * memcpy(outbuf, md5_final(&c), MD5_SIZE); + */ void md5_hash_buffer(byte *outbuf, const byte *buffer, uns length); -#define MD5_HEX_SIZE 33 -#define MD5_SIZE 16 +#define MD5_HEX_SIZE 33 /** How many bytes a string buffer for MD5 in hexadecimal format should have. **/ +#define MD5_SIZE 16 /** Number of bytes the MD5 hash takes in the binary form. **/ #endif /* !_UCW_MD5_H */ diff --git a/ucw/sha1.h b/ucw/sha1.h index 05dc4853..d9ca009e 100644 --- a/ucw/sha1.h +++ b/ucw/sha1.h @@ -14,6 +14,11 @@ #ifndef _UCW_SHA1_H #define _UCW_SHA1_H +/** + * Internal SHA1 state. + * You can consider it an opaque handle, if you want just hash + * functions. + */ typedef struct { u32 h0,h1,h2,h3,h4; u32 nblocks; @@ -21,18 +26,43 @@ typedef struct { int count; } sha1_context; -void sha1_init(sha1_context *hd); +void sha1_init(sha1_context *hd); /** Initialize new algorithm run in the @hd context. **/ +/** + * Push another @inlen bytes of data pointed to by @inbuf onto the + * SHA1 hash currently in @hd. You can call this any times you want on + * the same hash (and you do not need to reinitialize it by + * sha1_init()). It has the same effect as concatenating all the data + * together and passing them at once. + */ void sha1_update(sha1_context *hd, const byte *inbuf, uns inlen); +/** + * No more sha1_update() calls will be done. This terminates the hash + * and returns pointer to it. + * + * Note the pointer points into data in the @hd context. If it ceases + * to exist, the pointer becomes invalid. + */ byte *sha1_final(sha1_context *hd); -/* One-shot interface */ +/** + * Convenience one-shot function for SHA1 hash. + * It is equivalent to this snippet of code: + * + * sha1_context hd; + * sha1_init(&hd); + * sha1_update(&hd, buffer, length); + * memcpy(outbuf, sha1_final(&hd), 20); + */ void sha1_hash_buffer(byte *outbuf, const byte *buffer, uns length); -/* HMAC */ +/** + * SHA1 HMAC message authentication. If you provide @key and @data, + * the result will be stored in @outbuf. + */ void sha1_hmac(byte *outbuf, const byte *key, uns keylen, const byte *data, uns datalen); -#define SHA1_SIZE 20 -#define SHA1_HEX_SIZE 41 -#define SHA1_BLOCK_SIZE 64 +#define SHA1_SIZE 20 /** Size of the SHA1 hash in its binary representation **/ +#define SHA1_HEX_SIZE 41 /** Buffer length for a string containing SHA1 in hexadecimal format. **/ +#define SHA1_BLOCK_SIZE 64 /** SHA1 splits input to blocks of this size. **/ #endif -- 2.39.2