X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=ucw%2Fsha1-hmac.c;h=b52011b1b74dcf71cacf1ca8ec82f78c99ddcb46;hb=0895fc9a44fde521ec31e066cccafd052f2a15a0;hp=2c4ee1247e5e4e75077a8d54d12628d39fa88ea5;hpb=031256ad2e123eec58521f8e3eb9496c197641d2;p=libucw.git diff --git a/ucw/sha1-hmac.c b/ucw/sha1-hmac.c index 2c4ee124..b52011b1 100644 --- a/ucw/sha1-hmac.c +++ b/ucw/sha1-hmac.c @@ -1,21 +1,20 @@ /* * HMAC-SHA1 Message Authentication Code (RFC 2202) * - * (c) 2008 Martin Mares + * (c) 2008--2009 Martin Mares * * 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 +#include #include 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 -#include "ucw/string.h" +#include -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);