]> mj.ucw.cz Git - libucw.git/blobdiff - ucw/sha1-hmac.c
XTypes: CF_XTYPE requires '&' before xt_*, just like most other parameters in CF_...
[libucw.git] / ucw / sha1-hmac.c
index 2c4ee1247e5e4e75077a8d54d12628d39fa88ea5..b52011b1b74dcf71cacf1ca8ec82f78c99ddcb46 100644 (file)
@@ -1,21 +1,20 @@
 /*
  *     HMAC-SHA1 Message Authentication Code (RFC 2202)
  *
- *     (c) 2008 Martin Mares <mj@ucw.cz>
+ *     (c) 2008--2009 Martin Mares <mj@ucw.cz>
  *
  *     This software may be freely distributed and used according to the terms
  *     of the GNU Lesser General Public License.
  */
 
-#include "ucw/lib.h"
-#include "ucw/sha1.h"
+#include <ucw/lib.h>
+#include <ucw/sha1.h>
 
 #include <string.h>
 
 void
-sha1_hmac(byte *outbuf, const byte *key, uns keylen, const byte *data, uns datalen)
+sha1_hmac_init(sha1_hmac_context *hd, const byte *key, uint keylen)
 {
-  sha1_context ictx, octx;
   byte keybuf[SHA1_BLOCK_SIZE], buf[SHA1_BLOCK_SIZE];
 
   // Hash the key if necessary
@@ -30,35 +29,56 @@ sha1_hmac(byte *outbuf, const byte *key, uns keylen, const byte *data, uns datal
       bzero(keybuf + SHA1_SIZE, SHA1_BLOCK_SIZE - SHA1_SIZE);
     }
 
-  // The inner digest
-  sha1_init(&ictx);
+  // Initialize the inner digest
+  sha1_init(&hd->ictx);
   for (int i=0; i < SHA1_BLOCK_SIZE; i++)
     buf[i] = keybuf[i] ^ 0x36;
-  sha1_update(&ictx, buf, SHA1_BLOCK_SIZE);
-  sha1_update(&ictx, data, datalen);
-  byte *isha = sha1_final(&ictx);
+  sha1_update(&hd->ictx, buf, SHA1_BLOCK_SIZE);
 
-  // The outer digest
-  sha1_init(&octx);
+  // Initialize the outer digest
+  sha1_init(&hd->octx);
   for (int i=0; i < SHA1_BLOCK_SIZE; i++)
     buf[i] = keybuf[i] ^ 0x5c;
-  sha1_update(&octx, buf, SHA1_BLOCK_SIZE);
-  sha1_update(&octx, isha, SHA1_SIZE);
-  byte *osha = sha1_final(&octx);
+  sha1_update(&hd->octx, buf, SHA1_BLOCK_SIZE);
+}
+
+void
+sha1_hmac_update(sha1_hmac_context *hd, const byte *data, uint datalen)
+{
+  // Just update the inner digest
+  sha1_update(&hd->ictx, data, datalen);
+}
 
-  // Copy the result
+byte *sha1_hmac_final(sha1_hmac_context *hd)
+{
+  // Finish the inner digest
+  byte *isha = sha1_final(&hd->ictx);
+
+  // Finish the outer digest
+  sha1_update(&hd->octx, isha, SHA1_SIZE);
+  return sha1_final(&hd->octx);
+}
+
+void
+sha1_hmac(byte *outbuf, const byte *key, uint keylen, const byte *data, uint datalen)
+{
+  sha1_hmac_context hd;
+  sha1_hmac_init(&hd, key, keylen);
+  sha1_hmac_update(&hd, data, datalen);
+  byte *osha = sha1_hmac_final(&hd);
   memcpy(outbuf, osha, SHA1_SIZE);
 }
 
 #ifdef TEST
 
 #include <stdio.h>
-#include "ucw/string.h"
+#include <ucw/string.h>
 
-static uns rd(char *dest)
+static uint rd(char *dest)
 {
   char buf[1024];
-  fgets(buf, sizeof(buf), stdin);
+  if (!fgets(buf, sizeof(buf), stdin))
+    die("fgets()");
   *strchr(buf, '\n') = 0;
   if (buf[0] == '0' && buf[1] == 'x')
     {
@@ -77,8 +97,8 @@ int main(void)
 {
   char key[1024], data[1024];
   byte hmac[SHA1_SIZE];
-  uns kl = rd(key);
-  uns dl = rd(data);
+  uint kl = rd(key);
+  uint dl = rd(data);
   sha1_hmac(hmac, key, kl, data, dl);
   mem_to_hex(data, hmac, SHA1_SIZE, 0);
   puts(data);