1# Test cases for MACsec/MKA 2# Copyright (c) 2018-2019, Jouni Malinen <j@w1.fi> 3# 4# This software may be distributed under the terms of the BSD license. 5# See README for more details. 6 7import logging 8logger = logging.getLogger() 9import binascii 10import os 11import signal 12import subprocess 13import time 14 15import hostapd 16from wpasupplicant import WpaSupplicant 17import hwsim_utils 18from utils import HwsimSkip, alloc_fail, fail_test, wait_fail_trigger 19from wlantest import WlantestCapture 20 21def cleanup_macsec(): 22 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5', monitor=False) 23 wpas.interface_remove("veth0") 24 wpas.interface_remove("veth1") 25 del wpas 26 subprocess.call(["ip", "link", "del", "veth0"], 27 stderr=open('/dev/null', 'w')) 28 29def test_macsec_psk(dev, apdev, params): 30 """MACsec PSK""" 31 try: 32 run_macsec_psk(dev, apdev, params, "macsec_psk") 33 finally: 34 cleanup_macsec() 35 36def test_macsec_psk_mka_life_time(dev, apdev, params): 37 """MACsec PSK - MKA life time""" 38 try: 39 run_macsec_psk(dev, apdev, params, "macsec_psk_mka_life_time") 40 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5', monitor=False) 41 wpas.interface_remove("veth1") 42 del wpas 43 # Wait for live peer to be removed on veth0 44 time.sleep(6.1) 45 finally: 46 cleanup_macsec() 47 48def test_macsec_psk_integ_only(dev, apdev, params): 49 """MACsec PSK (integrity only)""" 50 try: 51 run_macsec_psk(dev, apdev, params, "macsec_psk_integ_only", 52 integ_only=True) 53 finally: 54 cleanup_macsec() 55 56def test_macsec_psk_port(dev, apdev, params): 57 """MACsec PSK (port)""" 58 try: 59 run_macsec_psk(dev, apdev, params, "macsec_psk_port", 60 port0=65534, port1=65534) 61 finally: 62 cleanup_macsec() 63 64def test_macsec_psk_different_ports(dev, apdev, params): 65 """MACsec PSK (different ports)""" 66 try: 67 run_macsec_psk(dev, apdev, params, "macsec_psk_different_ports", 68 port0=2, port1=3) 69 finally: 70 cleanup_macsec() 71 72def test_macsec_psk_shorter_ckn(dev, apdev, params): 73 """MACsec PSK (shorter CKN)""" 74 try: 75 ckn = "11223344" 76 run_macsec_psk(dev, apdev, params, "macsec_psk_shorter_ckn", 77 ckn0=ckn, ckn1=ckn) 78 finally: 79 cleanup_macsec() 80 81def test_macsec_psk_shorter_ckn2(dev, apdev, params): 82 """MACsec PSK (shorter CKN, unaligned)""" 83 try: 84 ckn = "112233" 85 run_macsec_psk(dev, apdev, params, "macsec_psk_shorter_ckn2", 86 ckn0=ckn, ckn1=ckn) 87 finally: 88 cleanup_macsec() 89 90def test_macsec_psk_ckn_mismatch(dev, apdev, params): 91 """MACsec PSK (CKN mismatch)""" 92 try: 93 ckn0 = "11223344" 94 ckn1 = "1122334455667788" 95 run_macsec_psk(dev, apdev, params, "macsec_psk_ckn_mismatch", 96 ckn0=ckn0, ckn1=ckn1, expect_failure=True) 97 finally: 98 cleanup_macsec() 99 100def test_macsec_psk_cak_mismatch(dev, apdev, params): 101 """MACsec PSK (CAK mismatch)""" 102 try: 103 cak0 = 16*"11" 104 cak1 = 16*"22" 105 run_macsec_psk(dev, apdev, params, "macsec_psk_cak_mismatch", 106 cak0=cak0, cak1=cak1, expect_failure=True) 107 finally: 108 cleanup_macsec() 109 110def test_macsec_psk_256(dev, apdev, params): 111 """MACsec PSK with 256-bit keys""" 112 try: 113 cak = "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" 114 run_macsec_psk(dev, apdev, params, "macsec_psk_256", cak0=cak, cak1=cak) 115 finally: 116 cleanup_macsec() 117 118def test_macsec_gcm_aes_256(dev, apdev, params): 119 """MACsec PSK with GCM-AES-256""" 120 try: 121 cak = "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" 122 run_macsec_psk(dev, apdev, params, "macsec_gcm_aes_256", 123 cak0=cak, cak1=cak, csindex=1) 124 finally: 125 cleanup_macsec() 126 127def set_mka_psk_config(dev, mka_priority=None, integ_only=False, port=None, 128 ckn=None, cak=None, csindex=None): 129 dev.set("eapol_version", "3") 130 dev.set("ap_scan", "0") 131 dev.set("fast_reauth", "1") 132 133 id = dev.add_network() 134 dev.set_network(id, "key_mgmt", "NONE") 135 if cak is None: 136 cak = "000102030405060708090a0b0c0d0e0f" 137 dev.set_network(id, "mka_cak", cak) 138 if ckn is None: 139 ckn = "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" 140 dev.set_network(id, "mka_ckn", ckn) 141 dev.set_network(id, "eapol_flags", "0") 142 dev.set_network(id, "macsec_policy", "1") 143 if integ_only: 144 dev.set_network(id, "macsec_integ_only", "1") 145 if mka_priority is not None: 146 dev.set_network(id, "mka_priority", str(mka_priority)) 147 if port is not None: 148 dev.set_network(id, "macsec_port", str(port)) 149 if csindex is not None: 150 dev.set_network(id, "macsec_csindex", str(csindex)) 151 152 dev.select_network(id) 153 154def set_mka_eap_config(dev, mka_priority=None, integ_only=False, port=None): 155 dev.set("eapol_version", "3") 156 dev.set("ap_scan", "0") 157 dev.set("fast_reauth", "1") 158 159 id = dev.add_network() 160 dev.set_network(id, "key_mgmt", "NONE") 161 dev.set_network(id, "eapol_flags", "0") 162 dev.set_network(id, "macsec_policy", "1") 163 if integ_only: 164 dev.set_network(id, "macsec_integ_only", "1") 165 if mka_priority is not None: 166 dev.set_network(id, "mka_priority", str(mka_priority)) 167 if port is not None: 168 dev.set_network(id, "macsec_port", str(port)) 169 170 dev.set_network(id, "key_mgmt", "IEEE8021X") 171 dev.set_network(id, "eap", "TTLS") 172 dev.set_network_quoted(id, "ca_cert", "auth_serv/ca.pem") 173 dev.set_network_quoted(id, "phase2", "auth=MSCHAPV2") 174 dev.set_network_quoted(id, "anonymous_identity", "ttls") 175 dev.set_network_quoted(id, "identity", "DOMAIN\mschapv2 user") 176 dev.set_network_quoted(id, "password", "password") 177 178 dev.select_network(id) 179 180def log_ip_macsec(): 181 cmd = subprocess.Popen(["ip", "macsec", "show"], 182 stdout=subprocess.PIPE, 183 stderr=open('/dev/null', 'w')) 184 res = cmd.stdout.read().decode() 185 cmd.stdout.close() 186 logger.info("ip macsec:\n" + res) 187 188def log_ip_link(): 189 cmd = subprocess.Popen(["ip", "link", "show"], 190 stdout=subprocess.PIPE) 191 res = cmd.stdout.read().decode() 192 cmd.stdout.close() 193 logger.info("ip link:\n" + res) 194 195def add_veth(): 196 try: 197 subprocess.check_call(["ip", "link", "add", "veth0", "type", "veth", 198 "peer", "name", "veth1"]) 199 except subprocess.CalledProcessError: 200 raise HwsimSkip("veth not supported (kernel CONFIG_VETH)") 201 202def add_wpas_interfaces(count=2): 203 wpa = [] 204 try: 205 for i in range(count): 206 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') 207 wpas.interface_add("veth%d" % i, driver="macsec_linux") 208 wpa.append(wpas) 209 except Exception as e: 210 if "Failed to add a dynamic wpa_supplicant interface" in str(e): 211 raise HwsimSkip("macsec supported (wpa_supplicant CONFIG_MACSEC, CONFIG_DRIVER_MACSEC_LINUX; kernel CONFIG_MACSEC)") 212 raise 213 214 return wpa 215 216def lower_addr(addr1, addr2): 217 a1 = addr1.split(':') 218 a2 = addr2.split(':') 219 for i in range(6): 220 if binascii.unhexlify(a1[i]) < binascii.unhexlify(a2[i]): 221 return True 222 if binascii.unhexlify(a1[i]) > binascii.unhexlify(a2[i]): 223 return False 224 return False 225 226def wait_mka_done(wpa, expect_failure=False, hostapd=False): 227 max_iter = 14 if expect_failure else 40 228 for i in range(max_iter): 229 done = True 230 for w in wpa: 231 secured = w.get_status_field("Secured") 232 live_peers = w.get_status_field("live_peers") 233 peers = int(live_peers) if live_peers else 0 234 if expect_failure and (secured == "Yes" or peers > 0): 235 raise Exception("MKA completed unexpectedly") 236 expect_peers = len(wpa) - 1 237 if hostapd: 238 expect_peers += 1 239 if peers != expect_peers or secured != "Yes": 240 done = False 241 break 242 w.dump_monitor() 243 if done: 244 break 245 time.sleep(0.5) 246 247 if expect_failure: 248 return 249 250 if not done: 251 raise Exception("MKA not completed successfully") 252 253 if hostapd: 254 # TODO: check that hostapd is the key server 255 return 256 257 key_server = None 258 ks_prio = 999 259 for w in wpa: 260 logger.info("%s STATUS:\n%s" % (w.ifname, w.request("STATUS"))) 261 addr = w.get_status_field("address") 262 prio = int(w.get_status_field("Actor Priority")) 263 if key_server is None or prio < ks_prio or \ 264 (prio == ks_prio and lower_addr(addr, ks_addr)): 265 key_server = w 266 ks_addr = addr 267 ks_prio = prio 268 269 logger.info("Expected key server: " + key_server.ifname) 270 if key_server.get_status_field("is_key_server") != "Yes": 271 raise Exception("Expected key server was not elected") 272 for w in wpa: 273 if w != key_server and w.get_status_field("is_key_server") == "Yes": 274 raise Exception("Unexpected key server") 275 276def run_macsec_psk(dev, apdev, params, prefix, integ_only=False, port0=None, 277 port1=None, ckn0=None, ckn1=None, cak0=None, cak1=None, 278 csindex=None, expect_failure=False): 279 add_veth() 280 281 cap_veth0 = os.path.join(params['logdir'], prefix + ".veth0.pcap") 282 cap_veth1 = os.path.join(params['logdir'], prefix + ".veth1.pcap") 283 cap_macsec0 = os.path.join(params['logdir'], prefix + ".macsec0.pcap") 284 cap_macsec1 = os.path.join(params['logdir'], prefix + ".macsec1.pcap") 285 286 for i in range(2): 287 subprocess.check_call(["ip", "link", "set", "dev", "veth%d" % i, "up"]) 288 289 cmd = {} 290 cmd[0] = WlantestCapture('veth0', cap_veth0) 291 cmd[1] = WlantestCapture('veth1', cap_veth1) 292 293 wpa = add_wpas_interfaces() 294 wpas0 = wpa[0] 295 wpas1 = wpa[1] 296 297 set_mka_psk_config(wpas0, integ_only=integ_only, port=port0, ckn=ckn0, 298 cak=cak0, csindex=csindex) 299 set_mka_psk_config(wpas1, mka_priority=100, integ_only=integ_only, 300 port=port1, ckn=ckn1, cak=cak1, csindex=csindex) 301 302 log_ip_macsec() 303 log_ip_link() 304 305 logger.info("wpas0 STATUS:\n" + wpas0.request("STATUS")) 306 logger.info("wpas1 STATUS:\n" + wpas1.request("STATUS")) 307 logger.info("wpas0 STATUS-DRIVER:\n" + wpas0.request("STATUS-DRIVER")) 308 logger.info("wpas1 STATUS-DRIVER:\n" + wpas1.request("STATUS-DRIVER")) 309 macsec_ifname0 = wpas0.get_driver_status_field("parent_ifname") 310 macsec_ifname1 = wpas1.get_driver_status_field("parent_ifname") 311 312 wait_mka_done(wpa, expect_failure=expect_failure) 313 314 if expect_failure: 315 for i in range(len(cmd)): 316 cmd[i].close() 317 return 318 319 cmd[2] = WlantestCapture(macsec_ifname0, cap_macsec0) 320 cmd[3] = WlantestCapture(macsec_ifname1, cap_macsec1) 321 time.sleep(0.5) 322 323 mi0 = wpas0.get_status_field("mi") 324 mi1 = wpas1.get_status_field("mi") 325 sci0 = wpas0.get_status_field("actor_sci") 326 sci1 = wpas1.get_status_field("actor_sci") 327 logger.info("wpas0 MIB:\n" + wpas0.request("MIB")) 328 logger.info("wpas1 MIB:\n" + wpas1.request("MIB")) 329 mib0 = wpas0.get_mib() 330 mib1 = wpas1.get_mib() 331 332 if mib0['ieee8021XKayMkaPeerListMI'] != mi1: 333 raise Exception("Unexpected ieee8021XKayMkaPeerListMI value (0)") 334 if mib0['ieee8021XKayMkaPeerListType'] != "1": 335 raise Exception("Unexpected ieee8021XKayMkaPeerListType value (0)") 336 if mib0['ieee8021XKayMkaPeerListSCI'] != sci1: 337 raise Exception("Unexpected ieee8021XKayMkaPeerListSCI value (0)") 338 if mib1['ieee8021XKayMkaPeerListMI'] != mi0: 339 raise Exception("Unexpected ieee8021XKayMkaPeerListMI value (1)") 340 if mib1['ieee8021XKayMkaPeerListType'] != "1": 341 raise Exception("Unexpected ieee8021XKayMkaPeerListType value (1)") 342 if mib1['ieee8021XKayMkaPeerListSCI'] != sci0: 343 raise Exception("Unexpected ieee8021XKayMkaPeerListSCI value (1)") 344 345 logger.info("wpas0 STATUS:\n" + wpas0.request("STATUS")) 346 logger.info("wpas1 STATUS:\n" + wpas1.request("STATUS")) 347 log_ip_macsec() 348 hwsim_utils.test_connectivity(wpas0, wpas1, 349 ifname1=macsec_ifname0, 350 ifname2=macsec_ifname1, 351 send_len=1400) 352 log_ip_macsec() 353 354 time.sleep(1) 355 for i in range(len(cmd)): 356 cmd[i].close() 357 358def cleanup_macsec_br(count): 359 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5', monitor=False) 360 for i in range(count): 361 wpas.interface_remove("veth%d" % i) 362 subprocess.call(["ip", "link", "del", "veth%d" % i], 363 stderr=open('/dev/null', 'w')) 364 del wpas 365 subprocess.call(["ip", "link", "set", "brveth", "down"]) 366 subprocess.call(["brctl", "delbr", "brveth"]) 367 368def test_macsec_psk_br2(dev, apdev): 369 """MACsec PSK (bridge; 2 devices)""" 370 try: 371 run_macsec_psk_br(dev, apdev, 2, [10, 20]) 372 finally: 373 cleanup_macsec_br(count=2) 374 375def test_macsec_psk_br2_same_prio(dev, apdev): 376 """MACsec PSK (bridge; 2 devices, same mka_priority)""" 377 try: 378 run_macsec_psk_br(dev, apdev, 2, [None, None]) 379 finally: 380 cleanup_macsec_br(count=2) 381 382def test_macsec_psk_br3(dev, apdev): 383 """MACsec PSK (bridge; 3 devices)""" 384 try: 385 run_macsec_psk_br(dev, apdev, 3, [10, 20, 30]) 386 finally: 387 cleanup_macsec_br(count=3) 388 389def test_macsec_psk_br3_same_prio(dev, apdev): 390 """MACsec PSK (bridge; 3 devices, same mka_priority)""" 391 try: 392 run_macsec_psk_br(dev, apdev, 3, [None, None, None]) 393 finally: 394 cleanup_macsec_br(count=3) 395 396def run_macsec_psk_br(dev, apdev, count, mka_priority): 397 subprocess.check_call(["brctl", "addbr", "brveth"]) 398 subprocess.call(["echo 8 > /sys/devices/virtual/net/brveth/bridge/group_fwd_mask"], 399 shell=True) 400 401 try: 402 for i in range(count): 403 subprocess.check_call(["ip", "link", "add", "veth%d" % i, 404 "type", "veth", 405 "peer", "name", "vethbr%d" % i]) 406 subprocess.check_call(["ip", "link", "set", "vethbr%d" % i, "up"]) 407 subprocess.check_call(["brctl", "addif", "brveth", 408 "vethbr%d" % i]) 409 except subprocess.CalledProcessError: 410 raise HwsimSkip("veth not supported (kernel CONFIG_VETH)") 411 412 subprocess.check_call(["ip", "link", "set", "brveth", "up"]) 413 414 log_ip_link() 415 416 wpa = add_wpas_interfaces(count=count) 417 for i in range(count): 418 set_mka_psk_config(wpa[i], mka_priority=mka_priority[i]) 419 wpa[i].dump_monitor() 420 wait_mka_done(wpa) 421 422 macsec_ifname = [] 423 for i in range(count): 424 macsec_ifname.append(wpa[i].get_driver_status_field("parent_ifname")) 425 426 timeout = 2 427 max_tries = 2 if count > 2 else 1 428 success_seen = False 429 failure_seen = False 430 for i in range(1, count): 431 try: 432 hwsim_utils.test_connectivity(wpa[0], wpa[i], 433 ifname1=macsec_ifname[0], 434 ifname2=macsec_ifname[i], 435 send_len=1400, 436 timeout=timeout, max_tries=max_tries) 437 success_seen = True 438 logger.info("Traffic test %d<->%d success" % (0, i)) 439 except: 440 failure_seen = True 441 logger.info("Traffic test %d<->%d failure" % (0, i)) 442 for i in range(2, count): 443 try: 444 hwsim_utils.test_connectivity(wpa[1], wpa[i], 445 ifname1=macsec_ifname[1], 446 ifname2=macsec_ifname[i], 447 send_len=1400, 448 timeout=timeout, max_tries=max_tries) 449 success_seen = True 450 logger.info("Traffic test %d<->%d success" % (1, i)) 451 except: 452 failure_seen = True 453 logger.info("Traffic test %d<->%d failure" % (1, i)) 454 455 if not success_seen: 456 raise Exception("None of the data traffic tests succeeded") 457 458 # Something seems to be failing with three device tests semi-regularly, so 459 # do not report this as a failed test case until the real reason behind 460 # those failures have been determined. 461 if failure_seen: 462 if count < 3: 463 raise Exception("Data traffic test failed") 464 else: 465 logger.info("Data traffic test failed - ignore for now for >= 3 device cases") 466 467 for i in range(count): 468 wpa[i].close_monitor() 469 for i in range(count): 470 wpa[0].close_control() 471 del wpa[0] 472 473def test_macsec_psk_ns(dev, apdev, params): 474 """MACsec PSK (netns)""" 475 try: 476 run_macsec_psk_ns(dev, apdev, params) 477 finally: 478 prefix = "macsec_psk_ns" 479 pidfile = os.path.join(params['logdir'], prefix + ".pid") 480 for i in range(2): 481 was_running = False 482 if os.path.exists(pidfile + str(i)): 483 with open(pidfile + str(i), 'r') as f: 484 pid = int(f.read().strip()) 485 logger.info("wpa_supplicant for wpas%d still running with pid %d - kill it" % (i, pid)) 486 was_running = True 487 os.kill(pid, signal.SIGTERM) 488 if was_running: 489 time.sleep(1) 490 491 subprocess.call(["ip", "netns", "exec", "ns0", 492 "ip", "link", "del", "veth0"], 493 stderr=open('/dev/null', 'w')) 494 subprocess.call(["ip", "link", "del", "veth0"], 495 stderr=open('/dev/null', 'w')) 496 log_ip_link_ns() 497 subprocess.call(["ip", "netns", "delete", "ns0"], 498 stderr=open('/dev/null', 'w')) 499 subprocess.call(["ip", "netns", "delete", "ns1"], 500 stderr=open('/dev/null', 'w')) 501 502def log_ip_macsec_ns(): 503 cmd = subprocess.Popen(["ip", "macsec", "show"], 504 stdout=subprocess.PIPE, 505 stderr=open('/dev/null', 'w')) 506 res = cmd.stdout.read().decode() 507 cmd.stdout.close() 508 logger.info("ip macsec show:\n" + res) 509 510 cmd = subprocess.Popen(["ip", "netns", "exec", "ns0", 511 "ip", "macsec", "show"], 512 stdout=subprocess.PIPE, 513 stderr=open('/dev/null', 'w')) 514 res = cmd.stdout.read().decode() 515 cmd.stdout.close() 516 logger.info("ip macsec show (ns0):\n" + res) 517 518 cmd = subprocess.Popen(["ip", "netns", "exec", "ns1", 519 "ip", "macsec", "show"], 520 stdout=subprocess.PIPE, 521 stderr=open('/dev/null', 'w')) 522 res = cmd.stdout.read().decode() 523 cmd.stdout.close() 524 logger.info("ip macsec show (ns1):\n" + res) 525 526def log_ip_link_ns(): 527 cmd = subprocess.Popen(["ip", "link", "show"], 528 stdout=subprocess.PIPE) 529 res = cmd.stdout.read().decode() 530 cmd.stdout.close() 531 logger.info("ip link:\n" + res) 532 533 cmd = subprocess.Popen(["ip", "netns", "exec", "ns0", 534 "ip", "link", "show"], 535 stdout=subprocess.PIPE, 536 stderr=open('/dev/null', 'w')) 537 res = cmd.stdout.read().decode() 538 cmd.stdout.close() 539 logger.info("ip link show (ns0):\n" + res) 540 541 cmd = subprocess.Popen(["ip", "netns", "exec", "ns1", 542 "ip", "link", "show"], 543 stdout=subprocess.PIPE, 544 stderr=open('/dev/null', 'w')) 545 res = cmd.stdout.read().decode() 546 cmd.stdout.close() 547 logger.info("ip link show (ns1):\n" + res) 548 549def write_conf(conffile, mka_priority=None): 550 with open(conffile, 'w') as f: 551 f.write("ctrl_interface=DIR=/var/run/wpa_supplicant\n") 552 f.write("eapol_version=3\n") 553 f.write("ap_scan=0\n") 554 f.write("fast_reauth=1\n") 555 f.write("network={\n") 556 f.write(" key_mgmt=NONE\n") 557 f.write(" mka_cak=000102030405060708090a0b0c0d0e0f\n") 558 f.write(" mka_ckn=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\n") 559 if mka_priority is not None: 560 f.write(" mka_priority=%d\n" % mka_priority) 561 f.write(" eapol_flags=0\n") 562 f.write(" macsec_policy=1\n") 563 f.write("}\n") 564 565def run_macsec_psk_ns(dev, apdev, params): 566 try: 567 subprocess.check_call(["ip", "link", "add", "veth0", "type", "veth", 568 "peer", "name", "veth1"]) 569 except subprocess.CalledProcessError: 570 raise HwsimSkip("veth not supported (kernel CONFIG_VETH)") 571 572 prefix = "macsec_psk_ns" 573 conffile = os.path.join(params['logdir'], prefix + ".conf") 574 pidfile = os.path.join(params['logdir'], prefix + ".pid") 575 logfile0 = os.path.join(params['logdir'], prefix + ".veth0.log") 576 logfile1 = os.path.join(params['logdir'], prefix + ".veth1.log") 577 cap_veth0 = os.path.join(params['logdir'], prefix + ".veth0.pcap") 578 cap_veth1 = os.path.join(params['logdir'], prefix + ".veth1.pcap") 579 cap_macsec0 = os.path.join(params['logdir'], prefix + ".macsec0.pcap") 580 cap_macsec1 = os.path.join(params['logdir'], prefix + ".macsec1.pcap") 581 582 for i in range(2): 583 try: 584 subprocess.check_call(["ip", "netns", "add", "ns%d" % i]) 585 except subprocess.CalledProcessError: 586 raise HwsimSkip("network namespace not supported (kernel CONFIG_NAMESPACES, CONFIG_NET_NS)") 587 subprocess.check_call(["ip", "link", "set", "veth%d" % i, 588 "netns", "ns%d" %i]) 589 subprocess.check_call(["ip", "netns", "exec", "ns%d" % i, 590 "ip", "link", "set", "dev", "veth%d" % i, 591 "up"]) 592 593 cmd = {} 594 cmd[0] = WlantestCapture('veth0', cap_veth0, netns='ns0') 595 cmd[1] = WlantestCapture('veth1', cap_veth1, netns='ns1') 596 597 write_conf(conffile + '0') 598 write_conf(conffile + '1', mka_priority=100) 599 600 prg = os.path.join(params['logdir'], 601 'alt-wpa_supplicant/wpa_supplicant/wpa_supplicant') 602 if not os.path.exists(prg): 603 prg = '../../wpa_supplicant/wpa_supplicant' 604 605 arg = ["ip", "netns", "exec", "ns0", 606 prg, '-BdddtKW', '-P', pidfile + '0', '-f', logfile0, 607 '-g', '/tmp/wpas-veth0', 608 '-Dmacsec_linux', '-c', conffile + '0', '-i', "veth0"] 609 logger.info("Start wpa_supplicant: " + str(arg)) 610 try: 611 subprocess.check_call(arg) 612 except subprocess.CalledProcessError: 613 raise HwsimSkip("macsec supported (wpa_supplicant CONFIG_MACSEC, CONFIG_DRIVER_MACSEC_LINUX; kernel CONFIG_MACSEC)") 614 615 if os.path.exists("wpa_supplicant-macsec2"): 616 logger.info("Use alternative wpa_supplicant binary for one of the macsec devices") 617 prg = "wpa_supplicant-macsec2" 618 619 arg = ["ip", "netns", "exec", "ns1", 620 prg, '-BdddtKW', '-P', pidfile + '1', '-f', logfile1, 621 '-g', '/tmp/wpas-veth1', 622 '-Dmacsec_linux', '-c', conffile + '1', '-i', "veth1"] 623 logger.info("Start wpa_supplicant: " + str(arg)) 624 subprocess.check_call(arg) 625 626 wpas0 = WpaSupplicant('veth0', '/tmp/wpas-veth0') 627 wpas1 = WpaSupplicant('veth1', '/tmp/wpas-veth1') 628 629 log_ip_macsec_ns() 630 log_ip_link_ns() 631 632 logger.info("wpas0 STATUS:\n" + wpas0.request("STATUS")) 633 logger.info("wpas1 STATUS:\n" + wpas1.request("STATUS")) 634 logger.info("wpas0 STATUS-DRIVER:\n" + wpas0.request("STATUS-DRIVER")) 635 logger.info("wpas1 STATUS-DRIVER:\n" + wpas1.request("STATUS-DRIVER")) 636 637 for i in range(10): 638 macsec_ifname0 = wpas0.get_driver_status_field("parent_ifname") 639 macsec_ifname1 = wpas1.get_driver_status_field("parent_ifname") 640 if "Number of Keys" in wpas0.request("STATUS"): 641 key_tx0 = int(wpas0.get_status_field("Number of Keys Distributed")) 642 key_rx0 = int(wpas0.get_status_field("Number of Keys Received")) 643 else: 644 key_tx0 = 0 645 key_rx0 = 0 646 if "Number of Keys" in wpas1.request("STATUS"): 647 key_tx1 = int(wpas1.get_status_field("Number of Keys Distributed")) 648 key_rx1 = int(wpas1.get_status_field("Number of Keys Received")) 649 else: 650 key_tx1 = 0 651 key_rx1 = 0 652 if key_rx0 > 0 and key_tx1 > 0: 653 break 654 time.sleep(1) 655 656 cmd[2] = WlantestCapture(macsec_ifname0, cap_macsec0, netns='ns0') 657 cmd[3] = WlantestCapture(macsec_ifname1, cap_macsec1, netns='ns0') 658 time.sleep(0.5) 659 660 logger.info("wpas0 STATUS:\n" + wpas0.request("STATUS")) 661 logger.info("wpas1 STATUS:\n" + wpas1.request("STATUS")) 662 log_ip_macsec_ns() 663 hwsim_utils.test_connectivity(wpas0, wpas1, 664 ifname1=macsec_ifname0, 665 ifname2=macsec_ifname1, 666 send_len=1400) 667 log_ip_macsec_ns() 668 669 subprocess.check_call(['ip', 'netns', 'exec', 'ns0', 670 'ip', 'addr', 'add', '192.168.248.17/30', 671 'dev', macsec_ifname0]) 672 subprocess.check_call(['ip', 'netns', 'exec', 'ns1', 673 'ip', 'addr', 'add', '192.168.248.18/30', 674 'dev', macsec_ifname1]) 675 c = subprocess.Popen(['ip', 'netns', 'exec', 'ns0', 676 'ping', '-c', '2', '192.168.248.18'], 677 stdout=subprocess.PIPE) 678 res = c.stdout.read().decode() 679 c.stdout.close() 680 logger.info("ping:\n" + res) 681 if "2 packets transmitted, 2 received" not in res: 682 raise Exception("ping did not work") 683 684 wpas0.close_monitor() 685 wpas0.request("TERMINATE") 686 wpas0.close_control() 687 del wpas0 688 wpas1.close_monitor() 689 wpas1.request("TERMINATE") 690 wpas1.close_control() 691 del wpas1 692 693 time.sleep(1) 694 for i in range(len(cmd)): 695 cmd[i].close() 696 697def test_macsec_psk_fail_cp(dev, apdev): 698 """MACsec PSK local failures in CP state machine""" 699 try: 700 add_veth() 701 wpa = add_wpas_interfaces() 702 set_mka_psk_config(wpa[0]) 703 with alloc_fail(wpa[0], 1, "sm_CP_RECEIVE_Enter"): 704 set_mka_psk_config(wpa[1]) 705 wait_fail_trigger(wpa[0], "GET_ALLOC_FAIL", max_iter=100) 706 707 wait_mka_done(wpa) 708 finally: 709 cleanup_macsec() 710 711def test_macsec_psk_fail_cp2(dev, apdev): 712 """MACsec PSK local failures in CP state machine (2)""" 713 try: 714 add_veth() 715 wpa = add_wpas_interfaces() 716 set_mka_psk_config(wpa[0]) 717 with alloc_fail(wpa[1], 1, "ieee802_1x_cp_sm_init"): 718 set_mka_psk_config(wpa[1]) 719 wait_fail_trigger(wpa[1], "GET_ALLOC_FAIL", max_iter=100) 720 721 wait_mka_done(wpa) 722 finally: 723 cleanup_macsec() 724 725def cleanup_macsec_hostapd(): 726 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5', monitor=False) 727 wpas.interface_remove("veth0") 728 del wpas 729 hapd = hostapd.HostapdGlobal() 730 hapd.remove('veth1') 731 subprocess.call(["ip", "link", "del", "veth0"], 732 stderr=open('/dev/null', 'w')) 733 log_ip_link() 734 735def test_macsec_hostapd_psk(dev, apdev, params): 736 """MACsec PSK with hostapd""" 737 try: 738 run_macsec_hostapd_psk(dev, apdev, params, "macsec_hostapd_psk") 739 finally: 740 cleanup_macsec_hostapd() 741 742def run_macsec_hostapd_psk(dev, apdev, params, prefix, integ_only=False, 743 port0=None, port1=None, ckn0=None, ckn1=None, 744 cak0=None, cak1=None, expect_failure=False): 745 add_veth() 746 747 cap_veth0 = os.path.join(params['logdir'], prefix + ".veth0.pcap") 748 cap_veth1 = os.path.join(params['logdir'], prefix + ".veth1.pcap") 749 cap_macsec0 = os.path.join(params['logdir'], prefix + ".macsec0.pcap") 750 cap_macsec1 = os.path.join(params['logdir'], prefix + ".macsec1.pcap") 751 752 for i in range(2): 753 subprocess.check_call(["ip", "link", "set", "dev", "veth%d" % i, "up"]) 754 755 cmd = {} 756 cmd[0] = WlantestCapture('veth0', cap_veth0) 757 cmd[1] = WlantestCapture('veth1', cap_veth1) 758 759 wpa = add_wpas_interfaces(count=1) 760 wpas0 = wpa[0] 761 762 set_mka_psk_config(wpas0, integ_only=integ_only, port=port0, ckn=ckn0, 763 cak=cak0, mka_priority=100) 764 765 if cak1 is None: 766 cak1 = "000102030405060708090a0b0c0d0e0f" 767 if ckn1 is None: 768 ckn1 = "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" 769 params = {"driver": "macsec_linux", 770 "interface": "veth1", 771 "eapol_version": "3", 772 "mka_cak": cak1, 773 "mka_ckn": ckn1, 774 "macsec_policy": "1", 775 "mka_priority": "1"} 776 if integ_only: 777 params["macsec_integ_only"] = "1" 778 if port1 is not None: 779 params["macsec_port"] = str(port1) 780 apdev = {'ifname': 'veth1'} 781 try: 782 hapd = hostapd.add_ap(apdev, params, driver="macsec_linux") 783 except: 784 raise HwsimSkip("No CONFIG_MACSEC=y in hostapd") 785 786 log_ip_macsec() 787 log_ip_link() 788 789 logger.info("wpas0 STATUS:\n" + wpas0.request("STATUS")) 790 logger.info("wpas0 STATUS-DRIVER:\n" + wpas0.request("STATUS-DRIVER")) 791 792 wait_mka_done(wpa, expect_failure=expect_failure, hostapd=True) 793 log_ip_link() 794 795 if expect_failure: 796 for i in range(len(cmd)): 797 cmd[i].close() 798 return 799 800 macsec_ifname0 = wpas0.get_driver_status_field("parent_ifname") 801 macsec_ifname1 = hapd.get_driver_status_field("parent_ifname") 802 803 cmd[2] = WlantestCapture(macsec_ifname0, cap_macsec0) 804 cmd[3] = WlantestCapture(macsec_ifname1, cap_macsec1) 805 time.sleep(0.5) 806 807 logger.info("wpas0 MIB:\n" + wpas0.request("MIB")) 808 logger.info("wpas0 STATUS:\n" + wpas0.request("STATUS")) 809 log_ip_macsec() 810 hwsim_utils.test_connectivity(wpas0, hapd, 811 ifname1=macsec_ifname0, 812 ifname2=macsec_ifname1, 813 send_len=1400) 814 log_ip_macsec() 815 816 time.sleep(1) 817 for i in range(len(cmd)): 818 cmd[i].close() 819 820def test_macsec_hostapd_eap(dev, apdev, params): 821 """MACsec EAP with hostapd""" 822 try: 823 run_macsec_hostapd_eap(dev, apdev, params, "macsec_hostapd_eap") 824 finally: 825 cleanup_macsec_hostapd() 826 827def run_macsec_hostapd_eap(dev, apdev, params, prefix, integ_only=False, 828 port0=None, port1=None, expect_failure=False): 829 add_veth() 830 831 cap_veth0 = os.path.join(params['logdir'], prefix + ".veth0.pcap") 832 cap_veth1 = os.path.join(params['logdir'], prefix + ".veth1.pcap") 833 cap_macsec0 = os.path.join(params['logdir'], prefix + ".macsec0.pcap") 834 cap_macsec1 = os.path.join(params['logdir'], prefix + ".macsec1.pcap") 835 836 for i in range(2): 837 subprocess.check_call(["ip", "link", "set", "dev", "veth%d" % i, "up"]) 838 839 cmd = {} 840 cmd[0] = WlantestCapture('veth0', cap_veth0) 841 cmd[1] = WlantestCapture('veth1', cap_veth1) 842 843 wpa = add_wpas_interfaces(count=1) 844 wpas0 = wpa[0] 845 846 set_mka_eap_config(wpas0, integ_only=integ_only, port=port0, 847 mka_priority=100) 848 849 params = {"driver": "macsec_linux", 850 "interface": "veth1", 851 "eapol_version": "3", 852 "macsec_policy": "1", 853 "mka_priority": "1", 854 "ieee8021x": "1", 855 "auth_server_addr": "127.0.0.1", 856 "auth_server_port": "1812", 857 "auth_server_shared_secret": "radius", 858 "nas_identifier": "nas.w1.fi"} 859 if integ_only: 860 params["macsec_integ_only"] = "1" 861 if port1 is not None: 862 params["macsec_port"] = str(port1) 863 apdev = {'ifname': 'veth1'} 864 try: 865 hapd = hostapd.add_ap(apdev, params, driver="macsec_linux") 866 except: 867 raise HwsimSkip("No CONFIG_MACSEC=y in hostapd") 868 869 log_ip_macsec() 870 log_ip_link() 871 872 logger.info("wpas0 STATUS:\n" + wpas0.request("STATUS")) 873 logger.info("wpas0 STATUS-DRIVER:\n" + wpas0.request("STATUS-DRIVER")) 874 875 wait_mka_done(wpa, expect_failure=expect_failure, hostapd=True) 876 log_ip_link() 877 878 if expect_failure: 879 for i in range(len(cmd)): 880 cmd[i].close() 881 return 882 883 macsec_ifname0 = wpas0.get_driver_status_field("parent_ifname") 884 macsec_ifname1 = hapd.get_driver_status_field("parent_ifname") 885 886 cmd[2] = WlantestCapture(macsec_ifname0, cap_macsec0) 887 cmd[3] = WlantestCapture(macsec_ifname1, cap_macsec1) 888 time.sleep(0.5) 889 890 logger.info("wpas0 MIB:\n" + wpas0.request("MIB")) 891 logger.info("wpas0 STATUS:\n" + wpas0.request("STATUS")) 892 log_ip_macsec() 893 hwsim_utils.test_connectivity(wpas0, hapd, 894 ifname1=macsec_ifname0, 895 ifname2=macsec_ifname1, 896 send_len=1400) 897 log_ip_macsec() 898 899 time.sleep(1) 900 for i in range(len(cmd)): 901 cmd[i].close() 902