summaryrefslogtreecommitdiffstats
path: root/kbiff/kbiffcrypt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kbiff/kbiffcrypt.cpp')
-rw-r--r--kbiff/kbiffcrypt.cpp72
1 files changed, 72 insertions, 0 deletions
diff --git a/kbiff/kbiffcrypt.cpp b/kbiff/kbiffcrypt.cpp
new file mode 100644
index 0000000..66ce0b0
--- /dev/null
+++ b/kbiff/kbiffcrypt.cpp
@@ -0,0 +1,72 @@
+/*
+ * kbiffcrypt.cpp
+ * Copyright (C) 2005 Michael Hendricks <michael@palmcluster.org>
+ *
+ * This file contains the implementation of the functions in
+ * the KBiffCrypt namespace.
+ *
+ * $Id$
+ */
+#include "kbiffcrypt.h"
+
+#include <kmdcodec.h>
+#include <qcstring.h>
+
+QString KBiffCrypt::hmac_md5(const QString& text, const QString& k)
+{
+ // If the original key is too long, the new key will be a hash of
+ // the original key. Then the new key might have NULL bytes in it,
+ // so we can't use QCString
+ QByteArray key = (QByteArray)k.utf8();
+
+ KMD5 context; // for calculating MD5 sums
+ KMD5::Digest digest; // intermediate storage for MD5 sums
+
+ // inner and outer padding (key XORd with ipad and opad, respectively)
+ QByteArray k_ipad(64);
+ QByteArray k_opad(64);
+
+
+ // if key is longer than 64 bytes reset it to key=MD5(key)
+ if (key.size() > 64) {
+ // cast to a QCString because we don't want to hash the
+ // trailing NULL byte
+ KMD5 tctx((QCString)key);
+
+ key.duplicate((char*)tctx.rawDigest(), 16);
+ }
+
+ /* the HMAC-MD5 transform looks like this:
+ *
+ * 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
+ * text is the data being protected
+ */
+
+ // XOR key with ipad and opad values, copying
+ // the pad values after the key's end
+ for (unsigned int i=0; i<64; i++) {
+ if( i < key.size() ) {
+ k_ipad[i] = key[i] ^ 0x36;
+ k_opad[i] = key[i] ^ 0x5c;
+ } else {
+ k_ipad[i] = 0x36;
+ k_opad[i] = 0x5c;
+ }
+ }
+
+ // perform inner MD5
+ context.reset(); // init context for 1st pass
+ context.update(k_ipad); // start with inner pad
+ context.update(text.utf8()); // then text of datagram
+ context.rawDigest(digest); // finish up 1st pass
+
+ // perform outer MD5
+ context.reset(); // init context for 2nd pass
+ context.update(k_opad); // start with outer pad
+ context.update(digest, 16); // then results of 1st hash
+ return context.hexDigest(); // finish up 2nd pass and return
+}