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, ¶ms);
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