# HG changeset patch # User Simon Josefsson # Date 1129554788 0 # Node ID a4b7c6c3f5bc03a5f689ae20047c58b1ceab47ba # Parent 1cc68a6a839867c4249d18d90a26af2f60eb7ec4 Add more hash functions. diff --git a/lib/ChangeLog b/lib/ChangeLog --- a/lib/ChangeLog +++ b/lib/ChangeLog @@ -1,3 +1,7 @@ +2005-10-17 Simon Josefsson + + * gc.h, gc-libgcrypt.c: Add more hash types/functions. + 2005-10-17 Simon Josefsson * gc.h, gc-libgcrypt.c: Add ciphers. diff --git a/lib/gc-libgcrypt.c b/lib/gc-libgcrypt.c --- a/lib/gc-libgcrypt.c +++ b/lib/gc-libgcrypt.c @@ -215,6 +215,118 @@ /* Hashes. */ Gc_rc +gc_hash_open (Gc_hash hash, Gc_hash_mode mode, gc_hash_handle * outhandle) +{ + int gcryalg, gcrymode; + gcry_error_t err; + + switch (hash) + { + case GC_MD5: + gcryalg = GCRY_MD_MD5; + break; + + case GC_SHA1: + gcryalg = GCRY_MD_SHA1; + break; + + case GC_RMD160: + gcryalg = GCRY_MD_RMD160; + break; + + default: + return GC_INVALID_HASH; + } + + switch (mode) + { + case 0: + gcrymode = 0; + break; + + case GC_HMAC: + gcrymode = GCRY_MD_FLAG_HMAC; + break; + + default: + return GC_INVALID_HASH; + } + + err = gcry_md_open ((gcry_md_hd_t *) outhandle, gcryalg, gcrymode); + if (gcry_err_code (err)) + return GC_INVALID_HASH; + + return GC_OK; +} + +Gc_rc +gc_hash_clone (gc_hash_handle handle, gc_hash_handle * outhandle) +{ + int err; + + err = gcry_md_copy ((gcry_md_hd_t *) outhandle, (gcry_md_hd_t) handle); + if (err) + return GC_INVALID_HASH; + + return GC_OK; +} + +size_t +gc_hash_digest_length (Gc_hash hash) +{ + int gcryalg; + + switch (hash) + { + case GC_MD5: + gcryalg = GCRY_MD_MD5; + break; + + case GC_SHA1: + gcryalg = GCRY_MD_SHA1; + break; + + case GC_RMD160: + gcryalg = GCRY_MD_RMD160; + break; + + default: + return 0; + } + + return gcry_md_get_algo_dlen (gcryalg); +} + +void +gc_hash_hmac_setkey (gc_hash_handle handle, size_t len, const char *key) +{ + gcry_md_setkey ((gcry_md_hd_t) handle, key, len); +} + +void +gc_hash_write (gc_hash_handle handle, size_t len, const char *data) +{ + gcry_md_write ((gcry_md_hd_t) handle, data, len); +} + +const char * +gc_hash_read (gc_hash_handle handle) +{ + const char *digest; + + gcry_md_final ((gcry_md_hd_t) handle); + digest = gcry_md_read ((gcry_md_hd_t) handle, 0); + + return digest; +} + +void +gc_hash_close (gc_hash_handle handle) +{ + gcry_md_close ((gcry_md_hd_t) handle); +} + +Gc_rc gc_hash_buffer (Gc_hash hash, const void *in, size_t inlen, char *resbuf) { int gcryalg; @@ -233,6 +345,12 @@ break; #endif +#ifdef GC_USE_RMD160 + case GC_RMD160: + gcryalg = GCRY_MD_RMD160; + break; +#endif + default: return GC_INVALID_HASH; } diff --git a/lib/gc.h b/lib/gc.h --- a/lib/gc.h +++ b/lib/gc.h @@ -42,10 +42,20 @@ enum Gc_hash { GC_MD5, - GC_SHA1 + GC_SHA1, + GC_MD2, + GC_RMD160 }; typedef enum Gc_hash Gc_hash; +enum Gc_hash_mode + { + GC_HMAC = 1 + }; +typedef enum Gc_hash_mode Gc_hash_mode; + +typedef void *gc_hash_handle; + #define GC_MD5_DIGEST_SIZE 16 #define GC_SHA1_DIGEST_SIZE 20 @@ -102,6 +112,17 @@ /* Hashes. */ +extern Gc_rc gc_hash_open (Gc_hash hash, Gc_hash_mode mode, + gc_hash_handle * outhandle); +extern Gc_rc gc_hash_clone (gc_hash_handle handle, gc_hash_handle * outhandle); +extern size_t gc_hash_digest_length (Gc_hash hash); +extern void gc_hash_hmac_setkey (gc_hash_handle handle, + size_t len, const char *key); +extern void gc_hash_write (gc_hash_handle handle, + size_t len, const char *data); +extern const char *gc_hash_read (gc_hash_handle handle); +extern void gc_hash_close (gc_hash_handle handle); + /* Compute a hash value over buffer IN of INLEN bytes size using the algorithm HASH, placing the result in the pre-allocated buffer OUT. The required size of OUT depends on HASH, and is generally