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_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 
68 int 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 
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 
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 
116 int 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 
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 
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 
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_receive_lowest_pn operation not supported");
191 		return -1;
192 	}
193 
194 	return ops->get_transmit_next_pn(ops->ctx, txsa);
195 }
196 
197 
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 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 
219 int 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 
239 int 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 
259 int 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 
279 int 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 
299 int 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 
321 int 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 
343 int 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 
364 int 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 
385 int 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 
406 int 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 
427 int 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 
450 int 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 
473 int 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 
501 int 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