summaryrefslogtreecommitdiffstats
path: root/lib/md5.c
diff options
context:
space:
mode:
authorFritz Reichmann <fritz@reichmann.nl>2011-10-01 15:49:48 +0200
committerDenis Ovsienko <infrastation@yandex.ru>2012-02-14 00:06:36 +0100
commite6b03b77766dce8009ad7b4a2392e14addf4ab0f (patch)
treea47466541c8f85e70b228ae4ab3da31af3391507 /lib/md5.c
parentisisd: unexpected kernel routing table (BZ#544) (diff)
downloadfrr-e6b03b77766dce8009ad7b4a2392e14addf4ab0f.tar.xz
frr-e6b03b77766dce8009ad7b4a2392e14addf4ab0f.zip
isisd: implement MD5 circuit authentication
* Replace command "isis passwd" with "isis passwd {clear|md5}" * Verify HMAC MD5 on ISIS Hello PDUs * Add HMAC MD5 authentication to md5.h/md5.c from RFC2104
Diffstat (limited to 'lib/md5.c')
-rw-r--r--lib/md5.c73
1 files changed, 73 insertions, 0 deletions
diff --git a/lib/md5.c b/lib/md5.c
index 894de648b..2fc36e179 100644
--- 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 */
+}