diff --git a/lib/modules/Crypto/hmac.pike b/lib/modules/Crypto/hmac.pike
new file mode 100644
index 0000000000000000000000000000000000000000..0bbf0dd0739102d68f44a095c23909b6eb37362d
--- /dev/null
+++ b/lib/modules/Crypto/hmac.pike
@@ -0,0 +1,54 @@
+/* hmac.pike
+ *
+ * HMAC, defined by RFC-2104
+ */
+
+function H;  /* Constructor for hash object */
+
+/* B is the size of one compression block, in octets. */
+int B;
+
+void create(function h, int|void b)
+{
+  // werror("hmac.pike->create()\n");
+  H = h;
+  
+  /* Block size is 64 octets for md5 and sha */
+  B = b || 64;
+}
+
+string raw_hash(string s)
+{
+  return H()->update(s)->digest();
+}
+
+string pkcs_digest(string s)
+{
+  return Crypto.Signature.build_digestinfo(s, H());
+}
+
+class `()
+{
+  string ikey; /* ipad XOR:ed with the key */
+  string okey; /* opad XOR:ed with the key */
+
+  void create(string passwd)
+    {
+      if (strlen(passwd) < B)
+	passwd = passwd + "\0" * (B - strlen(passwd));
+
+      ikey = passwd ^ ("6" * B);
+      okey = passwd ^ ("\\" * B);
+    }
+      
+  string `()(string text)
+    {
+      return raw_hash(okey + raw_hash(ikey + text));
+    }
+
+  string digest_info(string text)
+    {
+      return pkcs_digest(okey + raw_hash(ikey + text));
+    }
+}
+