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_replay(struct ieee802_1x_kay *kay, Boolean enabled, u32 win)
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->set_replay_protect) {
59		wpa_printf(MSG_ERROR,
60			   "KaY: secy set_replay_protect operation not supported");
61		return -1;
62	}
63
64	return ops->set_replay_protect(ops->ctx, enabled, win);
65}
66
67
68int secy_cp_control_current_cipher_suite(struct ieee802_1x_kay *kay,
69					 const u8 *cs, size_t cs_len)
70{
71	struct ieee802_1x_kay_ctx *ops;
72
73	if (!kay) {
74		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
75		return -1;
76	}
77
78	ops = kay->ctx;
79	if (!ops || !ops->set_current_cipher_suite) {
80		wpa_printf(MSG_ERROR,
81			   "KaY: secy set_current_cipher_suite operation not supported");
82		return -1;
83	}
84
85	return ops->set_current_cipher_suite(ops->ctx, cs, cs_len);
86}
87
88
89int secy_cp_control_confidentiality_offset(struct ieee802_1x_kay *kay,
90					   enum confidentiality_offset co)
91{
92	kay->co = co;
93	return 0;
94}
95
96
97int secy_cp_control_enable_port(struct ieee802_1x_kay *kay, Boolean enabled)
98{
99	struct ieee802_1x_kay_ctx *ops;
100
101	if (!kay) {
102		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
103		return -1;
104	}
105
106	ops = kay->ctx;
107	if (!ops || !ops->enable_controlled_port) {
108		wpa_printf(MSG_ERROR,
109			   "KaY: secy enable_controlled_port operation not supported");
110		return -1;
111	}
112
113	return ops->enable_controlled_port(ops->ctx, enabled);
114}
115
116
117int secy_get_receive_lowest_pn(struct ieee802_1x_kay *kay,
118			       struct receive_sa *rxsa)
119{
120	struct ieee802_1x_kay_ctx *ops;
121
122	if (!kay || !rxsa) {
123		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
124		return -1;
125	}
126
127	ops = kay->ctx;
128	if (!ops || !ops->get_receive_lowest_pn) {
129		wpa_printf(MSG_ERROR,
130			   "KaY: secy get_receive_lowest_pn operation not supported");
131		return -1;
132	}
133
134	return ops->get_receive_lowest_pn(ops->ctx,
135					rxsa->sc->channel,
136					rxsa->an,
137					&rxsa->lowest_pn);
138}
139
140
141int secy_get_transmit_next_pn(struct ieee802_1x_kay *kay,
142			      struct transmit_sa *txsa)
143{
144	struct ieee802_1x_kay_ctx *ops;
145
146	if (!kay || !txsa) {
147		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
148		return -1;
149	}
150
151	ops = kay->ctx;
152	if (!ops || !ops->get_transmit_next_pn) {
153		wpa_printf(MSG_ERROR,
154			   "KaY: secy get_receive_lowest_pn operation not supported");
155		return -1;
156	}
157
158	return ops->get_transmit_next_pn(ops->ctx,
159					txsa->sc->channel,
160					txsa->an,
161					&txsa->next_pn);
162}
163
164
165int secy_set_transmit_next_pn(struct ieee802_1x_kay *kay,
166			      struct transmit_sa *txsa)
167{
168	struct ieee802_1x_kay_ctx *ops;
169
170	if (!kay || !txsa) {
171		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
172		return -1;
173	}
174
175	ops = kay->ctx;
176	if (!ops || !ops->set_transmit_next_pn) {
177		wpa_printf(MSG_ERROR,
178			   "KaY: secy get_receive_lowest_pn operation not supported");
179		return -1;
180	}
181
182	return ops->set_transmit_next_pn(ops->ctx,
183					txsa->sc->channel,
184					txsa->an,
185					txsa->next_pn);
186}
187
188
189int secy_get_available_receive_sc(struct ieee802_1x_kay *kay, u32 *channel)
190{
191	struct ieee802_1x_kay_ctx *ops;
192
193	if (!kay) {
194		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
195		return -1;
196	}
197
198	ops = kay->ctx;
199	if (!ops || !ops->get_available_receive_sc) {
200		wpa_printf(MSG_ERROR,
201			   "KaY: secy get_available_receive_sc operation not supported");
202		return -1;
203	}
204
205	return ops->get_available_receive_sc(ops->ctx, channel);
206}
207
208
209int secy_create_receive_sc(struct ieee802_1x_kay *kay, struct receive_sc *rxsc)
210{
211	struct ieee802_1x_kay_ctx *ops;
212
213	if (!kay || !rxsc) {
214		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
215		return -1;
216	}
217
218	ops = kay->ctx;
219	if (!ops || !ops->create_receive_sc) {
220		wpa_printf(MSG_ERROR,
221			   "KaY: secy create_receive_sc operation not supported");
222		return -1;
223	}
224
225	return ops->create_receive_sc(ops->ctx, rxsc->channel, &rxsc->sci,
226				      kay->vf, kay->co);
227}
228
229
230int secy_delete_receive_sc(struct ieee802_1x_kay *kay, struct receive_sc *rxsc)
231{
232	struct ieee802_1x_kay_ctx *ops;
233
234	if (!kay || !rxsc) {
235		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
236		return -1;
237	}
238
239	ops = kay->ctx;
240	if (!ops || !ops->delete_receive_sc) {
241		wpa_printf(MSG_ERROR,
242			   "KaY: secy delete_receive_sc operation not supported");
243		return -1;
244	}
245
246	return ops->delete_receive_sc(ops->ctx, rxsc->channel);
247}
248
249
250int secy_create_receive_sa(struct ieee802_1x_kay *kay, struct receive_sa *rxsa)
251{
252	struct ieee802_1x_kay_ctx *ops;
253
254	if (!kay || !rxsa) {
255		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
256		return -1;
257	}
258
259	ops = kay->ctx;
260	if (!ops || !ops->create_receive_sa) {
261		wpa_printf(MSG_ERROR,
262			   "KaY: secy create_receive_sa operation not supported");
263		return -1;
264	}
265
266	return ops->create_receive_sa(ops->ctx, rxsa->sc->channel, rxsa->an,
267				      rxsa->lowest_pn, rxsa->pkey->key);
268}
269
270
271int secy_enable_receive_sa(struct ieee802_1x_kay *kay, struct receive_sa *rxsa)
272{
273	struct ieee802_1x_kay_ctx *ops;
274
275	if (!kay || !rxsa) {
276		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
277		return -1;
278	}
279
280	ops = kay->ctx;
281	if (!ops || !ops->enable_receive_sa) {
282		wpa_printf(MSG_ERROR,
283			   "KaY: secy enable_receive_sa operation not supported");
284		return -1;
285	}
286
287	rxsa->enable_receive = TRUE;
288
289	return ops->enable_receive_sa(ops->ctx, rxsa->sc->channel, rxsa->an);
290}
291
292
293int secy_disable_receive_sa(struct ieee802_1x_kay *kay, struct receive_sa *rxsa)
294{
295	struct ieee802_1x_kay_ctx *ops;
296
297	if (!kay || !rxsa) {
298		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
299		return -1;
300	}
301
302	ops = kay->ctx;
303	if (!ops || !ops->disable_receive_sa) {
304		wpa_printf(MSG_ERROR,
305			   "KaY: secy disable_receive_sa operation not supported");
306		return -1;
307	}
308
309	rxsa->enable_receive = FALSE;
310
311	return ops->disable_receive_sa(ops->ctx, rxsa->sc->channel, rxsa->an);
312}
313
314
315int secy_get_available_transmit_sc(struct ieee802_1x_kay *kay, u32 *channel)
316{
317	struct ieee802_1x_kay_ctx *ops;
318
319	if (!kay) {
320		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
321		return -1;
322	}
323
324	ops = kay->ctx;
325	if (!ops || !ops->get_available_transmit_sc) {
326		wpa_printf(MSG_ERROR,
327			   "KaY: secy get_available_transmit_sc operation not supported");
328		return -1;
329	}
330
331	return ops->get_available_transmit_sc(ops->ctx, channel);
332}
333
334
335int secy_create_transmit_sc(struct ieee802_1x_kay *kay,
336			    struct transmit_sc *txsc)
337{
338	struct ieee802_1x_kay_ctx *ops;
339
340	if (!kay || !txsc) {
341		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
342		return -1;
343	}
344
345	ops = kay->ctx;
346	if (!ops || !ops->create_transmit_sc) {
347		wpa_printf(MSG_ERROR,
348			   "KaY: secy create_transmit_sc operation not supported");
349		return -1;
350	}
351
352	return ops->create_transmit_sc(ops->ctx, txsc->channel, &txsc->sci,
353				       kay->co);
354}
355
356
357int secy_delete_transmit_sc(struct ieee802_1x_kay *kay,
358			    struct transmit_sc *txsc)
359{
360	struct ieee802_1x_kay_ctx *ops;
361
362	if (!kay || !txsc) {
363		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
364		return -1;
365	}
366
367	ops = kay->ctx;
368	if (!ops || !ops->delete_transmit_sc) {
369		wpa_printf(MSG_ERROR,
370			   "KaY: secy delete_transmit_sc operation not supported");
371		return -1;
372	}
373
374	return ops->delete_transmit_sc(ops->ctx, txsc->channel);
375}
376
377
378int secy_create_transmit_sa(struct ieee802_1x_kay *kay,
379			    struct transmit_sa *txsa)
380{
381	struct ieee802_1x_kay_ctx *ops;
382
383	if (!kay || !txsa) {
384		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
385		return -1;
386	}
387
388	ops = kay->ctx;
389	if (!ops || !ops->create_transmit_sa) {
390		wpa_printf(MSG_ERROR,
391			   "KaY: secy create_transmit_sa operation not supported");
392		return -1;
393	}
394
395	return ops->create_transmit_sa(ops->ctx, txsa->sc->channel, txsa->an,
396					txsa->next_pn, txsa->confidentiality,
397					txsa->pkey->key);
398}
399
400
401int secy_enable_transmit_sa(struct ieee802_1x_kay *kay,
402			    struct transmit_sa *txsa)
403{
404	struct ieee802_1x_kay_ctx *ops;
405
406	if (!kay || !txsa) {
407		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
408		return -1;
409	}
410
411	ops = kay->ctx;
412	if (!ops || !ops->enable_transmit_sa) {
413		wpa_printf(MSG_ERROR,
414			   "KaY: secy enable_transmit_sa operation not supported");
415		return -1;
416	}
417
418	txsa->enable_transmit = TRUE;
419
420	return ops->enable_transmit_sa(ops->ctx, txsa->sc->channel, txsa->an);
421}
422
423
424int secy_disable_transmit_sa(struct ieee802_1x_kay *kay,
425			     struct transmit_sa *txsa)
426{
427	struct ieee802_1x_kay_ctx *ops;
428
429	if (!kay || !txsa) {
430		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
431		return -1;
432	}
433
434	ops = kay->ctx;
435	if (!ops || !ops->disable_transmit_sa) {
436		wpa_printf(MSG_ERROR,
437			   "KaY: secy disable_transmit_sa operation not supported");
438		return -1;
439	}
440
441	txsa->enable_transmit = FALSE;
442
443	return ops->disable_transmit_sa(ops->ctx, txsa->sc->channel, txsa->an);
444}
445
446
447int secy_init_macsec(struct ieee802_1x_kay *kay)
448{
449	int ret;
450	struct ieee802_1x_kay_ctx *ops;
451	struct macsec_init_params params;
452
453	if (!kay) {
454		wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
455		return -1;
456	}
457
458	ops = kay->ctx;
459	if (!ops || !ops->macsec_init) {
460		wpa_printf(MSG_ERROR,
461			   "KaY: secy macsec_init operation not supported");
462		return -1;
463	}
464
465	params.use_es = FALSE;
466	params.use_scb = FALSE;
467	params.always_include_sci = TRUE;
468
469	ret = ops->macsec_init(ops->ctx, &params);
470
471	return ret;
472}
473
474
475int secy_deinit_macsec(struct ieee802_1x_kay *kay)
476{
477	struct ieee802_1x_kay_ctx *ops;
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_deinit) {
486		wpa_printf(MSG_ERROR,
487			   "KaY: secy macsec_deinit operation not supported");
488		return -1;
489	}
490
491	return ops->macsec_deinit(ops->ctx);
492}
493