summaryrefslogtreecommitdiff
path: root/lib/mac.h
blob: 99a56eedf4183baaf5df3bea51773f611d4bbead (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*
 *	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);
  uint min_key_length;			/* Minimum allowed key length */
  uint max_key_length;			/* Maximum allowed key length */
};

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_ */