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 
secy_cp_control_validate_frames(struct ieee802_1x_kay * kay,enum validate_frames vf)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 
secy_cp_control_protect_frames(struct ieee802_1x_kay * kay,bool enabled)28 int 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 
secy_cp_control_encrypt(struct ieee802_1x_kay * kay,bool enabled)48 int 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 
secy_cp_control_replay(struct ieee802_1x_kay * kay,bool enabled,u32 win)68 int 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 
secy_cp_control_current_cipher_suite(struct ieee802_1x_kay * kay,u64 cs)88 int 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 
secy_cp_control_confidentiality_offset(struct ieee802_1x_kay * kay,enum confidentiality_offset co)108 int 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 
secy_cp_control_enable_port(struct ieee802_1x_kay * kay,bool enabled)116 int 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 
secy_get_capability(struct ieee802_1x_kay * kay,enum macsec_cap * cap)136 int 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 
secy_get_receive_lowest_pn(struct ieee802_1x_kay * kay,struct receive_sa * rxsa)156 int 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 
secy_get_transmit_next_pn(struct ieee802_1x_kay * kay,struct transmit_sa * txsa)177 int 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 
secy_set_transmit_next_pn(struct ieee802_1x_kay * kay,struct transmit_sa * txsa)198 int 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 
secy_set_receive_lowest_pn(struct ieee802_1x_kay * kay,struct receive_sa * rxsa)219 int 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 
secy_create_receive_sc(struct ieee802_1x_kay * kay,struct receive_sc * rxsc)240 int 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 
secy_delete_receive_sc(struct ieee802_1x_kay * kay,struct receive_sc * rxsc)260 int 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 
secy_create_receive_sa(struct ieee802_1x_kay * kay,struct receive_sa * rxsa)280 int 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 
secy_delete_receive_sa(struct ieee802_1x_kay * kay,struct receive_sa * rxsa)300 int 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 
secy_enable_receive_sa(struct ieee802_1x_kay * kay,struct receive_sa * rxsa)320 int 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 
secy_disable_receive_sa(struct ieee802_1x_kay * kay,struct receive_sa * rxsa)342 int 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 
secy_create_transmit_sc(struct ieee802_1x_kay * kay,struct transmit_sc * txsc)364 int 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 
secy_delete_transmit_sc(struct ieee802_1x_kay * kay,struct transmit_sc * txsc)385 int 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 
secy_create_transmit_sa(struct ieee802_1x_kay * kay,struct transmit_sa * txsa)406 int 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 
secy_delete_transmit_sa(struct ieee802_1x_kay * kay,struct transmit_sa * txsa)427 int 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 
secy_enable_transmit_sa(struct ieee802_1x_kay * kay,struct transmit_sa * txsa)448 int 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 
secy_disable_transmit_sa(struct ieee802_1x_kay * kay,struct transmit_sa * txsa)471 int 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 
secy_init_macsec(struct ieee802_1x_kay * kay)494 int 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 
secy_deinit_macsec(struct ieee802_1x_kay * kay)522 int 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