2016-10-25 23:04:17 +08:00
|
|
|
/*
|
|
|
|
* 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"
|
2021-04-10 23:33:28 +08:00
|
|
|
#include "lib/blake2.h"
|
2016-10-25 23:04:17 +08:00
|
|
|
|
|
|
|
|
|
|
|
#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
|
2021-04-10 23:33:28 +08:00
|
|
|
#define ALG_BLAKE2S_128 0x07
|
|
|
|
#define ALG_BLAKE2S_256 0x08
|
|
|
|
#define ALG_BLAKE2B_256 0x09
|
|
|
|
#define ALG_BLAKE2B_512 0x0A
|
2016-10-26 22:07:45 +08:00
|
|
|
#define ALG_HMAC 0x10
|
2016-10-25 23:04:17 +08:00
|
|
|
#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)
|
|
|
|
|
2016-10-26 22:07:45 +08:00
|
|
|
/* This value is used by several IETF protocols for padding */
|
|
|
|
#define HMAC_MAGIC htonl(0x878FE1F3)
|
|
|
|
|
2016-10-25 23:04:17 +08:00
|
|
|
/* 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;
|
2021-04-10 23:33:28 +08:00
|
|
|
struct blake2s_context blake2s;
|
|
|
|
struct blake2b_context blake2b;
|
2016-10-25 23:04:17 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
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);
|
2021-04-15 10:38:49 +08:00
|
|
|
uint min_key_length; /* Minimum allowed key length */
|
|
|
|
uint max_key_length; /* Maximum allowed key length */
|
2016-10-25 23:04:17 +08:00
|
|
|
};
|
|
|
|
|
2016-11-03 16:53:53 +08:00
|
|
|
extern const struct mac_desc mac_table[ALG_MAX];
|
2016-10-25 23:04:17 +08:00
|
|
|
|
|
|
|
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_ */
|