aboutsummaryrefslogtreecommitdiff
path: root/contrib/wpa/src/pae/ieee802_1x_kay_i.h
blob: 7a041692a5d50786b573858c7a53db7aa92d48f0 (plain) (blame)
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
/*
 * IEEE 802.1X-2010 Key Agree Protocol of PAE state machine
 * Copyright (c) 2013, Qualcomm Atheros, Inc.
 *
 * This software may be distributed under the terms of the BSD license.
 * See README for more details.
 */

#ifndef IEEE802_1X_KAY_I_H
#define IEEE802_1X_KAY_I_H

#include "utils/list.h"
#include "common/defs.h"
#include "common/ieee802_1x_defs.h"

#define MKA_VERSION_ID              1

/* IEEE Std 802.1X-2010, 11.11.1, Table 11-7 (MKPDU parameter sets) */
enum mka_packet_type {
	MKA_BASIC_PARAMETER_SET = MKA_VERSION_ID,
	MKA_LIVE_PEER_LIST = 1,
	MKA_POTENTIAL_PEER_LIST = 2,
	MKA_SAK_USE = 3,
	MKA_DISTRIBUTED_SAK = 4,
	MKA_DISTRIBUTED_CAK = 5,
	MKA_KMD = 6,
	MKA_ANNOUNCEMENT = 7,
	MKA_ICV_INDICATOR = 255
};

#define ICV_LEN                         16  /* 16 bytes */
#define SAK_WRAPPED_LEN                 24
/* KN + Wrapper SAK */
#define DEFAULT_DIS_SAK_BODY_LENGTH     (SAK_WRAPPED_LEN + 4)
#define MAX_RETRY_CNT                   5

struct ieee802_1x_kay;

struct ieee802_1x_mka_peer_id {
	u8 mi[MI_LEN];
	be32 mn;
} STRUCT_PACKED;

struct ieee802_1x_kay_peer {
	struct ieee802_1x_mka_sci sci;
	u8 mi[MI_LEN];
	u32 mn;
	time_t expire;
	bool is_key_server;
	u8 key_server_priority;
	bool macsec_desired;
	enum macsec_cap macsec_capability;
	bool sak_used;
	int missing_sak_use_count;
	struct dl_list list;
};

struct macsec_ciphersuite {
	u64 id;
	char name[32];
	enum macsec_cap capable;
	int sak_len; /* unit: byte */
};

struct mka_alg {
	u8 parameter[4];
	size_t icv_len;

	int (*cak_trfm)(const u8 *msk, size_t msk_bytes, const u8 *mac1,
			const u8 *mac2, u8 *cak, size_t cak_bytes);
	int (*ckn_trfm)(const u8 *msk, size_t msk_bytes, const u8 *mac1,
			const u8 *mac2, const u8 *sid, size_t sid_len, u8 *ckn);
	int (*kek_trfm)(const u8 *cak, size_t cak_bytes,
			const u8 *ckn, size_t ckn_len,
			u8 *kek, size_t kek_bytes);
	int (*ick_trfm)(const u8 *cak, size_t cak_bytes,
			const u8 *ckn, size_t ckn_len,
			u8 *ick, size_t ick_bytes);
	int (*icv_hash)(const u8 *ick, size_t ick_bytes,
			const u8 *msg, size_t msg_len, u8 *icv);
};

#define DEFAULT_MKA_ALG_INDEX 0

/* See IEEE Std 802.1X-2010, 9.16 MKA management */
struct ieee802_1x_mka_participant {
	/* used for active and potential participant */
	struct mka_key_name ckn;
	struct mka_key cak;
	bool cached;

	/* used by management to monitor and control activation */
	bool active;
	bool participant;
	bool retain;
	enum mka_created_mode mode;

	enum activate_ctrl { DEFAULT, DISABLED, ON_OPER_UP, ALWAYS } activate;

	/* used for active participant */
	bool principal;
	struct dl_list live_peers;
	struct dl_list potential_peers;

	/* not defined in IEEE 802.1X */
	struct dl_list list;

	struct mka_key kek;
	struct mka_key ick;

	struct ieee802_1x_mka_ki lki;
	u8 lan;
	bool ltx;
	bool lrx;

	struct ieee802_1x_mka_ki oki;
	u8 oan;
	bool otx;
	bool orx;

	bool is_key_server;
	bool is_obliged_key_server;
	bool can_be_key_server;
	bool is_elected;

	struct dl_list sak_list;
	struct dl_list rxsc_list;

	struct transmit_sc *txsc;

	u8 mi[MI_LEN];
	u32 mn;

	/* Current peer MI and SCI during MKPDU processing */
	struct ieee802_1x_mka_peer_id current_peer_id;
	struct ieee802_1x_mka_sci current_peer_sci;

	time_t cak_life;
	time_t mka_life;
	bool to_dist_sak;
	bool to_use_sak;
	bool new_sak;

	bool advised_desired;
	enum macsec_cap advised_capability;

	struct data_key *new_key;
	u32 retry_count;

	struct ieee802_1x_kay *kay;
};

struct ieee802_1x_mka_hdr {
	/* octet 1 */
	u8 type;
	/* octet 2 */
	u8 reserve;
	/* octet 3 */
#if __BYTE_ORDER == __LITTLE_ENDIAN
	u8 length:4;
	u8 reserve1:4;
#elif __BYTE_ORDER == __BIG_ENDIAN
	u8 reserve1:4;
	u8 length:4;
#else
#error "Please fix <bits/endian.h>"
#endif
	/* octet 4 */
	u8 length1;
} STRUCT_PACKED;

#define MKA_HDR_LEN sizeof(struct ieee802_1x_mka_hdr)

/**
 * struct ieee802_1x_mka_basic_body - Basic Parameter Set (Figure 11-8)
 * @version: MKA Version Identifier
 * @priority: Key Server Priority
 * @length: Parameter set body length
 * @macsec_capability: MACsec capability, as defined in ieee802_1x_defs.h
 * @macsec_desired: the participant wants MACsec to be used to protect frames
 *	(9.6.1)
 * @key_server: the participant has not decided that another participant is or
 *	will be the key server (9.5.1)
 * @length1: Parameter set body length (cont)
 * @actor_mi: Actor's Member Identifier
 * @actor_mn: Actor's Message Number
 * @algo_agility: Algorithm Agility parameter
 * @ckn: CAK Name
 */
struct ieee802_1x_mka_basic_body {
	/* octet 1 */
	u8 version;
	/* octet 2 */
	u8 priority;
	/* octet 3 */
#if __BYTE_ORDER == __LITTLE_ENDIAN
	u8 length:4;
	u8 macsec_capability:2;
	u8 macsec_desired:1;
	u8 key_server:1;
#elif __BYTE_ORDER == __BIG_ENDIAN
	u8 key_server:1;
	u8 macsec_desired:1;
	u8 macsec_capability:2;
	u8 length:4;
#endif
	/* octet 4 */
	u8 length1;

	struct ieee802_1x_mka_sci actor_sci;
	u8 actor_mi[MI_LEN];
	be32 actor_mn;
	u8 algo_agility[4];

	/* followed by CAK Name */
	u8 ckn[0];
} STRUCT_PACKED;

/**
 * struct ieee802_1x_mka_peer_body - Live Peer List and Potential Peer List
 *	parameter sets (Figure 11-9)
 * @type: Parameter set type (1 or 2)
 * @length: Parameter set body length
 * @length1: Parameter set body length (cont)
 * @peer: array of (MI, MN) pairs
 */
struct ieee802_1x_mka_peer_body {
	/* octet 1 */
	u8 type;
	/* octet 2 */
	u8 reserve;
	/* octet 3 */
#if __BYTE_ORDER == __LITTLE_ENDIAN
	u8 length:4;
	u8 reserve1:4;
#elif __BYTE_ORDER == __BIG_ENDIAN
	u8 reserve1:4;
	u8 length:4;
#endif
	/* octet 4 */
	u8 length1;

	/* followed by Peers */
	u8 peer[0];
} STRUCT_PACKED;

/**
 * struct ieee802_1x_mka_sak_use_body - MACsec SAK Use parameter set (Figure
 *	11-10)
 * @type: MKA message type
 * @lan: latest key AN
 * @ltx: latest key TX
 * @lrx: latest key RX
 * @oan: old key AN
 * @otx: old key TX
 * @orx: old key RX
 * @ptx: plain TX, ie protectFrames is False
 * @prx: plain RX, ie validateFrames is not Strict
 * @delay_protect: True if LPNs are being reported sufficiently frequently to
 *	allow the recipient to provide data delay protection. If False, the LPN
 *	can be reported as zero.
 * @lsrv_mi: latest key server MI
 * @lkn: latest key number (together with MI, form the KI)
 * @llpn: latest lowest acceptable PN (LPN)
 * @osrv_mi: old key server MI
 * @okn: old key number (together with MI, form the KI)
 * @olpn: old lowest acceptable PN (LPN)
 */
struct ieee802_1x_mka_sak_use_body {
	/* octet 1 */
	u8 type;
	/* octet 2 */
#if __BYTE_ORDER == __LITTLE_ENDIAN
	u8 orx:1;
	u8 otx:1;
	u8 oan:2;
	u8 lrx:1;
	u8 ltx:1;
	u8 lan:2;
#elif __BYTE_ORDER == __BIG_ENDIAN
	u8 lan:2;
	u8 ltx:1;
	u8 lrx:1;
	u8 oan:2;
	u8 otx:1;
	u8 orx:1;
#endif

	/* octet 3 */
#if __BYTE_ORDER == __LITTLE_ENDIAN
	u8 length:4;
	u8 delay_protect:1;
	u8 reserve:1;
	u8 prx:1;
	u8 ptx:1;
#elif __BYTE_ORDER == __BIG_ENDIAN
	u8 ptx:1;
	u8 prx:1;
	u8 reserve:1;
	u8 delay_protect:1;
	u8 length:4;
#endif

	/* octet 4 */
	u8 length1;

	/* octet 5 - 16 */
	u8 lsrv_mi[MI_LEN];
	/* octet 17 - 20 */
	be32 lkn;
	/* octet 21 - 24 */
	be32 llpn;

	/* octet 25 - 36 */
	u8 osrv_mi[MI_LEN];
	/* octet 37 - 40 */
	be32 okn;
	/* octet 41 - 44 */
	be32 olpn;
} STRUCT_PACKED;

/**
 * struct ieee802_1x_mka_dist_sak_body - Distributed SAK parameter set
 *	(GCM-AES-128, Figure 11-11)
 * @type: Parameter set type (4)
 * @length: Parameter set body length
 * @length1: Parameter set body length (cont)
 *           Total parameter body length values:
 *            -  0 for plain text
 *            - 28 for GCM-AES-128
 *            - 36 or more for other cipher suites
 * @confid_offset: confidentiality offset, as defined in ieee802_1x_defs.h
 * @dan: distributed AN (0 for plain text)
 * @kn: Key Number
 * @sak: AES Key Wrap of SAK (see 9.8)
 */
struct ieee802_1x_mka_dist_sak_body {
	/* octet 1 */
	u8 type;
	/* octet 2 */
#if __BYTE_ORDER == __LITTLE_ENDIAN
	u8 reserve:4;
	u8 confid_offset:2;
	u8 dan:2;
#elif __BYTE_ORDER == __BIG_ENDIAN
	u8 dan:2;
	u8 confid_offset:2;
	u8 reserve:4;
#endif
	/* octet 3 */
#if __BYTE_ORDER == __LITTLE_ENDIAN
	u8 length:4;
	u8 reserve1:4;
#elif __BYTE_ORDER == __BIG_ENDIAN
	u8 reserve1:4;
	u8 length:4;
#endif
	/* octet 4 */
	u8 length1;
	/* octet 5 - 8 */
	be32 kn;

	/* for GCM-AES-128: octet 9-32: SAK
	 * for other cipher suite: octet 9-16: cipher suite id, octet 17-: SAK
	 */
	u8 sak[0];
} STRUCT_PACKED;

/**
 * struct ieee802_1x_mka_dist_cak_body - Distributed CAK parameter set (Figure
 *	11-13)
 * @type: Parameter set type (5)
 * @length: Parameter set body length
 * @length1: Parameter set body length (cont)
 *           Total parameter body length values:
 *            -  0 for plain text
 *            - 28 for GCM-AES-128
 *            - 36 or more for other cipher suites
 * @cak: AES Key Wrap of CAK (see 9.8)
 * @ckn: CAK Name
 */
struct ieee802_1x_mka_dist_cak_body {
	/* octet 1 */
	u8 type;
	/* octet 2 */
	u8 reserve;
	/* octet 3 */
#if __BYTE_ORDER == __LITTLE_ENDIAN
	u8 length:4;
	u8 reserve1:4;
#elif __BYTE_ORDER == __BIG_ENDIAN
	u8 reserve1:4;
	u8 length:4;
#endif
	/* octet 4 */
	u8 length1;

	/* octet 5 - 28 */
	u8 cak[24];

	/* followed by CAK Name, 29- */
	u8 ckn[0];
} STRUCT_PACKED;

struct ieee802_1x_mka_icv_body {
	/* octet 1 */
	u8 type;
	/* octet 2 */
	u8 reserve;
	/* octet 3 */
#if __BYTE_ORDER == __LITTLE_ENDIAN
	u8 length:4;
	u8 reserve1:4;
#elif __BYTE_ORDER == __BIG_ENDIAN
	u8 reserve1:4;
	u8 length:4;
#endif
	/* octet 4 */
	u8 length1;

	/* octet 5 - */
	u8 icv[0];
} STRUCT_PACKED;

#endif /* IEEE802_1X_KAY_I_H */