1 /* 2 * IEEE 802.1X-2010 KaY Interface 3 * Copyright (c) 2019, The Linux Foundation 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 "pae/ieee802_1x_key.h" 13 #include "pae/ieee802_1x_kay.h" 14 #include "hostapd.h" 15 #include "sta_info.h" 16 #include "wpa_auth_kay.h" 17 #include "ieee802_1x.h" 18 19 20 #define DEFAULT_KEY_LEN 16 21 /* secure Connectivity Association Key Name (CKN) */ 22 #define DEFAULT_CKN_LEN 16 23 24 25 static int hapd_macsec_init(void *priv, struct macsec_init_params *params) 26 { 27 struct hostapd_data *hapd = priv; 28 29 if (!hapd->driver->macsec_init) 30 return -1; 31 return hapd->driver->macsec_init(hapd->drv_priv, params); 32 } 33 34 35 static int hapd_macsec_deinit(void *priv) 36 { 37 struct hostapd_data *hapd = priv; 38 39 if (!hapd->driver->macsec_deinit) 40 return -1; 41 return hapd->driver->macsec_deinit(hapd->drv_priv); 42 } 43 44 45 static int hapd_macsec_get_capability(void *priv, enum macsec_cap *cap) 46 { 47 struct hostapd_data *hapd = priv; 48 49 if (!hapd->driver->macsec_get_capability) 50 return -1; 51 return hapd->driver->macsec_get_capability(hapd->drv_priv, cap); 52 } 53 54 55 static int hapd_enable_protect_frames(void *priv, bool enabled) 56 { 57 struct hostapd_data *hapd = priv; 58 59 if (!hapd->driver->enable_protect_frames) 60 return -1; 61 return hapd->driver->enable_protect_frames(hapd->drv_priv, enabled); 62 } 63 64 65 static int hapd_enable_encrypt(void *priv, bool enabled) 66 { 67 struct hostapd_data *hapd = priv; 68 69 if (!hapd->driver->enable_encrypt) 70 return -1; 71 return hapd->driver->enable_encrypt(hapd->drv_priv, enabled); 72 } 73 74 75 static int hapd_set_replay_protect(void *priv, bool enabled, u32 window) 76 { 77 struct hostapd_data *hapd = priv; 78 79 if (!hapd->driver->set_replay_protect) 80 return -1; 81 return hapd->driver->set_replay_protect(hapd->drv_priv, enabled, 82 window); 83 } 84 85 86 static int hapd_set_current_cipher_suite(void *priv, u64 cs) 87 { 88 struct hostapd_data *hapd = priv; 89 90 if (!hapd->driver->set_current_cipher_suite) 91 return -1; 92 return hapd->driver->set_current_cipher_suite(hapd->drv_priv, cs); 93 } 94 95 96 static int hapd_enable_controlled_port(void *priv, bool enabled) 97 { 98 struct hostapd_data *hapd = priv; 99 100 if (!hapd->driver->enable_controlled_port) 101 return -1; 102 return hapd->driver->enable_controlled_port(hapd->drv_priv, enabled); 103 } 104 105 106 static int hapd_get_receive_lowest_pn(void *priv, struct receive_sa *sa) 107 { 108 struct hostapd_data *hapd = priv; 109 110 if (!hapd->driver->get_receive_lowest_pn) 111 return -1; 112 return hapd->driver->get_receive_lowest_pn(hapd->drv_priv, sa); 113 } 114 115 116 static int hapd_get_transmit_next_pn(void *priv, struct transmit_sa *sa) 117 { 118 struct hostapd_data *hapd = priv; 119 120 if (!hapd->driver->get_transmit_next_pn) 121 return -1; 122 return hapd->driver->get_transmit_next_pn(hapd->drv_priv, sa); 123 } 124 125 126 static int hapd_set_transmit_next_pn(void *priv, struct transmit_sa *sa) 127 { 128 struct hostapd_data *hapd = priv; 129 130 if (!hapd->driver->set_transmit_next_pn) 131 return -1; 132 return hapd->driver->set_transmit_next_pn(hapd->drv_priv, sa); 133 } 134 135 136 static unsigned int conf_offset_val(enum confidentiality_offset co) 137 { 138 switch (co) { 139 case CONFIDENTIALITY_OFFSET_30: 140 return 30; 141 break; 142 case CONFIDENTIALITY_OFFSET_50: 143 return 50; 144 default: 145 return 0; 146 } 147 } 148 149 150 static int hapd_create_receive_sc(void *priv, struct receive_sc *sc, 151 enum validate_frames vf, 152 enum confidentiality_offset co) 153 { 154 struct hostapd_data *hapd = priv; 155 156 if (!hapd->driver->create_receive_sc) 157 return -1; 158 return hapd->driver->create_receive_sc(hapd->drv_priv, sc, 159 conf_offset_val(co), vf); 160 } 161 162 163 static int hapd_delete_receive_sc(void *priv, struct receive_sc *sc) 164 { 165 struct hostapd_data *hapd = priv; 166 167 if (!hapd->driver->delete_receive_sc) 168 return -1; 169 return hapd->driver->delete_receive_sc(hapd->drv_priv, sc); 170 } 171 172 173 static int hapd_create_receive_sa(void *priv, struct receive_sa *sa) 174 { 175 struct hostapd_data *hapd = priv; 176 177 if (!hapd->driver->create_receive_sa) 178 return -1; 179 return hapd->driver->create_receive_sa(hapd->drv_priv, sa); 180 } 181 182 183 static int hapd_delete_receive_sa(void *priv, struct receive_sa *sa) 184 { 185 struct hostapd_data *hapd = priv; 186 187 if (!hapd->driver->delete_receive_sa) 188 return -1; 189 return hapd->driver->delete_receive_sa(hapd->drv_priv, sa); 190 } 191 192 193 static int hapd_enable_receive_sa(void *priv, struct receive_sa *sa) 194 { 195 struct hostapd_data *hapd = priv; 196 197 if (!hapd->driver->enable_receive_sa) 198 return -1; 199 return hapd->driver->enable_receive_sa(hapd->drv_priv, sa); 200 } 201 202 203 static int hapd_disable_receive_sa(void *priv, struct receive_sa *sa) 204 { 205 struct hostapd_data *hapd = priv; 206 207 if (!hapd->driver->disable_receive_sa) 208 return -1; 209 return hapd->driver->disable_receive_sa(hapd->drv_priv, sa); 210 } 211 212 213 static int 214 hapd_create_transmit_sc(void *priv, struct transmit_sc *sc, 215 enum confidentiality_offset co) 216 { 217 struct hostapd_data *hapd = priv; 218 219 if (!hapd->driver->create_transmit_sc) 220 return -1; 221 return hapd->driver->create_transmit_sc(hapd->drv_priv, sc, 222 conf_offset_val(co)); 223 } 224 225 226 static int hapd_delete_transmit_sc(void *priv, struct transmit_sc *sc) 227 { 228 struct hostapd_data *hapd = priv; 229 230 if (!hapd->driver->delete_transmit_sc) 231 return -1; 232 return hapd->driver->delete_transmit_sc(hapd->drv_priv, sc); 233 } 234 235 236 static int hapd_create_transmit_sa(void *priv, struct transmit_sa *sa) 237 { 238 struct hostapd_data *hapd = priv; 239 240 if (!hapd->driver->create_transmit_sa) 241 return -1; 242 return hapd->driver->create_transmit_sa(hapd->drv_priv, sa); 243 } 244 245 246 static int hapd_delete_transmit_sa(void *priv, struct transmit_sa *sa) 247 { 248 struct hostapd_data *hapd = priv; 249 250 if (!hapd->driver->delete_transmit_sa) 251 return -1; 252 return hapd->driver->delete_transmit_sa(hapd->drv_priv, sa); 253 } 254 255 256 static int hapd_enable_transmit_sa(void *priv, struct transmit_sa *sa) 257 { 258 struct hostapd_data *hapd = priv; 259 260 if (!hapd->driver->enable_transmit_sa) 261 return -1; 262 return hapd->driver->enable_transmit_sa(hapd->drv_priv, sa); 263 } 264 265 266 static int hapd_disable_transmit_sa(void *priv, struct transmit_sa *sa) 267 { 268 struct hostapd_data *hapd = priv; 269 270 if (!hapd->driver->disable_transmit_sa) 271 return -1; 272 return hapd->driver->disable_transmit_sa(hapd->drv_priv, sa); 273 } 274 275 276 int ieee802_1x_alloc_kay_sm_hapd(struct hostapd_data *hapd, 277 struct sta_info *sta) 278 { 279 struct ieee802_1x_kay_ctx *kay_ctx; 280 struct ieee802_1x_kay *res = NULL; 281 enum macsec_policy policy; 282 283 ieee802_1x_dealloc_kay_sm_hapd(hapd); 284 285 if (!hapd->conf || hapd->conf->macsec_policy == 0) 286 return 0; 287 288 if (hapd->conf->macsec_policy == 1) { 289 if (hapd->conf->macsec_integ_only == 1) 290 policy = SHOULD_SECURE; 291 else 292 policy = SHOULD_ENCRYPT; 293 } else { 294 policy = DO_NOT_SECURE; 295 } 296 297 wpa_printf(MSG_DEBUG, "%s: if_name=%s", __func__, hapd->conf->iface); 298 kay_ctx = os_zalloc(sizeof(*kay_ctx)); 299 if (!kay_ctx) 300 return -1; 301 302 kay_ctx->ctx = hapd; 303 304 kay_ctx->macsec_init = hapd_macsec_init; 305 kay_ctx->macsec_deinit = hapd_macsec_deinit; 306 kay_ctx->macsec_get_capability = hapd_macsec_get_capability; 307 kay_ctx->enable_protect_frames = hapd_enable_protect_frames; 308 kay_ctx->enable_encrypt = hapd_enable_encrypt; 309 kay_ctx->set_replay_protect = hapd_set_replay_protect; 310 kay_ctx->set_current_cipher_suite = hapd_set_current_cipher_suite; 311 kay_ctx->enable_controlled_port = hapd_enable_controlled_port; 312 kay_ctx->get_receive_lowest_pn = hapd_get_receive_lowest_pn; 313 kay_ctx->get_transmit_next_pn = hapd_get_transmit_next_pn; 314 kay_ctx->set_transmit_next_pn = hapd_set_transmit_next_pn; 315 kay_ctx->create_receive_sc = hapd_create_receive_sc; 316 kay_ctx->delete_receive_sc = hapd_delete_receive_sc; 317 kay_ctx->create_receive_sa = hapd_create_receive_sa; 318 kay_ctx->delete_receive_sa = hapd_delete_receive_sa; 319 kay_ctx->enable_receive_sa = hapd_enable_receive_sa; 320 kay_ctx->disable_receive_sa = hapd_disable_receive_sa; 321 kay_ctx->create_transmit_sc = hapd_create_transmit_sc; 322 kay_ctx->delete_transmit_sc = hapd_delete_transmit_sc; 323 kay_ctx->create_transmit_sa = hapd_create_transmit_sa; 324 kay_ctx->delete_transmit_sa = hapd_delete_transmit_sa; 325 kay_ctx->enable_transmit_sa = hapd_enable_transmit_sa; 326 kay_ctx->disable_transmit_sa = hapd_disable_transmit_sa; 327 328 res = ieee802_1x_kay_init(kay_ctx, policy, 329 hapd->conf->macsec_replay_protect, 330 hapd->conf->macsec_replay_window, 331 hapd->conf->macsec_port, 332 hapd->conf->mka_priority, hapd->conf->iface, 333 hapd->own_addr); 334 /* ieee802_1x_kay_init() frees kay_ctx on failure */ 335 if (!res) 336 return -1; 337 338 hapd->kay = res; 339 340 return 0; 341 } 342 343 344 void ieee802_1x_dealloc_kay_sm_hapd(struct hostapd_data *hapd) 345 { 346 if (!hapd->kay) 347 return; 348 349 ieee802_1x_kay_deinit(hapd->kay); 350 hapd->kay = NULL; 351 } 352 353 354 static int ieee802_1x_auth_get_session_id(struct hostapd_data *hapd, 355 struct sta_info *sta, u8 *sid, 356 size_t *len) 357 { 358 const u8 *session_id; 359 size_t id_len, need_len; 360 361 session_id = ieee802_1x_get_session_id(sta->eapol_sm, &id_len); 362 if (!session_id) { 363 wpa_printf(MSG_DEBUG, 364 "MACsec: Failed to get SessionID from EAPOL state machines"); 365 return -1; 366 } 367 368 need_len = 1 + 2 * 32 /* random size */; 369 if (need_len > id_len) { 370 wpa_printf(MSG_DEBUG, "EAP Session-Id not long enough"); 371 return -1; 372 } 373 374 os_memcpy(sid, session_id, need_len); 375 *len = need_len; 376 377 return 0; 378 } 379 380 381 static int ieee802_1x_auth_get_msk(struct hostapd_data *hapd, 382 struct sta_info *sta, u8 *msk, size_t *len) 383 { 384 const u8 *key; 385 size_t keylen; 386 387 if (!sta->eapol_sm) 388 return -1; 389 390 key = ieee802_1x_get_key(sta->eapol_sm, &keylen); 391 if (key == NULL) { 392 wpa_printf(MSG_DEBUG, 393 "MACsec: Failed to get MSK from EAPOL state machines"); 394 return -1; 395 } 396 wpa_printf(MSG_DEBUG, "MACsec: Successfully fetched key (len=%lu)", 397 (unsigned long) keylen); 398 wpa_hexdump_key(MSG_DEBUG, "MSK: ", key, keylen); 399 400 if (keylen > *len) 401 keylen = *len; 402 os_memcpy(msk, key, keylen); 403 *len = keylen; 404 405 return 0; 406 } 407 408 409 void * ieee802_1x_notify_create_actor_hapd(struct hostapd_data *hapd, 410 struct sta_info *sta) 411 { 412 u8 *sid; 413 size_t sid_len = 128; 414 struct mka_key_name *ckn; 415 struct mka_key *cak; 416 struct mka_key *msk; 417 void *res = NULL; 418 419 if (!hapd->kay || hapd->kay->policy == DO_NOT_SECURE) 420 return NULL; 421 422 wpa_printf(MSG_DEBUG, 423 "IEEE 802.1X: External notification - Create MKA for " 424 MACSTR, MAC2STR(sta->addr)); 425 426 msk = os_zalloc(sizeof(*msk)); 427 sid = os_zalloc(sid_len); 428 ckn = os_zalloc(sizeof(*ckn)); 429 cak = os_zalloc(sizeof(*cak)); 430 if (!msk || !sid || !ckn || !cak) 431 goto fail; 432 433 msk->len = DEFAULT_KEY_LEN; 434 if (ieee802_1x_auth_get_msk(hapd, sta, msk->key, &msk->len)) { 435 wpa_printf(MSG_ERROR, "IEEE 802.1X: Could not get MSK"); 436 goto fail; 437 } 438 439 if (ieee802_1x_auth_get_session_id(hapd, sta, sid, &sid_len)) 440 { 441 wpa_printf(MSG_ERROR, 442 "IEEE 802.1X: Could not get EAP Session Id"); 443 goto fail; 444 } 445 446 wpa_hexdump(MSG_DEBUG, "own_addr", hapd->own_addr, ETH_ALEN); 447 wpa_hexdump(MSG_DEBUG, "sta_addr", sta->addr, ETH_ALEN); 448 449 /* Derive CAK from MSK */ 450 cak->len = DEFAULT_KEY_LEN; 451 if (ieee802_1x_cak_aes_cmac(msk->key, msk->len, hapd->own_addr, 452 sta->addr, cak->key, cak->len)) { 453 wpa_printf(MSG_ERROR, "IEEE 802.1X: Deriving CAK failed"); 454 goto fail; 455 } 456 wpa_hexdump_key(MSG_DEBUG, "Derived CAK", cak->key, cak->len); 457 458 /* Derive CKN from MSK */ 459 ckn->len = DEFAULT_CKN_LEN; 460 if (ieee802_1x_ckn_aes_cmac(msk->key, msk->len, hapd->own_addr, 461 sta->addr, sid, sid_len, ckn->name)) { 462 wpa_printf(MSG_ERROR, "IEEE 802.1X: Deriving CKN failed"); 463 goto fail; 464 } 465 wpa_hexdump(MSG_DEBUG, "Derived CKN", ckn->name, ckn->len); 466 467 res = ieee802_1x_kay_create_mka(hapd->kay, ckn, cak, 0, EAP_EXCHANGE, 468 true); 469 470 fail: 471 bin_clear_free(msk, sizeof(*msk)); 472 os_free(sid); 473 os_free(ckn); 474 bin_clear_free(cak, sizeof(*cak)); 475 476 return res; 477 } 478 479 480 void * ieee802_1x_create_preshared_mka_hapd(struct hostapd_data *hapd, 481 struct sta_info *sta) 482 { 483 struct mka_key *cak; 484 struct mka_key_name *ckn; 485 void *res = NULL; 486 487 if ((hapd->conf->mka_psk_set & MKA_PSK_SET) != MKA_PSK_SET) 488 goto end; 489 490 ckn = os_zalloc(sizeof(*ckn)); 491 if (!ckn) 492 goto end; 493 494 cak = os_zalloc(sizeof(*cak)); 495 if (!cak) 496 goto free_ckn; 497 498 if (ieee802_1x_alloc_kay_sm_hapd(hapd, sta) < 0 || !hapd->kay) 499 goto free_cak; 500 501 if (hapd->kay->policy == DO_NOT_SECURE) 502 goto dealloc; 503 504 cak->len = hapd->conf->mka_cak_len; 505 os_memcpy(cak->key, hapd->conf->mka_cak, cak->len); 506 507 ckn->len = hapd->conf->mka_ckn_len;; 508 os_memcpy(ckn->name, hapd->conf->mka_ckn, ckn->len); 509 510 res = ieee802_1x_kay_create_mka(hapd->kay, ckn, cak, 0, PSK, true); 511 if (res) 512 goto free_cak; 513 514 dealloc: 515 /* Failed to create MKA */ 516 ieee802_1x_dealloc_kay_sm_hapd(hapd); 517 free_cak: 518 os_free(cak); 519 free_ckn: 520 os_free(ckn); 521 end: 522 return res; 523 } 524