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