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, bool 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, bool 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, bool 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, bool 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_transmit_next_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 set_transmit_next_pn operation not supported");
212		return -1;
213	}
214
215	return ops->set_transmit_next_pn(ops->ctx, txsa);
216}
217
218
219int secy_set_receive_lowest_pn(struct ieee802_1x_kay *kay,
220			       struct receive_sa *rxsa)
221{
222	struct ieee802_1x_kay_ctx *ops;
223
224	if (!kay || !rxsa) {
225		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
226		return -1;
227	}
228
229	ops = kay->ctx;
230	if (!ops || !ops->set_receive_lowest_pn) {
231		wpa_printf(MSG_ERROR,
232			   "KaY: secy set_receive_lowest_pn operation not supported");
233		return -1;
234	}
235
236	return ops->set_receive_lowest_pn(ops->ctx, rxsa);
237}
238
239
240int secy_create_receive_sc(struct ieee802_1x_kay *kay, struct receive_sc *rxsc)
241{
242	struct ieee802_1x_kay_ctx *ops;
243
244	if (!kay || !rxsc) {
245		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
246		return -1;
247	}
248
249	ops = kay->ctx;
250	if (!ops || !ops->create_receive_sc) {
251		wpa_printf(MSG_ERROR,
252			   "KaY: secy create_receive_sc operation not supported");
253		return -1;
254	}
255
256	return ops->create_receive_sc(ops->ctx, rxsc, kay->vf, kay->co);
257}
258
259
260int secy_delete_receive_sc(struct ieee802_1x_kay *kay, struct receive_sc *rxsc)
261{
262	struct ieee802_1x_kay_ctx *ops;
263
264	if (!kay || !rxsc) {
265		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
266		return -1;
267	}
268
269	ops = kay->ctx;
270	if (!ops || !ops->delete_receive_sc) {
271		wpa_printf(MSG_ERROR,
272			   "KaY: secy delete_receive_sc operation not supported");
273		return -1;
274	}
275
276	return ops->delete_receive_sc(ops->ctx, rxsc);
277}
278
279
280int secy_create_receive_sa(struct ieee802_1x_kay *kay, struct receive_sa *rxsa)
281{
282	struct ieee802_1x_kay_ctx *ops;
283
284	if (!kay || !rxsa) {
285		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
286		return -1;
287	}
288
289	ops = kay->ctx;
290	if (!ops || !ops->create_receive_sa) {
291		wpa_printf(MSG_ERROR,
292			   "KaY: secy create_receive_sa operation not supported");
293		return -1;
294	}
295
296	return ops->create_receive_sa(ops->ctx, rxsa);
297}
298
299
300int secy_delete_receive_sa(struct ieee802_1x_kay *kay, struct receive_sa *rxsa)
301{
302	struct ieee802_1x_kay_ctx *ops;
303
304	if (!kay || !rxsa) {
305		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
306		return -1;
307	}
308
309	ops = kay->ctx;
310	if (!ops || !ops->delete_receive_sa) {
311		wpa_printf(MSG_ERROR,
312			   "KaY: secy delete_receive_sa operation not supported");
313		return -1;
314	}
315
316	return ops->delete_receive_sa(ops->ctx, rxsa);
317}
318
319
320int secy_enable_receive_sa(struct ieee802_1x_kay *kay, struct receive_sa *rxsa)
321{
322	struct ieee802_1x_kay_ctx *ops;
323
324	if (!kay || !rxsa) {
325		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
326		return -1;
327	}
328
329	ops = kay->ctx;
330	if (!ops || !ops->enable_receive_sa) {
331		wpa_printf(MSG_ERROR,
332			   "KaY: secy enable_receive_sa operation not supported");
333		return -1;
334	}
335
336	rxsa->enable_receive = true;
337
338	return ops->enable_receive_sa(ops->ctx, rxsa);
339}
340
341
342int secy_disable_receive_sa(struct ieee802_1x_kay *kay, struct receive_sa *rxsa)
343{
344	struct ieee802_1x_kay_ctx *ops;
345
346	if (!kay || !rxsa) {
347		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
348		return -1;
349	}
350
351	ops = kay->ctx;
352	if (!ops || !ops->disable_receive_sa) {
353		wpa_printf(MSG_ERROR,
354			   "KaY: secy disable_receive_sa operation not supported");
355		return -1;
356	}
357
358	rxsa->enable_receive = false;
359
360	return ops->disable_receive_sa(ops->ctx, rxsa);
361}
362
363
364int secy_create_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->create_transmit_sc) {
376		wpa_printf(MSG_ERROR,
377			   "KaY: secy create_transmit_sc operation not supported");
378		return -1;
379	}
380
381	return ops->create_transmit_sc(ops->ctx, txsc, kay->co);
382}
383
384
385int secy_delete_transmit_sc(struct ieee802_1x_kay *kay,
386			    struct transmit_sc *txsc)
387{
388	struct ieee802_1x_kay_ctx *ops;
389
390	if (!kay || !txsc) {
391		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
392		return -1;
393	}
394
395	ops = kay->ctx;
396	if (!ops || !ops->delete_transmit_sc) {
397		wpa_printf(MSG_ERROR,
398			   "KaY: secy delete_transmit_sc operation not supported");
399		return -1;
400	}
401
402	return ops->delete_transmit_sc(ops->ctx, txsc);
403}
404
405
406int secy_create_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->create_transmit_sa) {
418		wpa_printf(MSG_ERROR,
419			   "KaY: secy create_transmit_sa operation not supported");
420		return -1;
421	}
422
423	return ops->create_transmit_sa(ops->ctx, txsa);
424}
425
426
427int secy_delete_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->delete_transmit_sa) {
439		wpa_printf(MSG_ERROR,
440			   "KaY: secy delete_transmit_sa operation not supported");
441		return -1;
442	}
443
444	return ops->delete_transmit_sa(ops->ctx, txsa);
445}
446
447
448int secy_enable_transmit_sa(struct ieee802_1x_kay *kay,
449			    struct transmit_sa *txsa)
450{
451	struct ieee802_1x_kay_ctx *ops;
452
453	if (!kay || !txsa) {
454		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
455		return -1;
456	}
457
458	ops = kay->ctx;
459	if (!ops || !ops->enable_transmit_sa) {
460		wpa_printf(MSG_ERROR,
461			   "KaY: secy enable_transmit_sa operation not supported");
462		return -1;
463	}
464
465	txsa->enable_transmit = true;
466
467	return ops->enable_transmit_sa(ops->ctx, txsa);
468}
469
470
471int secy_disable_transmit_sa(struct ieee802_1x_kay *kay,
472			     struct transmit_sa *txsa)
473{
474	struct ieee802_1x_kay_ctx *ops;
475
476	if (!kay || !txsa) {
477		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
478		return -1;
479	}
480
481	ops = kay->ctx;
482	if (!ops || !ops->disable_transmit_sa) {
483		wpa_printf(MSG_ERROR,
484			   "KaY: secy disable_transmit_sa operation not supported");
485		return -1;
486	}
487
488	txsa->enable_transmit = false;
489
490	return ops->disable_transmit_sa(ops->ctx, txsa);
491}
492
493
494int secy_init_macsec(struct ieee802_1x_kay *kay)
495{
496	int ret;
497	struct ieee802_1x_kay_ctx *ops;
498	struct macsec_init_params params;
499
500	if (!kay) {
501		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
502		return -1;
503	}
504
505	ops = kay->ctx;
506	if (!ops || !ops->macsec_init) {
507		wpa_printf(MSG_ERROR,
508			   "KaY: secy macsec_init operation not supported");
509		return -1;
510	}
511
512	params.use_es = false;
513	params.use_scb = false;
514	params.always_include_sci = true;
515
516	ret = ops->macsec_init(ops->ctx, &params);
517
518	return ret;
519}
520
521
522int secy_deinit_macsec(struct ieee802_1x_kay *kay)
523{
524	struct ieee802_1x_kay_ctx *ops;
525
526	if (!kay) {
527		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
528		return -1;
529	}
530
531	ops = kay->ctx;
532	if (!ops || !ops->macsec_deinit) {
533		wpa_printf(MSG_ERROR,
534			   "KaY: secy macsec_deinit operation not supported");
535		return -1;
536	}
537
538	return ops->macsec_deinit(ops->ctx);
539}
540