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 20int 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 28int 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 48int 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 68int 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 89int 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 97int 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 117int 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 141int 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 165int 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 189int 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 209int 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 230int 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 250int 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 271int 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 293int 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 315int 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 335int 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 357int 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 378int 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 401int 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 424int 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 447int 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 475int 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