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