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