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_offload(struct ieee802_1x_kay * kay,u8 offload)88 int secy_cp_control_offload(struct ieee802_1x_kay *kay, u8 offload)
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_offload) {
99 wpa_printf(MSG_ERROR,
100 "KaY: secy set_offload operation not supported");
101 return -1;
102 }
103
104 return ops->set_offload(ops->ctx, offload);
105 }
106
107
secy_cp_control_current_cipher_suite(struct ieee802_1x_kay * kay,u64 cs)108 int secy_cp_control_current_cipher_suite(struct ieee802_1x_kay *kay, u64 cs)
109 {
110 struct ieee802_1x_kay_ctx *ops;
111
112 if (!kay) {
113 wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
114 return -1;
115 }
116
117 ops = kay->ctx;
118 if (!ops || !ops->set_current_cipher_suite) {
119 wpa_printf(MSG_ERROR,
120 "KaY: secy set_current_cipher_suite operation not supported");
121 return -1;
122 }
123
124 return ops->set_current_cipher_suite(ops->ctx, cs);
125 }
126
127
secy_cp_control_confidentiality_offset(struct ieee802_1x_kay * kay,enum confidentiality_offset co)128 int secy_cp_control_confidentiality_offset(struct ieee802_1x_kay *kay,
129 enum confidentiality_offset co)
130 {
131 kay->co = co;
132 return 0;
133 }
134
135
secy_cp_control_enable_port(struct ieee802_1x_kay * kay,bool enabled)136 int secy_cp_control_enable_port(struct ieee802_1x_kay *kay, bool enabled)
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->enable_controlled_port) {
147 wpa_printf(MSG_ERROR,
148 "KaY: secy enable_controlled_port operation not supported");
149 return -1;
150 }
151
152 return ops->enable_controlled_port(ops->ctx, enabled);
153 }
154
155
secy_get_capability(struct ieee802_1x_kay * kay,enum macsec_cap * cap)156 int secy_get_capability(struct ieee802_1x_kay *kay, enum macsec_cap *cap)
157 {
158 struct ieee802_1x_kay_ctx *ops;
159
160 if (!kay) {
161 wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
162 return -1;
163 }
164
165 ops = kay->ctx;
166 if (!ops || !ops->macsec_get_capability) {
167 wpa_printf(MSG_ERROR,
168 "KaY: secy macsec_get_capability operation not supported");
169 return -1;
170 }
171
172 return ops->macsec_get_capability(ops->ctx, cap);
173 }
174
175
secy_get_receive_lowest_pn(struct ieee802_1x_kay * kay,struct receive_sa * rxsa)176 int secy_get_receive_lowest_pn(struct ieee802_1x_kay *kay,
177 struct receive_sa *rxsa)
178 {
179 struct ieee802_1x_kay_ctx *ops;
180
181 if (!kay || !rxsa) {
182 wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
183 return -1;
184 }
185
186 ops = kay->ctx;
187 if (!ops || !ops->get_receive_lowest_pn) {
188 wpa_printf(MSG_ERROR,
189 "KaY: secy get_receive_lowest_pn operation not supported");
190 return -1;
191 }
192
193 return ops->get_receive_lowest_pn(ops->ctx, rxsa);
194 }
195
196
secy_get_transmit_next_pn(struct ieee802_1x_kay * kay,struct transmit_sa * txsa)197 int secy_get_transmit_next_pn(struct ieee802_1x_kay *kay,
198 struct transmit_sa *txsa)
199 {
200 struct ieee802_1x_kay_ctx *ops;
201
202 if (!kay || !txsa) {
203 wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
204 return -1;
205 }
206
207 ops = kay->ctx;
208 if (!ops || !ops->get_transmit_next_pn) {
209 wpa_printf(MSG_ERROR,
210 "KaY: secy get_transmit_next_pn operation not supported");
211 return -1;
212 }
213
214 return ops->get_transmit_next_pn(ops->ctx, txsa);
215 }
216
217
secy_set_transmit_next_pn(struct ieee802_1x_kay * kay,struct transmit_sa * txsa)218 int secy_set_transmit_next_pn(struct ieee802_1x_kay *kay,
219 struct transmit_sa *txsa)
220 {
221 struct ieee802_1x_kay_ctx *ops;
222
223 if (!kay || !txsa) {
224 wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
225 return -1;
226 }
227
228 ops = kay->ctx;
229 if (!ops || !ops->set_transmit_next_pn) {
230 wpa_printf(MSG_ERROR,
231 "KaY: secy set_transmit_next_pn operation not supported");
232 return -1;
233 }
234
235 return ops->set_transmit_next_pn(ops->ctx, txsa);
236 }
237
238
secy_set_receive_lowest_pn(struct ieee802_1x_kay * kay,struct receive_sa * rxsa)239 int secy_set_receive_lowest_pn(struct ieee802_1x_kay *kay,
240 struct receive_sa *rxsa)
241 {
242 struct ieee802_1x_kay_ctx *ops;
243
244 if (!kay || !rxsa) {
245 wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
246 return -1;
247 }
248
249 ops = kay->ctx;
250 if (!ops || !ops->set_receive_lowest_pn) {
251 wpa_printf(MSG_ERROR,
252 "KaY: secy set_receive_lowest_pn operation not supported");
253 return -1;
254 }
255
256 return ops->set_receive_lowest_pn(ops->ctx, rxsa);
257 }
258
259
secy_create_receive_sc(struct ieee802_1x_kay * kay,struct receive_sc * rxsc)260 int secy_create_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->create_receive_sc) {
271 wpa_printf(MSG_ERROR,
272 "KaY: secy create_receive_sc operation not supported");
273 return -1;
274 }
275
276 return ops->create_receive_sc(ops->ctx, rxsc, kay->vf, kay->co);
277 }
278
279
secy_delete_receive_sc(struct ieee802_1x_kay * kay,struct receive_sc * rxsc)280 int secy_delete_receive_sc(struct ieee802_1x_kay *kay, struct receive_sc *rxsc)
281 {
282 struct ieee802_1x_kay_ctx *ops;
283
284 if (!kay || !rxsc) {
285 wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
286 return -1;
287 }
288
289 ops = kay->ctx;
290 if (!ops || !ops->delete_receive_sc) {
291 wpa_printf(MSG_ERROR,
292 "KaY: secy delete_receive_sc operation not supported");
293 return -1;
294 }
295
296 return ops->delete_receive_sc(ops->ctx, rxsc);
297 }
298
299
secy_create_receive_sa(struct ieee802_1x_kay * kay,struct receive_sa * rxsa)300 int secy_create_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->create_receive_sa) {
311 wpa_printf(MSG_ERROR,
312 "KaY: secy create_receive_sa operation not supported");
313 return -1;
314 }
315
316 return ops->create_receive_sa(ops->ctx, rxsa);
317 }
318
319
secy_delete_receive_sa(struct ieee802_1x_kay * kay,struct receive_sa * rxsa)320 int secy_delete_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->delete_receive_sa) {
331 wpa_printf(MSG_ERROR,
332 "KaY: secy delete_receive_sa operation not supported");
333 return -1;
334 }
335
336 return ops->delete_receive_sa(ops->ctx, rxsa);
337 }
338
339
secy_enable_receive_sa(struct ieee802_1x_kay * kay,struct receive_sa * rxsa)340 int secy_enable_receive_sa(struct ieee802_1x_kay *kay, struct receive_sa *rxsa)
341 {
342 struct ieee802_1x_kay_ctx *ops;
343
344 if (!kay || !rxsa) {
345 wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
346 return -1;
347 }
348
349 ops = kay->ctx;
350 if (!ops || !ops->enable_receive_sa) {
351 wpa_printf(MSG_ERROR,
352 "KaY: secy enable_receive_sa operation not supported");
353 return -1;
354 }
355
356 rxsa->enable_receive = true;
357
358 return ops->enable_receive_sa(ops->ctx, rxsa);
359 }
360
361
secy_disable_receive_sa(struct ieee802_1x_kay * kay,struct receive_sa * rxsa)362 int secy_disable_receive_sa(struct ieee802_1x_kay *kay, struct receive_sa *rxsa)
363 {
364 struct ieee802_1x_kay_ctx *ops;
365
366 if (!kay || !rxsa) {
367 wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
368 return -1;
369 }
370
371 ops = kay->ctx;
372 if (!ops || !ops->disable_receive_sa) {
373 wpa_printf(MSG_ERROR,
374 "KaY: secy disable_receive_sa operation not supported");
375 return -1;
376 }
377
378 rxsa->enable_receive = false;
379
380 return ops->disable_receive_sa(ops->ctx, rxsa);
381 }
382
383
secy_create_transmit_sc(struct ieee802_1x_kay * kay,struct transmit_sc * txsc)384 int secy_create_transmit_sc(struct ieee802_1x_kay *kay,
385 struct transmit_sc *txsc)
386 {
387 struct ieee802_1x_kay_ctx *ops;
388
389 if (!kay || !txsc) {
390 wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
391 return -1;
392 }
393
394 ops = kay->ctx;
395 if (!ops || !ops->create_transmit_sc) {
396 wpa_printf(MSG_ERROR,
397 "KaY: secy create_transmit_sc operation not supported");
398 return -1;
399 }
400
401 return ops->create_transmit_sc(ops->ctx, txsc, kay->co);
402 }
403
404
secy_delete_transmit_sc(struct ieee802_1x_kay * kay,struct transmit_sc * txsc)405 int secy_delete_transmit_sc(struct ieee802_1x_kay *kay,
406 struct transmit_sc *txsc)
407 {
408 struct ieee802_1x_kay_ctx *ops;
409
410 if (!kay || !txsc) {
411 wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
412 return -1;
413 }
414
415 ops = kay->ctx;
416 if (!ops || !ops->delete_transmit_sc) {
417 wpa_printf(MSG_ERROR,
418 "KaY: secy delete_transmit_sc operation not supported");
419 return -1;
420 }
421
422 return ops->delete_transmit_sc(ops->ctx, txsc);
423 }
424
425
secy_create_transmit_sa(struct ieee802_1x_kay * kay,struct transmit_sa * txsa)426 int secy_create_transmit_sa(struct ieee802_1x_kay *kay,
427 struct transmit_sa *txsa)
428 {
429 struct ieee802_1x_kay_ctx *ops;
430
431 if (!kay || !txsa) {
432 wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
433 return -1;
434 }
435
436 ops = kay->ctx;
437 if (!ops || !ops->create_transmit_sa) {
438 wpa_printf(MSG_ERROR,
439 "KaY: secy create_transmit_sa operation not supported");
440 return -1;
441 }
442
443 return ops->create_transmit_sa(ops->ctx, txsa);
444 }
445
446
secy_delete_transmit_sa(struct ieee802_1x_kay * kay,struct transmit_sa * txsa)447 int secy_delete_transmit_sa(struct ieee802_1x_kay *kay,
448 struct transmit_sa *txsa)
449 {
450 struct ieee802_1x_kay_ctx *ops;
451
452 if (!kay || !txsa) {
453 wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
454 return -1;
455 }
456
457 ops = kay->ctx;
458 if (!ops || !ops->delete_transmit_sa) {
459 wpa_printf(MSG_ERROR,
460 "KaY: secy delete_transmit_sa operation not supported");
461 return -1;
462 }
463
464 return ops->delete_transmit_sa(ops->ctx, txsa);
465 }
466
467
secy_enable_transmit_sa(struct ieee802_1x_kay * kay,struct transmit_sa * txsa)468 int secy_enable_transmit_sa(struct ieee802_1x_kay *kay,
469 struct transmit_sa *txsa)
470 {
471 struct ieee802_1x_kay_ctx *ops;
472
473 if (!kay || !txsa) {
474 wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
475 return -1;
476 }
477
478 ops = kay->ctx;
479 if (!ops || !ops->enable_transmit_sa) {
480 wpa_printf(MSG_ERROR,
481 "KaY: secy enable_transmit_sa operation not supported");
482 return -1;
483 }
484
485 txsa->enable_transmit = true;
486
487 return ops->enable_transmit_sa(ops->ctx, txsa);
488 }
489
490
secy_disable_transmit_sa(struct ieee802_1x_kay * kay,struct transmit_sa * txsa)491 int secy_disable_transmit_sa(struct ieee802_1x_kay *kay,
492 struct transmit_sa *txsa)
493 {
494 struct ieee802_1x_kay_ctx *ops;
495
496 if (!kay || !txsa) {
497 wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
498 return -1;
499 }
500
501 ops = kay->ctx;
502 if (!ops || !ops->disable_transmit_sa) {
503 wpa_printf(MSG_ERROR,
504 "KaY: secy disable_transmit_sa operation not supported");
505 return -1;
506 }
507
508 txsa->enable_transmit = false;
509
510 return ops->disable_transmit_sa(ops->ctx, txsa);
511 }
512
513
secy_init_macsec(struct ieee802_1x_kay * kay)514 int secy_init_macsec(struct ieee802_1x_kay *kay)
515 {
516 int ret;
517 struct ieee802_1x_kay_ctx *ops;
518 struct macsec_init_params params;
519
520 if (!kay) {
521 wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
522 return -1;
523 }
524
525 ops = kay->ctx;
526 if (!ops || !ops->macsec_init) {
527 wpa_printf(MSG_ERROR,
528 "KaY: secy macsec_init operation not supported");
529 return -1;
530 }
531
532 params.use_es = false;
533 params.use_scb = false;
534 params.always_include_sci = true;
535
536 ret = ops->macsec_init(ops->ctx, ¶ms);
537
538 return ret;
539 }
540
541
secy_deinit_macsec(struct ieee802_1x_kay * kay)542 int secy_deinit_macsec(struct ieee802_1x_kay *kay)
543 {
544 struct ieee802_1x_kay_ctx *ops;
545
546 if (!kay) {
547 wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__);
548 return -1;
549 }
550
551 ops = kay->ctx;
552 if (!ops || !ops->macsec_deinit) {
553 wpa_printf(MSG_ERROR,
554 "KaY: secy macsec_deinit operation not supported");
555 return -1;
556 }
557
558 return ops->macsec_deinit(ops->ctx);
559 }
560