url \
mainloop exitstatus runcmd sighandler \
lizard lizard-safe adler32 \
- md5 sha1 \
+ md5 sha1 sha1-hmac \
base64 base224 \
sync \
qache \
$(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)
--- /dev/null
+/*
+ * HMAC-SHA1 Message Authentication Code (RFC 2202)
+ *
+ * (c) 2008 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 "lib/lib.h"
+#include "lib/sha1.h"
+
+#include <string.h>
+
+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 <stdio.h>
+#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
/* 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
# 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