1 /*
2 * SecY Operations
3 * Copyright (c) 2013, Qualcomm Atheros, Inc.
4 *
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
7 */
8
9#include "utils/includes.h"
10
11#include "utils/common.h"
12#include "utils/eloop.h"
13#include "common/defs.h"
14#include "drivers/driver.h"
15#include "pae/ieee802_1x_kay.h"
16#include "pae/ieee802_1x_kay_i.h"
17#include "pae/ieee802_1x_secy_ops.h"
18
19
20int secy_cp_control_validate_frames(struct ieee802_1x_kay *kay,
21				    enum validate_frames vf)
22{
23	kay->vf = vf;
24	return 0;
25}
26
27
28int secy_cp_control_protect_frames(struct ieee802_1x_kay *kay, Boolean enabled)
29{
30	struct ieee802_1x_kay_ctx *ops;
31
32	if (!kay) {
33		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
34		return -1;
35	}
36
37	ops = kay->ctx;
38	if (!ops || !ops->enable_protect_frames) {
39		wpa_printf(MSG_ERROR,
40			   "KaY: secy enable_protect_frames operation not supported");
41		return -1;
42	}
43
44	return ops->enable_protect_frames(ops->ctx, enabled);
45}
46
47
48int secy_cp_control_encrypt(struct ieee802_1x_kay *kay, Boolean enabled)
49{
50	struct ieee802_1x_kay_ctx *ops;
51
52	if (!kay) {
53		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
54		return -1;
55	}
56
57	ops = kay->ctx;
58	if (!ops || !ops->enable_encrypt) {
59		wpa_printf(MSG_ERROR,
60			   "KaY: secy enable_encrypt operation not supported");
61		return -1;
62	}
63
64	return ops->enable_encrypt(ops->ctx, enabled);
65}
66
67
68int secy_cp_control_replay(struct ieee802_1x_kay *kay, Boolean enabled, u32 win)
69{
70	struct ieee802_1x_kay_ctx *ops;
71
72	if (!kay) {
73		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
74		return -1;
75	}
76
77	ops = kay->ctx;
78	if (!ops || !ops->set_replay_protect) {
79		wpa_printf(MSG_ERROR,
80			   "KaY: secy set_replay_protect operation not supported");
81		return -1;
82	}
83
84	return ops->set_replay_protect(ops->ctx, enabled, win);
85}
86
87
88int secy_cp_control_current_cipher_suite(struct ieee802_1x_kay *kay, u64 cs)
89{
90	struct ieee802_1x_kay_ctx *ops;
91
92	if (!kay) {
93		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
94		return -1;
95	}
96
97	ops = kay->ctx;
98	if (!ops || !ops->set_current_cipher_suite) {
99		wpa_printf(MSG_ERROR,
100			   "KaY: secy set_current_cipher_suite operation not supported");
101		return -1;
102	}
103
104	return ops->set_current_cipher_suite(ops->ctx, cs);
105}
106
107
108int secy_cp_control_confidentiality_offset(struct ieee802_1x_kay *kay,
109					   enum confidentiality_offset co)
110{
111	kay->co = co;
112	return 0;
113}
114
115
116int secy_cp_control_enable_port(struct ieee802_1x_kay *kay, Boolean enabled)
117{
118	struct ieee802_1x_kay_ctx *ops;
119
120	if (!kay) {
121		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
122		return -1;
123	}
124
125	ops = kay->ctx;
126	if (!ops || !ops->enable_controlled_port) {
127		wpa_printf(MSG_ERROR,
128			   "KaY: secy enable_controlled_port operation not supported");
129		return -1;
130	}
131
132	return ops->enable_controlled_port(ops->ctx, enabled);
133}
134
135
136int secy_get_capability(struct ieee802_1x_kay *kay, enum macsec_cap *cap)
137{
138	struct ieee802_1x_kay_ctx *ops;
139
140	if (!kay) {
141		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
142		return -1;
143	}
144
145	ops = kay->ctx;
146	if (!ops || !ops->macsec_get_capability) {
147		wpa_printf(MSG_ERROR,
148			   "KaY: secy macsec_get_capability operation not supported");
149		return -1;
150	}
151
152	return ops->macsec_get_capability(ops->ctx, cap);
153}
154
155
156int secy_get_receive_lowest_pn(struct ieee802_1x_kay *kay,
157			       struct receive_sa *rxsa)
158{
159	struct ieee802_1x_kay_ctx *ops;
160
161	if (!kay || !rxsa) {
162		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
163		return -1;
164	}
165
166	ops = kay->ctx;
167	if (!ops || !ops->get_receive_lowest_pn) {
168		wpa_printf(MSG_ERROR,
169			   "KaY: secy get_receive_lowest_pn operation not supported");
170		return -1;
171	}
172
173	return ops->get_receive_lowest_pn(ops->ctx, rxsa);
174}
175
176
177int secy_get_transmit_next_pn(struct ieee802_1x_kay *kay,
178			      struct transmit_sa *txsa)
179{
180	struct ieee802_1x_kay_ctx *ops;
181
182	if (!kay || !txsa) {
183		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
184		return -1;
185	}
186
187	ops = kay->ctx;
188	if (!ops || !ops->get_transmit_next_pn) {
189		wpa_printf(MSG_ERROR,
190			   "KaY: secy get_receive_lowest_pn operation not supported");
191		return -1;
192	}
193
194	return ops->get_transmit_next_pn(ops->ctx, txsa);
195}
196
197
198int secy_set_transmit_next_pn(struct ieee802_1x_kay *kay,
199			      struct transmit_sa *txsa)
200{
201	struct ieee802_1x_kay_ctx *ops;
202
203	if (!kay || !txsa) {
204		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
205		return -1;
206	}
207
208	ops = kay->ctx;
209	if (!ops || !ops->set_transmit_next_pn) {
210		wpa_printf(MSG_ERROR,
211			   "KaY: secy get_receive_lowest_pn operation not supported");
212		return -1;
213	}
214
215	return ops->set_transmit_next_pn(ops->ctx, txsa);
216}
217
218
219int secy_create_receive_sc(struct ieee802_1x_kay *kay, struct receive_sc *rxsc)
220{
221	struct ieee802_1x_kay_ctx *ops;
222
223	if (!kay || !rxsc) {
224		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
225		return -1;
226	}
227
228	ops = kay->ctx;
229	if (!ops || !ops->create_receive_sc) {
230		wpa_printf(MSG_ERROR,
231			   "KaY: secy create_receive_sc operation not supported");
232		return -1;
233	}
234
235	return ops->create_receive_sc(ops->ctx, rxsc, kay->vf, kay->co);
236}
237
238
239int secy_delete_receive_sc(struct ieee802_1x_kay *kay, struct receive_sc *rxsc)
240{
241	struct ieee802_1x_kay_ctx *ops;
242
243	if (!kay || !rxsc) {
244		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
245		return -1;
246	}
247
248	ops = kay->ctx;
249	if (!ops || !ops->delete_receive_sc) {
250		wpa_printf(MSG_ERROR,
251			   "KaY: secy delete_receive_sc operation not supported");
252		return -1;
253	}
254
255	return ops->delete_receive_sc(ops->ctx, rxsc);
256}
257
258
259int secy_create_receive_sa(struct ieee802_1x_kay *kay, struct receive_sa *rxsa)
260{
261	struct ieee802_1x_kay_ctx *ops;
262
263	if (!kay || !rxsa) {
264		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
265		return -1;
266	}
267
268	ops = kay->ctx;
269	if (!ops || !ops->create_receive_sa) {
270		wpa_printf(MSG_ERROR,
271			   "KaY: secy create_receive_sa operation not supported");
272		return -1;
273	}
274
275	return ops->create_receive_sa(ops->ctx, rxsa);
276}
277
278
279int secy_delete_receive_sa(struct ieee802_1x_kay *kay, struct receive_sa *rxsa)
280{
281	struct ieee802_1x_kay_ctx *ops;
282
283	if (!kay || !rxsa) {
284		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
285		return -1;
286	}
287
288	ops = kay->ctx;
289	if (!ops || !ops->delete_receive_sa) {
290		wpa_printf(MSG_ERROR,
291			   "KaY: secy delete_receive_sa operation not supported");
292		return -1;
293	}
294
295	return ops->delete_receive_sa(ops->ctx, rxsa);
296}
297
298
299int secy_enable_receive_sa(struct ieee802_1x_kay *kay, struct receive_sa *rxsa)
300{
301	struct ieee802_1x_kay_ctx *ops;
302
303	if (!kay || !rxsa) {
304		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
305		return -1;
306	}
307
308	ops = kay->ctx;
309	if (!ops || !ops->enable_receive_sa) {
310		wpa_printf(MSG_ERROR,
311			   "KaY: secy enable_receive_sa operation not supported");
312		return -1;
313	}
314
315	rxsa->enable_receive = TRUE;
316
317	return ops->enable_receive_sa(ops->ctx, rxsa);
318}
319
320
321int secy_disable_receive_sa(struct ieee802_1x_kay *kay, struct receive_sa *rxsa)
322{
323	struct ieee802_1x_kay_ctx *ops;
324
325	if (!kay || !rxsa) {
326		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
327		return -1;
328	}
329
330	ops = kay->ctx;
331	if (!ops || !ops->disable_receive_sa) {
332		wpa_printf(MSG_ERROR,
333			   "KaY: secy disable_receive_sa operation not supported");
334		return -1;
335	}
336
337	rxsa->enable_receive = FALSE;
338
339	return ops->disable_receive_sa(ops->ctx, rxsa);
340}
341
342
343int secy_create_transmit_sc(struct ieee802_1x_kay *kay,
344			    struct transmit_sc *txsc)
345{
346	struct ieee802_1x_kay_ctx *ops;
347
348	if (!kay || !txsc) {
349		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
350		return -1;
351	}
352
353	ops = kay->ctx;
354	if (!ops || !ops->create_transmit_sc) {
355		wpa_printf(MSG_ERROR,
356			   "KaY: secy create_transmit_sc operation not supported");
357		return -1;
358	}
359
360	return ops->create_transmit_sc(ops->ctx, txsc, kay->co);
361}
362
363
364int secy_delete_transmit_sc(struct ieee802_1x_kay *kay,
365			    struct transmit_sc *txsc)
366{
367	struct ieee802_1x_kay_ctx *ops;
368
369	if (!kay || !txsc) {
370		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
371		return -1;
372	}
373
374	ops = kay->ctx;
375	if (!ops || !ops->delete_transmit_sc) {
376		wpa_printf(MSG_ERROR,
377			   "KaY: secy delete_transmit_sc operation not supported");
378		return -1;
379	}
380
381	return ops->delete_transmit_sc(ops->ctx, txsc);
382}
383
384
385int secy_create_transmit_sa(struct ieee802_1x_kay *kay,
386			    struct transmit_sa *txsa)
387{
388	struct ieee802_1x_kay_ctx *ops;
389
390	if (!kay || !txsa) {
391		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
392		return -1;
393	}
394
395	ops = kay->ctx;
396	if (!ops || !ops->create_transmit_sa) {
397		wpa_printf(MSG_ERROR,
398			   "KaY: secy create_transmit_sa operation not supported");
399		return -1;
400	}
401
402	return ops->create_transmit_sa(ops->ctx, txsa);
403}
404
405
406int secy_delete_transmit_sa(struct ieee802_1x_kay *kay,
407			    struct transmit_sa *txsa)
408{
409	struct ieee802_1x_kay_ctx *ops;
410
411	if (!kay || !txsa) {
412		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
413		return -1;
414	}
415
416	ops = kay->ctx;
417	if (!ops || !ops->delete_transmit_sa) {
418		wpa_printf(MSG_ERROR,
419			   "KaY: secy delete_transmit_sa operation not supported");
420		return -1;
421	}
422
423	return ops->delete_transmit_sa(ops->ctx, txsa);
424}
425
426
427int secy_enable_transmit_sa(struct ieee802_1x_kay *kay,
428			    struct transmit_sa *txsa)
429{
430	struct ieee802_1x_kay_ctx *ops;
431
432	if (!kay || !txsa) {
433		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
434		return -1;
435	}
436
437	ops = kay->ctx;
438	if (!ops || !ops->enable_transmit_sa) {
439		wpa_printf(MSG_ERROR,
440			   "KaY: secy enable_transmit_sa operation not supported");
441		return -1;
442	}
443
444	txsa->enable_transmit = TRUE;
445
446	return ops->enable_transmit_sa(ops->ctx, txsa);
447}
448
449
450int secy_disable_transmit_sa(struct ieee802_1x_kay *kay,
451			     struct transmit_sa *txsa)
452{
453	struct ieee802_1x_kay_ctx *ops;
454
455	if (!kay || !txsa) {
456		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
457		return -1;
458	}
459
460	ops = kay->ctx;
461	if (!ops || !ops->disable_transmit_sa) {
462		wpa_printf(MSG_ERROR,
463			   "KaY: secy disable_transmit_sa operation not supported");
464		return -1;
465	}
466
467	txsa->enable_transmit = FALSE;
468
469	return ops->disable_transmit_sa(ops->ctx, txsa);
470}
471
472
473int secy_init_macsec(struct ieee802_1x_kay *kay)
474{
475	int ret;
476	struct ieee802_1x_kay_ctx *ops;
477	struct macsec_init_params params;
478
479	if (!kay) {
480		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
481		return -1;
482	}
483
484	ops = kay->ctx;
485	if (!ops || !ops->macsec_init) {
486		wpa_printf(MSG_ERROR,
487			   "KaY: secy macsec_init operation not supported");
488		return -1;
489	}
490
491	params.use_es = FALSE;
492	params.use_scb = FALSE;
493	params.always_include_sci = TRUE;
494
495	ret = ops->macsec_init(ops->ctx, &params);
496
497	return ret;
498}
499
500
501int secy_deinit_macsec(struct ieee802_1x_kay *kay)
502{
503	struct ieee802_1x_kay_ctx *ops;
504
505	if (!kay) {
506		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
507		return -1;
508	}
509
510	ops = kay->ctx;
511	if (!ops || !ops->macsec_deinit) {
512		wpa_printf(MSG_ERROR,
513			   "KaY: secy macsec_deinit operation not supported");
514		return -1;
515	}
516
517	return ops->macsec_deinit(ops->ctx);
518}
519