1# EAP protocol tests 2# Copyright (c) 2014-2015, 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 binascii 8import hashlib 9import hmac 10import logging 11logger = logging.getLogger() 12import os 13import select 14import struct 15import threading 16import time 17 18import hostapd 19from utils import * 20from test_ap_eap import check_eap_capa, check_hlr_auc_gw_support, int_eap_server_params 21 22try: 23 import OpenSSL 24 openssl_imported = True 25except ImportError: 26 openssl_imported = False 27 28EAP_CODE_REQUEST = 1 29EAP_CODE_RESPONSE = 2 30EAP_CODE_SUCCESS = 3 31EAP_CODE_FAILURE = 4 32EAP_CODE_INITIATE = 5 33EAP_CODE_FINISH = 6 34 35EAP_TYPE_IDENTITY = 1 36EAP_TYPE_NOTIFICATION = 2 37EAP_TYPE_NAK = 3 38EAP_TYPE_MD5 = 4 39EAP_TYPE_OTP = 5 40EAP_TYPE_GTC = 6 41EAP_TYPE_TLS = 13 42EAP_TYPE_LEAP = 17 43EAP_TYPE_SIM = 18 44EAP_TYPE_TTLS = 21 45EAP_TYPE_AKA = 23 46EAP_TYPE_PEAP = 25 47EAP_TYPE_MSCHAPV2 = 26 48EAP_TYPE_TLV = 33 49EAP_TYPE_TNC = 38 50EAP_TYPE_FAST = 43 51EAP_TYPE_PAX = 46 52EAP_TYPE_PSK = 47 53EAP_TYPE_SAKE = 48 54EAP_TYPE_IKEV2 = 49 55EAP_TYPE_AKA_PRIME = 50 56EAP_TYPE_GPSK = 51 57EAP_TYPE_PWD = 52 58EAP_TYPE_EKE = 53 59EAP_TYPE_EXPANDED = 254 60 61# Type field in EAP-Initiate and EAP-Finish messages 62EAP_ERP_TYPE_REAUTH_START = 1 63EAP_ERP_TYPE_REAUTH = 2 64 65EAP_ERP_TLV_KEYNAME_NAI = 1 66EAP_ERP_TV_RRK_LIFETIME = 2 67EAP_ERP_TV_RMSK_LIFETIME = 3 68EAP_ERP_TLV_DOMAIN_NAME = 4 69EAP_ERP_TLV_CRYPTOSUITES = 5 70EAP_ERP_TLV_AUTHORIZATION_INDICATION = 6 71EAP_ERP_TLV_CALLED_STATION_ID = 128 72EAP_ERP_TLV_CALLING_STATION_ID = 129 73EAP_ERP_TLV_NAS_IDENTIFIER = 130 74EAP_ERP_TLV_NAS_IP_ADDRESS = 131 75EAP_ERP_TLV_NAS_IPV6_ADDRESS = 132 76 77def add_message_authenticator_attr(reply, digest): 78 if digest.startswith(b'0x'): 79 # Work around pyrad tools.py EncodeOctets() functionality that 80 # assumes a binary value that happens to start with "0x" to be 81 # a hex string. 82 digest = b"0x" + binascii.hexlify(digest) 83 reply.AddAttribute("Message-Authenticator", digest) 84 85def build_message_auth(pkt, reply, secret=None): 86 if secret is None: 87 secret = reply.secret 88 hmac_obj = hmac.new(secret, digestmod=hashlib.md5) 89 hmac_obj.update(struct.pack("B", reply.code)) 90 hmac_obj.update(struct.pack("B", reply.id)) 91 92 reply.AddAttribute("Message-Authenticator", 16*b'\x00') 93 attrs = reply._PktEncodeAttributes() 94 95 # Length 96 flen = 4 + 16 + len(attrs) 97 hmac_obj.update(struct.pack(">H", flen)) 98 hmac_obj.update(pkt.authenticator) 99 hmac_obj.update(attrs) 100 del reply[80] 101 add_message_authenticator_attr(reply, hmac_obj.digest()) 102 103def run_pyrad_server(srv, t_stop, eap_handler): 104 srv.RunWithStop(t_stop, eap_handler) 105 106def start_radius_server(eap_handler): 107 try: 108 import pyrad.server 109 import pyrad.packet 110 import pyrad.dictionary 111 except ImportError: 112 raise HwsimSkip("No pyrad modules available") 113 114 class TestServer(pyrad.server.Server): 115 def _HandleAuthPacket(self, pkt): 116 pyrad.server.Server._HandleAuthPacket(self, pkt) 117 eap = b'' 118 for p in pkt[79]: 119 eap += p 120 eap_req = self.eap_handler(self.ctx, eap) 121 reply = self.CreateReplyPacket(pkt) 122 if eap_req: 123 while True: 124 if len(eap_req) > 253: 125 reply.AddAttribute("EAP-Message", eap_req[0:253]) 126 eap_req = eap_req[253:] 127 else: 128 reply.AddAttribute("EAP-Message", eap_req) 129 break 130 else: 131 logger.info("No EAP request available") 132 reply.code = pyrad.packet.AccessChallenge 133 134 # reply attributes 135 build_message_auth(pkt, reply) 136 137 self.SendReplyPacket(pkt.fd, reply) 138 139 def RunWithStop(self, t_stop, eap_handler): 140 self._poll = select.poll() 141 self._fdmap = {} 142 self._PrepareSockets() 143 self.t_stop = t_stop 144 self.eap_handler = eap_handler 145 self.ctx = {} 146 147 while not t_stop.is_set(): 148 for (fd, event) in self._poll.poll(200): 149 if event == select.POLLIN: 150 try: 151 fdo = self._fdmap[fd] 152 self._ProcessInput(fdo) 153 except pyrad.server.ServerPacketError as err: 154 logger.info("pyrad server dropping packet: " + str(err)) 155 except pyrad.packet.PacketError as err: 156 logger.info("pyrad server received invalid packet: " + str(err)) 157 else: 158 logger.error("Unexpected event in pyrad server main loop") 159 160 for fd in self.authfds + self.acctfds: 161 fd.close() 162 163 srv = TestServer(dict=pyrad.dictionary.Dictionary("dictionary.radius"), 164 authport=18138, acctport=18139) 165 srv.hosts["127.0.0.1"] = pyrad.server.RemoteHost("127.0.0.1", 166 b"radius", 167 "localhost") 168 srv.BindToAddress("127.0.0.1") 169 t_stop = threading.Event() 170 t = threading.Thread(target=run_pyrad_server, args=(srv, t_stop, eap_handler)) 171 t.start() 172 173 return {'srv': srv, 'stop': t_stop, 'thread': t} 174 175def stop_radius_server(srv): 176 srv['stop'].set() 177 srv['thread'].join() 178 179def start_ap(ap): 180 params = hostapd.wpa2_eap_params(ssid="eap-test") 181 params['auth_server_port'] = "18138" 182 hapd = hostapd.add_ap(ap, params) 183 return hapd 184 185def test_eap_proto(dev, apdev): 186 """EAP protocol tests""" 187 check_eap_capa(dev[0], "MD5") 188 def eap_handler(ctx, req): 189 logger.info("eap_handler - RX " + binascii.hexlify(req).decode()) 190 if 'num' not in ctx: 191 ctx['num'] = 0 192 ctx['num'] = ctx['num'] + 1 193 if 'id' not in ctx: 194 ctx['id'] = 1 195 ctx['id'] = (ctx['id'] + 1) % 256 196 idx = 0 197 198 idx += 1 199 if ctx['num'] == idx: 200 logger.info("Test: MD5 challenge") 201 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 202 4 + 1 + 3, 203 EAP_TYPE_MD5, 204 1, 0xaa, ord('n')) 205 idx += 1 206 if ctx['num'] == idx: 207 logger.info("Test: EAP-Success - id off by 2") 208 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'] + 1, 4) 209 210 idx += 1 211 if ctx['num'] == idx: 212 logger.info("Test: MD5 challenge") 213 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 214 4 + 1 + 3, 215 EAP_TYPE_MD5, 216 1, 0xaa, ord('n')) 217 idx += 1 218 if ctx['num'] == idx: 219 logger.info("Test: EAP-Success - id off by 3") 220 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'] + 2, 4) 221 222 idx += 1 223 if ctx['num'] == idx: 224 logger.info("Test: MD5 challenge") 225 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 226 4 + 1 + 3, 227 EAP_TYPE_MD5, 228 1, 0xaa, ord('n')) 229 idx += 1 230 if ctx['num'] == idx: 231 logger.info("Test: EAP-Notification/Request") 232 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 233 4 + 1 + 1, 234 EAP_TYPE_NOTIFICATION, 235 ord('A')) 236 idx += 1 237 if ctx['num'] == idx: 238 logger.info("Test: EAP-Success") 239 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'] - 1, 4) 240 241 idx += 1 242 if ctx['num'] == idx: 243 logger.info("Test: EAP-Notification/Request") 244 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 245 4 + 1 + 1, 246 EAP_TYPE_NOTIFICATION, 247 ord('B')) 248 idx += 1 249 if ctx['num'] == idx: 250 logger.info("Test: MD5 challenge") 251 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 252 4 + 1 + 3, 253 EAP_TYPE_MD5, 254 1, 0xaa, ord('n')) 255 idx += 1 256 if ctx['num'] == idx: 257 logger.info("Test: EAP-Success") 258 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'] - 1, 4) 259 260 idx += 1 261 if ctx['num'] == idx: 262 logger.info("Test: EAP-Notification/Request") 263 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 264 4 + 1 + 1, 265 EAP_TYPE_NOTIFICATION, 266 ord('C')) 267 idx += 1 268 if ctx['num'] == idx: 269 logger.info("Test: MD5 challenge") 270 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 271 4 + 1 + 3, 272 EAP_TYPE_MD5, 273 1, 0xaa, ord('n')) 274 idx += 1 275 if ctx['num'] == idx: 276 logger.info("Test: EAP-Notification/Request") 277 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 278 4 + 1 + 1, 279 EAP_TYPE_NOTIFICATION, 280 ord('D')) 281 idx += 1 282 if ctx['num'] == idx: 283 logger.info("Test: EAP-Success") 284 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'] - 1, 4) 285 286 idx += 1 287 if ctx['num'] == idx: 288 logger.info("Test: EAP-Notification/Request") 289 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 290 4 + 1 + 1, 291 EAP_TYPE_NOTIFICATION, 292 ord('E')) 293 idx += 1 294 if ctx['num'] == idx: 295 logger.info("Test: EAP-Notification/Request (same id)") 296 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'] - 1, 297 4 + 1 + 1, 298 EAP_TYPE_NOTIFICATION, 299 ord('F')) 300 idx += 1 301 if ctx['num'] == idx: 302 logger.info("Test: Unexpected EAP-Success") 303 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'] - 2, 4) 304 305 return None 306 307 srv = start_radius_server(eap_handler) 308 309 try: 310 hapd = start_ap(apdev[0]) 311 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 312 313 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 314 eap="MD5", identity="user", password="password", 315 wait_connect=False) 316 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15) 317 if ev is None: 318 raise Exception("Timeout on EAP start") 319 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15) 320 if ev is None: 321 raise Exception("Timeout on EAP success") 322 dev[0].request("REMOVE_NETWORK all") 323 324 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 325 eap="MD5", identity="user", password="password", 326 wait_connect=False) 327 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15) 328 if ev is None: 329 raise Exception("Timeout on EAP start") 330 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=1) 331 if ev is not None: 332 raise Exception("Unexpected EAP success") 333 dev[0].request("REMOVE_NETWORK all") 334 335 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 336 eap="MD5", identity="user", password="password", 337 wait_connect=False) 338 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15) 339 if ev is None: 340 raise Exception("Timeout on EAP start") 341 ev = dev[0].wait_event(["CTRL-EVENT-EAP-NOTIFICATION"], timeout=10) 342 if ev is None: 343 raise Exception("Timeout on EAP notification") 344 if ev != "<3>CTRL-EVENT-EAP-NOTIFICATION A": 345 raise Exception("Unexpected notification contents: " + ev) 346 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15) 347 if ev is None: 348 raise Exception("Timeout on EAP success") 349 dev[0].request("REMOVE_NETWORK all") 350 351 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 352 eap="MD5", identity="user", password="password", 353 wait_connect=False) 354 ev = dev[0].wait_event(["CTRL-EVENT-EAP-NOTIFICATION"], timeout=10) 355 if ev is None: 356 raise Exception("Timeout on EAP notification") 357 if ev != "<3>CTRL-EVENT-EAP-NOTIFICATION B": 358 raise Exception("Unexpected notification contents: " + ev) 359 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15) 360 if ev is None: 361 raise Exception("Timeout on EAP start") 362 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15) 363 if ev is None: 364 raise Exception("Timeout on EAP success") 365 dev[0].request("REMOVE_NETWORK all") 366 367 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 368 eap="MD5", identity="user", password="password", 369 wait_connect=False) 370 ev = dev[0].wait_event(["CTRL-EVENT-EAP-NOTIFICATION"], timeout=10) 371 if ev is None: 372 raise Exception("Timeout on EAP notification") 373 if ev != "<3>CTRL-EVENT-EAP-NOTIFICATION C": 374 raise Exception("Unexpected notification contents: " + ev) 375 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15) 376 if ev is None: 377 raise Exception("Timeout on EAP start") 378 ev = dev[0].wait_event(["CTRL-EVENT-EAP-NOTIFICATION"], timeout=10) 379 if ev is None: 380 raise Exception("Timeout on EAP notification") 381 if ev != "<3>CTRL-EVENT-EAP-NOTIFICATION D": 382 raise Exception("Unexpected notification contents: " + ev) 383 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15) 384 if ev is None: 385 raise Exception("Timeout on EAP success") 386 dev[0].request("REMOVE_NETWORK all") 387 388 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 389 eap="MD5", identity="user", password="password", 390 wait_connect=False) 391 ev = dev[0].wait_event(["CTRL-EVENT-EAP-NOTIFICATION"], timeout=10) 392 if ev is None: 393 raise Exception("Timeout on EAP notification") 394 if ev != "<3>CTRL-EVENT-EAP-NOTIFICATION E": 395 raise Exception("Unexpected notification contents: " + ev) 396 ev = dev[0].wait_event(["CTRL-EVENT-EAP-NOTIFICATION"], timeout=10) 397 if ev is None: 398 raise Exception("Timeout on EAP notification") 399 if ev != "<3>CTRL-EVENT-EAP-NOTIFICATION F": 400 raise Exception("Unexpected notification contents: " + ev) 401 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=15) 402 if ev is None: 403 raise Exception("Timeout on EAP failure") 404 dev[0].request("REMOVE_NETWORK all") 405 finally: 406 stop_radius_server(srv) 407 408def test_eap_proto_notification_errors(dev, apdev): 409 """EAP Notification errors""" 410 def eap_handler(ctx, req): 411 logger.info("eap_handler - RX " + binascii.hexlify(req).decode()) 412 if 'num' not in ctx: 413 ctx['num'] = 0 414 ctx['num'] = ctx['num'] + 1 415 if 'id' not in ctx: 416 ctx['id'] = 1 417 ctx['id'] = (ctx['id'] + 1) % 256 418 idx = 0 419 420 idx += 1 421 if ctx['num'] == idx: 422 logger.info("Test: MD5 challenge") 423 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 424 4 + 1 + 3, 425 EAP_TYPE_MD5, 426 1, 0xaa, ord('n')) 427 idx += 1 428 if ctx['num'] == idx: 429 logger.info("Test: EAP-Notification/Request") 430 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 431 4 + 1 + 1, 432 EAP_TYPE_NOTIFICATION, 433 ord('A')) 434 435 idx += 1 436 if ctx['num'] == idx: 437 logger.info("Test: MD5 challenge") 438 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 439 4 + 1 + 3, 440 EAP_TYPE_MD5, 441 1, 0xaa, ord('n')) 442 idx += 1 443 if ctx['num'] == idx: 444 logger.info("Test: EAP-Notification/Request") 445 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 446 4 + 1 + 1, 447 EAP_TYPE_NOTIFICATION, 448 ord('A')) 449 450 return None 451 452 srv = start_radius_server(eap_handler) 453 454 try: 455 hapd = start_ap(apdev[0]) 456 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 457 458 with alloc_fail(dev[0], 1, "eap_sm_processNotify"): 459 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 460 eap="MD5", identity="user", password="password", 461 wait_connect=False) 462 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 463 dev[0].request("REMOVE_NETWORK all") 464 dev[0].wait_disconnected() 465 466 with alloc_fail(dev[0], 1, "eap_msg_alloc;sm_EAP_NOTIFICATION_Enter"): 467 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 468 eap="MD5", identity="user", password="password", 469 wait_connect=False) 470 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 471 dev[0].request("REMOVE_NETWORK all") 472 dev[0].wait_disconnected() 473 finally: 474 stop_radius_server(srv) 475 476EAP_SAKE_VERSION = 2 477 478EAP_SAKE_SUBTYPE_CHALLENGE = 1 479EAP_SAKE_SUBTYPE_CONFIRM = 2 480EAP_SAKE_SUBTYPE_AUTH_REJECT = 3 481EAP_SAKE_SUBTYPE_IDENTITY = 4 482 483EAP_SAKE_AT_RAND_S = 1 484EAP_SAKE_AT_RAND_P = 2 485EAP_SAKE_AT_MIC_S = 3 486EAP_SAKE_AT_MIC_P = 4 487EAP_SAKE_AT_SERVERID = 5 488EAP_SAKE_AT_PEERID = 6 489EAP_SAKE_AT_SPI_S = 7 490EAP_SAKE_AT_SPI_P = 8 491EAP_SAKE_AT_ANY_ID_REQ = 9 492EAP_SAKE_AT_PERM_ID_REQ = 10 493EAP_SAKE_AT_ENCR_DATA = 128 494EAP_SAKE_AT_IV = 129 495EAP_SAKE_AT_PADDING = 130 496EAP_SAKE_AT_NEXT_TMPID = 131 497EAP_SAKE_AT_MSK_LIFE = 132 498 499def test_eap_proto_sake(dev, apdev): 500 """EAP-SAKE protocol tests""" 501 global eap_proto_sake_test_done 502 eap_proto_sake_test_done = False 503 504 def sake_challenge(ctx): 505 logger.info("Test: Challenge subtype") 506 return struct.pack(">BBHBBBBBBLLLL", EAP_CODE_REQUEST, ctx['id'], 507 4 + 1 + 3 + 18, 508 EAP_TYPE_SAKE, 509 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_CHALLENGE, 510 EAP_SAKE_AT_RAND_S, 18, 0, 0, 0, 0) 511 512 def sake_handler(ctx, req): 513 logger.info("sake_handler - RX " + binascii.hexlify(req).decode()) 514 if 'num' not in ctx: 515 ctx['num'] = 0 516 ctx['num'] += 1 517 if 'id' not in ctx: 518 ctx['id'] = 1 519 ctx['id'] = (ctx['id'] + 1) % 256 520 idx = 0 521 522 idx += 1 523 if ctx['num'] == idx: 524 logger.info("Test: Missing payload") 525 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 4 + 1, 526 EAP_TYPE_SAKE) 527 528 idx += 1 529 if ctx['num'] == idx: 530 logger.info("Test: Identity subtype without any attributes") 531 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 532 4 + 1 + 3, 533 EAP_TYPE_SAKE, 534 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_IDENTITY) 535 536 idx += 1 537 if ctx['num'] == idx: 538 logger.info("Test: Identity subtype") 539 return struct.pack(">BBHBBBBBBH", EAP_CODE_REQUEST, ctx['id'], 540 4 + 1 + 3 + 4, 541 EAP_TYPE_SAKE, 542 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_IDENTITY, 543 EAP_SAKE_AT_ANY_ID_REQ, 4, 0) 544 idx += 1 545 if ctx['num'] == idx: 546 logger.info("Test: Identity subtype (different session id)") 547 return struct.pack(">BBHBBBBBBH", EAP_CODE_REQUEST, ctx['id'], 548 4 + 1 + 3 + 4, 549 EAP_TYPE_SAKE, 550 EAP_SAKE_VERSION, 1, EAP_SAKE_SUBTYPE_IDENTITY, 551 EAP_SAKE_AT_PERM_ID_REQ, 4, 0) 552 553 idx += 1 554 if ctx['num'] == idx: 555 logger.info("Test: Identity subtype with too short attribute") 556 return struct.pack(">BBHBBBBBB", EAP_CODE_REQUEST, ctx['id'], 557 4 + 1 + 3 + 2, 558 EAP_TYPE_SAKE, 559 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_IDENTITY, 560 EAP_SAKE_AT_ANY_ID_REQ, 2) 561 562 idx += 1 563 if ctx['num'] == idx: 564 logger.info("Test: Identity subtype with truncated attribute") 565 return struct.pack(">BBHBBBBBB", EAP_CODE_REQUEST, ctx['id'], 566 4 + 1 + 3 + 2, 567 EAP_TYPE_SAKE, 568 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_IDENTITY, 569 EAP_SAKE_AT_ANY_ID_REQ, 4) 570 571 idx += 1 572 if ctx['num'] == idx: 573 logger.info("Test: Identity subtype with too short attribute header") 574 payload = struct.pack("B", EAP_SAKE_AT_ANY_ID_REQ) 575 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 576 4 + 1 + 3 + len(payload), 577 EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0, 578 EAP_SAKE_SUBTYPE_IDENTITY) + payload 579 580 idx += 1 581 if ctx['num'] == idx: 582 logger.info("Test: Identity subtype with AT_IV but not AT_ENCR_DATA") 583 payload = struct.pack("BB", EAP_SAKE_AT_IV, 2) 584 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 585 4 + 1 + 3 + len(payload), 586 EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0, 587 EAP_SAKE_SUBTYPE_IDENTITY) + payload 588 589 idx += 1 590 if ctx['num'] == idx: 591 logger.info("Test: Identity subtype with skippable and non-skippable unknown attribute") 592 payload = struct.pack("BBBB", 255, 2, 127, 2) 593 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 594 4 + 1 + 3 + len(payload), 595 EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0, 596 EAP_SAKE_SUBTYPE_IDENTITY) + payload 597 598 idx += 1 599 if ctx['num'] == idx: 600 logger.info("Test: Identity subtype: AT_RAND_P with invalid payload length") 601 payload = struct.pack("BB", EAP_SAKE_AT_RAND_P, 2) 602 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 603 4 + 1 + 3 + len(payload), 604 EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0, 605 EAP_SAKE_SUBTYPE_IDENTITY) + payload 606 607 idx += 1 608 if ctx['num'] == idx: 609 logger.info("Test: Identity subtype: AT_MIC_P with invalid payload length") 610 payload = struct.pack("BB", EAP_SAKE_AT_MIC_P, 2) 611 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 612 4 + 1 + 3 + len(payload), 613 EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0, 614 EAP_SAKE_SUBTYPE_IDENTITY) + payload 615 616 idx += 1 617 if ctx['num'] == idx: 618 logger.info("Test: Identity subtype: AT_PERM_ID_REQ with invalid payload length") 619 payload = struct.pack("BBBBBBBBBBBBBB", 620 EAP_SAKE_AT_SPI_S, 2, 621 EAP_SAKE_AT_SPI_P, 2, 622 EAP_SAKE_AT_ENCR_DATA, 2, 623 EAP_SAKE_AT_NEXT_TMPID, 2, 624 EAP_SAKE_AT_PERM_ID_REQ, 4, 0, 0, 625 EAP_SAKE_AT_PERM_ID_REQ, 2) 626 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 627 4 + 1 + 3 + len(payload), 628 EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0, 629 EAP_SAKE_SUBTYPE_IDENTITY) + payload 630 631 idx += 1 632 if ctx['num'] == idx: 633 logger.info("Test: Identity subtype: AT_PADDING") 634 payload = struct.pack("BBBBBB", 635 EAP_SAKE_AT_PADDING, 3, 0, 636 EAP_SAKE_AT_PADDING, 3, 1) 637 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 638 4 + 1 + 3 + len(payload), 639 EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0, 640 EAP_SAKE_SUBTYPE_IDENTITY) + payload 641 642 idx += 1 643 if ctx['num'] == idx: 644 logger.info("Test: Identity subtype: AT_MSK_LIFE") 645 payload = struct.pack(">BBLBBH", 646 EAP_SAKE_AT_MSK_LIFE, 6, 0, 647 EAP_SAKE_AT_MSK_LIFE, 4, 0) 648 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 649 4 + 1 + 3 + len(payload), 650 EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0, 651 EAP_SAKE_SUBTYPE_IDENTITY) + payload 652 653 idx += 1 654 if ctx['num'] == idx: 655 logger.info("Test: Identity subtype with invalid attribute length") 656 payload = struct.pack("BB", EAP_SAKE_AT_ANY_ID_REQ, 0) 657 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 658 4 + 1 + 3 + len(payload), 659 EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0, 660 EAP_SAKE_SUBTYPE_IDENTITY) + payload 661 662 idx += 1 663 if ctx['num'] == idx: 664 logger.info("Test: Unknown subtype") 665 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 666 4 + 1 + 3, 667 EAP_TYPE_SAKE, 668 EAP_SAKE_VERSION, 0, 123) 669 670 idx += 1 671 if ctx['num'] == idx: 672 logger.info("Test: Challenge subtype without any attributes") 673 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 674 4 + 1 + 3, 675 EAP_TYPE_SAKE, 676 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_CHALLENGE) 677 678 idx += 1 679 if ctx['num'] == idx: 680 logger.info("Test: Challenge subtype with too short AT_RAND_S") 681 return struct.pack(">BBHBBBBBB", EAP_CODE_REQUEST, ctx['id'], 682 4 + 1 + 3 + 2, 683 EAP_TYPE_SAKE, 684 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_CHALLENGE, 685 EAP_SAKE_AT_RAND_S, 2) 686 687 idx += 1 688 if ctx['num'] == idx: 689 return sake_challenge(ctx) 690 idx += 1 691 if ctx['num'] == idx: 692 logger.info("Test: Unexpected Identity subtype") 693 return struct.pack(">BBHBBBBBBH", EAP_CODE_REQUEST, ctx['id'], 694 4 + 1 + 3 + 4, 695 EAP_TYPE_SAKE, 696 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_IDENTITY, 697 EAP_SAKE_AT_ANY_ID_REQ, 4, 0) 698 699 idx += 1 700 if ctx['num'] == idx: 701 return sake_challenge(ctx) 702 idx += 1 703 if ctx['num'] == idx: 704 logger.info("Test: Unexpected Challenge subtype") 705 return struct.pack(">BBHBBBBBBLLLL", EAP_CODE_REQUEST, ctx['id'], 706 4 + 1 + 3 + 18, 707 EAP_TYPE_SAKE, 708 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_CHALLENGE, 709 EAP_SAKE_AT_RAND_S, 18, 0, 0, 0, 0) 710 711 idx += 1 712 if ctx['num'] == idx: 713 return sake_challenge(ctx) 714 idx += 1 715 if ctx['num'] == idx: 716 logger.info("Test: Confirm subtype without any attributes") 717 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 718 4 + 1 + 3, 719 EAP_TYPE_SAKE, 720 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_CONFIRM) 721 722 idx += 1 723 if ctx['num'] == idx: 724 return sake_challenge(ctx) 725 idx += 1 726 if ctx['num'] == idx: 727 logger.info("Test: Confirm subtype with too short AT_MIC_S") 728 return struct.pack(">BBHBBBBBB", EAP_CODE_REQUEST, ctx['id'], 729 4 + 1 + 3 + 2, 730 EAP_TYPE_SAKE, 731 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_CONFIRM, 732 EAP_SAKE_AT_MIC_S, 2) 733 734 idx += 1 735 if ctx['num'] == idx: 736 logger.info("Test: Unexpected Confirm subtype") 737 return struct.pack(">BBHBBBBBBLLLL", EAP_CODE_REQUEST, ctx['id'], 738 4 + 1 + 3 + 18, 739 EAP_TYPE_SAKE, 740 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_CONFIRM, 741 EAP_SAKE_AT_MIC_S, 18, 0, 0, 0, 0) 742 743 idx += 1 744 if ctx['num'] == idx: 745 return sake_challenge(ctx) 746 idx += 1 747 if ctx['num'] == idx: 748 logger.info("Test: Confirm subtype with incorrect AT_MIC_S") 749 return struct.pack(">BBHBBBBBBLLLL", EAP_CODE_REQUEST, ctx['id'], 750 4 + 1 + 3 + 18, 751 EAP_TYPE_SAKE, 752 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_CONFIRM, 753 EAP_SAKE_AT_MIC_S, 18, 0, 0, 0, 0) 754 755 global eap_proto_sake_test_done 756 if eap_proto_sake_test_done: 757 return sake_challenge(ctx) 758 759 logger.info("No more test responses available - test case completed") 760 eap_proto_sake_test_done = True 761 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 762 763 srv = start_radius_server(sake_handler) 764 765 try: 766 hapd = start_ap(apdev[0]) 767 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 768 769 while not eap_proto_sake_test_done: 770 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 771 eap="SAKE", identity="sake user", 772 password_hex="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", 773 wait_connect=False) 774 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15) 775 if ev is None: 776 raise Exception("Timeout on EAP start") 777 time.sleep(0.1) 778 dev[0].request("REMOVE_NETWORK all") 779 dev[0].dump_monitor() 780 781 logger.info("Too short password") 782 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 783 eap="SAKE", identity="sake user", 784 password_hex="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcd", 785 wait_connect=False) 786 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15) 787 if ev is None: 788 raise Exception("Timeout on EAP start") 789 start = os.times()[4] 790 while True: 791 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 792 timeout=0.1) 793 if ev is None: 794 break 795 now = os.times()[4] 796 if now - start > 0.1: 797 break 798 dev[0].dump_monitor() 799 800 dev[0].request("REMOVE_NETWORK all") 801 time.sleep(0.1) 802 dev[0].dump_monitor() 803 finally: 804 stop_radius_server(srv) 805 806def test_eap_proto_sake_errors(dev, apdev): 807 """EAP-SAKE local error cases""" 808 check_eap_capa(dev[0], "SAKE") 809 params = hostapd.wpa2_eap_params(ssid="eap-test") 810 hapd = hostapd.add_ap(apdev[0], params) 811 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 812 813 for i in range(1, 3): 814 with alloc_fail(dev[0], i, "eap_sake_init"): 815 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 816 eap="SAKE", identity="sake user", 817 password_hex="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", 818 wait_connect=False) 819 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"], 820 timeout=15) 821 if ev is None: 822 raise Exception("Timeout on EAP start") 823 dev[0].request("REMOVE_NETWORK all") 824 dev[0].wait_disconnected() 825 dev[0].dump_monitor() 826 827 tests = [(1, "eap_msg_alloc;eap_sake_build_msg;eap_sake_process_challenge"), 828 (1, "=eap_sake_process_challenge"), 829 (1, "eap_sake_compute_mic;eap_sake_process_challenge"), 830 (1, "eap_sake_build_msg;eap_sake_process_confirm"), 831 (1, "eap_sake_compute_mic;eap_sake_process_confirm"), 832 (2, "eap_sake_compute_mic"), 833 (3, "eap_sake_compute_mic"), 834 (1, "eap_sake_getKey"), 835 (1, "eap_sake_get_emsk"), 836 (1, "eap_sake_get_session_id")] 837 for count, func in tests: 838 with alloc_fail(dev[0], count, func): 839 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 840 eap="SAKE", identity="sake user@domain", 841 password_hex="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", 842 erp="1", 843 wait_connect=False) 844 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 845 timeout=15) 846 if ev is None: 847 raise Exception("Timeout on EAP start") 848 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 849 dev[0].request("REMOVE_NETWORK all") 850 dev[0].wait_disconnected() 851 dev[0].dump_monitor() 852 853 tests = [(1, "os_get_random;eap_sake_process_challenge"), 854 (1, "eap_sake_derive_keys;eap_sake_process_challenge"), 855 (2, "eap_sake_derive_keys;eap_sake_process_challenge"), 856 (3, "eap_sake_derive_keys;eap_sake_process_challenge"), 857 (4, "eap_sake_derive_keys;eap_sake_process_challenge"), 858 (5, "eap_sake_derive_keys;eap_sake_process_challenge"), 859 (6, "eap_sake_derive_keys;eap_sake_process_challenge")] 860 for count, func in tests: 861 with fail_test(dev[0], count, func): 862 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 863 eap="SAKE", identity="sake user", 864 password_hex="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", 865 wait_connect=False) 866 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15) 867 if ev is None: 868 raise Exception("Timeout on EAP start") 869 wait_fail_trigger(dev[0], "GET_FAIL") 870 dev[0].request("REMOVE_NETWORK all") 871 dev[0].wait_disconnected() 872 dev[0].dump_monitor() 873 874def test_eap_proto_sake_errors2(dev, apdev): 875 """EAP-SAKE protocol tests (2)""" 876 def sake_handler(ctx, req): 877 logger.info("sake_handler - RX " + binascii.hexlify(req).decode()) 878 if 'num' not in ctx: 879 ctx['num'] = 0 880 ctx['num'] += 1 881 if 'id' not in ctx: 882 ctx['id'] = 1 883 ctx['id'] = (ctx['id'] + 1) % 256 884 idx = 0 885 886 idx += 1 887 if ctx['num'] == idx: 888 logger.info("Test: Identity subtype") 889 return struct.pack(">BBHBBBBBBH", EAP_CODE_REQUEST, ctx['id'], 890 4 + 1 + 3 + 4, 891 EAP_TYPE_SAKE, 892 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_IDENTITY, 893 EAP_SAKE_AT_ANY_ID_REQ, 4, 0) 894 895 srv = start_radius_server(sake_handler) 896 897 try: 898 hapd = start_ap(apdev[0]) 899 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 900 901 with alloc_fail(dev[0], 1, "eap_msg_alloc;eap_sake_build_msg;eap_sake_process_identity"): 902 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 903 eap="SAKE", identity="sake user", 904 password_hex="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", 905 wait_connect=False) 906 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 907 timeout=15) 908 if ev is None: 909 raise Exception("Timeout on EAP start") 910 dev[0].request("REMOVE_NETWORK all") 911 dev[0].wait_disconnected() 912 913 finally: 914 stop_radius_server(srv) 915 916def run_eap_sake_connect(dev): 917 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412", 918 eap="SAKE", identity="sake user", 919 password_hex="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", 920 wait_connect=False) 921 ev = dev.wait_event(["CTRL-EVENT-EAP-SUCCESS", "CTRL-EVENT-EAP-FAILURE", 922 "CTRL-EVENT-DISCONNECTED"], 923 timeout=1) 924 dev.request("REMOVE_NETWORK all") 925 if not ev or "CTRL-EVENT-DISCONNECTED" not in ev: 926 dev.wait_disconnected() 927 dev.dump_monitor() 928 929def test_eap_proto_sake_errors_server(dev, apdev): 930 """EAP-SAKE local error cases on server""" 931 check_eap_capa(dev[0], "SAKE") 932 params = int_eap_server_params() 933 params['erp_domain'] = 'example.com' 934 params['eap_server_erp'] = '1' 935 hapd = hostapd.add_ap(apdev[0], params) 936 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 937 938 tests = [(1, "eap_sake_init"), 939 (1, "eap_sake_build_msg;eap_sake_build_challenge"), 940 (1, "eap_sake_build_msg;eap_sake_build_confirm"), 941 (1, "eap_sake_compute_mic;eap_sake_build_confirm"), 942 (1, "eap_sake_process_challenge"), 943 (1, "eap_sake_getKey"), 944 (1, "eap_sake_get_emsk"), 945 (1, "eap_sake_get_session_id")] 946 for count, func in tests: 947 with alloc_fail(hapd, count, func): 948 run_eap_sake_connect(dev[0]) 949 950 tests = [(1, "eap_sake_init"), 951 (1, "eap_sake_build_challenge"), 952 (1, "eap_sake_build_confirm"), 953 (1, "eap_sake_derive_keys;eap_sake_process_challenge"), 954 (1, "eap_sake_compute_mic;eap_sake_process_challenge"), 955 (1, "eap_sake_compute_mic;eap_sake_process_confirm"), 956 (1, "eap_sake_compute_mic;eap_sake_build_confirm"), 957 (1, "eap_sake_process_confirm")] 958 for count, func in tests: 959 with fail_test(hapd, count, func): 960 run_eap_sake_connect(dev[0]) 961 962def start_sake_assoc(dev, hapd): 963 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412", 964 eap="SAKE", identity="sake user", 965 password_hex="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", 966 wait_connect=False) 967 proxy_msg(hapd, dev) # EAP-Identity/Request 968 proxy_msg(dev, hapd) # EAP-Identity/Response 969 proxy_msg(hapd, dev) # SAKE/Challenge/Request 970 971def stop_sake_assoc(dev, hapd): 972 dev.request("REMOVE_NETWORK all") 973 dev.wait_disconnected() 974 dev.dump_monitor() 975 hapd.dump_monitor() 976 977def test_eap_proto_sake_server(dev, apdev): 978 """EAP-SAKE protocol testing for the server""" 979 check_eap_capa(dev[0], "SAKE") 980 params = int_eap_server_params() 981 params['erp_domain'] = 'example.com' 982 params['eap_server_erp'] = '1' 983 hapd = hostapd.add_ap(apdev[0], params) 984 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 985 hapd.request("SET ext_eapol_frame_io 1") 986 dev[0].request("SET ext_eapol_frame_io 1") 987 988 # Successful exchange to verify proxying mechanism 989 start_sake_assoc(dev[0], hapd) 990 proxy_msg(dev[0], hapd) # SAKE/Challenge/Response 991 proxy_msg(hapd, dev[0]) # SAKE/Confirm/Request 992 proxy_msg(dev[0], hapd) # SAKE/Confirm/Response 993 proxy_msg(hapd, dev[0]) # EAP-Success 994 proxy_msg(hapd, dev[0]) # EAPOL-Key msg 1/4 995 proxy_msg(dev[0], hapd) # EAPOL-Key msg 2/4 996 proxy_msg(hapd, dev[0]) # EAPOL-Key msg 3/4 997 proxy_msg(dev[0], hapd) # EAPOL-Key msg 4/4 998 dev[0].wait_connected() 999 stop_sake_assoc(dev[0], hapd) 1000 1001 start_sake_assoc(dev[0], hapd) 1002 resp = rx_msg(dev[0]) 1003 # Too short EAP-SAKE header 1004 # --> EAP-SAKE: Invalid frame 1005 msg = resp[0:4] + "0007" + resp[8:12] + "0007" + "300200" 1006 tx_msg(dev[0], hapd, msg) 1007 # Unknown version 1008 # --> EAP-SAKE: Unknown version 1 1009 msg = resp[0:4] + "0008" + resp[8:12] + "0008" + "30010000" 1010 tx_msg(dev[0], hapd, msg) 1011 # Unknown session 1012 # --> EAP-SAKE: Session ID mismatch 1013 sess, = struct.unpack('B', binascii.unhexlify(resp[20:22])) 1014 sess = binascii.hexlify(struct.pack('B', (sess + 1) % 256)).decode() 1015 msg = resp[0:4] + "0008" + resp[8:12] + "0008" + "3002" + sess + "00" 1016 tx_msg(dev[0], hapd, msg) 1017 # Unknown subtype 1018 # --> EAP-SAKE: Unexpected subtype=5 in state=1 1019 msg = resp[0:22] + "05" + resp[24:] 1020 tx_msg(dev[0], hapd, msg) 1021 # Empty challenge 1022 # --> EAP-SAKE: Response/Challenge did not include AT_RAND_P or AT_MIC_P 1023 msg = resp[0:4] + "0008" + resp[8:12] + "0008" + resp[16:24] 1024 tx_msg(dev[0], hapd, msg) 1025 rx_msg(hapd) 1026 stop_sake_assoc(dev[0], hapd) 1027 1028 start_sake_assoc(dev[0], hapd) 1029 resp = rx_msg(dev[0]) 1030 # Invalid attribute in challenge 1031 # --> EAP-SAKE: Too short attribute 1032 msg = resp[0:4] + "0009" + resp[8:12] + "0009" + resp[16:26] 1033 tx_msg(dev[0], hapd, msg) 1034 rx_msg(hapd) 1035 stop_sake_assoc(dev[0], hapd) 1036 1037 start_sake_assoc(dev[0], hapd) 1038 proxy_msg(dev[0], hapd) # SAKE/Challenge/Response 1039 proxy_msg(hapd, dev[0]) # SAKE/Confirm/Request 1040 resp = rx_msg(dev[0]) 1041 # Empty confirm 1042 # --> EAP-SAKE: Response/Confirm did not include AT_MIC_P 1043 msg = resp[0:4] + "0008" + resp[8:12] + "0008" + resp[16:26] 1044 tx_msg(dev[0], hapd, msg) 1045 rx_msg(hapd) 1046 stop_sake_assoc(dev[0], hapd) 1047 1048 start_sake_assoc(dev[0], hapd) 1049 proxy_msg(dev[0], hapd) # SAKE/Challenge/Response 1050 proxy_msg(hapd, dev[0]) # SAKE/Confirm/Request 1051 resp = rx_msg(dev[0]) 1052 # Invalid attribute in confirm 1053 # --> EAP-SAKE: Too short attribute 1054 msg = resp[0:4] + "0009" + resp[8:12] + "0009" + resp[16:26] 1055 tx_msg(dev[0], hapd, msg) 1056 rx_msg(hapd) 1057 stop_sake_assoc(dev[0], hapd) 1058 1059 start_sake_assoc(dev[0], hapd) 1060 proxy_msg(dev[0], hapd) # SAKE/Challenge/Response 1061 proxy_msg(hapd, dev[0]) # SAKE/Confirm/Request 1062 resp = rx_msg(dev[0]) 1063 # Corrupted AT_MIC_P value 1064 # --> EAP-SAKE: Incorrect AT_MIC_P 1065 msg = resp[0:30] + "000000000000" + resp[42:] 1066 tx_msg(dev[0], hapd, msg) 1067 rx_msg(hapd) 1068 stop_sake_assoc(dev[0], hapd) 1069 1070def test_eap_proto_leap(dev, apdev): 1071 """EAP-LEAP protocol tests""" 1072 check_eap_capa(dev[0], "LEAP") 1073 def leap_handler(ctx, req): 1074 logger.info("leap_handler - RX " + binascii.hexlify(req).decode()) 1075 if 'num' not in ctx: 1076 ctx['num'] = 0 1077 ctx['num'] = ctx['num'] + 1 1078 if 'id' not in ctx: 1079 ctx['id'] = 1 1080 ctx['id'] = (ctx['id'] + 1) % 256 1081 1082 if ctx['num'] == 1: 1083 logger.info("Test: Missing payload") 1084 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 1085 4 + 1, 1086 EAP_TYPE_LEAP) 1087 1088 if ctx['num'] == 2: 1089 logger.info("Test: Unexpected version") 1090 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 1091 4 + 1 + 3, 1092 EAP_TYPE_LEAP, 1093 0, 0, 0) 1094 1095 if ctx['num'] == 3: 1096 logger.info("Test: Invalid challenge length") 1097 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 1098 4 + 1 + 3, 1099 EAP_TYPE_LEAP, 1100 1, 0, 0) 1101 1102 if ctx['num'] == 4: 1103 logger.info("Test: Truncated challenge") 1104 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 1105 4 + 1 + 3, 1106 EAP_TYPE_LEAP, 1107 1, 0, 8) 1108 1109 if ctx['num'] == 5: 1110 logger.info("Test: Valid challenge") 1111 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], 1112 4 + 1 + 3 + 8, 1113 EAP_TYPE_LEAP, 1114 1, 0, 8, 0, 0) 1115 if ctx['num'] == 6: 1116 logger.info("Test: Missing payload in Response") 1117 return struct.pack(">BBHB", EAP_CODE_RESPONSE, ctx['id'], 1118 4 + 1, 1119 EAP_TYPE_LEAP) 1120 1121 if ctx['num'] == 7: 1122 logger.info("Test: Valid challenge") 1123 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], 1124 4 + 1 + 3 + 8, 1125 EAP_TYPE_LEAP, 1126 1, 0, 8, 0, 0) 1127 if ctx['num'] == 8: 1128 logger.info("Test: Unexpected version in Response") 1129 return struct.pack(">BBHBBBB", EAP_CODE_RESPONSE, ctx['id'], 1130 4 + 1 + 3, 1131 EAP_TYPE_LEAP, 1132 0, 0, 8) 1133 1134 if ctx['num'] == 9: 1135 logger.info("Test: Valid challenge") 1136 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], 1137 4 + 1 + 3 + 8, 1138 EAP_TYPE_LEAP, 1139 1, 0, 8, 0, 0) 1140 if ctx['num'] == 10: 1141 logger.info("Test: Invalid challenge length in Response") 1142 return struct.pack(">BBHBBBB", EAP_CODE_RESPONSE, ctx['id'], 1143 4 + 1 + 3, 1144 EAP_TYPE_LEAP, 1145 1, 0, 0) 1146 1147 if ctx['num'] == 11: 1148 logger.info("Test: Valid challenge") 1149 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], 1150 4 + 1 + 3 + 8, 1151 EAP_TYPE_LEAP, 1152 1, 0, 8, 0, 0) 1153 if ctx['num'] == 12: 1154 logger.info("Test: Truncated challenge in Response") 1155 return struct.pack(">BBHBBBB", EAP_CODE_RESPONSE, ctx['id'], 1156 4 + 1 + 3, 1157 EAP_TYPE_LEAP, 1158 1, 0, 24) 1159 1160 if ctx['num'] == 13: 1161 logger.info("Test: Valid challenge") 1162 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], 1163 4 + 1 + 3 + 8, 1164 EAP_TYPE_LEAP, 1165 1, 0, 8, 0, 0) 1166 if ctx['num'] == 14: 1167 logger.info("Test: Invalid challange value in Response") 1168 return struct.pack(">BBHBBBB6L", EAP_CODE_RESPONSE, ctx['id'], 1169 4 + 1 + 3 + 24, 1170 EAP_TYPE_LEAP, 1171 1, 0, 24, 1172 0, 0, 0, 0, 0, 0) 1173 1174 if ctx['num'] == 15: 1175 logger.info("Test: Valid challenge") 1176 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], 1177 4 + 1 + 3 + 8, 1178 EAP_TYPE_LEAP, 1179 1, 0, 8, 0, 0) 1180 if ctx['num'] == 16: 1181 logger.info("Test: Valid challange value in Response") 1182 return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'], 1183 4 + 1 + 3 + 24, 1184 EAP_TYPE_LEAP, 1185 1, 0, 24, 1186 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd, 1187 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04, 1188 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66) 1189 1190 if ctx['num'] == 17: 1191 logger.info("Test: Valid challenge") 1192 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], 1193 4 + 1 + 3 + 8, 1194 EAP_TYPE_LEAP, 1195 1, 0, 8, 0, 0) 1196 if ctx['num'] == 18: 1197 logger.info("Test: Success") 1198 return struct.pack(">BBHB", EAP_CODE_SUCCESS, ctx['id'], 1199 4 + 1, 1200 EAP_TYPE_LEAP) 1201 # hostapd will drop the next frame in the sequence 1202 1203 if ctx['num'] == 19: 1204 logger.info("Test: Valid challenge") 1205 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], 1206 4 + 1 + 3 + 8, 1207 EAP_TYPE_LEAP, 1208 1, 0, 8, 0, 0) 1209 if ctx['num'] == 20: 1210 logger.info("Test: Failure") 1211 return struct.pack(">BBHB", EAP_CODE_FAILURE, ctx['id'], 1212 4 + 1, 1213 EAP_TYPE_LEAP) 1214 1215 return None 1216 1217 srv = start_radius_server(leap_handler) 1218 1219 try: 1220 hapd = start_ap(apdev[0]) 1221 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 1222 1223 for i in range(0, 12): 1224 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 1225 eap="LEAP", identity="user", password="password", 1226 wait_connect=False) 1227 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15) 1228 if ev is None: 1229 raise Exception("Timeout on EAP start") 1230 time.sleep(0.1) 1231 if i == 10: 1232 logger.info("Wait for additional roundtrip") 1233 time.sleep(1) 1234 dev[0].request("REMOVE_NETWORK all") 1235 finally: 1236 stop_radius_server(srv) 1237 1238def test_eap_proto_leap_errors(dev, apdev): 1239 """EAP-LEAP protocol tests (error paths)""" 1240 check_eap_capa(dev[0], "LEAP") 1241 1242 def leap_handler2(ctx, req): 1243 logger.info("leap_handler2 - RX " + binascii.hexlify(req).decode()) 1244 if 'num' not in ctx: 1245 ctx['num'] = 0 1246 ctx['num'] = ctx['num'] + 1 1247 if 'id' not in ctx: 1248 ctx['id'] = 1 1249 ctx['id'] = (ctx['id'] + 1) % 256 1250 idx = 0 1251 1252 idx += 1 1253 if ctx['num'] == idx: 1254 logger.info("Test: Valid challenge") 1255 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], 1256 4 + 1 + 3 + 8, 1257 EAP_TYPE_LEAP, 1258 1, 0, 8, 0, 0) 1259 idx += 1 1260 if ctx['num'] == idx: 1261 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 1262 1263 idx += 1 1264 if ctx['num'] == idx: 1265 logger.info("Test: Valid challenge") 1266 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], 1267 4 + 1 + 3 + 8, 1268 EAP_TYPE_LEAP, 1269 1, 0, 8, 0, 0) 1270 1271 idx += 1 1272 if ctx['num'] == idx: 1273 logger.info("Test: Valid challenge") 1274 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], 1275 4 + 1 + 3 + 8, 1276 EAP_TYPE_LEAP, 1277 1, 0, 8, 0, 0) 1278 idx += 1 1279 if ctx['num'] == idx: 1280 logger.info("Test: Success") 1281 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4) 1282 1283 idx += 1 1284 if ctx['num'] == idx: 1285 logger.info("Test: Valid challenge") 1286 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], 1287 4 + 1 + 3 + 8, 1288 EAP_TYPE_LEAP, 1289 1, 0, 8, 0, 0) 1290 idx += 1 1291 if ctx['num'] == idx: 1292 logger.info("Test: Success") 1293 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4) 1294 1295 idx += 1 1296 if ctx['num'] == idx: 1297 logger.info("Test: Valid challenge") 1298 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], 1299 4 + 1 + 3 + 8, 1300 EAP_TYPE_LEAP, 1301 1, 0, 8, 0, 0) 1302 idx += 1 1303 if ctx['num'] == idx: 1304 logger.info("Test: Valid challange value in Response") 1305 return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'], 1306 4 + 1 + 3 + 24, 1307 EAP_TYPE_LEAP, 1308 1, 0, 24, 1309 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd, 1310 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04, 1311 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66) 1312 1313 idx += 1 1314 if ctx['num'] == idx: 1315 logger.info("Test: Valid challenge") 1316 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], 1317 4 + 1 + 3 + 8, 1318 EAP_TYPE_LEAP, 1319 1, 0, 8, 0, 0) 1320 idx += 1 1321 if ctx['num'] == idx: 1322 logger.info("Test: Valid challange value in Response") 1323 return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'], 1324 4 + 1 + 3 + 24, 1325 EAP_TYPE_LEAP, 1326 1, 0, 24, 1327 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd, 1328 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04, 1329 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66) 1330 1331 idx += 1 1332 if ctx['num'] == idx: 1333 logger.info("Test: Valid challenge") 1334 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], 1335 4 + 1 + 3 + 8, 1336 EAP_TYPE_LEAP, 1337 1, 0, 8, 0, 0) 1338 idx += 1 1339 if ctx['num'] == idx: 1340 logger.info("Test: Valid challange value in Response") 1341 return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'], 1342 4 + 1 + 3 + 24, 1343 EAP_TYPE_LEAP, 1344 1, 0, 24, 1345 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd, 1346 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04, 1347 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66) 1348 1349 idx += 1 1350 if ctx['num'] == idx: 1351 logger.info("Test: Valid challenge") 1352 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], 1353 4 + 1 + 3 + 8, 1354 EAP_TYPE_LEAP, 1355 1, 0, 8, 0, 0) 1356 idx += 1 1357 if ctx['num'] == idx: 1358 logger.info("Test: Valid challange value in Response") 1359 return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'], 1360 4 + 1 + 3 + 24, 1361 EAP_TYPE_LEAP, 1362 1, 0, 24, 1363 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd, 1364 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04, 1365 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66) 1366 1367 idx += 1 1368 if ctx['num'] == idx: 1369 logger.info("Test: Valid challenge") 1370 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], 1371 4 + 1 + 3 + 8, 1372 EAP_TYPE_LEAP, 1373 1, 0, 8, 0, 0) 1374 idx += 1 1375 if ctx['num'] == idx: 1376 logger.info("Test: Valid challange value in Response") 1377 return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'], 1378 4 + 1 + 3 + 24, 1379 EAP_TYPE_LEAP, 1380 1, 0, 24, 1381 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd, 1382 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04, 1383 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66) 1384 1385 idx += 1 1386 if ctx['num'] == idx: 1387 logger.info("Test: Valid challenge") 1388 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], 1389 4 + 1 + 3 + 8, 1390 EAP_TYPE_LEAP, 1391 1, 0, 8, 0, 0) 1392 idx += 1 1393 if ctx['num'] == idx: 1394 logger.info("Test: Valid challange value in Response") 1395 return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'], 1396 4 + 1 + 3 + 24, 1397 EAP_TYPE_LEAP, 1398 1, 0, 24, 1399 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd, 1400 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04, 1401 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66) 1402 1403 idx += 1 1404 if ctx['num'] == idx: 1405 logger.info("Test: Valid challenge") 1406 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], 1407 4 + 1 + 3 + 8, 1408 EAP_TYPE_LEAP, 1409 1, 0, 8, 0, 0) 1410 idx += 1 1411 if ctx['num'] == idx: 1412 logger.info("Test: Valid challange value in Response") 1413 return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'], 1414 4 + 1 + 3 + 24, 1415 EAP_TYPE_LEAP, 1416 1, 0, 24, 1417 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd, 1418 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04, 1419 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66) 1420 1421 idx += 1 1422 if ctx['num'] == idx: 1423 logger.info("Test: Valid challenge") 1424 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], 1425 4 + 1 + 3 + 8, 1426 EAP_TYPE_LEAP, 1427 1, 0, 8, 0, 0) 1428 1429 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 1430 1431 srv = start_radius_server(leap_handler2) 1432 1433 try: 1434 hapd = start_ap(apdev[0]) 1435 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 1436 1437 with alloc_fail(dev[0], 1, "eap_leap_init"): 1438 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 1439 eap="LEAP", identity="user", password="password", 1440 wait_connect=False) 1441 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 1442 dev[0].request("REMOVE_NETWORK all") 1443 dev[0].wait_disconnected() 1444 1445 with alloc_fail(dev[0], 1, "eap_msg_alloc;eap_leap_process_request"): 1446 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 1447 eap="LEAP", identity="user", 1448 password_hex="hash:8846f7eaee8fb117ad06bdd830b7586c", 1449 wait_connect=False) 1450 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 1451 dev[0].request("REMOVE_NETWORK all") 1452 dev[0].wait_disconnected() 1453 1454 with alloc_fail(dev[0], 1, "eap_leap_process_success"): 1455 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 1456 eap="LEAP", identity="user", password="password", 1457 wait_connect=False) 1458 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 1459 dev[0].request("REMOVE_NETWORK all") 1460 dev[0].wait_disconnected() 1461 1462 with fail_test(dev[0], 1, "os_get_random;eap_leap_process_success"): 1463 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 1464 eap="LEAP", identity="user", password="password", 1465 wait_connect=False) 1466 wait_fail_trigger(dev[0], "GET_FAIL") 1467 dev[0].request("REMOVE_NETWORK all") 1468 dev[0].wait_disconnected() 1469 1470 with fail_test(dev[0], 1, "eap_leap_process_response"): 1471 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 1472 eap="LEAP", identity="user", 1473 password_hex="hash:8846f7eaee8fb117ad06bdd830b7586c", 1474 wait_connect=False) 1475 wait_fail_trigger(dev[0], "GET_FAIL") 1476 dev[0].request("REMOVE_NETWORK all") 1477 dev[0].wait_disconnected() 1478 1479 with fail_test(dev[0], 1, "nt_password_hash;eap_leap_process_response"): 1480 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 1481 eap="LEAP", identity="user", password="password", 1482 wait_connect=False) 1483 wait_fail_trigger(dev[0], "GET_FAIL") 1484 dev[0].request("REMOVE_NETWORK all") 1485 dev[0].wait_disconnected() 1486 1487 with fail_test(dev[0], 1, "hash_nt_password_hash;eap_leap_process_response"): 1488 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 1489 eap="LEAP", identity="user", password="password", 1490 wait_connect=False) 1491 wait_fail_trigger(dev[0], "GET_FAIL") 1492 dev[0].request("REMOVE_NETWORK all") 1493 dev[0].wait_disconnected() 1494 1495 with alloc_fail(dev[0], 1, "eap_leap_getKey"): 1496 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 1497 eap="LEAP", identity="user", 1498 password_hex="hash:8846f7eaee8fb117ad06bdd830b7586c", 1499 wait_connect=False) 1500 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 1501 dev[0].request("REMOVE_NETWORK all") 1502 dev[0].wait_disconnected() 1503 1504 with fail_test(dev[0], 1, "eap_leap_getKey"): 1505 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 1506 eap="LEAP", identity="user", 1507 password_hex="hash:8846f7eaee8fb117ad06bdd830b7586c", 1508 wait_connect=False) 1509 wait_fail_trigger(dev[0], "GET_FAIL") 1510 dev[0].request("REMOVE_NETWORK all") 1511 dev[0].wait_disconnected() 1512 1513 with fail_test(dev[0], 1, "nt_password_hash;eap_leap_getKey"): 1514 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 1515 eap="LEAP", identity="user", password="password", 1516 wait_connect=False) 1517 wait_fail_trigger(dev[0], "GET_FAIL") 1518 dev[0].request("REMOVE_NETWORK all") 1519 dev[0].wait_disconnected() 1520 1521 with fail_test(dev[0], 1, "hash_nt_password_hash;eap_leap_getKey"): 1522 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 1523 eap="LEAP", identity="user", password="password", 1524 wait_connect=False) 1525 wait_fail_trigger(dev[0], "GET_FAIL") 1526 dev[0].request("REMOVE_NETWORK all") 1527 dev[0].wait_disconnected() 1528 1529 with fail_test(dev[0], 1, 1530 "nt_challenge_response;eap_leap_process_request"): 1531 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 1532 eap="LEAP", identity="user", password="password", 1533 wait_connect=False) 1534 wait_fail_trigger(dev[0], "GET_FAIL") 1535 dev[0].request("REMOVE_NETWORK all") 1536 dev[0].wait_disconnected() 1537 finally: 1538 stop_radius_server(srv) 1539 1540def test_eap_proto_md5(dev, apdev): 1541 """EAP-MD5 protocol tests""" 1542 check_eap_capa(dev[0], "MD5") 1543 1544 def md5_handler(ctx, req): 1545 logger.info("md5_handler - RX " + binascii.hexlify(req).decode()) 1546 if 'num' not in ctx: 1547 ctx['num'] = 0 1548 ctx['num'] = ctx['num'] + 1 1549 if 'id' not in ctx: 1550 ctx['id'] = 1 1551 ctx['id'] = (ctx['id'] + 1) % 256 1552 1553 if ctx['num'] == 1: 1554 logger.info("Test: Missing payload") 1555 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 1556 4 + 1, 1557 EAP_TYPE_MD5) 1558 1559 if ctx['num'] == 2: 1560 logger.info("Test: Zero-length challenge") 1561 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 1562 4 + 1 + 1, 1563 EAP_TYPE_MD5, 1564 0) 1565 1566 if ctx['num'] == 3: 1567 logger.info("Test: Truncated challenge") 1568 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 1569 4 + 1 + 1, 1570 EAP_TYPE_MD5, 1571 1) 1572 1573 if ctx['num'] == 4: 1574 logger.info("Test: Shortest possible challenge and name") 1575 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 1576 4 + 1 + 3, 1577 EAP_TYPE_MD5, 1578 1, 0xaa, ord('n')) 1579 1580 return None 1581 1582 srv = start_radius_server(md5_handler) 1583 1584 try: 1585 hapd = start_ap(apdev[0]) 1586 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 1587 1588 for i in range(0, 4): 1589 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 1590 eap="MD5", identity="user", password="password", 1591 wait_connect=False) 1592 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15) 1593 if ev is None: 1594 raise Exception("Timeout on EAP start") 1595 time.sleep(0.1) 1596 dev[0].request("REMOVE_NETWORK all") 1597 finally: 1598 stop_radius_server(srv) 1599 1600def test_eap_proto_md5_errors(dev, apdev): 1601 """EAP-MD5 local error cases""" 1602 check_eap_capa(dev[0], "MD5") 1603 params = hostapd.wpa2_eap_params(ssid="eap-test") 1604 hapd = hostapd.add_ap(apdev[0], params) 1605 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 1606 1607 with fail_test(dev[0], 1, "chap_md5"): 1608 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 1609 eap="MD5", identity="phase1-user", password="password", 1610 wait_connect=False) 1611 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=15) 1612 if ev is None: 1613 raise Exception("Timeout on EAP start") 1614 dev[0].request("REMOVE_NETWORK all") 1615 dev[0].wait_disconnected() 1616 1617 with alloc_fail(dev[0], 1, "eap_msg_alloc;eap_md5_process"): 1618 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 1619 eap="MD5", identity="phase1-user", password="password", 1620 wait_connect=False) 1621 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=15) 1622 if ev is None: 1623 raise Exception("Timeout on EAP start") 1624 time.sleep(0.1) 1625 dev[0].request("REMOVE_NETWORK all") 1626 1627def run_eap_md5_connect(dev): 1628 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412", 1629 eap="MD5", identity="phase1-user", password="password", 1630 wait_connect=False) 1631 ev = dev.wait_event(["CTRL-EVENT-EAP-SUCCESS", "CTRL-EVENT-EAP-FAILURE", 1632 "CTRL-EVENT-DISCONNECTED"], 1633 timeout=1) 1634 dev.request("REMOVE_NETWORK all") 1635 if not ev or "CTRL-EVENT-DISCONNECTED" not in ev: 1636 dev.wait_disconnected() 1637 dev.dump_monitor() 1638 1639def test_eap_proto_md5_errors_server(dev, apdev): 1640 """EAP-MD5 local error cases on server""" 1641 check_eap_capa(dev[0], "MD5") 1642 params = int_eap_server_params() 1643 params['erp_domain'] = 'example.com' 1644 params['eap_server_erp'] = '1' 1645 hapd = hostapd.add_ap(apdev[0], params) 1646 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 1647 1648 tests = [(1, "eap_md5_init")] 1649 for count, func in tests: 1650 with alloc_fail(hapd, count, func): 1651 run_eap_md5_connect(dev[0]) 1652 1653 tests = [(1, "os_get_random;eap_md5_buildReq"), 1654 (1, "chap_md5;eap_md5_process")] 1655 for count, func in tests: 1656 with fail_test(hapd, count, func): 1657 run_eap_md5_connect(dev[0]) 1658 1659def start_md5_assoc(dev, hapd): 1660 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412", 1661 eap="MD5", identity="phase1-user", password="password", 1662 wait_connect=False) 1663 proxy_msg(hapd, dev) # EAP-Identity/Request 1664 proxy_msg(dev, hapd) # EAP-Identity/Response 1665 proxy_msg(hapd, dev) # MSCHAPV2/Request 1666 proxy_msg(dev, hapd) # NAK 1667 proxy_msg(hapd, dev) # MD5 Request 1668 1669def stop_md5_assoc(dev, hapd, wait=True): 1670 dev.request("REMOVE_NETWORK all") 1671 if wait: 1672 dev.wait_disconnected() 1673 dev.dump_monitor() 1674 hapd.dump_monitor() 1675 1676def test_eap_proto_md5_server(dev, apdev): 1677 """EAP-MD5 protocol testing for the server""" 1678 check_eap_capa(dev[0], "MD5") 1679 params = int_eap_server_params() 1680 params['erp_domain'] = 'example.com' 1681 params['eap_server_erp'] = '1' 1682 hapd = hostapd.add_ap(apdev[0], params) 1683 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 1684 hapd.request("SET ext_eapol_frame_io 1") 1685 dev[0].request("SET ext_eapol_frame_io 1") 1686 1687 # Successful exchange to verify proxying mechanism 1688 start_md5_assoc(dev[0], hapd) 1689 proxy_msg(dev[0], hapd) # MD5 Response 1690 proxy_msg(hapd, dev[0]) # EAP-Success 1691 # Accept both EAP-Success and disconnection indication since it is possible 1692 # for disconnection from the AP (due to EAP-MD5 not deriving keys) to be 1693 # processed more quickly. 1694 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS", 1695 "CTRL-EVENT-DISCONNECTED"], timeout=5) 1696 if ev is None: 1697 raise Exception("No EAP-Success reported") 1698 stop_md5_assoc(dev[0], hapd, wait="CTRL-EVENT-EAP-SUCCESS" in ev) 1699 1700 start_md5_assoc(dev[0], hapd) 1701 resp = rx_msg(dev[0]) 1702 # Too short EAP-MD5 header (no length field) 1703 hapd.note("EAP-MD5: Invalid frame") 1704 msg = resp[0:4] + "0005" + resp[8:12] + "0005" + "04" 1705 tx_msg(dev[0], hapd, msg) 1706 # Too short EAP-MD5 header (no length field) 1707 hapd.note("EAP-MD5: Invalid response (response_len=0 payload_len=1") 1708 msg = resp[0:4] + "0006" + resp[8:12] + "0006" + "0400" 1709 tx_msg(dev[0], hapd, msg) 1710 stop_md5_assoc(dev[0], hapd) 1711 1712def test_eap_proto_otp(dev, apdev): 1713 """EAP-OTP protocol tests""" 1714 def otp_handler(ctx, req): 1715 logger.info("otp_handler - RX " + binascii.hexlify(req).decode()) 1716 if 'num' not in ctx: 1717 ctx['num'] = 0 1718 ctx['num'] = ctx['num'] + 1 1719 if 'id' not in ctx: 1720 ctx['id'] = 1 1721 ctx['id'] = (ctx['id'] + 1) % 256 1722 1723 if ctx['num'] == 1: 1724 logger.info("Test: Empty payload") 1725 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 1726 4 + 1, 1727 EAP_TYPE_OTP) 1728 if ctx['num'] == 2: 1729 logger.info("Test: Success") 1730 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 1731 4) 1732 1733 if ctx['num'] == 3: 1734 logger.info("Test: Challenge included") 1735 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 1736 4 + 1 + 1, 1737 EAP_TYPE_OTP, 1738 ord('A')) 1739 if ctx['num'] == 4: 1740 logger.info("Test: Success") 1741 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 1742 4) 1743 1744 return None 1745 1746 srv = start_radius_server(otp_handler) 1747 1748 try: 1749 hapd = start_ap(apdev[0]) 1750 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 1751 1752 for i in range(0, 1): 1753 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 1754 eap="OTP", identity="user", password="password", 1755 wait_connect=False) 1756 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 1757 timeout=15) 1758 if ev is None: 1759 raise Exception("Timeout on EAP start") 1760 time.sleep(0.1) 1761 dev[0].request("REMOVE_NETWORK all") 1762 1763 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 1764 eap="OTP", identity="user", wait_connect=False) 1765 ev = dev[0].wait_event(["CTRL-REQ-OTP"]) 1766 if ev is None: 1767 raise Exception("Request for password timed out") 1768 id = ev.split(':')[0].split('-')[-1] 1769 dev[0].request("CTRL-RSP-OTP-" + id + ":password") 1770 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"]) 1771 if ev is None: 1772 raise Exception("Success not reported") 1773 finally: 1774 stop_radius_server(srv) 1775 1776def test_eap_proto_otp_errors(dev, apdev): 1777 """EAP-OTP local error cases""" 1778 def otp_handler2(ctx, req): 1779 logger.info("otp_handler2 - RX " + binascii.hexlify(req).decode()) 1780 if 'num' not in ctx: 1781 ctx['num'] = 0 1782 ctx['num'] = ctx['num'] + 1 1783 if 'id' not in ctx: 1784 ctx['id'] = 1 1785 ctx['id'] = (ctx['id'] + 1) % 256 1786 idx = 0 1787 1788 idx += 1 1789 if ctx['num'] == idx: 1790 logger.info("Test: Challenge included") 1791 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 1792 4 + 1 + 1, 1793 EAP_TYPE_OTP, 1794 ord('A')) 1795 1796 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 1797 1798 srv = start_radius_server(otp_handler2) 1799 1800 try: 1801 hapd = start_ap(apdev[0]) 1802 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 1803 1804 with alloc_fail(dev[0], 1, "eap_msg_alloc;eap_otp_process"): 1805 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 1806 eap="OTP", identity="user", password="password", 1807 wait_connect=False) 1808 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 1809 dev[0].request("REMOVE_NETWORK all") 1810 dev[0].wait_disconnected() 1811 finally: 1812 stop_radius_server(srv) 1813 1814EAP_GPSK_OPCODE_GPSK_1 = 1 1815EAP_GPSK_OPCODE_GPSK_2 = 2 1816EAP_GPSK_OPCODE_GPSK_3 = 3 1817EAP_GPSK_OPCODE_GPSK_4 = 4 1818EAP_GPSK_OPCODE_FAIL = 5 1819EAP_GPSK_OPCODE_PROTECTED_FAIL = 6 1820 1821def test_eap_proto_gpsk(dev, apdev): 1822 """EAP-GPSK protocol tests""" 1823 def gpsk_handler(ctx, req): 1824 logger.info("gpsk_handler - RX " + binascii.hexlify(req).decode()) 1825 if 'num' not in ctx: 1826 ctx['num'] = 0 1827 ctx['num'] = ctx['num'] + 1 1828 if 'id' not in ctx: 1829 ctx['id'] = 1 1830 ctx['id'] = (ctx['id'] + 1) % 256 1831 1832 idx = 0 1833 1834 idx += 1 1835 if ctx['num'] == idx: 1836 logger.info("Test: Missing payload") 1837 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 1838 4 + 1, 1839 EAP_TYPE_GPSK) 1840 1841 idx += 1 1842 if ctx['num'] == idx: 1843 logger.info("Test: Unknown opcode") 1844 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 1845 4 + 1 + 1, 1846 EAP_TYPE_GPSK, 1847 255) 1848 1849 idx += 1 1850 if ctx['num'] == idx: 1851 logger.info("Test: Unexpected GPSK-3") 1852 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 1853 4 + 1 + 1, 1854 EAP_TYPE_GPSK, 1855 EAP_GPSK_OPCODE_GPSK_3) 1856 1857 idx += 1 1858 if ctx['num'] == idx: 1859 logger.info("Test: GPSK-1 Too short GPSK-1") 1860 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 1861 4 + 1 + 1, 1862 EAP_TYPE_GPSK, 1863 EAP_GPSK_OPCODE_GPSK_1) 1864 1865 idx += 1 1866 if ctx['num'] == idx: 1867 logger.info("Test: GPSK-1 Truncated ID_Server") 1868 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], 1869 4 + 1 + 1 + 2, 1870 EAP_TYPE_GPSK, 1871 EAP_GPSK_OPCODE_GPSK_1, 1) 1872 1873 idx += 1 1874 if ctx['num'] == idx: 1875 logger.info("Test: GPSK-1 Missing RAND_Server") 1876 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], 1877 4 + 1 + 1 + 2, 1878 EAP_TYPE_GPSK, 1879 EAP_GPSK_OPCODE_GPSK_1, 0) 1880 1881 idx += 1 1882 if ctx['num'] == idx: 1883 logger.info("Test: GPSK-1 Missing CSuite_List") 1884 return struct.pack(">BBHBBH8L", EAP_CODE_REQUEST, ctx['id'], 1885 4 + 1 + 1 + 2 + 32, 1886 EAP_TYPE_GPSK, 1887 EAP_GPSK_OPCODE_GPSK_1, 0, 1888 0, 0, 0, 0, 0, 0, 0, 0) 1889 1890 idx += 1 1891 if ctx['num'] == idx: 1892 logger.info("Test: GPSK-1 Truncated CSuite_List") 1893 return struct.pack(">BBHBBH8LH", EAP_CODE_REQUEST, ctx['id'], 1894 4 + 1 + 1 + 2 + 32 + 2, 1895 EAP_TYPE_GPSK, 1896 EAP_GPSK_OPCODE_GPSK_1, 0, 1897 0, 0, 0, 0, 0, 0, 0, 0, 1898 1) 1899 1900 idx += 1 1901 if ctx['num'] == idx: 1902 logger.info("Test: GPSK-1 Empty CSuite_List") 1903 return struct.pack(">BBHBBH8LH", EAP_CODE_REQUEST, ctx['id'], 1904 4 + 1 + 1 + 2 + 32 + 2, 1905 EAP_TYPE_GPSK, 1906 EAP_GPSK_OPCODE_GPSK_1, 0, 1907 0, 0, 0, 0, 0, 0, 0, 0, 1908 0) 1909 1910 idx += 1 1911 if ctx['num'] == idx: 1912 logger.info("Test: GPSK-1 Invalid CSuite_List") 1913 return struct.pack(">BBHBBH8LHB", EAP_CODE_REQUEST, ctx['id'], 1914 4 + 1 + 1 + 2 + 32 + 2 + 1, 1915 EAP_TYPE_GPSK, 1916 EAP_GPSK_OPCODE_GPSK_1, 0, 1917 0, 0, 0, 0, 0, 0, 0, 0, 1918 1, 0) 1919 1920 idx += 1 1921 if ctx['num'] == idx: 1922 logger.info("Test: GPSK-1 No supported CSuite") 1923 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], 1924 4 + 1 + 1 + 2 + 32 + 2 + 6, 1925 EAP_TYPE_GPSK, 1926 EAP_GPSK_OPCODE_GPSK_1, 0, 1927 0, 0, 0, 0, 0, 0, 0, 0, 1928 6, 0, 0) 1929 1930 idx += 1 1931 if ctx['num'] == idx: 1932 logger.info("Test: GPSK-1 Supported CSuite") 1933 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], 1934 4 + 1 + 1 + 2 + 32 + 2 + 6, 1935 EAP_TYPE_GPSK, 1936 EAP_GPSK_OPCODE_GPSK_1, 0, 1937 0, 0, 0, 0, 0, 0, 0, 0, 1938 6, 0, 1) 1939 idx += 1 1940 if ctx['num'] == idx: 1941 logger.info("Test: Unexpected GPSK-1") 1942 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], 1943 4 + 1 + 1 + 2 + 32 + 2 + 6, 1944 EAP_TYPE_GPSK, 1945 EAP_GPSK_OPCODE_GPSK_1, 0, 1946 0, 0, 0, 0, 0, 0, 0, 0, 1947 6, 0, 1) 1948 1949 idx += 1 1950 if ctx['num'] == idx: 1951 logger.info("Test: GPSK-1 Supported CSuite but too short key") 1952 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], 1953 4 + 1 + 1 + 2 + 32 + 2 + 6, 1954 EAP_TYPE_GPSK, 1955 EAP_GPSK_OPCODE_GPSK_1, 0, 1956 0, 0, 0, 0, 0, 0, 0, 0, 1957 6, 0, 1) 1958 1959 idx += 1 1960 if ctx['num'] == idx: 1961 logger.info("Test: GPSK-1 Supported CSuite") 1962 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], 1963 4 + 1 + 1 + 2 + 32 + 2 + 6, 1964 EAP_TYPE_GPSK, 1965 EAP_GPSK_OPCODE_GPSK_1, 0, 1966 0, 0, 0, 0, 0, 0, 0, 0, 1967 6, 0, 1) 1968 idx += 1 1969 if ctx['num'] == idx: 1970 logger.info("Test: Too short GPSK-3") 1971 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 1972 4 + 1 + 1, 1973 EAP_TYPE_GPSK, 1974 EAP_GPSK_OPCODE_GPSK_3) 1975 1976 idx += 1 1977 if ctx['num'] == idx: 1978 logger.info("Test: GPSK-1 Supported CSuite") 1979 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], 1980 4 + 1 + 1 + 2 + 32 + 2 + 6, 1981 EAP_TYPE_GPSK, 1982 EAP_GPSK_OPCODE_GPSK_1, 0, 1983 0, 0, 0, 0, 0, 0, 0, 0, 1984 6, 0, 1) 1985 idx += 1 1986 if ctx['num'] == idx: 1987 logger.info("Test: GPSK-3 Mismatch in RAND_Peer") 1988 return struct.pack(">BBHBB8L", EAP_CODE_REQUEST, ctx['id'], 1989 4 + 1 + 1 + 32, 1990 EAP_TYPE_GPSK, 1991 EAP_GPSK_OPCODE_GPSK_3, 1992 0, 0, 0, 0, 0, 0, 0, 0) 1993 1994 idx += 1 1995 if ctx['num'] == idx: 1996 logger.info("Test: GPSK-1 Supported CSuite") 1997 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], 1998 4 + 1 + 1 + 2 + 32 + 2 + 6, 1999 EAP_TYPE_GPSK, 2000 EAP_GPSK_OPCODE_GPSK_1, 0, 2001 0, 0, 0, 0, 0, 0, 0, 0, 2002 6, 0, 1) 2003 idx += 1 2004 if ctx['num'] == idx: 2005 logger.info("Test: GPSK-3 Missing RAND_Server") 2006 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 2007 4 + 1 + 1 + 32, 2008 EAP_TYPE_GPSK, 2009 EAP_GPSK_OPCODE_GPSK_3) 2010 msg += req[14:46] 2011 return msg 2012 2013 idx += 1 2014 if ctx['num'] == idx: 2015 logger.info("Test: GPSK-1 Supported CSuite") 2016 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], 2017 4 + 1 + 1 + 2 + 32 + 2 + 6, 2018 EAP_TYPE_GPSK, 2019 EAP_GPSK_OPCODE_GPSK_1, 0, 2020 0, 0, 0, 0, 0, 0, 0, 0, 2021 6, 0, 1) 2022 idx += 1 2023 if ctx['num'] == idx: 2024 logger.info("Test: GPSK-3 Mismatch in RAND_Server") 2025 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 2026 4 + 1 + 1 + 32 + 32, 2027 EAP_TYPE_GPSK, 2028 EAP_GPSK_OPCODE_GPSK_3) 2029 msg += req[14:46] 2030 msg += struct.pack(">8L", 1, 1, 1, 1, 1, 1, 1, 1) 2031 return msg 2032 2033 idx += 1 2034 if ctx['num'] == idx: 2035 logger.info("Test: GPSK-1 Supported CSuite") 2036 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], 2037 4 + 1 + 1 + 2 + 32 + 2 + 6, 2038 EAP_TYPE_GPSK, 2039 EAP_GPSK_OPCODE_GPSK_1, 0, 2040 0, 0, 0, 0, 0, 0, 0, 0, 2041 6, 0, 1) 2042 idx += 1 2043 if ctx['num'] == idx: 2044 logger.info("Test: GPSK-3 Missing ID_Server") 2045 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 2046 4 + 1 + 1 + 32 + 32, 2047 EAP_TYPE_GPSK, 2048 EAP_GPSK_OPCODE_GPSK_3) 2049 msg += req[14:46] 2050 msg += struct.pack(">8L", 0, 0, 0, 0, 0, 0, 0, 0) 2051 return msg 2052 2053 idx += 1 2054 if ctx['num'] == idx: 2055 logger.info("Test: GPSK-1 Supported CSuite") 2056 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], 2057 4 + 1 + 1 + 2 + 32 + 2 + 6, 2058 EAP_TYPE_GPSK, 2059 EAP_GPSK_OPCODE_GPSK_1, 0, 2060 0, 0, 0, 0, 0, 0, 0, 0, 2061 6, 0, 1) 2062 idx += 1 2063 if ctx['num'] == idx: 2064 logger.info("Test: GPSK-3 Truncated ID_Server") 2065 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 2066 4 + 1 + 1 + 32 + 32 + 2, 2067 EAP_TYPE_GPSK, 2068 EAP_GPSK_OPCODE_GPSK_3) 2069 msg += req[14:46] 2070 msg += struct.pack(">8LH", 0, 0, 0, 0, 0, 0, 0, 0, 1) 2071 return msg 2072 2073 idx += 1 2074 if ctx['num'] == idx: 2075 logger.info("Test: GPSK-1 Supported CSuite") 2076 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], 2077 4 + 1 + 1 + 2 + 32 + 2 + 6, 2078 EAP_TYPE_GPSK, 2079 EAP_GPSK_OPCODE_GPSK_1, 0, 2080 0, 0, 0, 0, 0, 0, 0, 0, 2081 6, 0, 1) 2082 idx += 1 2083 if ctx['num'] == idx: 2084 logger.info("Test: GPSK-3 Mismatch in ID_Server") 2085 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 2086 4 + 1 + 1 + 32 + 32 + 3, 2087 EAP_TYPE_GPSK, 2088 EAP_GPSK_OPCODE_GPSK_3) 2089 msg += req[14:46] 2090 msg += struct.pack(">8LHB", 0, 0, 0, 0, 0, 0, 0, 0, 1, ord('B')) 2091 return msg 2092 2093 idx += 1 2094 if ctx['num'] == idx: 2095 logger.info("Test: GPSK-1 Supported CSuite") 2096 return struct.pack(">BBHBBHB8LHLH", EAP_CODE_REQUEST, ctx['id'], 2097 4 + 1 + 1 + 3 + 32 + 2 + 6, 2098 EAP_TYPE_GPSK, 2099 EAP_GPSK_OPCODE_GPSK_1, 1, ord('A'), 2100 0, 0, 0, 0, 0, 0, 0, 0, 2101 6, 0, 1) 2102 idx += 1 2103 if ctx['num'] == idx: 2104 logger.info("Test: GPSK-3 Mismatch in ID_Server (same length)") 2105 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 2106 4 + 1 + 1 + 32 + 32 + 3, 2107 EAP_TYPE_GPSK, 2108 EAP_GPSK_OPCODE_GPSK_3) 2109 msg += req[15:47] 2110 msg += struct.pack(">8LHB", 0, 0, 0, 0, 0, 0, 0, 0, 1, ord('B')) 2111 return msg 2112 2113 idx += 1 2114 if ctx['num'] == idx: 2115 logger.info("Test: GPSK-1 Supported CSuite") 2116 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], 2117 4 + 1 + 1 + 2 + 32 + 2 + 6, 2118 EAP_TYPE_GPSK, 2119 EAP_GPSK_OPCODE_GPSK_1, 0, 2120 0, 0, 0, 0, 0, 0, 0, 0, 2121 6, 0, 1) 2122 idx += 1 2123 if ctx['num'] == idx: 2124 logger.info("Test: GPSK-3 Missing CSuite_Sel") 2125 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 2126 4 + 1 + 1 + 32 + 32 + 2, 2127 EAP_TYPE_GPSK, 2128 EAP_GPSK_OPCODE_GPSK_3) 2129 msg += req[14:46] 2130 msg += struct.pack(">8LH", 0, 0, 0, 0, 0, 0, 0, 0, 0) 2131 return msg 2132 2133 idx += 1 2134 if ctx['num'] == idx: 2135 logger.info("Test: GPSK-1 Supported CSuite") 2136 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], 2137 4 + 1 + 1 + 2 + 32 + 2 + 6, 2138 EAP_TYPE_GPSK, 2139 EAP_GPSK_OPCODE_GPSK_1, 0, 2140 0, 0, 0, 0, 0, 0, 0, 0, 2141 6, 0, 1) 2142 idx += 1 2143 if ctx['num'] == idx: 2144 logger.info("Test: GPSK-3 Mismatch in CSuite_Sel") 2145 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 2146 4 + 1 + 1 + 32 + 32 + 2 + 6, 2147 EAP_TYPE_GPSK, 2148 EAP_GPSK_OPCODE_GPSK_3) 2149 msg += req[14:46] 2150 msg += struct.pack(">8LHLH", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2) 2151 return msg 2152 2153 idx += 1 2154 if ctx['num'] == idx: 2155 logger.info("Test: GPSK-1 Supported CSuite") 2156 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], 2157 4 + 1 + 1 + 2 + 32 + 2 + 6, 2158 EAP_TYPE_GPSK, 2159 EAP_GPSK_OPCODE_GPSK_1, 0, 2160 0, 0, 0, 0, 0, 0, 0, 0, 2161 6, 0, 1) 2162 idx += 1 2163 if ctx['num'] == idx: 2164 logger.info("Test: GPSK-3 Missing len(PD_Payload_Block)") 2165 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 2166 4 + 1 + 1 + 32 + 32 + 2 + 6, 2167 EAP_TYPE_GPSK, 2168 EAP_GPSK_OPCODE_GPSK_3) 2169 msg += req[14:46] 2170 msg += struct.pack(">8LHLH", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1) 2171 return msg 2172 2173 idx += 1 2174 if ctx['num'] == idx: 2175 logger.info("Test: GPSK-1 Supported CSuite") 2176 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], 2177 4 + 1 + 1 + 2 + 32 + 2 + 6, 2178 EAP_TYPE_GPSK, 2179 EAP_GPSK_OPCODE_GPSK_1, 0, 2180 0, 0, 0, 0, 0, 0, 0, 0, 2181 6, 0, 1) 2182 idx += 1 2183 if ctx['num'] == idx: 2184 logger.info("Test: GPSK-3 Truncated PD_Payload_Block") 2185 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 2186 4 + 1 + 1 + 32 + 32 + 2 + 6 + 2, 2187 EAP_TYPE_GPSK, 2188 EAP_GPSK_OPCODE_GPSK_3) 2189 msg += req[14:46] 2190 msg += struct.pack(">8LHLHH", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1) 2191 return msg 2192 2193 idx += 1 2194 if ctx['num'] == idx: 2195 logger.info("Test: GPSK-1 Supported CSuite") 2196 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], 2197 4 + 1 + 1 + 2 + 32 + 2 + 6, 2198 EAP_TYPE_GPSK, 2199 EAP_GPSK_OPCODE_GPSK_1, 0, 2200 0, 0, 0, 0, 0, 0, 0, 0, 2201 6, 0, 1) 2202 idx += 1 2203 if ctx['num'] == idx: 2204 logger.info("Test: GPSK-3 Missing MAC") 2205 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 2206 4 + 1 + 1 + 32 + 32 + 2 + 6 + 3, 2207 EAP_TYPE_GPSK, 2208 EAP_GPSK_OPCODE_GPSK_3) 2209 msg += req[14:46] 2210 msg += struct.pack(">8LHLHHB", 2211 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 123) 2212 return msg 2213 2214 idx += 1 2215 if ctx['num'] == idx: 2216 logger.info("Test: GPSK-1 Supported CSuite") 2217 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], 2218 4 + 1 + 1 + 2 + 32 + 2 + 6, 2219 EAP_TYPE_GPSK, 2220 EAP_GPSK_OPCODE_GPSK_1, 0, 2221 0, 0, 0, 0, 0, 0, 0, 0, 2222 6, 0, 1) 2223 idx += 1 2224 if ctx['num'] == idx: 2225 logger.info("Test: GPSK-3 Incorrect MAC") 2226 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 2227 4 + 1 + 1 + 32 + 32 + 2 + 6 + 3 + 16, 2228 EAP_TYPE_GPSK, 2229 EAP_GPSK_OPCODE_GPSK_3) 2230 msg += req[14:46] 2231 msg += struct.pack(">8LHLHHB4L", 2232 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 123, 2233 0, 0, 0, 0) 2234 return msg 2235 2236 return None 2237 2238 srv = start_radius_server(gpsk_handler) 2239 2240 try: 2241 hapd = start_ap(apdev[0]) 2242 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 2243 2244 for i in range(0, 27): 2245 if i == 12: 2246 pw = "short" 2247 else: 2248 pw = "abcdefghijklmnop0123456789abcdef" 2249 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 2250 eap="GPSK", identity="user", password=pw, 2251 wait_connect=False) 2252 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 2253 timeout=15) 2254 if ev is None: 2255 raise Exception("Timeout on EAP start") 2256 time.sleep(0.05) 2257 dev[0].request("REMOVE_NETWORK all") 2258 finally: 2259 stop_radius_server(srv) 2260 2261def run_eap_gpsk_connect(dev): 2262 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412", 2263 eap="GPSK", identity="gpsk user", 2264 password="abcdefghijklmnop0123456789abcdef", 2265 wait_connect=False) 2266 ev = dev.wait_event(["CTRL-EVENT-EAP-SUCCESS", "CTRL-EVENT-EAP-FAILURE", 2267 "CTRL-EVENT-DISCONNECTED"], 2268 timeout=1) 2269 dev.request("REMOVE_NETWORK all") 2270 if not ev or "CTRL-EVENT-DISCONNECTED" not in ev: 2271 dev.wait_disconnected() 2272 dev.dump_monitor() 2273 2274def test_eap_proto_gpsk_errors_server(dev, apdev): 2275 """EAP-GPSK local error cases on server""" 2276 check_eap_capa(dev[0], "GPSK") 2277 params = int_eap_server_params() 2278 params['erp_domain'] = 'example.com' 2279 params['eap_server_erp'] = '1' 2280 hapd = hostapd.add_ap(apdev[0], params) 2281 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 2282 2283 tests = [(1, "eap_gpsk_init"), 2284 (1, "eap_msg_alloc;eap_gpsk_build_gpsk_1"), 2285 (1, "eap_msg_alloc;eap_gpsk_build_gpsk_3"), 2286 (1, "eap_gpsk_process_gpsk_2"), 2287 (1, "eap_gpsk_derive_keys;eap_gpsk_process_gpsk_2"), 2288 (1, "eap_gpsk_derive_session_id;eap_gpsk_process_gpsk_2"), 2289 (1, "eap_gpsk_getKey"), 2290 (1, "eap_gpsk_get_emsk"), 2291 (1, "eap_gpsk_get_session_id")] 2292 for count, func in tests: 2293 with alloc_fail(hapd, count, func): 2294 run_eap_gpsk_connect(dev[0]) 2295 2296 tests = [(1, "os_get_random;eap_gpsk_build_gpsk_1"), 2297 (1, "eap_gpsk_compute_mic;eap_gpsk_build_gpsk_3"), 2298 (1, "eap_gpsk_derive_keys;eap_gpsk_process_gpsk_2"), 2299 (1, "eap_gpsk_derive_session_id;eap_gpsk_process_gpsk_2"), 2300 (1, "eap_gpsk_compute_mic;eap_gpsk_process_gpsk_2"), 2301 (1, "eap_gpsk_compute_mic;eap_gpsk_process_gpsk_4")] 2302 for count, func in tests: 2303 with fail_test(hapd, count, func): 2304 run_eap_gpsk_connect(dev[0]) 2305 2306def start_gpsk_assoc(dev, hapd): 2307 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412", 2308 eap="GPSK", identity="gpsk user", 2309 password="abcdefghijklmnop0123456789abcdef", 2310 wait_connect=False) 2311 proxy_msg(hapd, dev) # EAP-Identity/Request 2312 proxy_msg(dev, hapd) # EAP-Identity/Response 2313 proxy_msg(hapd, dev) # GPSK-1 2314 2315def stop_gpsk_assoc(dev, hapd): 2316 dev.request("REMOVE_NETWORK all") 2317 dev.wait_disconnected() 2318 dev.dump_monitor() 2319 hapd.dump_monitor() 2320 2321def test_eap_proto_gpsk_server(dev, apdev): 2322 """EAP-GPSK protocol testing for the server""" 2323 check_eap_capa(dev[0], "GPSK") 2324 params = int_eap_server_params() 2325 params['erp_domain'] = 'example.com' 2326 params['eap_server_erp'] = '1' 2327 hapd = hostapd.add_ap(apdev[0], params) 2328 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 2329 hapd.request("SET ext_eapol_frame_io 1") 2330 dev[0].request("SET ext_eapol_frame_io 1") 2331 2332 # Successful exchange to verify proxying mechanism 2333 start_gpsk_assoc(dev[0], hapd) 2334 proxy_msg(dev[0], hapd) # GPSK-2 2335 proxy_msg(hapd, dev[0]) # GPSK-3 2336 proxy_msg(dev[0], hapd) # GPSK-4 2337 proxy_msg(hapd, dev[0]) # EAP-Success 2338 proxy_msg(hapd, dev[0]) # EAPOL-Key msg 1/4 2339 proxy_msg(dev[0], hapd) # EAPOL-Key msg 2/4 2340 proxy_msg(hapd, dev[0]) # EAPOL-Key msg 3/4 2341 proxy_msg(dev[0], hapd) # EAPOL-Key msg 4/4 2342 dev[0].wait_connected() 2343 stop_gpsk_assoc(dev[0], hapd) 2344 2345 start_gpsk_assoc(dev[0], hapd) 2346 resp = rx_msg(dev[0]) 2347 # Too short EAP-GPSK header (no OP-Code) 2348 # --> EAP-GPSK: Invalid frame 2349 msg = resp[0:4] + "0005" + resp[8:12] + "0005" + "33" 2350 tx_msg(dev[0], hapd, msg) 2351 # Unknown OP-Code 2352 # --> EAP-GPSK: Unexpected opcode=7 in state=0 2353 msg = resp[0:4] + "0006" + resp[8:12] + "0006" + "3307" 2354 tx_msg(dev[0], hapd, msg) 2355 # Too short GPSK-2 2356 # --> EAP-GPSK: Too short message for ID_Peer length 2357 msg = resp[0:4] + "0006" + resp[8:12] + "0006" + "3302" 2358 tx_msg(dev[0], hapd, msg) 2359 rx_msg(hapd) 2360 stop_gpsk_assoc(dev[0], hapd) 2361 2362 start_gpsk_assoc(dev[0], hapd) 2363 resp = rx_msg(dev[0]) 2364 # Too short GPSK-2 2365 # --> EAP-GPSK: Too short message for ID_Peer 2366 msg = resp[0:4] + "0008" + resp[8:12] + "0008" + "33020001" 2367 tx_msg(dev[0], hapd, msg) 2368 rx_msg(hapd) 2369 stop_gpsk_assoc(dev[0], hapd) 2370 2371 start_gpsk_assoc(dev[0], hapd) 2372 resp = rx_msg(dev[0]) 2373 # Too short GPSK-2 2374 # --> EAP-GPSK: Too short message for ID_Server length 2375 msg = resp[0:4] + "0008" + resp[8:12] + "0008" + "33020000" 2376 tx_msg(dev[0], hapd, msg) 2377 rx_msg(hapd) 2378 stop_gpsk_assoc(dev[0], hapd) 2379 2380 start_gpsk_assoc(dev[0], hapd) 2381 resp = rx_msg(dev[0]) 2382 # Too short GPSK-2 2383 # --> EAP-GPSK: Too short message for ID_Server 2384 msg = resp[0:4] + "000a" + resp[8:12] + "000a" + "330200000001" 2385 tx_msg(dev[0], hapd, msg) 2386 rx_msg(hapd) 2387 stop_gpsk_assoc(dev[0], hapd) 2388 2389 start_gpsk_assoc(dev[0], hapd) 2390 resp = rx_msg(dev[0]) 2391 # ID_Server mismatch 2392 # --> EAP-GPSK: ID_Server in GPSK-1 and GPSK-2 did not match 2393 msg = resp[0:4] + "000a" + resp[8:12] + "000a" + "330200000000" 2394 tx_msg(dev[0], hapd, msg) 2395 rx_msg(hapd) 2396 stop_gpsk_assoc(dev[0], hapd) 2397 2398 start_gpsk_assoc(dev[0], hapd) 2399 resp = rx_msg(dev[0]) 2400 # Too short GPSK-2 2401 # --> EAP-GPSK: Too short message for RAND_Peer 2402 msg = resp[0:4] + "0011" + resp[8:12] + "0011" + "330200000007" + binascii.hexlify(b"hostapd").decode() 2403 tx_msg(dev[0], hapd, msg) 2404 rx_msg(hapd) 2405 stop_gpsk_assoc(dev[0], hapd) 2406 2407 start_gpsk_assoc(dev[0], hapd) 2408 resp = rx_msg(dev[0]) 2409 # Too short GPSK-2 2410 # --> EAP-GPSK: Too short message for RAND_Server 2411 msg = resp[0:4] + "0031" + resp[8:12] + "0031" + "330200000007" + binascii.hexlify(b"hostapd").decode() + 32*"00" 2412 tx_msg(dev[0], hapd, msg) 2413 rx_msg(hapd) 2414 stop_gpsk_assoc(dev[0], hapd) 2415 2416 start_gpsk_assoc(dev[0], hapd) 2417 resp = rx_msg(dev[0]) 2418 # RAND_Server mismatch 2419 # --> EAP-GPSK: RAND_Server in GPSK-1 and GPSK-2 did not match 2420 msg = resp[0:4] + "0051" + resp[8:12] + "0051" + "330200000007" + binascii.hexlify(b"hostapd").decode() + 32*"00" + 32*"00" 2421 tx_msg(dev[0], hapd, msg) 2422 rx_msg(hapd) 2423 stop_gpsk_assoc(dev[0], hapd) 2424 2425 start_gpsk_assoc(dev[0], hapd) 2426 resp = rx_msg(dev[0]) 2427 # Too short GPSK-2 2428 # --> EAP-GPSK: Too short message for CSuite_List length 2429 msg = resp[0:4] + "005a" + resp[8:12] + "005a" + resp[16:188] 2430 tx_msg(dev[0], hapd, msg) 2431 rx_msg(hapd) 2432 stop_gpsk_assoc(dev[0], hapd) 2433 2434 start_gpsk_assoc(dev[0], hapd) 2435 resp = rx_msg(dev[0]) 2436 # Too short GPSK-2 2437 # --> EAP-GPSK: Too short message for CSuite_List 2438 msg = resp[0:4] + "005c" + resp[8:12] + "005c" + resp[16:192] 2439 tx_msg(dev[0], hapd, msg) 2440 rx_msg(hapd) 2441 stop_gpsk_assoc(dev[0], hapd) 2442 2443 start_gpsk_assoc(dev[0], hapd) 2444 resp = rx_msg(dev[0]) 2445 # Too short GPSK-2 2446 # --> EAP-GPSK: CSuite_List in GPSK-1 and GPSK-2 did not match 2447 msg = resp[0:4] + "005c" + resp[8:12] + "005c" + resp[16:188] + "0000" 2448 tx_msg(dev[0], hapd, msg) 2449 rx_msg(hapd) 2450 stop_gpsk_assoc(dev[0], hapd) 2451 2452 start_gpsk_assoc(dev[0], hapd) 2453 resp = rx_msg(dev[0]) 2454 # Too short GPSK-2 2455 # --> EAP-GPSK: Too short message for CSuite_Sel 2456 msg = resp[0:4] + "0068" + resp[8:12] + "0068" + resp[16:216] 2457 tx_msg(dev[0], hapd, msg) 2458 rx_msg(hapd) 2459 stop_gpsk_assoc(dev[0], hapd) 2460 2461 start_gpsk_assoc(dev[0], hapd) 2462 resp = rx_msg(dev[0]) 2463 # Unsupported CSuite_Sel 2464 # --> EAP-GPSK: Peer selected unsupported ciphersuite 0:255 2465 msg = resp[0:4] + "006e" + resp[8:12] + "006e" + resp[16:226] + "ff" 2466 tx_msg(dev[0], hapd, msg) 2467 rx_msg(hapd) 2468 stop_gpsk_assoc(dev[0], hapd) 2469 2470 start_gpsk_assoc(dev[0], hapd) 2471 resp = rx_msg(dev[0]) 2472 # Too short GPSK-2 2473 # --> EAP-GPSK: Too short message for PD_Payload_1 length 2474 msg = resp[0:4] + "006e" + resp[8:12] + "006e" + resp[16:228] 2475 tx_msg(dev[0], hapd, msg) 2476 rx_msg(hapd) 2477 stop_gpsk_assoc(dev[0], hapd) 2478 2479 start_gpsk_assoc(dev[0], hapd) 2480 resp = rx_msg(dev[0]) 2481 # Too short GPSK-2 2482 # --> EAP-GPSK: Too short message for PD_Payload_1 2483 msg = resp[0:4] + "0070" + resp[8:12] + "0070" + resp[16:230] + "ff" 2484 tx_msg(dev[0], hapd, msg) 2485 rx_msg(hapd) 2486 stop_gpsk_assoc(dev[0], hapd) 2487 2488 start_gpsk_assoc(dev[0], hapd) 2489 resp = rx_msg(dev[0]) 2490 # Too short GPSK-2 2491 # --> EAP-GPSK: Message too short for MIC (left=0 miclen=16) 2492 msg = resp[0:4] + "0070" + resp[8:12] + "0070" + resp[16:232] 2493 tx_msg(dev[0], hapd, msg) 2494 rx_msg(hapd) 2495 stop_gpsk_assoc(dev[0], hapd) 2496 2497 start_gpsk_assoc(dev[0], hapd) 2498 resp = rx_msg(dev[0]) 2499 # Extra data in the end of GPSK-2 2500 # --> EAP-GPSK: Ignored 1 bytes of extra data in the end of GPSK-2 2501 msg = resp[0:4] + "0081" + resp[8:12] + "0081" + resp[16:264] + "00" 2502 tx_msg(dev[0], hapd, msg) 2503 proxy_msg(hapd, dev[0]) # GPSK-3 2504 resp = rx_msg(dev[0]) 2505 # Too short GPSK-4 2506 # --> EAP-GPSK: Too short message for PD_Payload_1 length 2507 msg = resp[0:4] + "0006" + resp[8:12] + "0006" + "3304" 2508 tx_msg(dev[0], hapd, msg) 2509 rx_msg(hapd) # EAP-Failure 2510 stop_gpsk_assoc(dev[0], hapd) 2511 2512 start_gpsk_assoc(dev[0], hapd) 2513 proxy_msg(dev[0], hapd) # GPSK-2 2514 proxy_msg(hapd, dev[0]) # GPSK-3 2515 resp = rx_msg(dev[0]) 2516 # Too short GPSK-4 2517 # --> EAP-GPSK: Too short message for PD_Payload_1 2518 msg = resp[0:4] + "0008" + resp[8:12] + "0008" + "33040001" 2519 tx_msg(dev[0], hapd, msg) 2520 rx_msg(hapd) # EAP-Failure 2521 stop_gpsk_assoc(dev[0], hapd) 2522 2523 start_gpsk_assoc(dev[0], hapd) 2524 proxy_msg(dev[0], hapd) # GPSK-2 2525 proxy_msg(hapd, dev[0]) # GPSK-3 2526 resp = rx_msg(dev[0]) 2527 # Too short GPSK-4 2528 # --> EAP-GPSK: Message too short for MIC (left=0 miclen=16) 2529 msg = resp[0:4] + "0008" + resp[8:12] + "0008" + "33040000" 2530 tx_msg(dev[0], hapd, msg) 2531 rx_msg(hapd) # EAP-Failure 2532 stop_gpsk_assoc(dev[0], hapd) 2533 2534 start_gpsk_assoc(dev[0], hapd) 2535 proxy_msg(dev[0], hapd) # GPSK-2 2536 proxy_msg(hapd, dev[0]) # GPSK-3 2537 resp = rx_msg(dev[0]) 2538 # Incorrect MIC in GPSK-4 2539 # --> EAP-GPSK: Incorrect MIC in GPSK-4 2540 msg = resp[0:4] + "0018" + resp[8:12] + "0018" + "33040000" + 16*"00" 2541 tx_msg(dev[0], hapd, msg) 2542 rx_msg(hapd) # EAP-Failure 2543 stop_gpsk_assoc(dev[0], hapd) 2544 2545 start_gpsk_assoc(dev[0], hapd) 2546 proxy_msg(dev[0], hapd) # GPSK-2 2547 proxy_msg(hapd, dev[0]) # GPSK-3 2548 resp = rx_msg(dev[0]) 2549 # Incorrect MIC in GPSK-4 2550 # --> EAP-GPSK: Ignored 1 bytes of extra data in the end of GPSK-4 2551 msg = resp[0:4] + "0019" + resp[8:12] + "0019" + resp[16:] + "00" 2552 tx_msg(dev[0], hapd, msg) 2553 rx_msg(hapd) # EAP-Success 2554 stop_gpsk_assoc(dev[0], hapd) 2555 2556EAP_EKE_ID = 1 2557EAP_EKE_COMMIT = 2 2558EAP_EKE_CONFIRM = 3 2559EAP_EKE_FAILURE = 4 2560 2561def test_eap_proto_eke(dev, apdev): 2562 """EAP-EKE protocol tests""" 2563 def eke_handler(ctx, req): 2564 logger.info("eke_handler - RX " + binascii.hexlify(req).decode()) 2565 if 'num' not in ctx: 2566 ctx['num'] = 0 2567 ctx['num'] = ctx['num'] + 1 2568 if 'id' not in ctx: 2569 ctx['id'] = 1 2570 ctx['id'] = (ctx['id'] + 1) % 256 2571 2572 idx = 0 2573 2574 idx += 1 2575 if ctx['num'] == idx: 2576 logger.info("Test: Missing payload") 2577 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 2578 4 + 1, 2579 EAP_TYPE_EKE) 2580 2581 idx += 1 2582 if ctx['num'] == idx: 2583 logger.info("Test: Unknown exchange") 2584 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 2585 4 + 1 + 1, 2586 EAP_TYPE_EKE, 2587 255) 2588 2589 idx += 1 2590 if ctx['num'] == idx: 2591 logger.info("Test: No NumProposals in EAP-EKE-ID/Request") 2592 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 2593 4 + 1 + 1, 2594 EAP_TYPE_EKE, 2595 EAP_EKE_ID) 2596 idx += 1 2597 if ctx['num'] == idx: 2598 logger.info("Test: EAP-Failure") 2599 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 2600 2601 idx += 1 2602 if ctx['num'] == idx: 2603 logger.info("Test: NumProposals=0 in EAP-EKE-ID/Request") 2604 return struct.pack(">BBHBBB", EAP_CODE_REQUEST, ctx['id'], 2605 4 + 1 + 1 + 1, 2606 EAP_TYPE_EKE, 2607 EAP_EKE_ID, 2608 0) 2609 idx += 1 2610 if ctx['num'] == idx: 2611 logger.info("Test: EAP-Failure") 2612 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 2613 2614 idx += 1 2615 if ctx['num'] == idx: 2616 logger.info("Test: Truncated Proposals list in EAP-EKE-ID/Request") 2617 return struct.pack(">BBHBBBB4B", EAP_CODE_REQUEST, ctx['id'], 2618 4 + 1 + 1 + 2 + 4, 2619 EAP_TYPE_EKE, 2620 EAP_EKE_ID, 2621 2, 0, 0, 0, 0, 0) 2622 idx += 1 2623 if ctx['num'] == idx: 2624 logger.info("Test: EAP-Failure") 2625 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 2626 2627 idx += 1 2628 if ctx['num'] == idx: 2629 logger.info("Test: Unsupported proposals in EAP-EKE-ID/Request") 2630 return struct.pack(">BBHBBBB4B4B4B4B", EAP_CODE_REQUEST, ctx['id'], 2631 4 + 1 + 1 + 2 + 4 * 4, 2632 EAP_TYPE_EKE, 2633 EAP_EKE_ID, 2634 4, 0, 2635 0, 0, 0, 0, 2636 3, 0, 0, 0, 2637 3, 1, 0, 0, 2638 3, 1, 1, 0) 2639 idx += 1 2640 if ctx['num'] == idx: 2641 logger.info("Test: EAP-Failure") 2642 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 2643 2644 idx += 1 2645 if ctx['num'] == idx: 2646 logger.info("Test: Missing IDType/Identity in EAP-EKE-ID/Request") 2647 return struct.pack(">BBHBBBB4B4B4B4B4B", 2648 EAP_CODE_REQUEST, ctx['id'], 2649 4 + 1 + 1 + 2 + 5 * 4, 2650 EAP_TYPE_EKE, 2651 EAP_EKE_ID, 2652 5, 0, 2653 0, 0, 0, 0, 2654 3, 0, 0, 0, 2655 3, 1, 0, 0, 2656 3, 1, 1, 0, 2657 3, 1, 1, 1) 2658 idx += 1 2659 if ctx['num'] == idx: 2660 logger.info("Test: EAP-Failure") 2661 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 2662 2663 idx += 1 2664 if ctx['num'] == idx: 2665 logger.info("Test: Valid EAP-EKE-ID/Request") 2666 return struct.pack(">BBHBBBB4BB", 2667 EAP_CODE_REQUEST, ctx['id'], 2668 4 + 1 + 1 + 2 + 4 + 1, 2669 EAP_TYPE_EKE, 2670 EAP_EKE_ID, 2671 1, 0, 2672 3, 1, 1, 1, 2673 255) 2674 idx += 1 2675 if ctx['num'] == idx: 2676 logger.info("Test: Unexpected EAP-EKE-ID/Request") 2677 return struct.pack(">BBHBBBB4BB", 2678 EAP_CODE_REQUEST, ctx['id'], 2679 4 + 1 + 1 + 2 + 4 + 1, 2680 EAP_TYPE_EKE, 2681 EAP_EKE_ID, 2682 1, 0, 2683 3, 1, 1, 1, 2684 255) 2685 idx += 1 2686 if ctx['num'] == idx: 2687 logger.info("Test: EAP-Failure") 2688 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 2689 2690 idx += 1 2691 if ctx['num'] == idx: 2692 logger.info("Test: Valid EAP-EKE-ID/Request") 2693 return struct.pack(">BBHBBBB4BB", 2694 EAP_CODE_REQUEST, ctx['id'], 2695 4 + 1 + 1 + 2 + 4 + 1, 2696 EAP_TYPE_EKE, 2697 EAP_EKE_ID, 2698 1, 0, 2699 3, 1, 1, 1, 2700 255) 2701 idx += 1 2702 if ctx['num'] == idx: 2703 logger.info("Test: Unexpected EAP-EKE-Confirm/Request") 2704 return struct.pack(">BBHBB", 2705 EAP_CODE_REQUEST, ctx['id'], 2706 4 + 1 + 1, 2707 EAP_TYPE_EKE, 2708 EAP_EKE_CONFIRM) 2709 idx += 1 2710 if ctx['num'] == idx: 2711 logger.info("Test: EAP-Failure") 2712 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 2713 2714 idx += 1 2715 if ctx['num'] == idx: 2716 logger.info("Test: Too short EAP-EKE-Failure/Request") 2717 return struct.pack(">BBHBB", 2718 EAP_CODE_REQUEST, ctx['id'], 2719 4 + 1 + 1, 2720 EAP_TYPE_EKE, 2721 EAP_EKE_FAILURE) 2722 idx += 1 2723 if ctx['num'] == idx: 2724 logger.info("Test: EAP-Failure") 2725 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 2726 2727 idx += 1 2728 if ctx['num'] == idx: 2729 logger.info("Test: Unexpected EAP-EKE-Commit/Request") 2730 return struct.pack(">BBHBB", 2731 EAP_CODE_REQUEST, ctx['id'], 2732 4 + 1 + 1, 2733 EAP_TYPE_EKE, 2734 EAP_EKE_COMMIT) 2735 idx += 1 2736 if ctx['num'] == idx: 2737 logger.info("Test: EAP-Failure") 2738 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 2739 2740 idx += 1 2741 if ctx['num'] == idx: 2742 logger.info("Test: Valid EAP-EKE-ID/Request") 2743 return struct.pack(">BBHBBBB4BB", 2744 EAP_CODE_REQUEST, ctx['id'], 2745 4 + 1 + 1 + 2 + 4 + 1, 2746 EAP_TYPE_EKE, 2747 EAP_EKE_ID, 2748 1, 0, 2749 3, 1, 1, 1, 2750 255) 2751 idx += 1 2752 if ctx['num'] == idx: 2753 logger.info("Test: Too short EAP-EKE-Commit/Request") 2754 return struct.pack(">BBHBB", 2755 EAP_CODE_REQUEST, ctx['id'], 2756 4 + 1 + 1, 2757 EAP_TYPE_EKE, 2758 EAP_EKE_COMMIT) 2759 idx += 1 2760 if ctx['num'] == idx: 2761 logger.info("Test: EAP-Failure") 2762 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 2763 2764 idx += 1 2765 if ctx['num'] == idx: 2766 logger.info("Test: Valid EAP-EKE-ID/Request") 2767 return struct.pack(">BBHBBBB4BB", 2768 EAP_CODE_REQUEST, ctx['id'], 2769 4 + 1 + 1 + 2 + 4 + 1, 2770 EAP_TYPE_EKE, 2771 EAP_EKE_ID, 2772 1, 0, 2773 1, 1, 1, 1, 2774 255) 2775 idx += 1 2776 if ctx['num'] == idx: 2777 logger.info("Test: All zeroes DHComponent_S and empty CBvalue in EAP-EKE-Commit/Request") 2778 return struct.pack(">BBHBB4L32L", 2779 EAP_CODE_REQUEST, ctx['id'], 2780 4 + 1 + 1 + 16 + 128, 2781 EAP_TYPE_EKE, 2782 EAP_EKE_COMMIT, 2783 0, 0, 0, 0, 2784 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2785 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) 2786 idx += 1 2787 if ctx['num'] == idx: 2788 logger.info("Test: Too short EAP-EKE-Confirm/Request") 2789 return struct.pack(">BBHBB", 2790 EAP_CODE_REQUEST, ctx['id'], 2791 4 + 1 + 1, 2792 EAP_TYPE_EKE, 2793 EAP_EKE_CONFIRM) 2794 idx += 1 2795 if ctx['num'] == idx: 2796 logger.info("Test: EAP-Failure") 2797 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 2798 2799 idx += 1 2800 if ctx['num'] == idx: 2801 logger.info("Test: Valid EAP-EKE-ID/Request") 2802 return struct.pack(">BBHBBBB4BB", 2803 EAP_CODE_REQUEST, ctx['id'], 2804 4 + 1 + 1 + 2 + 4 + 1, 2805 EAP_TYPE_EKE, 2806 EAP_EKE_ID, 2807 1, 0, 2808 1, 1, 1, 1, 2809 255) 2810 idx += 1 2811 if ctx['num'] == idx: 2812 logger.info("Test: All zeroes DHComponent_S and empty CBvalue in EAP-EKE-Commit/Request") 2813 return struct.pack(">BBHBB4L32L", 2814 EAP_CODE_REQUEST, ctx['id'], 2815 4 + 1 + 1 + 16 + 128, 2816 EAP_TYPE_EKE, 2817 EAP_EKE_COMMIT, 2818 0, 0, 0, 0, 2819 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2820 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) 2821 idx += 1 2822 if ctx['num'] == idx: 2823 logger.info("Test: Invalid PNonce_PS and Auth_S values in EAP-EKE-Confirm/Request") 2824 return struct.pack(">BBHBB4L8L5L5L", 2825 EAP_CODE_REQUEST, ctx['id'], 2826 4 + 1 + 1 + 16 + 2 * 16 + 20 + 20, 2827 EAP_TYPE_EKE, 2828 EAP_EKE_CONFIRM, 2829 0, 0, 0, 0, 2830 0, 0, 0, 0, 0, 0, 0, 0, 2831 0, 0, 0, 0, 0, 2832 0, 0, 0, 0, 0) 2833 idx += 1 2834 if ctx['num'] == idx: 2835 logger.info("Test: EAP-Failure") 2836 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 2837 2838 return None 2839 2840 srv = start_radius_server(eke_handler) 2841 2842 try: 2843 hapd = start_ap(apdev[0]) 2844 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 2845 2846 for i in range(0, 14): 2847 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 2848 eap="EKE", identity="user", password="password", 2849 wait_connect=False) 2850 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 2851 timeout=15) 2852 if ev is None: 2853 raise Exception("Timeout on EAP start") 2854 if i in [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]: 2855 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], 2856 timeout=10) 2857 if ev is None: 2858 raise Exception("Timeout on EAP failure") 2859 else: 2860 time.sleep(0.05) 2861 dev[0].request("REMOVE_NETWORK all") 2862 dev[0].dump_monitor() 2863 finally: 2864 stop_radius_server(srv) 2865 2866def eap_eke_test_fail(dev, phase1=None, success=False): 2867 dev.connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 2868 eap="EKE", identity="eke user@domain", password="hello", 2869 phase1=phase1, erp="1", wait_connect=False) 2870 ev = dev.wait_event(["CTRL-EVENT-EAP-FAILURE", 2871 "CTRL-EVENT-EAP-SUCCESS"], timeout=5) 2872 if ev is None: 2873 raise Exception("Timeout on EAP failure") 2874 if not success and "CTRL-EVENT-EAP-FAILURE" not in ev: 2875 raise Exception("EAP did not fail during failure test") 2876 dev.request("REMOVE_NETWORK all") 2877 dev.wait_disconnected() 2878 2879def test_eap_proto_eke_errors(dev, apdev): 2880 """EAP-EKE local error cases""" 2881 check_eap_capa(dev[0], "EKE") 2882 params = hostapd.wpa2_eap_params(ssid="eap-test") 2883 hapd = hostapd.add_ap(apdev[0], params) 2884 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 2885 2886 for i in range(1, 3): 2887 with alloc_fail(dev[0], i, "eap_eke_init"): 2888 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 2889 eap="EKE", identity="eke user", password="hello", 2890 wait_connect=False) 2891 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"], 2892 timeout=15) 2893 if ev is None: 2894 raise Exception("Timeout on EAP start") 2895 dev[0].request("REMOVE_NETWORK all") 2896 dev[0].wait_disconnected() 2897 2898 tests = [(1, "eap_eke_dh_init", None), 2899 (1, "eap_eke_prf_hmac_sha1", "dhgroup=3 encr=1 prf=1 mac=1"), 2900 (1, "eap_eke_prf_hmac_sha256", "dhgroup=5 encr=1 prf=2 mac=2"), 2901 (1, "eap_eke_prf_*", None), 2902 (1, "os_get_random;eap_eke_dhcomp", None), 2903 (1, "aes_128_cbc_encrypt;eap_eke_dhcomp", None), 2904 (1, "aes_128_cbc_decrypt;eap_eke_shared_secret", None), 2905 (1, "hmac_sha256_vector;eap_eke_shared_secret", None), 2906 (1, "eap_eke_prf_hmac_sha256;eap_eke_derive_ke_ki", None), 2907 (1, "eap_eke_prf_hmac_sha256;eap_eke_derive_ka", None), 2908 (1, "eap_eke_prf_hmac_sha256;eap_eke_derive_msk", None), 2909 (1, "os_get_random;eap_eke_prot", None), 2910 (1, "aes_128_cbc_decrypt;eap_eke_decrypt_prot", None), 2911 (1, "eap_eke_derive_key;eap_eke_process_commit", None), 2912 (1, "eap_eke_dh_init;eap_eke_process_commit", None), 2913 (1, "eap_eke_shared_secret;eap_eke_process_commit", None), 2914 (1, "eap_eke_derive_ke_ki;eap_eke_process_commit", None), 2915 (1, "eap_eke_dhcomp;eap_eke_process_commit", None), 2916 (1, "os_get_random;eap_eke_process_commit", None), 2917 (1, "os_get_random;=eap_eke_process_commit", None), 2918 (1, "eap_eke_prot;eap_eke_process_commit", None), 2919 (1, "eap_eke_decrypt_prot;eap_eke_process_confirm", None), 2920 (1, "eap_eke_derive_ka;eap_eke_process_confirm", None), 2921 (1, "eap_eke_auth;eap_eke_process_confirm", None), 2922 (2, "eap_eke_auth;eap_eke_process_confirm", None), 2923 (1, "eap_eke_prot;eap_eke_process_confirm", None), 2924 (1, "aes_128_cbc_encrypt;eap_eke_prot;eap_eke_process_confirm", None), 2925 (1, "hmac_sha256;eap_eke_prot;eap_eke_process_confirm", None), 2926 (1, "eap_eke_derive_msk;eap_eke_process_confirm", None)] 2927 for count, func, phase1 in tests: 2928 with fail_test(dev[0], count, func): 2929 eap_eke_test_fail(dev[0], phase1) 2930 2931 tests = [(1, "=eap_eke_derive_ke_ki", None), 2932 (1, "=eap_eke_derive_ka", None), 2933 (1, "=eap_eke_derive_msk", None), 2934 (1, "eap_eke_build_msg;eap_eke_process_id", None), 2935 (1, "wpabuf_alloc;eap_eke_process_id", None), 2936 (1, "=eap_eke_process_id", None), 2937 (1, "wpabuf_alloc;=eap_eke_process_id", None), 2938 (1, "wpabuf_alloc;eap_eke_process_id", None), 2939 (1, "eap_eke_build_msg;eap_eke_process_commit", None), 2940 (1, "wpabuf_resize;eap_eke_process_commit", None), 2941 (1, "eap_eke_build_msg;eap_eke_process_confirm", None)] 2942 for count, func, phase1 in tests: 2943 with alloc_fail(dev[0], count, func): 2944 eap_eke_test_fail(dev[0], phase1) 2945 2946 tests = [(1, "eap_eke_getKey", None), 2947 (1, "eap_eke_get_emsk", None), 2948 (1, "eap_eke_get_session_id", None)] 2949 for count, func, phase1 in tests: 2950 with alloc_fail(dev[0], count, func): 2951 eap_eke_test_fail(dev[0], phase1, success=True) 2952 2953EAP_PAX_OP_STD_1 = 0x01 2954EAP_PAX_OP_STD_2 = 0x02 2955EAP_PAX_OP_STD_3 = 0x03 2956EAP_PAX_OP_SEC_1 = 0x11 2957EAP_PAX_OP_SEC_2 = 0x12 2958EAP_PAX_OP_SEC_3 = 0x13 2959EAP_PAX_OP_SEC_4 = 0x14 2960EAP_PAX_OP_SEC_5 = 0x15 2961EAP_PAX_OP_ACK = 0x21 2962 2963EAP_PAX_FLAGS_MF = 0x01 2964EAP_PAX_FLAGS_CE = 0x02 2965EAP_PAX_FLAGS_AI = 0x04 2966 2967EAP_PAX_MAC_HMAC_SHA1_128 = 0x01 2968EAP_PAX_HMAC_SHA256_128 = 0x02 2969 2970EAP_PAX_DH_GROUP_NONE = 0x00 2971EAP_PAX_DH_GROUP_2048_MODP = 0x01 2972EAP_PAX_DH_GROUP_3072_MODP = 0x02 2973EAP_PAX_DH_GROUP_NIST_ECC_P_256 = 0x03 2974 2975EAP_PAX_PUBLIC_KEY_NONE = 0x00 2976EAP_PAX_PUBLIC_KEY_RSAES_OAEP = 0x01 2977EAP_PAX_PUBLIC_KEY_RSA_PKCS1_V1_5 = 0x02 2978EAP_PAX_PUBLIC_KEY_EL_GAMAL_NIST_ECC = 0x03 2979 2980EAP_PAX_ADE_VENDOR_SPECIFIC = 0x01 2981EAP_PAX_ADE_CLIENT_CHANNEL_BINDING = 0x02 2982EAP_PAX_ADE_SERVER_CHANNEL_BINDING = 0x03 2983 2984def test_eap_proto_pax(dev, apdev): 2985 """EAP-PAX protocol tests""" 2986 def pax_std_1(ctx): 2987 logger.info("Test: STD-1") 2988 ctx['id'] = 10 2989 return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'], 2990 4 + 1 + 5 + 2 + 32 + 16, 2991 EAP_TYPE_PAX, 2992 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128, 2993 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE, 2994 32, 0, 0, 0, 0, 0, 0, 0, 0, 2995 0x16, 0xc9, 0x08, 0x9d, 0x98, 0xa5, 0x6e, 0x1f, 2996 0xf0, 0xac, 0xcf, 0xc4, 0x66, 0xcd, 0x2d, 0xbf) 2997 2998 def pax_handler(ctx, req): 2999 logger.info("pax_handler - RX " + binascii.hexlify(req).decode()) 3000 if 'num' not in ctx: 3001 ctx['num'] = 0 3002 ctx['num'] = ctx['num'] + 1 3003 if 'id' not in ctx: 3004 ctx['id'] = 1 3005 ctx['id'] = (ctx['id'] + 1) % 256 3006 3007 idx = 0 3008 3009 idx += 1 3010 if ctx['num'] == idx: 3011 logger.info("Test: Missing payload") 3012 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 3013 4 + 1, 3014 EAP_TYPE_PAX) 3015 3016 idx += 1 3017 if ctx['num'] == idx: 3018 logger.info("Test: Minimum length payload") 3019 return struct.pack(">BBHB4L", EAP_CODE_REQUEST, ctx['id'], 3020 4 + 1 + 16, 3021 EAP_TYPE_PAX, 3022 0, 0, 0, 0) 3023 3024 idx += 1 3025 if ctx['num'] == idx: 3026 logger.info("Test: Unsupported MAC ID") 3027 return struct.pack(">BBHBBBBBB4L", EAP_CODE_REQUEST, ctx['id'], 3028 4 + 1 + 5 + 16, 3029 EAP_TYPE_PAX, 3030 EAP_PAX_OP_STD_1, 0, 255, EAP_PAX_DH_GROUP_NONE, 3031 EAP_PAX_PUBLIC_KEY_NONE, 3032 0, 0, 0, 0) 3033 3034 idx += 1 3035 if ctx['num'] == idx: 3036 logger.info("Test: Unsupported DH Group ID") 3037 return struct.pack(">BBHBBBBBB4L", EAP_CODE_REQUEST, ctx['id'], 3038 4 + 1 + 5 + 16, 3039 EAP_TYPE_PAX, 3040 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128, 3041 255, EAP_PAX_PUBLIC_KEY_NONE, 3042 0, 0, 0, 0) 3043 3044 idx += 1 3045 if ctx['num'] == idx: 3046 logger.info("Test: Unsupported Public Key ID") 3047 return struct.pack(">BBHBBBBBB4L", EAP_CODE_REQUEST, ctx['id'], 3048 4 + 1 + 5 + 16, 3049 EAP_TYPE_PAX, 3050 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128, 3051 EAP_PAX_DH_GROUP_NONE, 255, 3052 0, 0, 0, 0) 3053 3054 idx += 1 3055 if ctx['num'] == idx: 3056 logger.info("Test: More fragments") 3057 return struct.pack(">BBHBBBBBB4L", EAP_CODE_REQUEST, ctx['id'], 3058 4 + 1 + 5 + 16, 3059 EAP_TYPE_PAX, 3060 EAP_PAX_OP_STD_1, EAP_PAX_FLAGS_MF, 3061 EAP_PAX_MAC_HMAC_SHA1_128, 3062 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE, 3063 0, 0, 0, 0) 3064 3065 idx += 1 3066 if ctx['num'] == idx: 3067 logger.info("Test: Invalid ICV") 3068 return struct.pack(">BBHBBBBBB4L", EAP_CODE_REQUEST, ctx['id'], 3069 4 + 1 + 5 + 16, 3070 EAP_TYPE_PAX, 3071 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128, 3072 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE, 3073 0, 0, 0, 0) 3074 3075 idx += 1 3076 if ctx['num'] == idx: 3077 logger.info("Test: Invalid ICV in short frame") 3078 return struct.pack(">BBHBBBBBB3L", EAP_CODE_REQUEST, ctx['id'], 3079 4 + 1 + 5 + 12, 3080 EAP_TYPE_PAX, 3081 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128, 3082 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE, 3083 0, 0, 0) 3084 3085 idx += 1 3086 if ctx['num'] == idx: 3087 logger.info("Test: Correct ICV - unsupported op_code") 3088 ctx['id'] = 10 3089 return struct.pack(">BBHBBBBBB16B", EAP_CODE_REQUEST, ctx['id'], 3090 4 + 1 + 5 + 16, 3091 EAP_TYPE_PAX, 3092 255, 0, EAP_PAX_MAC_HMAC_SHA1_128, 3093 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE, 3094 0x90, 0x78, 0x97, 0x38, 0x29, 0x94, 0x32, 0xd4, 3095 0x81, 0x27, 0xe0, 0xf6, 0x3b, 0x0d, 0xb2, 0xb2) 3096 3097 idx += 1 3098 if ctx['num'] == idx: 3099 logger.info("Test: Correct ICV - CE flag in STD-1") 3100 ctx['id'] = 10 3101 return struct.pack(">BBHBBBBBB16B", EAP_CODE_REQUEST, ctx['id'], 3102 4 + 1 + 5 + 16, 3103 EAP_TYPE_PAX, 3104 EAP_PAX_OP_STD_1, EAP_PAX_FLAGS_CE, 3105 EAP_PAX_MAC_HMAC_SHA1_128, 3106 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE, 3107 0x9c, 0x98, 0xb4, 0x0b, 0x94, 0x90, 0xde, 0x88, 3108 0xb7, 0x72, 0x63, 0x44, 0x1d, 0xe3, 0x7c, 0x5c) 3109 3110 idx += 1 3111 if ctx['num'] == idx: 3112 logger.info("Test: Correct ICV - too short STD-1 payload") 3113 ctx['id'] = 10 3114 return struct.pack(">BBHBBBBBB16B", EAP_CODE_REQUEST, ctx['id'], 3115 4 + 1 + 5 + 16, 3116 EAP_TYPE_PAX, 3117 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128, 3118 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE, 3119 0xda, 0xab, 0x2c, 0xe7, 0x84, 0x41, 0xb5, 0x5c, 3120 0xee, 0xcf, 0x62, 0x03, 0xc5, 0x69, 0xcb, 0xf4) 3121 3122 idx += 1 3123 if ctx['num'] == idx: 3124 logger.info("Test: Correct ICV - incorrect A length in STD-1") 3125 ctx['id'] = 10 3126 return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'], 3127 4 + 1 + 5 + 2 + 32 + 16, 3128 EAP_TYPE_PAX, 3129 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128, 3130 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE, 3131 0, 0, 0, 0, 0, 0, 0, 0, 0, 3132 0xc4, 0xb0, 0x81, 0xe4, 0x6c, 0x8c, 0x20, 0x23, 3133 0x60, 0x46, 0x89, 0xea, 0x94, 0x60, 0xf3, 0x2a) 3134 3135 idx += 1 3136 if ctx['num'] == idx: 3137 logger.info("Test: Correct ICV - extra data in STD-1") 3138 ctx['id'] = 10 3139 return struct.pack(">BBHBBBBBBH8LB16B", EAP_CODE_REQUEST, ctx['id'], 3140 4 + 1 + 5 + 2 + 32 + 1 + 16, 3141 EAP_TYPE_PAX, 3142 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128, 3143 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE, 3144 32, 0, 0, 0, 0, 0, 0, 0, 0, 3145 1, 3146 0x61, 0x49, 0x65, 0x37, 0x21, 0xe8, 0xd8, 0xbf, 3147 0xf3, 0x02, 0x01, 0xe5, 0x42, 0x51, 0xd3, 0x34) 3148 idx += 1 3149 if ctx['num'] == idx: 3150 logger.info("Test: Unexpected STD-1") 3151 return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'], 3152 4 + 1 + 5 + 2 + 32 + 16, 3153 EAP_TYPE_PAX, 3154 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128, 3155 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE, 3156 32, 0, 0, 0, 0, 0, 0, 0, 0, 3157 0xe5, 0x1d, 0xbf, 0xb8, 0x70, 0x20, 0x5c, 0xba, 3158 0x41, 0xbb, 0x34, 0xda, 0x1a, 0x08, 0xe6, 0x8d) 3159 3160 idx += 1 3161 if ctx['num'] == idx: 3162 return pax_std_1(ctx) 3163 idx += 1 3164 if ctx['num'] == idx: 3165 logger.info("Test: MAC ID changed during session") 3166 return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'], 3167 4 + 1 + 5 + 2 + 32 + 16, 3168 EAP_TYPE_PAX, 3169 EAP_PAX_OP_STD_1, 0, EAP_PAX_HMAC_SHA256_128, 3170 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE, 3171 32, 0, 0, 0, 0, 0, 0, 0, 0, 3172 0xee, 0x00, 0xbf, 0xb8, 0x70, 0x20, 0x5c, 0xba, 3173 0x41, 0xbb, 0x34, 0xda, 0x1a, 0x08, 0xe6, 0x8d) 3174 3175 idx += 1 3176 if ctx['num'] == idx: 3177 return pax_std_1(ctx) 3178 idx += 1 3179 if ctx['num'] == idx: 3180 logger.info("Test: DH Group ID changed during session") 3181 return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'], 3182 4 + 1 + 5 + 2 + 32 + 16, 3183 EAP_TYPE_PAX, 3184 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128, 3185 EAP_PAX_DH_GROUP_2048_MODP, 3186 EAP_PAX_PUBLIC_KEY_NONE, 3187 32, 0, 0, 0, 0, 0, 0, 0, 0, 3188 0xee, 0x01, 0xbf, 0xb8, 0x70, 0x20, 0x5c, 0xba, 3189 0x41, 0xbb, 0x34, 0xda, 0x1a, 0x08, 0xe6, 0x8d) 3190 3191 idx += 1 3192 if ctx['num'] == idx: 3193 return pax_std_1(ctx) 3194 idx += 1 3195 if ctx['num'] == idx: 3196 logger.info("Test: Public Key ID changed during session") 3197 return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'], 3198 4 + 1 + 5 + 2 + 32 + 16, 3199 EAP_TYPE_PAX, 3200 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128, 3201 EAP_PAX_DH_GROUP_NONE, 3202 EAP_PAX_PUBLIC_KEY_RSAES_OAEP, 3203 32, 0, 0, 0, 0, 0, 0, 0, 0, 3204 0xee, 0x02, 0xbf, 0xb8, 0x70, 0x20, 0x5c, 0xba, 3205 0x41, 0xbb, 0x34, 0xda, 0x1a, 0x08, 0xe6, 0x8d) 3206 3207 idx += 1 3208 if ctx['num'] == idx: 3209 logger.info("Test: Unexpected STD-3") 3210 ctx['id'] = 10 3211 return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'], 3212 4 + 1 + 5 + 2 + 32 + 16, 3213 EAP_TYPE_PAX, 3214 EAP_PAX_OP_STD_3, 0, EAP_PAX_MAC_HMAC_SHA1_128, 3215 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE, 3216 32, 0, 0, 0, 0, 0, 0, 0, 0, 3217 0x47, 0xbb, 0xc0, 0xf9, 0xb9, 0x69, 0xf5, 0xcb, 3218 0x3a, 0xe8, 0xe7, 0xd6, 0x80, 0x28, 0xf2, 0x59) 3219 3220 idx += 1 3221 if ctx['num'] == idx: 3222 return pax_std_1(ctx) 3223 idx += 1 3224 if ctx['num'] == idx: 3225 # TODO: MAC calculation; for now, this gets dropped due to incorrect 3226 # ICV 3227 logger.info("Test: STD-3 with CE flag") 3228 return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'], 3229 4 + 1 + 5 + 2 + 32 + 16, 3230 EAP_TYPE_PAX, 3231 EAP_PAX_OP_STD_3, EAP_PAX_FLAGS_CE, 3232 EAP_PAX_MAC_HMAC_SHA1_128, 3233 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE, 3234 32, 0, 0, 0, 0, 0, 0, 0, 0, 3235 0x8a, 0xc2, 0xf9, 0xf4, 0x8b, 0x75, 0x72, 0xa2, 3236 0x4d, 0xd3, 0x1e, 0x54, 0x77, 0x04, 0x05, 0xe2) 3237 3238 idx += 1 3239 if ctx['num'] & 0x1 == idx & 0x1: 3240 logger.info("Test: Default request") 3241 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 3242 4 + 1, 3243 EAP_TYPE_PAX) 3244 else: 3245 logger.info("Test: Default EAP-Failure") 3246 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 3247 3248 srv = start_radius_server(pax_handler) 3249 3250 try: 3251 hapd = start_ap(apdev[0]) 3252 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 3253 3254 for i in range(0, 18): 3255 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 3256 eap="PAX", identity="user", 3257 password_hex="0123456789abcdef0123456789abcdef", 3258 wait_connect=False) 3259 logger.info("Waiting for EAP method to start") 3260 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 3261 timeout=15) 3262 if ev is None: 3263 raise Exception("Timeout on EAP start") 3264 time.sleep(0.05) 3265 dev[0].request("REMOVE_NETWORK all") 3266 dev[0].dump_monitor() 3267 3268 logger.info("Too short password") 3269 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 3270 eap="PAX", identity="user", 3271 password_hex="0123456789abcdef0123456789abcd", 3272 wait_connect=False) 3273 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15) 3274 if ev is None: 3275 raise Exception("Timeout on EAP start") 3276 time.sleep(0.1) 3277 dev[0].request("REMOVE_NETWORK all") 3278 dev[0].dump_monitor() 3279 3280 logger.info("No password") 3281 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 3282 eap="PAX", identity="user", 3283 wait_connect=False) 3284 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15) 3285 if ev is None: 3286 raise Exception("Timeout on EAP start") 3287 time.sleep(0.1) 3288 dev[0].request("REMOVE_NETWORK all") 3289 dev[0].dump_monitor() 3290 finally: 3291 stop_radius_server(srv) 3292 3293def test_eap_proto_pax_errors(dev, apdev): 3294 """EAP-PAX local error cases""" 3295 check_eap_capa(dev[0], "PAX") 3296 params = hostapd.wpa2_eap_params(ssid="eap-test") 3297 hapd = hostapd.add_ap(apdev[0], params) 3298 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 3299 3300 for i in range(1, 3): 3301 with alloc_fail(dev[0], i, "eap_pax_init"): 3302 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 3303 eap="PAX", identity="pax.user@example.com", 3304 password_hex="0123456789abcdef0123456789abcdef", 3305 wait_connect=False) 3306 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"], 3307 timeout=15) 3308 if ev is None: 3309 raise Exception("Timeout on EAP start") 3310 dev[0].request("REMOVE_NETWORK all") 3311 dev[0].wait_disconnected() 3312 3313 tests = ["eap_msg_alloc;eap_pax_alloc_resp;eap_pax_process_std_1", 3314 "eap_msg_alloc;eap_pax_alloc_resp;eap_pax_process_std_3", 3315 "eap_pax_getKey", 3316 "eap_pax_get_emsk", 3317 "eap_pax_get_session_id"] 3318 for func in tests: 3319 with alloc_fail(dev[0], 1, func): 3320 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 3321 eap="PAX", identity="pax.user@example.com", 3322 password_hex="0123456789abcdef0123456789abcdef", 3323 erp="1", wait_connect=False) 3324 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 3325 dev[0].request("REMOVE_NETWORK all") 3326 dev[0].wait_disconnected() 3327 3328 tests = [(1, "os_get_random;eap_pax_process_std_1"), 3329 (1, "eap_pax_initial_key_derivation"), 3330 (1, "eap_pax_mac;eap_pax_process_std_3"), 3331 (2, "eap_pax_mac;eap_pax_process_std_3"), 3332 (1, "eap_pax_kdf;eap_pax_getKey"), 3333 (1, "eap_pax_kdf;eap_pax_get_emsk")] 3334 for count, func in tests: 3335 with fail_test(dev[0], count, func): 3336 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 3337 eap="PAX", identity="pax.user@example.com", 3338 password_hex="0123456789abcdef0123456789abcdef", 3339 erp="1", wait_connect=False) 3340 wait_fail_trigger(dev[0], "GET_FAIL") 3341 dev[0].request("REMOVE_NETWORK all") 3342 dev[0].wait_disconnected() 3343 3344def run_eap_pax_connect(dev): 3345 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412", 3346 eap="PAX", identity="pax.user@example.com", 3347 password_hex="0123456789abcdef0123456789abcdef", 3348 wait_connect=False) 3349 ev = dev.wait_event(["CTRL-EVENT-EAP-SUCCESS", "CTRL-EVENT-EAP-FAILURE", 3350 "CTRL-EVENT-DISCONNECTED"], 3351 timeout=1) 3352 dev.request("REMOVE_NETWORK all") 3353 if not ev or "CTRL-EVENT-DISCONNECTED" not in ev: 3354 dev.wait_disconnected() 3355 dev.dump_monitor() 3356 3357def test_eap_proto_pax_errors_server(dev, apdev): 3358 """EAP-PAX local error cases on server""" 3359 check_eap_capa(dev[0], "PAX") 3360 params = int_eap_server_params() 3361 params['erp_domain'] = 'example.com' 3362 params['eap_server_erp'] = '1' 3363 hapd = hostapd.add_ap(apdev[0], params) 3364 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 3365 3366 tests = [(1, "eap_pax_init"), 3367 (1, "eap_msg_alloc;eap_pax_build_std_1"), 3368 (1, "eap_msg_alloc;eap_pax_build_std_3"), 3369 (1, "=eap_pax_process_std_2"), 3370 (1, "eap_pax_getKey"), 3371 (1, "eap_pax_get_emsk"), 3372 (1, "eap_pax_get_session_id")] 3373 for count, func in tests: 3374 with alloc_fail(hapd, count, func): 3375 run_eap_pax_connect(dev[0]) 3376 3377 tests = [(1, "os_get_random;eap_pax_build_std_1"), 3378 (1, "eap_pax_mac;eap_pax_build_std_1"), 3379 (1, "eap_pax_mac;eap_pax_build_std_3"), 3380 (2, "eap_pax_mac;=eap_pax_build_std_3"), 3381 (1, "eap_pax_initial_key_derivation;eap_pax_process_std_2"), 3382 (1, "eap_pax_mac;eap_pax_process_std_2"), 3383 (2, "eap_pax_mac;=eap_pax_process_std_2"), 3384 (1, "eap_pax_mac;eap_pax_check")] 3385 for count, func in tests: 3386 with fail_test(hapd, count, func): 3387 run_eap_pax_connect(dev[0]) 3388 3389def start_pax_assoc(dev, hapd): 3390 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412", 3391 eap="PAX", identity="pax.user@example.com", 3392 password_hex="0123456789abcdef0123456789abcdef", 3393 wait_connect=False) 3394 proxy_msg(hapd, dev) # EAP-Identity/Request 3395 proxy_msg(dev, hapd) # EAP-Identity/Response 3396 proxy_msg(hapd, dev) # PAX_STD-1 3397 3398def stop_pax_assoc(dev, hapd): 3399 dev.request("REMOVE_NETWORK all") 3400 dev.wait_disconnected() 3401 dev.dump_monitor() 3402 hapd.dump_monitor() 3403 3404def test_eap_proto_pax_server(dev, apdev): 3405 """EAP-PAX protocol testing for the server""" 3406 check_eap_capa(dev[0], "PAX") 3407 params = int_eap_server_params() 3408 params['erp_domain'] = 'example.com' 3409 params['eap_server_erp'] = '1' 3410 hapd = hostapd.add_ap(apdev[0], params) 3411 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 3412 hapd.request("SET ext_eapol_frame_io 1") 3413 dev[0].request("SET ext_eapol_frame_io 1") 3414 3415 # Successful exchange to verify proxying mechanism 3416 start_pax_assoc(dev[0], hapd) 3417 proxy_msg(dev[0], hapd) # PAX_STD-2 3418 proxy_msg(hapd, dev[0]) # PAX_STD-3 3419 proxy_msg(dev[0], hapd) # PAX-ACK 3420 proxy_msg(hapd, dev[0]) # EAP-Success 3421 proxy_msg(hapd, dev[0]) # EAPOL-Key msg 1/4 3422 proxy_msg(dev[0], hapd) # EAPOL-Key msg 2/4 3423 proxy_msg(hapd, dev[0]) # EAPOL-Key msg 3/4 3424 proxy_msg(dev[0], hapd) # EAPOL-Key msg 4/4 3425 dev[0].wait_connected() 3426 stop_pax_assoc(dev[0], hapd) 3427 3428 start_pax_assoc(dev[0], hapd) 3429 resp = rx_msg(dev[0]) 3430 # Too short EAP-PAX header (no OP-Code) 3431 hapd.note("EAP-PAX: Invalid frame") 3432 msg = resp[0:4] + "0005" + resp[8:12] + "0005" + "2e" 3433 tx_msg(dev[0], hapd, msg) 3434 # Too short EAP-PAX message (no payload) 3435 hapd.note("EAP-PAX: Invalid frame") 3436 msg = resp[0:4] + "000a" + resp[8:12] + "000a" + "2e1100000000" 3437 tx_msg(dev[0], hapd, msg) 3438 # Unexpected PAX_SEC-2 3439 hapd.note("EAP-PAX: Expected PAX_STD-2 - ignore op 17") 3440 msg = resp[0:4] + "001a" + resp[8:12] + "001a" + "2e1100000000" + 16*"00" 3441 tx_msg(dev[0], hapd, msg) 3442 # Unexpected MAC ID 3443 hapd.note("EAP-PAX: Expected MAC ID 0x1, received 0xff") 3444 msg = resp[0:4] + "001a" + resp[8:12] + "001a" + "2e0200ff0000" + 16*"00" 3445 tx_msg(dev[0], hapd, msg) 3446 # Unexpected DH Group ID 3447 hapd.note("EAP-PAX: Expected DH Group ID 0x0, received 0xff") 3448 msg = resp[0:4] + "001a" + resp[8:12] + "001a" + "2e020001ff00" + 16*"00" 3449 tx_msg(dev[0], hapd, msg) 3450 # Unexpected Public Key ID 3451 hapd.note("EAP-PAX: Expected Public Key ID 0x0, received 0xff") 3452 msg = resp[0:4] + "001a" + resp[8:12] + "001a" + "2e02000100ff" + 16*"00" 3453 tx_msg(dev[0], hapd, msg) 3454 # Unsupported Flags - MF 3455 hapd.note("EAP-PAX: fragmentation not supported") 3456 msg = resp[0:4] + "001a" + resp[8:12] + "001a" + "2e0201010000" + 16*"00" 3457 tx_msg(dev[0], hapd, msg) 3458 # Unsupported Flags - CE 3459 hapd.note("EAP-PAX: Unexpected CE flag") 3460 msg = resp[0:4] + "001a" + resp[8:12] + "001a" + "2e0202010000" + 16*"00" 3461 tx_msg(dev[0], hapd, msg) 3462 # Too short Payload in PAX_STD-2 3463 hapd.note("EAP-PAX: Too short PAX_STD-2 (B)") 3464 msg = resp[0:4] + "001a" + resp[8:12] + "001a" + "2e0200010000" + 16*"00" 3465 tx_msg(dev[0], hapd, msg) 3466 rx_msg(hapd) 3467 stop_pax_assoc(dev[0], hapd) 3468 3469 start_pax_assoc(dev[0], hapd) 3470 resp = rx_msg(dev[0]) 3471 # Too short Payload in PAX_STD-2 3472 hapd.note("EAP-PAX: Too short PAX_STD-2 (CID)") 3473 msg = resp[0:4] + "002c" + resp[8:12] + "002c" + "2e0200010000" + "0020" + 32*"00" 3474 tx_msg(dev[0], hapd, msg) 3475 rx_msg(hapd) 3476 stop_pax_assoc(dev[0], hapd) 3477 3478 start_pax_assoc(dev[0], hapd) 3479 resp = rx_msg(dev[0]) 3480 # Too short Payload in PAX_STD-2 3481 hapd.note("EAP-PAX: Too short PAX_STD-2 (CID)") 3482 msg = resp[0:4] + "002e" + resp[8:12] + "002e" + "2e0200010000" + "0020" + 32*"00" + "ffff" 3483 tx_msg(dev[0], hapd, msg) 3484 rx_msg(hapd) 3485 stop_pax_assoc(dev[0], hapd) 3486 3487 start_pax_assoc(dev[0], hapd) 3488 resp = rx_msg(dev[0]) 3489 # Too long CID in PAX_STD-2 3490 hapd.note("EAP-PAX: Too long CID") 3491 msg = resp[0:4] + "062e" + resp[8:12] + "062e" + "2e0200010000" + "0020" + 32*"00" + "0600" + 1536*"00" 3492 tx_msg(dev[0], hapd, msg) 3493 rx_msg(hapd) 3494 stop_pax_assoc(dev[0], hapd) 3495 3496 start_pax_assoc(dev[0], hapd) 3497 resp = rx_msg(dev[0]) 3498 # Too short Payload in PAX_STD-2 3499 hapd.note("EAP-PAX: Too short PAX_STD-2 (MAC_CK)") 3500 msg = resp[0:4] + "003c" + resp[8:12] + "003c" + "2e0200010000" + "0020" + 32*"00" + 16*"00" 3501 tx_msg(dev[0], hapd, msg) 3502 rx_msg(hapd) 3503 stop_pax_assoc(dev[0], hapd) 3504 3505 start_pax_assoc(dev[0], hapd) 3506 resp = rx_msg(dev[0]) 3507 # Unknown CID for PAX 3508 hapd.note("EAP-PAX: EAP-PAX not enabled for CID") 3509 msg = resp[0:4] + "0041" + resp[8:12] + "0041" + "2e0200010000" + "0020" + 32*"00" + "0001" + "00" + "0010" + 16*"00" 3510 tx_msg(dev[0], hapd, msg) 3511 rx_msg(hapd) 3512 stop_pax_assoc(dev[0], hapd) 3513 3514 start_pax_assoc(dev[0], hapd) 3515 resp = rx_msg(dev[0]) 3516 # Too short ICV 3517 hapd.note("EAP-PAX: Too short ICV (15) in PAX_STD-2") 3518 msg = resp[0:4] + "0063" + resp[8:12] + "0063" + resp[16:206] 3519 tx_msg(dev[0], hapd, msg) 3520 rx_msg(hapd) 3521 stop_pax_assoc(dev[0], hapd) 3522 3523 start_pax_assoc(dev[0], hapd) 3524 proxy_msg(dev[0], hapd) # PAX_STD-2 3525 proxy_msg(hapd, dev[0]) # PAX_STD-3 3526 resp = rx_msg(dev[0]) 3527 # Unexpected PAX_STD-2 3528 hapd.note("EAP-PAX: Expected PAX-ACK - ignore op 1") 3529 msg = resp[0:4] + "001a" + resp[8:12] + "001a" + "2e0100000000" + 16*"00" 3530 tx_msg(dev[0], hapd, msg) 3531 stop_pax_assoc(dev[0], hapd) 3532 3533def test_eap_proto_psk(dev, apdev): 3534 """EAP-PSK protocol tests""" 3535 def psk_handler(ctx, req): 3536 logger.info("psk_handler - RX " + binascii.hexlify(req).decode()) 3537 if 'num' not in ctx: 3538 ctx['num'] = 0 3539 ctx['num'] = ctx['num'] + 1 3540 if 'id' not in ctx: 3541 ctx['id'] = 1 3542 ctx['id'] = (ctx['id'] + 1) % 256 3543 3544 idx = 0 3545 3546 idx += 1 3547 if ctx['num'] == idx: 3548 logger.info("Test: Missing payload") 3549 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 3550 4 + 1, 3551 EAP_TYPE_PSK) 3552 3553 idx += 1 3554 if ctx['num'] == idx: 3555 logger.info("Test: Non-zero T in first message") 3556 return struct.pack(">BBHBB4L", EAP_CODE_REQUEST, ctx['id'], 3557 4 + 1 + 1 + 16, 3558 EAP_TYPE_PSK, 0xc0, 0, 0, 0, 0) 3559 3560 idx += 1 3561 if ctx['num'] == idx: 3562 logger.info("Test: Valid first message") 3563 return struct.pack(">BBHBB4L", EAP_CODE_REQUEST, ctx['id'], 3564 4 + 1 + 1 + 16, 3565 EAP_TYPE_PSK, 0, 0, 0, 0, 0) 3566 idx += 1 3567 if ctx['num'] == idx: 3568 logger.info("Test: Too short third message") 3569 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 3570 4 + 1, 3571 EAP_TYPE_PSK) 3572 3573 idx += 1 3574 if ctx['num'] == idx: 3575 logger.info("Test: Valid first message") 3576 return struct.pack(">BBHBB4L", EAP_CODE_REQUEST, ctx['id'], 3577 4 + 1 + 1 + 16, 3578 EAP_TYPE_PSK, 0, 0, 0, 0, 0) 3579 idx += 1 3580 if ctx['num'] == idx: 3581 logger.info("Test: Incorrect T in third message") 3582 return struct.pack(">BBHBB4L4L", EAP_CODE_REQUEST, ctx['id'], 3583 4 + 1 + 1 + 16 + 16, 3584 EAP_TYPE_PSK, 0, 0, 0, 0, 0, 0, 0, 0, 0) 3585 3586 idx += 1 3587 if ctx['num'] == idx: 3588 logger.info("Test: Valid first message") 3589 return struct.pack(">BBHBB4L", EAP_CODE_REQUEST, ctx['id'], 3590 4 + 1 + 1 + 16, 3591 EAP_TYPE_PSK, 0, 0, 0, 0, 0) 3592 idx += 1 3593 if ctx['num'] == idx: 3594 logger.info("Test: Missing PCHANNEL in third message") 3595 return struct.pack(">BBHBB4L4L", EAP_CODE_REQUEST, ctx['id'], 3596 4 + 1 + 1 + 16 + 16, 3597 EAP_TYPE_PSK, 0x80, 0, 0, 0, 0, 0, 0, 0, 0) 3598 3599 idx += 1 3600 if ctx['num'] == idx: 3601 logger.info("Test: Valid first message") 3602 return struct.pack(">BBHBB4L", EAP_CODE_REQUEST, ctx['id'], 3603 4 + 1 + 1 + 16, 3604 EAP_TYPE_PSK, 0, 0, 0, 0, 0) 3605 idx += 1 3606 if ctx['num'] == idx: 3607 logger.info("Test: Invalic MAC_S in third message") 3608 return struct.pack(">BBHBB4L4L5LB", EAP_CODE_REQUEST, ctx['id'], 3609 4 + 1 + 1 + 16 + 16 + 21, 3610 EAP_TYPE_PSK, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 3611 0, 0, 0, 0, 0, 0) 3612 3613 idx += 1 3614 if ctx['num'] == idx: 3615 logger.info("Test: Valid first message") 3616 return struct.pack(">BBHBB4L", EAP_CODE_REQUEST, ctx['id'], 3617 4 + 1 + 1 + 16, 3618 EAP_TYPE_PSK, 0, 0, 0, 0, 0) 3619 idx += 1 3620 if ctx['num'] == idx: 3621 logger.info("Test: EAP-Failure") 3622 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 3623 3624 return None 3625 3626 srv = start_radius_server(psk_handler) 3627 3628 try: 3629 hapd = start_ap(apdev[0]) 3630 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 3631 3632 for i in range(0, 6): 3633 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 3634 eap="PSK", identity="user", 3635 password_hex="0123456789abcdef0123456789abcdef", 3636 wait_connect=False) 3637 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 3638 timeout=15) 3639 if ev is None: 3640 raise Exception("Timeout on EAP start") 3641 time.sleep(0.1) 3642 dev[0].request("REMOVE_NETWORK all") 3643 3644 logger.info("Test: Invalid PSK length") 3645 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 3646 eap="PSK", identity="user", 3647 password_hex="0123456789abcdef0123456789abcd", 3648 wait_connect=False) 3649 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 3650 timeout=15) 3651 if ev is None: 3652 raise Exception("Timeout on EAP start") 3653 time.sleep(0.1) 3654 dev[0].request("REMOVE_NETWORK all") 3655 finally: 3656 stop_radius_server(srv) 3657 3658def test_eap_proto_psk_errors(dev, apdev): 3659 """EAP-PSK local error cases""" 3660 check_eap_capa(dev[0], "PSK") 3661 params = hostapd.wpa2_eap_params(ssid="eap-test") 3662 hapd = hostapd.add_ap(apdev[0], params) 3663 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 3664 3665 for i in range(1, 3): 3666 with alloc_fail(dev[0], i, "eap_psk_init"): 3667 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 3668 eap="PSK", identity="psk.user@example.com", 3669 password_hex="0123456789abcdef0123456789abcdef", 3670 wait_connect=False) 3671 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"], 3672 timeout=15) 3673 if ev is None: 3674 raise Exception("Timeout on EAP start") 3675 dev[0].request("REMOVE_NETWORK all") 3676 dev[0].wait_disconnected() 3677 3678 for i in range(1, 4): 3679 with fail_test(dev[0], i, "eap_psk_key_setup;eap_psk_init"): 3680 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 3681 eap="PSK", identity="psk.user@example.com", 3682 password_hex="0123456789abcdef0123456789abcdef", 3683 wait_connect=False) 3684 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"], 3685 timeout=15) 3686 if ev is None: 3687 raise Exception("Timeout on EAP start") 3688 dev[0].request("REMOVE_NETWORK all") 3689 dev[0].wait_disconnected() 3690 3691 tests = [(1, "=eap_psk_process_1"), 3692 (2, "=eap_psk_process_1"), 3693 (1, "eap_msg_alloc;eap_psk_process_1"), 3694 (1, "=eap_psk_process_3"), 3695 (2, "=eap_psk_process_3"), 3696 (1, "eap_msg_alloc;eap_psk_process_3"), 3697 (1, "eap_psk_getKey"), 3698 (1, "eap_psk_get_session_id"), 3699 (1, "eap_psk_get_emsk")] 3700 for count, func in tests: 3701 with alloc_fail(dev[0], count, func): 3702 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 3703 eap="PSK", identity="psk.user@example.com", 3704 password_hex="0123456789abcdef0123456789abcdef", 3705 erp="1", wait_connect=False) 3706 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 3707 timeout=15) 3708 if ev is None: 3709 raise Exception("Timeout on EAP start") 3710 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL", 3711 note="No allocation failure seen for %d:%s" % (count, func)) 3712 dev[0].request("REMOVE_NETWORK all") 3713 dev[0].wait_disconnected() 3714 3715 tests = [(1, "os_get_random;eap_psk_process_1"), 3716 (1, "omac1_aes_128;eap_psk_process_3"), 3717 (1, "=omac1_aes_vector;omac1_aes_128;aes_128_eax_encrypt"), 3718 (2, "=omac1_aes_vector;omac1_aes_128;aes_128_eax_encrypt"), 3719 (3, "=omac1_aes_vector;omac1_aes_128;aes_128_eax_encrypt"), 3720 (1, "=omac1_aes_vector;omac1_aes_128;aes_128_eax_decrypt"), 3721 (2, "=omac1_aes_vector;omac1_aes_128;aes_128_eax_decrypt"), 3722 (3, "=omac1_aes_vector;omac1_aes_128;aes_128_eax_decrypt"), 3723 (1, "aes_128_eax_decrypt;eap_psk_process_3"), 3724 (2, "aes_128_eax_decrypt;eap_psk_process_3"), 3725 (3, "aes_128_eax_decrypt;eap_psk_process_3"), 3726 (1, "aes_128_eax_encrypt;eap_psk_process_3"), 3727 (2, "aes_128_eax_encrypt;eap_psk_process_3"), 3728 (3, "aes_128_eax_encrypt;eap_psk_process_3"), 3729 (1, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"), 3730 (2, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"), 3731 (3, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"), 3732 (4, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"), 3733 (5, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"), 3734 (6, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"), 3735 (7, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"), 3736 (8, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"), 3737 (9, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"), 3738 (10, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"), 3739 (1, "aes_ctr_encrypt;aes_128_eax_decrypt;eap_psk_process_3"), 3740 (1, "aes_ctr_encrypt;aes_128_eax_encrypt;eap_psk_process_3")] 3741 for count, func in tests: 3742 with fail_test(dev[0], count, func): 3743 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 3744 eap="PSK", identity="psk.user@example.com", 3745 password_hex="0123456789abcdef0123456789abcdef", 3746 wait_connect=False) 3747 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 3748 timeout=15) 3749 if ev is None: 3750 raise Exception("Timeout on EAP start") 3751 wait_fail_trigger(dev[0], "GET_FAIL", 3752 note="No failure seen for %d:%s" % (count, func)) 3753 dev[0].request("REMOVE_NETWORK all") 3754 dev[0].wait_disconnected() 3755 dev[0].dump_monitor() 3756 3757def run_eap_psk_connect(dev): 3758 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412", 3759 eap="PSK", identity="psk.user@example.com", 3760 password_hex="0123456789abcdef0123456789abcdef", 3761 wait_connect=False) 3762 ev = dev.wait_event(["CTRL-EVENT-EAP-SUCCESS", "CTRL-EVENT-EAP-FAILURE", 3763 "CTRL-EVENT-DISCONNECTED"], 3764 timeout=1) 3765 dev.request("REMOVE_NETWORK all") 3766 if not ev or "CTRL-EVENT-DISCONNECTED" not in ev: 3767 dev.wait_disconnected() 3768 dev.dump_monitor() 3769 3770def test_eap_proto_psk_errors_server(dev, apdev): 3771 """EAP-PSK local error cases on server""" 3772 check_eap_capa(dev[0], "PSK") 3773 params = int_eap_server_params() 3774 params['erp_domain'] = 'example.com' 3775 params['eap_server_erp'] = '1' 3776 hapd = hostapd.add_ap(apdev[0], params) 3777 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 3778 3779 tests = [(1, "eap_psk_init"), 3780 (1, "eap_msg_alloc;eap_psk_build_1"), 3781 (1, "eap_msg_alloc;eap_psk_build_3"), 3782 (1, "=eap_psk_build_3"), 3783 (1, "=eap_psk_process_2"), 3784 (2, "=eap_psk_process_2"), 3785 (1, "=eap_psk_process_4"), 3786 (1, "aes_128_eax_decrypt;eap_psk_process_4"), 3787 (1, "eap_psk_getKey"), 3788 (1, "eap_psk_get_emsk"), 3789 (1, "eap_psk_get_session_id")] 3790 for count, func in tests: 3791 with alloc_fail(hapd, count, func): 3792 run_eap_psk_connect(dev[0]) 3793 3794 tests = [(1, "os_get_random;eap_psk_build_1"), 3795 (1, "omac1_aes_128;eap_psk_build_3"), 3796 (1, "eap_psk_derive_keys;eap_psk_build_3"), 3797 (1, "aes_128_eax_encrypt;eap_psk_build_3"), 3798 (1, "eap_psk_key_setup;eap_psk_process_2"), 3799 (1, "omac1_aes_128;eap_psk_process_2"), 3800 (1, "aes_128_eax_decrypt;eap_psk_process_4")] 3801 for count, func in tests: 3802 with fail_test(hapd, count, func): 3803 run_eap_psk_connect(dev[0]) 3804 3805def start_psk_assoc(dev, hapd): 3806 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412", 3807 eap="PSK", identity="psk.user@example.com", 3808 password_hex="0123456789abcdef0123456789abcdef", 3809 wait_connect=False) 3810 proxy_msg(hapd, dev) # EAP-Identity/Request 3811 proxy_msg(dev, hapd) # EAP-Identity/Response 3812 proxy_msg(hapd, dev) # PSK-1 3813 3814def stop_psk_assoc(dev, hapd): 3815 dev.request("REMOVE_NETWORK all") 3816 dev.wait_disconnected() 3817 dev.dump_monitor() 3818 hapd.dump_monitor() 3819 3820def test_eap_proto_psk_server(dev, apdev): 3821 """EAP-PSK protocol testing for the server""" 3822 check_eap_capa(dev[0], "PSK") 3823 params = int_eap_server_params() 3824 params['erp_domain'] = 'example.com' 3825 params['eap_server_erp'] = '1' 3826 hapd = hostapd.add_ap(apdev[0], params) 3827 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 3828 hapd.request("SET ext_eapol_frame_io 1") 3829 dev[0].request("SET ext_eapol_frame_io 1") 3830 3831 # Successful exchange to verify proxying mechanism 3832 start_psk_assoc(dev[0], hapd) 3833 proxy_msg(dev[0], hapd) # PSK-2 3834 proxy_msg(hapd, dev[0]) # PSK-3 3835 proxy_msg(dev[0], hapd) # PSK-4 3836 proxy_msg(hapd, dev[0]) # EAP-Success 3837 proxy_msg(hapd, dev[0]) # EAPOL-Key msg 1/4 3838 proxy_msg(dev[0], hapd) # EAPOL-Key msg 2/4 3839 proxy_msg(hapd, dev[0]) # EAPOL-Key msg 3/4 3840 proxy_msg(dev[0], hapd) # EAPOL-Key msg 4/4 3841 dev[0].wait_connected() 3842 stop_psk_assoc(dev[0], hapd) 3843 3844 start_psk_assoc(dev[0], hapd) 3845 resp = rx_msg(dev[0]) 3846 # Too short EAP-PSK header (no Flags) 3847 hapd.note("EAP-PSK: Invalid frame") 3848 msg = resp[0:4] + "0005" + resp[8:12] + "0005" + "2f" 3849 tx_msg(dev[0], hapd, msg) 3850 # Unexpected PSK-1 3851 hapd.note("EAP-PSK: Expected PSK-2 - ignore T=0") 3852 msg = resp[0:4] + "0006" + resp[8:12] + "0006" + "2f00" 3853 tx_msg(dev[0], hapd, msg) 3854 # Too short PSK-2 3855 hapd.note("EAP-PSK: Too short frame") 3856 msg = resp[0:4] + "0006" + resp[8:12] + "0006" + "2f40" 3857 tx_msg(dev[0], hapd, msg) 3858 # PSK-2 with unknown ID_P 3859 hapd.note("EAP-PSK: EAP-PSK not enabled for ID_P") 3860 msg = resp[0:4] + "004a" + resp[8:12] + "004a" + "2f40" + 3*16*"00" + 20*"00" 3861 tx_msg(dev[0], hapd, msg) 3862 rx_msg(hapd) # EAP-Failure 3863 stop_psk_assoc(dev[0], hapd) 3864 3865 start_psk_assoc(dev[0], hapd) 3866 proxy_msg(dev[0], hapd) # PSK-2 3867 proxy_msg(hapd, dev[0]) # PSK-3 3868 resp = rx_msg(dev[0]) 3869 # Unexpected PSK-2 3870 hapd.note("EAP-PSK: Expected PSK-4 - ignore T=1") 3871 msg = resp[0:4] + "0016" + resp[8:12] + "0016" + "2f40" + 16*"00" 3872 tx_msg(dev[0], hapd, msg) 3873 # Too short PSK-4 (no PCHANNEL) 3874 hapd.note("EAP-PSK: Too short PCHANNEL data in PSK-4 (len=0, expected 21)") 3875 msg = resp[0:4] + "0016" + resp[8:12] + "0016" + "2fc0" + 16*"00" 3876 tx_msg(dev[0], hapd, msg) 3877 rx_msg(hapd) # PSK-3 retry 3878 stop_psk_assoc(dev[0], hapd) 3879 3880 start_psk_assoc(dev[0], hapd) 3881 proxy_msg(dev[0], hapd) # PSK-2 3882 proxy_msg(hapd, dev[0]) # PSK-3 3883 resp = rx_msg(dev[0]) 3884 # PCHANNEL Nonce did not increase 3885 hapd.note("EAP-PSK: Nonce did not increase") 3886 msg = resp[0:4] + "002b" + resp[8:12] + "002b" + "2fc0" + 16*"00" + 21*"00" 3887 tx_msg(dev[0], hapd, msg) 3888 rx_msg(hapd) # PSK-3 retry 3889 stop_psk_assoc(dev[0], hapd) 3890 3891 start_psk_assoc(dev[0], hapd) 3892 proxy_msg(dev[0], hapd) # PSK-2 3893 proxy_msg(hapd, dev[0]) # PSK-3 3894 resp = rx_msg(dev[0]) 3895 # Invalid PCHANNEL encryption 3896 hapd.note("EAP-PSK: PCHANNEL decryption failed") 3897 msg = resp[0:4] + "002b" + resp[8:12] + "002b" + "2fc0" + 16*"00" + 21*"11" 3898 tx_msg(dev[0], hapd, msg) 3899 rx_msg(hapd) # PSK-3 retry 3900 stop_psk_assoc(dev[0], hapd) 3901 3902EAP_SIM_SUBTYPE_START = 10 3903EAP_SIM_SUBTYPE_CHALLENGE = 11 3904EAP_SIM_SUBTYPE_NOTIFICATION = 12 3905EAP_SIM_SUBTYPE_REAUTHENTICATION = 13 3906EAP_SIM_SUBTYPE_CLIENT_ERROR = 14 3907 3908EAP_AKA_SUBTYPE_CHALLENGE = 1 3909EAP_AKA_SUBTYPE_AUTHENTICATION_REJECT = 2 3910EAP_AKA_SUBTYPE_SYNCHRONIZATION_FAILURE = 4 3911EAP_AKA_SUBTYPE_IDENTITY = 5 3912EAP_AKA_SUBTYPE_NOTIFICATION = 12 3913EAP_AKA_SUBTYPE_REAUTHENTICATION = 13 3914EAP_AKA_SUBTYPE_CLIENT_ERROR = 14 3915 3916EAP_SIM_AT_RAND = 1 3917EAP_SIM_AT_AUTN = 2 3918EAP_SIM_AT_RES = 3 3919EAP_SIM_AT_AUTS = 4 3920EAP_SIM_AT_PADDING = 6 3921EAP_SIM_AT_NONCE_MT = 7 3922EAP_SIM_AT_PERMANENT_ID_REQ = 10 3923EAP_SIM_AT_MAC = 11 3924EAP_SIM_AT_NOTIFICATION = 12 3925EAP_SIM_AT_ANY_ID_REQ = 13 3926EAP_SIM_AT_IDENTITY = 14 3927EAP_SIM_AT_VERSION_LIST = 15 3928EAP_SIM_AT_SELECTED_VERSION = 16 3929EAP_SIM_AT_FULLAUTH_ID_REQ = 17 3930EAP_SIM_AT_COUNTER = 19 3931EAP_SIM_AT_COUNTER_TOO_SMALL = 20 3932EAP_SIM_AT_NONCE_S = 21 3933EAP_SIM_AT_CLIENT_ERROR_CODE = 22 3934EAP_SIM_AT_KDF_INPUT = 23 3935EAP_SIM_AT_KDF = 24 3936EAP_SIM_AT_IV = 129 3937EAP_SIM_AT_ENCR_DATA = 130 3938EAP_SIM_AT_NEXT_PSEUDONYM = 132 3939EAP_SIM_AT_NEXT_REAUTH_ID = 133 3940EAP_SIM_AT_CHECKCODE = 134 3941EAP_SIM_AT_RESULT_IND = 135 3942EAP_SIM_AT_BIDDING = 136 3943 3944def test_eap_proto_aka(dev, apdev): 3945 """EAP-AKA protocol tests""" 3946 def aka_handler(ctx, req): 3947 logger.info("aka_handler - RX " + binascii.hexlify(req).decode()) 3948 if 'num' not in ctx: 3949 ctx['num'] = 0 3950 ctx['num'] = ctx['num'] + 1 3951 if 'id' not in ctx: 3952 ctx['id'] = 1 3953 ctx['id'] = (ctx['id'] + 1) % 256 3954 3955 idx = 0 3956 3957 idx += 1 3958 if ctx['num'] == idx: 3959 logger.info("Test: Missing payload") 3960 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 3961 4 + 1, 3962 EAP_TYPE_AKA) 3963 3964 idx += 1 3965 if ctx['num'] == idx: 3966 logger.info("Test: Unknown subtype") 3967 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], 3968 4 + 1 + 3, 3969 EAP_TYPE_AKA, 255, 0) 3970 idx += 1 3971 if ctx['num'] == idx: 3972 logger.info("Test: EAP-Failure") 3973 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 3974 3975 idx += 1 3976 if ctx['num'] == idx: 3977 logger.info("Test: Client Error") 3978 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], 3979 4 + 1 + 3, 3980 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CLIENT_ERROR, 0) 3981 idx += 1 3982 if ctx['num'] == idx: 3983 logger.info("Test: EAP-Failure") 3984 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 3985 3986 idx += 1 3987 if ctx['num'] == idx: 3988 logger.info("Test: Too short attribute header") 3989 return struct.pack(">BBHBBHB", EAP_CODE_REQUEST, ctx['id'], 3990 4 + 1 + 1 + 3, 3991 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 255) 3992 idx += 1 3993 if ctx['num'] == idx: 3994 logger.info("Test: EAP-Failure") 3995 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 3996 3997 idx += 1 3998 if ctx['num'] == idx: 3999 logger.info("Test: Truncated attribute") 4000 return struct.pack(">BBHBBHBB", EAP_CODE_REQUEST, ctx['id'], 4001 4 + 1 + 1 + 4, 4002 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 255, 4003 255) 4004 idx += 1 4005 if ctx['num'] == idx: 4006 logger.info("Test: EAP-Failure") 4007 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4008 4009 idx += 1 4010 if ctx['num'] == idx: 4011 logger.info("Test: Too short attribute data") 4012 return struct.pack(">BBHBBHBB", EAP_CODE_REQUEST, ctx['id'], 4013 4 + 1 + 1 + 4, 4014 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 255, 4015 0) 4016 idx += 1 4017 if ctx['num'] == idx: 4018 logger.info("Test: EAP-Failure") 4019 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4020 4021 idx += 1 4022 if ctx['num'] == idx: 4023 logger.info("Test: Skippable/non-skippable unrecognzized attribute") 4024 return struct.pack(">BBHBBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4025 4 + 1 + 1 + 10, 4026 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4027 255, 1, 0, 127, 1, 0) 4028 idx += 1 4029 if ctx['num'] == idx: 4030 logger.info("Test: EAP-Failure") 4031 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4032 4033 idx += 1 4034 if ctx['num'] == idx: 4035 logger.info("Test: Identity request without ID type") 4036 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], 4037 4 + 1 + 3, 4038 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0) 4039 idx += 1 4040 if ctx['num'] == idx: 4041 logger.info("Test: Identity request ANY_ID") 4042 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4043 4 + 1 + 3 + 4, 4044 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4045 EAP_SIM_AT_ANY_ID_REQ, 1, 0) 4046 idx += 1 4047 if ctx['num'] == idx: 4048 logger.info("Test: Identity request ANY_ID (duplicate)") 4049 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4050 4 + 1 + 3 + 4, 4051 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4052 EAP_SIM_AT_ANY_ID_REQ, 1, 0) 4053 idx += 1 4054 if ctx['num'] == idx: 4055 logger.info("Test: EAP-Failure") 4056 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4057 4058 idx += 1 4059 if ctx['num'] == idx: 4060 logger.info("Test: Identity request ANY_ID") 4061 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4062 4 + 1 + 3 + 4, 4063 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4064 EAP_SIM_AT_ANY_ID_REQ, 1, 0) 4065 idx += 1 4066 if ctx['num'] == idx: 4067 logger.info("Test: Identity request FULLAUTH_ID") 4068 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4069 4 + 1 + 3 + 4, 4070 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4071 EAP_SIM_AT_FULLAUTH_ID_REQ, 1, 0) 4072 idx += 1 4073 if ctx['num'] == idx: 4074 logger.info("Test: Identity request FULLAUTH_ID (duplicate)") 4075 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4076 4 + 1 + 3 + 4, 4077 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4078 EAP_SIM_AT_FULLAUTH_ID_REQ, 1, 0) 4079 idx += 1 4080 if ctx['num'] == idx: 4081 logger.info("Test: EAP-Failure") 4082 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4083 4084 idx += 1 4085 if ctx['num'] == idx: 4086 logger.info("Test: Identity request ANY_ID") 4087 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4088 4 + 1 + 3 + 4, 4089 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4090 EAP_SIM_AT_ANY_ID_REQ, 1, 0) 4091 idx += 1 4092 if ctx['num'] == idx: 4093 logger.info("Test: Identity request FULLAUTH_ID") 4094 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4095 4 + 1 + 3 + 4, 4096 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4097 EAP_SIM_AT_FULLAUTH_ID_REQ, 1, 0) 4098 idx += 1 4099 if ctx['num'] == idx: 4100 logger.info("Test: Identity request PERMANENT_ID") 4101 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4102 4 + 1 + 3 + 4, 4103 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4104 EAP_SIM_AT_PERMANENT_ID_REQ, 1, 0) 4105 idx += 1 4106 if ctx['num'] == idx: 4107 logger.info("Test: Identity request PERMANENT_ID (duplicate)") 4108 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4109 4 + 1 + 3 + 4, 4110 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4111 EAP_SIM_AT_PERMANENT_ID_REQ, 1, 0) 4112 idx += 1 4113 if ctx['num'] == idx: 4114 logger.info("Test: EAP-Failure") 4115 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4116 4117 idx += 1 4118 if ctx['num'] == idx: 4119 logger.info("Test: Challenge with no attributes") 4120 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], 4121 4 + 1 + 3, 4122 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CHALLENGE, 0) 4123 idx += 1 4124 if ctx['num'] == idx: 4125 logger.info("Test: EAP-Failure") 4126 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4127 4128 idx += 1 4129 if ctx['num'] == idx: 4130 logger.info("Test: AKA Challenge with BIDDING") 4131 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4132 4 + 1 + 3 + 4, 4133 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4134 EAP_SIM_AT_BIDDING, 1, 0x8000) 4135 idx += 1 4136 if ctx['num'] == idx: 4137 logger.info("Test: EAP-Failure") 4138 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4139 4140 idx += 1 4141 if ctx['num'] == idx: 4142 logger.info("Test: Notification with no attributes") 4143 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], 4144 4 + 1 + 3, 4145 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0) 4146 idx += 1 4147 if ctx['num'] == idx: 4148 logger.info("Test: EAP-Failure") 4149 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4150 4151 idx += 1 4152 if ctx['num'] == idx: 4153 logger.info("Test: Notification indicating success, but no MAC") 4154 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4155 4 + 1 + 3 + 4, 4156 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0, 4157 EAP_SIM_AT_NOTIFICATION, 1, 32768) 4158 idx += 1 4159 if ctx['num'] == idx: 4160 logger.info("Test: EAP-Failure") 4161 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4162 4163 idx += 1 4164 if ctx['num'] == idx: 4165 logger.info("Test: Notification indicating success, but invalid MAC value") 4166 return struct.pack(">BBHBBHBBHBBH4L", EAP_CODE_REQUEST, ctx['id'], 4167 4 + 1 + 3 + 4 + 20, 4168 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0, 4169 EAP_SIM_AT_NOTIFICATION, 1, 32768, 4170 EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0) 4171 idx += 1 4172 if ctx['num'] == idx: 4173 logger.info("Test: EAP-Failure") 4174 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4175 4176 idx += 1 4177 if ctx['num'] == idx: 4178 logger.info("Test: Notification indicating success with zero-key MAC") 4179 return struct.pack(">BBHBBHBBHBBH16B", EAP_CODE_REQUEST, 4180 ctx['id'] - 2, 4181 4 + 1 + 3 + 4 + 20, 4182 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0, 4183 EAP_SIM_AT_NOTIFICATION, 1, 32768, 4184 EAP_SIM_AT_MAC, 5, 0, 4185 0xbe, 0x2e, 0xbb, 0xa9, 0xfa, 0x2e, 0x82, 0x36, 4186 0x37, 0x8c, 0x32, 0x41, 0xb7, 0xc7, 0x58, 0xa3) 4187 idx += 1 4188 if ctx['num'] == idx: 4189 logger.info("Test: EAP-Success") 4190 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4) 4191 4192 idx += 1 4193 if ctx['num'] == idx: 4194 logger.info("Test: Notification before auth") 4195 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4196 4 + 1 + 3 + 4, 4197 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0, 4198 EAP_SIM_AT_NOTIFICATION, 1, 16384) 4199 idx += 1 4200 if ctx['num'] == idx: 4201 logger.info("Test: EAP-Failure") 4202 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4203 4204 idx += 1 4205 if ctx['num'] == idx: 4206 logger.info("Test: Notification before auth") 4207 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4208 4 + 1 + 3 + 4, 4209 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0, 4210 EAP_SIM_AT_NOTIFICATION, 1, 16385) 4211 idx += 1 4212 if ctx['num'] == idx: 4213 logger.info("Test: EAP-Failure") 4214 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4215 4216 idx += 1 4217 if ctx['num'] == idx: 4218 logger.info("Test: Notification with unrecognized non-failure") 4219 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4220 4 + 1 + 3 + 4, 4221 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0, 4222 EAP_SIM_AT_NOTIFICATION, 1, 0xc000) 4223 idx += 1 4224 if ctx['num'] == idx: 4225 logger.info("Test: Notification before auth (duplicate)") 4226 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4227 4 + 1 + 3 + 4, 4228 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0, 4229 EAP_SIM_AT_NOTIFICATION, 1, 0xc000) 4230 idx += 1 4231 if ctx['num'] == idx: 4232 logger.info("Test: EAP-Failure") 4233 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4234 4235 idx += 1 4236 if ctx['num'] == idx: 4237 logger.info("Test: Re-authentication (unexpected) with no attributes") 4238 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], 4239 4 + 1 + 3, 4240 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_REAUTHENTICATION, 4241 0) 4242 idx += 1 4243 if ctx['num'] == idx: 4244 logger.info("Test: EAP-Failure") 4245 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4246 4247 idx += 1 4248 if ctx['num'] == idx: 4249 logger.info("Test: AKA Challenge with Checkcode claiming identity round was used") 4250 return struct.pack(">BBHBBHBBH5L", EAP_CODE_REQUEST, ctx['id'], 4251 4 + 1 + 3 + 24, 4252 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4253 EAP_SIM_AT_CHECKCODE, 6, 0, 0, 0, 0, 0, 0) 4254 idx += 1 4255 if ctx['num'] == idx: 4256 logger.info("Test: EAP-Failure") 4257 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4258 4259 idx += 1 4260 if ctx['num'] == idx: 4261 logger.info("Test: Identity request ANY_ID") 4262 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4263 4 + 1 + 3 + 4, 4264 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4265 EAP_SIM_AT_ANY_ID_REQ, 1, 0) 4266 idx += 1 4267 if ctx['num'] == idx: 4268 logger.info("Test: AKA Challenge with Checkcode claiming no identity round was used") 4269 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4270 4 + 1 + 3 + 4, 4271 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4272 EAP_SIM_AT_CHECKCODE, 1, 0) 4273 idx += 1 4274 if ctx['num'] == idx: 4275 logger.info("Test: EAP-Failure") 4276 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4277 4278 idx += 1 4279 if ctx['num'] == idx: 4280 logger.info("Test: Identity request ANY_ID") 4281 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4282 4 + 1 + 3 + 4, 4283 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4284 EAP_SIM_AT_ANY_ID_REQ, 1, 0) 4285 idx += 1 4286 if ctx['num'] == idx: 4287 logger.info("Test: AKA Challenge with mismatching Checkcode value") 4288 return struct.pack(">BBHBBHBBH5L", EAP_CODE_REQUEST, ctx['id'], 4289 4 + 1 + 3 + 24, 4290 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4291 EAP_SIM_AT_CHECKCODE, 6, 0, 0, 0, 0, 0, 0) 4292 idx += 1 4293 if ctx['num'] == idx: 4294 logger.info("Test: EAP-Failure") 4295 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4296 4297 idx += 1 4298 if ctx['num'] == idx: 4299 logger.info("Test: Re-authentication (unexpected) with Checkcode claimin identity round was used") 4300 return struct.pack(">BBHBBHBBH5L", EAP_CODE_REQUEST, ctx['id'], 4301 4 + 1 + 3 + 24, 4302 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_REAUTHENTICATION, 4303 0, 4304 EAP_SIM_AT_CHECKCODE, 6, 0, 0, 0, 0, 0, 0) 4305 idx += 1 4306 if ctx['num'] == idx: 4307 logger.info("Test: EAP-Failure") 4308 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4309 4310 idx += 1 4311 if ctx['num'] == idx: 4312 logger.info("Test: Invalid AT_RAND length") 4313 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4314 4 + 1 + 3 + 4, 4315 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4316 EAP_SIM_AT_RAND, 1, 0) 4317 idx += 1 4318 if ctx['num'] == idx: 4319 logger.info("Test: EAP-Failure") 4320 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4321 4322 idx += 1 4323 if ctx['num'] == idx: 4324 logger.info("Test: Invalid AT_AUTN length") 4325 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4326 4 + 1 + 3 + 4, 4327 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4328 EAP_SIM_AT_AUTN, 1, 0) 4329 idx += 1 4330 if ctx['num'] == idx: 4331 logger.info("Test: EAP-Failure") 4332 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4333 4334 idx += 1 4335 if ctx['num'] == idx: 4336 logger.info("Test: Unencrypted AT_PADDING") 4337 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4338 4 + 1 + 3 + 4, 4339 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4340 EAP_SIM_AT_PADDING, 1, 0) 4341 idx += 1 4342 if ctx['num'] == idx: 4343 logger.info("Test: EAP-Failure") 4344 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4345 4346 idx += 1 4347 if ctx['num'] == idx: 4348 logger.info("Test: Invalid AT_NONCE_MT length") 4349 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4350 4 + 1 + 3 + 4, 4351 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4352 EAP_SIM_AT_NONCE_MT, 1, 0) 4353 idx += 1 4354 if ctx['num'] == idx: 4355 logger.info("Test: EAP-Failure") 4356 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4357 4358 idx += 1 4359 if ctx['num'] == idx: 4360 logger.info("Test: Invalid AT_MAC length") 4361 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4362 4 + 1 + 3 + 4, 4363 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4364 EAP_SIM_AT_MAC, 1, 0) 4365 idx += 1 4366 if ctx['num'] == idx: 4367 logger.info("Test: EAP-Failure") 4368 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4369 4370 idx += 1 4371 if ctx['num'] == idx: 4372 logger.info("Test: Invalid AT_NOTIFICATION length") 4373 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], 4374 4 + 1 + 3 + 8, 4375 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4376 EAP_SIM_AT_NOTIFICATION, 2, 0, 0) 4377 idx += 1 4378 if ctx['num'] == idx: 4379 logger.info("Test: EAP-Failure") 4380 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4381 4382 idx += 1 4383 if ctx['num'] == idx: 4384 logger.info("Test: AT_IDENTITY overflow") 4385 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4386 4 + 1 + 3 + 4, 4387 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4388 EAP_SIM_AT_IDENTITY, 1, 0xffff) 4389 idx += 1 4390 if ctx['num'] == idx: 4391 logger.info("Test: EAP-Failure") 4392 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4393 4394 idx += 1 4395 if ctx['num'] == idx: 4396 logger.info("Test: Unexpected AT_VERSION_LIST") 4397 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4398 4 + 1 + 3 + 4, 4399 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4400 EAP_SIM_AT_VERSION_LIST, 1, 0) 4401 idx += 1 4402 if ctx['num'] == idx: 4403 logger.info("Test: EAP-Failure") 4404 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4405 4406 idx += 1 4407 if ctx['num'] == idx: 4408 logger.info("Test: Invalid AT_SELECTED_VERSION length") 4409 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], 4410 4 + 1 + 3 + 8, 4411 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4412 EAP_SIM_AT_SELECTED_VERSION, 2, 0, 0) 4413 idx += 1 4414 if ctx['num'] == idx: 4415 logger.info("Test: EAP-Failure") 4416 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4417 4418 idx += 1 4419 if ctx['num'] == idx: 4420 logger.info("Test: Unencrypted AT_COUNTER") 4421 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4422 4 + 1 + 3 + 4, 4423 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4424 EAP_SIM_AT_COUNTER, 1, 0) 4425 idx += 1 4426 if ctx['num'] == idx: 4427 logger.info("Test: EAP-Failure") 4428 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4429 4430 idx += 1 4431 if ctx['num'] == idx: 4432 logger.info("Test: Unencrypted AT_COUNTER_TOO_SMALL") 4433 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4434 4 + 1 + 3 + 4, 4435 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4436 EAP_SIM_AT_COUNTER_TOO_SMALL, 1, 0) 4437 idx += 1 4438 if ctx['num'] == idx: 4439 logger.info("Test: EAP-Failure") 4440 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4441 4442 idx += 1 4443 if ctx['num'] == idx: 4444 logger.info("Test: Unencrypted AT_NONCE_S") 4445 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4446 4 + 1 + 3 + 4, 4447 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4448 EAP_SIM_AT_NONCE_S, 1, 0) 4449 idx += 1 4450 if ctx['num'] == idx: 4451 logger.info("Test: EAP-Failure") 4452 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4453 4454 idx += 1 4455 if ctx['num'] == idx: 4456 logger.info("Test: Invalid AT_CLIENT_ERROR_CODE length") 4457 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], 4458 4 + 1 + 3 + 8, 4459 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4460 EAP_SIM_AT_CLIENT_ERROR_CODE, 2, 0, 0) 4461 idx += 1 4462 if ctx['num'] == idx: 4463 logger.info("Test: EAP-Failure") 4464 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4465 4466 idx += 1 4467 if ctx['num'] == idx: 4468 logger.info("Test: Invalid AT_IV length") 4469 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4470 4 + 1 + 3 + 4, 4471 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4472 EAP_SIM_AT_IV, 1, 0) 4473 idx += 1 4474 if ctx['num'] == idx: 4475 logger.info("Test: EAP-Failure") 4476 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4477 4478 idx += 1 4479 if ctx['num'] == idx: 4480 logger.info("Test: Invalid AT_ENCR_DATA length") 4481 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], 4482 4 + 1 + 3 + 8, 4483 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4484 EAP_SIM_AT_ENCR_DATA, 2, 0, 0) 4485 idx += 1 4486 if ctx['num'] == idx: 4487 logger.info("Test: EAP-Failure") 4488 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4489 4490 idx += 1 4491 if ctx['num'] == idx: 4492 logger.info("Test: Unencrypted AT_NEXT_PSEUDONYM") 4493 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4494 4 + 1 + 3 + 4, 4495 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4496 EAP_SIM_AT_NEXT_PSEUDONYM, 1, 0) 4497 idx += 1 4498 if ctx['num'] == idx: 4499 logger.info("Test: EAP-Failure") 4500 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4501 4502 idx += 1 4503 if ctx['num'] == idx: 4504 logger.info("Test: Unencrypted AT_NEXT_REAUTH_ID") 4505 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4506 4 + 1 + 3 + 4, 4507 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4508 EAP_SIM_AT_NEXT_REAUTH_ID, 1, 0) 4509 idx += 1 4510 if ctx['num'] == idx: 4511 logger.info("Test: EAP-Failure") 4512 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4513 4514 idx += 1 4515 if ctx['num'] == idx: 4516 logger.info("Test: Invalid AT_RES length") 4517 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4518 4 + 1 + 3 + 4, 4519 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4520 EAP_SIM_AT_RES, 1, 0) 4521 idx += 1 4522 if ctx['num'] == idx: 4523 logger.info("Test: EAP-Failure") 4524 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4525 4526 idx += 1 4527 if ctx['num'] == idx: 4528 logger.info("Test: Invalid AT_RES length") 4529 return struct.pack(">BBHBBHBBH5L", EAP_CODE_REQUEST, ctx['id'], 4530 4 + 1 + 3 + 24, 4531 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4532 EAP_SIM_AT_RES, 6, 0xffff, 0, 0, 0, 0, 0) 4533 idx += 1 4534 if ctx['num'] == idx: 4535 logger.info("Test: EAP-Failure") 4536 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4537 4538 idx += 1 4539 if ctx['num'] == idx: 4540 logger.info("Test: Invalid AT_AUTS length") 4541 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], 4542 4 + 1 + 3 + 8, 4543 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4544 EAP_SIM_AT_AUTS, 2, 0, 0) 4545 idx += 1 4546 if ctx['num'] == idx: 4547 logger.info("Test: EAP-Failure") 4548 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4549 4550 idx += 1 4551 if ctx['num'] == idx: 4552 logger.info("Test: Invalid AT_CHECKCODE length") 4553 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], 4554 4 + 1 + 3 + 8, 4555 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4556 EAP_SIM_AT_CHECKCODE, 2, 0, 0) 4557 idx += 1 4558 if ctx['num'] == idx: 4559 logger.info("Test: EAP-Failure") 4560 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4561 4562 idx += 1 4563 if ctx['num'] == idx: 4564 logger.info("Test: Invalid AT_RESULT_IND length") 4565 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], 4566 4 + 1 + 3 + 8, 4567 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4568 EAP_SIM_AT_RESULT_IND, 2, 0, 0) 4569 idx += 1 4570 if ctx['num'] == idx: 4571 logger.info("Test: EAP-Failure") 4572 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4573 4574 idx += 1 4575 if ctx['num'] == idx: 4576 logger.info("Test: Unexpected AT_KDF_INPUT") 4577 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], 4578 4 + 1 + 3 + 8, 4579 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4580 EAP_SIM_AT_KDF_INPUT, 2, 0, 0) 4581 idx += 1 4582 if ctx['num'] == idx: 4583 logger.info("Test: EAP-Failure") 4584 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4585 4586 idx += 1 4587 if ctx['num'] == idx: 4588 logger.info("Test: Unexpected AT_KDF") 4589 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], 4590 4 + 1 + 3 + 8, 4591 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4592 EAP_SIM_AT_KDF, 2, 0, 0) 4593 idx += 1 4594 if ctx['num'] == idx: 4595 logger.info("Test: EAP-Failure") 4596 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4597 4598 idx += 1 4599 if ctx['num'] == idx: 4600 logger.info("Test: Invalid AT_BIDDING length") 4601 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], 4602 4 + 1 + 3 + 8, 4603 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4604 EAP_SIM_AT_BIDDING, 2, 0, 0) 4605 idx += 1 4606 if ctx['num'] == idx: 4607 logger.info("Test: EAP-Failure") 4608 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4609 4610 return None 4611 4612 srv = start_radius_server(aka_handler) 4613 4614 try: 4615 hapd = start_ap(apdev[0]) 4616 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 4617 4618 for i in range(0, 49): 4619 eap = "AKA AKA'" if i == 11 else "AKA" 4620 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 4621 eap=eap, identity="0232010000000000", 4622 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123", 4623 wait_connect=False) 4624 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 4625 timeout=15) 4626 if ev is None: 4627 raise Exception("Timeout on EAP start") 4628 if i in [0, 15]: 4629 time.sleep(0.1) 4630 else: 4631 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], 4632 timeout=10) 4633 if ev is None: 4634 raise Exception("Timeout on EAP failure") 4635 dev[0].request("REMOVE_NETWORK all") 4636 dev[0].dump_monitor() 4637 finally: 4638 stop_radius_server(srv) 4639 4640def test_eap_proto_aka_prime(dev, apdev): 4641 """EAP-AKA' protocol tests""" 4642 def aka_prime_handler(ctx, req): 4643 logger.info("aka_prime_handler - RX " + binascii.hexlify(req).decode()) 4644 if 'num' not in ctx: 4645 ctx['num'] = 0 4646 ctx['num'] = ctx['num'] + 1 4647 if 'id' not in ctx: 4648 ctx['id'] = 1 4649 ctx['id'] = (ctx['id'] + 1) % 256 4650 4651 idx = 0 4652 4653 idx += 1 4654 if ctx['num'] == idx: 4655 logger.info("Test: Missing payload") 4656 dev[0].note("Missing payload") 4657 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 4658 4 + 1, 4659 EAP_TYPE_AKA_PRIME) 4660 4661 idx += 1 4662 if ctx['num'] == idx: 4663 logger.info("Test: Challenge with no attributes") 4664 dev[0].note("Challenge with no attributes") 4665 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], 4666 4 + 1 + 3, 4667 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0) 4668 idx += 1 4669 if ctx['num'] == idx: 4670 logger.info("Test: EAP-Failure") 4671 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4672 4673 idx += 1 4674 if ctx['num'] == idx: 4675 logger.info("Test: Challenge with empty AT_KDF_INPUT") 4676 dev[0].note("Challenge with empty AT_KDF_INPUT") 4677 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4678 4 + 1 + 3 + 4, 4679 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4680 EAP_SIM_AT_KDF_INPUT, 1, 0) 4681 idx += 1 4682 if ctx['num'] == idx: 4683 logger.info("Test: EAP-Failure") 4684 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4685 4686 idx += 1 4687 if ctx['num'] == idx: 4688 logger.info("Test: Challenge with AT_KDF_INPUT") 4689 dev[0].note("Test: Challenge with AT_KDF_INPUT") 4690 return struct.pack(">BBHBBHBBHBBBB", EAP_CODE_REQUEST, ctx['id'], 4691 4 + 1 + 3 + 8, 4692 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4693 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), 4694 ord('c'), ord('d')) 4695 idx += 1 4696 if ctx['num'] == idx: 4697 logger.info("Test: EAP-Failure") 4698 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4699 4700 idx += 1 4701 if ctx['num'] == idx: 4702 logger.info("Test: Challenge with duplicated KDF") 4703 dev[0].note("Challenge with duplicated KDF") 4704 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH", 4705 EAP_CODE_REQUEST, ctx['id'], 4706 4 + 1 + 3 + 8 + 3 * 4, 4707 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4708 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), 4709 ord('c'), ord('d'), 4710 EAP_SIM_AT_KDF, 1, 1, 4711 EAP_SIM_AT_KDF, 1, 2, 4712 EAP_SIM_AT_KDF, 1, 1) 4713 idx += 1 4714 if ctx['num'] == idx: 4715 logger.info("Test: EAP-Failure") 4716 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4717 4718 idx += 1 4719 if ctx['num'] == idx: 4720 logger.info("Test: Challenge with multiple KDF proposals") 4721 dev[0].note("Challenge with multiple KDF proposals (preparation)") 4722 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH", 4723 EAP_CODE_REQUEST, ctx['id'], 4724 4 + 1 + 3 + 8 + 3 * 4, 4725 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4726 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), 4727 ord('c'), ord('d'), 4728 EAP_SIM_AT_KDF, 1, 255, 4729 EAP_SIM_AT_KDF, 1, 254, 4730 EAP_SIM_AT_KDF, 1, 1) 4731 idx += 1 4732 if ctx['num'] == idx: 4733 logger.info("Test: Challenge with incorrect KDF selected") 4734 dev[0].note("Challenge with incorrect KDF selected") 4735 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBHBBH", 4736 EAP_CODE_REQUEST, ctx['id'], 4737 4 + 1 + 3 + 8 + 4 * 4, 4738 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4739 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), 4740 ord('c'), ord('d'), 4741 EAP_SIM_AT_KDF, 1, 255, 4742 EAP_SIM_AT_KDF, 1, 255, 4743 EAP_SIM_AT_KDF, 1, 254, 4744 EAP_SIM_AT_KDF, 1, 1) 4745 idx += 1 4746 if ctx['num'] == idx: 4747 logger.info("Test: EAP-Failure") 4748 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4749 4750 idx += 1 4751 if ctx['num'] == idx: 4752 logger.info("Test: Challenge with multiple KDF proposals") 4753 dev[0].note("Challenge with multiple KDF proposals (preparation)") 4754 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH", 4755 EAP_CODE_REQUEST, ctx['id'], 4756 4 + 1 + 3 + 8 + 3 * 4, 4757 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4758 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), 4759 ord('c'), ord('d'), 4760 EAP_SIM_AT_KDF, 1, 255, 4761 EAP_SIM_AT_KDF, 1, 254, 4762 EAP_SIM_AT_KDF, 1, 1) 4763 idx += 1 4764 if ctx['num'] == idx: 4765 logger.info("Test: Challenge with selected KDF not duplicated") 4766 dev[0].note("Challenge with selected KDF not duplicated") 4767 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH", 4768 EAP_CODE_REQUEST, ctx['id'], 4769 4 + 1 + 3 + 8 + 3 * 4, 4770 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4771 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), 4772 ord('c'), ord('d'), 4773 EAP_SIM_AT_KDF, 1, 1, 4774 EAP_SIM_AT_KDF, 1, 255, 4775 EAP_SIM_AT_KDF, 1, 254) 4776 idx += 1 4777 if ctx['num'] == idx: 4778 logger.info("Test: EAP-Failure") 4779 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4780 4781 idx += 1 4782 if ctx['num'] == idx: 4783 logger.info("Test: Challenge with multiple KDF proposals") 4784 dev[0].note("Challenge with multiple KDF proposals (preparation)") 4785 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH", 4786 EAP_CODE_REQUEST, ctx['id'], 4787 4 + 1 + 3 + 8 + 3 * 4, 4788 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4789 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), 4790 ord('c'), ord('d'), 4791 EAP_SIM_AT_KDF, 1, 255, 4792 EAP_SIM_AT_KDF, 1, 254, 4793 EAP_SIM_AT_KDF, 1, 1) 4794 idx += 1 4795 if ctx['num'] == idx: 4796 logger.info("Test: Challenge with selected KDF duplicated (missing MAC, RAND, AUTN)") 4797 dev[0].note("Challenge with selected KDF duplicated (missing MAC, RAND, AUTN)") 4798 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBHBBH", 4799 EAP_CODE_REQUEST, ctx['id'], 4800 4 + 1 + 3 + 8 + 4 * 4, 4801 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4802 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), 4803 ord('c'), ord('d'), 4804 EAP_SIM_AT_KDF, 1, 1, 4805 EAP_SIM_AT_KDF, 1, 255, 4806 EAP_SIM_AT_KDF, 1, 254, 4807 EAP_SIM_AT_KDF, 1, 1) 4808 idx += 1 4809 if ctx['num'] == idx: 4810 logger.info("Test: EAP-Failure") 4811 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4812 4813 idx += 1 4814 if ctx['num'] == idx: 4815 logger.info("Test: Challenge with multiple unsupported KDF proposals") 4816 dev[0].note("Challenge with multiple unsupported KDF proposals") 4817 return struct.pack(">BBHBBHBBHBBBBBBHBBH", 4818 EAP_CODE_REQUEST, ctx['id'], 4819 4 + 1 + 3 + 8 + 2 * 4, 4820 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4821 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), 4822 ord('c'), ord('d'), 4823 EAP_SIM_AT_KDF, 1, 255, 4824 EAP_SIM_AT_KDF, 1, 254) 4825 idx += 1 4826 if ctx['num'] == idx: 4827 logger.info("Test: EAP-Failure") 4828 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4829 4830 idx += 1 4831 if ctx['num'] == idx: 4832 logger.info("Test: Challenge with multiple KDF proposals") 4833 dev[0].note("Challenge with multiple KDF proposals (preparation)") 4834 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH", 4835 EAP_CODE_REQUEST, ctx['id'], 4836 4 + 1 + 3 + 8 + 3 * 4, 4837 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4838 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), 4839 ord('c'), ord('d'), 4840 EAP_SIM_AT_KDF, 1, 255, 4841 EAP_SIM_AT_KDF, 1, 254, 4842 EAP_SIM_AT_KDF, 1, 1) 4843 idx += 1 4844 if ctx['num'] == idx: 4845 logger.info("Test: Challenge with invalid MAC, RAND, AUTN values)") 4846 dev[0].note("Challenge with invalid MAC, RAND, AUTN values)") 4847 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBHBBHBBH4LBBH4LBBH4L", 4848 EAP_CODE_REQUEST, ctx['id'], 4849 4 + 1 + 3 + 8 + 4 * 4 + 20 + 20 + 20, 4850 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4851 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), 4852 ord('c'), ord('d'), 4853 EAP_SIM_AT_KDF, 1, 1, 4854 EAP_SIM_AT_KDF, 1, 255, 4855 EAP_SIM_AT_KDF, 1, 254, 4856 EAP_SIM_AT_KDF, 1, 1, 4857 EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0, 4858 EAP_SIM_AT_RAND, 5, 0, 0, 0, 0, 0, 4859 EAP_SIM_AT_AUTN, 5, 0, 0, 0, 0, 0) 4860 idx += 1 4861 if ctx['num'] == idx: 4862 logger.info("Test: EAP-Failure") 4863 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4864 4865 idx += 1 4866 if ctx['num'] == idx: 4867 logger.info("Test: Challenge - AMF separation bit not set)") 4868 dev[0].note("Challenge - AMF separation bit not set)") 4869 return struct.pack(">BBHBBHBBHBBBBBBHBBH4LBBH4LBBH4L", 4870 EAP_CODE_REQUEST, ctx['id'], 4871 4 + 1 + 3 + 8 + 4 + 20 + 20 + 20, 4872 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4873 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), 4874 ord('c'), ord('d'), 4875 EAP_SIM_AT_KDF, 1, 1, 4876 EAP_SIM_AT_MAC, 5, 0, 1, 2, 3, 4, 4877 EAP_SIM_AT_RAND, 5, 0, 5, 6, 7, 8, 4878 EAP_SIM_AT_AUTN, 5, 0, 9, 10, 4879 0x2fda8ef7, 0xbba518cc) 4880 idx += 1 4881 if ctx['num'] == idx: 4882 logger.info("Test: EAP-Failure") 4883 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4884 4885 idx += 1 4886 if ctx['num'] == idx: 4887 logger.info("Test: Challenge - Invalid MAC") 4888 dev[0].note("Challenge - Invalid MAC") 4889 return struct.pack(">BBHBBHBBHBBBBBBHBBH4LBBH4LBBH4L", 4890 EAP_CODE_REQUEST, ctx['id'], 4891 4 + 1 + 3 + 8 + 4 + 20 + 20 + 20, 4892 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4893 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), 4894 ord('c'), ord('d'), 4895 EAP_SIM_AT_KDF, 1, 1, 4896 EAP_SIM_AT_MAC, 5, 0, 1, 2, 3, 4, 4897 EAP_SIM_AT_RAND, 5, 0, 5, 6, 7, 8, 4898 EAP_SIM_AT_AUTN, 5, 0, 0xffffffff, 0xffffffff, 4899 0xd1f90322, 0x40514cb4) 4900 idx += 1 4901 if ctx['num'] == idx: 4902 logger.info("Test: EAP-Failure") 4903 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4904 4905 idx += 1 4906 if ctx['num'] == idx: 4907 logger.info("Test: Challenge - Valid MAC") 4908 dev[0].note("Challenge - Valid MAC") 4909 return struct.pack(">BBHBBHBBHBBBBBBHBBH4LBBH4LBBH4L", 4910 EAP_CODE_REQUEST, ctx['id'], 4911 4 + 1 + 3 + 8 + 4 + 20 + 20 + 20, 4912 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4913 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), 4914 ord('c'), ord('d'), 4915 EAP_SIM_AT_KDF, 1, 1, 4916 EAP_SIM_AT_MAC, 5, 0, 4917 0xf4a3c1d3, 0x7c901401, 0x34bd8b01, 0x6f7fa32f, 4918 EAP_SIM_AT_RAND, 5, 0, 5, 6, 7, 8, 4919 EAP_SIM_AT_AUTN, 5, 0, 0xffffffff, 0xffffffff, 4920 0xd1f90322, 0x40514cb4) 4921 idx += 1 4922 if ctx['num'] == idx: 4923 logger.info("Test: EAP-Failure") 4924 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4925 4926 idx += 1 4927 if ctx['num'] == idx: 4928 logger.info("Test: Invalid AT_KDF_INPUT length") 4929 dev[0].note("Invalid AT_KDF_INPUT length") 4930 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], 4931 4 + 1 + 3 + 8, 4932 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_IDENTITY, 0, 4933 EAP_SIM_AT_KDF_INPUT, 2, 0xffff, 0) 4934 idx += 1 4935 if ctx['num'] == idx: 4936 logger.info("Test: EAP-Failure") 4937 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4938 4939 idx += 1 4940 if ctx['num'] == idx: 4941 logger.info("Test: Invalid AT_KDF length") 4942 dev[0].note("Invalid AT_KDF length") 4943 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], 4944 4 + 1 + 3 + 8, 4945 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_IDENTITY, 0, 4946 EAP_SIM_AT_KDF, 2, 0, 0) 4947 idx += 1 4948 if ctx['num'] == idx: 4949 logger.info("Test: EAP-Failure") 4950 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4951 4952 idx += 1 4953 if ctx['num'] == idx: 4954 logger.info("Test: Challenge with large number of KDF proposals") 4955 dev[0].note("Challenge with large number of KDF proposals") 4956 return struct.pack(">BBHBBHBBHBBHBBHBBHBBHBBHBBHBBHBBHBBHBBHBBH", 4957 EAP_CODE_REQUEST, ctx['id'], 4958 4 + 1 + 3 + 12 * 4, 4959 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4960 EAP_SIM_AT_KDF, 1, 255, 4961 EAP_SIM_AT_KDF, 1, 254, 4962 EAP_SIM_AT_KDF, 1, 253, 4963 EAP_SIM_AT_KDF, 1, 252, 4964 EAP_SIM_AT_KDF, 1, 251, 4965 EAP_SIM_AT_KDF, 1, 250, 4966 EAP_SIM_AT_KDF, 1, 249, 4967 EAP_SIM_AT_KDF, 1, 248, 4968 EAP_SIM_AT_KDF, 1, 247, 4969 EAP_SIM_AT_KDF, 1, 246, 4970 EAP_SIM_AT_KDF, 1, 245, 4971 EAP_SIM_AT_KDF, 1, 244) 4972 idx += 1 4973 if ctx['num'] == idx: 4974 logger.info("Test: EAP-Failure") 4975 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4976 4977 idx += 1 4978 if ctx['num'] == idx: 4979 logger.info("Test: Challenge with multiple KDF proposals") 4980 dev[0].note("Challenge with multiple KDF proposals (preparation)") 4981 return struct.pack(">BBHBBHBBHBBBBBBHBBH", 4982 EAP_CODE_REQUEST, ctx['id'], 4983 4 + 1 + 3 + 8 + 2 * 4, 4984 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4985 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), 4986 ord('c'), ord('d'), 4987 EAP_SIM_AT_KDF, 1, 2, 4988 EAP_SIM_AT_KDF, 1, 1) 4989 idx += 1 4990 if ctx['num'] == idx: 4991 logger.info("Test: Challenge with an extra KDF appended") 4992 dev[0].note("Challenge with an extra KDF appended") 4993 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBHBBH", 4994 EAP_CODE_REQUEST, ctx['id'], 4995 4 + 1 + 3 + 8 + 4 * 4, 4996 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4997 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), 4998 ord('c'), ord('d'), 4999 EAP_SIM_AT_KDF, 1, 1, 5000 EAP_SIM_AT_KDF, 1, 2, 5001 EAP_SIM_AT_KDF, 1, 1, 5002 EAP_SIM_AT_KDF, 1, 0) 5003 idx += 1 5004 if ctx['num'] == idx: 5005 logger.info("Test: EAP-Failure") 5006 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5007 5008 idx += 1 5009 if ctx['num'] == idx: 5010 logger.info("Test: Challenge with multiple KDF proposals") 5011 dev[0].note("Challenge with multiple KDF proposals (preparation)") 5012 return struct.pack(">BBHBBHBBHBBBBBBHBBH", 5013 EAP_CODE_REQUEST, ctx['id'], 5014 4 + 1 + 3 + 8 + 2 * 4, 5015 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, 5016 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), 5017 ord('c'), ord('d'), 5018 EAP_SIM_AT_KDF, 1, 2, 5019 EAP_SIM_AT_KDF, 1, 1) 5020 idx += 1 5021 if ctx['num'] == idx: 5022 logger.info("Test: Challenge with a modified KDF") 5023 dev[0].note("Challenge with a modified KDF") 5024 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH", 5025 EAP_CODE_REQUEST, ctx['id'], 5026 4 + 1 + 3 + 8 + 3 * 4, 5027 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, 5028 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), 5029 ord('c'), ord('d'), 5030 EAP_SIM_AT_KDF, 1, 1, 5031 EAP_SIM_AT_KDF, 1, 0, 5032 EAP_SIM_AT_KDF, 1, 1) 5033 idx += 1 5034 if ctx['num'] == idx: 5035 logger.info("Test: EAP-Failure") 5036 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5037 5038 return None 5039 5040 srv = start_radius_server(aka_prime_handler) 5041 5042 try: 5043 hapd = start_ap(apdev[0]) 5044 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 5045 5046 for i in range(0, 18): 5047 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 5048 eap="AKA'", identity="6555444333222111", 5049 password="5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123", 5050 wait_connect=False) 5051 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 5052 timeout=15) 5053 if ev is None: 5054 raise Exception("Timeout on EAP start") 5055 if i in [0]: 5056 time.sleep(0.1) 5057 else: 5058 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], 5059 timeout=10) 5060 if ev is None: 5061 raise Exception("Timeout on EAP failure") 5062 dev[0].request("REMOVE_NETWORK all") 5063 dev[0].dump_monitor() 5064 finally: 5065 stop_radius_server(srv) 5066 5067def test_eap_proto_sim(dev, apdev): 5068 """EAP-SIM protocol tests""" 5069 def sim_handler(ctx, req): 5070 logger.info("sim_handler - RX " + binascii.hexlify(req).decode()) 5071 if 'num' not in ctx: 5072 ctx['num'] = 0 5073 ctx['num'] = ctx['num'] + 1 5074 if 'id' not in ctx: 5075 ctx['id'] = 1 5076 ctx['id'] = (ctx['id'] + 1) % 256 5077 5078 idx = 0 5079 5080 idx += 1 5081 if ctx['num'] == idx: 5082 logger.info("Test: Missing payload") 5083 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 5084 4 + 1, 5085 EAP_TYPE_SIM) 5086 5087 idx += 1 5088 if ctx['num'] == idx: 5089 logger.info("Test: Unexpected AT_AUTN") 5090 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], 5091 4 + 1 + 3 + 8, 5092 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, 5093 EAP_SIM_AT_AUTN, 2, 0, 0) 5094 idx += 1 5095 if ctx['num'] == idx: 5096 logger.info("Test: EAP-Failure") 5097 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5098 5099 idx += 1 5100 if ctx['num'] == idx: 5101 logger.info("Test: Too short AT_VERSION_LIST") 5102 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 5103 4 + 1 + 3 + 4, 5104 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, 5105 EAP_SIM_AT_VERSION_LIST, 1, 0) 5106 idx += 1 5107 if ctx['num'] == idx: 5108 logger.info("Test: EAP-Failure") 5109 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5110 5111 idx += 1 5112 if ctx['num'] == idx: 5113 logger.info("Test: AT_VERSION_LIST overflow") 5114 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 5115 4 + 1 + 3 + 4, 5116 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, 5117 EAP_SIM_AT_VERSION_LIST, 1, 0xffff) 5118 idx += 1 5119 if ctx['num'] == idx: 5120 logger.info("Test: EAP-Failure") 5121 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5122 5123 idx += 1 5124 if ctx['num'] == idx: 5125 logger.info("Test: Unexpected AT_AUTS") 5126 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], 5127 4 + 1 + 3 + 8, 5128 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, 5129 EAP_SIM_AT_AUTS, 2, 0, 0) 5130 idx += 1 5131 if ctx['num'] == idx: 5132 logger.info("Test: EAP-Failure") 5133 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5134 5135 idx += 1 5136 if ctx['num'] == idx: 5137 logger.info("Test: Unexpected AT_CHECKCODE") 5138 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], 5139 4 + 1 + 3 + 8, 5140 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, 5141 EAP_SIM_AT_CHECKCODE, 2, 0, 0) 5142 idx += 1 5143 if ctx['num'] == idx: 5144 logger.info("Test: EAP-Failure") 5145 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5146 5147 idx += 1 5148 if ctx['num'] == idx: 5149 logger.info("Test: No AT_VERSION_LIST in Start") 5150 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], 5151 4 + 1 + 3, 5152 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0) 5153 idx += 1 5154 if ctx['num'] == idx: 5155 logger.info("Test: EAP-Failure") 5156 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5157 5158 idx += 1 5159 if ctx['num'] == idx: 5160 logger.info("Test: No support version in AT_VERSION_LIST") 5161 return struct.pack(">BBHBBHBBH4B", EAP_CODE_REQUEST, ctx['id'], 5162 4 + 1 + 3 + 8, 5163 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, 5164 EAP_SIM_AT_VERSION_LIST, 2, 3, 2, 3, 4, 5) 5165 idx += 1 5166 if ctx['num'] == idx: 5167 logger.info("Test: EAP-Failure") 5168 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5169 5170 5171 idx += 1 5172 if ctx['num'] == idx: 5173 logger.info("Test: Identity request without ID type") 5174 return struct.pack(">BBHBBHBBH2H", EAP_CODE_REQUEST, ctx['id'], 5175 4 + 1 + 3 + 8, 5176 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, 5177 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0) 5178 idx += 1 5179 if ctx['num'] == idx: 5180 logger.info("Test: Identity request ANY_ID") 5181 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'], 5182 4 + 1 + 3 + 8 + 4, 5183 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, 5184 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0, 5185 EAP_SIM_AT_ANY_ID_REQ, 1, 0) 5186 idx += 1 5187 if ctx['num'] == idx: 5188 logger.info("Test: Identity request ANY_ID (duplicate)") 5189 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'], 5190 4 + 1 + 3 + 8 + 4, 5191 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, 5192 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0, 5193 EAP_SIM_AT_ANY_ID_REQ, 1, 0) 5194 idx += 1 5195 if ctx['num'] == idx: 5196 logger.info("Test: EAP-Failure") 5197 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5198 5199 idx += 1 5200 if ctx['num'] == idx: 5201 logger.info("Test: Identity request ANY_ID") 5202 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'], 5203 4 + 1 + 3 + 8 + 4, 5204 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, 5205 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0, 5206 EAP_SIM_AT_ANY_ID_REQ, 1, 0) 5207 idx += 1 5208 if ctx['num'] == idx: 5209 logger.info("Test: Identity request FULLAUTH_ID") 5210 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'], 5211 4 + 1 + 3 + 8 + 4, 5212 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, 5213 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0, 5214 EAP_SIM_AT_FULLAUTH_ID_REQ, 1, 0) 5215 idx += 1 5216 if ctx['num'] == idx: 5217 logger.info("Test: Identity request FULLAUTH_ID (duplicate)") 5218 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'], 5219 4 + 1 + 3 + 8 + 4, 5220 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, 5221 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0, 5222 EAP_SIM_AT_FULLAUTH_ID_REQ, 1, 0) 5223 idx += 1 5224 if ctx['num'] == idx: 5225 logger.info("Test: EAP-Failure") 5226 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5227 5228 idx += 1 5229 if ctx['num'] == idx: 5230 logger.info("Test: Identity request ANY_ID") 5231 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'], 5232 4 + 1 + 3 + 8 + 4, 5233 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, 5234 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0, 5235 EAP_SIM_AT_ANY_ID_REQ, 1, 0) 5236 idx += 1 5237 if ctx['num'] == idx: 5238 logger.info("Test: Identity request FULLAUTH_ID") 5239 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'], 5240 4 + 1 + 3 + 8 + 4, 5241 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, 5242 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0, 5243 EAP_SIM_AT_FULLAUTH_ID_REQ, 1, 0) 5244 idx += 1 5245 if ctx['num'] == idx: 5246 logger.info("Test: Identity request PERMANENT_ID") 5247 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'], 5248 4 + 1 + 3 + 8 + 4, 5249 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, 5250 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0, 5251 EAP_SIM_AT_PERMANENT_ID_REQ, 1, 0) 5252 idx += 1 5253 if ctx['num'] == idx: 5254 logger.info("Test: Identity request PERMANENT_ID (duplicate)") 5255 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'], 5256 4 + 1 + 3 + 8 + 4, 5257 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, 5258 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0, 5259 EAP_SIM_AT_PERMANENT_ID_REQ, 1, 0) 5260 idx += 1 5261 if ctx['num'] == idx: 5262 logger.info("Test: EAP-Failure") 5263 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5264 5265 idx += 1 5266 if ctx['num'] == idx: 5267 logger.info("Test: No AT_MAC and AT_RAND in Challenge") 5268 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], 5269 4 + 1 + 3, 5270 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CHALLENGE, 0) 5271 idx += 1 5272 if ctx['num'] == idx: 5273 logger.info("Test: EAP-Failure") 5274 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5275 5276 idx += 1 5277 if ctx['num'] == idx: 5278 logger.info("Test: No AT_RAND in Challenge") 5279 return struct.pack(">BBHBBHBBH4L", EAP_CODE_REQUEST, ctx['id'], 5280 4 + 1 + 3 + 20, 5281 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CHALLENGE, 0, 5282 EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0) 5283 idx += 1 5284 if ctx['num'] == idx: 5285 logger.info("Test: EAP-Failure") 5286 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5287 5288 idx += 1 5289 if ctx['num'] == idx: 5290 logger.info("Test: Insufficient number of challenges in Challenge") 5291 return struct.pack(">BBHBBHBBH4LBBH4L", EAP_CODE_REQUEST, ctx['id'], 5292 4 + 1 + 3 + 20 + 20, 5293 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CHALLENGE, 0, 5294 EAP_SIM_AT_RAND, 5, 0, 0, 0, 0, 0, 5295 EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0) 5296 idx += 1 5297 if ctx['num'] == idx: 5298 logger.info("Test: EAP-Failure") 5299 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5300 5301 idx += 1 5302 if ctx['num'] == idx: 5303 logger.info("Test: Too many challenges in Challenge") 5304 return struct.pack(">BBHBBHBBH4L4L4L4LBBH4L", EAP_CODE_REQUEST, 5305 ctx['id'], 5306 4 + 1 + 3 + 4 + 4 * 16 + 20, 5307 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CHALLENGE, 0, 5308 EAP_SIM_AT_RAND, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5309 0, 0, 0, 0, 0, 0, 0, 0, 5310 EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0) 5311 idx += 1 5312 if ctx['num'] == idx: 5313 logger.info("Test: EAP-Failure") 5314 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5315 5316 idx += 1 5317 if ctx['num'] == idx: 5318 logger.info("Test: Same RAND multiple times in Challenge") 5319 return struct.pack(">BBHBBHBBH4L4L4LBBH4L", EAP_CODE_REQUEST, 5320 ctx['id'], 5321 4 + 1 + 3 + 4 + 3 * 16 + 20, 5322 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CHALLENGE, 0, 5323 EAP_SIM_AT_RAND, 13, 0, 0, 0, 0, 0, 0, 0, 0, 1, 5324 0, 0, 0, 0, 5325 EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0) 5326 idx += 1 5327 if ctx['num'] == idx: 5328 logger.info("Test: EAP-Failure") 5329 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5330 5331 idx += 1 5332 if ctx['num'] == idx: 5333 logger.info("Test: Notification with no attributes") 5334 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], 5335 4 + 1 + 3, 5336 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0) 5337 idx += 1 5338 if ctx['num'] == idx: 5339 logger.info("Test: EAP-Failure") 5340 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5341 5342 idx += 1 5343 if ctx['num'] == idx: 5344 logger.info("Test: Notification indicating success, but no MAC") 5345 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 5346 4 + 1 + 3 + 4, 5347 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0, 5348 EAP_SIM_AT_NOTIFICATION, 1, 32768) 5349 idx += 1 5350 if ctx['num'] == idx: 5351 logger.info("Test: EAP-Failure") 5352 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5353 5354 idx += 1 5355 if ctx['num'] == idx: 5356 logger.info("Test: Notification indicating success, but invalid MAC value") 5357 return struct.pack(">BBHBBHBBHBBH4L", EAP_CODE_REQUEST, ctx['id'], 5358 4 + 1 + 3 + 4 + 20, 5359 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0, 5360 EAP_SIM_AT_NOTIFICATION, 1, 32768, 5361 EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0) 5362 idx += 1 5363 if ctx['num'] == idx: 5364 logger.info("Test: EAP-Failure") 5365 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5366 5367 idx += 1 5368 if ctx['num'] == idx: 5369 logger.info("Test: Notification before auth") 5370 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 5371 4 + 1 + 3 + 4, 5372 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0, 5373 EAP_SIM_AT_NOTIFICATION, 1, 16384) 5374 idx += 1 5375 if ctx['num'] == idx: 5376 logger.info("Test: EAP-Failure") 5377 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5378 5379 idx += 1 5380 if ctx['num'] == idx: 5381 logger.info("Test: Notification before auth") 5382 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 5383 4 + 1 + 3 + 4, 5384 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0, 5385 EAP_SIM_AT_NOTIFICATION, 1, 16385) 5386 idx += 1 5387 if ctx['num'] == idx: 5388 logger.info("Test: EAP-Failure") 5389 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5390 5391 idx += 1 5392 if ctx['num'] == idx: 5393 logger.info("Test: Notification with unrecognized non-failure") 5394 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 5395 4 + 1 + 3 + 4, 5396 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0, 5397 EAP_SIM_AT_NOTIFICATION, 1, 0xc000) 5398 idx += 1 5399 if ctx['num'] == idx: 5400 logger.info("Test: Notification before auth (duplicate)") 5401 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 5402 4 + 1 + 3 + 4, 5403 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0, 5404 EAP_SIM_AT_NOTIFICATION, 1, 0xc000) 5405 idx += 1 5406 if ctx['num'] == idx: 5407 logger.info("Test: EAP-Failure") 5408 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5409 5410 idx += 1 5411 if ctx['num'] == idx: 5412 logger.info("Test: Re-authentication (unexpected) with no attributes") 5413 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], 5414 4 + 1 + 3, 5415 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_REAUTHENTICATION, 5416 0) 5417 idx += 1 5418 if ctx['num'] == idx: 5419 logger.info("Test: EAP-Failure") 5420 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5421 5422 idx += 1 5423 if ctx['num'] == idx: 5424 logger.info("Test: Client Error") 5425 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], 5426 4 + 1 + 3, 5427 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CLIENT_ERROR, 0) 5428 idx += 1 5429 if ctx['num'] == idx: 5430 logger.info("Test: EAP-Failure") 5431 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5432 5433 idx += 1 5434 if ctx['num'] == idx: 5435 logger.info("Test: Unknown subtype") 5436 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], 5437 4 + 1 + 3, 5438 EAP_TYPE_SIM, 255, 0) 5439 idx += 1 5440 if ctx['num'] == idx: 5441 logger.info("Test: EAP-Failure") 5442 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5443 5444 return None 5445 5446 srv = start_radius_server(sim_handler) 5447 5448 try: 5449 hapd = start_ap(apdev[0]) 5450 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 5451 5452 for i in range(0, 25): 5453 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 5454 eap="SIM", identity="1232010000000000", 5455 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581", 5456 wait_connect=False) 5457 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 5458 timeout=15) 5459 if ev is None: 5460 raise Exception("Timeout on EAP start") 5461 if i in [0]: 5462 time.sleep(0.1) 5463 else: 5464 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], 5465 timeout=10) 5466 if ev is None: 5467 raise Exception("Timeout on EAP failure") 5468 dev[0].request("REMOVE_NETWORK all") 5469 dev[0].dump_monitor() 5470 finally: 5471 stop_radius_server(srv) 5472 5473def test_eap_proto_sim_errors(dev, apdev): 5474 """EAP-SIM protocol tests (error paths)""" 5475 check_hlr_auc_gw_support() 5476 params = hostapd.wpa2_eap_params(ssid="eap-test") 5477 hapd = hostapd.add_ap(apdev[0], params) 5478 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 5479 5480 with alloc_fail(dev[0], 1, "eap_sim_init"): 5481 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 5482 eap="SIM", identity="1232010000000000", 5483 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581", 5484 wait_connect=False) 5485 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"], 5486 timeout=15) 5487 if ev is None: 5488 raise Exception("Timeout on EAP start") 5489 dev[0].request("REMOVE_NETWORK all") 5490 dev[0].wait_disconnected() 5491 5492 with fail_test(dev[0], 1, "os_get_random;eap_sim_init"): 5493 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 5494 eap="SIM", identity="1232010000000000", 5495 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581", 5496 wait_connect=False) 5497 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"], 5498 timeout=15) 5499 if ev is None: 5500 raise Exception("Timeout on EAP start") 5501 dev[0].request("REMOVE_NETWORK all") 5502 dev[0].wait_disconnected() 5503 5504 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 5505 eap="SIM", identity="1232010000000000", 5506 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581") 5507 5508 with fail_test(dev[0], 1, "aes_128_cbc_encrypt;eap_sim_response_reauth"): 5509 hapd.request("EAPOL_REAUTH " + dev[0].own_addr()) 5510 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5) 5511 if ev is None: 5512 raise Exception("EAP re-authentication did not start") 5513 wait_fail_trigger(dev[0], "GET_FAIL") 5514 dev[0].request("REMOVE_NETWORK all") 5515 dev[0].dump_monitor() 5516 5517 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 5518 eap="SIM", identity="1232010000000000", 5519 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581") 5520 5521 with fail_test(dev[0], 1, "os_get_random;eap_sim_msg_add_encr_start"): 5522 hapd.request("EAPOL_REAUTH " + dev[0].own_addr()) 5523 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5) 5524 if ev is None: 5525 raise Exception("EAP re-authentication did not start") 5526 wait_fail_trigger(dev[0], "GET_FAIL") 5527 dev[0].request("REMOVE_NETWORK all") 5528 dev[0].dump_monitor() 5529 5530 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 5531 eap="SIM", identity="1232010000000000", 5532 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581") 5533 5534 with fail_test(dev[0], 1, "os_get_random;eap_sim_init_for_reauth"): 5535 hapd.request("EAPOL_REAUTH " + dev[0].own_addr()) 5536 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5) 5537 if ev is None: 5538 raise Exception("EAP re-authentication did not start") 5539 wait_fail_trigger(dev[0], "GET_FAIL") 5540 dev[0].request("REMOVE_NETWORK all") 5541 dev[0].dump_monitor() 5542 5543 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 5544 eap="SIM", identity="1232010000000000", 5545 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581") 5546 5547 with alloc_fail(dev[0], 1, "eap_sim_parse_encr;eap_sim_process_reauthentication"): 5548 hapd.request("EAPOL_REAUTH " + dev[0].own_addr()) 5549 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5) 5550 if ev is None: 5551 raise Exception("EAP re-authentication did not start") 5552 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 5553 dev[0].request("REMOVE_NETWORK all") 5554 dev[0].dump_monitor() 5555 5556 tests = [(1, "eap_sim_verify_mac"), 5557 (1, "eap_sim_parse_encr;eap_sim_process_challenge"), 5558 (1, "eap_sim_msg_init;eap_sim_response_start"), 5559 (1, "wpabuf_alloc;eap_sim_msg_init;eap_sim_response_start"), 5560 (1, "=eap_sim_learn_ids"), 5561 (2, "=eap_sim_learn_ids"), 5562 (2, "eap_sim_learn_ids"), 5563 (3, "eap_sim_learn_ids"), 5564 (1, "eap_sim_process_start"), 5565 (1, "eap_sim_getKey"), 5566 (1, "eap_sim_get_emsk"), 5567 (1, "eap_sim_get_session_id")] 5568 for count, func in tests: 5569 with alloc_fail(dev[0], count, func): 5570 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 5571 eap="SIM", identity="1232010000000000@domain", 5572 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581", 5573 erp="1", wait_connect=False) 5574 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 5575 dev[0].request("REMOVE_NETWORK all") 5576 dev[0].dump_monitor() 5577 5578 tests = [(1, "aes_128_cbc_decrypt;eap_sim_parse_encr")] 5579 for count, func in tests: 5580 with fail_test(dev[0], count, func): 5581 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 5582 eap="SIM", identity="1232010000000000", 5583 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581", 5584 wait_connect=False) 5585 wait_fail_trigger(dev[0], "GET_FAIL") 5586 dev[0].request("REMOVE_NETWORK all") 5587 dev[0].dump_monitor() 5588 5589 params = int_eap_server_params() 5590 params['eap_sim_db'] = "unix:/tmp/hlr_auc_gw.sock" 5591 params['eap_sim_aka_result_ind'] = "1" 5592 hapd2 = hostapd.add_ap(apdev[1], params) 5593 dev[0].scan_for_bss(hapd2.own_addr(), freq=2412) 5594 5595 with alloc_fail(dev[0], 1, 5596 "eap_sim_msg_init;eap_sim_response_notification"): 5597 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", 5598 scan_freq="2412", 5599 eap="SIM", identity="1232010000000000", 5600 phase1="result_ind=1", 5601 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581", 5602 wait_connect=False) 5603 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 5604 dev[0].request("REMOVE_NETWORK all") 5605 dev[0].dump_monitor() 5606 5607 hapd2.dump_monitor() 5608 tests = ["eap_sim_msg_add_encr_start;eap_sim_response_notification", 5609 "aes_128_cbc_encrypt;eap_sim_response_notification"] 5610 for func in tests: 5611 with fail_test(dev[0], 1, func): 5612 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", 5613 scan_freq="2412", 5614 eap="SIM", identity="1232010000000000", 5615 phase1="result_ind=1", 5616 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581") 5617 hapd2.wait_sta() 5618 dev[0].request("REAUTHENTICATE") 5619 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5) 5620 if ev is None: 5621 raise Exception("EAP method not started on reauthentication") 5622 time.sleep(0.1) 5623 wait_fail_trigger(dev[0], "GET_FAIL") 5624 dev[0].request("REMOVE_NETWORK all") 5625 dev[0].dump_monitor() 5626 hapd2.wait_sta_disconnect() 5627 5628 hapd2.dump_monitor() 5629 tests = ["eap_sim_parse_encr;eap_sim_process_notification_reauth"] 5630 for func in tests: 5631 with alloc_fail(dev[0], 1, func): 5632 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", 5633 scan_freq="2412", 5634 eap="SIM", identity="1232010000000000", 5635 phase1="result_ind=1", 5636 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581") 5637 hapd2.wait_sta() 5638 dev[0].request("REAUTHENTICATE") 5639 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5) 5640 if ev is None: 5641 raise Exception("EAP method not started on reauthentication") 5642 time.sleep(0.1) 5643 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 5644 dev[0].request("REMOVE_NETWORK all") 5645 dev[0].dump_monitor() 5646 hapd2.wait_sta_disconnect() 5647 5648def test_eap_proto_aka_errors(dev, apdev): 5649 """EAP-AKA protocol tests (error paths)""" 5650 check_hlr_auc_gw_support() 5651 params = hostapd.wpa2_eap_params(ssid="eap-test") 5652 hapd = hostapd.add_ap(apdev[0], params) 5653 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 5654 5655 with alloc_fail(dev[0], 1, "eap_aka_init"): 5656 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 5657 eap="AKA", identity="0232010000000000", 5658 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123", 5659 wait_connect=False) 5660 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"], 5661 timeout=15) 5662 if ev is None: 5663 raise Exception("Timeout on EAP start") 5664 dev[0].request("REMOVE_NETWORK all") 5665 dev[0].wait_disconnected() 5666 5667 tests = [(1, "=eap_aka_learn_ids"), 5668 (2, "=eap_aka_learn_ids"), 5669 (1, "eap_sim_parse_encr;eap_aka_process_challenge"), 5670 (1, "wpabuf_alloc;eap_aka_add_id_msg"), 5671 (1, "eap_aka_getKey"), 5672 (1, "eap_aka_get_emsk"), 5673 (1, "eap_aka_get_session_id")] 5674 for count, func in tests: 5675 with alloc_fail(dev[0], count, func): 5676 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 5677 eap="AKA", identity="0232010000000000@domain", 5678 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123", 5679 erp="1", wait_connect=False) 5680 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 5681 dev[0].request("REMOVE_NETWORK all") 5682 dev[0].dump_monitor() 5683 5684 params = int_eap_server_params() 5685 params['eap_sim_db'] = "unix:/tmp/hlr_auc_gw.sock" 5686 params['eap_sim_aka_result_ind'] = "1" 5687 hapd2 = hostapd.add_ap(apdev[1], params) 5688 dev[0].scan_for_bss(hapd2.own_addr(), freq=2412) 5689 5690 with alloc_fail(dev[0], 1, 5691 "eap_sim_msg_init;eap_aka_response_notification"): 5692 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412", 5693 eap="AKA", identity="0232010000000000", 5694 phase1="result_ind=1", 5695 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123", 5696 wait_connect=False) 5697 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 5698 dev[0].request("REMOVE_NETWORK all") 5699 dev[0].dump_monitor() 5700 5701 tests = [(1, "aes_128_encrypt_block;milenage_f1;milenage_check", None), 5702 (2, "aes_128_encrypt_block;milenage_f1;milenage_check", None), 5703 (1, "milenage_f2345;milenage_check", None), 5704 (7, "aes_128_encrypt_block;milenage_f2345;milenage_check", 5705 "ff0000000123"), 5706 (1, "aes_128_encrypt_block;milenage_f1;milenage_check", 5707 "fff000000123")] 5708 for count, func, seq in tests: 5709 if not seq: 5710 seq = "000000000123" 5711 with fail_test(dev[0], count, func): 5712 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", 5713 scan_freq="2412", 5714 eap="AKA", identity="0232010000000000", 5715 phase1="result_ind=1", 5716 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:" + seq, 5717 wait_connect=False) 5718 wait_fail_trigger(dev[0], "GET_FAIL") 5719 dev[0].request("REMOVE_NETWORK all") 5720 dev[0].wait_disconnected() 5721 dev[0].dump_monitor() 5722 5723 hapd2.dump_monitor() 5724 tests = ["eap_sim_msg_add_encr_start;eap_aka_response_notification", 5725 "aes_128_cbc_encrypt;eap_aka_response_notification"] 5726 for func in tests: 5727 with fail_test(dev[0], 1, func): 5728 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", 5729 scan_freq="2412", 5730 eap="AKA", identity="0232010000000000", 5731 phase1="result_ind=1", 5732 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123") 5733 hapd2.wait_sta() 5734 dev[0].request("REAUTHENTICATE") 5735 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5) 5736 if ev is None: 5737 raise Exception("EAP method not started on reauthentication") 5738 time.sleep(0.1) 5739 wait_fail_trigger(dev[0], "GET_FAIL") 5740 dev[0].request("REMOVE_NETWORK all") 5741 dev[0].dump_monitor() 5742 hapd2.wait_sta_disconnect() 5743 5744 hapd2.dump_monitor() 5745 tests = ["eap_sim_parse_encr;eap_aka_process_notification_reauth"] 5746 for func in tests: 5747 with alloc_fail(dev[0], 1, func): 5748 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", 5749 scan_freq="2412", 5750 eap="AKA", identity="0232010000000000", 5751 phase1="result_ind=1", 5752 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123") 5753 hapd2.wait_sta() 5754 dev[0].request("REAUTHENTICATE") 5755 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5) 5756 if ev is None: 5757 raise Exception("EAP method not started on reauthentication") 5758 time.sleep(0.1) 5759 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 5760 dev[0].request("REMOVE_NETWORK all") 5761 dev[0].dump_monitor() 5762 hapd2.wait_sta_disconnect() 5763 5764def test_eap_proto_aka_prime_errors(dev, apdev): 5765 """EAP-AKA' protocol tests (error paths)""" 5766 check_hlr_auc_gw_support() 5767 params = hostapd.wpa2_eap_params(ssid="eap-test") 5768 hapd = hostapd.add_ap(apdev[0], params) 5769 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 5770 5771 with alloc_fail(dev[0], 1, "eap_aka_init"): 5772 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 5773 eap="AKA'", identity="6555444333222111", 5774 password="5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123", 5775 wait_connect=False) 5776 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"], 5777 timeout=15) 5778 if ev is None: 5779 raise Exception("Timeout on EAP start") 5780 dev[0].request("REMOVE_NETWORK all") 5781 dev[0].wait_disconnected() 5782 5783 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 5784 eap="AKA'", identity="6555444333222111", 5785 password="5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123") 5786 5787 with fail_test(dev[0], 1, "aes_128_cbc_encrypt;eap_aka_response_reauth"): 5788 hapd.request("EAPOL_REAUTH " + dev[0].own_addr()) 5789 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5) 5790 if ev is None: 5791 raise Exception("EAP re-authentication did not start") 5792 wait_fail_trigger(dev[0], "GET_FAIL") 5793 dev[0].request("REMOVE_NETWORK all") 5794 dev[0].dump_monitor() 5795 5796 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 5797 eap="AKA'", identity="6555444333222111", 5798 password="5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123") 5799 5800 with alloc_fail(dev[0], 1, "eap_sim_parse_encr;eap_aka_process_reauthentication"): 5801 hapd.request("EAPOL_REAUTH " + dev[0].own_addr()) 5802 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5) 5803 if ev is None: 5804 raise Exception("EAP re-authentication did not start") 5805 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 5806 dev[0].request("REMOVE_NETWORK all") 5807 dev[0].dump_monitor() 5808 5809 tests = [(1, "eap_sim_verify_mac_sha256"), 5810 (1, "=eap_aka_process_challenge")] 5811 for count, func in tests: 5812 with alloc_fail(dev[0], count, func): 5813 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 5814 eap="AKA'", identity="6555444333222111", 5815 password="5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123", 5816 erp="1", wait_connect=False) 5817 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 5818 dev[0].request("REMOVE_NETWORK all") 5819 dev[0].dump_monitor() 5820 5821def test_eap_proto_ikev2(dev, apdev): 5822 """EAP-IKEv2 protocol tests""" 5823 check_eap_capa(dev[0], "IKEV2") 5824 5825 global eap_proto_ikev2_test_done 5826 eap_proto_ikev2_test_done = False 5827 5828 def ikev2_handler(ctx, req): 5829 logger.info("ikev2_handler - RX " + binascii.hexlify(req).decode()) 5830 if 'num' not in ctx: 5831 ctx['num'] = 0 5832 ctx['num'] = ctx['num'] + 1 5833 if 'id' not in ctx: 5834 ctx['id'] = 1 5835 ctx['id'] = (ctx['id'] + 1) % 256 5836 5837 idx = 0 5838 5839 idx += 1 5840 if ctx['num'] == idx: 5841 logger.info("Test: Missing payload") 5842 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 5843 4 + 1, 5844 EAP_TYPE_IKEV2) 5845 5846 idx += 1 5847 if ctx['num'] == idx: 5848 logger.info("Test: Truncated Message Length field") 5849 return struct.pack(">BBHBB3B", EAP_CODE_REQUEST, ctx['id'], 5850 4 + 1 + 1 + 3, 5851 EAP_TYPE_IKEV2, 0x80, 0, 0, 0) 5852 5853 idx += 1 5854 if ctx['num'] == idx: 5855 logger.info("Test: Too short Message Length value") 5856 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'], 5857 4 + 1 + 1 + 4 + 1, 5858 EAP_TYPE_IKEV2, 0x80, 0, 1) 5859 5860 idx += 1 5861 if ctx['num'] == idx: 5862 logger.info("Test: Truncated message") 5863 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'], 5864 4 + 1 + 1 + 4, 5865 EAP_TYPE_IKEV2, 0x80, 1) 5866 5867 idx += 1 5868 if ctx['num'] == idx: 5869 logger.info("Test: Truncated message(2)") 5870 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'], 5871 4 + 1 + 1 + 4, 5872 EAP_TYPE_IKEV2, 0x80, 0xffffffff) 5873 5874 idx += 1 5875 if ctx['num'] == idx: 5876 logger.info("Test: Truncated message(3)") 5877 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'], 5878 4 + 1 + 1 + 4, 5879 EAP_TYPE_IKEV2, 0xc0, 0xffffffff) 5880 5881 idx += 1 5882 if ctx['num'] == idx: 5883 logger.info("Test: Truncated message(4)") 5884 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'], 5885 4 + 1 + 1 + 4, 5886 EAP_TYPE_IKEV2, 0xc0, 10000000) 5887 5888 idx += 1 5889 if ctx['num'] == idx: 5890 logger.info("Test: Too long fragments (first fragment)") 5891 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'], 5892 4 + 1 + 1 + 4 + 1, 5893 EAP_TYPE_IKEV2, 0xc0, 2, 1) 5894 5895 idx += 1 5896 if ctx['num'] == idx: 5897 logger.info("Test: Too long fragments (second fragment)") 5898 return struct.pack(">BBHBB2B", EAP_CODE_REQUEST, ctx['id'], 5899 4 + 1 + 1 + 2, 5900 EAP_TYPE_IKEV2, 0x00, 2, 3) 5901 5902 idx += 1 5903 if ctx['num'] == idx: 5904 logger.info("Test: No Message Length field in first fragment") 5905 return struct.pack(">BBHBBB", EAP_CODE_REQUEST, ctx['id'], 5906 4 + 1 + 1 + 1, 5907 EAP_TYPE_IKEV2, 0x40, 1) 5908 5909 idx += 1 5910 if ctx['num'] == idx: 5911 logger.info("Test: ICV before keys") 5912 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 5913 4 + 1 + 1, 5914 EAP_TYPE_IKEV2, 0x20) 5915 5916 idx += 1 5917 if ctx['num'] == idx: 5918 logger.info("Test: Unsupported IKEv2 header version") 5919 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'], 5920 4 + 1 + 1 + 28, 5921 EAP_TYPE_IKEV2, 0x00, 5922 0, 0, 0, 0, 5923 0, 0, 0, 0, 0, 0) 5924 5925 idx += 1 5926 if ctx['num'] == idx: 5927 logger.info("Test: Incorrect IKEv2 header Length") 5928 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'], 5929 4 + 1 + 1 + 28, 5930 EAP_TYPE_IKEV2, 0x00, 5931 0, 0, 0, 0, 5932 0, 0x20, 0, 0, 0, 0) 5933 5934 idx += 1 5935 if ctx['num'] == idx: 5936 logger.info("Test: Unexpected IKEv2 Exchange Type in SA_INIT state") 5937 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'], 5938 4 + 1 + 1 + 28, 5939 EAP_TYPE_IKEV2, 0x00, 5940 0, 0, 0, 0, 5941 0, 0x20, 0, 0, 0, 28) 5942 5943 idx += 1 5944 if ctx['num'] == idx: 5945 logger.info("Test: Unexpected IKEv2 Message ID in SA_INIT state") 5946 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'], 5947 4 + 1 + 1 + 28, 5948 EAP_TYPE_IKEV2, 0x00, 5949 0, 0, 0, 0, 5950 0, 0x20, 34, 0, 1, 28) 5951 5952 idx += 1 5953 if ctx['num'] == idx: 5954 logger.info("Test: Unexpected IKEv2 Flags value") 5955 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'], 5956 4 + 1 + 1 + 28, 5957 EAP_TYPE_IKEV2, 0x00, 5958 0, 0, 0, 0, 5959 0, 0x20, 34, 0, 0, 28) 5960 5961 idx += 1 5962 if ctx['num'] == idx: 5963 logger.info("Test: Unexpected IKEv2 Flags value(2)") 5964 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'], 5965 4 + 1 + 1 + 28, 5966 EAP_TYPE_IKEV2, 0x00, 5967 0, 0, 0, 0, 5968 0, 0x20, 34, 0x20, 0, 28) 5969 5970 idx += 1 5971 if ctx['num'] == idx: 5972 logger.info("Test: No SAi1 in SA_INIT") 5973 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'], 5974 4 + 1 + 1 + 28, 5975 EAP_TYPE_IKEV2, 0x00, 5976 0, 0, 0, 0, 5977 0, 0x20, 34, 0x08, 0, 28) 5978 5979 def build_ike(id, next=0, exch_type=34, flags=0x00, ike=b''): 5980 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, id, 5981 4 + 1 + 1 + 28 + len(ike), 5982 EAP_TYPE_IKEV2, flags, 5983 0, 0, 0, 0, 5984 next, 0x20, exch_type, 0x08, 0, 5985 28 + len(ike)) + ike 5986 5987 idx += 1 5988 if ctx['num'] == idx: 5989 logger.info("Test: Unexpected extra data after payloads") 5990 return build_ike(ctx['id'], ike=struct.pack(">B", 1)) 5991 5992 idx += 1 5993 if ctx['num'] == idx: 5994 logger.info("Test: Truncated payload header") 5995 return build_ike(ctx['id'], next=128, ike=struct.pack(">B", 1)) 5996 5997 idx += 1 5998 if ctx['num'] == idx: 5999 logger.info("Test: Too small payload header length") 6000 ike = struct.pack(">BBH", 0, 0, 3) 6001 return build_ike(ctx['id'], next=128, ike=ike) 6002 6003 idx += 1 6004 if ctx['num'] == idx: 6005 logger.info("Test: Too large payload header length") 6006 ike = struct.pack(">BBH", 0, 0, 5) 6007 return build_ike(ctx['id'], next=128, ike=ike) 6008 6009 idx += 1 6010 if ctx['num'] == idx: 6011 logger.info("Test: Unsupported payload (non-critical and critical)") 6012 ike = struct.pack(">BBHBBH", 129, 0, 4, 0, 0x01, 4) 6013 return build_ike(ctx['id'], next=128, ike=ike) 6014 6015 idx += 1 6016 if ctx['num'] == idx: 6017 logger.info("Test: Certificate and empty SAi1") 6018 ike = struct.pack(">BBHBBH", 33, 0, 4, 0, 0, 4) 6019 return build_ike(ctx['id'], next=37, ike=ike) 6020 6021 idx += 1 6022 if ctx['num'] == idx: 6023 logger.info("Test: Too short proposal") 6024 ike = struct.pack(">BBHBBHBBB", 0, 0, 4 + 7, 6025 0, 0, 7, 0, 0, 0) 6026 return build_ike(ctx['id'], next=33, ike=ike) 6027 6028 idx += 1 6029 if ctx['num'] == idx: 6030 logger.info("Test: Too small proposal length in SAi1") 6031 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8, 6032 0, 0, 7, 0, 0, 0, 0) 6033 return build_ike(ctx['id'], next=33, ike=ike) 6034 6035 idx += 1 6036 if ctx['num'] == idx: 6037 logger.info("Test: Too large proposal length in SAi1") 6038 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8, 6039 0, 0, 9, 0, 0, 0, 0) 6040 return build_ike(ctx['id'], next=33, ike=ike) 6041 6042 idx += 1 6043 if ctx['num'] == idx: 6044 logger.info("Test: Unexpected proposal type in SAi1") 6045 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8, 6046 1, 0, 8, 0, 0, 0, 0) 6047 return build_ike(ctx['id'], next=33, ike=ike) 6048 6049 idx += 1 6050 if ctx['num'] == idx: 6051 logger.info("Test: Unexpected Protocol ID in SAi1") 6052 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8, 6053 0, 0, 8, 0, 0, 0, 0) 6054 return build_ike(ctx['id'], next=33, ike=ike) 6055 6056 idx += 1 6057 if ctx['num'] == idx: 6058 logger.info("Test: Unexpected proposal number in SAi1") 6059 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8, 6060 0, 0, 8, 0, 1, 0, 0) 6061 return build_ike(ctx['id'], next=33, ike=ike) 6062 6063 idx += 1 6064 if ctx['num'] == idx: 6065 logger.info("Test: Not enough room for SPI in SAi1") 6066 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8, 6067 0, 0, 8, 1, 1, 1, 0) 6068 return build_ike(ctx['id'], next=33, ike=ike) 6069 6070 idx += 1 6071 if ctx['num'] == idx: 6072 logger.info("Test: Unexpected SPI in SAi1") 6073 ike = struct.pack(">BBHBBHBBBBB", 0, 0, 4 + 9, 6074 0, 0, 9, 1, 1, 1, 0, 1) 6075 return build_ike(ctx['id'], next=33, ike=ike) 6076 6077 idx += 1 6078 if ctx['num'] == idx: 6079 logger.info("Test: No transforms in SAi1") 6080 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8, 6081 0, 0, 8, 1, 1, 0, 0) 6082 return build_ike(ctx['id'], next=33, ike=ike) 6083 6084 idx += 1 6085 if ctx['num'] == idx: 6086 logger.info("Test: Too short transform in SAi1") 6087 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8, 6088 0, 0, 8, 1, 1, 0, 1) 6089 return build_ike(ctx['id'], next=33, ike=ike) 6090 6091 idx += 1 6092 if ctx['num'] == idx: 6093 logger.info("Test: Too small transform length in SAi1") 6094 ike = struct.pack(">BBHBBHBBBBBBHBBH", 0, 0, 4 + 8 + 8, 6095 0, 0, 8 + 8, 1, 1, 0, 1, 6096 0, 0, 7, 0, 0, 0) 6097 return build_ike(ctx['id'], next=33, ike=ike) 6098 6099 idx += 1 6100 if ctx['num'] == idx: 6101 logger.info("Test: Too large transform length in SAi1") 6102 ike = struct.pack(">BBHBBHBBBBBBHBBH", 0, 0, 4 + 8 + 8, 6103 0, 0, 8 + 8, 1, 1, 0, 1, 6104 0, 0, 9, 0, 0, 0) 6105 return build_ike(ctx['id'], next=33, ike=ike) 6106 6107 idx += 1 6108 if ctx['num'] == idx: 6109 logger.info("Test: Unexpected Transform type in SAi1") 6110 ike = struct.pack(">BBHBBHBBBBBBHBBH", 0, 0, 4 + 8 + 8, 6111 0, 0, 8 + 8, 1, 1, 0, 1, 6112 1, 0, 8, 0, 0, 0) 6113 return build_ike(ctx['id'], next=33, ike=ike) 6114 6115 idx += 1 6116 if ctx['num'] == idx: 6117 logger.info("Test: No transform attributes in SAi1") 6118 ike = struct.pack(">BBHBBHBBBBBBHBBH", 0, 0, 4 + 8 + 8, 6119 0, 0, 8 + 8, 1, 1, 0, 1, 6120 0, 0, 8, 0, 0, 0) 6121 return build_ike(ctx['id'], next=33, ike=ike) 6122 6123 idx += 1 6124 if ctx['num'] == idx: 6125 logger.info("Test: No transform attr for AES and unexpected data after transforms in SAi1") 6126 tlen1 = 8 + 3 6127 tlen2 = 8 + 4 6128 tlen3 = 8 + 4 6129 tlen = tlen1 + tlen2 + tlen3 6130 ike = struct.pack(">BBHBBHBBBBBBHBBH3BBBHBBHHHBBHBBHHHB", 6131 0, 0, 4 + 8 + tlen + 1, 6132 0, 0, 8 + tlen + 1, 1, 1, 0, 3, 6133 3, 0, tlen1, 1, 0, 12, 1, 2, 3, 6134 3, 0, tlen2, 1, 0, 12, 0, 128, 6135 0, 0, tlen3, 1, 0, 12, 0x8000 | 14, 127, 6136 1) 6137 return build_ike(ctx['id'], next=33, ike=ike) 6138 6139 def build_sa(next=0): 6140 tlen = 5 * 8 6141 return struct.pack(">BBHBBHBBBBBBHBBHBBHBBHBBHBBHBBHBBHBBHBBH", 6142 next, 0, 4 + 8 + tlen, 6143 0, 0, 8 + tlen, 1, 1, 0, 5, 6144 3, 0, 8, 1, 0, 3, 6145 3, 0, 8, 2, 0, 1, 6146 3, 0, 8, 3, 0, 1, 6147 3, 0, 8, 4, 0, 5, 6148 0, 0, 8, 241, 0, 0) 6149 6150 idx += 1 6151 if ctx['num'] == idx: 6152 logger.info("Test: Valid proposal, but no KEi in SAi1") 6153 ike = build_sa() 6154 return build_ike(ctx['id'], next=33, ike=ike) 6155 6156 idx += 1 6157 if ctx['num'] == idx: 6158 logger.info("Test: Empty KEi in SAi1") 6159 ike = build_sa(next=34) + struct.pack(">BBH", 0, 0, 4) 6160 return build_ike(ctx['id'], next=33, ike=ike) 6161 6162 idx += 1 6163 if ctx['num'] == idx: 6164 logger.info("Test: Mismatch in DH Group in SAi1") 6165 ike = build_sa(next=34) 6166 ike += struct.pack(">BBHHH", 0, 0, 4 + 4 + 96, 12345, 0) 6167 ike += 96*b'\x00' 6168 return build_ike(ctx['id'], next=33, ike=ike) 6169 idx += 1 6170 if ctx['num'] == idx: 6171 logger.info("Test: EAP-Failure") 6172 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 6173 6174 idx += 1 6175 if ctx['num'] == idx: 6176 logger.info("Test: Invalid DH public value length in SAi1") 6177 ike = build_sa(next=34) 6178 ike += struct.pack(">BBHHH", 0, 0, 4 + 4 + 96, 5, 0) 6179 ike += 96*b'\x00' 6180 return build_ike(ctx['id'], next=33, ike=ike) 6181 6182 def build_ke(next=0): 6183 ke = struct.pack(">BBHHH", next, 0, 4 + 4 + 192, 5, 0) 6184 ke += 191*b'\x00'+b'\x02' 6185 return ke 6186 6187 idx += 1 6188 if ctx['num'] == idx: 6189 logger.info("Test: Valid proposal and KEi, but no Ni in SAi1") 6190 ike = build_sa(next=34) 6191 ike += build_ke() 6192 return build_ike(ctx['id'], next=33, ike=ike) 6193 6194 idx += 1 6195 if ctx['num'] == idx: 6196 logger.info("Test: Too short Ni in SAi1") 6197 ike = build_sa(next=34) 6198 ike += build_ke(next=40) 6199 ike += struct.pack(">BBH", 0, 0, 4) 6200 return build_ike(ctx['id'], next=33, ike=ike) 6201 6202 idx += 1 6203 if ctx['num'] == idx: 6204 logger.info("Test: Too long Ni in SAi1") 6205 ike = build_sa(next=34) 6206 ike += build_ke(next=40) 6207 ike += struct.pack(">BBH", 0, 0, 4 + 257) + 257*b'\x00' 6208 return build_ike(ctx['id'], next=33, ike=ike) 6209 6210 def build_ni(next=0): 6211 return struct.pack(">BBH", next, 0, 4 + 256) + 256*b'\x00' 6212 6213 def build_sai1(id): 6214 ike = build_sa(next=34) 6215 ike += build_ke(next=40) 6216 ike += build_ni() 6217 return build_ike(ctx['id'], next=33, ike=ike) 6218 6219 idx += 1 6220 if ctx['num'] == idx: 6221 logger.info("Test: Valid proposal, KEi, and Ni in SAi1") 6222 return build_sai1(ctx['id']) 6223 idx += 1 6224 if ctx['num'] == idx: 6225 logger.info("Test: EAP-Failure") 6226 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 6227 6228 idx += 1 6229 if ctx['num'] == idx: 6230 logger.info("Test: Valid proposal, KEi, and Ni in SAi1") 6231 return build_sai1(ctx['id']) 6232 idx += 1 6233 if ctx['num'] == idx: 6234 logger.info("Test: No integrity checksum") 6235 ike = b'' 6236 return build_ike(ctx['id'], next=37, ike=ike) 6237 6238 idx += 1 6239 if ctx['num'] == idx: 6240 logger.info("Test: Valid proposal, KEi, and Ni in SAi1") 6241 return build_sai1(ctx['id']) 6242 idx += 1 6243 if ctx['num'] == idx: 6244 logger.info("Test: Truncated integrity checksum") 6245 return struct.pack(">BBHBB", 6246 EAP_CODE_REQUEST, ctx['id'], 6247 4 + 1 + 1, 6248 EAP_TYPE_IKEV2, 0x20) 6249 6250 idx += 1 6251 if ctx['num'] == idx: 6252 logger.info("Test: Valid proposal, KEi, and Ni in SAi1") 6253 return build_sai1(ctx['id']) 6254 idx += 1 6255 if ctx['num'] == idx: 6256 logger.info("Test: Invalid integrity checksum") 6257 ike = b'' 6258 return build_ike(ctx['id'], next=37, flags=0x20, ike=ike) 6259 6260 idx += 1 6261 if ctx['num'] == idx: 6262 logger.info("No more test responses available - test case completed") 6263 global eap_proto_ikev2_test_done 6264 eap_proto_ikev2_test_done = True 6265 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 6266 4 + 1, 6267 EAP_TYPE_IKEV2) 6268 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 6269 6270 srv = start_radius_server(ikev2_handler) 6271 6272 try: 6273 hapd = start_ap(apdev[0]) 6274 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 6275 6276 i = 0 6277 while not eap_proto_ikev2_test_done: 6278 i += 1 6279 logger.info("Running connection iteration %d" % i) 6280 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 6281 eap="IKEV2", identity="user", 6282 password="password", 6283 wait_connect=False) 6284 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=15) 6285 if ev is None: 6286 raise Exception("Timeout on EAP start") 6287 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 6288 timeout=15) 6289 if ev is None: 6290 raise Exception("Timeout on EAP method start") 6291 if i in [41, 46]: 6292 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], 6293 timeout=10) 6294 if ev is None: 6295 raise Exception("Timeout on EAP failure") 6296 else: 6297 time.sleep(0.05) 6298 dev[0].request("REMOVE_NETWORK all") 6299 dev[0].wait_disconnected() 6300 dev[0].dump_monitor() 6301 dev[1].dump_monitor() 6302 dev[2].dump_monitor() 6303 finally: 6304 stop_radius_server(srv) 6305 6306def NtPasswordHash(password): 6307 pw = password.encode('utf_16_le') 6308 return hashlib.new('md4', pw).digest() 6309 6310def HashNtPasswordHash(password_hash): 6311 return hashlib.new('md4', password_hash).digest() 6312 6313def ChallengeHash(peer_challenge, auth_challenge, username): 6314 data = peer_challenge + auth_challenge + username 6315 return hashlib.sha1(data).digest()[0:8] 6316 6317def GenerateAuthenticatorResponse(password, nt_response, peer_challenge, 6318 auth_challenge, username): 6319 magic1 = binascii.unhexlify("4D616769632073657276657220746F20636C69656E74207369676E696E6720636F6E7374616E74") 6320 magic2 = binascii.unhexlify("50616420746F206D616B6520697420646F206D6F7265207468616E206F6E6520697465726174696F6E") 6321 6322 password_hash = NtPasswordHash(password) 6323 password_hash_hash = HashNtPasswordHash(password_hash) 6324 data = password_hash_hash + nt_response + magic1 6325 digest = hashlib.sha1(data).digest() 6326 6327 challenge = ChallengeHash(peer_challenge, auth_challenge, username.encode()) 6328 6329 data = digest + challenge + magic2 6330 resp = hashlib.sha1(data).digest() 6331 return resp 6332 6333def test_eap_proto_ikev2_errors(dev, apdev): 6334 """EAP-IKEv2 local error cases""" 6335 check_eap_capa(dev[0], "IKEV2") 6336 params = hostapd.wpa2_eap_params(ssid="eap-test") 6337 hapd = hostapd.add_ap(apdev[0], params) 6338 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 6339 6340 for i in range(1, 5): 6341 with alloc_fail(dev[0], i, "eap_ikev2_init"): 6342 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 6343 eap="IKEV2", identity="ikev2 user", 6344 password="ike password", 6345 wait_connect=False) 6346 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"], 6347 timeout=15) 6348 if ev is None: 6349 raise Exception("Timeout on EAP start") 6350 dev[0].request("REMOVE_NETWORK all") 6351 dev[0].wait_disconnected() 6352 6353 tests = [(1, "ikev2_encr_encrypt"), 6354 (1, "ikev2_encr_decrypt"), 6355 (1, "ikev2_derive_auth_data"), 6356 (2, "ikev2_derive_auth_data"), 6357 (1, "=ikev2_decrypt_payload"), 6358 (1, "ikev2_encr_decrypt;ikev2_decrypt_payload"), 6359 (1, "ikev2_encr_encrypt;ikev2_build_encrypted"), 6360 (1, "ikev2_derive_sk_keys"), 6361 (2, "ikev2_derive_sk_keys"), 6362 (3, "ikev2_derive_sk_keys"), 6363 (4, "ikev2_derive_sk_keys"), 6364 (5, "ikev2_derive_sk_keys"), 6365 (6, "ikev2_derive_sk_keys"), 6366 (7, "ikev2_derive_sk_keys"), 6367 (8, "ikev2_derive_sk_keys"), 6368 (1, "eap_ikev2_derive_keymat;eap_ikev2_peer_keymat"), 6369 (1, "eap_msg_alloc;eap_ikev2_build_msg"), 6370 (1, "eap_ikev2_getKey"), 6371 (1, "eap_ikev2_get_emsk"), 6372 (1, "eap_ikev2_get_session_id"), 6373 (1, "=ikev2_derive_keys"), 6374 (2, "=ikev2_derive_keys"), 6375 (1, "wpabuf_alloc;ikev2_process_kei"), 6376 (1, "=ikev2_process_idi"), 6377 (1, "ikev2_derive_auth_data;ikev2_build_auth"), 6378 (1, "wpabuf_alloc;ikev2_build_sa_init"), 6379 (2, "wpabuf_alloc;ikev2_build_sa_init"), 6380 (3, "wpabuf_alloc;ikev2_build_sa_init"), 6381 (4, "wpabuf_alloc;ikev2_build_sa_init"), 6382 (5, "wpabuf_alloc;ikev2_build_sa_init"), 6383 (6, "wpabuf_alloc;ikev2_build_sa_init"), 6384 (1, "wpabuf_alloc;ikev2_build_sa_auth"), 6385 (2, "wpabuf_alloc;ikev2_build_sa_auth"), 6386 (1, "ikev2_build_auth;ikev2_build_sa_auth")] 6387 for count, func in tests: 6388 with alloc_fail(dev[0], count, func): 6389 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 6390 eap="IKEV2", identity="ikev2 user@domain", 6391 password="ike password", erp="1", wait_connect=False) 6392 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 6393 timeout=15) 6394 if ev is None: 6395 raise Exception("Timeout on EAP start") 6396 ok = False 6397 for j in range(10): 6398 state = dev[0].request('GET_ALLOC_FAIL') 6399 if state.startswith('0:'): 6400 ok = True 6401 break 6402 time.sleep(0.1) 6403 if not ok: 6404 raise Exception("No allocation failure seen for %d:%s" % (count, func)) 6405 dev[0].request("REMOVE_NETWORK all") 6406 dev[0].wait_disconnected() 6407 6408 tests = [(1, "wpabuf_alloc;ikev2_build_notify"), 6409 (2, "wpabuf_alloc;ikev2_build_notify"), 6410 (1, "ikev2_build_encrypted;ikev2_build_notify")] 6411 for count, func in tests: 6412 with alloc_fail(dev[0], count, func): 6413 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 6414 eap="IKEV2", identity="ikev2 user", 6415 password="wrong password", erp="1", 6416 wait_connect=False) 6417 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 6418 timeout=15) 6419 if ev is None: 6420 raise Exception("Timeout on EAP start") 6421 ok = False 6422 for j in range(10): 6423 state = dev[0].request('GET_ALLOC_FAIL') 6424 if state.startswith('0:'): 6425 ok = True 6426 break 6427 time.sleep(0.1) 6428 if not ok: 6429 raise Exception("No allocation failure seen for %d:%s" % (count, func)) 6430 dev[0].request("REMOVE_NETWORK all") 6431 dev[0].wait_disconnected() 6432 6433 tests = [(1, "ikev2_integ_hash"), 6434 (1, "ikev2_integ_hash;ikev2_decrypt_payload"), 6435 (1, "os_get_random;ikev2_build_encrypted"), 6436 (1, "ikev2_prf_plus;ikev2_derive_sk_keys"), 6437 (1, "eap_ikev2_derive_keymat;eap_ikev2_peer_keymat"), 6438 (1, "os_get_random;ikev2_build_sa_init"), 6439 (2, "os_get_random;ikev2_build_sa_init"), 6440 (1, "ikev2_integ_hash;eap_ikev2_validate_icv"), 6441 (1, "hmac_sha1_vector;?ikev2_prf_hash;ikev2_derive_keys"), 6442 (1, "hmac_sha1_vector;?ikev2_prf_hash;ikev2_derive_auth_data"), 6443 (2, "hmac_sha1_vector;?ikev2_prf_hash;ikev2_derive_auth_data"), 6444 (3, "hmac_sha1_vector;?ikev2_prf_hash;ikev2_derive_auth_data")] 6445 for count, func in tests: 6446 with fail_test(dev[0], count, func): 6447 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 6448 eap="IKEV2", identity="ikev2 user", 6449 password="ike password", wait_connect=False) 6450 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 6451 timeout=15) 6452 if ev is None: 6453 raise Exception("Timeout on EAP start") 6454 ok = False 6455 for j in range(10): 6456 state = dev[0].request('GET_FAIL') 6457 if state.startswith('0:'): 6458 ok = True 6459 break 6460 time.sleep(0.1) 6461 if not ok: 6462 raise Exception("No failure seen for %d:%s" % (count, func)) 6463 dev[0].request("REMOVE_NETWORK all") 6464 dev[0].wait_disconnected() 6465 6466 params = {"ssid": "eap-test2", "wpa": "2", "wpa_key_mgmt": "WPA-EAP", 6467 "rsn_pairwise": "CCMP", "ieee8021x": "1", 6468 "eap_server": "1", "eap_user_file": "auth_serv/eap_user.conf", 6469 "fragment_size": "50"} 6470 hapd2 = hostapd.add_ap(apdev[1], params) 6471 dev[0].scan_for_bss(hapd2.own_addr(), freq=2412) 6472 6473 tests = [(1, "eap_ikev2_build_frag_ack"), 6474 (1, "wpabuf_alloc;eap_ikev2_process_fragment")] 6475 for count, func in tests: 6476 with alloc_fail(dev[0], count, func): 6477 dev[0].connect("eap-test2", key_mgmt="WPA-EAP", scan_freq="2412", 6478 eap="IKEV2", identity="ikev2 user", 6479 password="ike password", erp="1", wait_connect=False) 6480 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 6481 timeout=15) 6482 if ev is None: 6483 raise Exception("Timeout on EAP start") 6484 ok = False 6485 for j in range(10): 6486 state = dev[0].request('GET_ALLOC_FAIL') 6487 if state.startswith('0:'): 6488 ok = True 6489 break 6490 time.sleep(0.1) 6491 if not ok: 6492 raise Exception("No allocation failure seen for %d:%s" % (count, func)) 6493 dev[0].request("REMOVE_NETWORK all") 6494 dev[0].wait_disconnected() 6495 6496def run_eap_ikev2_connect(dev): 6497 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412", 6498 eap="IKEV2", identity="ikev2 user", 6499 password="ike password", 6500 fragment_size="30", wait_connect=False) 6501 ev = dev.wait_event(["CTRL-EVENT-EAP-SUCCESS", "CTRL-EVENT-EAP-FAILURE", 6502 "CTRL-EVENT-DISCONNECTED"], 6503 timeout=1) 6504 dev.request("REMOVE_NETWORK all") 6505 if not ev or "CTRL-EVENT-DISCONNECTED" not in ev: 6506 dev.wait_disconnected() 6507 ev = dev.wait_event(["CTRL-EVENT-NETWORK-REMOVED"], timeout=1) 6508 if ev is None: 6509 raise Exception("Network removal not reported") 6510 time.sleep(0.01) 6511 dev.dump_monitor() 6512 6513def test_eap_proto_ikev2_errors_server(dev, apdev): 6514 """EAP-IKEV2 local error cases on server""" 6515 check_eap_capa(dev[0], "IKEV2") 6516 params = int_eap_server_params() 6517 params['erp_domain'] = 'example.com' 6518 params['eap_server_erp'] = '1' 6519 hapd = hostapd.add_ap(apdev[0], params) 6520 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 6521 6522 tests = [(1, "eap_ikev2_init"), 6523 (2, "=eap_ikev2_init"), 6524 (3, "=eap_ikev2_init"), 6525 (1, "eap_msg_alloc;eap_ikev2_build_msg"), 6526 (1, "ikev2_initiator_build;eap_ikev2_buildReq"), 6527 (1, "eap_ikev2_process_fragment"), 6528 (1, "wpabuf_alloc_copy;ikev2_process_ker"), 6529 (1, "ikev2_process_idr"), 6530 (1, "ikev2_derive_auth_data;ikev2_process_auth_secret"), 6531 (1, "ikev2_decrypt_payload;ikev2_process_sa_auth"), 6532 (1, "ikev2_process_sa_auth_decrypted;ikev2_process_sa_auth"), 6533 (1, "dh_init;ikev2_build_kei"), 6534 (1, "ikev2_build_auth"), 6535 (1, "wpabuf_alloc;ikev2_build_sa_init"), 6536 (1, "ikev2_build_sa_auth"), 6537 (1, "=ikev2_build_sa_auth"), 6538 (2, "=ikev2_derive_auth_data"), 6539 (1, "wpabuf_alloc;ikev2_build_sa_auth"), 6540 (2, "wpabuf_alloc;=ikev2_build_sa_auth"), 6541 (1, "ikev2_decrypt_payload;ikev2_process_sa_init_encr"), 6542 (1, "dh_derive_shared;ikev2_derive_keys"), 6543 (1, "=ikev2_derive_keys"), 6544 (2, "=ikev2_derive_keys"), 6545 (1, "eap_ikev2_getKey"), 6546 (1, "eap_ikev2_get_emsk"), 6547 (1, "eap_ikev2_get_session_id")] 6548 for count, func in tests: 6549 with alloc_fail(hapd, count, func): 6550 run_eap_ikev2_connect(dev[0]) 6551 6552 tests = [(1, "eap_ikev2_validate_icv;eap_ikev2_process_icv"), 6553 (1, "eap_ikev2_server_keymat"), 6554 (1, "ikev2_build_auth"), 6555 (1, "os_get_random;ikev2_build_sa_init"), 6556 (2, "os_get_random;ikev2_build_sa_init"), 6557 (1, "ikev2_derive_keys"), 6558 (2, "ikev2_derive_keys"), 6559 (3, "ikev2_derive_keys"), 6560 (4, "ikev2_derive_keys"), 6561 (5, "ikev2_derive_keys"), 6562 (6, "ikev2_derive_keys"), 6563 (7, "ikev2_derive_keys"), 6564 (8, "ikev2_derive_keys"), 6565 (1, "ikev2_decrypt_payload;ikev2_process_sa_auth"), 6566 (1, "eap_ikev2_process_icv;eap_ikev2_process")] 6567 for count, func in tests: 6568 with fail_test(hapd, count, func): 6569 run_eap_ikev2_connect(dev[0]) 6570 6571def start_ikev2_assoc(dev, hapd): 6572 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412", 6573 eap="IKEV2", identity="ikev2 user", 6574 password="ike password", wait_connect=False) 6575 proxy_msg(hapd, dev) # EAP-Identity/Request 6576 proxy_msg(dev, hapd) # EAP-Identity/Response 6577 proxy_msg(hapd, dev) # IKEV2 1 6578 6579def stop_ikev2_assoc(dev, hapd): 6580 dev.request("REMOVE_NETWORK all") 6581 dev.wait_disconnected() 6582 dev.dump_monitor() 6583 hapd.dump_monitor() 6584 6585def test_eap_proto_ikev2_server(dev, apdev): 6586 """EAP-IKEV2 protocol testing for the server""" 6587 check_eap_capa(dev[0], "IKEV2") 6588 params = int_eap_server_params() 6589 params['erp_domain'] = 'example.com' 6590 params['eap_server_erp'] = '1' 6591 hapd = hostapd.add_ap(apdev[0], params) 6592 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 6593 hapd.request("SET ext_eapol_frame_io 1") 6594 dev[0].request("SET ext_eapol_frame_io 1") 6595 6596 # Successful exchange to verify proxying mechanism 6597 start_ikev2_assoc(dev[0], hapd) 6598 proxy_msg(dev[0], hapd) # IKEV2 2 6599 proxy_msg(hapd, dev[0]) # IKEV2 3 6600 proxy_msg(dev[0], hapd) # IKEV2 4 6601 proxy_msg(hapd, dev[0]) # EAP-Success 6602 proxy_msg(hapd, dev[0]) # EAPOL-Key msg 1/4 6603 proxy_msg(dev[0], hapd) # EAPOL-Key msg 2/4 6604 proxy_msg(hapd, dev[0]) # EAPOL-Key msg 3/4 6605 proxy_msg(dev[0], hapd) # EAPOL-Key msg 4/4 6606 dev[0].wait_connected() 6607 stop_ikev2_assoc(dev[0], hapd) 6608 6609 start_ikev2_assoc(dev[0], hapd) 6610 resp = rx_msg(dev[0]) 6611 # Too short EAP-IKEV2 header 6612 hapd.note("IKEV2: Too short frame to include HDR") 6613 msg = resp[0:4] + "0005" + resp[8:12] + "0005" + "31" 6614 tx_msg(dev[0], hapd, msg) 6615 rx_msg(hapd) 6616 stop_ikev2_assoc(dev[0], hapd) 6617 6618 start_ikev2_assoc(dev[0], hapd) 6619 resp = rx_msg(dev[0]) 6620 # Too short EAP-IKEV2 header - missing Message Length field 6621 hapd.note("EAP-IKEV2: Message underflow") 6622 msg = resp[0:4] + "0006" + resp[8:12] + "0006" + "3180" 6623 tx_msg(dev[0], hapd, msg) 6624 rx_msg(hapd) 6625 stop_ikev2_assoc(dev[0], hapd) 6626 6627 start_ikev2_assoc(dev[0], hapd) 6628 resp = rx_msg(dev[0]) 6629 # Too short EAP-IKEV2 header - too small Message Length 6630 hapd.note("EAP-IKEV2: Invalid Message Length (0; 1 remaining in this msg)") 6631 msg = resp[0:4] + "000b" + resp[8:12] + "000b" + "318000000000ff" 6632 tx_msg(dev[0], hapd, msg) 6633 rx_msg(hapd) 6634 stop_ikev2_assoc(dev[0], hapd) 6635 6636 start_ikev2_assoc(dev[0], hapd) 6637 resp = rx_msg(dev[0]) 6638 # Too short EAP-IKEV2 header - too large Message Length 6639 hapd.note("EAP-IKEV2: Ignore too long message") 6640 msg = resp[0:4] + "000b" + resp[8:12] + "000b" + "31c0bbccddeeff" 6641 tx_msg(dev[0], hapd, msg) 6642 rx_msg(hapd) 6643 stop_ikev2_assoc(dev[0], hapd) 6644 6645 start_ikev2_assoc(dev[0], hapd) 6646 resp = rx_msg(dev[0]) 6647 # No Message Length in first fragment 6648 hapd.note("EAP-IKEV2: No Message Length field in a fragmented packet") 6649 msg = resp[0:4] + "0007" + resp[8:12] + "0007" + "3140ff" 6650 tx_msg(dev[0], hapd, msg) 6651 rx_msg(hapd) 6652 stop_ikev2_assoc(dev[0], hapd) 6653 6654 start_ikev2_assoc(dev[0], hapd) 6655 resp = rx_msg(dev[0]) 6656 # First fragment (valid) 6657 hapd.note("EAP-IKEV2: Received 1 bytes in first fragment, waiting for 255 bytes more") 6658 msg = resp[0:4] + "000b" + resp[8:12] + "000b" + "31c000000100ff" 6659 tx_msg(dev[0], hapd, msg) 6660 req = rx_msg(hapd) 6661 id, = struct.unpack('B', binascii.unhexlify(req)[5:6]) 6662 hapd.note("EAP-IKEV2: Received 1 bytes in first fragment, waiting for 254 bytes more") 6663 payload = struct.pack('BBB', 49, 0x40, 0) 6664 msg = struct.pack('>BBHBBH', 1, 0, 4 + len(payload), 2, id, 4 + len(payload)) + payload 6665 tx_msg(dev[0], hapd, binascii.hexlify(msg).decode()) 6666 req = rx_msg(hapd) 6667 id, = struct.unpack('B', binascii.unhexlify(req)[5:6]) 6668 hapd.note("EAP-IKEV2: Fragment overflow") 6669 payload = struct.pack('BB', 49, 0x40) + 255*b'\x00' 6670 msg = struct.pack('>BBHBBH', 1, 0, 4 + len(payload), 2, id, 4 + len(payload)) + payload 6671 tx_msg(dev[0], hapd, binascii.hexlify(msg).decode()) 6672 rx_msg(hapd) 6673 stop_ikev2_assoc(dev[0], hapd) 6674 6675 start_ikev2_assoc(dev[0], hapd) 6676 proxy_msg(dev[0], hapd) # IKEV2 2 6677 req = proxy_msg(hapd, dev[0]) # IKEV2 3 6678 id, = struct.unpack('B', binascii.unhexlify(req)[5:6]) 6679 # Missing ICV 6680 hapd.note("EAP-IKEV2: The message should have included integrity checksum") 6681 payload = struct.pack('BB', 49, 0) + b'\x00' 6682 msg = struct.pack('>BBHBBH', 1, 0, 4 + len(payload), 2, id, 4 + len(payload)) + payload 6683 tx_msg(dev[0], hapd, binascii.hexlify(msg).decode()) 6684 rx_msg(hapd) 6685 stop_ikev2_assoc(dev[0], hapd) 6686 6687 tests = [("Unsupported HDR version 0x0 (expected 0x20)", 6688 struct.pack('BB', 49, 0) + 16*b'\x00' + 6689 struct.pack('>BBBBLL', 0, 0, 0, 0, 0, 0)), 6690 ("IKEV2: Invalid length (HDR: 0 != RX: 28)", 6691 struct.pack('BB', 49, 0) + 16*b'\x00' + 6692 struct.pack('>BBBBLL', 0, 0x20, 0, 0, 0, 0)), 6693 ("IKEV2: Unexpected Exchange Type 0 in SA_INIT state", 6694 struct.pack('BB', 49, 0) + 16*b'\x00' + 6695 struct.pack('>BBBBLL', 0, 0x20, 0, 0, 0, 28)), 6696 ("IKEV2: Unexpected Flags value 0x0", 6697 struct.pack('BB', 49, 0) + 16*b'\x00' + 6698 struct.pack('>BBBBLL', 0, 0x20, 34, 0, 0, 28)), 6699 ("IKEV2: SAr1 not received", 6700 struct.pack('BB', 49, 0) + 16*b'\x00' + 6701 struct.pack('>BBBBLL', 0, 0x20, 34, 0x20, 0, 28))] 6702 for txt, payload in tests: 6703 start_ikev2_assoc(dev[0], hapd) 6704 resp = rx_msg(dev[0]) 6705 id, = struct.unpack('B', binascii.unhexlify(resp)[5:6]) 6706 hapd.note(txt) 6707 msg = struct.pack('>BBHBBH', 1, 0, 4 + len(payload), 2, id, 4 + len(payload)) + payload 6708 tx_msg(dev[0], hapd, binascii.hexlify(msg).decode()) 6709 rx_msg(hapd) 6710 stop_ikev2_assoc(dev[0], hapd) 6711 6712def test_eap_proto_mschapv2(dev, apdev): 6713 """EAP-MSCHAPv2 protocol tests""" 6714 check_eap_capa(dev[0], "MSCHAPV2") 6715 6716 def mschapv2_handler(ctx, req): 6717 logger.info("mschapv2_handler - RX " + binascii.hexlify(req).decode()) 6718 if 'num' not in ctx: 6719 ctx['num'] = 0 6720 ctx['num'] = ctx['num'] + 1 6721 if 'id' not in ctx: 6722 ctx['id'] = 1 6723 ctx['id'] = (ctx['id'] + 1) % 256 6724 idx = 0 6725 6726 idx += 1 6727 if ctx['num'] == idx: 6728 logger.info("Test: Missing payload") 6729 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 6730 4 + 1, 6731 EAP_TYPE_MSCHAPV2) 6732 6733 idx += 1 6734 if ctx['num'] == idx: 6735 logger.info("Test: Unknown MSCHAPv2 op_code") 6736 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'], 6737 4 + 1 + 4 + 1, 6738 EAP_TYPE_MSCHAPV2, 6739 0, 0, 5, 0) 6740 6741 idx += 1 6742 if ctx['num'] == idx: 6743 logger.info("Test: Invalid ms_len and unknown MSCHAPv2 op_code") 6744 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'], 6745 4 + 1 + 4 + 1, 6746 EAP_TYPE_MSCHAPV2, 6747 255, 0, 0, 0) 6748 6749 idx += 1 6750 if ctx['num'] == idx: 6751 logger.info("Test: Success before challenge") 6752 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'], 6753 4 + 1 + 4 + 1, 6754 EAP_TYPE_MSCHAPV2, 6755 3, 0, 5, 0) 6756 6757 idx += 1 6758 if ctx['num'] == idx: 6759 logger.info("Test: Failure before challenge - required challenge field not present") 6760 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'], 6761 4 + 1 + 4 + 1, 6762 EAP_TYPE_MSCHAPV2, 6763 4, 0, 5, 0) 6764 idx += 1 6765 if ctx['num'] == idx: 6766 logger.info("Test: Failure") 6767 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 6768 6769 idx += 1 6770 if ctx['num'] == idx: 6771 logger.info("Test: Failure before challenge - invalid failure challenge len") 6772 payload = b'C=12' 6773 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'], 6774 4 + 1 + 4 + len(payload), 6775 EAP_TYPE_MSCHAPV2, 6776 4, 0, 4 + len(payload)) + payload 6777 idx += 1 6778 if ctx['num'] == idx: 6779 logger.info("Test: Failure") 6780 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 6781 6782 idx += 1 6783 if ctx['num'] == idx: 6784 logger.info("Test: Failure before challenge - invalid failure challenge len") 6785 payload = b'C=12 V=3' 6786 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'], 6787 4 + 1 + 4 + len(payload), 6788 EAP_TYPE_MSCHAPV2, 6789 4, 0, 4 + len(payload)) + payload 6790 idx += 1 6791 if ctx['num'] == idx: 6792 logger.info("Test: Failure") 6793 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 6794 6795 idx += 1 6796 if ctx['num'] == idx: 6797 logger.info("Test: Failure before challenge - invalid failure challenge") 6798 payload = b'C=00112233445566778899aabbccddeefQ ' 6799 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'], 6800 4 + 1 + 4 + len(payload), 6801 EAP_TYPE_MSCHAPV2, 6802 4, 0, 4 + len(payload)) + payload 6803 idx += 1 6804 if ctx['num'] == idx: 6805 logger.info("Test: Failure") 6806 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 6807 6808 idx += 1 6809 if ctx['num'] == idx: 6810 logger.info("Test: Failure before challenge - password expired") 6811 payload = b'E=648 R=1 C=00112233445566778899aabbccddeeff V=3 M=Password expired' 6812 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'], 6813 4 + 1 + 4 + len(payload), 6814 EAP_TYPE_MSCHAPV2, 6815 4, 0, 4 + len(payload)) + payload 6816 idx += 1 6817 if ctx['num'] == idx: 6818 logger.info("Test: Success after password change") 6819 payload = b"S=1122334455667788990011223344556677889900" 6820 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'], 6821 4 + 1 + 4 + len(payload), 6822 EAP_TYPE_MSCHAPV2, 6823 3, 0, 4 + len(payload)) + payload 6824 6825 idx += 1 6826 if ctx['num'] == idx: 6827 logger.info("Test: Invalid challenge length") 6828 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'], 6829 4 + 1 + 4 + 1, 6830 EAP_TYPE_MSCHAPV2, 6831 1, 0, 4 + 1, 0) 6832 6833 idx += 1 6834 if ctx['num'] == idx: 6835 logger.info("Test: Too short challenge packet") 6836 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'], 6837 4 + 1 + 4 + 1, 6838 EAP_TYPE_MSCHAPV2, 6839 1, 0, 4 + 1, 16) 6840 6841 idx += 1 6842 if ctx['num'] == idx: 6843 logger.info("Test: Challenge") 6844 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'], 6845 4 + 1 + 4 + 1 + 16 + 6, 6846 EAP_TYPE_MSCHAPV2, 6847 1, 0, 4 + 1 + 16 + 6, 16) + 16*b'A' + b'foobar' 6848 idx += 1 6849 if ctx['num'] == idx: 6850 logger.info("Test: Failure - password expired") 6851 payload = b'E=648 R=1 C=00112233445566778899aabbccddeeff V=3 M=Password expired' 6852 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'], 6853 4 + 1 + 4 + len(payload), 6854 EAP_TYPE_MSCHAPV2, 6855 4, 0, 4 + len(payload)) + payload 6856 idx += 1 6857 if ctx['num'] == idx: 6858 logger.info("Test: Success after password change") 6859 if len(req) != 591: 6860 logger.info("Unexpected Change-Password packet length: %s" % len(req)) 6861 return None 6862 data = req[9:] 6863 enc_pw = data[0:516] 6864 data = data[516:] 6865 enc_hash = data[0:16] 6866 data = data[16:] 6867 peer_challenge = data[0:16] 6868 data = data[16:] 6869 # Reserved 6870 data = data[8:] 6871 nt_response = data[0:24] 6872 data = data[24:] 6873 flags = data 6874 logger.info("enc_hash: " + binascii.hexlify(enc_hash).decode()) 6875 logger.info("peer_challenge: " + binascii.hexlify(peer_challenge).decode()) 6876 logger.info("nt_response: " + binascii.hexlify(nt_response).decode()) 6877 logger.info("flags: " + binascii.hexlify(flags).decode()) 6878 6879 auth_challenge = binascii.unhexlify("00112233445566778899aabbccddeeff") 6880 logger.info("auth_challenge: " + binascii.hexlify(auth_challenge).decode()) 6881 6882 auth_resp = GenerateAuthenticatorResponse("new-pw", nt_response, 6883 peer_challenge, 6884 auth_challenge, "user") 6885 payload = b"S=" + binascii.hexlify(auth_resp).decode().upper().encode() 6886 logger.info("Success message payload: " + payload.decode()) 6887 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'], 6888 4 + 1 + 4 + len(payload), 6889 EAP_TYPE_MSCHAPV2, 6890 3, 0, 4 + len(payload)) + payload 6891 idx += 1 6892 if ctx['num'] == idx: 6893 logger.info("Test: EAP-Success") 6894 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4) 6895 6896 idx += 1 6897 if ctx['num'] == idx: 6898 logger.info("Test: Failure - password expired") 6899 payload = b'E=648 R=1 C=00112233445566778899aabbccddeeff V=3 M=Password expired' 6900 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'], 6901 4 + 1 + 4 + len(payload), 6902 EAP_TYPE_MSCHAPV2, 6903 4, 0, 4 + len(payload)) + payload 6904 idx += 1 6905 if ctx['num'] == idx: 6906 logger.info("Test: Success after password change") 6907 if len(req) != 591: 6908 logger.info("Unexpected Change-Password packet length: %s" % len(req)) 6909 return None 6910 data = req[9:] 6911 enc_pw = data[0:516] 6912 data = data[516:] 6913 enc_hash = data[0:16] 6914 data = data[16:] 6915 peer_challenge = data[0:16] 6916 data = data[16:] 6917 # Reserved 6918 data = data[8:] 6919 nt_response = data[0:24] 6920 data = data[24:] 6921 flags = data 6922 logger.info("enc_hash: " + binascii.hexlify(enc_hash).decode()) 6923 logger.info("peer_challenge: " + binascii.hexlify(peer_challenge).decode()) 6924 logger.info("nt_response: " + binascii.hexlify(nt_response).decode()) 6925 logger.info("flags: " + binascii.hexlify(flags).decode()) 6926 6927 auth_challenge = binascii.unhexlify("00112233445566778899aabbccddeeff") 6928 logger.info("auth_challenge: " + binascii.hexlify(auth_challenge).decode()) 6929 6930 auth_resp = GenerateAuthenticatorResponse("new-pw", nt_response, 6931 peer_challenge, 6932 auth_challenge, "user") 6933 payload = b"S=" + binascii.hexlify(auth_resp).decode().upper().encode() 6934 logger.info("Success message payload: " + payload.decode()) 6935 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'], 6936 4 + 1 + 4 + len(payload), 6937 EAP_TYPE_MSCHAPV2, 6938 3, 0, 4 + len(payload)) + payload 6939 idx += 1 6940 if ctx['num'] == idx: 6941 logger.info("Test: EAP-Success") 6942 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4) 6943 6944 idx += 1 6945 if ctx['num'] == idx: 6946 logger.info("Test: Challenge") 6947 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'], 6948 4 + 1 + 4 + 1 + 16 + 6, 6949 EAP_TYPE_MSCHAPV2, 6950 1, 0, 4 + 1 + 16 + 6, 16) + 16*b'A' + b'foobar' 6951 idx += 1 6952 if ctx['num'] == idx: 6953 logger.info("Test: Failure - authentication failure") 6954 payload = b'E=691 R=1 C=00112233445566778899aabbccddeeff V=3 M=Authentication failed' 6955 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'], 6956 4 + 1 + 4 + len(payload), 6957 EAP_TYPE_MSCHAPV2, 6958 4, 0, 4 + len(payload)) + payload 6959 6960 idx += 1 6961 if ctx['num'] == idx: 6962 logger.info("Test: Challenge") 6963 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'], 6964 4 + 1 + 4 + 1 + 16 + 6, 6965 EAP_TYPE_MSCHAPV2, 6966 1, 0, 4 + 1 + 16 + 6, 16) + 16*b'A' + b'foobar' 6967 idx += 1 6968 if ctx['num'] == idx: 6969 logger.info("Test: Failure - authentication failure") 6970 payload = b'E=691 R=1 C=00112233445566778899aabbccddeeff V=3 M=Authentication failed (2)' 6971 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'], 6972 4 + 1 + 4 + len(payload), 6973 EAP_TYPE_MSCHAPV2, 6974 4, 0, 4 + len(payload)) + payload 6975 idx += 1 6976 if ctx['num'] == idx: 6977 logger.info("Test: Failure") 6978 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 6979 6980 idx += 1 6981 if ctx['num'] == idx: 6982 logger.info("Test: Challenge - invalid ms_len and workaround disabled") 6983 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'], 6984 4 + 1 + 4 + 1 + 16 + 6, 6985 EAP_TYPE_MSCHAPV2, 6986 1, 0, 4 + 1 + 16 + 6 + 1, 16) + 16*b'A' + b'foobar' 6987 6988 return None 6989 6990 srv = start_radius_server(mschapv2_handler) 6991 6992 try: 6993 hapd = start_ap(apdev[0]) 6994 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 6995 6996 for i in range(0, 16): 6997 logger.info("RUN: %d" % i) 6998 if i == 12: 6999 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 7000 eap="MSCHAPV2", identity="user", 7001 password_hex="hash:8846f7eaee8fb117ad06bdd830b7586c", 7002 wait_connect=False) 7003 elif i == 14: 7004 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 7005 eap="MSCHAPV2", identity="user", 7006 phase2="mschapv2_retry=0", 7007 password="password", wait_connect=False) 7008 elif i == 15: 7009 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 7010 eap="MSCHAPV2", identity="user", 7011 eap_workaround="0", 7012 password="password", wait_connect=False) 7013 else: 7014 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 7015 eap="MSCHAPV2", identity="user", 7016 password="password", wait_connect=False) 7017 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15) 7018 if ev is None: 7019 raise Exception("Timeout on EAP start") 7020 7021 if i in [8, 11, 12]: 7022 ev = dev[0].wait_event(["CTRL-REQ-NEW_PASSWORD"], 7023 timeout=10) 7024 if ev is None: 7025 raise Exception("Timeout on new password request") 7026 id = ev.split(':')[0].split('-')[-1] 7027 dev[0].request("CTRL-RSP-NEW_PASSWORD-" + id + ":new-pw") 7028 if i in [11, 12]: 7029 ev = dev[0].wait_event(["CTRL-EVENT-PASSWORD-CHANGED"], 7030 timeout=10) 7031 if ev is None: 7032 raise Exception("Timeout on password change") 7033 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], 7034 timeout=10) 7035 if ev is None: 7036 raise Exception("Timeout on EAP success") 7037 else: 7038 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], 7039 timeout=10) 7040 if ev is None: 7041 raise Exception("Timeout on EAP failure") 7042 7043 if i in [13]: 7044 ev = dev[0].wait_event(["CTRL-REQ-IDENTITY"], 7045 timeout=10) 7046 if ev is None: 7047 raise Exception("Timeout on identity request") 7048 id = ev.split(':')[0].split('-')[-1] 7049 dev[0].request("CTRL-RSP-IDENTITY-" + id + ":user") 7050 7051 ev = dev[0].wait_event(["CTRL-REQ-PASSWORD"], 7052 timeout=10) 7053 if ev is None: 7054 raise Exception("Timeout on password request") 7055 id = ev.split(':')[0].split('-')[-1] 7056 dev[0].request("CTRL-RSP-PASSWORD-" + id + ":password") 7057 7058 # TODO: Does this work correctly? 7059 7060 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], 7061 timeout=10) 7062 if ev is None: 7063 raise Exception("Timeout on EAP failure") 7064 7065 if i in [4, 5, 6, 7, 14]: 7066 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], 7067 timeout=10) 7068 if ev is None: 7069 raise Exception("Timeout on EAP failure") 7070 else: 7071 time.sleep(0.05) 7072 dev[0].request("REMOVE_NETWORK all") 7073 dev[0].wait_disconnected(timeout=1) 7074 finally: 7075 stop_radius_server(srv) 7076 7077def test_eap_proto_mschapv2_errors(dev, apdev): 7078 """EAP-MSCHAPv2 protocol tests (error paths)""" 7079 check_eap_capa(dev[0], "MSCHAPV2") 7080 7081 def mschapv2_fail_password_expired(ctx): 7082 logger.info("Test: Failure before challenge - password expired") 7083 payload = b'E=648 R=1 C=00112233445566778899aabbccddeeff V=3 M=Password expired' 7084 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'], 7085 4 + 1 + 4 + len(payload), 7086 EAP_TYPE_MSCHAPV2, 7087 4, 0, 4 + len(payload)) + payload 7088 7089 def mschapv2_success_after_password_change(ctx, req=None): 7090 logger.info("Test: Success after password change") 7091 if req is None or len(req) != 591: 7092 payload = b"S=1122334455667788990011223344556677889900" 7093 else: 7094 data = req[9:] 7095 enc_pw = data[0:516] 7096 data = data[516:] 7097 enc_hash = data[0:16] 7098 data = data[16:] 7099 peer_challenge = data[0:16] 7100 data = data[16:] 7101 # Reserved 7102 data = data[8:] 7103 nt_response = data[0:24] 7104 data = data[24:] 7105 flags = data 7106 logger.info("enc_hash: " + binascii.hexlify(enc_hash).decode()) 7107 logger.info("peer_challenge: " + binascii.hexlify(peer_challenge).decode()) 7108 logger.info("nt_response: " + binascii.hexlify(nt_response).decode()) 7109 logger.info("flags: " + binascii.hexlify(flags).decode()) 7110 7111 auth_challenge = binascii.unhexlify("00112233445566778899aabbccddeeff") 7112 logger.info("auth_challenge: " + binascii.hexlify(auth_challenge).decode()) 7113 7114 auth_resp = GenerateAuthenticatorResponse("new-pw", nt_response, 7115 peer_challenge, 7116 auth_challenge, "user") 7117 payload = b"S=" + binascii.hexlify(auth_resp).decode().upper().encode() 7118 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'], 7119 4 + 1 + 4 + len(payload), 7120 EAP_TYPE_MSCHAPV2, 7121 3, 0, 4 + len(payload)) + payload 7122 7123 def mschapv2_handler(ctx, req): 7124 logger.info("mschapv2_handler - RX " + binascii.hexlify(req).decode()) 7125 if 'num' not in ctx: 7126 ctx['num'] = 0 7127 ctx['num'] = ctx['num'] + 1 7128 if 'id' not in ctx: 7129 ctx['id'] = 1 7130 ctx['id'] = (ctx['id'] + 1) % 256 7131 idx = 0 7132 7133 idx += 1 7134 if ctx['num'] == idx: 7135 return mschapv2_fail_password_expired(ctx) 7136 idx += 1 7137 if ctx['num'] == idx: 7138 return mschapv2_success_after_password_change(ctx, req) 7139 idx += 1 7140 if ctx['num'] == idx: 7141 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 7142 7143 idx += 1 7144 if ctx['num'] == idx: 7145 return mschapv2_fail_password_expired(ctx) 7146 idx += 1 7147 if ctx['num'] == idx: 7148 return mschapv2_success_after_password_change(ctx, req) 7149 idx += 1 7150 if ctx['num'] == idx: 7151 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 7152 7153 idx += 1 7154 if ctx['num'] == idx: 7155 return mschapv2_fail_password_expired(ctx) 7156 idx += 1 7157 if ctx['num'] == idx: 7158 return mschapv2_success_after_password_change(ctx, req) 7159 idx += 1 7160 if ctx['num'] == idx: 7161 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 7162 7163 idx += 1 7164 if ctx['num'] == idx: 7165 return mschapv2_fail_password_expired(ctx) 7166 idx += 1 7167 if ctx['num'] == idx: 7168 return mschapv2_success_after_password_change(ctx, req) 7169 idx += 1 7170 if ctx['num'] == idx: 7171 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 7172 7173 idx += 1 7174 if ctx['num'] == idx: 7175 return mschapv2_fail_password_expired(ctx) 7176 idx += 1 7177 if ctx['num'] == idx: 7178 return mschapv2_success_after_password_change(ctx, req) 7179 idx += 1 7180 if ctx['num'] == idx: 7181 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 7182 7183 idx += 1 7184 if ctx['num'] == idx: 7185 return mschapv2_fail_password_expired(ctx) 7186 idx += 1 7187 if ctx['num'] == idx: 7188 return mschapv2_success_after_password_change(ctx, req) 7189 idx += 1 7190 if ctx['num'] == idx: 7191 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 7192 7193 idx += 1 7194 if ctx['num'] == idx: 7195 return mschapv2_fail_password_expired(ctx) 7196 idx += 1 7197 if ctx['num'] == idx: 7198 return mschapv2_success_after_password_change(ctx, req) 7199 idx += 1 7200 if ctx['num'] == idx: 7201 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 7202 7203 idx += 1 7204 if ctx['num'] == idx: 7205 return mschapv2_fail_password_expired(ctx) 7206 idx += 1 7207 if ctx['num'] == idx: 7208 return mschapv2_success_after_password_change(ctx, req) 7209 idx += 1 7210 if ctx['num'] == idx: 7211 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 7212 7213 idx += 1 7214 if ctx['num'] == idx: 7215 return mschapv2_fail_password_expired(ctx) 7216 idx += 1 7217 if ctx['num'] == idx: 7218 return mschapv2_success_after_password_change(ctx, req) 7219 idx += 1 7220 if ctx['num'] == idx: 7221 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 7222 7223 return None 7224 7225 srv = start_radius_server(mschapv2_handler) 7226 7227 try: 7228 hapd = start_ap(apdev[0]) 7229 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 7230 7231 tests = ["os_get_random;eap_mschapv2_change_password", 7232 "generate_nt_response;eap_mschapv2_change_password", 7233 "get_master_key;eap_mschapv2_change_password", 7234 "nt_password_hash;eap_mschapv2_change_password", 7235 "old_nt_password_hash_encrypted_with_new_nt_password_hash"] 7236 for func in tests: 7237 with fail_test(dev[0], 1, func): 7238 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 7239 eap="MSCHAPV2", identity="user", 7240 password="password", wait_connect=False) 7241 ev = dev[0].wait_event(["CTRL-REQ-NEW_PASSWORD"], timeout=10) 7242 if ev is None: 7243 raise Exception("Timeout on new password request") 7244 id = ev.split(':')[0].split('-')[-1] 7245 dev[0].request("CTRL-RSP-NEW_PASSWORD-" + id + ":new-pw") 7246 time.sleep(0.1) 7247 wait_fail_trigger(dev[0], "GET_FAIL") 7248 dev[0].request("REMOVE_NETWORK all") 7249 dev[0].wait_disconnected(timeout=1) 7250 7251 tests = ["encrypt_pw_block_with_password_hash;eap_mschapv2_change_password", 7252 "nt_password_hash;eap_mschapv2_change_password", 7253 "nt_password_hash;eap_mschapv2_success"] 7254 for func in tests: 7255 with fail_test(dev[0], 1, func): 7256 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 7257 eap="MSCHAPV2", identity="user", 7258 password_hex="hash:8846f7eaee8fb117ad06bdd830b7586c", 7259 wait_connect=False) 7260 ev = dev[0].wait_event(["CTRL-REQ-NEW_PASSWORD"], timeout=10) 7261 if ev is None: 7262 raise Exception("Timeout on new password request") 7263 id = ev.split(':')[0].split('-')[-1] 7264 dev[0].request("CTRL-RSP-NEW_PASSWORD-" + id + ":new-pw") 7265 time.sleep(0.1) 7266 wait_fail_trigger(dev[0], "GET_FAIL") 7267 dev[0].request("REMOVE_NETWORK all") 7268 dev[0].wait_disconnected(timeout=1) 7269 7270 tests = ["eap_msg_alloc;eap_mschapv2_change_password"] 7271 for func in tests: 7272 with alloc_fail(dev[0], 1, func): 7273 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 7274 eap="MSCHAPV2", identity="user", 7275 password="password", wait_connect=False) 7276 ev = dev[0].wait_event(["CTRL-REQ-NEW_PASSWORD"], timeout=10) 7277 if ev is None: 7278 raise Exception("Timeout on new password request") 7279 id = ev.split(':')[0].split('-')[-1] 7280 dev[0].request("CTRL-RSP-NEW_PASSWORD-" + id + ":new-pw") 7281 time.sleep(0.1) 7282 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 7283 dev[0].request("REMOVE_NETWORK all") 7284 dev[0].wait_disconnected(timeout=1) 7285 finally: 7286 stop_radius_server(srv) 7287 7288def test_eap_proto_pwd(dev, apdev): 7289 """EAP-pwd protocol tests""" 7290 check_eap_capa(dev[0], "PWD") 7291 7292 global eap_proto_pwd_test_done, eap_proto_pwd_test_wait 7293 eap_proto_pwd_test_done = False 7294 eap_proto_pwd_test_wait = False 7295 7296 def pwd_handler(ctx, req): 7297 logger.info("pwd_handler - RX " + binascii.hexlify(req).decode()) 7298 if 'num' not in ctx: 7299 ctx['num'] = 0 7300 ctx['num'] = ctx['num'] + 1 7301 if 'id' not in ctx: 7302 ctx['id'] = 1 7303 ctx['id'] = (ctx['id'] + 1) % 256 7304 idx = 0 7305 7306 global eap_proto_pwd_test_wait 7307 eap_proto_pwd_test_wait = False 7308 7309 idx += 1 7310 if ctx['num'] == idx: 7311 logger.info("Test: Missing payload") 7312 # EAP-pwd: Got a frame but pos is not NULL and len is 0 7313 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 4 + 1, 7314 EAP_TYPE_PWD) 7315 7316 idx += 1 7317 if ctx['num'] == idx: 7318 logger.info("Test: Missing Total-Length field") 7319 # EAP-pwd: Frame too short to contain Total-Length field 7320 payload = struct.pack("B", 0x80) 7321 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7322 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7323 7324 idx += 1 7325 if ctx['num'] == idx: 7326 logger.info("Test: Too large Total-Length") 7327 # EAP-pwd: Incoming fragments whose total length = 65535 7328 payload = struct.pack(">BH", 0x80, 65535) 7329 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7330 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7331 7332 idx += 1 7333 if ctx['num'] == idx: 7334 eap_proto_pwd_test_wait = True 7335 logger.info("Test: First fragment") 7336 # EAP-pwd: Incoming fragments whose total length = 10 7337 # EAP-pwd: ACKing a 0 byte fragment 7338 payload = struct.pack(">BH", 0xc0, 10) 7339 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7340 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7341 idx += 1 7342 if ctx['num'] == idx: 7343 logger.info("Test: Unexpected Total-Length value in the second fragment") 7344 # EAP-pwd: Incoming fragments whose total length = 0 7345 # EAP-pwd: Unexpected new fragment start when previous fragment is still in use 7346 payload = struct.pack(">BH", 0x80, 0) 7347 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7348 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7349 7350 idx += 1 7351 if ctx['num'] == idx: 7352 logger.info("Test: First and only fragment") 7353 # EAP-pwd: Incoming fragments whose total length = 0 7354 # EAP-pwd: processing frame: exch 0, len 0 7355 # EAP-pwd: Ignoring message with unknown opcode 128 7356 payload = struct.pack(">BH", 0x80, 0) 7357 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7358 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7359 7360 idx += 1 7361 if ctx['num'] == idx: 7362 logger.info("Test: First and only fragment with extra data") 7363 # EAP-pwd: Incoming fragments whose total length = 0 7364 # EAP-pwd: processing frame: exch 0, len 1 7365 # EAP-pwd: Ignoring message with unknown opcode 128 7366 payload = struct.pack(">BHB", 0x80, 0, 0) 7367 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7368 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7369 7370 idx += 1 7371 if ctx['num'] == idx: 7372 eap_proto_pwd_test_wait = True 7373 logger.info("Test: First fragment") 7374 # EAP-pwd: Incoming fragments whose total length = 2 7375 # EAP-pwd: ACKing a 1 byte fragment 7376 payload = struct.pack(">BHB", 0xc0, 2, 1) 7377 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7378 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7379 idx += 1 7380 if ctx['num'] == idx: 7381 logger.info("Test: Extra data in the second fragment") 7382 # EAP-pwd: Buffer overflow attack detected (3 vs. 1)! 7383 payload = struct.pack(">BBB", 0x0, 2, 3) 7384 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7385 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7386 7387 idx += 1 7388 if ctx['num'] == idx: 7389 logger.info("Test: Too short id exchange") 7390 # EAP-pwd: processing frame: exch 1, len 0 7391 # EAP-PWD: PWD-ID-Req -> FAILURE 7392 payload = struct.pack(">B", 0x01) 7393 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7394 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7395 7396 idx += 1 7397 if ctx['num'] == idx: 7398 logger.info("Test: Unsupported rand func in id exchange") 7399 # EAP-PWD: Server EAP-pwd-ID proposal: group=0 random=0 prf=0 prep=0 7400 # EAP-PWD: PWD-ID-Req -> FAILURE 7401 payload = struct.pack(">BHBBLB", 0x01, 0, 0, 0, 0, 0) 7402 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7403 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7404 7405 idx += 1 7406 if ctx['num'] == idx: 7407 logger.info("Test: Unsupported prf in id exchange") 7408 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=0 prep=0 7409 # EAP-PWD: PWD-ID-Req -> FAILURE 7410 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 0, 0, 0) 7411 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7412 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7413 7414 idx += 1 7415 if ctx['num'] == idx: 7416 logger.info("Test: Unsupported password pre-processing technique in id exchange") 7417 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=255 7418 # EAP-PWD: Unsupported password pre-processing technique (Prep=255) 7419 # EAP-PWD: PWD-ID-Req -> FAILURE 7420 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 255) 7421 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7422 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7423 7424 idx += 1 7425 if ctx['num'] == idx: 7426 eap_proto_pwd_test_wait = True 7427 logger.info("Test: Valid id exchange") 7428 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=0 7429 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0) 7430 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7431 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7432 idx += 1 7433 if ctx['num'] == idx: 7434 logger.info("Test: Unexpected id exchange") 7435 # EAP-pwd: processing frame: exch 1, len 9 7436 # EAP-PWD: PWD-Commit-Req -> FAILURE 7437 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0) 7438 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7439 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7440 7441 idx += 1 7442 if ctx['num'] == idx: 7443 logger.info("Test: Unexpected commit exchange") 7444 # EAP-pwd: processing frame: exch 2, len 0 7445 # EAP-PWD: PWD-ID-Req -> FAILURE 7446 payload = struct.pack(">B", 0x02) 7447 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7448 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7449 7450 idx += 1 7451 if ctx['num'] == idx: 7452 eap_proto_pwd_test_wait = True 7453 logger.info("Test: Valid id exchange") 7454 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=0 7455 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0) 7456 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7457 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7458 idx += 1 7459 if ctx['num'] == idx: 7460 logger.info("Test: Unexpected Commit payload length (prep=None)") 7461 # EAP-pwd commit request, password prep is NONE 7462 # EAP-pwd: Unexpected Commit payload length 0 (expected 96) 7463 payload = struct.pack(">B", 0x02) 7464 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7465 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7466 7467 idx += 1 7468 if ctx['num'] == idx: 7469 eap_proto_pwd_test_wait = True 7470 logger.info("Test: Valid id exchange") 7471 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=0 7472 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0) 7473 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7474 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7475 idx += 1 7476 if ctx['num'] == idx: 7477 logger.info("Test: Commit payload with all zeros values --> Shared key at infinity") 7478 # EAP-pwd: Invalid coordinate in element 7479 payload = struct.pack(">B", 0x02) + 96*b'\0' 7480 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7481 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7482 7483 idx += 1 7484 if ctx['num'] == idx: 7485 eap_proto_pwd_test_wait = True 7486 logger.info("Test: Valid id exchange") 7487 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=0 7488 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0) 7489 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7490 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7491 idx += 1 7492 if ctx['num'] == idx: 7493 eap_proto_pwd_test_wait = True 7494 logger.info("Test: Commit payload with valid values") 7495 # EAP-pwd commit request, password prep is NONE 7496 element = binascii.unhexlify("8dcab2862c5396839a6bac0c689ff03d962863108e7c275bbf1d6eedf634ee832a214db99f0d0a1a6317733eecdd97f0fc4cda19f57e1bb9bb9c8dcf8c60ba6f") 7497 scalar = binascii.unhexlify("450f31e058cf2ac2636a5d6e2b3c70b1fcc301957f0716e77f13aa69f9a2e5bd") 7498 payload = struct.pack(">B", 0x02) + element + scalar 7499 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7500 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7501 idx += 1 7502 if ctx['num'] == idx: 7503 logger.info("Test: Unexpected Confirm payload length 0") 7504 # EAP-pwd: Unexpected Confirm payload length 0 (expected 32) 7505 payload = struct.pack(">B", 0x03) 7506 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7507 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7508 7509 idx += 1 7510 if ctx['num'] == idx: 7511 eap_proto_pwd_test_wait = True 7512 logger.info("Test: Valid id exchange") 7513 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=0 7514 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0) 7515 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7516 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7517 idx += 1 7518 if ctx['num'] == idx: 7519 eap_proto_pwd_test_wait = True 7520 logger.info("Test: Commit payload with valid values") 7521 # EAP-pwd commit request, password prep is NONE 7522 element = binascii.unhexlify("8dcab2862c5396839a6bac0c689ff03d962863108e7c275bbf1d6eedf634ee832a214db99f0d0a1a6317733eecdd97f0fc4cda19f57e1bb9bb9c8dcf8c60ba6f") 7523 scalar = binascii.unhexlify("450f31e058cf2ac2636a5d6e2b3c70b1fcc301957f0716e77f13aa69f9a2e5bd") 7524 payload = struct.pack(">B", 0x02) + element + scalar 7525 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7526 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7527 idx += 1 7528 if ctx['num'] == idx: 7529 logger.info("Test: Confirm payload with incorrect value") 7530 # EAP-PWD (peer): confirm did not verify 7531 payload = struct.pack(">B", 0x03) + 32*b'\0' 7532 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7533 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7534 7535 idx += 1 7536 if ctx['num'] == idx: 7537 logger.info("Test: Unexpected confirm exchange") 7538 # EAP-pwd: processing frame: exch 3, len 0 7539 # EAP-PWD: PWD-ID-Req -> FAILURE 7540 payload = struct.pack(">B", 0x03) 7541 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7542 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7543 7544 idx += 1 7545 if ctx['num'] == idx: 7546 logger.info("Test: Unsupported password pre-processing technique SASLprep in id exchange") 7547 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=2 7548 # EAP-PWD: Unsupported password pre-processing technique (Prep=2) 7549 # EAP-PWD: PWD-ID-Req -> FAILURE 7550 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 2) 7551 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7552 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7553 7554 idx += 1 7555 if ctx['num'] == idx: 7556 eap_proto_pwd_test_wait = True 7557 logger.info("Test: Valid id exchange") 7558 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=1 7559 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 1) 7560 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7561 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7562 idx += 1 7563 if ctx['num'] == idx: 7564 logger.info("Test: Unexpected Commit payload length (prep=MS)") 7565 # EAP-pwd commit request, password prep is MS 7566 # EAP-pwd: Unexpected Commit payload length 0 (expected 96) 7567 payload = struct.pack(">B", 0x02) 7568 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7569 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7570 7571 idx += 1 7572 if ctx['num'] == idx: 7573 eap_proto_pwd_test_wait = True 7574 logger.info("Test: Valid id exchange") 7575 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=3 7576 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 3) 7577 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7578 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7579 idx += 1 7580 if ctx['num'] == idx: 7581 logger.info("Test: Unexpected Commit payload length (prep=ssha1)") 7582 # EAP-pwd commit request, password prep is salted sha1 7583 # EAP-pwd: Invalid Salt-len 7584 payload = struct.pack(">B", 0x02) 7585 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7586 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7587 7588 idx += 1 7589 if ctx['num'] == idx: 7590 eap_proto_pwd_test_wait = True 7591 logger.info("Test: Valid id exchange") 7592 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=3 7593 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 3) 7594 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7595 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7596 idx += 1 7597 if ctx['num'] == idx: 7598 logger.info("Test: Unexpected Commit payload length (prep=ssha1)") 7599 # EAP-pwd commit request, password prep is salted sha1 7600 # EAP-pwd: Invalid Salt-len 7601 payload = struct.pack(">BB", 0x02, 0) 7602 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7603 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7604 7605 idx += 1 7606 if ctx['num'] == idx: 7607 eap_proto_pwd_test_wait = True 7608 logger.info("Test: Valid id exchange") 7609 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=3 7610 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 3) 7611 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7612 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7613 idx += 1 7614 if ctx['num'] == idx: 7615 logger.info("Test: Unexpected Commit payload length (prep=ssha1)") 7616 # EAP-pwd commit request, password prep is salted sha1 7617 # EAP-pwd: Unexpected Commit payload length 1 (expected 98) 7618 payload = struct.pack(">BB", 0x02, 1) 7619 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7620 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7621 7622 idx += 1 7623 if ctx['num'] == idx: 7624 eap_proto_pwd_test_wait = True 7625 logger.info("Test: Valid id exchange") 7626 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=4 7627 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 4) 7628 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7629 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7630 idx += 1 7631 if ctx['num'] == idx: 7632 logger.info("Test: Unexpected Commit payload length (prep=ssha256)") 7633 # EAP-pwd commit request, password prep is salted sha256 7634 # EAP-pwd: Invalid Salt-len 7635 payload = struct.pack(">B", 0x02) 7636 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7637 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7638 7639 idx += 1 7640 if ctx['num'] == idx: 7641 eap_proto_pwd_test_wait = True 7642 logger.info("Test: Valid id exchange") 7643 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=4 7644 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 4) 7645 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7646 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7647 idx += 1 7648 if ctx['num'] == idx: 7649 logger.info("Test: Unexpected Commit payload length (prep=ssha256)") 7650 # EAP-pwd commit request, password prep is salted sha256 7651 # EAP-pwd: Invalid Salt-len 7652 payload = struct.pack(">BB", 0x02, 0) 7653 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7654 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7655 7656 idx += 1 7657 if ctx['num'] == idx: 7658 eap_proto_pwd_test_wait = True 7659 logger.info("Test: Valid id exchange") 7660 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=4 7661 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 4) 7662 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7663 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7664 idx += 1 7665 if ctx['num'] == idx: 7666 logger.info("Test: Unexpected Commit payload length (prep=ssha256)") 7667 # EAP-pwd commit request, password prep is salted sha256 7668 # EAP-pwd: Unexpected Commit payload length 1 (expected 98) 7669 payload = struct.pack(">BB", 0x02, 1) 7670 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7671 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7672 7673 idx += 1 7674 if ctx['num'] == idx: 7675 eap_proto_pwd_test_wait = True 7676 logger.info("Test: Valid id exchange") 7677 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=5 7678 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 5) 7679 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7680 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7681 idx += 1 7682 if ctx['num'] == idx: 7683 logger.info("Test: Unexpected Commit payload length (prep=ssha512)") 7684 # EAP-pwd commit request, password prep is salted sha512 7685 # EAP-pwd: Invalid Salt-len 7686 payload = struct.pack(">B", 0x02) 7687 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7688 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7689 7690 idx += 1 7691 if ctx['num'] == idx: 7692 eap_proto_pwd_test_wait = True 7693 logger.info("Test: Valid id exchange") 7694 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=5 7695 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 5) 7696 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7697 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7698 idx += 1 7699 if ctx['num'] == idx: 7700 logger.info("Test: Unexpected Commit payload length (prep=ssha512)") 7701 # EAP-pwd commit request, password prep is salted sha512 7702 # EAP-pwd: Invalid Salt-len 7703 payload = struct.pack(">BB", 0x02, 0) 7704 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7705 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7706 7707 idx += 1 7708 if ctx['num'] == idx: 7709 eap_proto_pwd_test_wait = True 7710 logger.info("Test: Valid id exchange") 7711 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=5 7712 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 5) 7713 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7714 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7715 idx += 1 7716 if ctx['num'] == idx: 7717 logger.info("Test: Unexpected Commit payload length (prep=ssha512)") 7718 # EAP-pwd commit request, password prep is salted sha512 7719 # EAP-pwd: Unexpected Commit payload length 1 (expected 98) 7720 payload = struct.pack(">BB", 0x02, 1) 7721 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7722 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7723 7724 logger.info("No more test responses available - test case completed") 7725 global eap_proto_pwd_test_done 7726 eap_proto_pwd_test_done = True 7727 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 7728 7729 srv = start_radius_server(pwd_handler) 7730 7731 try: 7732 hapd = start_ap(apdev[0]) 7733 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 7734 7735 i = 0 7736 while not eap_proto_pwd_test_done: 7737 i += 1 7738 logger.info("Running connection iteration %d" % i) 7739 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 7740 eap="PWD", identity="pwd user", 7741 password="secret password", 7742 wait_connect=False) 7743 ok = False 7744 for j in range(5): 7745 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STATUS", 7746 "CTRL-EVENT-EAP-PROPOSED-METHOD"], 7747 timeout=5) 7748 if ev is None: 7749 raise Exception("Timeout on EAP start") 7750 if "CTRL-EVENT-EAP-PROPOSED-METHOD" in ev: 7751 ok = True 7752 break 7753 if "CTRL-EVENT-EAP-STATUS" in ev and "status='completion' parameter='failure'" in ev: 7754 ok = True 7755 break 7756 if not ok: 7757 raise Exception("Expected EAP event not seen") 7758 if eap_proto_pwd_test_wait: 7759 for k in range(20): 7760 time.sleep(0.1) 7761 if not eap_proto_pwd_test_wait: 7762 break 7763 if eap_proto_pwd_test_wait: 7764 raise Exception("eap_proto_pwd_test_wait not cleared") 7765 dev[0].request("REMOVE_NETWORK all") 7766 dev[0].wait_disconnected(timeout=1) 7767 dev[0].dump_monitor() 7768 finally: 7769 stop_radius_server(srv) 7770 7771def test_eap_proto_pwd_invalid_scalar(dev, apdev): 7772 """EAP-pwd protocol tests - invalid server scalar""" 7773 check_eap_capa(dev[0], "PWD") 7774 run_eap_proto_pwd_invalid_scalar(dev, apdev, 32*b'\0') 7775 run_eap_proto_pwd_invalid_scalar(dev, apdev, 31*b'\0' + b'\x01') 7776 # Group Order 7777 val = binascii.unhexlify("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551") 7778 run_eap_proto_pwd_invalid_scalar(dev, apdev, val) 7779 # Group Order - 1 7780 val = binascii.unhexlify("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632550") 7781 run_eap_proto_pwd_invalid_scalar(dev, apdev, val, valid_scalar=True) 7782 7783def run_eap_proto_pwd_invalid_scalar(dev, apdev, scalar, valid_scalar=False): 7784 global eap_proto_pwd_invalid_scalar_fail 7785 eap_proto_pwd_invalid_scalar_fail = False 7786 7787 def pwd_handler(ctx, req): 7788 logger.info("pwd_handler - RX " + binascii.hexlify(req).decode()) 7789 if 'num' not in ctx: 7790 ctx['num'] = 0 7791 ctx['num'] = ctx['num'] + 1 7792 if 'id' not in ctx: 7793 ctx['id'] = 1 7794 ctx['id'] = (ctx['id'] + 1) % 256 7795 idx = 0 7796 7797 idx += 1 7798 if ctx['num'] == idx: 7799 logger.info("Test: Valid id exchange") 7800 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0) 7801 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7802 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7803 idx += 1 7804 if ctx['num'] == idx: 7805 logger.info("Test: Commit payload with invalid scalar") 7806 payload = struct.pack(">B", 0x02) + binascii.unhexlify("67feb2b46d59e6dd3af3a429ec9c04a949337564615d3a2c19bdf6826eb6f5efa303aed86af3a072ed819d518d620adb2659f0e84c4f8b739629db8c93088cfc") + scalar 7807 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7808 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7809 idx += 1 7810 if ctx['num'] == idx: 7811 logger.info("Confirm message next - should not get here") 7812 global eap_proto_pwd_invalid_scalar_fail 7813 eap_proto_pwd_invalid_scalar_fail = True 7814 payload = struct.pack(">B", 0x03) + 32*b'\0' 7815 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7816 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7817 7818 logger.info("No more test responses available - test case completed") 7819 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 7820 7821 srv = start_radius_server(pwd_handler) 7822 7823 try: 7824 hapd = start_ap(apdev[0]) 7825 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 7826 7827 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 7828 eap="PWD", identity="pwd user", 7829 password="secret password", 7830 wait_connect=False) 7831 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5) 7832 if ev is None: 7833 raise Exception("EAP failure not reported") 7834 dev[0].request("REMOVE_NETWORK all") 7835 dev[0].wait_disconnected(timeout=1) 7836 dev[0].dump_monitor() 7837 finally: 7838 stop_radius_server(srv) 7839 7840 if valid_scalar and not eap_proto_pwd_invalid_scalar_fail: 7841 raise Exception("Peer did not accept valid EAP-pwd-Commit scalar") 7842 if not valid_scalar and eap_proto_pwd_invalid_scalar_fail: 7843 raise Exception("Peer did not stop after invalid EAP-pwd-Commit scalar") 7844 7845def test_eap_proto_pwd_invalid_element(dev, apdev): 7846 """EAP-pwd protocol tests - invalid server element""" 7847 check_eap_capa(dev[0], "PWD") 7848 # Invalid x,y coordinates 7849 run_eap_proto_pwd_invalid_element(dev, apdev, 64*b'\x00') 7850 run_eap_proto_pwd_invalid_element(dev, apdev, 32*b'\x00' + 32*b'\x01') 7851 run_eap_proto_pwd_invalid_element(dev, apdev, 32*b'\x01' + 32*b'\x00') 7852 run_eap_proto_pwd_invalid_element(dev, apdev, 32*b'\xff' + 32*b'\x01') 7853 run_eap_proto_pwd_invalid_element(dev, apdev, 32*b'\x01' + 32*b'\xff') 7854 run_eap_proto_pwd_invalid_element(dev, apdev, 64*b'\xff') 7855 # Not on curve 7856 run_eap_proto_pwd_invalid_element(dev, apdev, 64*b'\x01') 7857 7858def run_eap_proto_pwd_invalid_element(dev, apdev, element): 7859 global eap_proto_pwd_invalid_element_fail 7860 eap_proto_pwd_invalid_element_fail = False 7861 7862 def pwd_handler(ctx, req): 7863 logger.info("pwd_handler - RX " + binascii.hexlify(req).decode()) 7864 if 'num' not in ctx: 7865 ctx['num'] = 0 7866 ctx['num'] = ctx['num'] + 1 7867 if 'id' not in ctx: 7868 ctx['id'] = 1 7869 ctx['id'] = (ctx['id'] + 1) % 256 7870 idx = 0 7871 7872 idx += 1 7873 if ctx['num'] == idx: 7874 logger.info("Test: Valid id exchange") 7875 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0) 7876 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7877 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7878 idx += 1 7879 if ctx['num'] == idx: 7880 logger.info("Test: Commit payload with invalid element") 7881 payload = struct.pack(">B", 0x02) + element + 31*b'\0' + b'\x02' 7882 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7883 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7884 idx += 1 7885 if ctx['num'] == idx: 7886 logger.info("Confirm message next - should not get here") 7887 global eap_proto_pwd_invalid_element_fail 7888 eap_proto_pwd_invalid_element_fail = True 7889 payload = struct.pack(">B", 0x03) + 32*b'\0' 7890 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7891 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7892 7893 logger.info("No more test responses available - test case completed") 7894 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 7895 7896 srv = start_radius_server(pwd_handler) 7897 7898 try: 7899 hapd = start_ap(apdev[0]) 7900 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 7901 7902 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 7903 eap="PWD", identity="pwd user", 7904 password="secret password", 7905 wait_connect=False) 7906 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5) 7907 if ev is None: 7908 raise Exception("EAP failure not reported") 7909 dev[0].request("REMOVE_NETWORK all") 7910 dev[0].wait_disconnected(timeout=1) 7911 dev[0].dump_monitor() 7912 finally: 7913 stop_radius_server(srv) 7914 7915 if eap_proto_pwd_invalid_element_fail: 7916 raise Exception("Peer did not stop after invalid EAP-pwd-Commit element") 7917 7918def rx_msg(src): 7919 ev = src.wait_event(["EAPOL-TX"], timeout=5) 7920 if ev is None: 7921 raise Exception("No EAPOL-TX") 7922 return ev.split(' ')[2] 7923 7924def tx_msg(src, dst, msg): 7925 dst.request("EAPOL_RX " + src.own_addr() + " " + msg) 7926 7927def proxy_msg(src, dst): 7928 msg = rx_msg(src) 7929 tx_msg(src, dst, msg) 7930 return msg 7931 7932def start_pwd_exchange(dev, ap): 7933 check_eap_capa(dev, "PWD") 7934 params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap") 7935 hapd = hostapd.add_ap(ap, params) 7936 hapd.request("SET ext_eapol_frame_io 1") 7937 dev.request("SET ext_eapol_frame_io 1") 7938 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", 7939 eap="PWD", identity="pwd user", password="secret password", 7940 wait_connect=False, scan_freq="2412") 7941 proxy_msg(hapd, dev) # EAP-Identity/Request 7942 proxy_msg(dev, hapd) # EAP-Identity/Response 7943 proxy_msg(hapd, dev) # EAP-pwd-ID/Request 7944 proxy_msg(dev, hapd) # EAP-pwd-ID/Response 7945 return hapd 7946 7947def test_eap_proto_pwd_unexpected_fragment(dev, apdev): 7948 """EAP-pwd protocol tests - unexpected more-fragment frame""" 7949 hapd = start_pwd_exchange(dev[0], apdev[0]) 7950 7951 # EAP-pwd-Commit/Request 7952 req = rx_msg(hapd) 7953 if req[18:20] != "02": 7954 raise Exception("Unexpected EAP-pwd-Commit/Request flag") 7955 msg = req[0:18] + "42" + req[20:] 7956 tx_msg(hapd, dev[0], msg) 7957 7958def test_eap_proto_pwd_reflection_attack(dev, apdev): 7959 """EAP-pwd protocol tests - reflection attack on the server""" 7960 hapd = start_pwd_exchange(dev[0], apdev[0]) 7961 7962 # EAP-pwd-Commit/Request 7963 req = proxy_msg(hapd, dev[0]) 7964 if len(req) != 212: 7965 raise Exception("Unexpected EAP-pwd-Commit/Response length") 7966 7967 # EAP-pwd-Commit/Response 7968 resp = rx_msg(dev[0]) 7969 # Reflect same Element/Scalar back to the server 7970 msg = resp[0:20] + req[20:] 7971 tx_msg(dev[0], hapd, msg) 7972 7973 # EAP-pwd-Commit/Response or EAP-Failure 7974 req = rx_msg(hapd) 7975 if req[8:10] != "04": 7976 # reflect EAP-pwd-Confirm/Request 7977 msg = req[0:8] + "02" + req[10:] 7978 tx_msg(dev[0], hapd, msg) 7979 req = rx_msg(hapd) 7980 if req[8:10] == "03": 7981 raise Exception("EAP-Success after reflected Element/Scalar") 7982 raise Exception("No EAP-Failure to reject invalid EAP-pwd-Commit/Response") 7983 7984def test_eap_proto_pwd_invalid_scalar_peer(dev, apdev): 7985 """EAP-pwd protocol tests - invalid peer scalar""" 7986 run_eap_proto_pwd_invalid_scalar_peer(dev, apdev, 32*"00") 7987 run_eap_proto_pwd_invalid_scalar_peer(dev, apdev, 31*"00" + "01") 7988 # Group Order 7989 run_eap_proto_pwd_invalid_scalar_peer(dev, apdev, 7990 "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551") 7991 # Group Order - 1 7992 run_eap_proto_pwd_invalid_scalar_peer(dev, apdev, 7993 "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632550", 7994 valid_scalar=True) 7995 7996def run_eap_proto_pwd_invalid_scalar_peer(dev, apdev, scalar, 7997 valid_scalar=False): 7998 hapd = start_pwd_exchange(dev[0], apdev[0]) 7999 proxy_msg(hapd, dev[0]) # EAP-pwd-Commit/Request 8000 8001 # EAP-pwd-Commit/Response 8002 resp = rx_msg(dev[0]) 8003 # Replace scalar with an invalid value 8004 msg = resp[0:20] + resp[20:148] + scalar 8005 tx_msg(dev[0], hapd, msg) 8006 8007 # EAP-pwd-Commit/Response or EAP-Failure 8008 req = rx_msg(hapd) 8009 if valid_scalar and req[8:10] == "04": 8010 raise Exception("Unexpected EAP-Failure with valid scalar") 8011 if not valid_scalar and req[8:10] != "04": 8012 raise Exception("No EAP-Failure to reject invalid scalar") 8013 dev[0].request("REMOVE_NETWORK all") 8014 dev[0].wait_disconnected(timeout=1) 8015 hapd.disable() 8016 8017def test_eap_proto_pwd_invalid_element_peer(dev, apdev): 8018 """EAP-pwd protocol tests - invalid peer element""" 8019 # Invalid x,y coordinates 8020 run_eap_proto_pwd_invalid_element_peer(dev, apdev, 64*'00') 8021 run_eap_proto_pwd_invalid_element_peer(dev, apdev, 32*'00' + 32*'01') 8022 run_eap_proto_pwd_invalid_element_peer(dev, apdev, 32*'01' + 32*'00') 8023 run_eap_proto_pwd_invalid_element_peer(dev, apdev, 32*'ff' + 32*'01') 8024 run_eap_proto_pwd_invalid_element_peer(dev, apdev, 32*'01' + 32*'ff') 8025 run_eap_proto_pwd_invalid_element_peer(dev, apdev, 64*'ff') 8026 # Not on curve 8027 run_eap_proto_pwd_invalid_element_peer(dev, apdev, 64*'01') 8028 8029def run_eap_proto_pwd_invalid_element_peer(dev, apdev, element): 8030 hapd = start_pwd_exchange(dev[0], apdev[0]) 8031 proxy_msg(hapd, dev[0]) # EAP-pwd-Commit/Request 8032 8033 # EAP-pwd-Commit/Response 8034 resp = rx_msg(dev[0]) 8035 # Replace element with an invalid value 8036 msg = resp[0:20] + element + resp[148:] 8037 tx_msg(dev[0], hapd, msg) 8038 8039 # EAP-pwd-Commit/Response or EAP-Failure 8040 req = rx_msg(hapd) 8041 if req[8:10] != "04": 8042 raise Exception("No EAP-Failure to reject invalid element") 8043 dev[0].request("REMOVE_NETWORK all") 8044 dev[0].wait_disconnected(timeout=1) 8045 hapd.disable() 8046 8047def test_eap_proto_pwd_errors(dev, apdev): 8048 """EAP-pwd local error cases""" 8049 check_eap_capa(dev[0], "PWD") 8050 params = hostapd.wpa2_eap_params(ssid="eap-test") 8051 hapd = hostapd.add_ap(apdev[0], params) 8052 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 8053 8054 for i in range(1, 4): 8055 with alloc_fail(dev[0], i, "eap_pwd_init"): 8056 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8057 eap="PWD", identity="pwd user", 8058 password="secret password", 8059 wait_connect=False) 8060 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"], 8061 timeout=15) 8062 if ev is None: 8063 raise Exception("Timeout on EAP start") 8064 dev[0].request("REMOVE_NETWORK all") 8065 dev[0].wait_disconnected() 8066 8067 with alloc_fail(dev[0], 1, "eap_pwd_get_session_id"): 8068 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8069 eap="PWD", identity="pwd user", 8070 fragment_size="0", 8071 password="secret password") 8072 dev[0].request("REMOVE_NETWORK all") 8073 dev[0].wait_disconnected() 8074 8075 funcs = ["eap_pwd_getkey", "eap_pwd_get_emsk", 8076 "=wpabuf_alloc;eap_pwd_perform_commit_exchange", 8077 "=wpabuf_alloc;eap_pwd_perform_confirm_exchange"] 8078 for func in funcs: 8079 with alloc_fail(dev[0], 1, func): 8080 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8081 eap="PWD", identity="pwd user@domain", 8082 password="secret password", erp="1", 8083 wait_connect=False) 8084 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 8085 dev[0].request("REMOVE_NETWORK all") 8086 dev[0].wait_disconnected() 8087 8088 for i in range(1, 5): 8089 with alloc_fail(dev[0], i, "eap_pwd_perform_id_exchange"): 8090 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8091 eap="PWD", identity="pwd user", 8092 password="secret password", 8093 wait_connect=False) 8094 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 8095 timeout=15) 8096 if ev is None: 8097 raise Exception("Timeout on EAP start") 8098 ok = False 8099 for j in range(10): 8100 state = dev[0].request('GET_ALLOC_FAIL') 8101 if state.startswith('0:'): 8102 ok = True 8103 break 8104 time.sleep(0.1) 8105 if not ok: 8106 raise Exception("No allocation failure seen") 8107 dev[0].request("REMOVE_NETWORK all") 8108 dev[0].wait_disconnected() 8109 8110 with alloc_fail(dev[0], 1, "wpabuf_alloc;eap_pwd_perform_id_exchange"): 8111 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8112 eap="PWD", identity="pwd user", 8113 password="secret password", 8114 wait_connect=False) 8115 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 8116 timeout=15) 8117 if ev is None: 8118 raise Exception("Timeout on EAP start") 8119 dev[0].request("REMOVE_NETWORK all") 8120 dev[0].wait_disconnected() 8121 8122 for i in range(1, 9): 8123 with alloc_fail(dev[0], i, "eap_pwd_perform_commit_exchange"): 8124 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8125 eap="PWD", identity="pwd user", 8126 password="secret password", 8127 wait_connect=False) 8128 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 8129 timeout=15) 8130 if ev is None: 8131 raise Exception("Timeout on EAP start") 8132 ok = False 8133 for j in range(10): 8134 state = dev[0].request('GET_ALLOC_FAIL') 8135 if state.startswith('0:'): 8136 ok = True 8137 break 8138 time.sleep(0.1) 8139 if not ok: 8140 raise Exception("No allocation failure seen") 8141 dev[0].request("REMOVE_NETWORK all") 8142 dev[0].wait_disconnected() 8143 8144 for i in range(1, 12): 8145 with alloc_fail(dev[0], i, "eap_pwd_perform_confirm_exchange"): 8146 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8147 eap="PWD", identity="pwd user", 8148 password="secret password", 8149 wait_connect=False) 8150 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 8151 timeout=15) 8152 if ev is None: 8153 raise Exception("Timeout on EAP start") 8154 ok = False 8155 for j in range(10): 8156 state = dev[0].request('GET_ALLOC_FAIL') 8157 if state.startswith('0:'): 8158 ok = True 8159 break 8160 time.sleep(0.1) 8161 if not ok: 8162 raise Exception("No allocation failure seen") 8163 dev[0].request("REMOVE_NETWORK all") 8164 dev[0].wait_disconnected() 8165 8166 for i in range(1, 5): 8167 with alloc_fail(dev[0], i, "eap_msg_alloc;=eap_pwd_process"): 8168 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8169 eap="PWD", identity="pwd user", 8170 password="secret password", fragment_size="50", 8171 wait_connect=False) 8172 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 8173 timeout=15) 8174 if ev is None: 8175 raise Exception("Timeout on EAP start") 8176 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 8177 dev[0].request("REMOVE_NETWORK all") 8178 dev[0].wait_disconnected() 8179 8180 # No password configured 8181 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8182 eap="PWD", identity="pwd user", 8183 wait_connect=False) 8184 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD vendor=0 method=52"], 8185 timeout=15) 8186 if ev is None: 8187 raise Exception("EAP-pwd not started") 8188 dev[0].request("REMOVE_NETWORK all") 8189 dev[0].wait_disconnected() 8190 8191 funcs = [(1, "hash_nt_password_hash;eap_pwd_perform_commit_exchange"), 8192 (1, "=crypto_bignum_init;eap_pwd_perform_commit_exchange"), 8193 (1, "=crypto_ec_point_init;eap_pwd_perform_commit_exchange"), 8194 (2, "=crypto_ec_point_init;eap_pwd_perform_commit_exchange"), 8195 (1, "=crypto_ec_point_mul;eap_pwd_perform_commit_exchange"), 8196 (2, "=crypto_ec_point_mul;eap_pwd_perform_commit_exchange"), 8197 (3, "=crypto_ec_point_mul;eap_pwd_perform_commit_exchange"), 8198 (1, "=crypto_ec_point_add;eap_pwd_perform_commit_exchange"), 8199 (1, "=crypto_ec_point_invert;eap_pwd_perform_commit_exchange"), 8200 (1, "=crypto_ec_point_to_bin;eap_pwd_perform_commit_exchange"), 8201 (1, "crypto_hash_finish;eap_pwd_kdf"), 8202 (1, "crypto_ec_point_from_bin;eap_pwd_get_element"), 8203 (3, "crypto_bignum_init;compute_password_element"), 8204 (4, "crypto_bignum_init;compute_password_element"), 8205 (1, "crypto_bignum_init_set;compute_password_element"), 8206 (2, "crypto_bignum_init_set;compute_password_element"), 8207 (3, "crypto_bignum_init_set;compute_password_element"), 8208 (1, "crypto_bignum_to_bin;compute_password_element"), 8209 (1, "crypto_ec_point_compute_y_sqr;compute_password_element"), 8210 (1, "crypto_bignum_rand;compute_password_element"), 8211 (1, "crypto_bignum_sub;compute_password_element")] 8212 for count, func in funcs: 8213 with fail_test(dev[0], count, func): 8214 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8215 eap="PWD", identity="pwd-hash", 8216 password_hex="hash:e3718ece8ab74792cbbfffd316d2d19a", 8217 wait_connect=False) 8218 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10) 8219 if ev is None: 8220 raise Exception("No EAP-Failure reported") 8221 dev[0].request("REMOVE_NETWORK all") 8222 dev[0].wait_disconnected() 8223 8224 params = {"ssid": "eap-test2", "wpa": "2", "wpa_key_mgmt": "WPA-EAP", 8225 "rsn_pairwise": "CCMP", "ieee8021x": "1", 8226 "eap_server": "1", "eap_user_file": "auth_serv/eap_user.conf", 8227 "pwd_group": "19", "fragment_size": "40"} 8228 hapd2 = hostapd.add_ap(apdev[1], params) 8229 dev[0].scan_for_bss(hapd2.own_addr(), freq=2412) 8230 8231 with alloc_fail(dev[0], 1, "wpabuf_alloc;=eap_pwd_process"): 8232 dev[0].connect("eap-test2", key_mgmt="WPA-EAP", scan_freq="2412", 8233 eap="PWD", identity="pwd user", 8234 password="secret password", 8235 wait_connect=False) 8236 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 8237 dev[0].request("REMOVE_NETWORK all") 8238 dev[0].wait_disconnected() 8239 8240 for i in range(1, 5): 8241 with fail_test(dev[0], i, 8242 "=crypto_ec_point_to_bin;eap_pwd_perform_confirm_exchange"): 8243 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8244 eap="PWD", identity="pwd-hash", 8245 password_hex="hash:e3718ece8ab74792cbbfffd316d2d19a", 8246 wait_connect=False) 8247 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10) 8248 if ev is None: 8249 raise Exception("No EAP-Failure reported") 8250 dev[0].request("REMOVE_NETWORK all") 8251 dev[0].wait_disconnected() 8252 dev[0].dump_monitor() 8253 8254def run_eap_pwd_connect(dev, hash=True, fragment=2000): 8255 if hash: 8256 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", 8257 fragment_size=str(fragment), 8258 eap="PWD", identity="pwd-hash", 8259 password_hex="hash:e3718ece8ab74792cbbfffd316d2d19a", 8260 scan_freq="2412", wait_connect=False) 8261 else: 8262 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", 8263 fragment_size=str(fragment), 8264 eap="PWD", identity="pwd-hash-sha1", 8265 password="secret password", 8266 scan_freq="2412", wait_connect=False) 8267 ev = dev.wait_event(["CTRL-EVENT-EAP-SUCCESS", "CTRL-EVENT-EAP-FAILURE", 8268 "CTRL-EVENT-DISCONNECTED"], 8269 timeout=1) 8270 dev.request("REMOVE_NETWORK all") 8271 if not ev or "CTRL-EVENT-DISCONNECTED" not in ev: 8272 dev.wait_disconnected() 8273 dev.dump_monitor() 8274 8275def test_eap_proto_pwd_errors_server(dev, apdev): 8276 """EAP-pwd local error cases on server""" 8277 check_eap_capa(dev[0], "PWD") 8278 params = int_eap_server_params() 8279 params['erp_domain'] = 'example.com' 8280 params['eap_server_erp'] = '1' 8281 hapd = hostapd.add_ap(apdev[0], params) 8282 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 8283 8284 tests = [(1, "eap_pwd_init"), 8285 (2, "eap_pwd_init"), 8286 (3, "eap_pwd_init"), 8287 (1, "eap_pwd_build_id_req"), 8288 (1, "eap_pwd_build_commit_req"), 8289 (1, "eap_pwd_build_confirm_req"), 8290 (1, "eap_pwd_h_init;eap_pwd_build_confirm_req"), 8291 (1, "wpabuf_alloc;eap_pwd_build_confirm_req"), 8292 (1, "eap_msg_alloc;eap_pwd_build_req"), 8293 (1, "eap_pwd_process_id_resp"), 8294 (1, "get_eap_pwd_group;eap_pwd_process_id_resp"), 8295 (1, "eap_pwd_process_confirm_resp"), 8296 (1, "eap_pwd_h_init;eap_pwd_process_confirm_resp"), 8297 (1, "compute_keys;eap_pwd_process_confirm_resp"), 8298 (1, "eap_pwd_getkey"), 8299 (1, "eap_pwd_get_emsk"), 8300 (1, "eap_pwd_get_session_id")] 8301 for count, func in tests: 8302 with alloc_fail(hapd, count, func): 8303 run_eap_pwd_connect(dev[0], hash=True) 8304 8305 tests = [(1, "eap_msg_alloc;eap_pwd_build_req"), 8306 (2, "eap_msg_alloc;eap_pwd_build_req"), 8307 (1, "wpabuf_alloc;eap_pwd_process")] 8308 for count, func in tests: 8309 with alloc_fail(hapd, count, func): 8310 run_eap_pwd_connect(dev[0], hash=True, fragment=13) 8311 8312 tests = [(4, "eap_pwd_init")] 8313 for count, func in tests: 8314 with alloc_fail(hapd, count, func): 8315 run_eap_pwd_connect(dev[0], hash=False) 8316 8317 tests = [(1, "eap_pwd_build_id_req"), 8318 (1, "eap_pwd_build_commit_req"), 8319 (1, "crypto_ec_point_mul;eap_pwd_build_commit_req"), 8320 (1, "crypto_ec_point_invert;eap_pwd_build_commit_req"), 8321 (1, "crypto_ec_point_to_bin;eap_pwd_build_commit_req"), 8322 (1, "crypto_ec_point_to_bin;eap_pwd_build_confirm_req"), 8323 (2, "=crypto_ec_point_to_bin;eap_pwd_build_confirm_req"), 8324 (1, "hash_nt_password_hash;eap_pwd_process_id_resp"), 8325 (1, "compute_password_element;eap_pwd_process_id_resp"), 8326 (1, "crypto_bignum_init;eap_pwd_process_commit_resp"), 8327 (1, "crypto_ec_point_mul;eap_pwd_process_commit_resp"), 8328 (2, "crypto_ec_point_mul;eap_pwd_process_commit_resp"), 8329 (1, "crypto_ec_point_add;eap_pwd_process_commit_resp"), 8330 (1, "crypto_ec_point_to_bin;eap_pwd_process_confirm_resp"), 8331 (2, "=crypto_ec_point_to_bin;eap_pwd_process_confirm_resp")] 8332 for count, func in tests: 8333 with fail_test(hapd, count, func): 8334 run_eap_pwd_connect(dev[0], hash=True) 8335 8336def start_pwd_assoc(dev, hapd): 8337 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", 8338 eap="PWD", identity="pwd user", password="secret password", 8339 wait_connect=False, scan_freq="2412") 8340 proxy_msg(hapd, dev) # EAP-Identity/Request 8341 proxy_msg(dev, hapd) # EAP-Identity/Response 8342 proxy_msg(hapd, dev) # EAP-pwd-Identity/Request 8343 8344def stop_pwd_assoc(dev, hapd): 8345 dev.request("REMOVE_NETWORK all") 8346 dev.wait_disconnected() 8347 dev.dump_monitor() 8348 hapd.dump_monitor() 8349 8350def test_eap_proto_pwd_server(dev, apdev): 8351 """EAP-pwd protocol testing for the server""" 8352 check_eap_capa(dev[0], "PWD") 8353 params = int_eap_server_params() 8354 hapd = hostapd.add_ap(apdev[0], params) 8355 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 8356 hapd.request("SET ext_eapol_frame_io 1") 8357 dev[0].request("SET ext_eapol_frame_io 1") 8358 8359 start_pwd_assoc(dev[0], hapd) 8360 resp = rx_msg(dev[0]) 8361 # Replace exch field with unexpected value 8362 # --> EAP-pwd: Unexpected opcode=4 in state=0 8363 msg = resp[0:18] + "04" + resp[20:] 8364 tx_msg(dev[0], hapd, msg) 8365 8366 # Too short EAP-pwd header (no flags/exch field) 8367 # --> EAP-pwd: Invalid frame 8368 msg = resp[0:4] + "0005" + resp[8:12] + "0005" + "34" 8369 tx_msg(dev[0], hapd, msg) 8370 8371 # Too short EAP-pwd header (L=1 but only one octet of total length field) 8372 # --> EAP-pwd: Frame too short to contain Total-Length field 8373 msg = resp[0:4] + "0007" + resp[8:12] + "0007" + "34" + "81ff" 8374 tx_msg(dev[0], hapd, msg) 8375 # server continues exchange, so start from scratch for the next step 8376 rx_msg(hapd) 8377 stop_pwd_assoc(dev[0], hapd) 8378 8379 start_pwd_assoc(dev[0], hapd) 8380 resp = rx_msg(dev[0]) 8381 # Too large total length 8382 msg = resp[0:4] + "0008" + resp[8:12] + "0008" + "34" + "c1ffff" 8383 tx_msg(dev[0], hapd, msg) 8384 # server continues exchange, so start from scratch for the next step 8385 rx_msg(hapd) 8386 stop_pwd_assoc(dev[0], hapd) 8387 8388 start_pwd_assoc(dev[0], hapd) 8389 resp = rx_msg(dev[0]) 8390 # First fragment 8391 msg = resp[0:4] + "0009" + resp[8:12] + "0009" + "34" + "c100ff" + "aa" 8392 tx_msg(dev[0], hapd, msg) 8393 # Ack 8394 req = rx_msg(hapd) 8395 # Unexpected first fragment 8396 # --> EAP-pwd: Unexpected new fragment start when previous fragment is still in use 8397 msg = resp[0:4] + "0009" + resp[8:10] + req[10:12] + "0009" + "34" + "c100ee" + "bb" 8398 tx_msg(dev[0], hapd, msg) 8399 # server continues exchange, so start from scratch for the next step 8400 rx_msg(hapd) 8401 stop_pwd_assoc(dev[0], hapd) 8402 8403 start_pwd_assoc(dev[0], hapd) 8404 resp = rx_msg(dev[0]) 8405 # Too much data in first fragment 8406 # --> EAP-pwd: Buffer overflow attack detected! (0+2 > 1) 8407 msg = resp[0:4] + "000a" + resp[8:12] + "000a" + "34" + "c10001" + "aabb" 8408 tx_msg(dev[0], hapd, msg) 8409 # EAP-Failure 8410 rx_msg(hapd) 8411 stop_pwd_assoc(dev[0], hapd) 8412 8413 start_pwd_assoc(dev[0], hapd) 8414 resp = rx_msg(dev[0]) 8415 # Change parameters 8416 # --> EAP-pwd: peer changed parameters 8417 msg = resp[0:20] + "ff" + resp[22:] 8418 tx_msg(dev[0], hapd, msg) 8419 # EAP-Failure 8420 rx_msg(hapd) 8421 stop_pwd_assoc(dev[0], hapd) 8422 8423 start_pwd_assoc(dev[0], hapd) 8424 resp = rx_msg(dev[0]) 8425 # Too short ID response 8426 # --> EAP-pwd: Invalid ID response 8427 msg = resp[0:4] + "000a" + resp[8:12] + "000a" + "34" + "01ffeeddcc" 8428 tx_msg(dev[0], hapd, msg) 8429 # server continues exchange, so start from scratch for the next step 8430 rx_msg(hapd) 8431 stop_pwd_assoc(dev[0], hapd) 8432 8433 start_pwd_assoc(dev[0], hapd) 8434 # EAP-pwd-Identity/Response 8435 resp = rx_msg(dev[0]) 8436 tx_msg(dev[0], hapd, resp) 8437 # EAP-pwd-Commit/Request 8438 req = rx_msg(hapd) 8439 # Unexpected EAP-pwd-Identity/Response 8440 # --> EAP-pwd: Unexpected opcode=1 in state=1 8441 msg = resp[0:10] + req[10:12] + resp[12:] 8442 tx_msg(dev[0], hapd, msg) 8443 # server continues exchange, so start from scratch for the next step 8444 rx_msg(hapd) 8445 stop_pwd_assoc(dev[0], hapd) 8446 8447 start_pwd_assoc(dev[0], hapd) 8448 proxy_msg(dev[0], hapd) # EAP-pwd-Identity/Response 8449 proxy_msg(hapd, dev[0]) # EAP-pwd-Commit/Request 8450 # EAP-pwd-Commit/Response 8451 resp = rx_msg(dev[0]) 8452 # Too short Commit response 8453 # --> EAP-pwd: Unexpected Commit payload length 4 (expected 96) 8454 msg = resp[0:4] + "000a" + resp[8:12] + "000a" + "34" + "02ffeeddcc" 8455 tx_msg(dev[0], hapd, msg) 8456 # EAP-Failure 8457 rx_msg(hapd) 8458 stop_pwd_assoc(dev[0], hapd) 8459 8460 start_pwd_assoc(dev[0], hapd) 8461 proxy_msg(dev[0], hapd) # EAP-pwd-Identity/Response 8462 proxy_msg(hapd, dev[0]) # EAP-pwd-Commit/Request 8463 proxy_msg(dev[0], hapd) # EAP-pwd-Commit/Response 8464 proxy_msg(hapd, dev[0]) # EAP-pwd-Confirm/Request 8465 # EAP-pwd-Confirm/Response 8466 resp = rx_msg(dev[0]) 8467 # Too short Confirm response 8468 # --> EAP-pwd: Unexpected Confirm payload length 4 (expected 32) 8469 msg = resp[0:4] + "000a" + resp[8:12] + "000a" + "34" + "03ffeeddcc" 8470 tx_msg(dev[0], hapd, msg) 8471 # EAP-Failure 8472 rx_msg(hapd) 8473 stop_pwd_assoc(dev[0], hapd) 8474 8475 start_pwd_assoc(dev[0], hapd) 8476 resp = rx_msg(dev[0]) 8477 # Set M=1 8478 # --> EAP-pwd: No buffer for reassembly 8479 msg = resp[0:18] + "41" + resp[20:] 8480 tx_msg(dev[0], hapd, msg) 8481 # EAP-Failure 8482 rx_msg(hapd) 8483 stop_pwd_assoc(dev[0], hapd) 8484 8485def test_eap_proto_erp(dev, apdev): 8486 """ERP protocol tests""" 8487 check_erp_capa(dev[0]) 8488 8489 global eap_proto_erp_test_done 8490 eap_proto_erp_test_done = False 8491 8492 def erp_handler(ctx, req): 8493 logger.info("erp_handler - RX " + binascii.hexlify(req).decode()) 8494 if 'num' not in ctx: 8495 ctx['num'] = 0 8496 ctx['num'] += 1 8497 if 'id' not in ctx: 8498 ctx['id'] = 1 8499 ctx['id'] = (ctx['id'] + 1) % 256 8500 idx = 0 8501 8502 idx += 1 8503 if ctx['num'] == idx: 8504 logger.info("Test: Missing type") 8505 return struct.pack(">BBH", EAP_CODE_INITIATE, ctx['id'], 4) 8506 8507 idx += 1 8508 if ctx['num'] == idx: 8509 logger.info("Test: Unexpected type") 8510 return struct.pack(">BBHB", EAP_CODE_INITIATE, ctx['id'], 4 + 1, 8511 255) 8512 8513 idx += 1 8514 if ctx['num'] == idx: 8515 logger.info("Test: Missing Reserved field") 8516 return struct.pack(">BBHB", EAP_CODE_INITIATE, ctx['id'], 4 + 1, 8517 EAP_ERP_TYPE_REAUTH_START) 8518 8519 idx += 1 8520 if ctx['num'] == idx: 8521 logger.info("Test: Zero-length TVs/TLVs") 8522 payload = b"" 8523 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'], 8524 4 + 1 + 1 + len(payload), 8525 EAP_ERP_TYPE_REAUTH_START, 0) + payload 8526 8527 idx += 1 8528 if ctx['num'] == idx: 8529 logger.info("Test: Too short TLV") 8530 payload = struct.pack("B", 191) 8531 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'], 8532 4 + 1 + 1 + len(payload), 8533 EAP_ERP_TYPE_REAUTH_START, 0) + payload 8534 8535 idx += 1 8536 if ctx['num'] == idx: 8537 logger.info("Test: Truncated TLV") 8538 payload = struct.pack("BB", 191, 1) 8539 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'], 8540 4 + 1 + 1 + len(payload), 8541 EAP_ERP_TYPE_REAUTH_START, 0) + payload 8542 8543 idx += 1 8544 if ctx['num'] == idx: 8545 logger.info("Test: Ignored unknown TLV and unknown TV/TLV terminating parsing") 8546 payload = struct.pack("BBB", 191, 0, 192) 8547 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'], 8548 4 + 1 + 1 + len(payload), 8549 EAP_ERP_TYPE_REAUTH_START, 0) + payload 8550 8551 idx += 1 8552 if ctx['num'] == idx: 8553 logger.info("Test: More than one keyName-NAI") 8554 payload = struct.pack("BBBB", EAP_ERP_TLV_KEYNAME_NAI, 0, 8555 EAP_ERP_TLV_KEYNAME_NAI, 0) 8556 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'], 8557 4 + 1 + 1 + len(payload), 8558 EAP_ERP_TYPE_REAUTH_START, 0) + payload 8559 8560 idx += 1 8561 if ctx['num'] == idx: 8562 logger.info("Test: Too short TLV keyName-NAI") 8563 payload = struct.pack("B", EAP_ERP_TLV_KEYNAME_NAI) 8564 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'], 8565 4 + 1 + 1 + len(payload), 8566 EAP_ERP_TYPE_REAUTH_START, 0) + payload 8567 8568 idx += 1 8569 if ctx['num'] == idx: 8570 logger.info("Test: Truncated TLV keyName-NAI") 8571 payload = struct.pack("BB", EAP_ERP_TLV_KEYNAME_NAI, 1) 8572 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'], 8573 4 + 1 + 1 + len(payload), 8574 EAP_ERP_TYPE_REAUTH_START, 0) + payload 8575 8576 idx += 1 8577 if ctx['num'] == idx: 8578 logger.info("Test: Valid rRK lifetime TV followed by too short rMSK lifetime TV") 8579 payload = struct.pack(">BLBH", EAP_ERP_TV_RRK_LIFETIME, 0, 8580 EAP_ERP_TV_RMSK_LIFETIME, 0) 8581 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'], 8582 4 + 1 + 1 + len(payload), 8583 EAP_ERP_TYPE_REAUTH_START, 0) + payload 8584 8585 idx += 1 8586 if ctx['num'] == idx: 8587 logger.info("Test: Missing type (Finish)") 8588 return struct.pack(">BBH", EAP_CODE_FINISH, ctx['id'], 4) 8589 8590 idx += 1 8591 if ctx['num'] == idx: 8592 logger.info("Test: Unexpected type (Finish)") 8593 return struct.pack(">BBHB", EAP_CODE_FINISH, ctx['id'], 4 + 1, 8594 255) 8595 8596 idx += 1 8597 if ctx['num'] == idx: 8598 logger.info("Test: Missing fields (Finish)") 8599 return struct.pack(">BBHB", EAP_CODE_FINISH, ctx['id'], 4 + 1, 8600 EAP_ERP_TYPE_REAUTH) 8601 8602 idx += 1 8603 if ctx['num'] == idx: 8604 logger.info("Test: Unexpected SEQ (Finish)") 8605 return struct.pack(">BBHBBHB", EAP_CODE_FINISH, ctx['id'], 8606 4 + 1 + 4, 8607 EAP_ERP_TYPE_REAUTH, 0, 0xffff, 0) 8608 8609 logger.info("No more test responses available - test case completed") 8610 global eap_proto_erp_test_done 8611 eap_proto_erp_test_done = True 8612 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 8613 8614 srv = start_radius_server(erp_handler) 8615 8616 try: 8617 hapd = start_ap(apdev[0]) 8618 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 8619 8620 i = 0 8621 while not eap_proto_erp_test_done: 8622 i += 1 8623 logger.info("Running connection iteration %d" % i) 8624 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8625 eap="PAX", identity="pax.user@example.com", 8626 password_hex="0123456789abcdef0123456789abcdef", 8627 wait_connect=False) 8628 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5) 8629 if ev is None: 8630 raise Exception("Timeout on EAP start") 8631 time.sleep(0.1) 8632 dev[0].request("REMOVE_NETWORK all") 8633 dev[0].wait_disconnected(timeout=1) 8634 dev[0].dump_monitor() 8635 finally: 8636 stop_radius_server(srv) 8637 8638def test_eap_proto_fast_errors(dev, apdev): 8639 """EAP-FAST local error cases""" 8640 check_eap_capa(dev[0], "FAST") 8641 params = hostapd.wpa2_eap_params(ssid="eap-test") 8642 hapd = hostapd.add_ap(apdev[0], params) 8643 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 8644 8645 for i in range(1, 5): 8646 with alloc_fail(dev[0], i, "eap_fast_init"): 8647 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8648 eap="FAST", anonymous_identity="FAST", 8649 identity="user", password="password", 8650 ca_cert="auth_serv/ca.pem", phase2="auth=GTC", 8651 phase1="fast_provisioning=2", 8652 pac_file="blob://fast_pac_auth", 8653 wait_connect=False) 8654 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"], 8655 timeout=5) 8656 if ev is None: 8657 raise Exception("Timeout on EAP start") 8658 dev[0].request("REMOVE_NETWORK all") 8659 dev[0].wait_disconnected() 8660 8661 tests = [(1, "wpabuf_alloc;eap_fast_tlv_eap_payload"), 8662 (1, "eap_fast_derive_key;eap_fast_derive_key_auth"), 8663 (1, "eap_msg_alloc;eap_peer_tls_phase2_nak"), 8664 (1, "wpabuf_alloc;eap_fast_tlv_result"), 8665 (1, "wpabuf_alloc;eap_fast_tlv_pac_ack"), 8666 (1, "=eap_peer_tls_derive_session_id;eap_fast_process_crypto_binding"), 8667 (1, "eap_peer_tls_decrypt;eap_fast_decrypt"), 8668 (1, "eap_fast_getKey"), 8669 (1, "eap_fast_get_session_id"), 8670 (1, "eap_fast_get_emsk")] 8671 for count, func in tests: 8672 dev[0].request("SET blob fast_pac_auth_errors ") 8673 with alloc_fail(dev[0], count, func): 8674 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8675 eap="FAST", anonymous_identity="FAST", 8676 identity="user@example.com", password="password", 8677 ca_cert="auth_serv/ca.pem", phase2="auth=GTC", 8678 phase1="fast_provisioning=2", 8679 pac_file="blob://fast_pac_auth_errors", 8680 erp="1", 8681 wait_connect=False) 8682 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 8683 timeout=15) 8684 if ev is None: 8685 raise Exception("Timeout on EAP start") 8686 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 8687 dev[0].request("REMOVE_NETWORK all") 8688 dev[0].wait_disconnected() 8689 8690 tests = [(1, "eap_fast_derive_key;eap_fast_derive_key_provisioning"), 8691 (1, "eap_mschapv2_getKey;eap_fast_get_phase2_key"), 8692 (1, "=eap_fast_use_pac_opaque"), 8693 (1, "eap_fast_copy_buf"), 8694 (1, "=eap_fast_add_pac"), 8695 (1, "=eap_fast_init_pac_data"), 8696 (1, "=eap_fast_write_pac"), 8697 (2, "=eap_fast_write_pac")] 8698 for count, func in tests: 8699 dev[0].request("SET blob fast_pac_errors ") 8700 with alloc_fail(dev[0], count, func): 8701 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8702 eap="FAST", anonymous_identity="FAST", 8703 identity="user", password="password", 8704 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2", 8705 phase1="fast_provisioning=1", 8706 pac_file="blob://fast_pac_errors", 8707 erp="1", 8708 wait_connect=False) 8709 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 8710 timeout=15) 8711 if ev is None: 8712 raise Exception("Timeout on EAP start") 8713 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 8714 dev[0].request("REMOVE_NETWORK all") 8715 dev[0].wait_disconnected() 8716 8717 tests = [(1, "eap_fast_get_cmk;eap_fast_process_crypto_binding"), 8718 (1, "eap_fast_derive_eap_msk;eap_fast_process_crypto_binding"), 8719 (1, "eap_fast_derive_eap_emsk;eap_fast_process_crypto_binding")] 8720 for count, func in tests: 8721 dev[0].request("SET blob fast_pac_auth_errors ") 8722 with fail_test(dev[0], count, func): 8723 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8724 eap="FAST", anonymous_identity="FAST", 8725 identity="user", password="password", 8726 ca_cert="auth_serv/ca.pem", phase2="auth=GTC", 8727 phase1="fast_provisioning=2", 8728 pac_file="blob://fast_pac_auth_errors", 8729 erp="1", 8730 wait_connect=False) 8731 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 8732 timeout=15) 8733 if ev is None: 8734 raise Exception("Timeout on EAP start") 8735 wait_fail_trigger(dev[0], "GET_FAIL") 8736 dev[0].request("REMOVE_NETWORK all") 8737 dev[0].wait_disconnected() 8738 8739 dev[0].request("SET blob fast_pac_errors ") 8740 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8741 eap="FAST", anonymous_identity="FAST", 8742 identity="user", password="password", 8743 ca_cert="auth_serv/ca.pem", phase2="auth=GTC", 8744 phase1="fast_provisioning=1", 8745 pac_file="blob://fast_pac_errors", 8746 wait_connect=False) 8747 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5) 8748 if ev is None: 8749 raise Exception("Timeout on EAP start") 8750 # EAP-FAST: Only EAP-MSCHAPv2 is allowed during unauthenticated 8751 # provisioning; reject phase2 type 6 8752 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5) 8753 if ev is None: 8754 raise Exception("Timeout on EAP failure") 8755 dev[0].request("REMOVE_NETWORK all") 8756 dev[0].wait_disconnected() 8757 8758 logger.info("Wrong password in Phase 2") 8759 dev[0].request("SET blob fast_pac_errors ") 8760 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8761 eap="FAST", anonymous_identity="FAST", 8762 identity="user", password="wrong password", 8763 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2", 8764 phase1="fast_provisioning=1", 8765 pac_file="blob://fast_pac_errors", 8766 wait_connect=False) 8767 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5) 8768 if ev is None: 8769 raise Exception("Timeout on EAP start") 8770 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5) 8771 if ev is None: 8772 raise Exception("Timeout on EAP failure") 8773 dev[0].request("REMOVE_NETWORK all") 8774 dev[0].wait_disconnected() 8775 8776 tests = ["FOOBAR\n", 8777 "wpa_supplicant EAP-FAST PAC file - version 1\nFOOBAR\n", 8778 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\n", 8779 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nSTART\n", 8780 "wpa_supplicant EAP-FAST PAC file - version 1\nEND\n", 8781 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nPAC-Type=12345\nEND\n" 8782 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nPAC-Key=12\nEND\n", 8783 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nPAC-Key=1\nEND\n", 8784 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nPAC-Key=1q\nEND\n", 8785 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nPAC-Opaque=1\nEND\n", 8786 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nA-ID=1\nEND\n", 8787 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nI-ID=1\nEND\n", 8788 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nA-ID-Info=1\nEND\n"] 8789 for pac in tests: 8790 blob = binascii.hexlify(pac.encode()).decode() 8791 dev[0].request("SET blob fast_pac_errors " + blob) 8792 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8793 eap="FAST", anonymous_identity="FAST", 8794 identity="user", password="password", 8795 ca_cert="auth_serv/ca.pem", phase2="auth=GTC", 8796 phase1="fast_provisioning=2", 8797 pac_file="blob://fast_pac_errors", 8798 wait_connect=False) 8799 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"], 8800 timeout=5) 8801 if ev is None: 8802 raise Exception("Timeout on EAP start") 8803 dev[0].request("REMOVE_NETWORK all") 8804 dev[0].wait_disconnected() 8805 8806 tests = ["wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nEND\n", 8807 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nEND\nSTART\nEND\nSTART\nEND\n"] 8808 for pac in tests: 8809 blob = binascii.hexlify(pac.encode()).decode() 8810 dev[0].request("SET blob fast_pac_errors " + blob) 8811 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8812 eap="FAST", anonymous_identity="FAST", 8813 identity="user", password="password", 8814 ca_cert="auth_serv/ca.pem", phase2="auth=GTC", 8815 phase1="fast_provisioning=2", 8816 pac_file="blob://fast_pac_errors") 8817 dev[0].request("REMOVE_NETWORK all") 8818 dev[0].wait_disconnected() 8819 8820 dev[0].request("SET blob fast_pac_errors ") 8821 8822def test_eap_proto_peap_errors_server(dev, apdev): 8823 """EAP-PEAP local error cases on server""" 8824 params = int_eap_server_params() 8825 hapd = hostapd.add_ap(apdev[0], params) 8826 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 8827 8828 tests = [(1, "get_asymetric_start_key;eap_mschapv2_getKey"), 8829 (1, "generate_authenticator_response_pwhash;eap_mschapv2_process_response"), 8830 (1, "hash_nt_password_hash;eap_mschapv2_process_response"), 8831 (1, "get_master_key;eap_mschapv2_process_response")] 8832 for count, func in tests: 8833 with fail_test(hapd, count, func): 8834 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", 8835 scan_freq="2412", 8836 eap="PEAP", anonymous_identity="peap", 8837 identity="user", password="password", 8838 phase1="peapver=0 crypto_binding=2", 8839 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2", 8840 erp="1", wait_connect=False) 8841 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10) 8842 if ev is None: 8843 raise Exception("EAP-Failure not reported") 8844 dev[0].request("REMOVE_NETWORK all") 8845 dev[0].wait_disconnected() 8846 8847def test_eap_proto_peap_errors(dev, apdev): 8848 """EAP-PEAP local error cases""" 8849 check_eap_capa(dev[0], "PEAP") 8850 check_eap_capa(dev[0], "MSCHAPV2") 8851 params = hostapd.wpa2_eap_params(ssid="eap-test") 8852 hapd = hostapd.add_ap(apdev[0], params) 8853 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 8854 8855 for i in range(1, 5): 8856 with alloc_fail(dev[0], i, "eap_peap_init"): 8857 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8858 eap="PEAP", anonymous_identity="peap", 8859 identity="user", password="password", 8860 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2", 8861 wait_connect=False) 8862 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"], 8863 timeout=5) 8864 if ev is None: 8865 raise Exception("Timeout on EAP start") 8866 dev[0].request("REMOVE_NETWORK all") 8867 dev[0].wait_disconnected() 8868 8869 tests = [(1, "eap_mschapv2_getKey;eap_peap_get_isk;eap_peap_derive_cmk"), 8870 (1, "eap_msg_alloc;eap_tlv_build_result"), 8871 (1, "eap_mschapv2_init;eap_peap_phase2_request"), 8872 (1, "eap_peer_tls_decrypt;eap_peap_decrypt"), 8873 (1, "wpabuf_alloc;=eap_peap_decrypt"), 8874 (1, "eap_peer_tls_encrypt;eap_peap_decrypt"), 8875 (1, "eap_peer_tls_process_helper;eap_peap_process"), 8876 (1, "eap_peer_tls_derive_key;eap_peap_process"), 8877 (1, "eap_peer_tls_derive_session_id;eap_peap_process"), 8878 (1, "eap_peap_getKey"), 8879 (1, "eap_peap_get_session_id")] 8880 for count, func in tests: 8881 with alloc_fail(dev[0], count, func): 8882 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8883 eap="PEAP", anonymous_identity="peap", 8884 identity="user", password="password", 8885 phase1="peapver=0 crypto_binding=2", 8886 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2", 8887 erp="1", wait_connect=False) 8888 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 8889 timeout=15) 8890 if ev is None: 8891 raise Exception("Timeout on EAP start") 8892 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 8893 dev[0].request("REMOVE_NETWORK all") 8894 dev[0].wait_disconnected() 8895 8896 tests = [(1, "peap_prfplus;eap_peap_derive_cmk"), 8897 (1, "eap_tlv_add_cryptobinding;eap_tlv_build_result"), 8898 (1, "peap_prfplus;eap_peap_getKey"), 8899 (1, "get_asymetric_start_key;eap_mschapv2_getKey")] 8900 for count, func in tests: 8901 with fail_test(dev[0], count, func): 8902 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8903 eap="PEAP", anonymous_identity="peap", 8904 identity="user", password="password", 8905 phase1="peapver=0 crypto_binding=2", 8906 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2", 8907 erp="1", wait_connect=False) 8908 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 8909 timeout=15) 8910 if ev is None: 8911 raise Exception("Timeout on EAP start") 8912 wait_fail_trigger(dev[0], "GET_FAIL") 8913 dev[0].request("REMOVE_NETWORK all") 8914 dev[0].wait_disconnected() 8915 8916 with alloc_fail(dev[0], 1, 8917 "eap_peer_tls_phase2_nak;eap_peap_phase2_request"): 8918 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8919 eap="PEAP", anonymous_identity="peap", 8920 identity="cert user", password="password", 8921 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2", 8922 wait_connect=False) 8923 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 8924 dev[0].request("REMOVE_NETWORK all") 8925 dev[0].wait_disconnected() 8926 8927def test_eap_proto_ttls_errors(dev, apdev): 8928 """EAP-TTLS local error cases""" 8929 check_eap_capa(dev[0], "TTLS") 8930 check_eap_capa(dev[0], "MSCHAPV2") 8931 params = hostapd.wpa2_eap_params(ssid="eap-test") 8932 hapd = hostapd.add_ap(apdev[0], params) 8933 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 8934 8935 for i in range(1, 5): 8936 with alloc_fail(dev[0], i, "eap_ttls_init"): 8937 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8938 eap="TTLS", anonymous_identity="ttls", 8939 identity="user", password="password", 8940 ca_cert="auth_serv/ca.pem", 8941 phase2="autheap=MSCHAPV2", 8942 wait_connect=False) 8943 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"], 8944 timeout=5) 8945 if ev is None: 8946 raise Exception("Timeout on EAP start") 8947 dev[0].request("REMOVE_NETWORK all") 8948 dev[0].wait_disconnected() 8949 8950 tests = [(1, "eap_peer_tls_derive_key;eap_ttls_v0_derive_key", 8951 "DOMAIN\\mschapv2 user", "auth=MSCHAPV2"), 8952 (1, "eap_peer_tls_derive_session_id;eap_ttls_v0_derive_key", 8953 "DOMAIN\\mschapv2 user", "auth=MSCHAPV2"), 8954 (1, "wpabuf_alloc;eap_ttls_phase2_request_mschapv2", 8955 "DOMAIN\\mschapv2 user", "auth=MSCHAPV2"), 8956 (1, "eap_peer_tls_derive_key;eap_ttls_phase2_request_mschapv2", 8957 "DOMAIN\\mschapv2 user", "auth=MSCHAPV2"), 8958 (1, "eap_peer_tls_encrypt;eap_ttls_encrypt_response;eap_ttls_implicit_identity_request", 8959 "DOMAIN\\mschapv2 user", "auth=MSCHAPV2"), 8960 (1, "eap_peer_tls_decrypt;eap_ttls_decrypt", 8961 "DOMAIN\\mschapv2 user", "auth=MSCHAPV2"), 8962 (1, "eap_ttls_getKey", 8963 "DOMAIN\\mschapv2 user", "auth=MSCHAPV2"), 8964 (1, "eap_ttls_get_session_id", 8965 "DOMAIN\\mschapv2 user", "auth=MSCHAPV2"), 8966 (1, "eap_ttls_get_emsk", 8967 "mschapv2 user@domain", "auth=MSCHAPV2"), 8968 (1, "wpabuf_alloc;eap_ttls_phase2_request_mschap", 8969 "mschap user", "auth=MSCHAP"), 8970 (1, "eap_peer_tls_derive_key;eap_ttls_phase2_request_mschap", 8971 "mschap user", "auth=MSCHAP"), 8972 (1, "wpabuf_alloc;eap_ttls_phase2_request_chap", 8973 "chap user", "auth=CHAP"), 8974 (1, "eap_peer_tls_derive_key;eap_ttls_phase2_request_chap", 8975 "chap user", "auth=CHAP"), 8976 (1, "wpabuf_alloc;eap_ttls_phase2_request_pap", 8977 "pap user", "auth=PAP"), 8978 (1, "wpabuf_alloc;eap_ttls_avp_encapsulate", 8979 "user", "autheap=MSCHAPV2"), 8980 (1, "eap_mschapv2_init;eap_ttls_phase2_request_eap_method", 8981 "user", "autheap=MSCHAPV2"), 8982 (1, "eap_sm_buildIdentity;eap_ttls_phase2_request_eap", 8983 "user", "autheap=MSCHAPV2"), 8984 (1, "eap_ttls_avp_encapsulate;eap_ttls_phase2_request_eap", 8985 "user", "autheap=MSCHAPV2"), 8986 (1, "eap_ttls_parse_attr_eap", 8987 "user", "autheap=MSCHAPV2"), 8988 (1, "eap_peer_tls_encrypt;eap_ttls_encrypt_response;eap_ttls_process_decrypted", 8989 "user", "autheap=MSCHAPV2"), 8990 (1, "eap_ttls_fake_identity_request", 8991 "user", "autheap=MSCHAPV2"), 8992 (1, "eap_msg_alloc;eap_tls_process_output", 8993 "user", "autheap=MSCHAPV2"), 8994 (1, "eap_msg_alloc;eap_peer_tls_build_ack", 8995 "user", "autheap=MSCHAPV2"), 8996 (1, "eap_peer_tls_phase2_nak;eap_ttls_phase2_request_eap_method", 8997 "cert user", "autheap=MSCHAPV2")] 8998 tls = dev[0].request("GET tls_library") 8999 if tls.startswith("internal"): 9000 tests += [(1, "tlsv1_client_decrypt;eap_peer_tls_decrypt", 9001 "user", "autheap=MSCHAPV2")] 9002 else: 9003 tests += [(1, "tls_connection_decrypt;eap_peer_tls_decrypt", 9004 "user", "autheap=MSCHAPV2")] 9005 for count, func, identity, phase2 in tests: 9006 with alloc_fail(dev[0], count, func): 9007 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 9008 eap="TTLS", anonymous_identity="ttls", 9009 identity=identity, password="password", 9010 ca_cert="auth_serv/ca.pem", phase2=phase2, 9011 erp="1", wait_connect=False) 9012 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 9013 timeout=15) 9014 if ev is None: 9015 raise Exception("Timeout on EAP start") 9016 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL", 9017 note="Allocation failure not triggered for: %d:%s" % (count, func)) 9018 dev[0].request("REMOVE_NETWORK all") 9019 dev[0].wait_disconnected() 9020 9021 tests = [(1, "os_get_random;eap_ttls_phase2_request_mschapv2"), 9022 (1, "mschapv2_derive_response;eap_ttls_phase2_request_mschapv2")] 9023 for count, func in tests: 9024 with fail_test(dev[0], count, func): 9025 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 9026 eap="TTLS", anonymous_identity="ttls", 9027 identity="DOMAIN\\mschapv2 user", 9028 password="password", 9029 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2", 9030 erp="1", wait_connect=False) 9031 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 9032 timeout=15) 9033 if ev is None: 9034 raise Exception("Timeout on EAP start") 9035 wait_fail_trigger(dev[0], "GET_FAIL", 9036 note="Test failure not triggered for: %d:%s" % (count, func)) 9037 dev[0].request("REMOVE_NETWORK all") 9038 dev[0].wait_disconnected() 9039 9040 tests = [(1, "nt_challenge_response;eap_ttls_phase2_request_mschap")] 9041 for count, func in tests: 9042 with fail_test(dev[0], count, func): 9043 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 9044 eap="TTLS", anonymous_identity="ttls", 9045 identity="mschap user", password="password", 9046 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAP", 9047 erp="1", wait_connect=False) 9048 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 9049 timeout=15) 9050 if ev is None: 9051 raise Exception("Timeout on EAP start") 9052 wait_fail_trigger(dev[0], "GET_FAIL", 9053 note="Test failure not triggered for: %d:%s" % (count, func)) 9054 dev[0].request("REMOVE_NETWORK all") 9055 dev[0].wait_disconnected() 9056 9057def test_eap_proto_expanded(dev, apdev): 9058 """EAP protocol tests with expanded header""" 9059 global eap_proto_expanded_test_done 9060 eap_proto_expanded_test_done = False 9061 9062 def expanded_handler(ctx, req): 9063 logger.info("expanded_handler - RX " + binascii.hexlify(req).decode()) 9064 if 'num' not in ctx: 9065 ctx['num'] = 0 9066 ctx['num'] += 1 9067 if 'id' not in ctx: 9068 ctx['id'] = 1 9069 ctx['id'] = (ctx['id'] + 1) % 256 9070 idx = 0 9071 9072 idx += 1 9073 if ctx['num'] == idx: 9074 logger.info("Test: MD5 challenge in expanded header") 9075 return struct.pack(">BBHB3BLBBB", EAP_CODE_REQUEST, ctx['id'], 9076 4 + 1 + 3 + 4 + 3, 9077 EAP_TYPE_EXPANDED, 0, 0, 0, EAP_TYPE_MD5, 9078 1, 0xaa, ord('n')) 9079 idx += 1 9080 if ctx['num'] == idx: 9081 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9082 9083 idx += 1 9084 if ctx['num'] == idx: 9085 logger.info("Test: Invalid expanded EAP length") 9086 return struct.pack(">BBHB3BH", EAP_CODE_REQUEST, ctx['id'], 9087 4 + 1 + 3 + 2, 9088 EAP_TYPE_EXPANDED, 0, 0, 0, EAP_TYPE_MD5) 9089 idx += 1 9090 if ctx['num'] == idx: 9091 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9092 9093 idx += 1 9094 if ctx['num'] == idx: 9095 logger.info("Test: Invalid expanded frame type") 9096 return struct.pack(">BBHB3BL", EAP_CODE_REQUEST, ctx['id'], 9097 4 + 1 + 3 + 4, 9098 EAP_TYPE_EXPANDED, 0, 0, 1, EAP_TYPE_MD5) 9099 idx += 1 9100 if ctx['num'] == idx: 9101 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9102 9103 idx += 1 9104 if ctx['num'] == idx: 9105 logger.info("Test: MSCHAPv2 Challenge") 9106 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'], 9107 4 + 1 + 4 + 1 + 16 + 6, 9108 EAP_TYPE_MSCHAPV2, 9109 1, 0, 4 + 1 + 16 + 6, 16) + 16*b'A' + b'foobar' 9110 idx += 1 9111 if ctx['num'] == idx: 9112 logger.info("Test: Invalid expanded frame type") 9113 return struct.pack(">BBHB3BL", EAP_CODE_REQUEST, ctx['id'], 9114 4 + 1 + 3 + 4, 9115 EAP_TYPE_EXPANDED, 0, 0, 1, EAP_TYPE_MSCHAPV2) 9116 9117 logger.info("No more test responses available - test case completed") 9118 global eap_proto_expanded_test_done 9119 eap_proto_expanded_test_done = True 9120 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9121 9122 srv = start_radius_server(expanded_handler) 9123 9124 try: 9125 hapd = start_ap(apdev[0]) 9126 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 9127 9128 i = 0 9129 while not eap_proto_expanded_test_done: 9130 i += 1 9131 logger.info("Running connection iteration %d" % i) 9132 if i == 4: 9133 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 9134 eap="MSCHAPV2", identity="user", 9135 password="password", 9136 wait_connect=False) 9137 else: 9138 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 9139 eap="MD5", identity="user", password="password", 9140 wait_connect=False) 9141 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5) 9142 if ev is None: 9143 raise Exception("Timeout on EAP start") 9144 if i in [1]: 9145 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5) 9146 if ev is None: 9147 raise Exception("Timeout on EAP method start") 9148 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5) 9149 if ev is None: 9150 raise Exception("Timeout on EAP failure") 9151 elif i in [2, 3]: 9152 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 9153 timeout=5) 9154 if ev is None: 9155 raise Exception("Timeout on EAP proposed method") 9156 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5) 9157 if ev is None: 9158 raise Exception("Timeout on EAP failure") 9159 else: 9160 time.sleep(0.1) 9161 dev[0].request("REMOVE_NETWORK all") 9162 dev[0].wait_disconnected(timeout=1) 9163 dev[0].dump_monitor() 9164 finally: 9165 stop_radius_server(srv) 9166 9167def test_eap_proto_tls(dev, apdev): 9168 """EAP-TLS protocol tests""" 9169 check_eap_capa(dev[0], "TLS") 9170 global eap_proto_tls_test_done, eap_proto_tls_test_wait 9171 eap_proto_tls_test_done = False 9172 eap_proto_tls_test_wait = False 9173 9174 def tls_handler(ctx, req): 9175 logger.info("tls_handler - RX " + binascii.hexlify(req).decode()) 9176 if 'num' not in ctx: 9177 ctx['num'] = 0 9178 ctx['num'] += 1 9179 if 'id' not in ctx: 9180 ctx['id'] = 1 9181 ctx['id'] = (ctx['id'] + 1) % 256 9182 idx = 0 9183 9184 global eap_proto_tls_test_wait 9185 9186 idx += 1 9187 if ctx['num'] == idx: 9188 logger.info("Test: Too much payload in TLS/Start: TLS Message Length (0 bytes) smaller than this fragment (1 bytes)") 9189 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'], 9190 4 + 1 + 1 + 4 + 1, 9191 EAP_TYPE_TLS, 0xa0, 0, 1) 9192 9193 idx += 1 9194 if ctx['num'] == idx: 9195 logger.info("Test: Fragmented TLS/Start") 9196 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'], 9197 4 + 1 + 1 + 4 + 1, 9198 EAP_TYPE_TLS, 0xe0, 2, 1) 9199 idx += 1 9200 if ctx['num'] == idx: 9201 logger.info("Test: Too long fragment of TLS/Start: Invalid reassembly state: tls_in_left=2 tls_in_len=0 in_len=0") 9202 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 9203 4 + 1 + 1 + 2, 9204 EAP_TYPE_TLS, 0x00, 2, 3) 9205 idx += 1 9206 if ctx['num'] == idx: 9207 logger.info("Test: EAP-Failure") 9208 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9209 9210 idx += 1 9211 if ctx['num'] == idx: 9212 logger.info("Test: TLS/Start") 9213 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9214 4 + 1 + 1, 9215 EAP_TYPE_TLS, 0x20) 9216 idx += 1 9217 if ctx['num'] == idx: 9218 logger.info("Test: Fragmented TLS message") 9219 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'], 9220 4 + 1 + 1 + 4 + 1, 9221 EAP_TYPE_TLS, 0xc0, 2, 1) 9222 idx += 1 9223 if ctx['num'] == idx: 9224 logger.info("Test: Invalid TLS message: no Flags octet included + workaround") 9225 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 9226 4 + 1, 9227 EAP_TYPE_TLS) 9228 idx += 1 9229 if ctx['num'] == idx: 9230 logger.info("Test: Too long fragment of TLS message: more data than TLS message length indicated") 9231 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 9232 4 + 1 + 1 + 2, 9233 EAP_TYPE_TLS, 0x00, 2, 3) 9234 idx += 1 9235 if ctx['num'] == idx: 9236 logger.info("Test: EAP-Failure") 9237 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9238 9239 idx += 1 9240 if ctx['num'] == idx: 9241 logger.info("Test: Fragmented TLS/Start and truncated Message Length field") 9242 return struct.pack(">BBHBB3B", EAP_CODE_REQUEST, ctx['id'], 9243 4 + 1 + 1 + 3, 9244 EAP_TYPE_TLS, 0xe0, 1, 2, 3) 9245 9246 idx += 1 9247 if ctx['num'] == idx: 9248 logger.info("Test: TLS/Start") 9249 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9250 4 + 1 + 1, 9251 EAP_TYPE_TLS, 0x20) 9252 idx += 1 9253 if ctx['num'] == idx: 9254 logger.info("Test: Fragmented TLS message") 9255 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'], 9256 4 + 1 + 1 + 4 + 1, 9257 EAP_TYPE_TLS, 0xc0, 2, 1) 9258 idx += 1 9259 if ctx['num'] == idx: 9260 logger.info("Test: Invalid TLS message: no Flags octet included + workaround disabled") 9261 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 9262 4 + 1, 9263 EAP_TYPE_TLS) 9264 9265 idx += 1 9266 if ctx['num'] == idx: 9267 logger.info("Test: TLS/Start") 9268 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9269 4 + 1 + 1, 9270 EAP_TYPE_TLS, 0x20) 9271 idx += 1 9272 if ctx['num'] == idx: 9273 logger.info("Test: Fragmented TLS message (long; first)") 9274 payload = 1450*b'A' 9275 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'], 9276 4 + 1 + 1 + 4 + len(payload), 9277 EAP_TYPE_TLS, 0xc0, 65536) + payload 9278 # "Too long TLS fragment (size over 64 kB)" on the last one 9279 for i in range(44): 9280 idx += 1 9281 if ctx['num'] == idx: 9282 logger.info("Test: Fragmented TLS message (long; cont %d)" % i) 9283 eap_proto_tls_test_wait = True 9284 payload = 1470*b'A' 9285 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9286 4 + 1 + 1 + len(payload), 9287 EAP_TYPE_TLS, 0x40) + payload 9288 eap_proto_tls_test_wait = False 9289 idx += 1 9290 if ctx['num'] == idx: 9291 logger.info("Test: EAP-Failure") 9292 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9293 9294 idx += 1 9295 if ctx['num'] == idx: 9296 logger.info("Test: TLS/Start") 9297 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9298 4 + 1 + 1, 9299 EAP_TYPE_TLS, 0x20) 9300 idx += 1 9301 if ctx['num'] == idx: 9302 logger.info("Test: Non-ACK to more-fragment message") 9303 return struct.pack(">BBHBBB", EAP_CODE_REQUEST, ctx['id'], 9304 4 + 1 + 1 + 1, 9305 EAP_TYPE_TLS, 0x00, 255) 9306 idx += 1 9307 if ctx['num'] == idx: 9308 logger.info("Test: EAP-Failure") 9309 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9310 9311 logger.info("No more test responses available - test case completed") 9312 global eap_proto_tls_test_done 9313 eap_proto_tls_test_done = True 9314 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9315 9316 srv = start_radius_server(tls_handler) 9317 9318 try: 9319 hapd = start_ap(apdev[0]) 9320 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 9321 9322 i = 0 9323 while not eap_proto_tls_test_done: 9324 i += 1 9325 logger.info("Running connection iteration %d" % i) 9326 workaround = "0" if i == 6 else "1" 9327 fragment_size = "100" if i == 8 else "1400" 9328 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 9329 eap="TLS", identity="tls user", 9330 ca_cert="auth_serv/ca.pem", 9331 client_cert="auth_serv/user.pem", 9332 private_key="auth_serv/user.key", 9333 eap_workaround=workaround, 9334 fragment_size=fragment_size, 9335 wait_connect=False) 9336 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5) 9337 if ev is None: 9338 raise Exception("Timeout on EAP start") 9339 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD", 9340 "CTRL-EVENT-EAP-STATUS"], timeout=5) 9341 if ev is None: 9342 raise Exception("Timeout on EAP method start") 9343 time.sleep(0.1) 9344 start = os.times()[4] 9345 while eap_proto_tls_test_wait: 9346 now = os.times()[4] 9347 if now - start > 10: 9348 break 9349 time.sleep(0.1) 9350 dev[0].request("REMOVE_NETWORK all") 9351 dev[0].wait_disconnected(timeout=1) 9352 dev[0].dump_monitor() 9353 finally: 9354 stop_radius_server(srv) 9355 9356def test_eap_proto_tnc(dev, apdev): 9357 """EAP-TNC protocol tests""" 9358 check_eap_capa(dev[0], "TNC") 9359 global eap_proto_tnc_test_done 9360 eap_proto_tnc_test_done = False 9361 9362 def tnc_handler(ctx, req): 9363 logger.info("tnc_handler - RX " + binascii.hexlify(req).decode()) 9364 if 'num' not in ctx: 9365 ctx['num'] = 0 9366 ctx['num'] += 1 9367 if 'id' not in ctx: 9368 ctx['id'] = 1 9369 ctx['id'] = (ctx['id'] + 1) % 256 9370 idx = 0 9371 9372 idx += 1 9373 if ctx['num'] == idx: 9374 logger.info("Test: TNC start with unsupported version") 9375 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9376 4 + 1 + 1, 9377 EAP_TYPE_TNC, 0x20) 9378 9379 idx += 1 9380 if ctx['num'] == idx: 9381 logger.info("Test: TNC without Flags field") 9382 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 9383 4 + 1, 9384 EAP_TYPE_TNC) 9385 9386 idx += 1 9387 if ctx['num'] == idx: 9388 logger.info("Test: Message underflow due to missing Message Length") 9389 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9390 4 + 1 + 1, 9391 EAP_TYPE_TNC, 0xa1) 9392 9393 idx += 1 9394 if ctx['num'] == idx: 9395 logger.info("Test: Invalid Message Length") 9396 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'], 9397 4 + 1 + 1 + 4 + 1, 9398 EAP_TYPE_TNC, 0xa1, 0, 0) 9399 9400 idx += 1 9401 if ctx['num'] == idx: 9402 logger.info("Test: Invalid Message Length") 9403 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'], 9404 4 + 1 + 1 + 4, 9405 EAP_TYPE_TNC, 0xe1, 75001) 9406 9407 idx += 1 9408 if ctx['num'] == idx: 9409 logger.info("Test: Start with Message Length") 9410 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'], 9411 4 + 1 + 1 + 4, 9412 EAP_TYPE_TNC, 0xa1, 1) 9413 idx += 1 9414 if ctx['num'] == idx: 9415 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9416 9417 idx += 1 9418 if ctx['num'] == idx: 9419 logger.info("Test: Server used start flag again") 9420 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9421 4 + 1 + 1, 9422 EAP_TYPE_TNC, 0x21) 9423 idx += 1 9424 if ctx['num'] == idx: 9425 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9426 4 + 1 + 1, 9427 EAP_TYPE_TNC, 0x21) 9428 9429 idx += 1 9430 if ctx['num'] == idx: 9431 logger.info("Test: Fragmentation and unexpected payload in ack") 9432 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9433 4 + 1 + 1, 9434 EAP_TYPE_TNC, 0x21) 9435 idx += 1 9436 if ctx['num'] == idx: 9437 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9438 4 + 1 + 1, 9439 EAP_TYPE_TNC, 0x01) 9440 idx += 1 9441 if ctx['num'] == idx: 9442 return struct.pack(">BBHBBB", EAP_CODE_REQUEST, ctx['id'], 9443 4 + 1 + 1 + 1, 9444 EAP_TYPE_TNC, 0x01, 0) 9445 9446 idx += 1 9447 if ctx['num'] == idx: 9448 logger.info("Test: Server fragmenting and fragment overflow") 9449 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'], 9450 4 + 1 + 1 + 4 + 1, 9451 EAP_TYPE_TNC, 0xe1, 2, 1) 9452 idx += 1 9453 if ctx['num'] == idx: 9454 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 9455 4 + 1 + 1 + 2, 9456 EAP_TYPE_TNC, 0x01, 2, 3) 9457 9458 idx += 1 9459 if ctx['num'] == idx: 9460 logger.info("Test: Server fragmenting and no message length in a fragment") 9461 return struct.pack(">BBHBBB", EAP_CODE_REQUEST, ctx['id'], 9462 4 + 1 + 1 + 1, 9463 EAP_TYPE_TNC, 0x61, 2) 9464 9465 idx += 1 9466 if ctx['num'] == idx: 9467 logger.info("Test: TNC start followed by invalid TNCCS-Batch") 9468 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9469 4 + 1 + 1, 9470 EAP_TYPE_TNC, 0x21) 9471 idx += 1 9472 if ctx['num'] == idx: 9473 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode()) 9474 resp = b"FOO" 9475 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9476 4 + 1 + 1 + len(resp), 9477 EAP_TYPE_TNC, 0x01) + resp 9478 9479 idx += 1 9480 if ctx['num'] == idx: 9481 logger.info("Test: TNC start followed by invalid TNCCS-Batch (2)") 9482 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9483 4 + 1 + 1, 9484 EAP_TYPE_TNC, 0x21) 9485 idx += 1 9486 if ctx['num'] == idx: 9487 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode()) 9488 resp = b"</TNCCS-Batch><TNCCS-Batch>" 9489 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9490 4 + 1 + 1 + len(resp), 9491 EAP_TYPE_TNC, 0x01) + resp 9492 9493 idx += 1 9494 if ctx['num'] == idx: 9495 logger.info("Test: TNCCS-Batch missing BatchId attribute") 9496 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9497 4 + 1 + 1, 9498 EAP_TYPE_TNC, 0x21) 9499 idx += 1 9500 if ctx['num'] == idx: 9501 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode()) 9502 resp = b"<TNCCS-Batch foo=3></TNCCS-Batch>" 9503 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9504 4 + 1 + 1 + len(resp), 9505 EAP_TYPE_TNC, 0x01) + resp 9506 9507 idx += 1 9508 if ctx['num'] == idx: 9509 logger.info("Test: Unexpected IF-TNCCS BatchId") 9510 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9511 4 + 1 + 1, 9512 EAP_TYPE_TNC, 0x21) 9513 idx += 1 9514 if ctx['num'] == idx: 9515 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode()) 9516 resp = b"<TNCCS-Batch BatchId=123456789></TNCCS-Batch>" 9517 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9518 4 + 1 + 1 + len(resp), 9519 EAP_TYPE_TNC, 0x01) + resp 9520 9521 idx += 1 9522 if ctx['num'] == idx: 9523 logger.info("Test: Missing IMC-IMV-Message and TNCC-TNCS-Message end tags") 9524 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9525 4 + 1 + 1, 9526 EAP_TYPE_TNC, 0x21) 9527 idx += 1 9528 if ctx['num'] == idx: 9529 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode()) 9530 resp = b"<TNCCS-Batch BatchId=2><IMC-IMV-Message><TNCC-TNCS-Message></TNCCS-Batch>" 9531 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9532 4 + 1 + 1 + len(resp), 9533 EAP_TYPE_TNC, 0x01) + resp 9534 idx += 1 9535 if ctx['num'] == idx: 9536 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9537 9538 idx += 1 9539 if ctx['num'] == idx: 9540 logger.info("Test: Missing IMC-IMV-Message and TNCC-TNCS-Message Type") 9541 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9542 4 + 1 + 1, 9543 EAP_TYPE_TNC, 0x21) 9544 idx += 1 9545 if ctx['num'] == idx: 9546 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode()) 9547 resp = b"<TNCCS-Batch BatchId=2><IMC-IMV-Message></IMC-IMV-Message><TNCC-TNCS-Message></TNCC-TNCS-Message></TNCCS-Batch>" 9548 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9549 4 + 1 + 1 + len(resp), 9550 EAP_TYPE_TNC, 0x01) + resp 9551 idx += 1 9552 if ctx['num'] == idx: 9553 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9554 9555 idx += 1 9556 if ctx['num'] == idx: 9557 logger.info("Test: Missing TNCC-TNCS-Message XML end tag") 9558 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9559 4 + 1 + 1, 9560 EAP_TYPE_TNC, 0x21) 9561 idx += 1 9562 if ctx['num'] == idx: 9563 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode()) 9564 resp = b"<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type><XML></TNCC-TNCS-Message></TNCCS-Batch>" 9565 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9566 4 + 1 + 1 + len(resp), 9567 EAP_TYPE_TNC, 0x01) + resp 9568 idx += 1 9569 if ctx['num'] == idx: 9570 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9571 9572 idx += 1 9573 if ctx['num'] == idx: 9574 logger.info("Test: Missing TNCC-TNCS-Message Base64 start tag") 9575 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9576 4 + 1 + 1, 9577 EAP_TYPE_TNC, 0x21) 9578 idx += 1 9579 if ctx['num'] == idx: 9580 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode()) 9581 resp = b"<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type></TNCC-TNCS-Message></TNCCS-Batch>" 9582 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9583 4 + 1 + 1 + len(resp), 9584 EAP_TYPE_TNC, 0x01) + resp 9585 idx += 1 9586 if ctx['num'] == idx: 9587 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9588 9589 idx += 1 9590 if ctx['num'] == idx: 9591 logger.info("Test: Missing TNCC-TNCS-Message Base64 end tag") 9592 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9593 4 + 1 + 1, 9594 EAP_TYPE_TNC, 0x21) 9595 idx += 1 9596 if ctx['num'] == idx: 9597 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode()) 9598 resp = b"<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type><Base64>abc</TNCC-TNCS-Message></TNCCS-Batch>" 9599 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9600 4 + 1 + 1 + len(resp), 9601 EAP_TYPE_TNC, 0x01) + resp 9602 idx += 1 9603 if ctx['num'] == idx: 9604 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9605 9606 idx += 1 9607 if ctx['num'] == idx: 9608 logger.info("Test: TNCC-TNCS-Message Base64 message") 9609 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9610 4 + 1 + 1, 9611 EAP_TYPE_TNC, 0x21) 9612 idx += 1 9613 if ctx['num'] == idx: 9614 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode()) 9615 resp = b"<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type><Base64>aGVsbG8=</Base64></TNCC-TNCS-Message></TNCCS-Batch>" 9616 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9617 4 + 1 + 1 + len(resp), 9618 EAP_TYPE_TNC, 0x01) + resp 9619 idx += 1 9620 if ctx['num'] == idx: 9621 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9622 9623 idx += 1 9624 if ctx['num'] == idx: 9625 logger.info("Test: Invalid TNCC-TNCS-Message XML message") 9626 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9627 4 + 1 + 1, 9628 EAP_TYPE_TNC, 0x21) 9629 idx += 1 9630 if ctx['num'] == idx: 9631 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode()) 9632 resp = b"<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type><XML>hello</XML></TNCC-TNCS-Message></TNCCS-Batch>" 9633 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9634 4 + 1 + 1 + len(resp), 9635 EAP_TYPE_TNC, 0x01) + resp 9636 idx += 1 9637 if ctx['num'] == idx: 9638 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9639 9640 idx += 1 9641 if ctx['num'] == idx: 9642 logger.info("Test: Missing TNCCS-Recommendation type") 9643 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9644 4 + 1 + 1, 9645 EAP_TYPE_TNC, 0x21) 9646 idx += 1 9647 if ctx['num'] == idx: 9648 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode()) 9649 resp = b'<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type><XML><TNCCS-Recommendation foo=1></TNCCS-Recommendation></XML></TNCC-TNCS-Message></TNCCS-Batch>' 9650 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9651 4 + 1 + 1 + len(resp), 9652 EAP_TYPE_TNC, 0x01) + resp 9653 idx += 1 9654 if ctx['num'] == idx: 9655 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9656 9657 idx += 1 9658 if ctx['num'] == idx: 9659 logger.info("Test: TNCCS-Recommendation type=none") 9660 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9661 4 + 1 + 1, 9662 EAP_TYPE_TNC, 0x21) 9663 idx += 1 9664 if ctx['num'] == idx: 9665 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode()) 9666 resp = b'<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type><XML><TNCCS-Recommendation type="none"></TNCCS-Recommendation></XML></TNCC-TNCS-Message></TNCCS-Batch>' 9667 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9668 4 + 1 + 1 + len(resp), 9669 EAP_TYPE_TNC, 0x01) + resp 9670 idx += 1 9671 if ctx['num'] == idx: 9672 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9673 9674 idx += 1 9675 if ctx['num'] == idx: 9676 logger.info("Test: TNCCS-Recommendation type=isolate") 9677 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9678 4 + 1 + 1, 9679 EAP_TYPE_TNC, 0x21) 9680 idx += 1 9681 if ctx['num'] == idx: 9682 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode()) 9683 resp = b'<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type><XML><TNCCS-Recommendation type="isolate"></TNCCS-Recommendation></XML></TNCC-TNCS-Message></TNCCS-Batch>' 9684 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9685 4 + 1 + 1 + len(resp), 9686 EAP_TYPE_TNC, 0x01) + resp 9687 idx += 1 9688 if ctx['num'] == idx: 9689 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9690 9691 logger.info("No more test responses available - test case completed") 9692 global eap_proto_tnc_test_done 9693 eap_proto_tnc_test_done = True 9694 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9695 9696 srv = start_radius_server(tnc_handler) 9697 9698 try: 9699 hapd = start_ap(apdev[0]) 9700 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 9701 9702 i = 0 9703 while not eap_proto_tnc_test_done: 9704 i += 1 9705 logger.info("Running connection iteration %d" % i) 9706 frag = 1400 9707 if i == 8: 9708 frag = 150 9709 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 9710 eap="TNC", identity="tnc", fragment_size=str(frag), 9711 wait_connect=False) 9712 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5) 9713 if ev is None: 9714 raise Exception("Timeout on EAP start") 9715 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD", 9716 "CTRL-EVENT-EAP-STATUS"], timeout=5) 9717 if ev is None: 9718 raise Exception("Timeout on EAP method start") 9719 time.sleep(0.1) 9720 dev[0].request("REMOVE_NETWORK all") 9721 dev[0].wait_disconnected(timeout=1) 9722 dev[0].dump_monitor() 9723 finally: 9724 stop_radius_server(srv) 9725 9726def test_eap_canned_success_after_identity(dev, apdev): 9727 """EAP protocol tests for canned EAP-Success after identity""" 9728 check_eap_capa(dev[0], "MD5") 9729 def eap_canned_success_handler(ctx, req): 9730 logger.info("eap_canned_success_handler - RX " + binascii.hexlify(req).decode()) 9731 if 'num' not in ctx: 9732 ctx['num'] = 0 9733 ctx['num'] = ctx['num'] + 1 9734 if 'id' not in ctx: 9735 ctx['id'] = 1 9736 ctx['id'] = (ctx['id'] + 1) % 256 9737 idx = 0 9738 9739 idx += 1 9740 if ctx['num'] == idx: 9741 logger.info("Test: EAP-Success") 9742 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4) 9743 9744 idx += 1 9745 if ctx['num'] == idx: 9746 logger.info("Test: EAP-Success") 9747 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4) 9748 9749 return None 9750 9751 srv = start_radius_server(eap_canned_success_handler) 9752 9753 try: 9754 hapd = start_ap(apdev[0]) 9755 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 9756 9757 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 9758 phase1="allow_canned_success=1", 9759 eap="MD5", identity="user", password="password", 9760 wait_connect=False) 9761 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15) 9762 if ev is None: 9763 raise Exception("Timeout on EAP success") 9764 dev[0].request("REMOVE_NETWORK all") 9765 dev[0].wait_disconnected() 9766 9767 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 9768 eap="MD5", identity="user", password="password", 9769 wait_connect=False) 9770 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5) 9771 if ev is None: 9772 raise Exception("Timeout on EAP start") 9773 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=0.1) 9774 if ev is not None: 9775 raise Exception("Unexpected EAP success") 9776 dev[0].request("REMOVE_NETWORK all") 9777 dev[0].wait_disconnected() 9778 finally: 9779 stop_radius_server(srv) 9780 9781def test_eap_proto_wsc(dev, apdev): 9782 """EAP-WSC protocol tests""" 9783 global eap_proto_wsc_test_done, eap_proto_wsc_wait_failure 9784 eap_proto_wsc_test_done = False 9785 9786 def wsc_handler(ctx, req): 9787 logger.info("wsc_handler - RX " + binascii.hexlify(req).decode()) 9788 if 'num' not in ctx: 9789 ctx['num'] = 0 9790 ctx['num'] += 1 9791 if 'id' not in ctx: 9792 ctx['id'] = 1 9793 ctx['id'] = (ctx['id'] + 1) % 256 9794 idx = 0 9795 9796 global eap_proto_wsc_wait_failure 9797 eap_proto_wsc_wait_failure = False 9798 9799 idx += 1 9800 if ctx['num'] == idx: 9801 logger.info("Test: Missing Flags field") 9802 return struct.pack(">BBHB3BLB", EAP_CODE_REQUEST, ctx['id'], 9803 4 + 1 + 3 + 4 + 1, 9804 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1, 9805 1) 9806 9807 idx += 1 9808 if ctx['num'] == idx: 9809 logger.info("Test: Message underflow (missing Message Length field)") 9810 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'], 9811 4 + 1 + 3 + 4 + 2, 9812 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1, 9813 1, 0x02) 9814 9815 idx += 1 9816 if ctx['num'] == idx: 9817 logger.info("Test: Invalid Message Length (> 50000)") 9818 return struct.pack(">BBHB3BLBBH", EAP_CODE_REQUEST, ctx['id'], 9819 4 + 1 + 3 + 4 + 4, 9820 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1, 9821 1, 0x02, 65535) 9822 9823 idx += 1 9824 if ctx['num'] == idx: 9825 logger.info("Test: Invalid Message Length (< current payload)") 9826 return struct.pack(">BBHB3BLBBHB", EAP_CODE_REQUEST, ctx['id'], 9827 4 + 1 + 3 + 4 + 5, 9828 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1, 9829 1, 0x02, 0, 0xff) 9830 9831 idx += 1 9832 if ctx['num'] == idx: 9833 logger.info("Test: Unexpected Op-Code 5 in WAIT_START state") 9834 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'], 9835 4 + 1 + 3 + 4 + 2, 9836 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1, 9837 5, 0x00) 9838 9839 idx += 1 9840 if ctx['num'] == idx: 9841 logger.info("Test: Valid WSC Start to start the sequence") 9842 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'], 9843 4 + 1 + 3 + 4 + 2, 9844 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1, 9845 1, 0x00) 9846 idx += 1 9847 if ctx['num'] == idx: 9848 logger.info("Test: No Message Length field in a fragmented packet") 9849 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'], 9850 4 + 1 + 3 + 4 + 2, 9851 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1, 9852 4, 0x01) 9853 9854 idx += 1 9855 if ctx['num'] == idx: 9856 logger.info("Test: Valid WSC Start to start the sequence") 9857 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'], 9858 4 + 1 + 3 + 4 + 2, 9859 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1, 9860 1, 0x00) 9861 idx += 1 9862 if ctx['num'] == idx: 9863 logger.info("Test: Valid first fragmented packet") 9864 return struct.pack(">BBHB3BLBBHB", EAP_CODE_REQUEST, ctx['id'], 9865 4 + 1 + 3 + 4 + 5, 9866 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1, 9867 4, 0x03, 10, 1) 9868 idx += 1 9869 if ctx['num'] == idx: 9870 logger.info("Test: Unexpected Op-Code 5 in fragment (expected 4)") 9871 return struct.pack(">BBHB3BLBBB", EAP_CODE_REQUEST, ctx['id'], 9872 4 + 1 + 3 + 4 + 3, 9873 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1, 9874 5, 0x01, 2) 9875 9876 idx += 1 9877 if ctx['num'] == idx: 9878 logger.info("Test: Valid WSC Start to start the sequence") 9879 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'], 9880 4 + 1 + 3 + 4 + 2, 9881 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1, 9882 1, 0x00) 9883 idx += 1 9884 if ctx['num'] == idx: 9885 logger.info("Test: Valid first fragmented packet") 9886 return struct.pack(">BBHB3BLBBHB", EAP_CODE_REQUEST, ctx['id'], 9887 4 + 1 + 3 + 4 + 5, 9888 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1, 9889 4, 0x03, 2, 1) 9890 idx += 1 9891 if ctx['num'] == idx: 9892 logger.info("Test: Fragment overflow") 9893 return struct.pack(">BBHB3BLBBBB", EAP_CODE_REQUEST, ctx['id'], 9894 4 + 1 + 3 + 4 + 4, 9895 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1, 9896 4, 0x01, 2, 3) 9897 9898 idx += 1 9899 if ctx['num'] == idx: 9900 logger.info("Test: Valid WSC Start to start the sequence") 9901 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'], 9902 4 + 1 + 3 + 4 + 2, 9903 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1, 9904 1, 0x00) 9905 idx += 1 9906 if ctx['num'] == idx: 9907 logger.info("Test: Unexpected Op-Code 5 in WAIT_FRAG_ACK state") 9908 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'], 9909 4 + 1 + 3 + 4 + 2, 9910 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1, 9911 5, 0x00) 9912 9913 idx += 1 9914 if ctx['num'] == idx: 9915 logger.info("Test: Valid WSC Start") 9916 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'], 9917 4 + 1 + 3 + 4 + 2, 9918 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1, 9919 1, 0x00) 9920 idx += 1 9921 if ctx['num'] == idx: 9922 logger.info("No more test responses available - test case completed") 9923 global eap_proto_wsc_test_done 9924 eap_proto_wsc_test_done = True 9925 eap_proto_wsc_wait_failure = True 9926 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9927 9928 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9929 9930 srv = start_radius_server(wsc_handler) 9931 9932 try: 9933 hapd = start_ap(apdev[0]) 9934 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 9935 9936 i = 0 9937 while not eap_proto_wsc_test_done: 9938 i += 1 9939 logger.info("Running connection iteration %d" % i) 9940 fragment_size = 1398 if i != 9 else 50 9941 dev[0].connect("eap-test", key_mgmt="WPA-EAP", eap="WSC", 9942 fragment_size=str(fragment_size), 9943 identity="WFA-SimpleConfig-Enrollee-1-0", 9944 phase1="pin=12345670", 9945 scan_freq="2412", wait_connect=False) 9946 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5) 9947 if ev is None: 9948 raise Exception("Timeout on EAP method start") 9949 if eap_proto_wsc_wait_failure: 9950 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5) 9951 if ev is None: 9952 raise Exception("Timeout on EAP failure") 9953 else: 9954 time.sleep(0.1) 9955 dev[0].request("REMOVE_NETWORK all") 9956 dev[0].wait_disconnected(timeout=1) 9957 dev[0].dump_monitor() 9958 finally: 9959 stop_radius_server(srv) 9960 9961def test_eap_canned_success_before_method(dev, apdev): 9962 """EAP protocol tests for canned EAP-Success before any method""" 9963 params = int_eap_server_params() 9964 hapd = hostapd.add_ap(apdev[0], params) 9965 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 9966 bssid = apdev[0]['bssid'] 9967 hapd.request("SET ext_eapol_frame_io 1") 9968 9969 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412", 9970 phase1="allow_canned_success=1", 9971 eap="MD5", identity="user", password="password", 9972 wait_connect=False) 9973 9974 ev = hapd.wait_event(["EAPOL-TX"], timeout=10) 9975 if ev is None: 9976 raise Exception("Timeout on EAPOL-TX from hostapd") 9977 9978 res = dev[0].request("EAPOL_RX " + bssid + " 0200000403020004") 9979 if "OK" not in res: 9980 raise Exception("EAPOL_RX to wpa_supplicant failed") 9981 9982 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=5) 9983 if ev is None: 9984 raise Exception("Timeout on EAP success") 9985 dev[0].request("REMOVE_NETWORK all") 9986 dev[0].wait_disconnected() 9987 9988def test_eap_canned_failure_before_method(dev, apdev): 9989 """EAP protocol tests for canned EAP-Failure before any method""" 9990 params = int_eap_server_params() 9991 hapd = hostapd.add_ap(apdev[0], params) 9992 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 9993 bssid = apdev[0]['bssid'] 9994 hapd.request("SET ext_eapol_frame_io 1") 9995 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412", 9996 phase1="allow_canned_success=1", 9997 eap="MD5", identity="user", password="password", 9998 wait_connect=False) 9999 10000 ev = hapd.wait_event(["EAPOL-TX"], timeout=10) 10001 if ev is None: 10002 raise Exception("Timeout on EAPOL-TX from hostapd") 10003 10004 res = dev[0].request("EAPOL_RX " + bssid + " 0200000404020004") 10005 if "OK" not in res: 10006 raise Exception("EAPOL_RX to wpa_supplicant failed") 10007 10008 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5) 10009 if ev is None: 10010 raise Exception("Timeout on EAP failure") 10011 dev[0].request("REMOVE_NETWORK all") 10012 dev[0].wait_disconnected() 10013 10014def test_eap_nak_oom(dev, apdev): 10015 """EAP-Nak OOM""" 10016 check_eap_capa(dev[0], "MD5") 10017 params = hostapd.wpa2_eap_params(ssid="eap-test") 10018 hapd = hostapd.add_ap(apdev[0], params) 10019 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 10020 with alloc_fail(dev[0], 1, "eap_msg_alloc;eap_sm_buildNak"): 10021 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 10022 eap="MD5", identity="sake user", password="password", 10023 wait_connect=False) 10024 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 10025 dev[0].request("REMOVE_NETWORK all") 10026 dev[0].wait_disconnected() 10027 10028def test_eap_nak_expanded(dev, apdev): 10029 """EAP-Nak with expanded method""" 10030 check_eap_capa(dev[0], "MD5") 10031 check_eap_capa(dev[0], "VENDOR-TEST") 10032 params = hostapd.wpa2_eap_params(ssid="eap-test") 10033 hapd = hostapd.add_ap(apdev[0], params) 10034 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 10035 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 10036 eap="VENDOR-TEST WSC", 10037 identity="sake user", password="password", 10038 wait_connect=False) 10039 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=10) 10040 if ev is None or "NAK" not in ev: 10041 raise Exception("No NAK event seen") 10042 10043 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10) 10044 if ev is None: 10045 raise Exception("No EAP-Failure seen") 10046 10047 dev[0].request("REMOVE_NETWORK all") 10048 dev[0].wait_disconnected() 10049 10050EAP_TLV_RESULT_TLV = 3 10051EAP_TLV_NAK_TLV = 4 10052EAP_TLV_ERROR_CODE_TLV = 5 10053EAP_TLV_CONNECTION_BINDING_TLV = 6 10054EAP_TLV_VENDOR_SPECIFIC_TLV = 7 10055EAP_TLV_URI_TLV = 8 10056EAP_TLV_EAP_PAYLOAD_TLV = 9 10057EAP_TLV_INTERMEDIATE_RESULT_TLV = 10 10058EAP_TLV_PAC_TLV = 11 10059EAP_TLV_CRYPTO_BINDING_TLV = 12 10060EAP_TLV_CALLING_STATION_ID_TLV = 13 10061EAP_TLV_CALLED_STATION_ID_TLV = 14 10062EAP_TLV_NAS_PORT_TYPE_TLV = 15 10063EAP_TLV_SERVER_IDENTIFIER_TLV = 16 10064EAP_TLV_IDENTITY_TYPE_TLV = 17 10065EAP_TLV_SERVER_TRUSTED_ROOT_TLV = 18 10066EAP_TLV_REQUEST_ACTION_TLV = 19 10067EAP_TLV_PKCS7_TLV = 20 10068 10069EAP_TLV_RESULT_SUCCESS = 1 10070EAP_TLV_RESULT_FAILURE = 2 10071 10072EAP_TLV_TYPE_MANDATORY = 0x8000 10073EAP_TLV_TYPE_MASK = 0x3fff 10074 10075PAC_TYPE_PAC_KEY = 1 10076PAC_TYPE_PAC_OPAQUE = 2 10077PAC_TYPE_CRED_LIFETIME = 3 10078PAC_TYPE_A_ID = 4 10079PAC_TYPE_I_ID = 5 10080PAC_TYPE_A_ID_INFO = 7 10081PAC_TYPE_PAC_ACKNOWLEDGEMENT = 8 10082PAC_TYPE_PAC_INFO = 9 10083PAC_TYPE_PAC_TYPE = 10 10084 10085def eap_fast_start(ctx): 10086 logger.info("Send EAP-FAST/Start") 10087 return struct.pack(">BBHBBHH", EAP_CODE_REQUEST, ctx['id'], 10088 4 + 1 + 1 + 4 + 16, 10089 EAP_TYPE_FAST, 0x21, 4, 16) + 16*b'A' 10090 10091def test_eap_fast_proto(dev, apdev): 10092 """EAP-FAST Phase protocol testing""" 10093 check_eap_capa(dev[0], "FAST") 10094 global eap_fast_proto_ctx 10095 eap_fast_proto_ctx = None 10096 10097 def eap_handler(ctx, req): 10098 logger.info("eap_handler - RX " + binascii.hexlify(req).decode()) 10099 if 'num' not in ctx: 10100 ctx['num'] = 0 10101 ctx['num'] = ctx['num'] + 1 10102 if 'id' not in ctx: 10103 ctx['id'] = 1 10104 ctx['id'] = (ctx['id'] + 1) % 256 10105 idx = 0 10106 10107 global eap_fast_proto_ctx 10108 eap_fast_proto_ctx = ctx 10109 ctx['test_done'] = False 10110 10111 idx += 1 10112 if ctx['num'] == idx: 10113 return eap_fast_start(ctx) 10114 idx += 1 10115 if ctx['num'] == idx: 10116 logger.info("EAP-FAST: TLS processing failed") 10117 data = b'ABCDEFGHIK' 10118 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 10119 4 + 1 + 1 + len(data), 10120 EAP_TYPE_FAST, 0x01) + data 10121 idx += 1 10122 if ctx['num'] == idx: 10123 ctx['test_done'] = True 10124 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 10125 10126 logger.info("Past last test case") 10127 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 10128 10129 srv = start_radius_server(eap_handler) 10130 try: 10131 hapd = start_ap(apdev[0]) 10132 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 10133 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 10134 eap="FAST", anonymous_identity="FAST", 10135 identity="user", password="password", 10136 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2", 10137 phase1="fast_provisioning=1", 10138 pac_file="blob://fast_pac_proto", 10139 wait_connect=False) 10140 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5) 10141 if ev is None: 10142 raise Exception("Could not start EAP-FAST") 10143 ok = False 10144 for i in range(100): 10145 if eap_fast_proto_ctx: 10146 if eap_fast_proto_ctx['test_done']: 10147 ok = True 10148 break 10149 time.sleep(0.05) 10150 dev[0].request("REMOVE_NETWORK all") 10151 dev[0].wait_disconnected() 10152 finally: 10153 stop_radius_server(srv) 10154 10155def run_eap_fast_phase2(dev, test_payload, test_failure=True): 10156 global eap_fast_proto_ctx 10157 eap_fast_proto_ctx = None 10158 10159 def ssl_info_callback(conn, where, ret): 10160 logger.debug("SSL: info where=%d ret=%d" % (where, ret)) 10161 10162 def log_conn_state(conn): 10163 try: 10164 state = conn.state_string() 10165 except AttributeError: 10166 state = conn.get_state_string() 10167 if state: 10168 logger.info("State: " + str(state)) 10169 10170 def process_clienthello(ctx, payload): 10171 logger.info("Process ClientHello") 10172 ctx['sslctx'] = OpenSSL.SSL.Context(OpenSSL.SSL.TLSv1_METHOD) 10173 ctx['sslctx'].set_info_callback(ssl_info_callback) 10174 ctx['sslctx'].load_tmp_dh("auth_serv/dh.conf") 10175 if OpenSSL.SSL.OPENSSL_VERSION_NUMBER >= 0x10100000: 10176 ctx['sslctx'].set_cipher_list("ADH-AES128-SHA:@SECLEVEL=0") 10177 else: 10178 ctx['sslctx'].set_cipher_list("ADH-AES128-SHA") 10179 ctx['conn'] = OpenSSL.SSL.Connection(ctx['sslctx'], None) 10180 ctx['conn'].set_accept_state() 10181 log_conn_state(ctx['conn']) 10182 ctx['conn'].bio_write(payload) 10183 try: 10184 ctx['conn'].do_handshake() 10185 except OpenSSL.SSL.WantReadError: 10186 pass 10187 log_conn_state(ctx['conn']) 10188 data = ctx['conn'].bio_read(4096) 10189 log_conn_state(ctx['conn']) 10190 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 10191 4 + 1 + 1 + len(data), 10192 EAP_TYPE_FAST, 0x01) + data 10193 10194 def process_clientkeyexchange(ctx, payload, appl_data): 10195 logger.info("Process ClientKeyExchange") 10196 log_conn_state(ctx['conn']) 10197 ctx['conn'].bio_write(payload) 10198 try: 10199 ctx['conn'].do_handshake() 10200 except OpenSSL.SSL.WantReadError: 10201 pass 10202 ctx['conn'].send(appl_data) 10203 log_conn_state(ctx['conn']) 10204 data = ctx['conn'].bio_read(4096) 10205 log_conn_state(ctx['conn']) 10206 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 10207 4 + 1 + 1 + len(data), 10208 EAP_TYPE_FAST, 0x01) + data 10209 10210 def eap_handler(ctx, req): 10211 logger.info("eap_handler - RX " + binascii.hexlify(req).decode()) 10212 if 'num' not in ctx: 10213 ctx['num'] = 0 10214 ctx['num'] = ctx['num'] + 1 10215 if 'id' not in ctx: 10216 ctx['id'] = 1 10217 ctx['id'] = (ctx['id'] + 1) % 256 10218 idx = 0 10219 10220 global eap_fast_proto_ctx 10221 eap_fast_proto_ctx = ctx 10222 ctx['test_done'] = False 10223 logger.debug("ctx['num']=%d" % ctx['num']) 10224 10225 idx += 1 10226 if ctx['num'] == idx: 10227 return eap_fast_start(ctx) 10228 idx += 1 10229 if ctx['num'] == idx: 10230 return process_clienthello(ctx, req[6:]) 10231 idx += 1 10232 if ctx['num'] == idx: 10233 if not test_failure: 10234 ctx['test_done'] = True 10235 return process_clientkeyexchange(ctx, req[6:], test_payload) 10236 idx += 1 10237 if ctx['num'] == idx: 10238 ctx['test_done'] = True 10239 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 10240 10241 logger.info("Past last test case") 10242 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 10243 10244 srv = start_radius_server(eap_handler) 10245 try: 10246 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 10247 eap="FAST", anonymous_identity="FAST", 10248 identity="user", password="password", 10249 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2", 10250 phase1="fast_provisioning=1", 10251 pac_file="blob://fast_pac_proto", 10252 wait_connect=False) 10253 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5) 10254 if ev is None: 10255 raise Exception("Could not start EAP-FAST") 10256 dev[0].dump_monitor() 10257 ok = False 10258 for i in range(100): 10259 if eap_fast_proto_ctx: 10260 if eap_fast_proto_ctx['test_done']: 10261 ok = True 10262 break 10263 time.sleep(0.05) 10264 time.sleep(0.1) 10265 dev[0].request("REMOVE_NETWORK all") 10266 dev[0].wait_disconnected() 10267 if not ok: 10268 raise Exception("EAP-FAST TLS exchange did not complete") 10269 for i in range(3): 10270 dev[i].dump_monitor() 10271 finally: 10272 stop_radius_server(srv) 10273 10274def test_eap_fast_proto_phase2(dev, apdev): 10275 """EAP-FAST Phase 2 protocol testing""" 10276 if not openssl_imported: 10277 raise HwsimSkip("OpenSSL python method not available") 10278 check_eap_capa(dev[0], "FAST") 10279 hapd = start_ap(apdev[0]) 10280 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 10281 10282 tests = [("Too short Phase 2 TLV frame (len=3)", 10283 "ABC", 10284 False), 10285 ("EAP-FAST: TLV overflow", 10286 struct.pack(">HHB", 0, 2, 0xff), 10287 False), 10288 ("EAP-FAST: Unknown TLV (optional and mandatory)", 10289 struct.pack(">HHB", 0, 1, 0xff) + 10290 struct.pack(">HHB", EAP_TLV_TYPE_MANDATORY, 1, 0xff), 10291 True), 10292 ("EAP-FAST: More than one EAP-Payload TLV in the message", 10293 struct.pack(">HHBHHB", 10294 EAP_TLV_EAP_PAYLOAD_TLV, 1, 0xff, 10295 EAP_TLV_EAP_PAYLOAD_TLV, 1, 0xff), 10296 True), 10297 ("EAP-FAST: Unknown Result 255 and More than one Result TLV in the message", 10298 struct.pack(">HHHHHH", 10299 EAP_TLV_RESULT_TLV, 2, 0xff, 10300 EAP_TLV_RESULT_TLV, 2, 0xff), 10301 True), 10302 ("EAP-FAST: Too short Result TLV", 10303 struct.pack(">HHB", EAP_TLV_RESULT_TLV, 1, 0xff), 10304 True), 10305 ("EAP-FAST: Unknown Intermediate Result 255 and More than one Intermediate-Result TLV in the message", 10306 struct.pack(">HHHHHH", 10307 EAP_TLV_INTERMEDIATE_RESULT_TLV, 2, 0xff, 10308 EAP_TLV_INTERMEDIATE_RESULT_TLV, 2, 0xff), 10309 True), 10310 ("EAP-FAST: Too short Intermediate-Result TLV", 10311 struct.pack(">HHB", EAP_TLV_INTERMEDIATE_RESULT_TLV, 1, 0xff), 10312 True), 10313 ("EAP-FAST: More than one Crypto-Binding TLV in the message", 10314 struct.pack(">HH", EAP_TLV_CRYPTO_BINDING_TLV, 60) + 60*b'A' + 10315 struct.pack(">HH", EAP_TLV_CRYPTO_BINDING_TLV, 60) + 60*b'A', 10316 True), 10317 ("EAP-FAST: Too short Crypto-Binding TLV", 10318 struct.pack(">HHB", EAP_TLV_CRYPTO_BINDING_TLV, 1, 0xff), 10319 True), 10320 ("EAP-FAST: More than one Request-Action TLV in the message", 10321 struct.pack(">HHBBHHBB", 10322 EAP_TLV_REQUEST_ACTION_TLV, 2, 0xff, 0xff, 10323 EAP_TLV_REQUEST_ACTION_TLV, 2, 0xff, 0xff), 10324 True), 10325 ("EAP-FAST: Too short Request-Action TLV", 10326 struct.pack(">HHB", EAP_TLV_REQUEST_ACTION_TLV, 1, 0xff), 10327 True), 10328 ("EAP-FAST: More than one PAC TLV in the message", 10329 struct.pack(">HHBHHB", 10330 EAP_TLV_PAC_TLV, 1, 0xff, 10331 EAP_TLV_PAC_TLV, 1, 0xff), 10332 True), 10333 ("EAP-FAST: Too short EAP Payload TLV (Len=3)", 10334 struct.pack(">HH3B", 10335 EAP_TLV_EAP_PAYLOAD_TLV, 3, 0, 0, 0), 10336 False), 10337 ("EAP-FAST: Too short Phase 2 request (Len=0)", 10338 struct.pack(">HHBBH", 10339 EAP_TLV_EAP_PAYLOAD_TLV, 4, 10340 EAP_CODE_REQUEST, 0, 0), 10341 False), 10342 ("EAP-FAST: EAP packet overflow in EAP Payload TLV", 10343 struct.pack(">HHBBH", 10344 EAP_TLV_EAP_PAYLOAD_TLV, 4, 10345 EAP_CODE_REQUEST, 0, 4 + 1), 10346 False), 10347 ("EAP-FAST: Unexpected code=0 in Phase 2 EAP header", 10348 struct.pack(">HHBBH", 10349 EAP_TLV_EAP_PAYLOAD_TLV, 4, 10350 0, 0, 0), 10351 False), 10352 ("EAP-FAST: PAC TLV without Result TLV acknowledging success", 10353 struct.pack(">HHB", EAP_TLV_PAC_TLV, 1, 0xff), 10354 True), 10355 ("EAP-FAST: PAC TLV does not include all the required fields", 10356 struct.pack(">HHH", EAP_TLV_RESULT_TLV, 2, 10357 EAP_TLV_RESULT_SUCCESS) + 10358 struct.pack(">HHB", EAP_TLV_PAC_TLV, 1, 0xff), 10359 True), 10360 ("EAP-FAST: Invalid PAC-Key length 0, Ignored unknown PAC type 0, and PAC TLV overrun (type=0 len=2 left=1)", 10361 struct.pack(">HHH", EAP_TLV_RESULT_TLV, 2, 10362 EAP_TLV_RESULT_SUCCESS) + 10363 struct.pack(">HHHHHHHHB", EAP_TLV_PAC_TLV, 4 + 4 + 5, 10364 PAC_TYPE_PAC_KEY, 0, 0, 0, 0, 2, 0), 10365 True), 10366 ("EAP-FAST: PAC-Info does not include all the required fields", 10367 struct.pack(">HHH", EAP_TLV_RESULT_TLV, 2, 10368 EAP_TLV_RESULT_SUCCESS) + 10369 struct.pack(">HHHHHHHH", EAP_TLV_PAC_TLV, 4 + 4 + 4 + 32, 10370 PAC_TYPE_PAC_OPAQUE, 0, 10371 PAC_TYPE_PAC_INFO, 0, 10372 PAC_TYPE_PAC_KEY, 32) + 32*b'A', 10373 True), 10374 ("EAP-FAST: Invalid CRED_LIFETIME length, Ignored unknown PAC-Info type 0, and Invalid PAC-Type length 1", 10375 struct.pack(">HHH", EAP_TLV_RESULT_TLV, 2, 10376 EAP_TLV_RESULT_SUCCESS) + 10377 struct.pack(">HHHHHHHHHHHHBHH", EAP_TLV_PAC_TLV, 4 + 4 + 13 + 4 + 32, 10378 PAC_TYPE_PAC_OPAQUE, 0, 10379 PAC_TYPE_PAC_INFO, 13, PAC_TYPE_CRED_LIFETIME, 0, 10380 0, 0, PAC_TYPE_PAC_TYPE, 1, 0, 10381 PAC_TYPE_PAC_KEY, 32) + 32*b'A', 10382 True), 10383 ("EAP-FAST: Unsupported PAC-Type 0", 10384 struct.pack(">HHH", EAP_TLV_RESULT_TLV, 2, 10385 EAP_TLV_RESULT_SUCCESS) + 10386 struct.pack(">HHHHHHHHHHH", EAP_TLV_PAC_TLV, 4 + 4 + 6 + 4 + 32, 10387 PAC_TYPE_PAC_OPAQUE, 0, 10388 PAC_TYPE_PAC_INFO, 6, PAC_TYPE_PAC_TYPE, 2, 0, 10389 PAC_TYPE_PAC_KEY, 32) + 32*b'A', 10390 True), 10391 ("EAP-FAST: PAC-Info overrun (type=0 len=2 left=1)", 10392 struct.pack(">HHH", EAP_TLV_RESULT_TLV, 2, 10393 EAP_TLV_RESULT_SUCCESS) + 10394 struct.pack(">HHHHHHHHBHH", EAP_TLV_PAC_TLV, 4 + 4 + 5 + 4 + 32, 10395 PAC_TYPE_PAC_OPAQUE, 0, 10396 PAC_TYPE_PAC_INFO, 5, 0, 2, 1, 10397 PAC_TYPE_PAC_KEY, 32) + 32*b'A', 10398 True), 10399 ("EAP-FAST: Valid PAC", 10400 struct.pack(">HHH", EAP_TLV_RESULT_TLV, 2, 10401 EAP_TLV_RESULT_SUCCESS) + 10402 struct.pack(">HHHHHHHHBHHBHH", EAP_TLV_PAC_TLV, 10403 4 + 4 + 10 + 4 + 32, 10404 PAC_TYPE_PAC_OPAQUE, 0, 10405 PAC_TYPE_PAC_INFO, 10, PAC_TYPE_A_ID, 1, 0x41, 10406 PAC_TYPE_A_ID_INFO, 1, 0x42, 10407 PAC_TYPE_PAC_KEY, 32) + 32*b'A', 10408 True), 10409 ("EAP-FAST: Invalid version/subtype in Crypto-Binding TLV", 10410 struct.pack(">HH", EAP_TLV_CRYPTO_BINDING_TLV, 60) + 60*b'A', 10411 True)] 10412 for title, payload, failure in tests: 10413 logger.info("Phase 2 test: " + title) 10414 run_eap_fast_phase2(dev, payload, failure) 10415 10416def test_eap_fast_tlv_nak_oom(dev, apdev): 10417 """EAP-FAST Phase 2 TLV NAK OOM""" 10418 if not openssl_imported: 10419 raise HwsimSkip("OpenSSL python method not available") 10420 check_eap_capa(dev[0], "FAST") 10421 hapd = start_ap(apdev[0]) 10422 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 10423 10424 with alloc_fail(dev[0], 1, "eap_fast_tlv_nak"): 10425 run_eap_fast_phase2(dev, struct.pack(">HHB", EAP_TLV_TYPE_MANDATORY, 10426 1, 0xff), False) 10427