From: Martin Mares Date: Tue, 1 Jul 2008 16:35:11 +0000 (+0200) Subject: Libucw: Added an implementation of HMAC-SHA1. X-Git-Tag: holmes-import~406 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=92655707e71f24b309fdc9966c4feaef42e46988;p=libucw.git Libucw: Added an implementation of HMAC-SHA1. --- diff --git a/lib/Makefile b/lib/Makefile index fcc96f77..1f4193c1 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -26,7 +26,7 @@ LIBUCW_MODS= \ url \ mainloop exitstatus runcmd sighandler \ lizard lizard-safe adler32 \ - md5 sha1 \ + md5 sha1 sha1-hmac \ base64 base224 \ sync \ qache \ @@ -113,7 +113,7 @@ $(o)/lib/ff-unicode.test: $(o)/lib/ff-unicode-t $(o)/lib/eltpool.test: $(o)/lib/eltpool-t $(o)/lib/fb-socket.test: $(o)/lib/fb-socket-t $(o)/lib/string.test: $(o)/lib/str-hex-t $(o)/lib/str-esc-t -$(o)/lib/sha1.test: $(o)/lib/sha1-t +$(o)/lib/sha1.test: $(o)/lib/sha1-t $(o)/lib/sha1-hmac-t ifdef CONFIG_UCW_THREADS TESTS+=$(addprefix $(o)/lib/,asio.test) diff --git a/lib/sha1-hmac.c b/lib/sha1-hmac.c new file mode 100644 index 00000000..a2423492 --- /dev/null +++ b/lib/sha1-hmac.c @@ -0,0 +1,88 @@ +/* + * HMAC-SHA1 Message Authentication Code (RFC 2202) + * + * (c) 2008 Martin Mares + * + * This software may be freely distributed and used according to the terms + * of the GNU Lesser General Public License. + */ + +#include "lib/lib.h" +#include "lib/sha1.h" + +#include + +void +sha1_hmac(byte *outbuf, const byte *key, uns keylen, const byte *data, uns datalen) +{ + sha1_context ictx, octx; + byte keybuf[SHA1_BLOCK_SIZE], buf[SHA1_BLOCK_SIZE]; + + // Hash the key if necessary + if (keylen <= SHA1_BLOCK_SIZE) + { + memcpy(keybuf, key, keylen); + bzero(keybuf + keylen, SHA1_BLOCK_SIZE - keylen); + } + else + { + sha1_hash_buffer(keybuf, key, keylen); + bzero(keybuf + SHA1_SIZE, SHA1_BLOCK_SIZE - SHA1_SIZE); + } + + // The inner digest + sha1_init(&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); + + // The outer digest + sha1_init(&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); + + // Copy the result + memcpy(outbuf, osha, SHA1_SIZE); +} + +#ifdef TEST + +#include +#include "lib/string.h" + +static uns rd(char *dest) +{ + char buf[1024]; + fgets(buf, sizeof(buf), stdin); + *strchr(buf, '\n') = 0; + if (buf[0] == '0' && buf[1] == 'x') + { + const char *e = hex_to_mem(dest, buf+2, 1024, 0); + ASSERT(!*e); + return (e-buf-2)/2; + } + else + { + strcpy(dest, buf); + return strlen(dest); + } +} + +int main(void) +{ + char key[1024], data[1024]; + byte hmac[SHA1_SIZE]; + uns kl = rd(key); + uns dl = rd(data); + sha1_hmac(hmac, key, kl, data, dl); + mem_to_hex(data, hmac, SHA1_SIZE, 0); + puts(data); + return 0; +} + +#endif diff --git a/lib/sha1.h b/lib/sha1.h index efc1dffd..05dc4853 100644 --- a/lib/sha1.h +++ b/lib/sha1.h @@ -28,7 +28,11 @@ byte *sha1_final(sha1_context *hd); /* One-shot interface */ void sha1_hash_buffer(byte *outbuf, const byte *buffer, uns length); +/* HMAC */ +void sha1_hmac(byte *outbuf, const byte *key, uns keylen, const byte *data, uns datalen); + #define SHA1_SIZE 20 #define SHA1_HEX_SIZE 41 +#define SHA1_BLOCK_SIZE 64 #endif diff --git a/lib/sha1.t b/lib/sha1.t index c5952df3..62696588 100644 --- a/lib/sha1.t +++ b/lib/sha1.t @@ -1,7 +1,65 @@ # Tests of the SHA1 module +Name: SHA1-1 Run: echo -n "abc" | ../obj/lib/sha1-t Out: a9993e364706816aba3e25717850c26c9cd0d89d +Name: SHA1-2 Run: echo -n "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" | ../obj/lib/sha1-t Out: 84983e441c3bd26ebaae4aa1f95129e5e54670f1 + +# Tests of SHA-1 HMAC specified in RFC 2202 + +Name: HMAC1 +Run: ../obj/lib/sha1-hmac-t +In: 0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b + Hi There +Out: b617318655057264e28bc0b6fb378c8ef146be00 + +Name: HMAC2 +Run: ../obj/lib/sha1-hmac-t +In: Jefe + what do ya want for nothing? +Out: effcdf6ae5eb2fa2d27416d5f184df9c259a7c79 + +Name: HMAC3 +Run: ../obj/lib/sha1-hmac-t +In: 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + 0xdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd +Out: 125d7342b9ac11cd91a39af48aa17b4f63f175d3 + +Name: HMAC4 +Run: ../obj/lib/sha1-hmac-t +In: 0x0102030405060708090a0b0c0d0e0f10111213141516171819 + 0xcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd +Out: 4c9007f4026250c6bc8414f9bf50c86c2d7235da + +Name: HMAC5 +Run: ../obj/lib/sha1-hmac-t +In: 0x0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c + Test With Truncation +Out: 4c1a03424b55e07fe7f27be1d58bb9324a9a5a04 + +Name: HMAC6 +Run: ../obj/lib/sha1-hmac-t +In: 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + Test Using Larger Than Block-Size Key - Hash Key First +Out: aa4ae5e15272d00e95705637ce8a3b55ed402112 + +Name: HMAC7 +Run: ../obj/lib/sha1-hmac-t +In: 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data +Out: e8e99d0f45237d786d6bbaa7965c7808bbff1a91 + +Name: HMAC8 +Run: ../obj/lib/sha1-hmac-t +In: 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + Test Using Larger Than Block-Size Key - Hash Key First +Out: aa4ae5e15272d00e95705637ce8a3b55ed402112 + +Name: HMAC9 +Run: ../obj/lib/sha1-hmac-t +In: 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data +Out: e8e99d0f45237d786d6bbaa7965c7808bbff1a91