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, 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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