aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--epan/crypt-md5.c63
-rw-r--r--epan/crypt-md5.h3
2 files changed, 66 insertions, 0 deletions
diff --git a/epan/crypt-md5.c b/epan/crypt-md5.c
index 42df1b920d..01931fdc4c 100644
--- a/epan/crypt-md5.c
+++ b/epan/crypt-md5.c
@@ -56,6 +56,7 @@
#endif
#include <string.h>
+#include <glib.h> /* for g_malloc() */
#include <epan/crypt-md5.h>
@@ -384,3 +385,65 @@ md5_finish(md5_state_t *pms, md5_byte_t digest[16])
for (i = 0; i < 16; ++i)
digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
}
+
+static void
+md5_checksum(const md5_byte_t *data,
+ int len,
+ md5_byte_t digest[16])
+{
+ md5_state_t ms;
+
+ md5_init(&ms);
+ md5_append(&ms, data, len);
+ md5_finish(&ms, digest);
+}
+
+void
+md5_hmac(const md5_byte_t *data,
+ int len,
+ md5_byte_t *key_data,
+ int key_length,
+ md5_byte_t digest[16])
+{
+ md5_byte_t *ipad;
+ md5_byte_t *key;
+ md5_byte_t opad[80];
+ int key_len;
+ int i;
+
+ ipad = g_malloc(64 + len);
+ if (ipad == NULL)
+ g_assert_not_reached();
+
+ memset(ipad, 0x36, 64);
+ memset(opad, 0x5c, 64);
+
+ if(key_length > 65){
+ md5_checksum(
+ key_data,
+ key_length,
+ digest);
+ key = digest;
+ key_len = 16;
+ } else {
+ key = key_data;
+ key_len = key_length;
+ }
+ for(i = 0; i < key_len; i++){
+ ipad[i] ^= key[i];
+ opad[i] ^= key[i];
+ }
+ memcpy(ipad + 64, data, len);
+ md5_checksum(
+ ipad,
+ 64+len,
+ digest);
+ memcpy(opad + 64, digest,
+ 16);
+ md5_checksum(
+ opad,
+ 64+16,
+ digest);
+ g_free(ipad);
+}
+
diff --git a/epan/crypt-md5.h b/epan/crypt-md5.h
index 5eb6d6c469..8581c90f0a 100644
--- a/epan/crypt-md5.h
+++ b/epan/crypt-md5.h
@@ -84,6 +84,9 @@ void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);
/* Finish the message and return the digest. */
void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
+ /* compute the MD5 HMAC */
+void md5_hmac(const md5_byte_t *data, int len, md5_byte_t *key_data, int key_length, md5_byte_t digest[16]);
+
#ifdef __cplusplus
} /* end extern "C" */
#endif