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