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_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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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, &params);
470 
471 	return ret;
472 }
473 
474 
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