bird/lib/mac.h
Toke Høiland-Jørgensen 725d9af94a Lib: Add Blake2s and Blake2b hash functions
The Babel MAC authentication RFC recommends implementing Blake2s as one of
the supported algorithms. In order to achieve do this, add the blake2b and
blake2s hash functions for MAC authentication. The hashing function
implementations are the reference implementations from blake2.net.

The Blake2 algorithms allow specifying an arbitrary output size, and the
Babel MAC spec says to implement Blake2s with 128-bit output. To satisfy
this, we add two different variants of each of the algorithms, one using
the default size (256 bits for Blake2s, 512 bits for Blake2b), and one
using half the default output size.

Update to BIRD coding style done by committer.
2021-06-06 16:26:58 +02:00

128 lines
3.5 KiB
C

/*
* 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"
#include "lib/blake2.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_BLAKE2S_128 0x07
#define ALG_BLAKE2S_256 0x08
#define ALG_BLAKE2B_256 0x09
#define ALG_BLAKE2B_512 0x0A
#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 blake2s_context blake2s;
struct blake2b_context blake2b;
};
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_ */