diff options
author | Ondrej Zajicek (work) <santiago@crfreenet.org> | 2016-11-08 19:27:58 +0100 |
---|---|---|
committer | Ondrej Zajicek (work) <santiago@crfreenet.org> | 2016-11-08 19:27:58 +0100 |
commit | 8860e991f6650e47cfe6c1af595fe4fe92a4edfd (patch) | |
tree | 18f49bb3a21739a1a596b54d9f65e82cff4fc09f /lib | |
parent | cc5b93f72db80abd1262a0a5e1d8400ceef54385 (diff) | |
parent | c8cafc8ebb5320ac7c6117c17e6460036f0fdf62 (diff) |
Merge branch 'master' into int-new
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Doc | 1 | ||||
-rw-r--r-- | lib/Makefile | 2 | ||||
-rw-r--r-- | lib/birdlib.h | 1 | ||||
-rw-r--r-- | lib/buffer.h | 16 | ||||
-rw-r--r-- | lib/hash.h | 29 | ||||
-rw-r--r-- | lib/idm.c | 2 | ||||
-rw-r--r-- | lib/mac.c | 289 | ||||
-rw-r--r-- | lib/mac.h | 121 | ||||
-rw-r--r-- | lib/md5.c | 81 | ||||
-rw-r--r-- | lib/md5.h | 21 | ||||
-rw-r--r-- | lib/sha1.c | 95 | ||||
-rw-r--r-- | lib/sha1.h | 30 | ||||
-rw-r--r-- | lib/sha256.c | 150 | ||||
-rw-r--r-- | lib/sha256.h | 42 | ||||
-rw-r--r-- | lib/sha512.c | 150 | ||||
-rw-r--r-- | lib/sha512.h | 44 | ||||
-rw-r--r-- | lib/socket.h | 2 | ||||
-rw-r--r-- | lib/string.h | 19 |
18 files changed, 545 insertions, 550 deletions
@@ -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_ */ @@ -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 @@ -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_ */ @@ -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); -} @@ -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_ */ @@ -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); -} @@ -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 |