]> git.puffer.fish Git - matthieu/frr.git/commitdiff
lib: add support for keyed-hashing with MD5
authorJosh Bailey <joshb@google.com>
Wed, 21 Mar 2012 17:22:19 +0000 (10:22 -0700)
committerAvneesh Sachdev <avneesh@opensourcerouting.org>
Sat, 7 Apr 2012 20:53:22 +0000 (13:53 -0700)
  * lib/md5.[ch] Add implementation of HMAC-MD5 from RFC 2104.

From: Josh Bailey <joshb@google.com>
Signed-off-by: Avneesh Sachdev <avneesh@opensourcerouting.org>
Signed-off-by: David Lamparter <equinox@diac24.net>
lib/md5.c
lib/md5.h

index 894de648b3de056660d122c66421c0730680c260..2fc36e179b8a3cbb6f42966549e8151d3d50c6f2 100644 (file)
--- a/lib/md5.c
+++ b/lib/md5.c
@@ -298,3 +298,76 @@ static void md5_calc(const uint8_t *b64, md5_ctxt * ctxt)
        ctxt->md5_stc += C;
        ctxt->md5_std += D;
 }
+
+/* From RFC 2104 */
+void
+hmac_md5(text, text_len, key, key_len, digest)
+unsigned char*  text;                  /* pointer to data stream */
+int             text_len;              /* length of data stream */
+unsigned char*  key;                   /* pointer to authentication key */
+int             key_len;               /* length of authentication key */
+caddr_t         digest;                /* caller digest to be filled in */
+
+{
+    MD5_CTX context;
+    unsigned char k_ipad[65];    /* inner padding -
+                                * key XORd with ipad
+                                */
+    unsigned char k_opad[65];    /* outer padding -
+                                * key XORd with opad
+                                */
+    unsigned char tk[16];
+    int i;
+    /* if key is longer than 64 bytes reset it to key=MD5(key) */
+    if (key_len > 64) {
+
+       MD5_CTX      tctx;
+
+       MD5Init(&tctx);
+       MD5Update(&tctx, key, key_len);
+       MD5Final(tk, &tctx);
+
+       key = tk;
+       key_len = 16;
+    }
+
+    /*
+     * the HMAC_MD5 transform looks like:
+     *
+     * MD5(K XOR opad, MD5(K XOR ipad, text))
+     *
+     * where K is an n byte key
+     * ipad is the byte 0x36 repeated 64 times
+     * opad is the byte 0x5c repeated 64 times
+     * and text is the data being protected
+     */
+
+    /* start out by storing key in pads */
+    bzero( k_ipad, sizeof k_ipad);
+    bzero( k_opad, sizeof k_opad);
+    bcopy( key, k_ipad, key_len);
+    bcopy( key, k_opad, key_len);
+
+    /* XOR key with ipad and opad values */
+    for (i=0; i<64; i++) {
+       k_ipad[i] ^= 0x36;
+       k_opad[i] ^= 0x5c;
+    }
+    /*
+     * perform inner MD5
+     */
+    MD5Init(&context);                 /* init context for 1st
+                                        * pass */
+    MD5Update(&context, k_ipad, 64);   /* start with inner pad */
+    MD5Update(&context, text, text_len); /* then text of datagram */
+    MD5Final(digest, &context);        /* finish up 1st pass */
+    /*
+     * perform outer MD5
+     */
+    MD5Init(&context);                 /* init context for 2nd
+                                        * pass */
+    MD5Update(&context, k_opad, 64);   /* start with outer pad */
+    MD5Update(&context, digest, 16);   /* then results of 1st
+                                        * hash */
+    MD5Final(digest, &context);        /* finish up 2nd pass */
+}
index 89b9a32093d4b47252735138dfe6c43135b0eb0f..a03bf22a22cd09a9c3bbdbb909776772bafd665d 100644 (file)
--- a/lib/md5.h
+++ b/lib/md5.h
@@ -82,4 +82,8 @@ do {                          \
        md5_result((x), (y));   \
 } while (0)
 
+/* From RFC 2104 */
+void hmac_md5(unsigned char* text, int text_len, unsigned char* key,
+              int key_len, caddr_t digest);
+
 #endif /* ! _LIBZEBRA_MD5_H_*/