summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorOndrej Zajicek (work) <santiago@crfreenet.org>2016-11-08 19:27:58 +0100
committerOndrej Zajicek (work) <santiago@crfreenet.org>2016-11-08 19:27:58 +0100
commit8860e991f6650e47cfe6c1af595fe4fe92a4edfd (patch)
tree18f49bb3a21739a1a596b54d9f65e82cff4fc09f /lib
parentcc5b93f72db80abd1262a0a5e1d8400ceef54385 (diff)
parentc8cafc8ebb5320ac7c6117c17e6460036f0fdf62 (diff)
Merge branch 'master' into int-new
Diffstat (limited to 'lib')
-rw-r--r--lib/Doc1
-rw-r--r--lib/Makefile2
-rw-r--r--lib/birdlib.h1
-rw-r--r--lib/buffer.h16
-rw-r--r--lib/hash.h29
-rw-r--r--lib/idm.c2
-rw-r--r--lib/mac.c289
-rw-r--r--lib/mac.h121
-rw-r--r--lib/md5.c81
-rw-r--r--lib/md5.h21
-rw-r--r--lib/sha1.c95
-rw-r--r--lib/sha1.h30
-rw-r--r--lib/sha256.c150
-rw-r--r--lib/sha256.h42
-rw-r--r--lib/sha512.c150
-rw-r--r--lib/sha512.h44
-rw-r--r--lib/socket.h2
-rw-r--r--lib/string.h19
18 files changed, 545 insertions, 550 deletions
diff --git a/lib/Doc b/lib/Doc
index 8af1c669..632bf1f6 100644
--- a/lib/Doc
+++ b/lib/Doc
@@ -2,6 +2,7 @@ H Library functions
S ip.c
S lists.c
S checksum.c bitops.c patmatch.c printf.c xmalloc.c tbf.c
+S mac.c
D resource.sgml
S resource.c
S mempool.c
diff --git a/lib/Makefile b/lib/Makefile
index 8e372bd3..551089c3 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -1,3 +1,3 @@
-src := bitops.c checksum.c event.c idm.c ip.c lists.c md5.c mempool.c net.c patmatch.c printf.c resource.c sha1.c sha256.c sha512.c slab.c slists.c tbf.c xmalloc.c
+src := bitops.c checksum.c event.c idm.c ip.c lists.c mac.c md5.c mempool.c net.c patmatch.c printf.c resource.c sha1.c sha256.c sha512.c slab.c slists.c tbf.c xmalloc.c
obj := $(src-o-files)
$(all-daemon)
diff --git a/lib/birdlib.h b/lib/birdlib.h
index 188e59b2..ddc963f4 100644
--- a/lib/birdlib.h
+++ b/lib/birdlib.h
@@ -63,7 +63,6 @@ static inline int u64_cmp(u64 i1, u64 i2)
#define UNUSED __attribute__((unused))
#define PACKED __attribute__((packed))
-
/* Microsecond time */
typedef s64 btime;
diff --git a/lib/buffer.h b/lib/buffer.h
index cf073e88..2a53f211 100644
--- a/lib/buffer.h
+++ b/lib/buffer.h
@@ -1,3 +1,17 @@
+/*
+ * BIRD Library -- Generic Buffer Structure
+ *
+ * (c) 2013 Ondrej Zajicek <santiago@crfreenet.org>
+ * (c) 2013 CZ.NIC z.s.p.o.
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#ifndef _BIRD_BUFFER_H_
+#define _BIRD_BUFFER_H_
+
+#include "lib/resource.h"
+#include "sysdep/config.h"
#define BUFFER(type) struct { type *data; uint used, size; }
@@ -32,4 +46,4 @@
#define BUFFER_FLUSH(v) ({ (v).used = 0; })
-
+#endif /* _BIRD_BUFFER_H_ */
diff --git a/lib/hash.h b/lib/hash.h
index c2fd8bca..b37d8fa5 100644
--- a/lib/hash.h
+++ b/lib/hash.h
@@ -1,8 +1,18 @@
-
+/*
+ * BIRD Library -- Generic Hash Table
+ *
+ * (c) 2013 Ondrej Zajicek <santiago@crfreenet.org>
+ * (c) 2013 CZ.NIC z.s.p.o.
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#ifndef _BIRD_HASH_H_
+#define _BIRD_HASH_H_
#define HASH(type) struct { type **data; uint count, order; }
#define HASH_TYPE(v) typeof(** (v).data)
-#define HASH_SIZE(v) (1 << (v).order)
+#define HASH_SIZE(v) (1U << (v).order)
#define HASH_EQ(v,id,k1,k2...) (id##_EQ(k1, k2))
#define HASH_FN(v,id,key...) ((u32) (id##_FN(key)) >> (32 - (v).order))
@@ -116,12 +126,12 @@
#define HASH_MAY_RESIZE_DOWN_(v,pool,rehash_fn,args) \
({ \
- int _o = (v).order; \
- while (((v).count < ((1 << _o) REHASH_LO_MARK(args))) && \
+ uint _o = (v).order; \
+ while (((v).count < ((1U << _o) REHASH_LO_MARK(args))) && \
(_o > (REHASH_LO_BOUND(args)))) \
_o -= (REHASH_LO_STEP(args)); \
if (_o < (v).order) \
- rehash_fn(&(v), pool, _o - (int) (v).order); \
+ rehash_fn(&(v), pool, _o - (v).order); \
})
@@ -178,6 +188,7 @@
#define HASH_WALK_FILTER_END } while (0)
+
static inline void
mem_hash_init(u64 *h)
{
@@ -185,14 +196,15 @@ mem_hash_init(u64 *h)
}
static inline void
-mem_hash_mix(u64 *h, void *p, int s)
+mem_hash_mix(u64 *h, void *p, uint s)
{
const u64 multiplier = 0xb38bc09a61202731ULL;
const char *pp = p;
uint i;
+
for (i=0; i<s/4; i++)
*h = *h * multiplier + ((const u32 *)pp)[i];
-
+
for (i=s & ~0x3; i<s; i++)
*h = *h * multiplier + pp[i];
}
@@ -204,7 +216,7 @@ mem_hash_value(u64 *h)
}
static inline uint
-mem_hash(void *p, int s)
+mem_hash(void *p, uint s)
{
static u64 h;
mem_hash_init(&h);
@@ -212,3 +224,4 @@ mem_hash(void *p, int s)
return mem_hash_value(&h);
}
+#endif
diff --git a/lib/idm.c b/lib/idm.c
index 16d0e855..66e311c6 100644
--- a/lib/idm.c
+++ b/lib/idm.c
@@ -53,7 +53,7 @@ idm_alloc(struct idm *m)
ASSERT(0);
- found:
+found:
ASSERT(i < 0x8000000);
m->pos = i;
diff --git a/lib/mac.c b/lib/mac.c
new file mode 100644
index 00000000..977d6559
--- /dev/null
+++ b/lib/mac.c
@@ -0,0 +1,289 @@
+/*
+ * BIRD Library -- Message Authentication Codes
+ *
+ * (c) 2016 Ondrej Zajicek <santiago@crfreenet.org>
+ * (c) 2016 CZ.NIC z.s.p.o.
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+/**
+ * DOC: Message authentication codes
+ *
+ * MAC algorithms are simple cryptographic tools for message authentication.
+ * They use shared a secret key a and message text to generate authentication
+ * code, which is then passed with the message to the other side, where the code
+ * is verified. There are multiple families of MAC algorithms based on different
+ * cryptographic primitives, BIRD implements two MAC families which use hash
+ * functions.
+ *
+ * The first family is simply a cryptographic hash camouflaged as MAC algorithm.
+ * Originally supposed to be (m|k)-hash (message is concatenated with key, and
+ * that is hashed), but later it turned out that a raw hash is more practical.
+ * This is used for cryptographic authentication in OSPFv2, RIP and BFD.
+ *
+ * The second family is the standard HMAC (RFC 2104), using inner and outer hash
+ * to process key and message. HMAC (with SHA) is used in advanced OSPF and RIP
+ * authentication (RFC 5709, RFC 4822).
+ */
+
+#include "lib/mac.h"
+#include "lib/md5.h"
+#include "lib/sha1.h"
+#include "lib/sha256.h"
+#include "lib/sha512.h"
+
+
+/*
+ * Internal hash calls
+ */
+
+static inline void
+hash_init(struct mac_context *mctx, struct hash_context *hctx)
+{ mctx->type->hash_init(hctx); }
+
+static inline void
+hash_update(struct mac_context *mctx, struct hash_context *hctx, const byte *buf, uint len)
+{ mctx->type->hash_update(hctx, buf, len); }
+
+static inline byte *
+hash_final(struct mac_context *mctx, struct hash_context *hctx)
+{ return mctx->type->hash_final(hctx); }
+
+static inline void
+hash_buffer(struct mac_context *mctx, byte *outbuf, const byte *buffer, uint length)
+{
+ struct hash_context hctx;
+
+ hash_init(mctx, &hctx);
+ hash_update(mctx, &hctx, buffer, length);
+ memcpy(outbuf, hash_final(mctx, &hctx), mctx->type->hash_size);
+}
+
+
+/*
+ * (not-really-MAC) Hash
+ */
+
+static void
+nrmh_init(struct mac_context *ctx, const byte *key UNUSED, uint keylen UNUSED)
+{
+ struct nrmh_context *ct = (void *) ctx;
+ hash_init(ctx, &ct->ictx);
+}
+
+static void
+nrmh_update(struct mac_context *ctx, const byte *data, uint datalen)
+{
+ struct nrmh_context *ct = (void *) ctx;
+ hash_update(ctx, &ct->ictx, data, datalen);
+}
+
+static byte *
+nrmh_final(struct mac_context *ctx)
+{
+ struct nrmh_context *ct = (void *) ctx;
+ return hash_final(ctx, &ct->ictx);
+}
+
+
+/*
+ * HMAC
+ */
+
+static void
+hmac_init(struct mac_context *ctx, const byte *key, uint keylen)
+{
+ struct hmac_context *ct = (void *) ctx;
+ uint block_size = ctx->type->block_size;
+ uint hash_size = ctx->type->hash_size;
+
+ byte *keybuf = alloca(block_size);
+ byte *buf = alloca(block_size);
+ uint i;
+
+ /* Hash the key if necessary */
+ if (keylen <= block_size)
+ {
+ memcpy(keybuf, key, keylen);
+ memset(keybuf + keylen, 0, block_size - keylen);
+ }
+ else
+ {
+ hash_buffer(ctx, keybuf, key, keylen);
+ memset(keybuf + hash_size, 0, block_size - hash_size);
+ }
+
+ /* Initialize the inner digest */
+ hash_init(ctx, &ct->ictx);
+ for (i = 0; i < block_size; i++)
+ buf[i] = keybuf[i] ^ 0x36;
+ hash_update(ctx, &ct->ictx, buf, block_size);
+
+ /* Initialize the outer digest */
+ hash_init(ctx, &ct->octx);
+ for (i = 0; i < block_size; i++)
+ buf[i] = keybuf[i] ^ 0x5c;
+ hash_update(ctx, &ct->octx, buf, block_size);
+}
+
+static void
+hmac_update(struct mac_context *ctx, const byte *data, uint datalen)
+{
+ struct hmac_context *ct = (void *) ctx;
+
+ /* Just update the inner digest */
+ hash_update(ctx, &ct->ictx, data, datalen);
+}
+
+static byte *
+hmac_final(struct mac_context *ctx)
+{
+ struct hmac_context *ct = (void *) ctx;
+
+ /* Finish the inner digest */
+ byte *isha = hash_final(ctx, &ct->ictx);
+
+ /* Finish the outer digest */
+ hash_update(ctx, &ct->octx, isha, ctx->type->hash_size);
+ return hash_final(ctx, &ct->octx);
+}
+
+
+/*
+ * Common code
+ */
+
+#define HASH_DESC(name, px, PX) \
+ { name, PX##_SIZE, sizeof(struct nrmh_context), nrmh_init, nrmh_update, nrmh_final, \
+ PX##_SIZE, PX##_BLOCK_SIZE, px##_init, px##_update, px##_final }
+
+#define HMAC_DESC(name, px, PX) \
+ { name, PX##_SIZE, sizeof(struct hmac_context), hmac_init, hmac_update, hmac_final, \
+ PX##_SIZE, PX##_BLOCK_SIZE, px##_init, px##_update, px##_final }
+
+const struct mac_desc mac_table[ALG_MAX] = {
+ [ALG_MD5] = HASH_DESC("Keyed MD5", md5, MD5),
+ [ALG_SHA1] = HASH_DESC("Keyed SHA-1", sha1, SHA1),
+ [ALG_SHA224] = HASH_DESC("Keyed SHA-224", sha224, SHA224),
+ [ALG_SHA256] = HASH_DESC("Keyed SHA-256", sha256, SHA256),
+ [ALG_SHA384] = HASH_DESC("Keyed SHA-384", sha384, SHA384),
+ [ALG_SHA512] = HASH_DESC("Keyed SHA-512", sha512, SHA512),
+ [ALG_HMAC_MD5] = HMAC_DESC("HMAC-MD5", md5, MD5),
+ [ALG_HMAC_SHA1] = HMAC_DESC("HMAC-SHA-1", sha1, SHA1),
+ [ALG_HMAC_SHA224] = HMAC_DESC("HMAC-SHA-224", sha224, SHA224),
+ [ALG_HMAC_SHA256] = HMAC_DESC("HMAC-SHA-256", sha256, SHA256),
+ [ALG_HMAC_SHA384] = HMAC_DESC("HMAC-SHA-384", sha384, SHA384),
+ [ALG_HMAC_SHA512] = HMAC_DESC("HMAC-SHA-512", sha512, SHA512),
+};
+
+
+/**
+ * mac_init - initialize MAC algorithm
+ * @ctx: context to initialize
+ * @id: MAC algorithm ID
+ * @key: MAC key
+ * @keylen: MAC key length
+ *
+ * Initialize MAC context @ctx for algorithm @id (e.g., %ALG_HMAC_SHA1), with
+ * key @key of length @keylen. After that, message data could be added using
+ * mac_update() function.
+ */
+void
+mac_init(struct mac_context *ctx, uint id, const byte *key, uint keylen)
+{
+ ctx->type = &mac_table[id];
+ ctx->type->init(ctx, key, keylen);
+}
+
+#if 0
+/**
+ * mac_update - add more data to MAC algorithm
+ * @ctx: MAC context
+ * @data: data to add
+ * @datalen: length of data
+ *
+ * Push another @datalen bytes of data pointed to by @data into the MAC
+ * algorithm currently in @ctx. Can be called multiple times for the same MAC
+ * context. It has the same effect as concatenating all the data together and
+ * passing them at once.
+ */
+void mac_update(struct mac_context *ctx, const byte *data, uint datalen)
+{ DUMMY; }
+
+/**
+ * mac_final - finalize MAC algorithm
+ * @ctx: MAC context
+ *
+ * Finish MAC computation and return a pointer to the result. No more
+ * @mac_update() calls could be done, but the context may be reinitialized
+ * later.
+ *
+ * Note that the returned pointer points into data in the @ctx context. If it
+ * ceases to exist, the pointer becomes invalid.
+ */
+byte *mac_final(struct mac_context *ctx)
+{ DUMMY; }
+
+/**
+ * mac_cleanup - cleanup MAC context
+ * @ctx: MAC context
+ *
+ * Cleanup MAC context after computation (by filling with zeros). Not strictly
+ * necessary, just to erase sensitive data from stack. This also invalidates the
+ * pointer returned by @mac_final().
+ */
+void mac_cleanup(struct mac_context *ctx)
+{ DUMMY; }
+
+#endif
+
+/**
+ * mac_fill - compute and fill MAC
+ * @id: MAC algorithm ID
+ * @key: secret key
+ * @keylen: key length
+ * @data: message data
+ * @datalen: message length
+ * @mac: place to fill MAC
+ *
+ * Compute MAC for specified key @key and message @data using algorithm @id and
+ * copy it to buffer @mac. mac_fill() is a shortcut function doing all usual
+ * steps for transmitted messages.
+ */
+void
+mac_fill(uint id, const byte *key, uint keylen, const byte *data, uint datalen, byte *mac)
+{
+ struct mac_context ctx;
+
+ mac_init(&ctx, id, key, keylen);
+ mac_update(&ctx, data, datalen);
+ memcpy(mac, mac_final(&ctx), mac_get_length(&ctx));
+ mac_cleanup(&ctx);
+}
+
+/**
+ * mac_verify - compute and verify MAC
+ * @id: MAC algorithm ID
+ * @key: secret key
+ * @keylen: key length
+ * @data: message data
+ * @datalen: message length
+ * @mac: received MAC
+ *
+ * Compute MAC for specified key @key and message @data using algorithm @id and
+ * compare it with received @mac, return whether they are the same. mac_verify()
+ * is a shortcut function doing all usual steps for received messages.
+ */
+int
+mac_verify(uint id, const byte *key, uint keylen, const byte *data, uint datalen, const byte *mac)
+{
+ struct mac_context ctx;
+
+ mac_init(&ctx, id, key, keylen);
+ mac_update(&ctx, data, datalen);
+ int res = !memcmp(mac, mac_final(&ctx), mac_get_length(&ctx));
+ mac_cleanup(&ctx);
+
+ return res;
+}
diff --git a/lib/mac.h b/lib/mac.h
new file mode 100644
index 00000000..b6f3af52
--- /dev/null
+++ b/lib/mac.h
@@ -0,0 +1,121 @@
+/*
+ * BIRD Library -- Message Authentication Codes
+ *
+ * (c) 2016 Ondrej Zajicek <santiago@crfreenet.org>
+ * (c) 2016 CZ.NIC z.s.p.o.
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#ifndef _BIRD_MAC_H_
+#define _BIRD_MAC_H_
+
+#include "nest/bird.h"
+#include "lib/sha512.h"
+
+
+#define ALG_UNDEFINED 0
+#define ALG_MD5 0x01
+#define ALG_SHA1 0x02
+#define ALG_SHA224 0x03
+#define ALG_SHA256 0x04
+#define ALG_SHA384 0x05
+#define ALG_SHA512 0x06
+#define ALG_HMAC 0x10
+#define ALG_HMAC_MD5 0x11
+#define ALG_HMAC_SHA1 0x12
+#define ALG_HMAC_SHA224 0x13
+#define ALG_HMAC_SHA256 0x14
+#define ALG_HMAC_SHA384 0x15
+#define ALG_HMAC_SHA512 0x16
+#define ALG_MAX 0x17
+
+/* These are maximums for HASH/MAC lengths and required context space */
+#define MAX_HASH_SIZE SHA512_SIZE
+#define HASH_STORAGE sizeof(struct sha512_context)
+#define MAC_STORAGE sizeof(struct hmac_context)
+
+/* This value is used by several IETF protocols for padding */
+#define HMAC_MAGIC htonl(0x878FE1F3)
+
+/* Generic context used by hash functions */
+struct hash_context
+{
+ u8 data[HASH_STORAGE];
+ u64 align[0];
+};
+
+/* Context for embedded hash (not-really-MAC hash) */
+struct nrmh_context {
+ const struct mac_desc *type;
+ struct hash_context ictx;
+};
+
+/* Context for hash based HMAC */
+struct hmac_context {
+ const struct mac_desc *type;
+ struct hash_context ictx;
+ struct hash_context octx;
+};
+
+/* Generic context used by MAC functions */
+struct mac_context
+{
+ const struct mac_desc *type;
+ u8 data[MAC_STORAGE - sizeof(void *)];
+ u64 align[0];
+};
+
+/* Union to satisfy C aliasing rules */
+union mac_context_union {
+ struct mac_context mac;
+ struct nrmh_context nrmh;
+ struct hmac_context hmac;
+};
+
+
+struct mac_desc {
+ const char *name; /* Name of MAC algorithm */
+ uint mac_length; /* Length of authentication code */
+ uint ctx_length; /* Length of algorithm context */
+ void (*init)(struct mac_context *ctx, const byte *key, uint keylen);
+ void (*update)(struct mac_context *ctx, const byte *data, uint datalen);
+ byte *(*final)(struct mac_context *ctx);
+
+ uint hash_size; /* Hash length, for hash-based MACs */
+ uint block_size; /* Hash block size, for hash-based MACs */
+ void (*hash_init)(struct hash_context *ctx);
+ void (*hash_update)(struct hash_context *ctx, const byte *data, uint datalen);
+ byte *(*hash_final)(struct hash_context *ctx);
+};
+
+extern const struct mac_desc mac_table[ALG_MAX];
+
+static inline const char *mac_type_name(uint id)
+{ return mac_table[id].name; }
+
+static inline uint mac_type_length(uint id)
+{ return mac_table[id].mac_length; }
+
+static inline const char *mac_get_name(struct mac_context *ctx)
+{ return ctx->type->name; }
+
+static inline uint mac_get_length(struct mac_context *ctx)
+{ return ctx->type->mac_length; }
+
+void mac_init(struct mac_context *ctx, uint id, const byte *key, uint keylen);
+
+static inline void mac_update(struct mac_context *ctx, const byte *data, uint datalen)
+{ ctx->type->update(ctx, data, datalen); }
+
+static inline byte *mac_final(struct mac_context *ctx)
+{ return ctx->type->final(ctx); }
+
+static inline void mac_cleanup(struct mac_context *ctx)
+{ memset(ctx, 0, ctx->type->ctx_length); }
+
+void mac_fill(uint id, const byte *key, uint keylen, const byte *data, uint datalen, byte *mac);
+int mac_verify(uint id, const byte *key, uint keylen, const byte *data, uint datalen, const byte *mac);
+
+
+#endif /* _BIRD_MAC_H_ */
diff --git a/lib/md5.c b/lib/md5.c
index 8efa62d6..df49de5d 100644
--- a/lib/md5.c
+++ b/lib/md5.c
@@ -39,8 +39,10 @@ static void md5_transform(u32 buf[4], u32 const in[16]);
* initialization constants.
*/
void
-md5_init(struct md5_context *ctx)
+md5_init(struct hash_context *CTX)
{
+ struct md5_context *ctx = (void *) CTX;
+
ctx->buf[0] = 0x67452301;
ctx->buf[1] = 0xefcdab89;
ctx->buf[2] = 0x98badcfe;
@@ -55,8 +57,9 @@ md5_init(struct md5_context *ctx)
* of bytes.
*/
void
-md5_update(struct md5_context *ctx, const byte *buf, uint len)
+md5_update(struct hash_context *CTX, const byte *buf, uint len)
{
+ struct md5_context *ctx = (void *) CTX;
u32 t;
/* Update bitcount */
@@ -105,8 +108,9 @@ md5_update(struct md5_context *ctx, const byte *buf, uint len)
* 1 0* (64-bit count of bits processed, MSB-first)
*/
byte *
-md5_final(struct md5_context *ctx)
+md5_final(struct hash_context *CTX)
{
+ struct md5_context *ctx = (void *) CTX;
uint count;
byte *p;
@@ -149,13 +153,6 @@ md5_final(struct md5_context *ctx)
return (byte*) ctx->buf;
}
-/* I am a hard paranoid */
-void
-md5_erase_ctx(struct md5_context *ctx)
-{
- memset((char *) ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
-}
-
/* The four core functions - F1 is optimized somewhat */
/* #define F1(x, y, z) (x & y | ~x & z) */
@@ -256,67 +253,3 @@ md5_transform(u32 buf[4], u32 const in[16])
buf[2] += c;
buf[3] += d;
}
-
-
-/*
- * MD5-HMAC
- */
-
-static void
-md5_hash_buffer(byte *outbuf, const byte *buffer, size_t length)
-{
- struct md5_context hd_tmp;
-
- md5_init(&hd_tmp);
- md5_update(&hd_tmp, buffer, length);
- memcpy(outbuf, md5_final(&hd_tmp), MD5_SIZE);
-}
-
-void
-md5_hmac_init(struct md5_hmac_context *ctx, const byte *key, size_t keylen)
-{
- byte keybuf[MD5_BLOCK_SIZE], buf[MD5_BLOCK_SIZE];
-
- /* Hash the key if necessary */
- if (keylen <= MD5_BLOCK_SIZE)
- {
- memcpy(keybuf, key, keylen);
- bzero(keybuf + keylen, MD5_BLOCK_SIZE - keylen);
- }
- else
- {
- md5_hash_buffer(keybuf, key, keylen);
- bzero(keybuf + MD5_SIZE, MD5_BLOCK_SIZE - MD5_SIZE);
- }
-
- /* Initialize the inner digest */
- md5_init(&ctx->ictx);
- int i;
- for (i = 0; i < MD5_BLOCK_SIZE; i++)
- buf[i] = keybuf[i] ^ 0x36;
- md5_update(&ctx->ictx, buf, MD5_BLOCK_SIZE);
-
- /* Initialize the outer digest */
- md5_init(&ctx->octx);
- for (i = 0; i < MD5_BLOCK_SIZE; i++)
- buf[i] = keybuf[i] ^ 0x5c;
- md5_update(&ctx->octx, buf, MD5_BLOCK_SIZE);
-}
-
-void
-md5_hmac_update(struct md5_hmac_context *ctx, const byte *buf, size_t buflen)
-{
- /* Just update the inner digest */
- md5_update(&ctx->ictx, buf, buflen);
-}
-
-byte *
-md5_hmac_final(struct md5_hmac_context *ctx)
-{
- /* Finish the inner digest */
- byte *isha = md5_final(&ctx->ictx);
-
- /* Finish the outer digest */
- md5_update(&ctx->octx, isha, MD5_SIZE);
- return md5_final(&ctx->octx);
-}
diff --git a/lib/md5.h b/lib/md5.h
index 034d764c..4e001851 100644
--- a/lib/md5.h
+++ b/lib/md5.h
@@ -19,29 +19,18 @@
#define MD5_BLOCK_SIZE 64
+struct hash_context;
+
struct md5_context {
u32 buf[4];
u32 bits[2];
byte in[64];
};
-void md5_init(struct md5_context *ctx);
-void md5_update(struct md5_context *ctx, const byte *buf, uint len);
-byte *md5_final(struct md5_context *ctx);
-
-
-/*
- * HMAC-MD5
- */
-
-struct md5_hmac_context {
- struct md5_context ictx;
- struct md5_context octx;
-};
-void md5_hmac_init(struct md5_hmac_context *ctx, const byte *key, size_t keylen);
-void md5_hmac_update(struct md5_hmac_context *ctx, const byte *buf, size_t buflen);
-byte *md5_hmac_final(struct md5_hmac_context *ctx);
+void md5_init(struct hash_context *ctx);
+void md5_update(struct hash_context *ctx, const byte *buf, uint len);
+byte *md5_final(struct hash_context *ctx);
#endif /* _BIRD_MD5_H_ */
diff --git a/lib/sha1.c b/lib/sha1.c
index 73b4b280..d6298b89 100644
--- a/lib/sha1.c
+++ b/lib/sha1.c
@@ -1,5 +1,5 @@
/*
- * BIRD Library -- SHA-1 Hash Function (FIPS 180-1, RFC 3174) and HMAC-SHA-1
+ * BIRD Library -- SHA-1 Hash Function (FIPS 180-1, RFC 3174)
*
* (c) 2015 CZ.NIC z.s.p.o.
*
@@ -17,8 +17,10 @@
void
-sha1_init(struct sha1_context *ctx)
+sha1_init(struct hash_context *CTX)
{
+ struct sha1_context *ctx = (void *) CTX;
+
ctx->h0 = 0x67452301;
ctx->h1 = 0xefcdab89;
ctx->h2 = 0x98badcfe;
@@ -167,8 +169,10 @@ sha1_transform(struct sha1_context *ctx, const byte *data)
* Update the message digest with the contents of BUF with length LEN.
*/
void
-sha1_update(struct sha1_context *ctx, const byte *buf, uint len)
+sha1_update(struct hash_context *CTX, const byte *buf, uint len)
{
+ struct sha1_context *ctx = (void *) CTX;
+
if (ctx->count)
{
/* Fill rest of internal buffer */
@@ -209,11 +213,12 @@ sha1_update(struct sha1_context *ctx, const byte *buf, uint len)
* Returns: 20 bytes representing the digest.
*/
byte *
-sha1_final(struct sha1_context *ctx)
+sha1_final(struct hash_context *CTX)
{
+ struct sha1_context *ctx = (void *) CTX;
u32 t, msb, lsb;
- sha1_update(ctx, NULL, 0); /* flush */
+ sha1_update(CTX, NULL, 0); /* flush */
t = ctx->nblocks;
/* multiply by 64 to make a byte count */
@@ -242,7 +247,7 @@ sha1_final(struct sha1_context *ctx)
ctx->buf[ctx->count++] = 0x80; /* pad character */
while (ctx->count < 64)
ctx->buf[ctx->count++] = 0;
- sha1_update(ctx, NULL, 0); /* flush */
+ sha1_update(CTX, NULL, 0); /* flush */
memset(ctx->buf, 0, 56); /* fill next block with zeroes */
}
@@ -268,81 +273,3 @@ sha1_final(struct sha1_context *ctx)
return ctx->buf;
}
-
-
-/*
- * SHA1-HMAC
- */
-
-/*
- * Shortcut function which puts the hash value of the supplied buffer
- * into outbuf which must have a size of 20 bytes.
- */
-void
-sha1_hash_buffer(byte *outbuf, const byte *buffer, uint length)
-{
- struct sha1_context ctx;
-
- sha1_init(&ctx);
- sha1_update(&ctx, buffer, length);
- memcpy(outbuf, sha1_final(&ctx), SHA1_SIZE);
-}
-
-void
-sha1_hmac_init(struct sha1_hmac_context *ctx, const byte *key, uint keylen)
-{
- byte keybuf[SHA1_BLOCK_SIZE], buf[SHA1_BLOCK_SIZE];
-
- /* Hash the key if necessary */
- if (keylen <= SHA1_BLOCK_SIZE)
- {
- memcpy(keybuf, key, keylen);
- memset(keybuf + keylen, 0, SHA1_BLOCK_SIZE - keylen);
- }
- else
- {
- sha1_hash_buffer(keybuf, key, keylen);
- memset(keybuf + SHA1_SIZE, 0, SHA1_BLOCK_SIZE - SHA1_SIZE);
- }
-
- /* Initialize the inner digest */
- sha1_init(&ctx->ictx);
- int i;
- for (i = 0; i < SHA1_BLOCK_SIZE; i++)
- buf[i] = keybuf[i] ^ 0x36;
- sha1_update(&ctx->ictx, buf, SHA1_BLOCK_SIZE);
-
- /* Initialize the outer digest */
- sha1_init(&ctx->octx);
- for (i = 0; i < SHA1_BLOCK_SIZE; i++)
- buf[i] = keybuf[i] ^ 0x5c;
- sha1_update(&ctx->octx, buf, SHA1_BLOCK_SIZE);
-}
-
-void
-sha1_hmac_update(struct sha1_hmac_context *ctx, const byte *data, uint datalen)
-{
- /* Just update the inner digest */
- sha1_update(&ctx->ictx, data, datalen);
-}
-
-byte *
-sha1_hmac_final(struct sha1_hmac_context *ctx)
-{
- /* Finish the inner digest */
- byte *isha = sha1_final(&ctx->ictx);
-
- /* Finish the outer digest */
- sha1_update(&ctx->octx, isha, SHA1_SIZE);
- return sha1_final(&ctx->octx);
-}
-
-void
-sha1_hmac(byte *outbuf, const byte *key, uint keylen, const byte *data, uint datalen)
-{
- struct sha1_hmac_context ctx;
-
- sha1_hmac_init(&ctx, key, keylen);
- sha1_hmac_update(&ctx, data, datalen);
- memcpy(outbuf, sha1_hmac_final(&ctx), SHA1_SIZE);
-}
diff --git a/lib/sha1.h b/lib/sha1.h
index c019bb49..8666a651 100644
--- a/lib/sha1.h
+++ b/lib/sha1.h
@@ -1,5 +1,5 @@
/*
- * BIRD Library -- SHA-1 Hash Function (FIPS 180-1, RFC 3174) and HMAC-SHA-1
+ * BIRD Library -- SHA-1 Hash Function (FIPS 180-1, RFC 3174)
*
* (c) 2015 CZ.NIC z.s.p.o.
*
@@ -27,6 +27,8 @@
* Internal SHA1 state.
* You should use it just as an opaque handle only.
*/
+struct hash_context;
+
struct sha1_context {
u32 h0, h1, h2, h3, h4;
byte buf[SHA1_BLOCK_SIZE];
@@ -34,15 +36,14 @@ struct sha1_context {
uint count;
};
-
-void sha1_init(struct sha1_context *ctx); /* Initialize new algorithm run in the @ctx context. **/
+void sha1_init(struct hash_context *ctx); /* Initialize new algorithm run in the @ctx context. **/
/*
* Push another @len bytes of data pointed to by @buf onto the SHA1 hash
* currently in @ctx. You can call this any times you want on the same hash (and
* you do not need to reinitialize it by @sha1_init()). It has the same effect
* as concatenating all the data together and passing them at once.
*/
-void sha1_update(struct sha1_context *ctx, const byte *buf, uint len);
+void sha1_update(struct hash_context *ctx, const byte *buf, uint len);
/*
* No more @sha1_update() calls will be done. This terminates the hash and
* returns a pointer to it.
@@ -50,7 +51,7 @@ void sha1_update(struct sha1_context *ctx, const byte *buf, uint len);
* Note that the pointer points into data in the @ctx context. If it ceases to
* exist, the pointer becomes invalid.
*/
-byte *sha1_final(struct sha1_context *ctx);
+byte *sha1_final(struct hash_context *ctx);
/*
* A convenience one-shot function for SHA1 hash. It is equivalent to this
@@ -63,24 +64,5 @@ byte *sha1_final(struct sha1_context *ctx);
*/
void sha1_hash_buffer(byte *outbuf, const byte *buffer, uint length);
-/*
- * SHA1 HMAC message authentication. If you provide @key and @data, the result
- * will be stored in @outbuf.
- */
-void sha1_hmac(byte *outbuf, const byte *key, uint keylen, const byte *data, uint datalen);
-
-/*
- * The HMAC also exists in a stream version in a way analogous to the plain
- * SHA1. Pass this as a context.
- */
-struct sha1_hmac_context {
- struct sha1_context ictx;
- struct sha1_context octx;
-};
-
-void sha1_hmac_init(struct sha1_hmac_context *ctx, const byte *key, uint keylen); /* Initialize HMAC with context @ctx and the given key. See sha1_init(). */
-void sha1_hmac_update(struct sha1_hmac_context *ctx, const byte *data, uint datalen); /* Hash another @datalen bytes of data. See sha1_update(). */
-byte *sha1_hmac_final(struct sha1_hmac_context *ctx); /* Terminate the HMAC and return a pointer to the allocated hash. See sha1_final(). */
-
#endif /* _BIRD_SHA1_H_ */
diff --git a/lib/sha256.c b/lib/sha256.c
index 440245d5..11ff2b05 100644
--- a/lib/sha256.c
+++ b/lib/sha256.c
@@ -1,6 +1,5 @@
/*
- * BIRD Library -- SHA-256 and SHA-224 Hash Functions,
- * HMAC-SHA-256 and HMAC-SHA-224 Functions
+ * BIRD Library -- SHA-256 and SHA-224 Hash Functions
*
* (c) 2015 CZ.NIC z.s.p.o.
*
@@ -17,8 +16,10 @@
// #define SHA256_UNROLLED
void
-sha256_init(struct sha256_context *ctx)
+sha256_init(struct hash_context *CTX)
{
+ struct sha256_context *ctx = (void *) CTX;
+
ctx->h0 = 0x6a09e667;
ctx->h1 = 0xbb67ae85;
ctx->h2 = 0x3c6ef372;
@@ -33,8 +34,10 @@ sha256_init(struct sha256_context *ctx)
}
void
-sha224_init(struct sha224_context *ctx)
+sha224_init(struct hash_context *CTX)
{
+ struct sha224_context *ctx = (void *) CTX;
+
ctx->h0 = 0xc1059ed8;
ctx->h1 = 0x367cd507;
ctx->h2 = 0x3070dd17;
@@ -219,8 +222,10 @@ sha256_transform(struct sha256_context *ctx, const byte *data)
not have any meaning but writing after finalize is sometimes
helpful to mitigate timing attacks. */
void
-sha256_update(struct sha256_context *ctx, const byte *buf, size_t len)
+sha256_update(struct hash_context *CTX, const byte *buf, uint len)
{
+ struct sha256_context *ctx = (void *) CTX;
+
if (ctx->count)
{
/* Fill rest of internal buffer */
@@ -261,11 +266,12 @@ sha256_update(struct sha256_context *ctx, const byte *buf, size_t len)
* Returns: 32 bytes with the message the digest. 28 bytes for SHA-224.
*/
byte *
-sha256_final(struct sha256_context *ctx)
+sha256_final(struct hash_context *CTX)
{
+ struct sha256_context *ctx = (void *) CTX;
u32 t, th, msb, lsb;
- sha256_update(ctx, NULL, 0); /* flush */
+ sha256_update(CTX, NULL, 0); /* flush */
t = ctx->nblocks;
th = 0;
@@ -296,7 +302,7 @@ sha256_final(struct sha256_context *ctx)
ctx->buf[ctx->count++] = 0x80; /* pad character */
while (ctx->count < 64)
ctx->buf[ctx->count++] = 0;
- sha256_update(ctx, NULL, 0); /* flush */;
+ sha256_update(CTX, NULL, 0); /* flush */;
memset(ctx->buf, 0, 56 ); /* fill next block with zeroes */
}
@@ -319,131 +325,3 @@ sha256_final(struct sha256_context *ctx)
return ctx->buf;
}
-
-
-/*
- * SHA256-HMAC
- */
-
-static void
-sha256_hash_buffer(byte *outbuf, const byte *buffer, size_t length)
-{
- struct sha256_context ctx;
-
- sha256_init(&ctx);
- sha256_update(&ctx, buffer, length);
- memcpy(outbuf, sha256_final(&ctx), SHA256_SIZE);
-}
-
-void
-sha256_hmac_init(struct sha256_hmac_context *ctx, const byte *key, size_t keylen)
-{
- byte keybuf[SHA256_BLOCK_SIZE], buf[SHA256_BLOCK_SIZE];
-
- /* Hash the key if necessary */
- if (keylen <= SHA256_BLOCK_SIZE)
- {
- memcpy(keybuf, key, keylen);
- memset(keybuf + keylen, 0, SHA256_BLOCK_SIZE - keylen);
- }
- else
- {
- sha256_hash_buffer(keybuf, key, keylen);
- memset(keybuf + SHA256_SIZE, 0, SHA256_BLOCK_SIZE - SHA256_SIZE);
- }
-
- /* Initialize the inner digest */
- sha256_init(&ctx->ictx);
- int i;
- for (i = 0; i < SHA256_BLOCK_SIZE; i++)
- buf[i] = keybuf[i] ^ 0x36;
- sha256_update(&ctx->ictx, buf, SHA256_BLOCK_SIZE);
-
- /* Initialize the outer digest */
- sha256_init(&ctx->octx);
- for (i = 0; i < SHA256_BLOCK_SIZE; i++)
- buf[i] = keybuf[i] ^ 0x5c;
- sha256_update(&ctx->octx, buf, SHA256_BLOCK_SIZE);
-}
-
-void
-sha256_hmac_update(struct sha256_hmac_context *ctx, const byte *buf, size_t buflen)
-{
- /* Just update the inner digest */
- sha256_update(&ctx->ictx, buf, buflen);
-}
-
-byte *
-sha256_hmac_final(struct sha256_hmac_context *ctx)
-{
- /* Finish the inner digest */
- byte *isha = sha256_final(&ctx->ictx);
-
- /* Finish the outer digest */
- sha256_update(&ctx->octx, isha, SHA256_SIZE);
- return sha256_final(&ctx->octx);
-}
-
-
-/*
- * SHA224-HMAC
- */
-
-static void
-sha224_hash_buffer(byte *outbuf, const byte *buffer, size_t length)
-{
- struct sha224_context ctx;
-
- sha224_init(&ctx);
- sha224_update(&ctx, buffer, length);
- memcpy(outbuf, sha224_final(&ctx), SHA224_SIZE);
-}
-
-void
-sha224_hmac_init(struct sha224_hmac_context *ctx, const byte *key, size_t keylen)
-{
- byte keybuf[SHA224_BLOCK_SIZE], buf[SHA224_BLOCK_SIZE];
-
- /* Hash the key if necessary */
- if (keylen <= SHA224_BLOCK_SIZE)
- {
- memcpy(keybuf, key, keylen);
- memset(keybuf + keylen, 0, SHA224_BLOCK_SIZE - keylen);
- }
- else
- {
- sha224_hash_buffer(keybuf, key, keylen);
- memset(keybuf + SHA224_SIZE, 0, SHA224_BLOCK_SIZE - SHA224_SIZE);
- }
-
- /* Initialize the inner digest */
- sha224_init(&ctx->ictx);
- int i;
- for (i = 0; i < SHA224_BLOCK_SIZE; i++)
- buf[i] = keybuf[i] ^ 0x36;
- sha224_update(&ctx->ictx, buf, SHA224_BLOCK_SIZE);
-
- /* Initialize the outer digest */
- sha224_init(&ctx->octx);
- for (i = 0; i < SHA224_BLOCK_SIZE; i++)
- buf[i] = keybuf[i] ^ 0x5c;
- sha224_update(&ctx->octx, buf, SHA224_BLOCK_SIZE);
-}
-
-void
-sha224_hmac_update(struct sha224_hmac_context *ctx, const byte *buf, size_t buflen)
-{
- /* Just update the inner digest */
- sha256_update(&ctx->ictx, buf, buflen);
-}
-
-byte *
-sha224_hmac_final(struct sha224_hmac_context *ctx)
-{
- /* Finish the inner digest */
- byte *isha = sha224_final(&ctx->ictx);
-
- /* Finish the outer digest */
- sha224_update(&ctx->octx, isha, SHA224_SIZE);
- return sha224_final(&ctx->octx);
-}
diff --git a/lib/sha256.h b/lib/sha256.h
index 381200a9..88a948eb 100644
--- a/lib/sha256.h
+++ b/lib/sha256.h
@@ -1,6 +1,5 @@
/*
- * BIRD Library -- SHA-256 and SHA-224 Hash Functions,
- * HMAC-SHA-256 and HMAC-SHA-224 Functions
+ * BIRD Library -- SHA-256 and SHA-224 Hash Functions
*
* (c) 2015 CZ.NIC z.s.p.o.
*
@@ -25,6 +24,8 @@
#define SHA256_BLOCK_SIZE 64
+struct hash_context;
+
struct sha256_context {
u32 h0, h1, h2, h3, h4, h5, h6, h7;
byte buf[SHA256_BLOCK_SIZE];
@@ -35,39 +36,14 @@ struct sha256_context {
#define sha224_context sha256_context
-void sha256_init(struct sha256_context *ctx);
-void sha224_init(struct sha224_context *ctx);
-
-void sha256_update(struct sha256_context *ctx, const byte *buf, size_t len);
-static inline void sha224_update(struct sha224_context *ctx, const byte *buf, size_t len)
-{ sha256_update(ctx, buf, len); }
-
-byte *sha256_final(struct sha256_context *ctx);
-static inline byte *sha224_final(struct sha224_context *ctx)
-{ return sha256_final(ctx); }
-
-
-/*
- * HMAC-SHA256, HMAC-SHA224
- */
-
-struct sha256_hmac_context
-{
- struct sha256_context ictx;
- struct sha256_context octx;
-};
-
-#define sha224_hmac_context sha256_hmac_context
-
-
-void sha256_hmac_init(struct sha256_hmac_context *ctx, const byte *key, size_t keylen);
-void sha224_hmac_init(struct sha224_hmac_context *ctx, const byte *key, size_t keylen);
+void sha256_init(struct hash_context *ctx);
+void sha224_init(struct hash_context *ctx);
-void sha256_hmac_update(struct sha256_hmac_context *ctx, const byte *buf, size_t buflen);
-void sha224_hmac_update(struct sha224_hmac_context *ctx, const byte *buf, size_t buflen);
+void sha256_update(struct hash_context *ctx, const byte *buf, uint len);
+#define sha224_update sha256_update
-byte *sha256_hmac_final(struct sha256_hmac_context *ctx);
-byte *sha224_hmac_final(struct sha224_hmac_context *ctx);
+byte *sha256_final(struct hash_context *ctx);
+#define sha224_final sha256_final
#endif /* _BIRD_SHA256_H_ */
diff --git a/lib/sha512.c b/lib/sha512.c
index 37e660f7..576ae1e8 100644
--- a/lib/sha512.c
+++ b/lib/sha512.c
@@ -1,6 +1,5 @@
/*
- * BIRD Library -- SHA-512 and SHA-384 Hash Functions,
- * HMAC-SHA-512 and HMAC-SHA-384 Functions
+ * BIRD Library -- SHA-512 and SHA-384 Hash Functions
*
* (c) 2015 CZ.NIC z.s.p.o.
*
@@ -17,8 +16,10 @@
// #define SHA512_UNROLLED
void
-sha512_init(struct sha512_context *ctx)
+sha512_init(struct hash_context *CTX)
{
+ struct sha512_context *ctx = (void *) CTX;
+
ctx->h0 = U64(0x6a09e667f3bcc908);
ctx->h1 = U64(0xbb67ae8584caa73b);
ctx->h2 = U64(0x3c6ef372fe94f82b);
@@ -33,8 +34,10 @@ sha512_init(struct sha512_context *ctx)
}
void
-sha384_init(struct sha384_context *ctx)
+sha384_init(struct hash_context *CTX)
{
+ struct sha384_context *ctx = (void *) CTX;
+
ctx->h0 = U64(0xcbbb9d5dc1059ed8);
ctx->h1 = U64(0x629a292a367cd507);
ctx->h2 = U64(0x9159015a3070dd17);
@@ -389,8 +392,10 @@ sha512_transform(struct sha512_context *ctx, const byte *data)
}
void
-sha512_update(struct sha512_context *ctx, const byte *buf, size_t len)
+sha512_update(struct hash_context *CTX, const byte *buf, uint len)
{
+ struct sha512_context *ctx = (void *) CTX;
+
if (ctx->count)
{
/* Fill rest of internal buffer */
@@ -432,11 +437,12 @@ sha512_update(struct sha512_context *ctx, const byte *buf, size_t len)
* first 48 of those bytes.
*/
byte *
-sha512_final(struct sha512_context *ctx)
+sha512_final(struct hash_context *CTX)
{
+ struct sha512_context *ctx = (void *) CTX;
u64 t, th, msb, lsb;
- sha512_update(ctx, NULL, 0); /* flush */
+ sha512_update(CTX, NULL, 0); /* flush */
t = ctx->nblocks;
th = 0;
@@ -467,7 +473,7 @@ sha512_final(struct sha512_context *ctx)
ctx->buf[ctx->count++] = 0x80; /* pad character */
while(ctx->count < 128)
ctx->buf[ctx->count++] = 0;
- sha512_update(ctx, NULL, 0); /* flush */
+ sha512_update(CTX, NULL, 0); /* flush */
memset(ctx->buf, 0, 112); /* fill next block with zeroes */
}
@@ -490,131 +496,3 @@ sha512_final(struct sha512_context *ctx)
return ctx->buf;
}
-
-
-/*
- * SHA512-HMAC
- */
-
-static void
-sha512_hash_buffer(byte *outbuf, const byte *buffer, size_t length)
-{
- struct sha512_context ctx;
-
- sha512_init(&ctx);
- sha512_update(&ctx, buffer, length);
- memcpy(outbuf, sha512_final(&ctx), SHA512_SIZE);
-}
-
-void
-sha512_hmac_init(struct sha512_hmac_context *ctx, const byte *key, size_t keylen)
-{
- byte keybuf[SHA512_BLOCK_SIZE], buf[SHA512_BLOCK_SIZE];
-
- /* Hash the key if necessary */
- if (keylen <= SHA512_BLOCK_SIZE)
- {
- memcpy(keybuf, key, keylen);
- memset(keybuf + keylen, 0, SHA512_BLOCK_SIZE - keylen);
- }
- else
- {
- sha512_hash_buffer(keybuf, key, keylen);
- memset(keybuf + SHA512_SIZE, 0, SHA512_BLOCK_SIZE - SHA512_SIZE);
- }
-
- /* Initialize the inner digest */
- sha512_init(&ctx->ictx);
- int i;
- for (i = 0; i < SHA512_BLOCK_SIZE; i++)
- buf[i] = keybuf[i] ^ 0x36;
- sha512_update(&ctx->ictx, buf, SHA512_BLOCK_SIZE);
-
- /* Initialize the outer digest */
- sha512_init(&ctx->octx);
- for (i = 0; i < SHA512_BLOCK_SIZE; i++)
- buf[i] = keybuf[i] ^ 0x5c;
- sha512_update(&ctx->octx, buf, SHA512_BLOCK_SIZE);
-}
-
-void
-sha512_hmac_update(struct sha512_hmac_context *ctx, const byte *buf, size_t buflen)
-{
- /* Just update the inner digest */
- sha512_update(&ctx->ictx, buf, buflen);
-}
-
-byte *
-sha512_hmac_final(struct sha512_hmac_context *ctx)
-{
- /* Finish the inner digest */
- byte *isha = sha512_final(&ctx->ictx);
-
- /* Finish the outer digest */
- sha512_update(&ctx->octx, isha, SHA512_SIZE);
- return sha512_final(&ctx->octx);
-}
-
-
-/*
- * SHA384-HMAC
- */
-
-static void
-sha384_hash_buffer(byte *outbuf, const byte *buffer, size_t length)
-{
- struct sha384_context ctx;
-
- sha384_init(&ctx);
- sha384_update(&ctx, buffer, length);
- memcpy(outbuf, sha384_final(&ctx), SHA384_SIZE);
-}
-
-void
-sha384_hmac_init(struct sha384_hmac_context *ctx, const byte *key, size_t keylen)
-{
- byte keybuf[SHA384_BLOCK_SIZE], buf[SHA384_BLOCK_SIZE];
-
- /* Hash the key if necessary */
- if (keylen <= SHA384_BLOCK_SIZE)
- {
- memcpy(keybuf, key, keylen);
- memset(keybuf + keylen, 0, SHA384_BLOCK_SIZE - keylen);
- }
- else
- {
- sha384_hash_buffer(keybuf, key, keylen);
- memset(keybuf + SHA384_SIZE, 0, SHA384_BLOCK_SIZE - SHA384_SIZE);
- }
-
- /* Initialize the inner digest */
- sha384_init(&ctx->ictx);
- int i;
- for (i = 0; i < SHA384_BLOCK_SIZE; i++)
- buf[i] = keybuf[i] ^ 0x36;
- sha384_update(&ctx->ictx, buf, SHA384_BLOCK_SIZE);
-
- /* Initialize the outer digest */
- sha384_init(&ctx->octx);
- for (i = 0; i < SHA384_BLOCK_SIZE; i++)
- buf[i] = keybuf[i] ^ 0x5c;
- sha384_update(&ctx->octx, buf, SHA384_BLOCK_SIZE);
-}
-
-void
-sha384_hmac_update(struct sha384_hmac_context *ctx, const byte *buf, size_t buflen)
-{
- /* Just update the inner digest */
- sha384_update(&ctx->ictx, buf, buflen);
-}
-
-byte *
-sha384_hmac_final(struct sha384_hmac_context *ctx)
-{
- /* Finish the inner digest */
- byte *isha = sha384_final(&ctx->ictx);
-
- /* Finish the outer digest */
- sha384_update(&ctx->octx, isha, SHA384_SIZE);
- return sha384_final(&ctx->octx);
-}
diff --git a/lib/sha512.h b/lib/sha512.h
index 1614a3ac..02220c93 100644
--- a/lib/sha512.h
+++ b/lib/sha512.h
@@ -1,6 +1,5 @@
/*
- * BIRD Library -- SHA-512 and SHA-384 Hash Functions,
- * HMAC-SHA-512 and HMAC-SHA-384 Functions
+ * BIRD Library -- SHA-512 and SHA-384 Hash Functions
*
* (c) 2015 CZ.NIC z.s.p.o.
*
@@ -25,8 +24,10 @@
#define SHA512_BLOCK_SIZE 128
+struct hash_context;
+
struct sha512_context {
- u64 h0, h1, h2, h3, h4, h5, h6, h7;
+ u64 h0, h1, h2, h3, h4, h5, h6, h7;
byte buf[SHA512_BLOCK_SIZE];
uint nblocks;
uint count;
@@ -35,39 +36,14 @@ struct sha512_context {
#define sha384_context sha512_context
-void sha512_init(struct sha512_context *ctx);
-void sha384_init(struct sha384_context *ctx);
-
-void sha512_update(struct sha512_context *ctx, const byte *buf, size_t len);
-static inline void sha384_update(struct sha384_context *ctx, const byte *buf, size_t len)
-{ sha512_update(ctx, buf, len); }
-
-byte *sha512_final(struct sha512_context *ctx);
-static inline byte *sha384_final(struct sha384_context *ctx)
-{ return sha512_final(ctx); }
-
-
-/*
- * HMAC-SHA512, HMAC-SHA384
- */
-
-struct sha512_hmac_context
-{
- struct sha512_context ictx;
- struct sha512_context octx;
-};
-
-#define sha384_hmac_context sha512_hmac_context
-
-
-void sha512_hmac_init(struct sha512_hmac_context *ctx, const byte *key, size_t keylen);
-void sha384_hmac_init(struct sha384_hmac_context *ctx, const byte *key, size_t keylen);
+void sha512_init(struct hash_context *ctx);
+void sha384_init(struct hash_context *ctx);
-void sha512_hmac_update(struct sha512_hmac_context *ctx, const byte *buf, size_t buflen);
-void sha384_hmac_update(struct sha384_hmac_context *ctx, const byte *buf, size_t buflen);
+void sha512_update(struct hash_context *ctx, const byte *buf, uint len);
+#define sha384_update sha512_update
-byte *sha512_hmac_final(struct sha512_hmac_context *ctx);
-byte *sha384_hmac_final(struct sha384_hmac_context *ctx);
+byte *sha512_final(struct hash_context *ctx);
+#define sha384_final sha512_final
#endif /* _BIRD_SHA512_H_ */
diff --git a/lib/socket.h b/lib/socket.h
index 7d1aa7ef..43db3cab 100644
--- a/lib/socket.h
+++ b/lib/socket.h
@@ -30,7 +30,7 @@ typedef struct birdsock {
byte *rbuf, *rpos; /* NULL=allocate automatically */
uint fast_rx; /* RX has higher priority in event loop */
uint rbsize;
- int (*rx_hook)(struct birdsock *, int size); /* NULL=receiving turned off, returns 1 to clear rx buffer */
+ int (*rx_hook)(struct birdsock *, uint size); /* NULL=receiving turned off, returns 1 to clear rx buffer */
byte *tbuf, *tpos; /* NULL=allocate automatically */
byte *ttx; /* Internal */
diff --git a/lib/string.h b/lib/string.h
index 9af49b9e..75cb88dd 100644
--- a/lib/string.h
+++ b/lib/string.h
@@ -30,6 +30,25 @@ static inline char *xbasename(const char *str)
return s ? s+1 : (char *) str;
}
+static inline char *
+xstrdup(const char *c)
+{
+ size_t l = strlen(c) + 1;
+ char *z = xmalloc(l);
+ memcpy(z, c, l);
+ return z;
+}
+
+static inline void
+memset32(void *D, u32 val, uint n)
+{
+ u32 *dst = D;
+ uint i;
+
+ for (i = 0; i < n; i++)
+ dst[i] = val;
+}
+
#define ROUTER_ID_64_LENGTH 23
#endif