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): 86 hmac_obj = hmac.new(reply.secret, digestmod=hashlib.md5) 87 hmac_obj.update(struct.pack("B", reply.code)) 88 hmac_obj.update(struct.pack("B", reply.id)) 89 90 reply.AddAttribute("Message-Authenticator", 16*b'\x00') 91 attrs = reply._PktEncodeAttributes() 92 93 # Length 94 flen = 4 + 16 + len(attrs) 95 hmac_obj.update(struct.pack(">H", flen)) 96 hmac_obj.update(pkt.authenticator) 97 hmac_obj.update(attrs) 98 del reply[80] 99 add_message_authenticator_attr(reply, hmac_obj.digest()) 100 101def run_pyrad_server(srv, t_stop, eap_handler): 102 srv.RunWithStop(t_stop, eap_handler) 103 104def start_radius_server(eap_handler): 105 try: 106 import pyrad.server 107 import pyrad.packet 108 import pyrad.dictionary 109 except ImportError: 110 raise HwsimSkip("No pyrad modules available") 111 112 class TestServer(pyrad.server.Server): 113 def _HandleAuthPacket(self, pkt): 114 pyrad.server.Server._HandleAuthPacket(self, pkt) 115 eap = b'' 116 for p in pkt[79]: 117 eap += p 118 eap_req = self.eap_handler(self.ctx, eap) 119 reply = self.CreateReplyPacket(pkt) 120 if eap_req: 121 while True: 122 if len(eap_req) > 253: 123 reply.AddAttribute("EAP-Message", eap_req[0:253]) 124 eap_req = eap_req[253:] 125 else: 126 reply.AddAttribute("EAP-Message", eap_req) 127 break 128 else: 129 logger.info("No EAP request available") 130 reply.code = pyrad.packet.AccessChallenge 131 132 # reply attributes 133 build_message_auth(pkt, reply) 134 135 self.SendReplyPacket(pkt.fd, reply) 136 137 def RunWithStop(self, t_stop, eap_handler): 138 self._poll = select.poll() 139 self._fdmap = {} 140 self._PrepareSockets() 141 self.t_stop = t_stop 142 self.eap_handler = eap_handler 143 self.ctx = {} 144 145 while not t_stop.is_set(): 146 for (fd, event) in self._poll.poll(200): 147 if event == select.POLLIN: 148 try: 149 fdo = self._fdmap[fd] 150 self._ProcessInput(fdo) 151 except pyrad.server.ServerPacketError as err: 152 logger.info("pyrad server dropping packet: " + str(err)) 153 except pyrad.packet.PacketError as err: 154 logger.info("pyrad server received invalid packet: " + str(err)) 155 else: 156 logger.error("Unexpected event in pyrad server main loop") 157 158 for fd in self.authfds + self.acctfds: 159 fd.close() 160 161 srv = TestServer(dict=pyrad.dictionary.Dictionary("dictionary.radius"), 162 authport=18138, acctport=18139) 163 srv.hosts["127.0.0.1"] = pyrad.server.RemoteHost("127.0.0.1", 164 b"radius", 165 "localhost") 166 srv.BindToAddress("127.0.0.1") 167 t_stop = threading.Event() 168 t = threading.Thread(target=run_pyrad_server, args=(srv, t_stop, eap_handler)) 169 t.start() 170 171 return {'srv': srv, 'stop': t_stop, 'thread': t} 172 173def stop_radius_server(srv): 174 srv['stop'].set() 175 srv['thread'].join() 176 177def start_ap(ap): 178 params = hostapd.wpa2_eap_params(ssid="eap-test") 179 params['auth_server_port'] = "18138" 180 hapd = hostapd.add_ap(ap, params) 181 return hapd 182 183def test_eap_proto(dev, apdev): 184 """EAP protocol tests""" 185 check_eap_capa(dev[0], "MD5") 186 def eap_handler(ctx, req): 187 logger.info("eap_handler - RX " + binascii.hexlify(req).decode()) 188 if 'num' not in ctx: 189 ctx['num'] = 0 190 ctx['num'] = ctx['num'] + 1 191 if 'id' not in ctx: 192 ctx['id'] = 1 193 ctx['id'] = (ctx['id'] + 1) % 256 194 idx = 0 195 196 idx += 1 197 if ctx['num'] == idx: 198 logger.info("Test: MD5 challenge") 199 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 200 4 + 1 + 3, 201 EAP_TYPE_MD5, 202 1, 0xaa, ord('n')) 203 idx += 1 204 if ctx['num'] == idx: 205 logger.info("Test: EAP-Success - id off by 2") 206 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'] + 1, 4) 207 208 idx += 1 209 if ctx['num'] == idx: 210 logger.info("Test: MD5 challenge") 211 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 212 4 + 1 + 3, 213 EAP_TYPE_MD5, 214 1, 0xaa, ord('n')) 215 idx += 1 216 if ctx['num'] == idx: 217 logger.info("Test: EAP-Success - id off by 3") 218 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'] + 2, 4) 219 220 idx += 1 221 if ctx['num'] == idx: 222 logger.info("Test: MD5 challenge") 223 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 224 4 + 1 + 3, 225 EAP_TYPE_MD5, 226 1, 0xaa, ord('n')) 227 idx += 1 228 if ctx['num'] == idx: 229 logger.info("Test: EAP-Notification/Request") 230 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 231 4 + 1 + 1, 232 EAP_TYPE_NOTIFICATION, 233 ord('A')) 234 idx += 1 235 if ctx['num'] == idx: 236 logger.info("Test: EAP-Success") 237 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'] - 1, 4) 238 239 idx += 1 240 if ctx['num'] == idx: 241 logger.info("Test: EAP-Notification/Request") 242 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 243 4 + 1 + 1, 244 EAP_TYPE_NOTIFICATION, 245 ord('B')) 246 idx += 1 247 if ctx['num'] == idx: 248 logger.info("Test: MD5 challenge") 249 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 250 4 + 1 + 3, 251 EAP_TYPE_MD5, 252 1, 0xaa, ord('n')) 253 idx += 1 254 if ctx['num'] == idx: 255 logger.info("Test: EAP-Success") 256 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'] - 1, 4) 257 258 idx += 1 259 if ctx['num'] == idx: 260 logger.info("Test: EAP-Notification/Request") 261 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 262 4 + 1 + 1, 263 EAP_TYPE_NOTIFICATION, 264 ord('C')) 265 idx += 1 266 if ctx['num'] == idx: 267 logger.info("Test: MD5 challenge") 268 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 269 4 + 1 + 3, 270 EAP_TYPE_MD5, 271 1, 0xaa, ord('n')) 272 idx += 1 273 if ctx['num'] == idx: 274 logger.info("Test: EAP-Notification/Request") 275 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 276 4 + 1 + 1, 277 EAP_TYPE_NOTIFICATION, 278 ord('D')) 279 idx += 1 280 if ctx['num'] == idx: 281 logger.info("Test: EAP-Success") 282 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'] - 1, 4) 283 284 idx += 1 285 if ctx['num'] == idx: 286 logger.info("Test: EAP-Notification/Request") 287 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 288 4 + 1 + 1, 289 EAP_TYPE_NOTIFICATION, 290 ord('E')) 291 idx += 1 292 if ctx['num'] == idx: 293 logger.info("Test: EAP-Notification/Request (same id)") 294 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'] - 1, 295 4 + 1 + 1, 296 EAP_TYPE_NOTIFICATION, 297 ord('F')) 298 idx += 1 299 if ctx['num'] == idx: 300 logger.info("Test: Unexpected EAP-Success") 301 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'] - 2, 4) 302 303 return None 304 305 srv = start_radius_server(eap_handler) 306 307 try: 308 hapd = start_ap(apdev[0]) 309 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 310 311 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 312 eap="MD5", identity="user", password="password", 313 wait_connect=False) 314 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15) 315 if ev is None: 316 raise Exception("Timeout on EAP start") 317 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15) 318 if ev is None: 319 raise Exception("Timeout on EAP success") 320 dev[0].request("REMOVE_NETWORK all") 321 322 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 323 eap="MD5", identity="user", password="password", 324 wait_connect=False) 325 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15) 326 if ev is None: 327 raise Exception("Timeout on EAP start") 328 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=1) 329 if ev is not None: 330 raise Exception("Unexpected EAP success") 331 dev[0].request("REMOVE_NETWORK all") 332 333 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 334 eap="MD5", identity="user", password="password", 335 wait_connect=False) 336 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15) 337 if ev is None: 338 raise Exception("Timeout on EAP start") 339 ev = dev[0].wait_event(["CTRL-EVENT-EAP-NOTIFICATION"], timeout=10) 340 if ev is None: 341 raise Exception("Timeout on EAP notification") 342 if ev != "<3>CTRL-EVENT-EAP-NOTIFICATION A": 343 raise Exception("Unexpected notification contents: " + ev) 344 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15) 345 if ev is None: 346 raise Exception("Timeout on EAP success") 347 dev[0].request("REMOVE_NETWORK all") 348 349 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 350 eap="MD5", identity="user", password="password", 351 wait_connect=False) 352 ev = dev[0].wait_event(["CTRL-EVENT-EAP-NOTIFICATION"], timeout=10) 353 if ev is None: 354 raise Exception("Timeout on EAP notification") 355 if ev != "<3>CTRL-EVENT-EAP-NOTIFICATION B": 356 raise Exception("Unexpected notification contents: " + ev) 357 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15) 358 if ev is None: 359 raise Exception("Timeout on EAP start") 360 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15) 361 if ev is None: 362 raise Exception("Timeout on EAP success") 363 dev[0].request("REMOVE_NETWORK all") 364 365 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 366 eap="MD5", identity="user", password="password", 367 wait_connect=False) 368 ev = dev[0].wait_event(["CTRL-EVENT-EAP-NOTIFICATION"], timeout=10) 369 if ev is None: 370 raise Exception("Timeout on EAP notification") 371 if ev != "<3>CTRL-EVENT-EAP-NOTIFICATION C": 372 raise Exception("Unexpected notification contents: " + ev) 373 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15) 374 if ev is None: 375 raise Exception("Timeout on EAP start") 376 ev = dev[0].wait_event(["CTRL-EVENT-EAP-NOTIFICATION"], timeout=10) 377 if ev is None: 378 raise Exception("Timeout on EAP notification") 379 if ev != "<3>CTRL-EVENT-EAP-NOTIFICATION D": 380 raise Exception("Unexpected notification contents: " + ev) 381 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15) 382 if ev is None: 383 raise Exception("Timeout on EAP success") 384 dev[0].request("REMOVE_NETWORK all") 385 386 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 387 eap="MD5", identity="user", password="password", 388 wait_connect=False) 389 ev = dev[0].wait_event(["CTRL-EVENT-EAP-NOTIFICATION"], timeout=10) 390 if ev is None: 391 raise Exception("Timeout on EAP notification") 392 if ev != "<3>CTRL-EVENT-EAP-NOTIFICATION E": 393 raise Exception("Unexpected notification contents: " + ev) 394 ev = dev[0].wait_event(["CTRL-EVENT-EAP-NOTIFICATION"], timeout=10) 395 if ev is None: 396 raise Exception("Timeout on EAP notification") 397 if ev != "<3>CTRL-EVENT-EAP-NOTIFICATION F": 398 raise Exception("Unexpected notification contents: " + ev) 399 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=15) 400 if ev is None: 401 raise Exception("Timeout on EAP failure") 402 dev[0].request("REMOVE_NETWORK all") 403 finally: 404 stop_radius_server(srv) 405 406def test_eap_proto_notification_errors(dev, apdev): 407 """EAP Notification errors""" 408 def eap_handler(ctx, req): 409 logger.info("eap_handler - RX " + binascii.hexlify(req).decode()) 410 if 'num' not in ctx: 411 ctx['num'] = 0 412 ctx['num'] = ctx['num'] + 1 413 if 'id' not in ctx: 414 ctx['id'] = 1 415 ctx['id'] = (ctx['id'] + 1) % 256 416 idx = 0 417 418 idx += 1 419 if ctx['num'] == idx: 420 logger.info("Test: MD5 challenge") 421 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 422 4 + 1 + 3, 423 EAP_TYPE_MD5, 424 1, 0xaa, ord('n')) 425 idx += 1 426 if ctx['num'] == idx: 427 logger.info("Test: EAP-Notification/Request") 428 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 429 4 + 1 + 1, 430 EAP_TYPE_NOTIFICATION, 431 ord('A')) 432 433 idx += 1 434 if ctx['num'] == idx: 435 logger.info("Test: MD5 challenge") 436 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 437 4 + 1 + 3, 438 EAP_TYPE_MD5, 439 1, 0xaa, ord('n')) 440 idx += 1 441 if ctx['num'] == idx: 442 logger.info("Test: EAP-Notification/Request") 443 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 444 4 + 1 + 1, 445 EAP_TYPE_NOTIFICATION, 446 ord('A')) 447 448 return None 449 450 srv = start_radius_server(eap_handler) 451 452 try: 453 hapd = start_ap(apdev[0]) 454 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 455 456 with alloc_fail(dev[0], 1, "eap_sm_processNotify"): 457 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 458 eap="MD5", identity="user", password="password", 459 wait_connect=False) 460 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 461 dev[0].request("REMOVE_NETWORK all") 462 dev[0].wait_disconnected() 463 464 with alloc_fail(dev[0], 1, "eap_msg_alloc;sm_EAP_NOTIFICATION_Enter"): 465 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 466 eap="MD5", identity="user", password="password", 467 wait_connect=False) 468 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 469 dev[0].request("REMOVE_NETWORK all") 470 dev[0].wait_disconnected() 471 finally: 472 stop_radius_server(srv) 473 474EAP_SAKE_VERSION = 2 475 476EAP_SAKE_SUBTYPE_CHALLENGE = 1 477EAP_SAKE_SUBTYPE_CONFIRM = 2 478EAP_SAKE_SUBTYPE_AUTH_REJECT = 3 479EAP_SAKE_SUBTYPE_IDENTITY = 4 480 481EAP_SAKE_AT_RAND_S = 1 482EAP_SAKE_AT_RAND_P = 2 483EAP_SAKE_AT_MIC_S = 3 484EAP_SAKE_AT_MIC_P = 4 485EAP_SAKE_AT_SERVERID = 5 486EAP_SAKE_AT_PEERID = 6 487EAP_SAKE_AT_SPI_S = 7 488EAP_SAKE_AT_SPI_P = 8 489EAP_SAKE_AT_ANY_ID_REQ = 9 490EAP_SAKE_AT_PERM_ID_REQ = 10 491EAP_SAKE_AT_ENCR_DATA = 128 492EAP_SAKE_AT_IV = 129 493EAP_SAKE_AT_PADDING = 130 494EAP_SAKE_AT_NEXT_TMPID = 131 495EAP_SAKE_AT_MSK_LIFE = 132 496 497def test_eap_proto_sake(dev, apdev): 498 """EAP-SAKE protocol tests""" 499 global eap_proto_sake_test_done 500 eap_proto_sake_test_done = False 501 502 def sake_challenge(ctx): 503 logger.info("Test: Challenge subtype") 504 return struct.pack(">BBHBBBBBBLLLL", EAP_CODE_REQUEST, ctx['id'], 505 4 + 1 + 3 + 18, 506 EAP_TYPE_SAKE, 507 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_CHALLENGE, 508 EAP_SAKE_AT_RAND_S, 18, 0, 0, 0, 0) 509 510 def sake_handler(ctx, req): 511 logger.info("sake_handler - RX " + binascii.hexlify(req).decode()) 512 if 'num' not in ctx: 513 ctx['num'] = 0 514 ctx['num'] += 1 515 if 'id' not in ctx: 516 ctx['id'] = 1 517 ctx['id'] = (ctx['id'] + 1) % 256 518 idx = 0 519 520 idx += 1 521 if ctx['num'] == idx: 522 logger.info("Test: Missing payload") 523 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 4 + 1, 524 EAP_TYPE_SAKE) 525 526 idx += 1 527 if ctx['num'] == idx: 528 logger.info("Test: Identity subtype without any attributes") 529 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 530 4 + 1 + 3, 531 EAP_TYPE_SAKE, 532 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_IDENTITY) 533 534 idx += 1 535 if ctx['num'] == idx: 536 logger.info("Test: Identity subtype") 537 return struct.pack(">BBHBBBBBBH", EAP_CODE_REQUEST, ctx['id'], 538 4 + 1 + 3 + 4, 539 EAP_TYPE_SAKE, 540 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_IDENTITY, 541 EAP_SAKE_AT_ANY_ID_REQ, 4, 0) 542 idx += 1 543 if ctx['num'] == idx: 544 logger.info("Test: Identity subtype (different session id)") 545 return struct.pack(">BBHBBBBBBH", EAP_CODE_REQUEST, ctx['id'], 546 4 + 1 + 3 + 4, 547 EAP_TYPE_SAKE, 548 EAP_SAKE_VERSION, 1, EAP_SAKE_SUBTYPE_IDENTITY, 549 EAP_SAKE_AT_PERM_ID_REQ, 4, 0) 550 551 idx += 1 552 if ctx['num'] == idx: 553 logger.info("Test: Identity subtype with too short attribute") 554 return struct.pack(">BBHBBBBBB", EAP_CODE_REQUEST, ctx['id'], 555 4 + 1 + 3 + 2, 556 EAP_TYPE_SAKE, 557 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_IDENTITY, 558 EAP_SAKE_AT_ANY_ID_REQ, 2) 559 560 idx += 1 561 if ctx['num'] == idx: 562 logger.info("Test: Identity subtype with truncated attribute") 563 return struct.pack(">BBHBBBBBB", EAP_CODE_REQUEST, ctx['id'], 564 4 + 1 + 3 + 2, 565 EAP_TYPE_SAKE, 566 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_IDENTITY, 567 EAP_SAKE_AT_ANY_ID_REQ, 4) 568 569 idx += 1 570 if ctx['num'] == idx: 571 logger.info("Test: Identity subtype with too short attribute header") 572 payload = struct.pack("B", EAP_SAKE_AT_ANY_ID_REQ) 573 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 574 4 + 1 + 3 + len(payload), 575 EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0, 576 EAP_SAKE_SUBTYPE_IDENTITY) + payload 577 578 idx += 1 579 if ctx['num'] == idx: 580 logger.info("Test: Identity subtype with AT_IV but not AT_ENCR_DATA") 581 payload = struct.pack("BB", EAP_SAKE_AT_IV, 2) 582 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 583 4 + 1 + 3 + len(payload), 584 EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0, 585 EAP_SAKE_SUBTYPE_IDENTITY) + payload 586 587 idx += 1 588 if ctx['num'] == idx: 589 logger.info("Test: Identity subtype with skippable and non-skippable unknown attribute") 590 payload = struct.pack("BBBB", 255, 2, 127, 2) 591 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 592 4 + 1 + 3 + len(payload), 593 EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0, 594 EAP_SAKE_SUBTYPE_IDENTITY) + payload 595 596 idx += 1 597 if ctx['num'] == idx: 598 logger.info("Test: Identity subtype: AT_RAND_P with invalid payload length") 599 payload = struct.pack("BB", EAP_SAKE_AT_RAND_P, 2) 600 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 601 4 + 1 + 3 + len(payload), 602 EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0, 603 EAP_SAKE_SUBTYPE_IDENTITY) + payload 604 605 idx += 1 606 if ctx['num'] == idx: 607 logger.info("Test: Identity subtype: AT_MIC_P with invalid payload length") 608 payload = struct.pack("BB", EAP_SAKE_AT_MIC_P, 2) 609 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 610 4 + 1 + 3 + len(payload), 611 EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0, 612 EAP_SAKE_SUBTYPE_IDENTITY) + payload 613 614 idx += 1 615 if ctx['num'] == idx: 616 logger.info("Test: Identity subtype: AT_PERM_ID_REQ with invalid payload length") 617 payload = struct.pack("BBBBBBBBBBBBBB", 618 EAP_SAKE_AT_SPI_S, 2, 619 EAP_SAKE_AT_SPI_P, 2, 620 EAP_SAKE_AT_ENCR_DATA, 2, 621 EAP_SAKE_AT_NEXT_TMPID, 2, 622 EAP_SAKE_AT_PERM_ID_REQ, 4, 0, 0, 623 EAP_SAKE_AT_PERM_ID_REQ, 2) 624 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 625 4 + 1 + 3 + len(payload), 626 EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0, 627 EAP_SAKE_SUBTYPE_IDENTITY) + payload 628 629 idx += 1 630 if ctx['num'] == idx: 631 logger.info("Test: Identity subtype: AT_PADDING") 632 payload = struct.pack("BBBBBB", 633 EAP_SAKE_AT_PADDING, 3, 0, 634 EAP_SAKE_AT_PADDING, 3, 1) 635 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 636 4 + 1 + 3 + len(payload), 637 EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0, 638 EAP_SAKE_SUBTYPE_IDENTITY) + payload 639 640 idx += 1 641 if ctx['num'] == idx: 642 logger.info("Test: Identity subtype: AT_MSK_LIFE") 643 payload = struct.pack(">BBLBBH", 644 EAP_SAKE_AT_MSK_LIFE, 6, 0, 645 EAP_SAKE_AT_MSK_LIFE, 4, 0) 646 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 647 4 + 1 + 3 + len(payload), 648 EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0, 649 EAP_SAKE_SUBTYPE_IDENTITY) + payload 650 651 idx += 1 652 if ctx['num'] == idx: 653 logger.info("Test: Identity subtype with invalid attribute length") 654 payload = struct.pack("BB", EAP_SAKE_AT_ANY_ID_REQ, 0) 655 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 656 4 + 1 + 3 + len(payload), 657 EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0, 658 EAP_SAKE_SUBTYPE_IDENTITY) + payload 659 660 idx += 1 661 if ctx['num'] == idx: 662 logger.info("Test: Unknown subtype") 663 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 664 4 + 1 + 3, 665 EAP_TYPE_SAKE, 666 EAP_SAKE_VERSION, 0, 123) 667 668 idx += 1 669 if ctx['num'] == idx: 670 logger.info("Test: Challenge subtype without any attributes") 671 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 672 4 + 1 + 3, 673 EAP_TYPE_SAKE, 674 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_CHALLENGE) 675 676 idx += 1 677 if ctx['num'] == idx: 678 logger.info("Test: Challenge subtype with too short AT_RAND_S") 679 return struct.pack(">BBHBBBBBB", EAP_CODE_REQUEST, ctx['id'], 680 4 + 1 + 3 + 2, 681 EAP_TYPE_SAKE, 682 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_CHALLENGE, 683 EAP_SAKE_AT_RAND_S, 2) 684 685 idx += 1 686 if ctx['num'] == idx: 687 return sake_challenge(ctx) 688 idx += 1 689 if ctx['num'] == idx: 690 logger.info("Test: Unexpected Identity subtype") 691 return struct.pack(">BBHBBBBBBH", EAP_CODE_REQUEST, ctx['id'], 692 4 + 1 + 3 + 4, 693 EAP_TYPE_SAKE, 694 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_IDENTITY, 695 EAP_SAKE_AT_ANY_ID_REQ, 4, 0) 696 697 idx += 1 698 if ctx['num'] == idx: 699 return sake_challenge(ctx) 700 idx += 1 701 if ctx['num'] == idx: 702 logger.info("Test: Unexpected Challenge subtype") 703 return struct.pack(">BBHBBBBBBLLLL", EAP_CODE_REQUEST, ctx['id'], 704 4 + 1 + 3 + 18, 705 EAP_TYPE_SAKE, 706 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_CHALLENGE, 707 EAP_SAKE_AT_RAND_S, 18, 0, 0, 0, 0) 708 709 idx += 1 710 if ctx['num'] == idx: 711 return sake_challenge(ctx) 712 idx += 1 713 if ctx['num'] == idx: 714 logger.info("Test: Confirm subtype without any attributes") 715 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 716 4 + 1 + 3, 717 EAP_TYPE_SAKE, 718 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_CONFIRM) 719 720 idx += 1 721 if ctx['num'] == idx: 722 return sake_challenge(ctx) 723 idx += 1 724 if ctx['num'] == idx: 725 logger.info("Test: Confirm subtype with too short AT_MIC_S") 726 return struct.pack(">BBHBBBBBB", EAP_CODE_REQUEST, ctx['id'], 727 4 + 1 + 3 + 2, 728 EAP_TYPE_SAKE, 729 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_CONFIRM, 730 EAP_SAKE_AT_MIC_S, 2) 731 732 idx += 1 733 if ctx['num'] == idx: 734 logger.info("Test: Unexpected Confirm subtype") 735 return struct.pack(">BBHBBBBBBLLLL", EAP_CODE_REQUEST, ctx['id'], 736 4 + 1 + 3 + 18, 737 EAP_TYPE_SAKE, 738 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_CONFIRM, 739 EAP_SAKE_AT_MIC_S, 18, 0, 0, 0, 0) 740 741 idx += 1 742 if ctx['num'] == idx: 743 return sake_challenge(ctx) 744 idx += 1 745 if ctx['num'] == idx: 746 logger.info("Test: Confirm subtype with incorrect AT_MIC_S") 747 return struct.pack(">BBHBBBBBBLLLL", EAP_CODE_REQUEST, ctx['id'], 748 4 + 1 + 3 + 18, 749 EAP_TYPE_SAKE, 750 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_CONFIRM, 751 EAP_SAKE_AT_MIC_S, 18, 0, 0, 0, 0) 752 753 global eap_proto_sake_test_done 754 if eap_proto_sake_test_done: 755 return sake_challenge(ctx) 756 757 logger.info("No more test responses available - test case completed") 758 eap_proto_sake_test_done = True 759 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 760 761 srv = start_radius_server(sake_handler) 762 763 try: 764 hapd = start_ap(apdev[0]) 765 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 766 767 while not eap_proto_sake_test_done: 768 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 769 eap="SAKE", identity="sake user", 770 password_hex="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", 771 wait_connect=False) 772 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15) 773 if ev is None: 774 raise Exception("Timeout on EAP start") 775 time.sleep(0.1) 776 dev[0].request("REMOVE_NETWORK all") 777 dev[0].dump_monitor() 778 779 logger.info("Too short password") 780 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 781 eap="SAKE", identity="sake user", 782 password_hex="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcd", 783 wait_connect=False) 784 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15) 785 if ev is None: 786 raise Exception("Timeout on EAP start") 787 start = os.times()[4] 788 while True: 789 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 790 timeout=0.1) 791 if ev is None: 792 break 793 now = os.times()[4] 794 if now - start > 0.1: 795 break 796 dev[0].dump_monitor() 797 798 dev[0].request("REMOVE_NETWORK all") 799 time.sleep(0.1) 800 dev[0].dump_monitor() 801 finally: 802 stop_radius_server(srv) 803 804def test_eap_proto_sake_errors(dev, apdev): 805 """EAP-SAKE local error cases""" 806 check_eap_capa(dev[0], "SAKE") 807 params = hostapd.wpa2_eap_params(ssid="eap-test") 808 hapd = hostapd.add_ap(apdev[0], params) 809 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 810 811 for i in range(1, 3): 812 with alloc_fail(dev[0], i, "eap_sake_init"): 813 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 814 eap="SAKE", identity="sake user", 815 password_hex="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", 816 wait_connect=False) 817 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"], 818 timeout=15) 819 if ev is None: 820 raise Exception("Timeout on EAP start") 821 dev[0].request("REMOVE_NETWORK all") 822 dev[0].wait_disconnected() 823 dev[0].dump_monitor() 824 825 tests = [(1, "eap_msg_alloc;eap_sake_build_msg;eap_sake_process_challenge"), 826 (1, "=eap_sake_process_challenge"), 827 (1, "eap_sake_compute_mic;eap_sake_process_challenge"), 828 (1, "eap_sake_build_msg;eap_sake_process_confirm"), 829 (1, "eap_sake_compute_mic;eap_sake_process_confirm"), 830 (2, "eap_sake_compute_mic;=eap_sake_process_confirm"), 831 (1, "eap_sake_getKey"), 832 (1, "eap_sake_get_emsk"), 833 (1, "eap_sake_get_session_id")] 834 for count, func in tests: 835 with alloc_fail(dev[0], count, func): 836 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 837 eap="SAKE", identity="sake user@domain", 838 password_hex="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", 839 erp="1", 840 wait_connect=False) 841 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 842 timeout=15) 843 if ev is None: 844 raise Exception("Timeout on EAP start") 845 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 846 dev[0].request("REMOVE_NETWORK all") 847 dev[0].wait_disconnected() 848 dev[0].dump_monitor() 849 850 tests = [(1, "os_get_random;eap_sake_process_challenge"), 851 (1, "eap_sake_derive_keys;eap_sake_process_challenge"), 852 (2, "eap_sake_derive_keys;eap_sake_process_challenge"), 853 (3, "eap_sake_derive_keys;eap_sake_process_challenge"), 854 (4, "eap_sake_derive_keys;eap_sake_process_challenge"), 855 (5, "eap_sake_derive_keys;eap_sake_process_challenge"), 856 (6, "eap_sake_derive_keys;eap_sake_process_challenge")] 857 for count, func in tests: 858 with fail_test(dev[0], count, func): 859 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 860 eap="SAKE", identity="sake user", 861 password_hex="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", 862 wait_connect=False) 863 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15) 864 if ev is None: 865 raise Exception("Timeout on EAP start") 866 wait_fail_trigger(dev[0], "GET_FAIL") 867 dev[0].request("REMOVE_NETWORK all") 868 dev[0].wait_disconnected() 869 dev[0].dump_monitor() 870 871def test_eap_proto_sake_errors2(dev, apdev): 872 """EAP-SAKE protocol tests (2)""" 873 def sake_handler(ctx, req): 874 logger.info("sake_handler - RX " + binascii.hexlify(req).decode()) 875 if 'num' not in ctx: 876 ctx['num'] = 0 877 ctx['num'] += 1 878 if 'id' not in ctx: 879 ctx['id'] = 1 880 ctx['id'] = (ctx['id'] + 1) % 256 881 idx = 0 882 883 idx += 1 884 if ctx['num'] == idx: 885 logger.info("Test: Identity subtype") 886 return struct.pack(">BBHBBBBBBH", EAP_CODE_REQUEST, ctx['id'], 887 4 + 1 + 3 + 4, 888 EAP_TYPE_SAKE, 889 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_IDENTITY, 890 EAP_SAKE_AT_ANY_ID_REQ, 4, 0) 891 892 srv = start_radius_server(sake_handler) 893 894 try: 895 hapd = start_ap(apdev[0]) 896 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 897 898 with alloc_fail(dev[0], 1, "eap_msg_alloc;eap_sake_build_msg;eap_sake_process_identity"): 899 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 900 eap="SAKE", identity="sake user", 901 password_hex="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", 902 wait_connect=False) 903 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 904 timeout=15) 905 if ev is None: 906 raise Exception("Timeout on EAP start") 907 dev[0].request("REMOVE_NETWORK all") 908 dev[0].wait_disconnected() 909 910 finally: 911 stop_radius_server(srv) 912 913def run_eap_sake_connect(dev): 914 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412", 915 eap="SAKE", identity="sake user", 916 password_hex="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", 917 wait_connect=False) 918 ev = dev.wait_event(["CTRL-EVENT-EAP-SUCCESS", "CTRL-EVENT-EAP-FAILURE", 919 "CTRL-EVENT-DISCONNECTED"], 920 timeout=1) 921 dev.request("REMOVE_NETWORK all") 922 if not ev or "CTRL-EVENT-DISCONNECTED" not in ev: 923 dev.wait_disconnected() 924 dev.dump_monitor() 925 926def test_eap_proto_sake_errors_server(dev, apdev): 927 """EAP-SAKE local error cases on server""" 928 check_eap_capa(dev[0], "SAKE") 929 params = int_eap_server_params() 930 params['erp_domain'] = 'example.com' 931 params['eap_server_erp'] = '1' 932 hapd = hostapd.add_ap(apdev[0], params) 933 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 934 935 tests = [(1, "eap_sake_init"), 936 (1, "eap_sake_build_msg;eap_sake_build_challenge"), 937 (1, "eap_sake_build_msg;eap_sake_build_confirm"), 938 (1, "eap_sake_compute_mic;eap_sake_build_confirm"), 939 (1, "eap_sake_process_challenge"), 940 (1, "eap_sake_getKey"), 941 (1, "eap_sake_get_emsk"), 942 (1, "eap_sake_get_session_id")] 943 for count, func in tests: 944 with alloc_fail(hapd, count, func): 945 run_eap_sake_connect(dev[0]) 946 947 tests = [(1, "eap_sake_init"), 948 (1, "eap_sake_build_challenge"), 949 (1, "eap_sake_build_confirm"), 950 (1, "eap_sake_derive_keys;eap_sake_process_challenge"), 951 (1, "eap_sake_compute_mic;eap_sake_process_challenge"), 952 (1, "eap_sake_compute_mic;eap_sake_process_confirm"), 953 (1, "eap_sake_compute_mic;eap_sake_build_confirm"), 954 (1, "eap_sake_process_confirm")] 955 for count, func in tests: 956 with fail_test(hapd, count, func): 957 run_eap_sake_connect(dev[0]) 958 959def start_sake_assoc(dev, hapd): 960 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412", 961 eap="SAKE", identity="sake user", 962 password_hex="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", 963 wait_connect=False) 964 proxy_msg(hapd, dev) # EAP-Identity/Request 965 proxy_msg(dev, hapd) # EAP-Identity/Response 966 proxy_msg(hapd, dev) # SAKE/Challenge/Request 967 968def stop_sake_assoc(dev, hapd): 969 dev.request("REMOVE_NETWORK all") 970 dev.wait_disconnected() 971 dev.dump_monitor() 972 hapd.dump_monitor() 973 974def test_eap_proto_sake_server(dev, apdev): 975 """EAP-SAKE protocol testing for the server""" 976 check_eap_capa(dev[0], "SAKE") 977 params = int_eap_server_params() 978 params['erp_domain'] = 'example.com' 979 params['eap_server_erp'] = '1' 980 hapd = hostapd.add_ap(apdev[0], params) 981 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 982 hapd.request("SET ext_eapol_frame_io 1") 983 dev[0].request("SET ext_eapol_frame_io 1") 984 985 # Successful exchange to verify proxying mechanism 986 start_sake_assoc(dev[0], hapd) 987 proxy_msg(dev[0], hapd) # SAKE/Challenge/Response 988 proxy_msg(hapd, dev[0]) # SAKE/Confirm/Request 989 proxy_msg(dev[0], hapd) # SAKE/Confirm/Response 990 proxy_msg(hapd, dev[0]) # EAP-Success 991 proxy_msg(hapd, dev[0]) # EAPOL-Key msg 1/4 992 proxy_msg(dev[0], hapd) # EAPOL-Key msg 2/4 993 proxy_msg(hapd, dev[0]) # EAPOL-Key msg 3/4 994 proxy_msg(dev[0], hapd) # EAPOL-Key msg 4/4 995 dev[0].wait_connected() 996 stop_sake_assoc(dev[0], hapd) 997 998 start_sake_assoc(dev[0], hapd) 999 resp = rx_msg(dev[0]) 1000 # Too short EAP-SAKE header 1001 # --> EAP-SAKE: Invalid frame 1002 msg = resp[0:4] + "0007" + resp[8:12] + "0007" + "300200" 1003 tx_msg(dev[0], hapd, msg) 1004 # Unknown version 1005 # --> EAP-SAKE: Unknown version 1 1006 msg = resp[0:4] + "0008" + resp[8:12] + "0008" + "30010000" 1007 tx_msg(dev[0], hapd, msg) 1008 # Unknown session 1009 # --> EAP-SAKE: Session ID mismatch 1010 sess, = struct.unpack('B', binascii.unhexlify(resp[20:22])) 1011 sess = binascii.hexlify(struct.pack('B', (sess + 1) % 256)).decode() 1012 msg = resp[0:4] + "0008" + resp[8:12] + "0008" + "3002" + sess + "00" 1013 tx_msg(dev[0], hapd, msg) 1014 # Unknown subtype 1015 # --> EAP-SAKE: Unexpected subtype=5 in state=1 1016 msg = resp[0:22] + "05" + resp[24:] 1017 tx_msg(dev[0], hapd, msg) 1018 # Empty challenge 1019 # --> EAP-SAKE: Response/Challenge did not include AT_RAND_P or AT_MIC_P 1020 msg = resp[0:4] + "0008" + resp[8:12] + "0008" + resp[16:24] 1021 tx_msg(dev[0], hapd, msg) 1022 rx_msg(hapd) 1023 stop_sake_assoc(dev[0], hapd) 1024 1025 start_sake_assoc(dev[0], hapd) 1026 resp = rx_msg(dev[0]) 1027 # Invalid attribute in challenge 1028 # --> EAP-SAKE: Too short attribute 1029 msg = resp[0:4] + "0009" + resp[8:12] + "0009" + resp[16:26] 1030 tx_msg(dev[0], hapd, msg) 1031 rx_msg(hapd) 1032 stop_sake_assoc(dev[0], hapd) 1033 1034 start_sake_assoc(dev[0], hapd) 1035 proxy_msg(dev[0], hapd) # SAKE/Challenge/Response 1036 proxy_msg(hapd, dev[0]) # SAKE/Confirm/Request 1037 resp = rx_msg(dev[0]) 1038 # Empty confirm 1039 # --> EAP-SAKE: Response/Confirm did not include AT_MIC_P 1040 msg = resp[0:4] + "0008" + resp[8:12] + "0008" + resp[16:26] 1041 tx_msg(dev[0], hapd, msg) 1042 rx_msg(hapd) 1043 stop_sake_assoc(dev[0], hapd) 1044 1045 start_sake_assoc(dev[0], hapd) 1046 proxy_msg(dev[0], hapd) # SAKE/Challenge/Response 1047 proxy_msg(hapd, dev[0]) # SAKE/Confirm/Request 1048 resp = rx_msg(dev[0]) 1049 # Invalid attribute in confirm 1050 # --> EAP-SAKE: Too short attribute 1051 msg = resp[0:4] + "0009" + resp[8:12] + "0009" + resp[16:26] 1052 tx_msg(dev[0], hapd, msg) 1053 rx_msg(hapd) 1054 stop_sake_assoc(dev[0], hapd) 1055 1056 start_sake_assoc(dev[0], hapd) 1057 proxy_msg(dev[0], hapd) # SAKE/Challenge/Response 1058 proxy_msg(hapd, dev[0]) # SAKE/Confirm/Request 1059 resp = rx_msg(dev[0]) 1060 # Corrupted AT_MIC_P value 1061 # --> EAP-SAKE: Incorrect AT_MIC_P 1062 msg = resp[0:30] + "000000000000" + resp[42:] 1063 tx_msg(dev[0], hapd, msg) 1064 rx_msg(hapd) 1065 stop_sake_assoc(dev[0], hapd) 1066 1067def test_eap_proto_leap(dev, apdev): 1068 """EAP-LEAP protocol tests""" 1069 check_eap_capa(dev[0], "LEAP") 1070 def leap_handler(ctx, req): 1071 logger.info("leap_handler - RX " + binascii.hexlify(req).decode()) 1072 if 'num' not in ctx: 1073 ctx['num'] = 0 1074 ctx['num'] = ctx['num'] + 1 1075 if 'id' not in ctx: 1076 ctx['id'] = 1 1077 ctx['id'] = (ctx['id'] + 1) % 256 1078 1079 if ctx['num'] == 1: 1080 logger.info("Test: Missing payload") 1081 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 1082 4 + 1, 1083 EAP_TYPE_LEAP) 1084 1085 if ctx['num'] == 2: 1086 logger.info("Test: Unexpected version") 1087 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 1088 4 + 1 + 3, 1089 EAP_TYPE_LEAP, 1090 0, 0, 0) 1091 1092 if ctx['num'] == 3: 1093 logger.info("Test: Invalid challenge length") 1094 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 1095 4 + 1 + 3, 1096 EAP_TYPE_LEAP, 1097 1, 0, 0) 1098 1099 if ctx['num'] == 4: 1100 logger.info("Test: Truncated challenge") 1101 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 1102 4 + 1 + 3, 1103 EAP_TYPE_LEAP, 1104 1, 0, 8) 1105 1106 if ctx['num'] == 5: 1107 logger.info("Test: Valid challenge") 1108 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], 1109 4 + 1 + 3 + 8, 1110 EAP_TYPE_LEAP, 1111 1, 0, 8, 0, 0) 1112 if ctx['num'] == 6: 1113 logger.info("Test: Missing payload in Response") 1114 return struct.pack(">BBHB", EAP_CODE_RESPONSE, ctx['id'], 1115 4 + 1, 1116 EAP_TYPE_LEAP) 1117 1118 if ctx['num'] == 7: 1119 logger.info("Test: Valid challenge") 1120 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], 1121 4 + 1 + 3 + 8, 1122 EAP_TYPE_LEAP, 1123 1, 0, 8, 0, 0) 1124 if ctx['num'] == 8: 1125 logger.info("Test: Unexpected version in Response") 1126 return struct.pack(">BBHBBBB", EAP_CODE_RESPONSE, ctx['id'], 1127 4 + 1 + 3, 1128 EAP_TYPE_LEAP, 1129 0, 0, 8) 1130 1131 if ctx['num'] == 9: 1132 logger.info("Test: Valid challenge") 1133 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], 1134 4 + 1 + 3 + 8, 1135 EAP_TYPE_LEAP, 1136 1, 0, 8, 0, 0) 1137 if ctx['num'] == 10: 1138 logger.info("Test: Invalid challenge length in Response") 1139 return struct.pack(">BBHBBBB", EAP_CODE_RESPONSE, ctx['id'], 1140 4 + 1 + 3, 1141 EAP_TYPE_LEAP, 1142 1, 0, 0) 1143 1144 if ctx['num'] == 11: 1145 logger.info("Test: Valid challenge") 1146 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], 1147 4 + 1 + 3 + 8, 1148 EAP_TYPE_LEAP, 1149 1, 0, 8, 0, 0) 1150 if ctx['num'] == 12: 1151 logger.info("Test: Truncated challenge in Response") 1152 return struct.pack(">BBHBBBB", EAP_CODE_RESPONSE, ctx['id'], 1153 4 + 1 + 3, 1154 EAP_TYPE_LEAP, 1155 1, 0, 24) 1156 1157 if ctx['num'] == 13: 1158 logger.info("Test: Valid challenge") 1159 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], 1160 4 + 1 + 3 + 8, 1161 EAP_TYPE_LEAP, 1162 1, 0, 8, 0, 0) 1163 if ctx['num'] == 14: 1164 logger.info("Test: Invalid challange value in Response") 1165 return struct.pack(">BBHBBBB6L", EAP_CODE_RESPONSE, ctx['id'], 1166 4 + 1 + 3 + 24, 1167 EAP_TYPE_LEAP, 1168 1, 0, 24, 1169 0, 0, 0, 0, 0, 0) 1170 1171 if ctx['num'] == 15: 1172 logger.info("Test: Valid challenge") 1173 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], 1174 4 + 1 + 3 + 8, 1175 EAP_TYPE_LEAP, 1176 1, 0, 8, 0, 0) 1177 if ctx['num'] == 16: 1178 logger.info("Test: Valid challange value in Response") 1179 return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'], 1180 4 + 1 + 3 + 24, 1181 EAP_TYPE_LEAP, 1182 1, 0, 24, 1183 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd, 1184 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04, 1185 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66) 1186 1187 if ctx['num'] == 17: 1188 logger.info("Test: Valid challenge") 1189 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], 1190 4 + 1 + 3 + 8, 1191 EAP_TYPE_LEAP, 1192 1, 0, 8, 0, 0) 1193 if ctx['num'] == 18: 1194 logger.info("Test: Success") 1195 return struct.pack(">BBHB", EAP_CODE_SUCCESS, ctx['id'], 1196 4 + 1, 1197 EAP_TYPE_LEAP) 1198 # hostapd will drop the next frame in the sequence 1199 1200 if ctx['num'] == 19: 1201 logger.info("Test: Valid challenge") 1202 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], 1203 4 + 1 + 3 + 8, 1204 EAP_TYPE_LEAP, 1205 1, 0, 8, 0, 0) 1206 if ctx['num'] == 20: 1207 logger.info("Test: Failure") 1208 return struct.pack(">BBHB", EAP_CODE_FAILURE, ctx['id'], 1209 4 + 1, 1210 EAP_TYPE_LEAP) 1211 1212 return None 1213 1214 srv = start_radius_server(leap_handler) 1215 1216 try: 1217 hapd = start_ap(apdev[0]) 1218 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 1219 1220 for i in range(0, 12): 1221 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 1222 eap="LEAP", identity="user", password="password", 1223 wait_connect=False) 1224 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15) 1225 if ev is None: 1226 raise Exception("Timeout on EAP start") 1227 time.sleep(0.1) 1228 if i == 10: 1229 logger.info("Wait for additional roundtrip") 1230 time.sleep(1) 1231 dev[0].request("REMOVE_NETWORK all") 1232 finally: 1233 stop_radius_server(srv) 1234 1235def test_eap_proto_leap_errors(dev, apdev): 1236 """EAP-LEAP protocol tests (error paths)""" 1237 check_eap_capa(dev[0], "LEAP") 1238 1239 def leap_handler2(ctx, req): 1240 logger.info("leap_handler2 - RX " + binascii.hexlify(req).decode()) 1241 if 'num' not in ctx: 1242 ctx['num'] = 0 1243 ctx['num'] = ctx['num'] + 1 1244 if 'id' not in ctx: 1245 ctx['id'] = 1 1246 ctx['id'] = (ctx['id'] + 1) % 256 1247 idx = 0 1248 1249 idx += 1 1250 if ctx['num'] == idx: 1251 logger.info("Test: Valid challenge") 1252 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], 1253 4 + 1 + 3 + 8, 1254 EAP_TYPE_LEAP, 1255 1, 0, 8, 0, 0) 1256 idx += 1 1257 if ctx['num'] == idx: 1258 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 1259 1260 idx += 1 1261 if ctx['num'] == idx: 1262 logger.info("Test: Valid challenge") 1263 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], 1264 4 + 1 + 3 + 8, 1265 EAP_TYPE_LEAP, 1266 1, 0, 8, 0, 0) 1267 1268 idx += 1 1269 if ctx['num'] == idx: 1270 logger.info("Test: Valid challenge") 1271 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], 1272 4 + 1 + 3 + 8, 1273 EAP_TYPE_LEAP, 1274 1, 0, 8, 0, 0) 1275 idx += 1 1276 if ctx['num'] == idx: 1277 logger.info("Test: Success") 1278 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4) 1279 1280 idx += 1 1281 if ctx['num'] == idx: 1282 logger.info("Test: Valid challenge") 1283 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], 1284 4 + 1 + 3 + 8, 1285 EAP_TYPE_LEAP, 1286 1, 0, 8, 0, 0) 1287 idx += 1 1288 if ctx['num'] == idx: 1289 logger.info("Test: Success") 1290 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4) 1291 1292 idx += 1 1293 if ctx['num'] == idx: 1294 logger.info("Test: Valid challenge") 1295 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], 1296 4 + 1 + 3 + 8, 1297 EAP_TYPE_LEAP, 1298 1, 0, 8, 0, 0) 1299 idx += 1 1300 if ctx['num'] == idx: 1301 logger.info("Test: Valid challange value in Response") 1302 return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'], 1303 4 + 1 + 3 + 24, 1304 EAP_TYPE_LEAP, 1305 1, 0, 24, 1306 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd, 1307 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04, 1308 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66) 1309 1310 idx += 1 1311 if ctx['num'] == idx: 1312 logger.info("Test: Valid challenge") 1313 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], 1314 4 + 1 + 3 + 8, 1315 EAP_TYPE_LEAP, 1316 1, 0, 8, 0, 0) 1317 idx += 1 1318 if ctx['num'] == idx: 1319 logger.info("Test: Valid challange value in Response") 1320 return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'], 1321 4 + 1 + 3 + 24, 1322 EAP_TYPE_LEAP, 1323 1, 0, 24, 1324 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd, 1325 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04, 1326 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66) 1327 1328 idx += 1 1329 if ctx['num'] == idx: 1330 logger.info("Test: Valid challenge") 1331 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], 1332 4 + 1 + 3 + 8, 1333 EAP_TYPE_LEAP, 1334 1, 0, 8, 0, 0) 1335 idx += 1 1336 if ctx['num'] == idx: 1337 logger.info("Test: Valid challange value in Response") 1338 return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'], 1339 4 + 1 + 3 + 24, 1340 EAP_TYPE_LEAP, 1341 1, 0, 24, 1342 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd, 1343 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04, 1344 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66) 1345 1346 idx += 1 1347 if ctx['num'] == idx: 1348 logger.info("Test: Valid challenge") 1349 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], 1350 4 + 1 + 3 + 8, 1351 EAP_TYPE_LEAP, 1352 1, 0, 8, 0, 0) 1353 idx += 1 1354 if ctx['num'] == idx: 1355 logger.info("Test: Valid challange value in Response") 1356 return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'], 1357 4 + 1 + 3 + 24, 1358 EAP_TYPE_LEAP, 1359 1, 0, 24, 1360 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd, 1361 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04, 1362 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66) 1363 1364 idx += 1 1365 if ctx['num'] == idx: 1366 logger.info("Test: Valid challenge") 1367 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], 1368 4 + 1 + 3 + 8, 1369 EAP_TYPE_LEAP, 1370 1, 0, 8, 0, 0) 1371 idx += 1 1372 if ctx['num'] == idx: 1373 logger.info("Test: Valid challange value in Response") 1374 return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'], 1375 4 + 1 + 3 + 24, 1376 EAP_TYPE_LEAP, 1377 1, 0, 24, 1378 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd, 1379 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04, 1380 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66) 1381 1382 idx += 1 1383 if ctx['num'] == idx: 1384 logger.info("Test: Valid challenge") 1385 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], 1386 4 + 1 + 3 + 8, 1387 EAP_TYPE_LEAP, 1388 1, 0, 8, 0, 0) 1389 idx += 1 1390 if ctx['num'] == idx: 1391 logger.info("Test: Valid challange value in Response") 1392 return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'], 1393 4 + 1 + 3 + 24, 1394 EAP_TYPE_LEAP, 1395 1, 0, 24, 1396 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd, 1397 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04, 1398 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66) 1399 1400 idx += 1 1401 if ctx['num'] == idx: 1402 logger.info("Test: Valid challenge") 1403 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], 1404 4 + 1 + 3 + 8, 1405 EAP_TYPE_LEAP, 1406 1, 0, 8, 0, 0) 1407 idx += 1 1408 if ctx['num'] == idx: 1409 logger.info("Test: Valid challange value in Response") 1410 return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'], 1411 4 + 1 + 3 + 24, 1412 EAP_TYPE_LEAP, 1413 1, 0, 24, 1414 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd, 1415 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04, 1416 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66) 1417 1418 idx += 1 1419 if ctx['num'] == idx: 1420 logger.info("Test: Valid challenge") 1421 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'], 1422 4 + 1 + 3 + 8, 1423 EAP_TYPE_LEAP, 1424 1, 0, 8, 0, 0) 1425 1426 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 1427 1428 srv = start_radius_server(leap_handler2) 1429 1430 try: 1431 hapd = start_ap(apdev[0]) 1432 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 1433 1434 with alloc_fail(dev[0], 1, "eap_leap_init"): 1435 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 1436 eap="LEAP", identity="user", password="password", 1437 wait_connect=False) 1438 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 1439 dev[0].request("REMOVE_NETWORK all") 1440 dev[0].wait_disconnected() 1441 1442 with alloc_fail(dev[0], 1, "eap_msg_alloc;eap_leap_process_request"): 1443 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 1444 eap="LEAP", identity="user", 1445 password_hex="hash:8846f7eaee8fb117ad06bdd830b7586c", 1446 wait_connect=False) 1447 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 1448 dev[0].request("REMOVE_NETWORK all") 1449 dev[0].wait_disconnected() 1450 1451 with alloc_fail(dev[0], 1, "eap_leap_process_success"): 1452 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 1453 eap="LEAP", identity="user", password="password", 1454 wait_connect=False) 1455 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 1456 dev[0].request("REMOVE_NETWORK all") 1457 dev[0].wait_disconnected() 1458 1459 with fail_test(dev[0], 1, "os_get_random;eap_leap_process_success"): 1460 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 1461 eap="LEAP", identity="user", password="password", 1462 wait_connect=False) 1463 wait_fail_trigger(dev[0], "GET_FAIL") 1464 dev[0].request("REMOVE_NETWORK all") 1465 dev[0].wait_disconnected() 1466 1467 with fail_test(dev[0], 1, "eap_leap_process_response"): 1468 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 1469 eap="LEAP", identity="user", 1470 password_hex="hash:8846f7eaee8fb117ad06bdd830b7586c", 1471 wait_connect=False) 1472 wait_fail_trigger(dev[0], "GET_FAIL") 1473 dev[0].request("REMOVE_NETWORK all") 1474 dev[0].wait_disconnected() 1475 1476 with fail_test(dev[0], 1, "nt_password_hash;eap_leap_process_response"): 1477 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 1478 eap="LEAP", identity="user", password="password", 1479 wait_connect=False) 1480 wait_fail_trigger(dev[0], "GET_FAIL") 1481 dev[0].request("REMOVE_NETWORK all") 1482 dev[0].wait_disconnected() 1483 1484 with fail_test(dev[0], 1, "hash_nt_password_hash;eap_leap_process_response"): 1485 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 1486 eap="LEAP", identity="user", password="password", 1487 wait_connect=False) 1488 wait_fail_trigger(dev[0], "GET_FAIL") 1489 dev[0].request("REMOVE_NETWORK all") 1490 dev[0].wait_disconnected() 1491 1492 with alloc_fail(dev[0], 1, "eap_leap_getKey"): 1493 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 1494 eap="LEAP", identity="user", 1495 password_hex="hash:8846f7eaee8fb117ad06bdd830b7586c", 1496 wait_connect=False) 1497 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 1498 dev[0].request("REMOVE_NETWORK all") 1499 dev[0].wait_disconnected() 1500 1501 with fail_test(dev[0], 1, "eap_leap_getKey"): 1502 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 1503 eap="LEAP", identity="user", 1504 password_hex="hash:8846f7eaee8fb117ad06bdd830b7586c", 1505 wait_connect=False) 1506 wait_fail_trigger(dev[0], "GET_FAIL") 1507 dev[0].request("REMOVE_NETWORK all") 1508 dev[0].wait_disconnected() 1509 1510 with fail_test(dev[0], 1, "nt_password_hash;eap_leap_getKey"): 1511 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 1512 eap="LEAP", identity="user", password="password", 1513 wait_connect=False) 1514 wait_fail_trigger(dev[0], "GET_FAIL") 1515 dev[0].request("REMOVE_NETWORK all") 1516 dev[0].wait_disconnected() 1517 1518 with fail_test(dev[0], 1, "hash_nt_password_hash;eap_leap_getKey"): 1519 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 1520 eap="LEAP", identity="user", password="password", 1521 wait_connect=False) 1522 wait_fail_trigger(dev[0], "GET_FAIL") 1523 dev[0].request("REMOVE_NETWORK all") 1524 dev[0].wait_disconnected() 1525 1526 with fail_test(dev[0], 1, 1527 "nt_challenge_response;eap_leap_process_request"): 1528 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 1529 eap="LEAP", identity="user", password="password", 1530 wait_connect=False) 1531 wait_fail_trigger(dev[0], "GET_FAIL") 1532 dev[0].request("REMOVE_NETWORK all") 1533 dev[0].wait_disconnected() 1534 finally: 1535 stop_radius_server(srv) 1536 1537def test_eap_proto_md5(dev, apdev): 1538 """EAP-MD5 protocol tests""" 1539 check_eap_capa(dev[0], "MD5") 1540 1541 def md5_handler(ctx, req): 1542 logger.info("md5_handler - RX " + binascii.hexlify(req).decode()) 1543 if 'num' not in ctx: 1544 ctx['num'] = 0 1545 ctx['num'] = ctx['num'] + 1 1546 if 'id' not in ctx: 1547 ctx['id'] = 1 1548 ctx['id'] = (ctx['id'] + 1) % 256 1549 1550 if ctx['num'] == 1: 1551 logger.info("Test: Missing payload") 1552 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 1553 4 + 1, 1554 EAP_TYPE_MD5) 1555 1556 if ctx['num'] == 2: 1557 logger.info("Test: Zero-length challenge") 1558 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 1559 4 + 1 + 1, 1560 EAP_TYPE_MD5, 1561 0) 1562 1563 if ctx['num'] == 3: 1564 logger.info("Test: Truncated challenge") 1565 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 1566 4 + 1 + 1, 1567 EAP_TYPE_MD5, 1568 1) 1569 1570 if ctx['num'] == 4: 1571 logger.info("Test: Shortest possible challenge and name") 1572 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 1573 4 + 1 + 3, 1574 EAP_TYPE_MD5, 1575 1, 0xaa, ord('n')) 1576 1577 return None 1578 1579 srv = start_radius_server(md5_handler) 1580 1581 try: 1582 hapd = start_ap(apdev[0]) 1583 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 1584 1585 for i in range(0, 4): 1586 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 1587 eap="MD5", identity="user", password="password", 1588 wait_connect=False) 1589 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15) 1590 if ev is None: 1591 raise Exception("Timeout on EAP start") 1592 time.sleep(0.1) 1593 dev[0].request("REMOVE_NETWORK all") 1594 finally: 1595 stop_radius_server(srv) 1596 1597def test_eap_proto_md5_errors(dev, apdev): 1598 """EAP-MD5 local error cases""" 1599 check_eap_capa(dev[0], "MD5") 1600 params = hostapd.wpa2_eap_params(ssid="eap-test") 1601 hapd = hostapd.add_ap(apdev[0], params) 1602 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 1603 1604 with fail_test(dev[0], 1, "chap_md5"): 1605 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 1606 eap="MD5", identity="phase1-user", password="password", 1607 wait_connect=False) 1608 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=15) 1609 if ev is None: 1610 raise Exception("Timeout on EAP start") 1611 dev[0].request("REMOVE_NETWORK all") 1612 dev[0].wait_disconnected() 1613 1614 with alloc_fail(dev[0], 1, "eap_msg_alloc;eap_md5_process"): 1615 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 1616 eap="MD5", identity="phase1-user", password="password", 1617 wait_connect=False) 1618 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=15) 1619 if ev is None: 1620 raise Exception("Timeout on EAP start") 1621 time.sleep(0.1) 1622 dev[0].request("REMOVE_NETWORK all") 1623 1624def run_eap_md5_connect(dev): 1625 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412", 1626 eap="MD5", identity="phase1-user", password="password", 1627 wait_connect=False) 1628 ev = dev.wait_event(["CTRL-EVENT-EAP-SUCCESS", "CTRL-EVENT-EAP-FAILURE", 1629 "CTRL-EVENT-DISCONNECTED"], 1630 timeout=1) 1631 dev.request("REMOVE_NETWORK all") 1632 if not ev or "CTRL-EVENT-DISCONNECTED" not in ev: 1633 dev.wait_disconnected() 1634 dev.dump_monitor() 1635 1636def test_eap_proto_md5_errors_server(dev, apdev): 1637 """EAP-MD5 local error cases on server""" 1638 check_eap_capa(dev[0], "MD5") 1639 params = int_eap_server_params() 1640 params['erp_domain'] = 'example.com' 1641 params['eap_server_erp'] = '1' 1642 hapd = hostapd.add_ap(apdev[0], params) 1643 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 1644 1645 tests = [(1, "eap_md5_init")] 1646 for count, func in tests: 1647 with alloc_fail(hapd, count, func): 1648 run_eap_md5_connect(dev[0]) 1649 1650 tests = [(1, "os_get_random;eap_md5_buildReq"), 1651 (1, "chap_md5;eap_md5_process")] 1652 for count, func in tests: 1653 with fail_test(hapd, count, func): 1654 run_eap_md5_connect(dev[0]) 1655 1656def start_md5_assoc(dev, hapd): 1657 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412", 1658 eap="MD5", identity="phase1-user", password="password", 1659 wait_connect=False) 1660 proxy_msg(hapd, dev) # EAP-Identity/Request 1661 proxy_msg(dev, hapd) # EAP-Identity/Response 1662 proxy_msg(hapd, dev) # MSCHAPV2/Request 1663 proxy_msg(dev, hapd) # NAK 1664 proxy_msg(hapd, dev) # MD5 Request 1665 1666def stop_md5_assoc(dev, hapd, wait=True): 1667 dev.request("REMOVE_NETWORK all") 1668 if wait: 1669 dev.wait_disconnected() 1670 dev.dump_monitor() 1671 hapd.dump_monitor() 1672 1673def test_eap_proto_md5_server(dev, apdev): 1674 """EAP-MD5 protocol testing for the server""" 1675 check_eap_capa(dev[0], "MD5") 1676 params = int_eap_server_params() 1677 params['erp_domain'] = 'example.com' 1678 params['eap_server_erp'] = '1' 1679 hapd = hostapd.add_ap(apdev[0], params) 1680 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 1681 hapd.request("SET ext_eapol_frame_io 1") 1682 dev[0].request("SET ext_eapol_frame_io 1") 1683 1684 # Successful exchange to verify proxying mechanism 1685 start_md5_assoc(dev[0], hapd) 1686 proxy_msg(dev[0], hapd) # MD5 Response 1687 proxy_msg(hapd, dev[0]) # EAP-Success 1688 # Accept both EAP-Success and disconnection indication since it is possible 1689 # for disconnection from the AP (due to EAP-MD5 not deriving keys) to be 1690 # processed more quickly. 1691 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS", 1692 "CTRL-EVENT-DISCONNECTED"], timeout=5) 1693 if ev is None: 1694 raise Exception("No EAP-Success reported") 1695 stop_md5_assoc(dev[0], hapd, wait="CTRL-EVENT-EAP-SUCCESS" in ev) 1696 1697 start_md5_assoc(dev[0], hapd) 1698 resp = rx_msg(dev[0]) 1699 # Too short EAP-MD5 header (no length field) 1700 hapd.note("EAP-MD5: Invalid frame") 1701 msg = resp[0:4] + "0005" + resp[8:12] + "0005" + "04" 1702 tx_msg(dev[0], hapd, msg) 1703 # Too short EAP-MD5 header (no length field) 1704 hapd.note("EAP-MD5: Invalid response (response_len=0 payload_len=1") 1705 msg = resp[0:4] + "0006" + resp[8:12] + "0006" + "0400" 1706 tx_msg(dev[0], hapd, msg) 1707 stop_md5_assoc(dev[0], hapd) 1708 1709def test_eap_proto_otp(dev, apdev): 1710 """EAP-OTP protocol tests""" 1711 def otp_handler(ctx, req): 1712 logger.info("otp_handler - RX " + binascii.hexlify(req).decode()) 1713 if 'num' not in ctx: 1714 ctx['num'] = 0 1715 ctx['num'] = ctx['num'] + 1 1716 if 'id' not in ctx: 1717 ctx['id'] = 1 1718 ctx['id'] = (ctx['id'] + 1) % 256 1719 1720 if ctx['num'] == 1: 1721 logger.info("Test: Empty payload") 1722 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 1723 4 + 1, 1724 EAP_TYPE_OTP) 1725 if ctx['num'] == 2: 1726 logger.info("Test: Success") 1727 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 1728 4) 1729 1730 if ctx['num'] == 3: 1731 logger.info("Test: Challenge included") 1732 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 1733 4 + 1 + 1, 1734 EAP_TYPE_OTP, 1735 ord('A')) 1736 if ctx['num'] == 4: 1737 logger.info("Test: Success") 1738 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 1739 4) 1740 1741 return None 1742 1743 srv = start_radius_server(otp_handler) 1744 1745 try: 1746 hapd = start_ap(apdev[0]) 1747 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 1748 1749 for i in range(0, 1): 1750 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 1751 eap="OTP", identity="user", password="password", 1752 wait_connect=False) 1753 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 1754 timeout=15) 1755 if ev is None: 1756 raise Exception("Timeout on EAP start") 1757 time.sleep(0.1) 1758 dev[0].request("REMOVE_NETWORK all") 1759 1760 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 1761 eap="OTP", identity="user", wait_connect=False) 1762 ev = dev[0].wait_event(["CTRL-REQ-OTP"]) 1763 if ev is None: 1764 raise Exception("Request for password timed out") 1765 id = ev.split(':')[0].split('-')[-1] 1766 dev[0].request("CTRL-RSP-OTP-" + id + ":password") 1767 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"]) 1768 if ev is None: 1769 raise Exception("Success not reported") 1770 finally: 1771 stop_radius_server(srv) 1772 1773def test_eap_proto_otp_errors(dev, apdev): 1774 """EAP-OTP local error cases""" 1775 def otp_handler2(ctx, req): 1776 logger.info("otp_handler2 - RX " + binascii.hexlify(req).decode()) 1777 if 'num' not in ctx: 1778 ctx['num'] = 0 1779 ctx['num'] = ctx['num'] + 1 1780 if 'id' not in ctx: 1781 ctx['id'] = 1 1782 ctx['id'] = (ctx['id'] + 1) % 256 1783 idx = 0 1784 1785 idx += 1 1786 if ctx['num'] == idx: 1787 logger.info("Test: Challenge included") 1788 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 1789 4 + 1 + 1, 1790 EAP_TYPE_OTP, 1791 ord('A')) 1792 1793 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 1794 1795 srv = start_radius_server(otp_handler2) 1796 1797 try: 1798 hapd = start_ap(apdev[0]) 1799 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 1800 1801 with alloc_fail(dev[0], 1, "eap_msg_alloc;eap_otp_process"): 1802 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 1803 eap="OTP", identity="user", password="password", 1804 wait_connect=False) 1805 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 1806 dev[0].request("REMOVE_NETWORK all") 1807 dev[0].wait_disconnected() 1808 finally: 1809 stop_radius_server(srv) 1810 1811EAP_GPSK_OPCODE_GPSK_1 = 1 1812EAP_GPSK_OPCODE_GPSK_2 = 2 1813EAP_GPSK_OPCODE_GPSK_3 = 3 1814EAP_GPSK_OPCODE_GPSK_4 = 4 1815EAP_GPSK_OPCODE_FAIL = 5 1816EAP_GPSK_OPCODE_PROTECTED_FAIL = 6 1817 1818def test_eap_proto_gpsk(dev, apdev): 1819 """EAP-GPSK protocol tests""" 1820 def gpsk_handler(ctx, req): 1821 logger.info("gpsk_handler - RX " + binascii.hexlify(req).decode()) 1822 if 'num' not in ctx: 1823 ctx['num'] = 0 1824 ctx['num'] = ctx['num'] + 1 1825 if 'id' not in ctx: 1826 ctx['id'] = 1 1827 ctx['id'] = (ctx['id'] + 1) % 256 1828 1829 idx = 0 1830 1831 idx += 1 1832 if ctx['num'] == idx: 1833 logger.info("Test: Missing payload") 1834 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 1835 4 + 1, 1836 EAP_TYPE_GPSK) 1837 1838 idx += 1 1839 if ctx['num'] == idx: 1840 logger.info("Test: Unknown opcode") 1841 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 1842 4 + 1 + 1, 1843 EAP_TYPE_GPSK, 1844 255) 1845 1846 idx += 1 1847 if ctx['num'] == idx: 1848 logger.info("Test: Unexpected GPSK-3") 1849 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 1850 4 + 1 + 1, 1851 EAP_TYPE_GPSK, 1852 EAP_GPSK_OPCODE_GPSK_3) 1853 1854 idx += 1 1855 if ctx['num'] == idx: 1856 logger.info("Test: GPSK-1 Too short GPSK-1") 1857 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 1858 4 + 1 + 1, 1859 EAP_TYPE_GPSK, 1860 EAP_GPSK_OPCODE_GPSK_1) 1861 1862 idx += 1 1863 if ctx['num'] == idx: 1864 logger.info("Test: GPSK-1 Truncated ID_Server") 1865 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], 1866 4 + 1 + 1 + 2, 1867 EAP_TYPE_GPSK, 1868 EAP_GPSK_OPCODE_GPSK_1, 1) 1869 1870 idx += 1 1871 if ctx['num'] == idx: 1872 logger.info("Test: GPSK-1 Missing RAND_Server") 1873 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], 1874 4 + 1 + 1 + 2, 1875 EAP_TYPE_GPSK, 1876 EAP_GPSK_OPCODE_GPSK_1, 0) 1877 1878 idx += 1 1879 if ctx['num'] == idx: 1880 logger.info("Test: GPSK-1 Missing CSuite_List") 1881 return struct.pack(">BBHBBH8L", EAP_CODE_REQUEST, ctx['id'], 1882 4 + 1 + 1 + 2 + 32, 1883 EAP_TYPE_GPSK, 1884 EAP_GPSK_OPCODE_GPSK_1, 0, 1885 0, 0, 0, 0, 0, 0, 0, 0) 1886 1887 idx += 1 1888 if ctx['num'] == idx: 1889 logger.info("Test: GPSK-1 Truncated CSuite_List") 1890 return struct.pack(">BBHBBH8LH", EAP_CODE_REQUEST, ctx['id'], 1891 4 + 1 + 1 + 2 + 32 + 2, 1892 EAP_TYPE_GPSK, 1893 EAP_GPSK_OPCODE_GPSK_1, 0, 1894 0, 0, 0, 0, 0, 0, 0, 0, 1895 1) 1896 1897 idx += 1 1898 if ctx['num'] == idx: 1899 logger.info("Test: GPSK-1 Empty CSuite_List") 1900 return struct.pack(">BBHBBH8LH", EAP_CODE_REQUEST, ctx['id'], 1901 4 + 1 + 1 + 2 + 32 + 2, 1902 EAP_TYPE_GPSK, 1903 EAP_GPSK_OPCODE_GPSK_1, 0, 1904 0, 0, 0, 0, 0, 0, 0, 0, 1905 0) 1906 1907 idx += 1 1908 if ctx['num'] == idx: 1909 logger.info("Test: GPSK-1 Invalid CSuite_List") 1910 return struct.pack(">BBHBBH8LHB", EAP_CODE_REQUEST, ctx['id'], 1911 4 + 1 + 1 + 2 + 32 + 2 + 1, 1912 EAP_TYPE_GPSK, 1913 EAP_GPSK_OPCODE_GPSK_1, 0, 1914 0, 0, 0, 0, 0, 0, 0, 0, 1915 1, 0) 1916 1917 idx += 1 1918 if ctx['num'] == idx: 1919 logger.info("Test: GPSK-1 No supported CSuite") 1920 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], 1921 4 + 1 + 1 + 2 + 32 + 2 + 6, 1922 EAP_TYPE_GPSK, 1923 EAP_GPSK_OPCODE_GPSK_1, 0, 1924 0, 0, 0, 0, 0, 0, 0, 0, 1925 6, 0, 0) 1926 1927 idx += 1 1928 if ctx['num'] == idx: 1929 logger.info("Test: GPSK-1 Supported CSuite") 1930 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], 1931 4 + 1 + 1 + 2 + 32 + 2 + 6, 1932 EAP_TYPE_GPSK, 1933 EAP_GPSK_OPCODE_GPSK_1, 0, 1934 0, 0, 0, 0, 0, 0, 0, 0, 1935 6, 0, 1) 1936 idx += 1 1937 if ctx['num'] == idx: 1938 logger.info("Test: Unexpected GPSK-1") 1939 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], 1940 4 + 1 + 1 + 2 + 32 + 2 + 6, 1941 EAP_TYPE_GPSK, 1942 EAP_GPSK_OPCODE_GPSK_1, 0, 1943 0, 0, 0, 0, 0, 0, 0, 0, 1944 6, 0, 1) 1945 1946 idx += 1 1947 if ctx['num'] == idx: 1948 logger.info("Test: GPSK-1 Supported CSuite but too short key") 1949 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], 1950 4 + 1 + 1 + 2 + 32 + 2 + 6, 1951 EAP_TYPE_GPSK, 1952 EAP_GPSK_OPCODE_GPSK_1, 0, 1953 0, 0, 0, 0, 0, 0, 0, 0, 1954 6, 0, 1) 1955 1956 idx += 1 1957 if ctx['num'] == idx: 1958 logger.info("Test: GPSK-1 Supported CSuite") 1959 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], 1960 4 + 1 + 1 + 2 + 32 + 2 + 6, 1961 EAP_TYPE_GPSK, 1962 EAP_GPSK_OPCODE_GPSK_1, 0, 1963 0, 0, 0, 0, 0, 0, 0, 0, 1964 6, 0, 1) 1965 idx += 1 1966 if ctx['num'] == idx: 1967 logger.info("Test: Too short GPSK-3") 1968 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 1969 4 + 1 + 1, 1970 EAP_TYPE_GPSK, 1971 EAP_GPSK_OPCODE_GPSK_3) 1972 1973 idx += 1 1974 if ctx['num'] == idx: 1975 logger.info("Test: GPSK-1 Supported CSuite") 1976 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], 1977 4 + 1 + 1 + 2 + 32 + 2 + 6, 1978 EAP_TYPE_GPSK, 1979 EAP_GPSK_OPCODE_GPSK_1, 0, 1980 0, 0, 0, 0, 0, 0, 0, 0, 1981 6, 0, 1) 1982 idx += 1 1983 if ctx['num'] == idx: 1984 logger.info("Test: GPSK-3 Mismatch in RAND_Peer") 1985 return struct.pack(">BBHBB8L", EAP_CODE_REQUEST, ctx['id'], 1986 4 + 1 + 1 + 32, 1987 EAP_TYPE_GPSK, 1988 EAP_GPSK_OPCODE_GPSK_3, 1989 0, 0, 0, 0, 0, 0, 0, 0) 1990 1991 idx += 1 1992 if ctx['num'] == idx: 1993 logger.info("Test: GPSK-1 Supported CSuite") 1994 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], 1995 4 + 1 + 1 + 2 + 32 + 2 + 6, 1996 EAP_TYPE_GPSK, 1997 EAP_GPSK_OPCODE_GPSK_1, 0, 1998 0, 0, 0, 0, 0, 0, 0, 0, 1999 6, 0, 1) 2000 idx += 1 2001 if ctx['num'] == idx: 2002 logger.info("Test: GPSK-3 Missing RAND_Server") 2003 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 2004 4 + 1 + 1 + 32, 2005 EAP_TYPE_GPSK, 2006 EAP_GPSK_OPCODE_GPSK_3) 2007 msg += req[14:46] 2008 return msg 2009 2010 idx += 1 2011 if ctx['num'] == idx: 2012 logger.info("Test: GPSK-1 Supported CSuite") 2013 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], 2014 4 + 1 + 1 + 2 + 32 + 2 + 6, 2015 EAP_TYPE_GPSK, 2016 EAP_GPSK_OPCODE_GPSK_1, 0, 2017 0, 0, 0, 0, 0, 0, 0, 0, 2018 6, 0, 1) 2019 idx += 1 2020 if ctx['num'] == idx: 2021 logger.info("Test: GPSK-3 Mismatch in RAND_Server") 2022 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 2023 4 + 1 + 1 + 32 + 32, 2024 EAP_TYPE_GPSK, 2025 EAP_GPSK_OPCODE_GPSK_3) 2026 msg += req[14:46] 2027 msg += struct.pack(">8L", 1, 1, 1, 1, 1, 1, 1, 1) 2028 return msg 2029 2030 idx += 1 2031 if ctx['num'] == idx: 2032 logger.info("Test: GPSK-1 Supported CSuite") 2033 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], 2034 4 + 1 + 1 + 2 + 32 + 2 + 6, 2035 EAP_TYPE_GPSK, 2036 EAP_GPSK_OPCODE_GPSK_1, 0, 2037 0, 0, 0, 0, 0, 0, 0, 0, 2038 6, 0, 1) 2039 idx += 1 2040 if ctx['num'] == idx: 2041 logger.info("Test: GPSK-3 Missing ID_Server") 2042 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 2043 4 + 1 + 1 + 32 + 32, 2044 EAP_TYPE_GPSK, 2045 EAP_GPSK_OPCODE_GPSK_3) 2046 msg += req[14:46] 2047 msg += struct.pack(">8L", 0, 0, 0, 0, 0, 0, 0, 0) 2048 return msg 2049 2050 idx += 1 2051 if ctx['num'] == idx: 2052 logger.info("Test: GPSK-1 Supported CSuite") 2053 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], 2054 4 + 1 + 1 + 2 + 32 + 2 + 6, 2055 EAP_TYPE_GPSK, 2056 EAP_GPSK_OPCODE_GPSK_1, 0, 2057 0, 0, 0, 0, 0, 0, 0, 0, 2058 6, 0, 1) 2059 idx += 1 2060 if ctx['num'] == idx: 2061 logger.info("Test: GPSK-3 Truncated ID_Server") 2062 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 2063 4 + 1 + 1 + 32 + 32 + 2, 2064 EAP_TYPE_GPSK, 2065 EAP_GPSK_OPCODE_GPSK_3) 2066 msg += req[14:46] 2067 msg += struct.pack(">8LH", 0, 0, 0, 0, 0, 0, 0, 0, 1) 2068 return msg 2069 2070 idx += 1 2071 if ctx['num'] == idx: 2072 logger.info("Test: GPSK-1 Supported CSuite") 2073 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], 2074 4 + 1 + 1 + 2 + 32 + 2 + 6, 2075 EAP_TYPE_GPSK, 2076 EAP_GPSK_OPCODE_GPSK_1, 0, 2077 0, 0, 0, 0, 0, 0, 0, 0, 2078 6, 0, 1) 2079 idx += 1 2080 if ctx['num'] == idx: 2081 logger.info("Test: GPSK-3 Mismatch in ID_Server") 2082 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 2083 4 + 1 + 1 + 32 + 32 + 3, 2084 EAP_TYPE_GPSK, 2085 EAP_GPSK_OPCODE_GPSK_3) 2086 msg += req[14:46] 2087 msg += struct.pack(">8LHB", 0, 0, 0, 0, 0, 0, 0, 0, 1, ord('B')) 2088 return msg 2089 2090 idx += 1 2091 if ctx['num'] == idx: 2092 logger.info("Test: GPSK-1 Supported CSuite") 2093 return struct.pack(">BBHBBHB8LHLH", EAP_CODE_REQUEST, ctx['id'], 2094 4 + 1 + 1 + 3 + 32 + 2 + 6, 2095 EAP_TYPE_GPSK, 2096 EAP_GPSK_OPCODE_GPSK_1, 1, ord('A'), 2097 0, 0, 0, 0, 0, 0, 0, 0, 2098 6, 0, 1) 2099 idx += 1 2100 if ctx['num'] == idx: 2101 logger.info("Test: GPSK-3 Mismatch in ID_Server (same length)") 2102 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 2103 4 + 1 + 1 + 32 + 32 + 3, 2104 EAP_TYPE_GPSK, 2105 EAP_GPSK_OPCODE_GPSK_3) 2106 msg += req[15:47] 2107 msg += struct.pack(">8LHB", 0, 0, 0, 0, 0, 0, 0, 0, 1, ord('B')) 2108 return msg 2109 2110 idx += 1 2111 if ctx['num'] == idx: 2112 logger.info("Test: GPSK-1 Supported CSuite") 2113 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], 2114 4 + 1 + 1 + 2 + 32 + 2 + 6, 2115 EAP_TYPE_GPSK, 2116 EAP_GPSK_OPCODE_GPSK_1, 0, 2117 0, 0, 0, 0, 0, 0, 0, 0, 2118 6, 0, 1) 2119 idx += 1 2120 if ctx['num'] == idx: 2121 logger.info("Test: GPSK-3 Missing CSuite_Sel") 2122 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 2123 4 + 1 + 1 + 32 + 32 + 2, 2124 EAP_TYPE_GPSK, 2125 EAP_GPSK_OPCODE_GPSK_3) 2126 msg += req[14:46] 2127 msg += struct.pack(">8LH", 0, 0, 0, 0, 0, 0, 0, 0, 0) 2128 return msg 2129 2130 idx += 1 2131 if ctx['num'] == idx: 2132 logger.info("Test: GPSK-1 Supported CSuite") 2133 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], 2134 4 + 1 + 1 + 2 + 32 + 2 + 6, 2135 EAP_TYPE_GPSK, 2136 EAP_GPSK_OPCODE_GPSK_1, 0, 2137 0, 0, 0, 0, 0, 0, 0, 0, 2138 6, 0, 1) 2139 idx += 1 2140 if ctx['num'] == idx: 2141 logger.info("Test: GPSK-3 Mismatch in CSuite_Sel") 2142 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 2143 4 + 1 + 1 + 32 + 32 + 2 + 6, 2144 EAP_TYPE_GPSK, 2145 EAP_GPSK_OPCODE_GPSK_3) 2146 msg += req[14:46] 2147 msg += struct.pack(">8LHLH", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2) 2148 return msg 2149 2150 idx += 1 2151 if ctx['num'] == idx: 2152 logger.info("Test: GPSK-1 Supported CSuite") 2153 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], 2154 4 + 1 + 1 + 2 + 32 + 2 + 6, 2155 EAP_TYPE_GPSK, 2156 EAP_GPSK_OPCODE_GPSK_1, 0, 2157 0, 0, 0, 0, 0, 0, 0, 0, 2158 6, 0, 1) 2159 idx += 1 2160 if ctx['num'] == idx: 2161 logger.info("Test: GPSK-3 Missing len(PD_Payload_Block)") 2162 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 2163 4 + 1 + 1 + 32 + 32 + 2 + 6, 2164 EAP_TYPE_GPSK, 2165 EAP_GPSK_OPCODE_GPSK_3) 2166 msg += req[14:46] 2167 msg += struct.pack(">8LHLH", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1) 2168 return msg 2169 2170 idx += 1 2171 if ctx['num'] == idx: 2172 logger.info("Test: GPSK-1 Supported CSuite") 2173 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], 2174 4 + 1 + 1 + 2 + 32 + 2 + 6, 2175 EAP_TYPE_GPSK, 2176 EAP_GPSK_OPCODE_GPSK_1, 0, 2177 0, 0, 0, 0, 0, 0, 0, 0, 2178 6, 0, 1) 2179 idx += 1 2180 if ctx['num'] == idx: 2181 logger.info("Test: GPSK-3 Truncated PD_Payload_Block") 2182 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 2183 4 + 1 + 1 + 32 + 32 + 2 + 6 + 2, 2184 EAP_TYPE_GPSK, 2185 EAP_GPSK_OPCODE_GPSK_3) 2186 msg += req[14:46] 2187 msg += struct.pack(">8LHLHH", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1) 2188 return msg 2189 2190 idx += 1 2191 if ctx['num'] == idx: 2192 logger.info("Test: GPSK-1 Supported CSuite") 2193 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], 2194 4 + 1 + 1 + 2 + 32 + 2 + 6, 2195 EAP_TYPE_GPSK, 2196 EAP_GPSK_OPCODE_GPSK_1, 0, 2197 0, 0, 0, 0, 0, 0, 0, 0, 2198 6, 0, 1) 2199 idx += 1 2200 if ctx['num'] == idx: 2201 logger.info("Test: GPSK-3 Missing MAC") 2202 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 2203 4 + 1 + 1 + 32 + 32 + 2 + 6 + 3, 2204 EAP_TYPE_GPSK, 2205 EAP_GPSK_OPCODE_GPSK_3) 2206 msg += req[14:46] 2207 msg += struct.pack(">8LHLHHB", 2208 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 123) 2209 return msg 2210 2211 idx += 1 2212 if ctx['num'] == idx: 2213 logger.info("Test: GPSK-1 Supported CSuite") 2214 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'], 2215 4 + 1 + 1 + 2 + 32 + 2 + 6, 2216 EAP_TYPE_GPSK, 2217 EAP_GPSK_OPCODE_GPSK_1, 0, 2218 0, 0, 0, 0, 0, 0, 0, 0, 2219 6, 0, 1) 2220 idx += 1 2221 if ctx['num'] == idx: 2222 logger.info("Test: GPSK-3 Incorrect MAC") 2223 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 2224 4 + 1 + 1 + 32 + 32 + 2 + 6 + 3 + 16, 2225 EAP_TYPE_GPSK, 2226 EAP_GPSK_OPCODE_GPSK_3) 2227 msg += req[14:46] 2228 msg += struct.pack(">8LHLHHB4L", 2229 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 123, 2230 0, 0, 0, 0) 2231 return msg 2232 2233 return None 2234 2235 srv = start_radius_server(gpsk_handler) 2236 2237 try: 2238 hapd = start_ap(apdev[0]) 2239 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 2240 2241 for i in range(0, 27): 2242 if i == 12: 2243 pw = "short" 2244 else: 2245 pw = "abcdefghijklmnop0123456789abcdef" 2246 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 2247 eap="GPSK", identity="user", password=pw, 2248 wait_connect=False) 2249 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 2250 timeout=15) 2251 if ev is None: 2252 raise Exception("Timeout on EAP start") 2253 time.sleep(0.05) 2254 dev[0].request("REMOVE_NETWORK all") 2255 finally: 2256 stop_radius_server(srv) 2257 2258def run_eap_gpsk_connect(dev): 2259 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412", 2260 eap="GPSK", identity="gpsk user", 2261 password="abcdefghijklmnop0123456789abcdef", 2262 wait_connect=False) 2263 ev = dev.wait_event(["CTRL-EVENT-EAP-SUCCESS", "CTRL-EVENT-EAP-FAILURE", 2264 "CTRL-EVENT-DISCONNECTED"], 2265 timeout=1) 2266 dev.request("REMOVE_NETWORK all") 2267 if not ev or "CTRL-EVENT-DISCONNECTED" not in ev: 2268 dev.wait_disconnected() 2269 dev.dump_monitor() 2270 2271def test_eap_proto_gpsk_errors_server(dev, apdev): 2272 """EAP-GPSK local error cases on server""" 2273 check_eap_capa(dev[0], "GPSK") 2274 params = int_eap_server_params() 2275 params['erp_domain'] = 'example.com' 2276 params['eap_server_erp'] = '1' 2277 hapd = hostapd.add_ap(apdev[0], params) 2278 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 2279 2280 tests = [(1, "eap_gpsk_init"), 2281 (1, "eap_msg_alloc;eap_gpsk_build_gpsk_1"), 2282 (1, "eap_msg_alloc;eap_gpsk_build_gpsk_3"), 2283 (1, "eap_gpsk_process_gpsk_2"), 2284 (1, "eap_gpsk_derive_keys;eap_gpsk_process_gpsk_2"), 2285 (1, "eap_gpsk_derive_session_id;eap_gpsk_process_gpsk_2"), 2286 (1, "eap_gpsk_getKey"), 2287 (1, "eap_gpsk_get_emsk"), 2288 (1, "eap_gpsk_get_session_id")] 2289 for count, func in tests: 2290 with alloc_fail(hapd, count, func): 2291 run_eap_gpsk_connect(dev[0]) 2292 2293 tests = [(1, "os_get_random;eap_gpsk_build_gpsk_1"), 2294 (1, "eap_gpsk_compute_mic;eap_gpsk_build_gpsk_3"), 2295 (1, "eap_gpsk_derive_keys;eap_gpsk_process_gpsk_2"), 2296 (1, "eap_gpsk_derive_session_id;eap_gpsk_process_gpsk_2"), 2297 (1, "eap_gpsk_compute_mic;eap_gpsk_process_gpsk_2"), 2298 (1, "eap_gpsk_compute_mic;eap_gpsk_process_gpsk_4")] 2299 for count, func in tests: 2300 with fail_test(hapd, count, func): 2301 run_eap_gpsk_connect(dev[0]) 2302 2303def start_gpsk_assoc(dev, hapd): 2304 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412", 2305 eap="GPSK", identity="gpsk user", 2306 password="abcdefghijklmnop0123456789abcdef", 2307 wait_connect=False) 2308 proxy_msg(hapd, dev) # EAP-Identity/Request 2309 proxy_msg(dev, hapd) # EAP-Identity/Response 2310 proxy_msg(hapd, dev) # GPSK-1 2311 2312def stop_gpsk_assoc(dev, hapd): 2313 dev.request("REMOVE_NETWORK all") 2314 dev.wait_disconnected() 2315 dev.dump_monitor() 2316 hapd.dump_monitor() 2317 2318def test_eap_proto_gpsk_server(dev, apdev): 2319 """EAP-GPSK protocol testing for the server""" 2320 check_eap_capa(dev[0], "GPSK") 2321 params = int_eap_server_params() 2322 params['erp_domain'] = 'example.com' 2323 params['eap_server_erp'] = '1' 2324 hapd = hostapd.add_ap(apdev[0], params) 2325 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 2326 hapd.request("SET ext_eapol_frame_io 1") 2327 dev[0].request("SET ext_eapol_frame_io 1") 2328 2329 # Successful exchange to verify proxying mechanism 2330 start_gpsk_assoc(dev[0], hapd) 2331 proxy_msg(dev[0], hapd) # GPSK-2 2332 proxy_msg(hapd, dev[0]) # GPSK-3 2333 proxy_msg(dev[0], hapd) # GPSK-4 2334 proxy_msg(hapd, dev[0]) # EAP-Success 2335 proxy_msg(hapd, dev[0]) # EAPOL-Key msg 1/4 2336 proxy_msg(dev[0], hapd) # EAPOL-Key msg 2/4 2337 proxy_msg(hapd, dev[0]) # EAPOL-Key msg 3/4 2338 proxy_msg(dev[0], hapd) # EAPOL-Key msg 4/4 2339 dev[0].wait_connected() 2340 stop_gpsk_assoc(dev[0], hapd) 2341 2342 start_gpsk_assoc(dev[0], hapd) 2343 resp = rx_msg(dev[0]) 2344 # Too short EAP-GPSK header (no OP-Code) 2345 # --> EAP-GPSK: Invalid frame 2346 msg = resp[0:4] + "0005" + resp[8:12] + "0005" + "33" 2347 tx_msg(dev[0], hapd, msg) 2348 # Unknown OP-Code 2349 # --> EAP-GPSK: Unexpected opcode=7 in state=0 2350 msg = resp[0:4] + "0006" + resp[8:12] + "0006" + "3307" 2351 tx_msg(dev[0], hapd, msg) 2352 # Too short GPSK-2 2353 # --> EAP-GPSK: Too short message for ID_Peer length 2354 msg = resp[0:4] + "0006" + resp[8:12] + "0006" + "3302" 2355 tx_msg(dev[0], hapd, msg) 2356 rx_msg(hapd) 2357 stop_gpsk_assoc(dev[0], hapd) 2358 2359 start_gpsk_assoc(dev[0], hapd) 2360 resp = rx_msg(dev[0]) 2361 # Too short GPSK-2 2362 # --> EAP-GPSK: Too short message for ID_Peer 2363 msg = resp[0:4] + "0008" + resp[8:12] + "0008" + "33020001" 2364 tx_msg(dev[0], hapd, msg) 2365 rx_msg(hapd) 2366 stop_gpsk_assoc(dev[0], hapd) 2367 2368 start_gpsk_assoc(dev[0], hapd) 2369 resp = rx_msg(dev[0]) 2370 # Too short GPSK-2 2371 # --> EAP-GPSK: Too short message for ID_Server length 2372 msg = resp[0:4] + "0008" + resp[8:12] + "0008" + "33020000" 2373 tx_msg(dev[0], hapd, msg) 2374 rx_msg(hapd) 2375 stop_gpsk_assoc(dev[0], hapd) 2376 2377 start_gpsk_assoc(dev[0], hapd) 2378 resp = rx_msg(dev[0]) 2379 # Too short GPSK-2 2380 # --> EAP-GPSK: Too short message for ID_Server 2381 msg = resp[0:4] + "000a" + resp[8:12] + "000a" + "330200000001" 2382 tx_msg(dev[0], hapd, msg) 2383 rx_msg(hapd) 2384 stop_gpsk_assoc(dev[0], hapd) 2385 2386 start_gpsk_assoc(dev[0], hapd) 2387 resp = rx_msg(dev[0]) 2388 # ID_Server mismatch 2389 # --> EAP-GPSK: ID_Server in GPSK-1 and GPSK-2 did not match 2390 msg = resp[0:4] + "000a" + resp[8:12] + "000a" + "330200000000" 2391 tx_msg(dev[0], hapd, msg) 2392 rx_msg(hapd) 2393 stop_gpsk_assoc(dev[0], hapd) 2394 2395 start_gpsk_assoc(dev[0], hapd) 2396 resp = rx_msg(dev[0]) 2397 # Too short GPSK-2 2398 # --> EAP-GPSK: Too short message for RAND_Peer 2399 msg = resp[0:4] + "0011" + resp[8:12] + "0011" + "330200000007" + binascii.hexlify(b"hostapd").decode() 2400 tx_msg(dev[0], hapd, msg) 2401 rx_msg(hapd) 2402 stop_gpsk_assoc(dev[0], hapd) 2403 2404 start_gpsk_assoc(dev[0], hapd) 2405 resp = rx_msg(dev[0]) 2406 # Too short GPSK-2 2407 # --> EAP-GPSK: Too short message for RAND_Server 2408 msg = resp[0:4] + "0031" + resp[8:12] + "0031" + "330200000007" + binascii.hexlify(b"hostapd").decode() + 32*"00" 2409 tx_msg(dev[0], hapd, msg) 2410 rx_msg(hapd) 2411 stop_gpsk_assoc(dev[0], hapd) 2412 2413 start_gpsk_assoc(dev[0], hapd) 2414 resp = rx_msg(dev[0]) 2415 # RAND_Server mismatch 2416 # --> EAP-GPSK: RAND_Server in GPSK-1 and GPSK-2 did not match 2417 msg = resp[0:4] + "0051" + resp[8:12] + "0051" + "330200000007" + binascii.hexlify(b"hostapd").decode() + 32*"00" + 32*"00" 2418 tx_msg(dev[0], hapd, msg) 2419 rx_msg(hapd) 2420 stop_gpsk_assoc(dev[0], hapd) 2421 2422 start_gpsk_assoc(dev[0], hapd) 2423 resp = rx_msg(dev[0]) 2424 # Too short GPSK-2 2425 # --> EAP-GPSK: Too short message for CSuite_List length 2426 msg = resp[0:4] + "005a" + resp[8:12] + "005a" + resp[16:188] 2427 tx_msg(dev[0], hapd, msg) 2428 rx_msg(hapd) 2429 stop_gpsk_assoc(dev[0], hapd) 2430 2431 start_gpsk_assoc(dev[0], hapd) 2432 resp = rx_msg(dev[0]) 2433 # Too short GPSK-2 2434 # --> EAP-GPSK: Too short message for CSuite_List 2435 msg = resp[0:4] + "005c" + resp[8:12] + "005c" + resp[16:192] 2436 tx_msg(dev[0], hapd, msg) 2437 rx_msg(hapd) 2438 stop_gpsk_assoc(dev[0], hapd) 2439 2440 start_gpsk_assoc(dev[0], hapd) 2441 resp = rx_msg(dev[0]) 2442 # Too short GPSK-2 2443 # --> EAP-GPSK: CSuite_List in GPSK-1 and GPSK-2 did not match 2444 msg = resp[0:4] + "005c" + resp[8:12] + "005c" + resp[16:188] + "0000" 2445 tx_msg(dev[0], hapd, msg) 2446 rx_msg(hapd) 2447 stop_gpsk_assoc(dev[0], hapd) 2448 2449 start_gpsk_assoc(dev[0], hapd) 2450 resp = rx_msg(dev[0]) 2451 # Too short GPSK-2 2452 # --> EAP-GPSK: Too short message for CSuite_Sel 2453 msg = resp[0:4] + "0068" + resp[8:12] + "0068" + resp[16:216] 2454 tx_msg(dev[0], hapd, msg) 2455 rx_msg(hapd) 2456 stop_gpsk_assoc(dev[0], hapd) 2457 2458 start_gpsk_assoc(dev[0], hapd) 2459 resp = rx_msg(dev[0]) 2460 # Unsupported CSuite_Sel 2461 # --> EAP-GPSK: Peer selected unsupported ciphersuite 0:255 2462 msg = resp[0:4] + "006e" + resp[8:12] + "006e" + resp[16:226] + "ff" 2463 tx_msg(dev[0], hapd, msg) 2464 rx_msg(hapd) 2465 stop_gpsk_assoc(dev[0], hapd) 2466 2467 start_gpsk_assoc(dev[0], hapd) 2468 resp = rx_msg(dev[0]) 2469 # Too short GPSK-2 2470 # --> EAP-GPSK: Too short message for PD_Payload_1 length 2471 msg = resp[0:4] + "006e" + resp[8:12] + "006e" + resp[16:228] 2472 tx_msg(dev[0], hapd, msg) 2473 rx_msg(hapd) 2474 stop_gpsk_assoc(dev[0], hapd) 2475 2476 start_gpsk_assoc(dev[0], hapd) 2477 resp = rx_msg(dev[0]) 2478 # Too short GPSK-2 2479 # --> EAP-GPSK: Too short message for PD_Payload_1 2480 msg = resp[0:4] + "0070" + resp[8:12] + "0070" + resp[16:230] + "ff" 2481 tx_msg(dev[0], hapd, msg) 2482 rx_msg(hapd) 2483 stop_gpsk_assoc(dev[0], hapd) 2484 2485 start_gpsk_assoc(dev[0], hapd) 2486 resp = rx_msg(dev[0]) 2487 # Too short GPSK-2 2488 # --> EAP-GPSK: Message too short for MIC (left=0 miclen=16) 2489 msg = resp[0:4] + "0070" + resp[8:12] + "0070" + resp[16:232] 2490 tx_msg(dev[0], hapd, msg) 2491 rx_msg(hapd) 2492 stop_gpsk_assoc(dev[0], hapd) 2493 2494 start_gpsk_assoc(dev[0], hapd) 2495 resp = rx_msg(dev[0]) 2496 # Extra data in the end of GPSK-2 2497 # --> EAP-GPSK: Ignored 1 bytes of extra data in the end of GPSK-2 2498 msg = resp[0:4] + "0081" + resp[8:12] + "0081" + resp[16:264] + "00" 2499 tx_msg(dev[0], hapd, msg) 2500 proxy_msg(hapd, dev[0]) # GPSK-3 2501 resp = rx_msg(dev[0]) 2502 # Too short GPSK-4 2503 # --> EAP-GPSK: Too short message for PD_Payload_1 length 2504 msg = resp[0:4] + "0006" + resp[8:12] + "0006" + "3304" 2505 tx_msg(dev[0], hapd, msg) 2506 rx_msg(hapd) # EAP-Failure 2507 stop_gpsk_assoc(dev[0], hapd) 2508 2509 start_gpsk_assoc(dev[0], hapd) 2510 proxy_msg(dev[0], hapd) # GPSK-2 2511 proxy_msg(hapd, dev[0]) # GPSK-3 2512 resp = rx_msg(dev[0]) 2513 # Too short GPSK-4 2514 # --> EAP-GPSK: Too short message for PD_Payload_1 2515 msg = resp[0:4] + "0008" + resp[8:12] + "0008" + "33040001" 2516 tx_msg(dev[0], hapd, msg) 2517 rx_msg(hapd) # EAP-Failure 2518 stop_gpsk_assoc(dev[0], hapd) 2519 2520 start_gpsk_assoc(dev[0], hapd) 2521 proxy_msg(dev[0], hapd) # GPSK-2 2522 proxy_msg(hapd, dev[0]) # GPSK-3 2523 resp = rx_msg(dev[0]) 2524 # Too short GPSK-4 2525 # --> EAP-GPSK: Message too short for MIC (left=0 miclen=16) 2526 msg = resp[0:4] + "0008" + resp[8:12] + "0008" + "33040000" 2527 tx_msg(dev[0], hapd, msg) 2528 rx_msg(hapd) # EAP-Failure 2529 stop_gpsk_assoc(dev[0], hapd) 2530 2531 start_gpsk_assoc(dev[0], hapd) 2532 proxy_msg(dev[0], hapd) # GPSK-2 2533 proxy_msg(hapd, dev[0]) # GPSK-3 2534 resp = rx_msg(dev[0]) 2535 # Incorrect MIC in GPSK-4 2536 # --> EAP-GPSK: Incorrect MIC in GPSK-4 2537 msg = resp[0:4] + "0018" + resp[8:12] + "0018" + "33040000" + 16*"00" 2538 tx_msg(dev[0], hapd, msg) 2539 rx_msg(hapd) # EAP-Failure 2540 stop_gpsk_assoc(dev[0], hapd) 2541 2542 start_gpsk_assoc(dev[0], hapd) 2543 proxy_msg(dev[0], hapd) # GPSK-2 2544 proxy_msg(hapd, dev[0]) # GPSK-3 2545 resp = rx_msg(dev[0]) 2546 # Incorrect MIC in GPSK-4 2547 # --> EAP-GPSK: Ignored 1 bytes of extra data in the end of GPSK-4 2548 msg = resp[0:4] + "0019" + resp[8:12] + "0019" + resp[16:] + "00" 2549 tx_msg(dev[0], hapd, msg) 2550 rx_msg(hapd) # EAP-Success 2551 stop_gpsk_assoc(dev[0], hapd) 2552 2553EAP_EKE_ID = 1 2554EAP_EKE_COMMIT = 2 2555EAP_EKE_CONFIRM = 3 2556EAP_EKE_FAILURE = 4 2557 2558def test_eap_proto_eke(dev, apdev): 2559 """EAP-EKE protocol tests""" 2560 def eke_handler(ctx, req): 2561 logger.info("eke_handler - RX " + binascii.hexlify(req).decode()) 2562 if 'num' not in ctx: 2563 ctx['num'] = 0 2564 ctx['num'] = ctx['num'] + 1 2565 if 'id' not in ctx: 2566 ctx['id'] = 1 2567 ctx['id'] = (ctx['id'] + 1) % 256 2568 2569 idx = 0 2570 2571 idx += 1 2572 if ctx['num'] == idx: 2573 logger.info("Test: Missing payload") 2574 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 2575 4 + 1, 2576 EAP_TYPE_EKE) 2577 2578 idx += 1 2579 if ctx['num'] == idx: 2580 logger.info("Test: Unknown exchange") 2581 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 2582 4 + 1 + 1, 2583 EAP_TYPE_EKE, 2584 255) 2585 2586 idx += 1 2587 if ctx['num'] == idx: 2588 logger.info("Test: No NumProposals in EAP-EKE-ID/Request") 2589 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 2590 4 + 1 + 1, 2591 EAP_TYPE_EKE, 2592 EAP_EKE_ID) 2593 idx += 1 2594 if ctx['num'] == idx: 2595 logger.info("Test: EAP-Failure") 2596 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 2597 2598 idx += 1 2599 if ctx['num'] == idx: 2600 logger.info("Test: NumProposals=0 in EAP-EKE-ID/Request") 2601 return struct.pack(">BBHBBB", EAP_CODE_REQUEST, ctx['id'], 2602 4 + 1 + 1 + 1, 2603 EAP_TYPE_EKE, 2604 EAP_EKE_ID, 2605 0) 2606 idx += 1 2607 if ctx['num'] == idx: 2608 logger.info("Test: EAP-Failure") 2609 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 2610 2611 idx += 1 2612 if ctx['num'] == idx: 2613 logger.info("Test: Truncated Proposals list in EAP-EKE-ID/Request") 2614 return struct.pack(">BBHBBBB4B", EAP_CODE_REQUEST, ctx['id'], 2615 4 + 1 + 1 + 2 + 4, 2616 EAP_TYPE_EKE, 2617 EAP_EKE_ID, 2618 2, 0, 0, 0, 0, 0) 2619 idx += 1 2620 if ctx['num'] == idx: 2621 logger.info("Test: EAP-Failure") 2622 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 2623 2624 idx += 1 2625 if ctx['num'] == idx: 2626 logger.info("Test: Unsupported proposals in EAP-EKE-ID/Request") 2627 return struct.pack(">BBHBBBB4B4B4B4B", EAP_CODE_REQUEST, ctx['id'], 2628 4 + 1 + 1 + 2 + 4 * 4, 2629 EAP_TYPE_EKE, 2630 EAP_EKE_ID, 2631 4, 0, 2632 0, 0, 0, 0, 2633 3, 0, 0, 0, 2634 3, 1, 0, 0, 2635 3, 1, 1, 0) 2636 idx += 1 2637 if ctx['num'] == idx: 2638 logger.info("Test: EAP-Failure") 2639 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 2640 2641 idx += 1 2642 if ctx['num'] == idx: 2643 logger.info("Test: Missing IDType/Identity in EAP-EKE-ID/Request") 2644 return struct.pack(">BBHBBBB4B4B4B4B4B", 2645 EAP_CODE_REQUEST, ctx['id'], 2646 4 + 1 + 1 + 2 + 5 * 4, 2647 EAP_TYPE_EKE, 2648 EAP_EKE_ID, 2649 5, 0, 2650 0, 0, 0, 0, 2651 3, 0, 0, 0, 2652 3, 1, 0, 0, 2653 3, 1, 1, 0, 2654 3, 1, 1, 1) 2655 idx += 1 2656 if ctx['num'] == idx: 2657 logger.info("Test: EAP-Failure") 2658 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 2659 2660 idx += 1 2661 if ctx['num'] == idx: 2662 logger.info("Test: Valid EAP-EKE-ID/Request") 2663 return struct.pack(">BBHBBBB4BB", 2664 EAP_CODE_REQUEST, ctx['id'], 2665 4 + 1 + 1 + 2 + 4 + 1, 2666 EAP_TYPE_EKE, 2667 EAP_EKE_ID, 2668 1, 0, 2669 3, 1, 1, 1, 2670 255) 2671 idx += 1 2672 if ctx['num'] == idx: 2673 logger.info("Test: Unexpected EAP-EKE-ID/Request") 2674 return struct.pack(">BBHBBBB4BB", 2675 EAP_CODE_REQUEST, ctx['id'], 2676 4 + 1 + 1 + 2 + 4 + 1, 2677 EAP_TYPE_EKE, 2678 EAP_EKE_ID, 2679 1, 0, 2680 3, 1, 1, 1, 2681 255) 2682 idx += 1 2683 if ctx['num'] == idx: 2684 logger.info("Test: EAP-Failure") 2685 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 2686 2687 idx += 1 2688 if ctx['num'] == idx: 2689 logger.info("Test: Valid EAP-EKE-ID/Request") 2690 return struct.pack(">BBHBBBB4BB", 2691 EAP_CODE_REQUEST, ctx['id'], 2692 4 + 1 + 1 + 2 + 4 + 1, 2693 EAP_TYPE_EKE, 2694 EAP_EKE_ID, 2695 1, 0, 2696 3, 1, 1, 1, 2697 255) 2698 idx += 1 2699 if ctx['num'] == idx: 2700 logger.info("Test: Unexpected EAP-EKE-Confirm/Request") 2701 return struct.pack(">BBHBB", 2702 EAP_CODE_REQUEST, ctx['id'], 2703 4 + 1 + 1, 2704 EAP_TYPE_EKE, 2705 EAP_EKE_CONFIRM) 2706 idx += 1 2707 if ctx['num'] == idx: 2708 logger.info("Test: EAP-Failure") 2709 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 2710 2711 idx += 1 2712 if ctx['num'] == idx: 2713 logger.info("Test: Too short EAP-EKE-Failure/Request") 2714 return struct.pack(">BBHBB", 2715 EAP_CODE_REQUEST, ctx['id'], 2716 4 + 1 + 1, 2717 EAP_TYPE_EKE, 2718 EAP_EKE_FAILURE) 2719 idx += 1 2720 if ctx['num'] == idx: 2721 logger.info("Test: EAP-Failure") 2722 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 2723 2724 idx += 1 2725 if ctx['num'] == idx: 2726 logger.info("Test: Unexpected EAP-EKE-Commit/Request") 2727 return struct.pack(">BBHBB", 2728 EAP_CODE_REQUEST, ctx['id'], 2729 4 + 1 + 1, 2730 EAP_TYPE_EKE, 2731 EAP_EKE_COMMIT) 2732 idx += 1 2733 if ctx['num'] == idx: 2734 logger.info("Test: EAP-Failure") 2735 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 2736 2737 idx += 1 2738 if ctx['num'] == idx: 2739 logger.info("Test: Valid EAP-EKE-ID/Request") 2740 return struct.pack(">BBHBBBB4BB", 2741 EAP_CODE_REQUEST, ctx['id'], 2742 4 + 1 + 1 + 2 + 4 + 1, 2743 EAP_TYPE_EKE, 2744 EAP_EKE_ID, 2745 1, 0, 2746 3, 1, 1, 1, 2747 255) 2748 idx += 1 2749 if ctx['num'] == idx: 2750 logger.info("Test: Too short EAP-EKE-Commit/Request") 2751 return struct.pack(">BBHBB", 2752 EAP_CODE_REQUEST, ctx['id'], 2753 4 + 1 + 1, 2754 EAP_TYPE_EKE, 2755 EAP_EKE_COMMIT) 2756 idx += 1 2757 if ctx['num'] == idx: 2758 logger.info("Test: EAP-Failure") 2759 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 2760 2761 idx += 1 2762 if ctx['num'] == idx: 2763 logger.info("Test: Valid EAP-EKE-ID/Request") 2764 return struct.pack(">BBHBBBB4BB", 2765 EAP_CODE_REQUEST, ctx['id'], 2766 4 + 1 + 1 + 2 + 4 + 1, 2767 EAP_TYPE_EKE, 2768 EAP_EKE_ID, 2769 1, 0, 2770 1, 1, 1, 1, 2771 255) 2772 idx += 1 2773 if ctx['num'] == idx: 2774 logger.info("Test: All zeroes DHComponent_S and empty CBvalue in EAP-EKE-Commit/Request") 2775 return struct.pack(">BBHBB4L32L", 2776 EAP_CODE_REQUEST, ctx['id'], 2777 4 + 1 + 1 + 16 + 128, 2778 EAP_TYPE_EKE, 2779 EAP_EKE_COMMIT, 2780 0, 0, 0, 0, 2781 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2782 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) 2783 idx += 1 2784 if ctx['num'] == idx: 2785 logger.info("Test: Too short EAP-EKE-Confirm/Request") 2786 return struct.pack(">BBHBB", 2787 EAP_CODE_REQUEST, ctx['id'], 2788 4 + 1 + 1, 2789 EAP_TYPE_EKE, 2790 EAP_EKE_CONFIRM) 2791 idx += 1 2792 if ctx['num'] == idx: 2793 logger.info("Test: EAP-Failure") 2794 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 2795 2796 idx += 1 2797 if ctx['num'] == idx: 2798 logger.info("Test: Valid EAP-EKE-ID/Request") 2799 return struct.pack(">BBHBBBB4BB", 2800 EAP_CODE_REQUEST, ctx['id'], 2801 4 + 1 + 1 + 2 + 4 + 1, 2802 EAP_TYPE_EKE, 2803 EAP_EKE_ID, 2804 1, 0, 2805 1, 1, 1, 1, 2806 255) 2807 idx += 1 2808 if ctx['num'] == idx: 2809 logger.info("Test: All zeroes DHComponent_S and empty CBvalue in EAP-EKE-Commit/Request") 2810 return struct.pack(">BBHBB4L32L", 2811 EAP_CODE_REQUEST, ctx['id'], 2812 4 + 1 + 1 + 16 + 128, 2813 EAP_TYPE_EKE, 2814 EAP_EKE_COMMIT, 2815 0, 0, 0, 0, 2816 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2817 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) 2818 idx += 1 2819 if ctx['num'] == idx: 2820 logger.info("Test: Invalid PNonce_PS and Auth_S values in EAP-EKE-Confirm/Request") 2821 return struct.pack(">BBHBB4L8L5L5L", 2822 EAP_CODE_REQUEST, ctx['id'], 2823 4 + 1 + 1 + 16 + 2 * 16 + 20 + 20, 2824 EAP_TYPE_EKE, 2825 EAP_EKE_CONFIRM, 2826 0, 0, 0, 0, 2827 0, 0, 0, 0, 0, 0, 0, 0, 2828 0, 0, 0, 0, 0, 2829 0, 0, 0, 0, 0) 2830 idx += 1 2831 if ctx['num'] == idx: 2832 logger.info("Test: EAP-Failure") 2833 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 2834 2835 return None 2836 2837 srv = start_radius_server(eke_handler) 2838 2839 try: 2840 hapd = start_ap(apdev[0]) 2841 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 2842 2843 for i in range(0, 14): 2844 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 2845 eap="EKE", identity="user", password="password", 2846 wait_connect=False) 2847 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 2848 timeout=15) 2849 if ev is None: 2850 raise Exception("Timeout on EAP start") 2851 if i in [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]: 2852 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], 2853 timeout=10) 2854 if ev is None: 2855 raise Exception("Timeout on EAP failure") 2856 else: 2857 time.sleep(0.05) 2858 dev[0].request("REMOVE_NETWORK all") 2859 dev[0].dump_monitor() 2860 finally: 2861 stop_radius_server(srv) 2862 2863def eap_eke_test_fail(dev, phase1=None, success=False): 2864 dev.connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 2865 eap="EKE", identity="eke user@domain", password="hello", 2866 phase1=phase1, erp="1", wait_connect=False) 2867 ev = dev.wait_event(["CTRL-EVENT-EAP-FAILURE", 2868 "CTRL-EVENT-EAP-SUCCESS"], timeout=5) 2869 if ev is None: 2870 raise Exception("Timeout on EAP failure") 2871 if not success and "CTRL-EVENT-EAP-FAILURE" not in ev: 2872 raise Exception("EAP did not fail during failure test") 2873 dev.request("REMOVE_NETWORK all") 2874 dev.wait_disconnected() 2875 2876def test_eap_proto_eke_errors(dev, apdev): 2877 """EAP-EKE local error cases""" 2878 check_eap_capa(dev[0], "EKE") 2879 params = hostapd.wpa2_eap_params(ssid="eap-test") 2880 hapd = hostapd.add_ap(apdev[0], params) 2881 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 2882 2883 for i in range(1, 3): 2884 with alloc_fail(dev[0], i, "eap_eke_init"): 2885 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 2886 eap="EKE", identity="eke user", password="hello", 2887 wait_connect=False) 2888 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"], 2889 timeout=15) 2890 if ev is None: 2891 raise Exception("Timeout on EAP start") 2892 dev[0].request("REMOVE_NETWORK all") 2893 dev[0].wait_disconnected() 2894 2895 tests = [(1, "eap_eke_dh_init", None), 2896 (1, "eap_eke_prf_hmac_sha1", "dhgroup=3 encr=1 prf=1 mac=1"), 2897 (1, "eap_eke_prf_hmac_sha256", "dhgroup=5 encr=1 prf=2 mac=2"), 2898 (1, "eap_eke_prf_*", None), 2899 (1, "os_get_random;eap_eke_dhcomp", None), 2900 (1, "aes_128_cbc_encrypt;eap_eke_dhcomp", None), 2901 (1, "aes_128_cbc_decrypt;eap_eke_shared_secret", None), 2902 (1, "hmac_sha256_vector;eap_eke_shared_secret", None), 2903 (1, "eap_eke_prf_hmac_sha256;eap_eke_derive_ke_ki", None), 2904 (1, "eap_eke_prf_hmac_sha256;eap_eke_derive_ka", None), 2905 (1, "eap_eke_prf_hmac_sha256;eap_eke_derive_msk", None), 2906 (1, "os_get_random;eap_eke_prot", None), 2907 (1, "aes_128_cbc_decrypt;eap_eke_decrypt_prot", None), 2908 (1, "eap_eke_derive_key;eap_eke_process_commit", None), 2909 (1, "eap_eke_dh_init;eap_eke_process_commit", None), 2910 (1, "eap_eke_shared_secret;eap_eke_process_commit", None), 2911 (1, "eap_eke_derive_ke_ki;eap_eke_process_commit", None), 2912 (1, "eap_eke_dhcomp;eap_eke_process_commit", None), 2913 (1, "os_get_random;eap_eke_process_commit", None), 2914 (1, "os_get_random;=eap_eke_process_commit", None), 2915 (1, "eap_eke_prot;eap_eke_process_commit", None), 2916 (1, "eap_eke_decrypt_prot;eap_eke_process_confirm", None), 2917 (1, "eap_eke_derive_ka;eap_eke_process_confirm", None), 2918 (1, "eap_eke_auth;eap_eke_process_confirm", None), 2919 (2, "eap_eke_auth;eap_eke_process_confirm", None), 2920 (1, "eap_eke_prot;eap_eke_process_confirm", None), 2921 (1, "aes_128_cbc_encrypt;eap_eke_prot;eap_eke_process_confirm", None), 2922 (1, "hmac_sha256;eap_eke_prot;eap_eke_process_confirm", None), 2923 (1, "eap_eke_derive_msk;eap_eke_process_confirm", None)] 2924 for count, func, phase1 in tests: 2925 with fail_test(dev[0], count, func): 2926 eap_eke_test_fail(dev[0], phase1) 2927 2928 tests = [(1, "=eap_eke_derive_ke_ki", None), 2929 (1, "=eap_eke_derive_ka", None), 2930 (1, "=eap_eke_derive_msk", None), 2931 (1, "eap_eke_build_msg;eap_eke_process_id", None), 2932 (1, "wpabuf_alloc;eap_eke_process_id", None), 2933 (1, "=eap_eke_process_id", None), 2934 (1, "wpabuf_alloc;=eap_eke_process_id", None), 2935 (1, "wpabuf_alloc;eap_eke_process_id", None), 2936 (1, "eap_eke_build_msg;eap_eke_process_commit", None), 2937 (1, "wpabuf_resize;eap_eke_process_commit", None), 2938 (1, "eap_eke_build_msg;eap_eke_process_confirm", None)] 2939 for count, func, phase1 in tests: 2940 with alloc_fail(dev[0], count, func): 2941 eap_eke_test_fail(dev[0], phase1) 2942 2943 tests = [(1, "eap_eke_getKey", None), 2944 (1, "eap_eke_get_emsk", None), 2945 (1, "eap_eke_get_session_id", None)] 2946 for count, func, phase1 in tests: 2947 with alloc_fail(dev[0], count, func): 2948 eap_eke_test_fail(dev[0], phase1, success=True) 2949 2950EAP_PAX_OP_STD_1 = 0x01 2951EAP_PAX_OP_STD_2 = 0x02 2952EAP_PAX_OP_STD_3 = 0x03 2953EAP_PAX_OP_SEC_1 = 0x11 2954EAP_PAX_OP_SEC_2 = 0x12 2955EAP_PAX_OP_SEC_3 = 0x13 2956EAP_PAX_OP_SEC_4 = 0x14 2957EAP_PAX_OP_SEC_5 = 0x15 2958EAP_PAX_OP_ACK = 0x21 2959 2960EAP_PAX_FLAGS_MF = 0x01 2961EAP_PAX_FLAGS_CE = 0x02 2962EAP_PAX_FLAGS_AI = 0x04 2963 2964EAP_PAX_MAC_HMAC_SHA1_128 = 0x01 2965EAP_PAX_HMAC_SHA256_128 = 0x02 2966 2967EAP_PAX_DH_GROUP_NONE = 0x00 2968EAP_PAX_DH_GROUP_2048_MODP = 0x01 2969EAP_PAX_DH_GROUP_3072_MODP = 0x02 2970EAP_PAX_DH_GROUP_NIST_ECC_P_256 = 0x03 2971 2972EAP_PAX_PUBLIC_KEY_NONE = 0x00 2973EAP_PAX_PUBLIC_KEY_RSAES_OAEP = 0x01 2974EAP_PAX_PUBLIC_KEY_RSA_PKCS1_V1_5 = 0x02 2975EAP_PAX_PUBLIC_KEY_EL_GAMAL_NIST_ECC = 0x03 2976 2977EAP_PAX_ADE_VENDOR_SPECIFIC = 0x01 2978EAP_PAX_ADE_CLIENT_CHANNEL_BINDING = 0x02 2979EAP_PAX_ADE_SERVER_CHANNEL_BINDING = 0x03 2980 2981def test_eap_proto_pax(dev, apdev): 2982 """EAP-PAX protocol tests""" 2983 def pax_std_1(ctx): 2984 logger.info("Test: STD-1") 2985 ctx['id'] = 10 2986 return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'], 2987 4 + 1 + 5 + 2 + 32 + 16, 2988 EAP_TYPE_PAX, 2989 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128, 2990 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE, 2991 32, 0, 0, 0, 0, 0, 0, 0, 0, 2992 0x16, 0xc9, 0x08, 0x9d, 0x98, 0xa5, 0x6e, 0x1f, 2993 0xf0, 0xac, 0xcf, 0xc4, 0x66, 0xcd, 0x2d, 0xbf) 2994 2995 def pax_handler(ctx, req): 2996 logger.info("pax_handler - RX " + binascii.hexlify(req).decode()) 2997 if 'num' not in ctx: 2998 ctx['num'] = 0 2999 ctx['num'] = ctx['num'] + 1 3000 if 'id' not in ctx: 3001 ctx['id'] = 1 3002 ctx['id'] = (ctx['id'] + 1) % 256 3003 3004 idx = 0 3005 3006 idx += 1 3007 if ctx['num'] == idx: 3008 logger.info("Test: Missing payload") 3009 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 3010 4 + 1, 3011 EAP_TYPE_PAX) 3012 3013 idx += 1 3014 if ctx['num'] == idx: 3015 logger.info("Test: Minimum length payload") 3016 return struct.pack(">BBHB4L", EAP_CODE_REQUEST, ctx['id'], 3017 4 + 1 + 16, 3018 EAP_TYPE_PAX, 3019 0, 0, 0, 0) 3020 3021 idx += 1 3022 if ctx['num'] == idx: 3023 logger.info("Test: Unsupported MAC ID") 3024 return struct.pack(">BBHBBBBBB4L", EAP_CODE_REQUEST, ctx['id'], 3025 4 + 1 + 5 + 16, 3026 EAP_TYPE_PAX, 3027 EAP_PAX_OP_STD_1, 0, 255, EAP_PAX_DH_GROUP_NONE, 3028 EAP_PAX_PUBLIC_KEY_NONE, 3029 0, 0, 0, 0) 3030 3031 idx += 1 3032 if ctx['num'] == idx: 3033 logger.info("Test: Unsupported DH Group ID") 3034 return struct.pack(">BBHBBBBBB4L", EAP_CODE_REQUEST, ctx['id'], 3035 4 + 1 + 5 + 16, 3036 EAP_TYPE_PAX, 3037 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128, 3038 255, EAP_PAX_PUBLIC_KEY_NONE, 3039 0, 0, 0, 0) 3040 3041 idx += 1 3042 if ctx['num'] == idx: 3043 logger.info("Test: Unsupported Public Key ID") 3044 return struct.pack(">BBHBBBBBB4L", EAP_CODE_REQUEST, ctx['id'], 3045 4 + 1 + 5 + 16, 3046 EAP_TYPE_PAX, 3047 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128, 3048 EAP_PAX_DH_GROUP_NONE, 255, 3049 0, 0, 0, 0) 3050 3051 idx += 1 3052 if ctx['num'] == idx: 3053 logger.info("Test: More fragments") 3054 return struct.pack(">BBHBBBBBB4L", EAP_CODE_REQUEST, ctx['id'], 3055 4 + 1 + 5 + 16, 3056 EAP_TYPE_PAX, 3057 EAP_PAX_OP_STD_1, EAP_PAX_FLAGS_MF, 3058 EAP_PAX_MAC_HMAC_SHA1_128, 3059 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE, 3060 0, 0, 0, 0) 3061 3062 idx += 1 3063 if ctx['num'] == idx: 3064 logger.info("Test: Invalid ICV") 3065 return struct.pack(">BBHBBBBBB4L", EAP_CODE_REQUEST, ctx['id'], 3066 4 + 1 + 5 + 16, 3067 EAP_TYPE_PAX, 3068 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128, 3069 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE, 3070 0, 0, 0, 0) 3071 3072 idx += 1 3073 if ctx['num'] == idx: 3074 logger.info("Test: Invalid ICV in short frame") 3075 return struct.pack(">BBHBBBBBB3L", EAP_CODE_REQUEST, ctx['id'], 3076 4 + 1 + 5 + 12, 3077 EAP_TYPE_PAX, 3078 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128, 3079 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE, 3080 0, 0, 0) 3081 3082 idx += 1 3083 if ctx['num'] == idx: 3084 logger.info("Test: Correct ICV - unsupported op_code") 3085 ctx['id'] = 10 3086 return struct.pack(">BBHBBBBBB16B", EAP_CODE_REQUEST, ctx['id'], 3087 4 + 1 + 5 + 16, 3088 EAP_TYPE_PAX, 3089 255, 0, EAP_PAX_MAC_HMAC_SHA1_128, 3090 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE, 3091 0x90, 0x78, 0x97, 0x38, 0x29, 0x94, 0x32, 0xd4, 3092 0x81, 0x27, 0xe0, 0xf6, 0x3b, 0x0d, 0xb2, 0xb2) 3093 3094 idx += 1 3095 if ctx['num'] == idx: 3096 logger.info("Test: Correct ICV - CE flag in STD-1") 3097 ctx['id'] = 10 3098 return struct.pack(">BBHBBBBBB16B", EAP_CODE_REQUEST, ctx['id'], 3099 4 + 1 + 5 + 16, 3100 EAP_TYPE_PAX, 3101 EAP_PAX_OP_STD_1, EAP_PAX_FLAGS_CE, 3102 EAP_PAX_MAC_HMAC_SHA1_128, 3103 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE, 3104 0x9c, 0x98, 0xb4, 0x0b, 0x94, 0x90, 0xde, 0x88, 3105 0xb7, 0x72, 0x63, 0x44, 0x1d, 0xe3, 0x7c, 0x5c) 3106 3107 idx += 1 3108 if ctx['num'] == idx: 3109 logger.info("Test: Correct ICV - too short STD-1 payload") 3110 ctx['id'] = 10 3111 return struct.pack(">BBHBBBBBB16B", EAP_CODE_REQUEST, ctx['id'], 3112 4 + 1 + 5 + 16, 3113 EAP_TYPE_PAX, 3114 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128, 3115 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE, 3116 0xda, 0xab, 0x2c, 0xe7, 0x84, 0x41, 0xb5, 0x5c, 3117 0xee, 0xcf, 0x62, 0x03, 0xc5, 0x69, 0xcb, 0xf4) 3118 3119 idx += 1 3120 if ctx['num'] == idx: 3121 logger.info("Test: Correct ICV - incorrect A length in STD-1") 3122 ctx['id'] = 10 3123 return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'], 3124 4 + 1 + 5 + 2 + 32 + 16, 3125 EAP_TYPE_PAX, 3126 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128, 3127 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE, 3128 0, 0, 0, 0, 0, 0, 0, 0, 0, 3129 0xc4, 0xb0, 0x81, 0xe4, 0x6c, 0x8c, 0x20, 0x23, 3130 0x60, 0x46, 0x89, 0xea, 0x94, 0x60, 0xf3, 0x2a) 3131 3132 idx += 1 3133 if ctx['num'] == idx: 3134 logger.info("Test: Correct ICV - extra data in STD-1") 3135 ctx['id'] = 10 3136 return struct.pack(">BBHBBBBBBH8LB16B", EAP_CODE_REQUEST, ctx['id'], 3137 4 + 1 + 5 + 2 + 32 + 1 + 16, 3138 EAP_TYPE_PAX, 3139 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128, 3140 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE, 3141 32, 0, 0, 0, 0, 0, 0, 0, 0, 3142 1, 3143 0x61, 0x49, 0x65, 0x37, 0x21, 0xe8, 0xd8, 0xbf, 3144 0xf3, 0x02, 0x01, 0xe5, 0x42, 0x51, 0xd3, 0x34) 3145 idx += 1 3146 if ctx['num'] == idx: 3147 logger.info("Test: Unexpected STD-1") 3148 return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'], 3149 4 + 1 + 5 + 2 + 32 + 16, 3150 EAP_TYPE_PAX, 3151 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128, 3152 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE, 3153 32, 0, 0, 0, 0, 0, 0, 0, 0, 3154 0xe5, 0x1d, 0xbf, 0xb8, 0x70, 0x20, 0x5c, 0xba, 3155 0x41, 0xbb, 0x34, 0xda, 0x1a, 0x08, 0xe6, 0x8d) 3156 3157 idx += 1 3158 if ctx['num'] == idx: 3159 return pax_std_1(ctx) 3160 idx += 1 3161 if ctx['num'] == idx: 3162 logger.info("Test: MAC ID changed during session") 3163 return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'], 3164 4 + 1 + 5 + 2 + 32 + 16, 3165 EAP_TYPE_PAX, 3166 EAP_PAX_OP_STD_1, 0, EAP_PAX_HMAC_SHA256_128, 3167 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE, 3168 32, 0, 0, 0, 0, 0, 0, 0, 0, 3169 0xee, 0x00, 0xbf, 0xb8, 0x70, 0x20, 0x5c, 0xba, 3170 0x41, 0xbb, 0x34, 0xda, 0x1a, 0x08, 0xe6, 0x8d) 3171 3172 idx += 1 3173 if ctx['num'] == idx: 3174 return pax_std_1(ctx) 3175 idx += 1 3176 if ctx['num'] == idx: 3177 logger.info("Test: DH Group ID changed during session") 3178 return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'], 3179 4 + 1 + 5 + 2 + 32 + 16, 3180 EAP_TYPE_PAX, 3181 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128, 3182 EAP_PAX_DH_GROUP_2048_MODP, 3183 EAP_PAX_PUBLIC_KEY_NONE, 3184 32, 0, 0, 0, 0, 0, 0, 0, 0, 3185 0xee, 0x01, 0xbf, 0xb8, 0x70, 0x20, 0x5c, 0xba, 3186 0x41, 0xbb, 0x34, 0xda, 0x1a, 0x08, 0xe6, 0x8d) 3187 3188 idx += 1 3189 if ctx['num'] == idx: 3190 return pax_std_1(ctx) 3191 idx += 1 3192 if ctx['num'] == idx: 3193 logger.info("Test: Public Key ID changed during session") 3194 return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'], 3195 4 + 1 + 5 + 2 + 32 + 16, 3196 EAP_TYPE_PAX, 3197 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128, 3198 EAP_PAX_DH_GROUP_NONE, 3199 EAP_PAX_PUBLIC_KEY_RSAES_OAEP, 3200 32, 0, 0, 0, 0, 0, 0, 0, 0, 3201 0xee, 0x02, 0xbf, 0xb8, 0x70, 0x20, 0x5c, 0xba, 3202 0x41, 0xbb, 0x34, 0xda, 0x1a, 0x08, 0xe6, 0x8d) 3203 3204 idx += 1 3205 if ctx['num'] == idx: 3206 logger.info("Test: Unexpected STD-3") 3207 ctx['id'] = 10 3208 return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'], 3209 4 + 1 + 5 + 2 + 32 + 16, 3210 EAP_TYPE_PAX, 3211 EAP_PAX_OP_STD_3, 0, EAP_PAX_MAC_HMAC_SHA1_128, 3212 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE, 3213 32, 0, 0, 0, 0, 0, 0, 0, 0, 3214 0x47, 0xbb, 0xc0, 0xf9, 0xb9, 0x69, 0xf5, 0xcb, 3215 0x3a, 0xe8, 0xe7, 0xd6, 0x80, 0x28, 0xf2, 0x59) 3216 3217 idx += 1 3218 if ctx['num'] == idx: 3219 return pax_std_1(ctx) 3220 idx += 1 3221 if ctx['num'] == idx: 3222 # TODO: MAC calculation; for now, this gets dropped due to incorrect 3223 # ICV 3224 logger.info("Test: STD-3 with CE flag") 3225 return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'], 3226 4 + 1 + 5 + 2 + 32 + 16, 3227 EAP_TYPE_PAX, 3228 EAP_PAX_OP_STD_3, EAP_PAX_FLAGS_CE, 3229 EAP_PAX_MAC_HMAC_SHA1_128, 3230 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE, 3231 32, 0, 0, 0, 0, 0, 0, 0, 0, 3232 0x8a, 0xc2, 0xf9, 0xf4, 0x8b, 0x75, 0x72, 0xa2, 3233 0x4d, 0xd3, 0x1e, 0x54, 0x77, 0x04, 0x05, 0xe2) 3234 3235 idx += 1 3236 if ctx['num'] & 0x1 == idx & 0x1: 3237 logger.info("Test: Default request") 3238 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 3239 4 + 1, 3240 EAP_TYPE_PAX) 3241 else: 3242 logger.info("Test: Default EAP-Failure") 3243 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 3244 3245 srv = start_radius_server(pax_handler) 3246 3247 try: 3248 hapd = start_ap(apdev[0]) 3249 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 3250 3251 for i in range(0, 18): 3252 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 3253 eap="PAX", identity="user", 3254 password_hex="0123456789abcdef0123456789abcdef", 3255 wait_connect=False) 3256 logger.info("Waiting for EAP method to start") 3257 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 3258 timeout=15) 3259 if ev is None: 3260 raise Exception("Timeout on EAP start") 3261 time.sleep(0.05) 3262 dev[0].request("REMOVE_NETWORK all") 3263 dev[0].dump_monitor() 3264 3265 logger.info("Too short password") 3266 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 3267 eap="PAX", identity="user", 3268 password_hex="0123456789abcdef0123456789abcd", 3269 wait_connect=False) 3270 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15) 3271 if ev is None: 3272 raise Exception("Timeout on EAP start") 3273 time.sleep(0.1) 3274 dev[0].request("REMOVE_NETWORK all") 3275 dev[0].dump_monitor() 3276 3277 logger.info("No password") 3278 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 3279 eap="PAX", identity="user", 3280 wait_connect=False) 3281 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15) 3282 if ev is None: 3283 raise Exception("Timeout on EAP start") 3284 time.sleep(0.1) 3285 dev[0].request("REMOVE_NETWORK all") 3286 dev[0].dump_monitor() 3287 finally: 3288 stop_radius_server(srv) 3289 3290def test_eap_proto_pax_errors(dev, apdev): 3291 """EAP-PAX local error cases""" 3292 check_eap_capa(dev[0], "PAX") 3293 params = hostapd.wpa2_eap_params(ssid="eap-test") 3294 hapd = hostapd.add_ap(apdev[0], params) 3295 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 3296 3297 for i in range(1, 3): 3298 with alloc_fail(dev[0], i, "eap_pax_init"): 3299 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 3300 eap="PAX", identity="pax.user@example.com", 3301 password_hex="0123456789abcdef0123456789abcdef", 3302 wait_connect=False) 3303 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"], 3304 timeout=15) 3305 if ev is None: 3306 raise Exception("Timeout on EAP start") 3307 dev[0].request("REMOVE_NETWORK all") 3308 dev[0].wait_disconnected() 3309 3310 tests = ["eap_msg_alloc;eap_pax_alloc_resp;eap_pax_process_std_1", 3311 "eap_msg_alloc;eap_pax_alloc_resp;eap_pax_process_std_3", 3312 "eap_pax_getKey", 3313 "eap_pax_get_emsk", 3314 "eap_pax_get_session_id"] 3315 for func in tests: 3316 with alloc_fail(dev[0], 1, func): 3317 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 3318 eap="PAX", identity="pax.user@example.com", 3319 password_hex="0123456789abcdef0123456789abcdef", 3320 erp="1", wait_connect=False) 3321 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 3322 dev[0].request("REMOVE_NETWORK all") 3323 dev[0].wait_disconnected() 3324 3325 tests = [(1, "os_get_random;eap_pax_process_std_1"), 3326 (1, "eap_pax_initial_key_derivation"), 3327 (1, "eap_pax_mac;eap_pax_process_std_3"), 3328 (2, "eap_pax_mac;eap_pax_process_std_3"), 3329 (1, "eap_pax_kdf;eap_pax_getKey"), 3330 (1, "eap_pax_kdf;eap_pax_get_emsk")] 3331 for count, func in tests: 3332 with fail_test(dev[0], count, func): 3333 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 3334 eap="PAX", identity="pax.user@example.com", 3335 password_hex="0123456789abcdef0123456789abcdef", 3336 erp="1", wait_connect=False) 3337 wait_fail_trigger(dev[0], "GET_FAIL") 3338 dev[0].request("REMOVE_NETWORK all") 3339 dev[0].wait_disconnected() 3340 3341def run_eap_pax_connect(dev): 3342 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412", 3343 eap="PAX", identity="pax.user@example.com", 3344 password_hex="0123456789abcdef0123456789abcdef", 3345 wait_connect=False) 3346 ev = dev.wait_event(["CTRL-EVENT-EAP-SUCCESS", "CTRL-EVENT-EAP-FAILURE", 3347 "CTRL-EVENT-DISCONNECTED"], 3348 timeout=1) 3349 dev.request("REMOVE_NETWORK all") 3350 if not ev or "CTRL-EVENT-DISCONNECTED" not in ev: 3351 dev.wait_disconnected() 3352 dev.dump_monitor() 3353 3354def test_eap_proto_pax_errors_server(dev, apdev): 3355 """EAP-PAX local error cases on server""" 3356 check_eap_capa(dev[0], "PAX") 3357 params = int_eap_server_params() 3358 params['erp_domain'] = 'example.com' 3359 params['eap_server_erp'] = '1' 3360 hapd = hostapd.add_ap(apdev[0], params) 3361 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 3362 3363 tests = [(1, "eap_pax_init"), 3364 (1, "eap_msg_alloc;eap_pax_build_std_1"), 3365 (1, "eap_msg_alloc;eap_pax_build_std_3"), 3366 (1, "=eap_pax_process_std_2"), 3367 (1, "eap_pax_getKey"), 3368 (1, "eap_pax_get_emsk"), 3369 (1, "eap_pax_get_session_id")] 3370 for count, func in tests: 3371 with alloc_fail(hapd, count, func): 3372 run_eap_pax_connect(dev[0]) 3373 3374 tests = [(1, "os_get_random;eap_pax_build_std_1"), 3375 (1, "eap_pax_mac;eap_pax_build_std_1"), 3376 (1, "eap_pax_mac;eap_pax_build_std_3"), 3377 (2, "eap_pax_mac;=eap_pax_build_std_3"), 3378 (1, "eap_pax_initial_key_derivation;eap_pax_process_std_2"), 3379 (1, "eap_pax_mac;eap_pax_process_std_2"), 3380 (2, "eap_pax_mac;=eap_pax_process_std_2"), 3381 (1, "eap_pax_mac;eap_pax_check")] 3382 for count, func in tests: 3383 with fail_test(hapd, count, func): 3384 run_eap_pax_connect(dev[0]) 3385 3386def start_pax_assoc(dev, hapd): 3387 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412", 3388 eap="PAX", identity="pax.user@example.com", 3389 password_hex="0123456789abcdef0123456789abcdef", 3390 wait_connect=False) 3391 proxy_msg(hapd, dev) # EAP-Identity/Request 3392 proxy_msg(dev, hapd) # EAP-Identity/Response 3393 proxy_msg(hapd, dev) # PAX_STD-1 3394 3395def stop_pax_assoc(dev, hapd): 3396 dev.request("REMOVE_NETWORK all") 3397 dev.wait_disconnected() 3398 dev.dump_monitor() 3399 hapd.dump_monitor() 3400 3401def test_eap_proto_pax_server(dev, apdev): 3402 """EAP-PAX protocol testing for the server""" 3403 check_eap_capa(dev[0], "PAX") 3404 params = int_eap_server_params() 3405 params['erp_domain'] = 'example.com' 3406 params['eap_server_erp'] = '1' 3407 hapd = hostapd.add_ap(apdev[0], params) 3408 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 3409 hapd.request("SET ext_eapol_frame_io 1") 3410 dev[0].request("SET ext_eapol_frame_io 1") 3411 3412 # Successful exchange to verify proxying mechanism 3413 start_pax_assoc(dev[0], hapd) 3414 proxy_msg(dev[0], hapd) # PAX_STD-2 3415 proxy_msg(hapd, dev[0]) # PAX_STD-3 3416 proxy_msg(dev[0], hapd) # PAX-ACK 3417 proxy_msg(hapd, dev[0]) # EAP-Success 3418 proxy_msg(hapd, dev[0]) # EAPOL-Key msg 1/4 3419 proxy_msg(dev[0], hapd) # EAPOL-Key msg 2/4 3420 proxy_msg(hapd, dev[0]) # EAPOL-Key msg 3/4 3421 proxy_msg(dev[0], hapd) # EAPOL-Key msg 4/4 3422 dev[0].wait_connected() 3423 stop_pax_assoc(dev[0], hapd) 3424 3425 start_pax_assoc(dev[0], hapd) 3426 resp = rx_msg(dev[0]) 3427 # Too short EAP-PAX header (no OP-Code) 3428 hapd.note("EAP-PAX: Invalid frame") 3429 msg = resp[0:4] + "0005" + resp[8:12] + "0005" + "2e" 3430 tx_msg(dev[0], hapd, msg) 3431 # Too short EAP-PAX message (no payload) 3432 hapd.note("EAP-PAX: Invalid frame") 3433 msg = resp[0:4] + "000a" + resp[8:12] + "000a" + "2e1100000000" 3434 tx_msg(dev[0], hapd, msg) 3435 # Unexpected PAX_SEC-2 3436 hapd.note("EAP-PAX: Expected PAX_STD-2 - ignore op 17") 3437 msg = resp[0:4] + "001a" + resp[8:12] + "001a" + "2e1100000000" + 16*"00" 3438 tx_msg(dev[0], hapd, msg) 3439 # Unexpected MAC ID 3440 hapd.note("EAP-PAX: Expected MAC ID 0x1, received 0xff") 3441 msg = resp[0:4] + "001a" + resp[8:12] + "001a" + "2e0200ff0000" + 16*"00" 3442 tx_msg(dev[0], hapd, msg) 3443 # Unexpected DH Group ID 3444 hapd.note("EAP-PAX: Expected DH Group ID 0x0, received 0xff") 3445 msg = resp[0:4] + "001a" + resp[8:12] + "001a" + "2e020001ff00" + 16*"00" 3446 tx_msg(dev[0], hapd, msg) 3447 # Unexpected Public Key ID 3448 hapd.note("EAP-PAX: Expected Public Key ID 0x0, received 0xff") 3449 msg = resp[0:4] + "001a" + resp[8:12] + "001a" + "2e02000100ff" + 16*"00" 3450 tx_msg(dev[0], hapd, msg) 3451 # Unsupported Flags - MF 3452 hapd.note("EAP-PAX: fragmentation not supported") 3453 msg = resp[0:4] + "001a" + resp[8:12] + "001a" + "2e0201010000" + 16*"00" 3454 tx_msg(dev[0], hapd, msg) 3455 # Unsupported Flags - CE 3456 hapd.note("EAP-PAX: Unexpected CE flag") 3457 msg = resp[0:4] + "001a" + resp[8:12] + "001a" + "2e0202010000" + 16*"00" 3458 tx_msg(dev[0], hapd, msg) 3459 # Too short Payload in PAX_STD-2 3460 hapd.note("EAP-PAX: Too short PAX_STD-2 (B)") 3461 msg = resp[0:4] + "001a" + resp[8:12] + "001a" + "2e0200010000" + 16*"00" 3462 tx_msg(dev[0], hapd, msg) 3463 rx_msg(hapd) 3464 stop_pax_assoc(dev[0], hapd) 3465 3466 start_pax_assoc(dev[0], hapd) 3467 resp = rx_msg(dev[0]) 3468 # Too short Payload in PAX_STD-2 3469 hapd.note("EAP-PAX: Too short PAX_STD-2 (CID)") 3470 msg = resp[0:4] + "002c" + resp[8:12] + "002c" + "2e0200010000" + "0020" + 32*"00" 3471 tx_msg(dev[0], hapd, msg) 3472 rx_msg(hapd) 3473 stop_pax_assoc(dev[0], hapd) 3474 3475 start_pax_assoc(dev[0], hapd) 3476 resp = rx_msg(dev[0]) 3477 # Too short Payload in PAX_STD-2 3478 hapd.note("EAP-PAX: Too short PAX_STD-2 (CID)") 3479 msg = resp[0:4] + "002e" + resp[8:12] + "002e" + "2e0200010000" + "0020" + 32*"00" + "ffff" 3480 tx_msg(dev[0], hapd, msg) 3481 rx_msg(hapd) 3482 stop_pax_assoc(dev[0], hapd) 3483 3484 start_pax_assoc(dev[0], hapd) 3485 resp = rx_msg(dev[0]) 3486 # Too long CID in PAX_STD-2 3487 hapd.note("EAP-PAX: Too long CID") 3488 msg = resp[0:4] + "062e" + resp[8:12] + "062e" + "2e0200010000" + "0020" + 32*"00" + "0600" + 1536*"00" 3489 tx_msg(dev[0], hapd, msg) 3490 rx_msg(hapd) 3491 stop_pax_assoc(dev[0], hapd) 3492 3493 start_pax_assoc(dev[0], hapd) 3494 resp = rx_msg(dev[0]) 3495 # Too short Payload in PAX_STD-2 3496 hapd.note("EAP-PAX: Too short PAX_STD-2 (MAC_CK)") 3497 msg = resp[0:4] + "003c" + resp[8:12] + "003c" + "2e0200010000" + "0020" + 32*"00" + 16*"00" 3498 tx_msg(dev[0], hapd, msg) 3499 rx_msg(hapd) 3500 stop_pax_assoc(dev[0], hapd) 3501 3502 start_pax_assoc(dev[0], hapd) 3503 resp = rx_msg(dev[0]) 3504 # Unknown CID for PAX 3505 hapd.note("EAP-PAX: EAP-PAX not enabled for CID") 3506 msg = resp[0:4] + "0041" + resp[8:12] + "0041" + "2e0200010000" + "0020" + 32*"00" + "0001" + "00" + "0010" + 16*"00" 3507 tx_msg(dev[0], hapd, msg) 3508 rx_msg(hapd) 3509 stop_pax_assoc(dev[0], hapd) 3510 3511 start_pax_assoc(dev[0], hapd) 3512 resp = rx_msg(dev[0]) 3513 # Too short ICV 3514 hapd.note("EAP-PAX: Too short ICV (15) in PAX_STD-2") 3515 msg = resp[0:4] + "0063" + resp[8:12] + "0063" + resp[16:206] 3516 tx_msg(dev[0], hapd, msg) 3517 rx_msg(hapd) 3518 stop_pax_assoc(dev[0], hapd) 3519 3520 start_pax_assoc(dev[0], hapd) 3521 proxy_msg(dev[0], hapd) # PAX_STD-2 3522 proxy_msg(hapd, dev[0]) # PAX_STD-3 3523 resp = rx_msg(dev[0]) 3524 # Unexpected PAX_STD-2 3525 hapd.note("EAP-PAX: Expected PAX-ACK - ignore op 1") 3526 msg = resp[0:4] + "001a" + resp[8:12] + "001a" + "2e0100000000" + 16*"00" 3527 tx_msg(dev[0], hapd, msg) 3528 stop_pax_assoc(dev[0], hapd) 3529 3530def test_eap_proto_psk(dev, apdev): 3531 """EAP-PSK protocol tests""" 3532 def psk_handler(ctx, req): 3533 logger.info("psk_handler - RX " + binascii.hexlify(req).decode()) 3534 if 'num' not in ctx: 3535 ctx['num'] = 0 3536 ctx['num'] = ctx['num'] + 1 3537 if 'id' not in ctx: 3538 ctx['id'] = 1 3539 ctx['id'] = (ctx['id'] + 1) % 256 3540 3541 idx = 0 3542 3543 idx += 1 3544 if ctx['num'] == idx: 3545 logger.info("Test: Missing payload") 3546 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 3547 4 + 1, 3548 EAP_TYPE_PSK) 3549 3550 idx += 1 3551 if ctx['num'] == idx: 3552 logger.info("Test: Non-zero T in first message") 3553 return struct.pack(">BBHBB4L", EAP_CODE_REQUEST, ctx['id'], 3554 4 + 1 + 1 + 16, 3555 EAP_TYPE_PSK, 0xc0, 0, 0, 0, 0) 3556 3557 idx += 1 3558 if ctx['num'] == idx: 3559 logger.info("Test: Valid first message") 3560 return struct.pack(">BBHBB4L", EAP_CODE_REQUEST, ctx['id'], 3561 4 + 1 + 1 + 16, 3562 EAP_TYPE_PSK, 0, 0, 0, 0, 0) 3563 idx += 1 3564 if ctx['num'] == idx: 3565 logger.info("Test: Too short third message") 3566 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 3567 4 + 1, 3568 EAP_TYPE_PSK) 3569 3570 idx += 1 3571 if ctx['num'] == idx: 3572 logger.info("Test: Valid first message") 3573 return struct.pack(">BBHBB4L", EAP_CODE_REQUEST, ctx['id'], 3574 4 + 1 + 1 + 16, 3575 EAP_TYPE_PSK, 0, 0, 0, 0, 0) 3576 idx += 1 3577 if ctx['num'] == idx: 3578 logger.info("Test: Incorrect T in third message") 3579 return struct.pack(">BBHBB4L4L", EAP_CODE_REQUEST, ctx['id'], 3580 4 + 1 + 1 + 16 + 16, 3581 EAP_TYPE_PSK, 0, 0, 0, 0, 0, 0, 0, 0, 0) 3582 3583 idx += 1 3584 if ctx['num'] == idx: 3585 logger.info("Test: Valid first message") 3586 return struct.pack(">BBHBB4L", EAP_CODE_REQUEST, ctx['id'], 3587 4 + 1 + 1 + 16, 3588 EAP_TYPE_PSK, 0, 0, 0, 0, 0) 3589 idx += 1 3590 if ctx['num'] == idx: 3591 logger.info("Test: Missing PCHANNEL in third message") 3592 return struct.pack(">BBHBB4L4L", EAP_CODE_REQUEST, ctx['id'], 3593 4 + 1 + 1 + 16 + 16, 3594 EAP_TYPE_PSK, 0x80, 0, 0, 0, 0, 0, 0, 0, 0) 3595 3596 idx += 1 3597 if ctx['num'] == idx: 3598 logger.info("Test: Valid first message") 3599 return struct.pack(">BBHBB4L", EAP_CODE_REQUEST, ctx['id'], 3600 4 + 1 + 1 + 16, 3601 EAP_TYPE_PSK, 0, 0, 0, 0, 0) 3602 idx += 1 3603 if ctx['num'] == idx: 3604 logger.info("Test: Invalic MAC_S in third message") 3605 return struct.pack(">BBHBB4L4L5LB", EAP_CODE_REQUEST, ctx['id'], 3606 4 + 1 + 1 + 16 + 16 + 21, 3607 EAP_TYPE_PSK, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 3608 0, 0, 0, 0, 0, 0) 3609 3610 idx += 1 3611 if ctx['num'] == idx: 3612 logger.info("Test: Valid first message") 3613 return struct.pack(">BBHBB4L", EAP_CODE_REQUEST, ctx['id'], 3614 4 + 1 + 1 + 16, 3615 EAP_TYPE_PSK, 0, 0, 0, 0, 0) 3616 idx += 1 3617 if ctx['num'] == idx: 3618 logger.info("Test: EAP-Failure") 3619 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 3620 3621 return None 3622 3623 srv = start_radius_server(psk_handler) 3624 3625 try: 3626 hapd = start_ap(apdev[0]) 3627 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 3628 3629 for i in range(0, 6): 3630 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 3631 eap="PSK", identity="user", 3632 password_hex="0123456789abcdef0123456789abcdef", 3633 wait_connect=False) 3634 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 3635 timeout=15) 3636 if ev is None: 3637 raise Exception("Timeout on EAP start") 3638 time.sleep(0.1) 3639 dev[0].request("REMOVE_NETWORK all") 3640 3641 logger.info("Test: Invalid PSK length") 3642 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 3643 eap="PSK", identity="user", 3644 password_hex="0123456789abcdef0123456789abcd", 3645 wait_connect=False) 3646 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 3647 timeout=15) 3648 if ev is None: 3649 raise Exception("Timeout on EAP start") 3650 time.sleep(0.1) 3651 dev[0].request("REMOVE_NETWORK all") 3652 finally: 3653 stop_radius_server(srv) 3654 3655def test_eap_proto_psk_errors(dev, apdev): 3656 """EAP-PSK local error cases""" 3657 check_eap_capa(dev[0], "PSK") 3658 params = hostapd.wpa2_eap_params(ssid="eap-test") 3659 hapd = hostapd.add_ap(apdev[0], params) 3660 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 3661 3662 for i in range(1, 3): 3663 with alloc_fail(dev[0], i, "eap_psk_init"): 3664 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 3665 eap="PSK", identity="psk.user@example.com", 3666 password_hex="0123456789abcdef0123456789abcdef", 3667 wait_connect=False) 3668 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"], 3669 timeout=15) 3670 if ev is None: 3671 raise Exception("Timeout on EAP start") 3672 dev[0].request("REMOVE_NETWORK all") 3673 dev[0].wait_disconnected() 3674 3675 for i in range(1, 4): 3676 with fail_test(dev[0], i, "eap_psk_key_setup;eap_psk_init"): 3677 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 3678 eap="PSK", identity="psk.user@example.com", 3679 password_hex="0123456789abcdef0123456789abcdef", 3680 wait_connect=False) 3681 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"], 3682 timeout=15) 3683 if ev is None: 3684 raise Exception("Timeout on EAP start") 3685 dev[0].request("REMOVE_NETWORK all") 3686 dev[0].wait_disconnected() 3687 3688 tests = [(1, "=eap_psk_process_1"), 3689 (2, "=eap_psk_process_1"), 3690 (1, "eap_msg_alloc;eap_psk_process_1"), 3691 (1, "=eap_psk_process_3"), 3692 (2, "=eap_psk_process_3"), 3693 (1, "eap_msg_alloc;eap_psk_process_3"), 3694 (1, "eap_psk_getKey"), 3695 (1, "eap_psk_get_session_id"), 3696 (1, "eap_psk_get_emsk")] 3697 for count, func in tests: 3698 with alloc_fail(dev[0], count, func): 3699 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 3700 eap="PSK", identity="psk.user@example.com", 3701 password_hex="0123456789abcdef0123456789abcdef", 3702 erp="1", wait_connect=False) 3703 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 3704 timeout=15) 3705 if ev is None: 3706 raise Exception("Timeout on EAP start") 3707 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL", 3708 note="No allocation failure seen for %d:%s" % (count, func)) 3709 dev[0].request("REMOVE_NETWORK all") 3710 dev[0].wait_disconnected() 3711 3712 tests = [(1, "os_get_random;eap_psk_process_1"), 3713 (1, "omac1_aes_128;eap_psk_process_3"), 3714 (1, "=omac1_aes_vector;omac1_aes_128;aes_128_eax_encrypt"), 3715 (2, "=omac1_aes_vector;omac1_aes_128;aes_128_eax_encrypt"), 3716 (3, "=omac1_aes_vector;omac1_aes_128;aes_128_eax_encrypt"), 3717 (1, "=omac1_aes_vector;omac1_aes_128;aes_128_eax_decrypt"), 3718 (2, "=omac1_aes_vector;omac1_aes_128;aes_128_eax_decrypt"), 3719 (3, "=omac1_aes_vector;omac1_aes_128;aes_128_eax_decrypt"), 3720 (1, "aes_128_eax_decrypt;eap_psk_process_3"), 3721 (2, "aes_128_eax_decrypt;eap_psk_process_3"), 3722 (3, "aes_128_eax_decrypt;eap_psk_process_3"), 3723 (1, "aes_128_eax_encrypt;eap_psk_process_3"), 3724 (2, "aes_128_eax_encrypt;eap_psk_process_3"), 3725 (3, "aes_128_eax_encrypt;eap_psk_process_3"), 3726 (1, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"), 3727 (2, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"), 3728 (3, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"), 3729 (4, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"), 3730 (5, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"), 3731 (6, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"), 3732 (7, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"), 3733 (8, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"), 3734 (9, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"), 3735 (10, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"), 3736 (1, "aes_ctr_encrypt;aes_128_eax_decrypt;eap_psk_process_3"), 3737 (1, "aes_ctr_encrypt;aes_128_eax_encrypt;eap_psk_process_3")] 3738 for count, func in tests: 3739 with fail_test(dev[0], count, func): 3740 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 3741 eap="PSK", identity="psk.user@example.com", 3742 password_hex="0123456789abcdef0123456789abcdef", 3743 wait_connect=False) 3744 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 3745 timeout=15) 3746 if ev is None: 3747 raise Exception("Timeout on EAP start") 3748 wait_fail_trigger(dev[0], "GET_FAIL", 3749 note="No failure seen for %d:%s" % (count, func)) 3750 dev[0].request("REMOVE_NETWORK all") 3751 dev[0].wait_disconnected() 3752 dev[0].dump_monitor() 3753 3754def run_eap_psk_connect(dev): 3755 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412", 3756 eap="PSK", identity="psk.user@example.com", 3757 password_hex="0123456789abcdef0123456789abcdef", 3758 wait_connect=False) 3759 ev = dev.wait_event(["CTRL-EVENT-EAP-SUCCESS", "CTRL-EVENT-EAP-FAILURE", 3760 "CTRL-EVENT-DISCONNECTED"], 3761 timeout=1) 3762 dev.request("REMOVE_NETWORK all") 3763 if not ev or "CTRL-EVENT-DISCONNECTED" not in ev: 3764 dev.wait_disconnected() 3765 dev.dump_monitor() 3766 3767def test_eap_proto_psk_errors_server(dev, apdev): 3768 """EAP-PSK local error cases on server""" 3769 check_eap_capa(dev[0], "PSK") 3770 params = int_eap_server_params() 3771 params['erp_domain'] = 'example.com' 3772 params['eap_server_erp'] = '1' 3773 hapd = hostapd.add_ap(apdev[0], params) 3774 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 3775 3776 tests = [(1, "eap_psk_init"), 3777 (1, "eap_msg_alloc;eap_psk_build_1"), 3778 (1, "eap_msg_alloc;eap_psk_build_3"), 3779 (1, "=eap_psk_build_3"), 3780 (1, "=eap_psk_process_2"), 3781 (2, "=eap_psk_process_2"), 3782 (1, "=eap_psk_process_4"), 3783 (1, "aes_128_eax_decrypt;eap_psk_process_4"), 3784 (1, "eap_psk_getKey"), 3785 (1, "eap_psk_get_emsk"), 3786 (1, "eap_psk_get_session_id")] 3787 for count, func in tests: 3788 with alloc_fail(hapd, count, func): 3789 run_eap_psk_connect(dev[0]) 3790 3791 tests = [(1, "os_get_random;eap_psk_build_1"), 3792 (1, "omac1_aes_128;eap_psk_build_3"), 3793 (1, "eap_psk_derive_keys;eap_psk_build_3"), 3794 (1, "aes_128_eax_encrypt;eap_psk_build_3"), 3795 (1, "eap_psk_key_setup;eap_psk_process_2"), 3796 (1, "omac1_aes_128;eap_psk_process_2"), 3797 (1, "aes_128_eax_decrypt;eap_psk_process_4")] 3798 for count, func in tests: 3799 with fail_test(hapd, count, func): 3800 run_eap_psk_connect(dev[0]) 3801 3802def start_psk_assoc(dev, hapd): 3803 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412", 3804 eap="PSK", identity="psk.user@example.com", 3805 password_hex="0123456789abcdef0123456789abcdef", 3806 wait_connect=False) 3807 proxy_msg(hapd, dev) # EAP-Identity/Request 3808 proxy_msg(dev, hapd) # EAP-Identity/Response 3809 proxy_msg(hapd, dev) # PSK-1 3810 3811def stop_psk_assoc(dev, hapd): 3812 dev.request("REMOVE_NETWORK all") 3813 dev.wait_disconnected() 3814 dev.dump_monitor() 3815 hapd.dump_monitor() 3816 3817def test_eap_proto_psk_server(dev, apdev): 3818 """EAP-PSK protocol testing for the server""" 3819 check_eap_capa(dev[0], "PSK") 3820 params = int_eap_server_params() 3821 params['erp_domain'] = 'example.com' 3822 params['eap_server_erp'] = '1' 3823 hapd = hostapd.add_ap(apdev[0], params) 3824 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 3825 hapd.request("SET ext_eapol_frame_io 1") 3826 dev[0].request("SET ext_eapol_frame_io 1") 3827 3828 # Successful exchange to verify proxying mechanism 3829 start_psk_assoc(dev[0], hapd) 3830 proxy_msg(dev[0], hapd) # PSK-2 3831 proxy_msg(hapd, dev[0]) # PSK-3 3832 proxy_msg(dev[0], hapd) # PSK-4 3833 proxy_msg(hapd, dev[0]) # EAP-Success 3834 proxy_msg(hapd, dev[0]) # EAPOL-Key msg 1/4 3835 proxy_msg(dev[0], hapd) # EAPOL-Key msg 2/4 3836 proxy_msg(hapd, dev[0]) # EAPOL-Key msg 3/4 3837 proxy_msg(dev[0], hapd) # EAPOL-Key msg 4/4 3838 dev[0].wait_connected() 3839 stop_psk_assoc(dev[0], hapd) 3840 3841 start_psk_assoc(dev[0], hapd) 3842 resp = rx_msg(dev[0]) 3843 # Too short EAP-PSK header (no Flags) 3844 hapd.note("EAP-PSK: Invalid frame") 3845 msg = resp[0:4] + "0005" + resp[8:12] + "0005" + "2f" 3846 tx_msg(dev[0], hapd, msg) 3847 # Unexpected PSK-1 3848 hapd.note("EAP-PSK: Expected PSK-2 - ignore T=0") 3849 msg = resp[0:4] + "0006" + resp[8:12] + "0006" + "2f00" 3850 tx_msg(dev[0], hapd, msg) 3851 # Too short PSK-2 3852 hapd.note("EAP-PSK: Too short frame") 3853 msg = resp[0:4] + "0006" + resp[8:12] + "0006" + "2f40" 3854 tx_msg(dev[0], hapd, msg) 3855 # PSK-2 with unknown ID_P 3856 hapd.note("EAP-PSK: EAP-PSK not enabled for ID_P") 3857 msg = resp[0:4] + "004a" + resp[8:12] + "004a" + "2f40" + 3*16*"00" + 20*"00" 3858 tx_msg(dev[0], hapd, msg) 3859 rx_msg(hapd) # EAP-Failure 3860 stop_psk_assoc(dev[0], hapd) 3861 3862 start_psk_assoc(dev[0], hapd) 3863 proxy_msg(dev[0], hapd) # PSK-2 3864 proxy_msg(hapd, dev[0]) # PSK-3 3865 resp = rx_msg(dev[0]) 3866 # Unexpected PSK-2 3867 hapd.note("EAP-PSK: Expected PSK-4 - ignore T=1") 3868 msg = resp[0:4] + "0016" + resp[8:12] + "0016" + "2f40" + 16*"00" 3869 tx_msg(dev[0], hapd, msg) 3870 # Too short PSK-4 (no PCHANNEL) 3871 hapd.note("EAP-PSK: Too short PCHANNEL data in PSK-4 (len=0, expected 21)") 3872 msg = resp[0:4] + "0016" + resp[8:12] + "0016" + "2fc0" + 16*"00" 3873 tx_msg(dev[0], hapd, msg) 3874 rx_msg(hapd) # PSK-3 retry 3875 stop_psk_assoc(dev[0], hapd) 3876 3877 start_psk_assoc(dev[0], hapd) 3878 proxy_msg(dev[0], hapd) # PSK-2 3879 proxy_msg(hapd, dev[0]) # PSK-3 3880 resp = rx_msg(dev[0]) 3881 # PCHANNEL Nonce did not increase 3882 hapd.note("EAP-PSK: Nonce did not increase") 3883 msg = resp[0:4] + "002b" + resp[8:12] + "002b" + "2fc0" + 16*"00" + 21*"00" 3884 tx_msg(dev[0], hapd, msg) 3885 rx_msg(hapd) # PSK-3 retry 3886 stop_psk_assoc(dev[0], hapd) 3887 3888 start_psk_assoc(dev[0], hapd) 3889 proxy_msg(dev[0], hapd) # PSK-2 3890 proxy_msg(hapd, dev[0]) # PSK-3 3891 resp = rx_msg(dev[0]) 3892 # Invalid PCHANNEL encryption 3893 hapd.note("EAP-PSK: PCHANNEL decryption failed") 3894 msg = resp[0:4] + "002b" + resp[8:12] + "002b" + "2fc0" + 16*"00" + 21*"11" 3895 tx_msg(dev[0], hapd, msg) 3896 rx_msg(hapd) # PSK-3 retry 3897 stop_psk_assoc(dev[0], hapd) 3898 3899EAP_SIM_SUBTYPE_START = 10 3900EAP_SIM_SUBTYPE_CHALLENGE = 11 3901EAP_SIM_SUBTYPE_NOTIFICATION = 12 3902EAP_SIM_SUBTYPE_REAUTHENTICATION = 13 3903EAP_SIM_SUBTYPE_CLIENT_ERROR = 14 3904 3905EAP_AKA_SUBTYPE_CHALLENGE = 1 3906EAP_AKA_SUBTYPE_AUTHENTICATION_REJECT = 2 3907EAP_AKA_SUBTYPE_SYNCHRONIZATION_FAILURE = 4 3908EAP_AKA_SUBTYPE_IDENTITY = 5 3909EAP_AKA_SUBTYPE_NOTIFICATION = 12 3910EAP_AKA_SUBTYPE_REAUTHENTICATION = 13 3911EAP_AKA_SUBTYPE_CLIENT_ERROR = 14 3912 3913EAP_SIM_AT_RAND = 1 3914EAP_SIM_AT_AUTN = 2 3915EAP_SIM_AT_RES = 3 3916EAP_SIM_AT_AUTS = 4 3917EAP_SIM_AT_PADDING = 6 3918EAP_SIM_AT_NONCE_MT = 7 3919EAP_SIM_AT_PERMANENT_ID_REQ = 10 3920EAP_SIM_AT_MAC = 11 3921EAP_SIM_AT_NOTIFICATION = 12 3922EAP_SIM_AT_ANY_ID_REQ = 13 3923EAP_SIM_AT_IDENTITY = 14 3924EAP_SIM_AT_VERSION_LIST = 15 3925EAP_SIM_AT_SELECTED_VERSION = 16 3926EAP_SIM_AT_FULLAUTH_ID_REQ = 17 3927EAP_SIM_AT_COUNTER = 19 3928EAP_SIM_AT_COUNTER_TOO_SMALL = 20 3929EAP_SIM_AT_NONCE_S = 21 3930EAP_SIM_AT_CLIENT_ERROR_CODE = 22 3931EAP_SIM_AT_KDF_INPUT = 23 3932EAP_SIM_AT_KDF = 24 3933EAP_SIM_AT_IV = 129 3934EAP_SIM_AT_ENCR_DATA = 130 3935EAP_SIM_AT_NEXT_PSEUDONYM = 132 3936EAP_SIM_AT_NEXT_REAUTH_ID = 133 3937EAP_SIM_AT_CHECKCODE = 134 3938EAP_SIM_AT_RESULT_IND = 135 3939EAP_SIM_AT_BIDDING = 136 3940 3941def test_eap_proto_aka(dev, apdev): 3942 """EAP-AKA protocol tests""" 3943 def aka_handler(ctx, req): 3944 logger.info("aka_handler - RX " + binascii.hexlify(req).decode()) 3945 if 'num' not in ctx: 3946 ctx['num'] = 0 3947 ctx['num'] = ctx['num'] + 1 3948 if 'id' not in ctx: 3949 ctx['id'] = 1 3950 ctx['id'] = (ctx['id'] + 1) % 256 3951 3952 idx = 0 3953 3954 idx += 1 3955 if ctx['num'] == idx: 3956 logger.info("Test: Missing payload") 3957 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 3958 4 + 1, 3959 EAP_TYPE_AKA) 3960 3961 idx += 1 3962 if ctx['num'] == idx: 3963 logger.info("Test: Unknown subtype") 3964 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], 3965 4 + 1 + 3, 3966 EAP_TYPE_AKA, 255, 0) 3967 idx += 1 3968 if ctx['num'] == idx: 3969 logger.info("Test: EAP-Failure") 3970 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 3971 3972 idx += 1 3973 if ctx['num'] == idx: 3974 logger.info("Test: Client Error") 3975 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], 3976 4 + 1 + 3, 3977 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CLIENT_ERROR, 0) 3978 idx += 1 3979 if ctx['num'] == idx: 3980 logger.info("Test: EAP-Failure") 3981 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 3982 3983 idx += 1 3984 if ctx['num'] == idx: 3985 logger.info("Test: Too short attribute header") 3986 return struct.pack(">BBHBBHB", EAP_CODE_REQUEST, ctx['id'], 3987 4 + 1 + 1 + 3, 3988 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 255) 3989 idx += 1 3990 if ctx['num'] == idx: 3991 logger.info("Test: EAP-Failure") 3992 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 3993 3994 idx += 1 3995 if ctx['num'] == idx: 3996 logger.info("Test: Truncated attribute") 3997 return struct.pack(">BBHBBHBB", EAP_CODE_REQUEST, ctx['id'], 3998 4 + 1 + 1 + 4, 3999 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 255, 4000 255) 4001 idx += 1 4002 if ctx['num'] == idx: 4003 logger.info("Test: EAP-Failure") 4004 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4005 4006 idx += 1 4007 if ctx['num'] == idx: 4008 logger.info("Test: Too short attribute data") 4009 return struct.pack(">BBHBBHBB", EAP_CODE_REQUEST, ctx['id'], 4010 4 + 1 + 1 + 4, 4011 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 255, 4012 0) 4013 idx += 1 4014 if ctx['num'] == idx: 4015 logger.info("Test: EAP-Failure") 4016 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4017 4018 idx += 1 4019 if ctx['num'] == idx: 4020 logger.info("Test: Skippable/non-skippable unrecognzized attribute") 4021 return struct.pack(">BBHBBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4022 4 + 1 + 1 + 10, 4023 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4024 255, 1, 0, 127, 1, 0) 4025 idx += 1 4026 if ctx['num'] == idx: 4027 logger.info("Test: EAP-Failure") 4028 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4029 4030 idx += 1 4031 if ctx['num'] == idx: 4032 logger.info("Test: Identity request without ID type") 4033 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], 4034 4 + 1 + 3, 4035 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0) 4036 idx += 1 4037 if ctx['num'] == idx: 4038 logger.info("Test: Identity request ANY_ID") 4039 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4040 4 + 1 + 3 + 4, 4041 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4042 EAP_SIM_AT_ANY_ID_REQ, 1, 0) 4043 idx += 1 4044 if ctx['num'] == idx: 4045 logger.info("Test: Identity request ANY_ID (duplicate)") 4046 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4047 4 + 1 + 3 + 4, 4048 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4049 EAP_SIM_AT_ANY_ID_REQ, 1, 0) 4050 idx += 1 4051 if ctx['num'] == idx: 4052 logger.info("Test: EAP-Failure") 4053 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4054 4055 idx += 1 4056 if ctx['num'] == idx: 4057 logger.info("Test: Identity request ANY_ID") 4058 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4059 4 + 1 + 3 + 4, 4060 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4061 EAP_SIM_AT_ANY_ID_REQ, 1, 0) 4062 idx += 1 4063 if ctx['num'] == idx: 4064 logger.info("Test: Identity request FULLAUTH_ID") 4065 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4066 4 + 1 + 3 + 4, 4067 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4068 EAP_SIM_AT_FULLAUTH_ID_REQ, 1, 0) 4069 idx += 1 4070 if ctx['num'] == idx: 4071 logger.info("Test: Identity request FULLAUTH_ID (duplicate)") 4072 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4073 4 + 1 + 3 + 4, 4074 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4075 EAP_SIM_AT_FULLAUTH_ID_REQ, 1, 0) 4076 idx += 1 4077 if ctx['num'] == idx: 4078 logger.info("Test: EAP-Failure") 4079 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4080 4081 idx += 1 4082 if ctx['num'] == idx: 4083 logger.info("Test: Identity request ANY_ID") 4084 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4085 4 + 1 + 3 + 4, 4086 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4087 EAP_SIM_AT_ANY_ID_REQ, 1, 0) 4088 idx += 1 4089 if ctx['num'] == idx: 4090 logger.info("Test: Identity request FULLAUTH_ID") 4091 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4092 4 + 1 + 3 + 4, 4093 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4094 EAP_SIM_AT_FULLAUTH_ID_REQ, 1, 0) 4095 idx += 1 4096 if ctx['num'] == idx: 4097 logger.info("Test: Identity request PERMANENT_ID") 4098 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4099 4 + 1 + 3 + 4, 4100 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4101 EAP_SIM_AT_PERMANENT_ID_REQ, 1, 0) 4102 idx += 1 4103 if ctx['num'] == idx: 4104 logger.info("Test: Identity request PERMANENT_ID (duplicate)") 4105 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4106 4 + 1 + 3 + 4, 4107 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4108 EAP_SIM_AT_PERMANENT_ID_REQ, 1, 0) 4109 idx += 1 4110 if ctx['num'] == idx: 4111 logger.info("Test: EAP-Failure") 4112 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4113 4114 idx += 1 4115 if ctx['num'] == idx: 4116 logger.info("Test: Challenge with no attributes") 4117 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], 4118 4 + 1 + 3, 4119 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CHALLENGE, 0) 4120 idx += 1 4121 if ctx['num'] == idx: 4122 logger.info("Test: EAP-Failure") 4123 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4124 4125 idx += 1 4126 if ctx['num'] == idx: 4127 logger.info("Test: AKA Challenge with BIDDING") 4128 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4129 4 + 1 + 3 + 4, 4130 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4131 EAP_SIM_AT_BIDDING, 1, 0x8000) 4132 idx += 1 4133 if ctx['num'] == idx: 4134 logger.info("Test: EAP-Failure") 4135 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4136 4137 idx += 1 4138 if ctx['num'] == idx: 4139 logger.info("Test: Notification with no attributes") 4140 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], 4141 4 + 1 + 3, 4142 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0) 4143 idx += 1 4144 if ctx['num'] == idx: 4145 logger.info("Test: EAP-Failure") 4146 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4147 4148 idx += 1 4149 if ctx['num'] == idx: 4150 logger.info("Test: Notification indicating success, but no MAC") 4151 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4152 4 + 1 + 3 + 4, 4153 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0, 4154 EAP_SIM_AT_NOTIFICATION, 1, 32768) 4155 idx += 1 4156 if ctx['num'] == idx: 4157 logger.info("Test: EAP-Failure") 4158 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4159 4160 idx += 1 4161 if ctx['num'] == idx: 4162 logger.info("Test: Notification indicating success, but invalid MAC value") 4163 return struct.pack(">BBHBBHBBHBBH4L", EAP_CODE_REQUEST, ctx['id'], 4164 4 + 1 + 3 + 4 + 20, 4165 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0, 4166 EAP_SIM_AT_NOTIFICATION, 1, 32768, 4167 EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0) 4168 idx += 1 4169 if ctx['num'] == idx: 4170 logger.info("Test: EAP-Failure") 4171 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4172 4173 idx += 1 4174 if ctx['num'] == idx: 4175 logger.info("Test: Notification indicating success with zero-key MAC") 4176 return struct.pack(">BBHBBHBBHBBH16B", EAP_CODE_REQUEST, 4177 ctx['id'] - 2, 4178 4 + 1 + 3 + 4 + 20, 4179 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0, 4180 EAP_SIM_AT_NOTIFICATION, 1, 32768, 4181 EAP_SIM_AT_MAC, 5, 0, 4182 0xbe, 0x2e, 0xbb, 0xa9, 0xfa, 0x2e, 0x82, 0x36, 4183 0x37, 0x8c, 0x32, 0x41, 0xb7, 0xc7, 0x58, 0xa3) 4184 idx += 1 4185 if ctx['num'] == idx: 4186 logger.info("Test: EAP-Success") 4187 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4) 4188 4189 idx += 1 4190 if ctx['num'] == idx: 4191 logger.info("Test: Notification before auth") 4192 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4193 4 + 1 + 3 + 4, 4194 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0, 4195 EAP_SIM_AT_NOTIFICATION, 1, 16384) 4196 idx += 1 4197 if ctx['num'] == idx: 4198 logger.info("Test: EAP-Failure") 4199 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4200 4201 idx += 1 4202 if ctx['num'] == idx: 4203 logger.info("Test: Notification before auth") 4204 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4205 4 + 1 + 3 + 4, 4206 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0, 4207 EAP_SIM_AT_NOTIFICATION, 1, 16385) 4208 idx += 1 4209 if ctx['num'] == idx: 4210 logger.info("Test: EAP-Failure") 4211 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4212 4213 idx += 1 4214 if ctx['num'] == idx: 4215 logger.info("Test: Notification with unrecognized non-failure") 4216 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4217 4 + 1 + 3 + 4, 4218 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0, 4219 EAP_SIM_AT_NOTIFICATION, 1, 0xc000) 4220 idx += 1 4221 if ctx['num'] == idx: 4222 logger.info("Test: Notification before auth (duplicate)") 4223 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4224 4 + 1 + 3 + 4, 4225 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0, 4226 EAP_SIM_AT_NOTIFICATION, 1, 0xc000) 4227 idx += 1 4228 if ctx['num'] == idx: 4229 logger.info("Test: EAP-Failure") 4230 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4231 4232 idx += 1 4233 if ctx['num'] == idx: 4234 logger.info("Test: Re-authentication (unexpected) with no attributes") 4235 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], 4236 4 + 1 + 3, 4237 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_REAUTHENTICATION, 4238 0) 4239 idx += 1 4240 if ctx['num'] == idx: 4241 logger.info("Test: EAP-Failure") 4242 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4243 4244 idx += 1 4245 if ctx['num'] == idx: 4246 logger.info("Test: AKA Challenge with Checkcode claiming identity round was used") 4247 return struct.pack(">BBHBBHBBH5L", EAP_CODE_REQUEST, ctx['id'], 4248 4 + 1 + 3 + 24, 4249 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4250 EAP_SIM_AT_CHECKCODE, 6, 0, 0, 0, 0, 0, 0) 4251 idx += 1 4252 if ctx['num'] == idx: 4253 logger.info("Test: EAP-Failure") 4254 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4255 4256 idx += 1 4257 if ctx['num'] == idx: 4258 logger.info("Test: Identity request ANY_ID") 4259 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4260 4 + 1 + 3 + 4, 4261 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4262 EAP_SIM_AT_ANY_ID_REQ, 1, 0) 4263 idx += 1 4264 if ctx['num'] == idx: 4265 logger.info("Test: AKA Challenge with Checkcode claiming no identity round was used") 4266 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4267 4 + 1 + 3 + 4, 4268 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4269 EAP_SIM_AT_CHECKCODE, 1, 0) 4270 idx += 1 4271 if ctx['num'] == idx: 4272 logger.info("Test: EAP-Failure") 4273 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4274 4275 idx += 1 4276 if ctx['num'] == idx: 4277 logger.info("Test: Identity request ANY_ID") 4278 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4279 4 + 1 + 3 + 4, 4280 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4281 EAP_SIM_AT_ANY_ID_REQ, 1, 0) 4282 idx += 1 4283 if ctx['num'] == idx: 4284 logger.info("Test: AKA Challenge with mismatching Checkcode value") 4285 return struct.pack(">BBHBBHBBH5L", EAP_CODE_REQUEST, ctx['id'], 4286 4 + 1 + 3 + 24, 4287 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4288 EAP_SIM_AT_CHECKCODE, 6, 0, 0, 0, 0, 0, 0) 4289 idx += 1 4290 if ctx['num'] == idx: 4291 logger.info("Test: EAP-Failure") 4292 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4293 4294 idx += 1 4295 if ctx['num'] == idx: 4296 logger.info("Test: Re-authentication (unexpected) with Checkcode claimin identity round was used") 4297 return struct.pack(">BBHBBHBBH5L", EAP_CODE_REQUEST, ctx['id'], 4298 4 + 1 + 3 + 24, 4299 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_REAUTHENTICATION, 4300 0, 4301 EAP_SIM_AT_CHECKCODE, 6, 0, 0, 0, 0, 0, 0) 4302 idx += 1 4303 if ctx['num'] == idx: 4304 logger.info("Test: EAP-Failure") 4305 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4306 4307 idx += 1 4308 if ctx['num'] == idx: 4309 logger.info("Test: Invalid AT_RAND length") 4310 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4311 4 + 1 + 3 + 4, 4312 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4313 EAP_SIM_AT_RAND, 1, 0) 4314 idx += 1 4315 if ctx['num'] == idx: 4316 logger.info("Test: EAP-Failure") 4317 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4318 4319 idx += 1 4320 if ctx['num'] == idx: 4321 logger.info("Test: Invalid AT_AUTN length") 4322 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4323 4 + 1 + 3 + 4, 4324 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4325 EAP_SIM_AT_AUTN, 1, 0) 4326 idx += 1 4327 if ctx['num'] == idx: 4328 logger.info("Test: EAP-Failure") 4329 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4330 4331 idx += 1 4332 if ctx['num'] == idx: 4333 logger.info("Test: Unencrypted AT_PADDING") 4334 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4335 4 + 1 + 3 + 4, 4336 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4337 EAP_SIM_AT_PADDING, 1, 0) 4338 idx += 1 4339 if ctx['num'] == idx: 4340 logger.info("Test: EAP-Failure") 4341 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4342 4343 idx += 1 4344 if ctx['num'] == idx: 4345 logger.info("Test: Invalid AT_NONCE_MT length") 4346 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4347 4 + 1 + 3 + 4, 4348 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4349 EAP_SIM_AT_NONCE_MT, 1, 0) 4350 idx += 1 4351 if ctx['num'] == idx: 4352 logger.info("Test: EAP-Failure") 4353 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4354 4355 idx += 1 4356 if ctx['num'] == idx: 4357 logger.info("Test: Invalid AT_MAC length") 4358 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4359 4 + 1 + 3 + 4, 4360 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4361 EAP_SIM_AT_MAC, 1, 0) 4362 idx += 1 4363 if ctx['num'] == idx: 4364 logger.info("Test: EAP-Failure") 4365 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4366 4367 idx += 1 4368 if ctx['num'] == idx: 4369 logger.info("Test: Invalid AT_NOTIFICATION length") 4370 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], 4371 4 + 1 + 3 + 8, 4372 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4373 EAP_SIM_AT_NOTIFICATION, 2, 0, 0) 4374 idx += 1 4375 if ctx['num'] == idx: 4376 logger.info("Test: EAP-Failure") 4377 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4378 4379 idx += 1 4380 if ctx['num'] == idx: 4381 logger.info("Test: AT_IDENTITY overflow") 4382 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4383 4 + 1 + 3 + 4, 4384 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4385 EAP_SIM_AT_IDENTITY, 1, 0xffff) 4386 idx += 1 4387 if ctx['num'] == idx: 4388 logger.info("Test: EAP-Failure") 4389 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4390 4391 idx += 1 4392 if ctx['num'] == idx: 4393 logger.info("Test: Unexpected AT_VERSION_LIST") 4394 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4395 4 + 1 + 3 + 4, 4396 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4397 EAP_SIM_AT_VERSION_LIST, 1, 0) 4398 idx += 1 4399 if ctx['num'] == idx: 4400 logger.info("Test: EAP-Failure") 4401 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4402 4403 idx += 1 4404 if ctx['num'] == idx: 4405 logger.info("Test: Invalid AT_SELECTED_VERSION length") 4406 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], 4407 4 + 1 + 3 + 8, 4408 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4409 EAP_SIM_AT_SELECTED_VERSION, 2, 0, 0) 4410 idx += 1 4411 if ctx['num'] == idx: 4412 logger.info("Test: EAP-Failure") 4413 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4414 4415 idx += 1 4416 if ctx['num'] == idx: 4417 logger.info("Test: Unencrypted AT_COUNTER") 4418 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4419 4 + 1 + 3 + 4, 4420 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4421 EAP_SIM_AT_COUNTER, 1, 0) 4422 idx += 1 4423 if ctx['num'] == idx: 4424 logger.info("Test: EAP-Failure") 4425 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4426 4427 idx += 1 4428 if ctx['num'] == idx: 4429 logger.info("Test: Unencrypted AT_COUNTER_TOO_SMALL") 4430 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4431 4 + 1 + 3 + 4, 4432 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4433 EAP_SIM_AT_COUNTER_TOO_SMALL, 1, 0) 4434 idx += 1 4435 if ctx['num'] == idx: 4436 logger.info("Test: EAP-Failure") 4437 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4438 4439 idx += 1 4440 if ctx['num'] == idx: 4441 logger.info("Test: Unencrypted AT_NONCE_S") 4442 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4443 4 + 1 + 3 + 4, 4444 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4445 EAP_SIM_AT_NONCE_S, 1, 0) 4446 idx += 1 4447 if ctx['num'] == idx: 4448 logger.info("Test: EAP-Failure") 4449 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4450 4451 idx += 1 4452 if ctx['num'] == idx: 4453 logger.info("Test: Invalid AT_CLIENT_ERROR_CODE length") 4454 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], 4455 4 + 1 + 3 + 8, 4456 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4457 EAP_SIM_AT_CLIENT_ERROR_CODE, 2, 0, 0) 4458 idx += 1 4459 if ctx['num'] == idx: 4460 logger.info("Test: EAP-Failure") 4461 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4462 4463 idx += 1 4464 if ctx['num'] == idx: 4465 logger.info("Test: Invalid AT_IV length") 4466 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4467 4 + 1 + 3 + 4, 4468 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4469 EAP_SIM_AT_IV, 1, 0) 4470 idx += 1 4471 if ctx['num'] == idx: 4472 logger.info("Test: EAP-Failure") 4473 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4474 4475 idx += 1 4476 if ctx['num'] == idx: 4477 logger.info("Test: Invalid AT_ENCR_DATA length") 4478 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], 4479 4 + 1 + 3 + 8, 4480 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4481 EAP_SIM_AT_ENCR_DATA, 2, 0, 0) 4482 idx += 1 4483 if ctx['num'] == idx: 4484 logger.info("Test: EAP-Failure") 4485 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4486 4487 idx += 1 4488 if ctx['num'] == idx: 4489 logger.info("Test: Unencrypted AT_NEXT_PSEUDONYM") 4490 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4491 4 + 1 + 3 + 4, 4492 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4493 EAP_SIM_AT_NEXT_PSEUDONYM, 1, 0) 4494 idx += 1 4495 if ctx['num'] == idx: 4496 logger.info("Test: EAP-Failure") 4497 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4498 4499 idx += 1 4500 if ctx['num'] == idx: 4501 logger.info("Test: Unencrypted AT_NEXT_REAUTH_ID") 4502 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4503 4 + 1 + 3 + 4, 4504 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4505 EAP_SIM_AT_NEXT_REAUTH_ID, 1, 0) 4506 idx += 1 4507 if ctx['num'] == idx: 4508 logger.info("Test: EAP-Failure") 4509 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4510 4511 idx += 1 4512 if ctx['num'] == idx: 4513 logger.info("Test: Invalid AT_RES length") 4514 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4515 4 + 1 + 3 + 4, 4516 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4517 EAP_SIM_AT_RES, 1, 0) 4518 idx += 1 4519 if ctx['num'] == idx: 4520 logger.info("Test: EAP-Failure") 4521 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4522 4523 idx += 1 4524 if ctx['num'] == idx: 4525 logger.info("Test: Invalid AT_RES length") 4526 return struct.pack(">BBHBBHBBH5L", EAP_CODE_REQUEST, ctx['id'], 4527 4 + 1 + 3 + 24, 4528 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4529 EAP_SIM_AT_RES, 6, 0xffff, 0, 0, 0, 0, 0) 4530 idx += 1 4531 if ctx['num'] == idx: 4532 logger.info("Test: EAP-Failure") 4533 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4534 4535 idx += 1 4536 if ctx['num'] == idx: 4537 logger.info("Test: Invalid AT_AUTS length") 4538 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], 4539 4 + 1 + 3 + 8, 4540 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4541 EAP_SIM_AT_AUTS, 2, 0, 0) 4542 idx += 1 4543 if ctx['num'] == idx: 4544 logger.info("Test: EAP-Failure") 4545 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4546 4547 idx += 1 4548 if ctx['num'] == idx: 4549 logger.info("Test: Invalid AT_CHECKCODE length") 4550 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], 4551 4 + 1 + 3 + 8, 4552 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4553 EAP_SIM_AT_CHECKCODE, 2, 0, 0) 4554 idx += 1 4555 if ctx['num'] == idx: 4556 logger.info("Test: EAP-Failure") 4557 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4558 4559 idx += 1 4560 if ctx['num'] == idx: 4561 logger.info("Test: Invalid AT_RESULT_IND length") 4562 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], 4563 4 + 1 + 3 + 8, 4564 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4565 EAP_SIM_AT_RESULT_IND, 2, 0, 0) 4566 idx += 1 4567 if ctx['num'] == idx: 4568 logger.info("Test: EAP-Failure") 4569 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4570 4571 idx += 1 4572 if ctx['num'] == idx: 4573 logger.info("Test: Unexpected AT_KDF_INPUT") 4574 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], 4575 4 + 1 + 3 + 8, 4576 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4577 EAP_SIM_AT_KDF_INPUT, 2, 0, 0) 4578 idx += 1 4579 if ctx['num'] == idx: 4580 logger.info("Test: EAP-Failure") 4581 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4582 4583 idx += 1 4584 if ctx['num'] == idx: 4585 logger.info("Test: Unexpected AT_KDF") 4586 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], 4587 4 + 1 + 3 + 8, 4588 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4589 EAP_SIM_AT_KDF, 2, 0, 0) 4590 idx += 1 4591 if ctx['num'] == idx: 4592 logger.info("Test: EAP-Failure") 4593 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4594 4595 idx += 1 4596 if ctx['num'] == idx: 4597 logger.info("Test: Invalid AT_BIDDING length") 4598 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], 4599 4 + 1 + 3 + 8, 4600 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 4601 EAP_SIM_AT_BIDDING, 2, 0, 0) 4602 idx += 1 4603 if ctx['num'] == idx: 4604 logger.info("Test: EAP-Failure") 4605 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4606 4607 return None 4608 4609 srv = start_radius_server(aka_handler) 4610 4611 try: 4612 hapd = start_ap(apdev[0]) 4613 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 4614 4615 for i in range(0, 49): 4616 eap = "AKA AKA'" if i == 11 else "AKA" 4617 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 4618 eap=eap, identity="0232010000000000", 4619 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123", 4620 wait_connect=False) 4621 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 4622 timeout=15) 4623 if ev is None: 4624 raise Exception("Timeout on EAP start") 4625 if i in [0, 15]: 4626 time.sleep(0.1) 4627 else: 4628 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], 4629 timeout=10) 4630 if ev is None: 4631 raise Exception("Timeout on EAP failure") 4632 dev[0].request("REMOVE_NETWORK all") 4633 dev[0].dump_monitor() 4634 finally: 4635 stop_radius_server(srv) 4636 4637def test_eap_proto_aka_prime(dev, apdev): 4638 """EAP-AKA' protocol tests""" 4639 def aka_prime_handler(ctx, req): 4640 logger.info("aka_prime_handler - RX " + binascii.hexlify(req).decode()) 4641 if 'num' not in ctx: 4642 ctx['num'] = 0 4643 ctx['num'] = ctx['num'] + 1 4644 if 'id' not in ctx: 4645 ctx['id'] = 1 4646 ctx['id'] = (ctx['id'] + 1) % 256 4647 4648 idx = 0 4649 4650 idx += 1 4651 if ctx['num'] == idx: 4652 logger.info("Test: Missing payload") 4653 dev[0].note("Missing payload") 4654 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 4655 4 + 1, 4656 EAP_TYPE_AKA_PRIME) 4657 4658 idx += 1 4659 if ctx['num'] == idx: 4660 logger.info("Test: Challenge with no attributes") 4661 dev[0].note("Challenge with no attributes") 4662 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], 4663 4 + 1 + 3, 4664 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0) 4665 idx += 1 4666 if ctx['num'] == idx: 4667 logger.info("Test: EAP-Failure") 4668 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4669 4670 idx += 1 4671 if ctx['num'] == idx: 4672 logger.info("Test: Challenge with empty AT_KDF_INPUT") 4673 dev[0].note("Challenge with empty AT_KDF_INPUT") 4674 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 4675 4 + 1 + 3 + 4, 4676 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4677 EAP_SIM_AT_KDF_INPUT, 1, 0) 4678 idx += 1 4679 if ctx['num'] == idx: 4680 logger.info("Test: EAP-Failure") 4681 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4682 4683 idx += 1 4684 if ctx['num'] == idx: 4685 logger.info("Test: Challenge with AT_KDF_INPUT") 4686 dev[0].note("Test: Challenge with AT_KDF_INPUT") 4687 return struct.pack(">BBHBBHBBHBBBB", EAP_CODE_REQUEST, ctx['id'], 4688 4 + 1 + 3 + 8, 4689 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4690 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), 4691 ord('c'), ord('d')) 4692 idx += 1 4693 if ctx['num'] == idx: 4694 logger.info("Test: EAP-Failure") 4695 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4696 4697 idx += 1 4698 if ctx['num'] == idx: 4699 logger.info("Test: Challenge with duplicated KDF") 4700 dev[0].note("Challenge with duplicated KDF") 4701 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH", 4702 EAP_CODE_REQUEST, ctx['id'], 4703 4 + 1 + 3 + 8 + 3 * 4, 4704 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4705 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), 4706 ord('c'), ord('d'), 4707 EAP_SIM_AT_KDF, 1, 1, 4708 EAP_SIM_AT_KDF, 1, 2, 4709 EAP_SIM_AT_KDF, 1, 1) 4710 idx += 1 4711 if ctx['num'] == idx: 4712 logger.info("Test: EAP-Failure") 4713 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4714 4715 idx += 1 4716 if ctx['num'] == idx: 4717 logger.info("Test: Challenge with multiple KDF proposals") 4718 dev[0].note("Challenge with multiple KDF proposals (preparation)") 4719 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH", 4720 EAP_CODE_REQUEST, ctx['id'], 4721 4 + 1 + 3 + 8 + 3 * 4, 4722 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4723 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), 4724 ord('c'), ord('d'), 4725 EAP_SIM_AT_KDF, 1, 255, 4726 EAP_SIM_AT_KDF, 1, 254, 4727 EAP_SIM_AT_KDF, 1, 1) 4728 idx += 1 4729 if ctx['num'] == idx: 4730 logger.info("Test: Challenge with incorrect KDF selected") 4731 dev[0].note("Challenge with incorrect KDF selected") 4732 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBHBBH", 4733 EAP_CODE_REQUEST, ctx['id'], 4734 4 + 1 + 3 + 8 + 4 * 4, 4735 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4736 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), 4737 ord('c'), ord('d'), 4738 EAP_SIM_AT_KDF, 1, 255, 4739 EAP_SIM_AT_KDF, 1, 255, 4740 EAP_SIM_AT_KDF, 1, 254, 4741 EAP_SIM_AT_KDF, 1, 1) 4742 idx += 1 4743 if ctx['num'] == idx: 4744 logger.info("Test: EAP-Failure") 4745 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4746 4747 idx += 1 4748 if ctx['num'] == idx: 4749 logger.info("Test: Challenge with multiple KDF proposals") 4750 dev[0].note("Challenge with multiple KDF proposals (preparation)") 4751 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH", 4752 EAP_CODE_REQUEST, ctx['id'], 4753 4 + 1 + 3 + 8 + 3 * 4, 4754 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4755 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), 4756 ord('c'), ord('d'), 4757 EAP_SIM_AT_KDF, 1, 255, 4758 EAP_SIM_AT_KDF, 1, 254, 4759 EAP_SIM_AT_KDF, 1, 1) 4760 idx += 1 4761 if ctx['num'] == idx: 4762 logger.info("Test: Challenge with selected KDF not duplicated") 4763 dev[0].note("Challenge with selected KDF not duplicated") 4764 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH", 4765 EAP_CODE_REQUEST, ctx['id'], 4766 4 + 1 + 3 + 8 + 3 * 4, 4767 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4768 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), 4769 ord('c'), ord('d'), 4770 EAP_SIM_AT_KDF, 1, 1, 4771 EAP_SIM_AT_KDF, 1, 255, 4772 EAP_SIM_AT_KDF, 1, 254) 4773 idx += 1 4774 if ctx['num'] == idx: 4775 logger.info("Test: EAP-Failure") 4776 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4777 4778 idx += 1 4779 if ctx['num'] == idx: 4780 logger.info("Test: Challenge with multiple KDF proposals") 4781 dev[0].note("Challenge with multiple KDF proposals (preparation)") 4782 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH", 4783 EAP_CODE_REQUEST, ctx['id'], 4784 4 + 1 + 3 + 8 + 3 * 4, 4785 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4786 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), 4787 ord('c'), ord('d'), 4788 EAP_SIM_AT_KDF, 1, 255, 4789 EAP_SIM_AT_KDF, 1, 254, 4790 EAP_SIM_AT_KDF, 1, 1) 4791 idx += 1 4792 if ctx['num'] == idx: 4793 logger.info("Test: Challenge with selected KDF duplicated (missing MAC, RAND, AUTN)") 4794 dev[0].note("Challenge with selected KDF duplicated (missing MAC, RAND, AUTN)") 4795 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBHBBH", 4796 EAP_CODE_REQUEST, ctx['id'], 4797 4 + 1 + 3 + 8 + 4 * 4, 4798 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4799 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), 4800 ord('c'), ord('d'), 4801 EAP_SIM_AT_KDF, 1, 1, 4802 EAP_SIM_AT_KDF, 1, 255, 4803 EAP_SIM_AT_KDF, 1, 254, 4804 EAP_SIM_AT_KDF, 1, 1) 4805 idx += 1 4806 if ctx['num'] == idx: 4807 logger.info("Test: EAP-Failure") 4808 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4809 4810 idx += 1 4811 if ctx['num'] == idx: 4812 logger.info("Test: Challenge with multiple unsupported KDF proposals") 4813 dev[0].note("Challenge with multiple unsupported KDF proposals") 4814 return struct.pack(">BBHBBHBBHBBBBBBHBBH", 4815 EAP_CODE_REQUEST, ctx['id'], 4816 4 + 1 + 3 + 8 + 2 * 4, 4817 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4818 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), 4819 ord('c'), ord('d'), 4820 EAP_SIM_AT_KDF, 1, 255, 4821 EAP_SIM_AT_KDF, 1, 254) 4822 idx += 1 4823 if ctx['num'] == idx: 4824 logger.info("Test: EAP-Failure") 4825 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4826 4827 idx += 1 4828 if ctx['num'] == idx: 4829 logger.info("Test: Challenge with multiple KDF proposals") 4830 dev[0].note("Challenge with multiple KDF proposals (preparation)") 4831 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH", 4832 EAP_CODE_REQUEST, ctx['id'], 4833 4 + 1 + 3 + 8 + 3 * 4, 4834 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4835 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), 4836 ord('c'), ord('d'), 4837 EAP_SIM_AT_KDF, 1, 255, 4838 EAP_SIM_AT_KDF, 1, 254, 4839 EAP_SIM_AT_KDF, 1, 1) 4840 idx += 1 4841 if ctx['num'] == idx: 4842 logger.info("Test: Challenge with invalid MAC, RAND, AUTN values)") 4843 dev[0].note("Challenge with invalid MAC, RAND, AUTN values)") 4844 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBHBBHBBH4LBBH4LBBH4L", 4845 EAP_CODE_REQUEST, ctx['id'], 4846 4 + 1 + 3 + 8 + 4 * 4 + 20 + 20 + 20, 4847 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4848 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), 4849 ord('c'), ord('d'), 4850 EAP_SIM_AT_KDF, 1, 1, 4851 EAP_SIM_AT_KDF, 1, 255, 4852 EAP_SIM_AT_KDF, 1, 254, 4853 EAP_SIM_AT_KDF, 1, 1, 4854 EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0, 4855 EAP_SIM_AT_RAND, 5, 0, 0, 0, 0, 0, 4856 EAP_SIM_AT_AUTN, 5, 0, 0, 0, 0, 0) 4857 idx += 1 4858 if ctx['num'] == idx: 4859 logger.info("Test: EAP-Failure") 4860 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4861 4862 idx += 1 4863 if ctx['num'] == idx: 4864 logger.info("Test: Challenge - AMF separation bit not set)") 4865 dev[0].note("Challenge - AMF separation bit not set)") 4866 return struct.pack(">BBHBBHBBHBBBBBBHBBH4LBBH4LBBH4L", 4867 EAP_CODE_REQUEST, ctx['id'], 4868 4 + 1 + 3 + 8 + 4 + 20 + 20 + 20, 4869 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4870 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), 4871 ord('c'), ord('d'), 4872 EAP_SIM_AT_KDF, 1, 1, 4873 EAP_SIM_AT_MAC, 5, 0, 1, 2, 3, 4, 4874 EAP_SIM_AT_RAND, 5, 0, 5, 6, 7, 8, 4875 EAP_SIM_AT_AUTN, 5, 0, 9, 10, 4876 0x2fda8ef7, 0xbba518cc) 4877 idx += 1 4878 if ctx['num'] == idx: 4879 logger.info("Test: EAP-Failure") 4880 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4881 4882 idx += 1 4883 if ctx['num'] == idx: 4884 logger.info("Test: Challenge - Invalid MAC") 4885 dev[0].note("Challenge - Invalid MAC") 4886 return struct.pack(">BBHBBHBBHBBBBBBHBBH4LBBH4LBBH4L", 4887 EAP_CODE_REQUEST, ctx['id'], 4888 4 + 1 + 3 + 8 + 4 + 20 + 20 + 20, 4889 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4890 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), 4891 ord('c'), ord('d'), 4892 EAP_SIM_AT_KDF, 1, 1, 4893 EAP_SIM_AT_MAC, 5, 0, 1, 2, 3, 4, 4894 EAP_SIM_AT_RAND, 5, 0, 5, 6, 7, 8, 4895 EAP_SIM_AT_AUTN, 5, 0, 0xffffffff, 0xffffffff, 4896 0xd1f90322, 0x40514cb4) 4897 idx += 1 4898 if ctx['num'] == idx: 4899 logger.info("Test: EAP-Failure") 4900 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4901 4902 idx += 1 4903 if ctx['num'] == idx: 4904 logger.info("Test: Challenge - Valid MAC") 4905 dev[0].note("Challenge - Valid MAC") 4906 return struct.pack(">BBHBBHBBHBBBBBBHBBH4LBBH4LBBH4L", 4907 EAP_CODE_REQUEST, ctx['id'], 4908 4 + 1 + 3 + 8 + 4 + 20 + 20 + 20, 4909 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4910 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), 4911 ord('c'), ord('d'), 4912 EAP_SIM_AT_KDF, 1, 1, 4913 EAP_SIM_AT_MAC, 5, 0, 4914 0xf4a3c1d3, 0x7c901401, 0x34bd8b01, 0x6f7fa32f, 4915 EAP_SIM_AT_RAND, 5, 0, 5, 6, 7, 8, 4916 EAP_SIM_AT_AUTN, 5, 0, 0xffffffff, 0xffffffff, 4917 0xd1f90322, 0x40514cb4) 4918 idx += 1 4919 if ctx['num'] == idx: 4920 logger.info("Test: EAP-Failure") 4921 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4922 4923 idx += 1 4924 if ctx['num'] == idx: 4925 logger.info("Test: Invalid AT_KDF_INPUT length") 4926 dev[0].note("Invalid AT_KDF_INPUT length") 4927 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], 4928 4 + 1 + 3 + 8, 4929 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_IDENTITY, 0, 4930 EAP_SIM_AT_KDF_INPUT, 2, 0xffff, 0) 4931 idx += 1 4932 if ctx['num'] == idx: 4933 logger.info("Test: EAP-Failure") 4934 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4935 4936 idx += 1 4937 if ctx['num'] == idx: 4938 logger.info("Test: Invalid AT_KDF length") 4939 dev[0].note("Invalid AT_KDF length") 4940 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], 4941 4 + 1 + 3 + 8, 4942 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_IDENTITY, 0, 4943 EAP_SIM_AT_KDF, 2, 0, 0) 4944 idx += 1 4945 if ctx['num'] == idx: 4946 logger.info("Test: EAP-Failure") 4947 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4948 4949 idx += 1 4950 if ctx['num'] == idx: 4951 logger.info("Test: Challenge with large number of KDF proposals") 4952 dev[0].note("Challenge with large number of KDF proposals") 4953 return struct.pack(">BBHBBHBBHBBHBBHBBHBBHBBHBBHBBHBBHBBHBBHBBH", 4954 EAP_CODE_REQUEST, ctx['id'], 4955 4 + 1 + 3 + 12 * 4, 4956 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4957 EAP_SIM_AT_KDF, 1, 255, 4958 EAP_SIM_AT_KDF, 1, 254, 4959 EAP_SIM_AT_KDF, 1, 253, 4960 EAP_SIM_AT_KDF, 1, 252, 4961 EAP_SIM_AT_KDF, 1, 251, 4962 EAP_SIM_AT_KDF, 1, 250, 4963 EAP_SIM_AT_KDF, 1, 249, 4964 EAP_SIM_AT_KDF, 1, 248, 4965 EAP_SIM_AT_KDF, 1, 247, 4966 EAP_SIM_AT_KDF, 1, 246, 4967 EAP_SIM_AT_KDF, 1, 245, 4968 EAP_SIM_AT_KDF, 1, 244) 4969 idx += 1 4970 if ctx['num'] == idx: 4971 logger.info("Test: EAP-Failure") 4972 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 4973 4974 idx += 1 4975 if ctx['num'] == idx: 4976 logger.info("Test: Challenge with multiple KDF proposals") 4977 dev[0].note("Challenge with multiple KDF proposals (preparation)") 4978 return struct.pack(">BBHBBHBBHBBBBBBHBBH", 4979 EAP_CODE_REQUEST, ctx['id'], 4980 4 + 1 + 3 + 8 + 2 * 4, 4981 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4982 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), 4983 ord('c'), ord('d'), 4984 EAP_SIM_AT_KDF, 1, 2, 4985 EAP_SIM_AT_KDF, 1, 1) 4986 idx += 1 4987 if ctx['num'] == idx: 4988 logger.info("Test: Challenge with an extra KDF appended") 4989 dev[0].note("Challenge with an extra KDF appended") 4990 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBHBBH", 4991 EAP_CODE_REQUEST, ctx['id'], 4992 4 + 1 + 3 + 8 + 4 * 4, 4993 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, 4994 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), 4995 ord('c'), ord('d'), 4996 EAP_SIM_AT_KDF, 1, 1, 4997 EAP_SIM_AT_KDF, 1, 2, 4998 EAP_SIM_AT_KDF, 1, 1, 4999 EAP_SIM_AT_KDF, 1, 0) 5000 idx += 1 5001 if ctx['num'] == idx: 5002 logger.info("Test: EAP-Failure") 5003 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5004 5005 idx += 1 5006 if ctx['num'] == idx: 5007 logger.info("Test: Challenge with multiple KDF proposals") 5008 dev[0].note("Challenge with multiple KDF proposals (preparation)") 5009 return struct.pack(">BBHBBHBBHBBBBBBHBBH", 5010 EAP_CODE_REQUEST, ctx['id'], 5011 4 + 1 + 3 + 8 + 2 * 4, 5012 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, 5013 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), 5014 ord('c'), ord('d'), 5015 EAP_SIM_AT_KDF, 1, 2, 5016 EAP_SIM_AT_KDF, 1, 1) 5017 idx += 1 5018 if ctx['num'] == idx: 5019 logger.info("Test: Challenge with a modified KDF") 5020 dev[0].note("Challenge with a modified KDF") 5021 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH", 5022 EAP_CODE_REQUEST, ctx['id'], 5023 4 + 1 + 3 + 8 + 3 * 4, 5024 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0, 5025 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'), 5026 ord('c'), ord('d'), 5027 EAP_SIM_AT_KDF, 1, 1, 5028 EAP_SIM_AT_KDF, 1, 0, 5029 EAP_SIM_AT_KDF, 1, 1) 5030 idx += 1 5031 if ctx['num'] == idx: 5032 logger.info("Test: EAP-Failure") 5033 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5034 5035 return None 5036 5037 srv = start_radius_server(aka_prime_handler) 5038 5039 try: 5040 hapd = start_ap(apdev[0]) 5041 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 5042 5043 for i in range(0, 18): 5044 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 5045 eap="AKA'", identity="6555444333222111", 5046 password="5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123", 5047 wait_connect=False) 5048 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 5049 timeout=15) 5050 if ev is None: 5051 raise Exception("Timeout on EAP start") 5052 if i in [0]: 5053 time.sleep(0.1) 5054 else: 5055 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], 5056 timeout=10) 5057 if ev is None: 5058 raise Exception("Timeout on EAP failure") 5059 dev[0].request("REMOVE_NETWORK all") 5060 dev[0].dump_monitor() 5061 finally: 5062 stop_radius_server(srv) 5063 5064def test_eap_proto_sim(dev, apdev): 5065 """EAP-SIM protocol tests""" 5066 def sim_handler(ctx, req): 5067 logger.info("sim_handler - RX " + binascii.hexlify(req).decode()) 5068 if 'num' not in ctx: 5069 ctx['num'] = 0 5070 ctx['num'] = ctx['num'] + 1 5071 if 'id' not in ctx: 5072 ctx['id'] = 1 5073 ctx['id'] = (ctx['id'] + 1) % 256 5074 5075 idx = 0 5076 5077 idx += 1 5078 if ctx['num'] == idx: 5079 logger.info("Test: Missing payload") 5080 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 5081 4 + 1, 5082 EAP_TYPE_SIM) 5083 5084 idx += 1 5085 if ctx['num'] == idx: 5086 logger.info("Test: Unexpected AT_AUTN") 5087 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], 5088 4 + 1 + 3 + 8, 5089 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, 5090 EAP_SIM_AT_AUTN, 2, 0, 0) 5091 idx += 1 5092 if ctx['num'] == idx: 5093 logger.info("Test: EAP-Failure") 5094 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5095 5096 idx += 1 5097 if ctx['num'] == idx: 5098 logger.info("Test: Too short AT_VERSION_LIST") 5099 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 5100 4 + 1 + 3 + 4, 5101 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, 5102 EAP_SIM_AT_VERSION_LIST, 1, 0) 5103 idx += 1 5104 if ctx['num'] == idx: 5105 logger.info("Test: EAP-Failure") 5106 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5107 5108 idx += 1 5109 if ctx['num'] == idx: 5110 logger.info("Test: AT_VERSION_LIST overflow") 5111 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 5112 4 + 1 + 3 + 4, 5113 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, 5114 EAP_SIM_AT_VERSION_LIST, 1, 0xffff) 5115 idx += 1 5116 if ctx['num'] == idx: 5117 logger.info("Test: EAP-Failure") 5118 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5119 5120 idx += 1 5121 if ctx['num'] == idx: 5122 logger.info("Test: Unexpected AT_AUTS") 5123 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], 5124 4 + 1 + 3 + 8, 5125 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, 5126 EAP_SIM_AT_AUTS, 2, 0, 0) 5127 idx += 1 5128 if ctx['num'] == idx: 5129 logger.info("Test: EAP-Failure") 5130 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5131 5132 idx += 1 5133 if ctx['num'] == idx: 5134 logger.info("Test: Unexpected AT_CHECKCODE") 5135 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'], 5136 4 + 1 + 3 + 8, 5137 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, 5138 EAP_SIM_AT_CHECKCODE, 2, 0, 0) 5139 idx += 1 5140 if ctx['num'] == idx: 5141 logger.info("Test: EAP-Failure") 5142 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5143 5144 idx += 1 5145 if ctx['num'] == idx: 5146 logger.info("Test: No AT_VERSION_LIST in Start") 5147 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], 5148 4 + 1 + 3, 5149 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0) 5150 idx += 1 5151 if ctx['num'] == idx: 5152 logger.info("Test: EAP-Failure") 5153 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5154 5155 idx += 1 5156 if ctx['num'] == idx: 5157 logger.info("Test: No support version in AT_VERSION_LIST") 5158 return struct.pack(">BBHBBHBBH4B", EAP_CODE_REQUEST, ctx['id'], 5159 4 + 1 + 3 + 8, 5160 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, 5161 EAP_SIM_AT_VERSION_LIST, 2, 3, 2, 3, 4, 5) 5162 idx += 1 5163 if ctx['num'] == idx: 5164 logger.info("Test: EAP-Failure") 5165 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5166 5167 5168 idx += 1 5169 if ctx['num'] == idx: 5170 logger.info("Test: Identity request without ID type") 5171 return struct.pack(">BBHBBHBBH2H", EAP_CODE_REQUEST, ctx['id'], 5172 4 + 1 + 3 + 8, 5173 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, 5174 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0) 5175 idx += 1 5176 if ctx['num'] == idx: 5177 logger.info("Test: Identity request ANY_ID") 5178 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'], 5179 4 + 1 + 3 + 8 + 4, 5180 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, 5181 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0, 5182 EAP_SIM_AT_ANY_ID_REQ, 1, 0) 5183 idx += 1 5184 if ctx['num'] == idx: 5185 logger.info("Test: Identity request ANY_ID (duplicate)") 5186 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'], 5187 4 + 1 + 3 + 8 + 4, 5188 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, 5189 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0, 5190 EAP_SIM_AT_ANY_ID_REQ, 1, 0) 5191 idx += 1 5192 if ctx['num'] == idx: 5193 logger.info("Test: EAP-Failure") 5194 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5195 5196 idx += 1 5197 if ctx['num'] == idx: 5198 logger.info("Test: Identity request ANY_ID") 5199 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'], 5200 4 + 1 + 3 + 8 + 4, 5201 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, 5202 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0, 5203 EAP_SIM_AT_ANY_ID_REQ, 1, 0) 5204 idx += 1 5205 if ctx['num'] == idx: 5206 logger.info("Test: Identity request FULLAUTH_ID") 5207 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'], 5208 4 + 1 + 3 + 8 + 4, 5209 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, 5210 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0, 5211 EAP_SIM_AT_FULLAUTH_ID_REQ, 1, 0) 5212 idx += 1 5213 if ctx['num'] == idx: 5214 logger.info("Test: Identity request FULLAUTH_ID (duplicate)") 5215 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'], 5216 4 + 1 + 3 + 8 + 4, 5217 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, 5218 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0, 5219 EAP_SIM_AT_FULLAUTH_ID_REQ, 1, 0) 5220 idx += 1 5221 if ctx['num'] == idx: 5222 logger.info("Test: EAP-Failure") 5223 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5224 5225 idx += 1 5226 if ctx['num'] == idx: 5227 logger.info("Test: Identity request ANY_ID") 5228 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'], 5229 4 + 1 + 3 + 8 + 4, 5230 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, 5231 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0, 5232 EAP_SIM_AT_ANY_ID_REQ, 1, 0) 5233 idx += 1 5234 if ctx['num'] == idx: 5235 logger.info("Test: Identity request FULLAUTH_ID") 5236 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'], 5237 4 + 1 + 3 + 8 + 4, 5238 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, 5239 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0, 5240 EAP_SIM_AT_FULLAUTH_ID_REQ, 1, 0) 5241 idx += 1 5242 if ctx['num'] == idx: 5243 logger.info("Test: Identity request PERMANENT_ID") 5244 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'], 5245 4 + 1 + 3 + 8 + 4, 5246 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, 5247 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0, 5248 EAP_SIM_AT_PERMANENT_ID_REQ, 1, 0) 5249 idx += 1 5250 if ctx['num'] == idx: 5251 logger.info("Test: Identity request PERMANENT_ID (duplicate)") 5252 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'], 5253 4 + 1 + 3 + 8 + 4, 5254 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0, 5255 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0, 5256 EAP_SIM_AT_PERMANENT_ID_REQ, 1, 0) 5257 idx += 1 5258 if ctx['num'] == idx: 5259 logger.info("Test: EAP-Failure") 5260 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5261 5262 idx += 1 5263 if ctx['num'] == idx: 5264 logger.info("Test: No AT_MAC and AT_RAND in Challenge") 5265 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], 5266 4 + 1 + 3, 5267 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CHALLENGE, 0) 5268 idx += 1 5269 if ctx['num'] == idx: 5270 logger.info("Test: EAP-Failure") 5271 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5272 5273 idx += 1 5274 if ctx['num'] == idx: 5275 logger.info("Test: No AT_RAND in Challenge") 5276 return struct.pack(">BBHBBHBBH4L", EAP_CODE_REQUEST, ctx['id'], 5277 4 + 1 + 3 + 20, 5278 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CHALLENGE, 0, 5279 EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0) 5280 idx += 1 5281 if ctx['num'] == idx: 5282 logger.info("Test: EAP-Failure") 5283 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5284 5285 idx += 1 5286 if ctx['num'] == idx: 5287 logger.info("Test: Insufficient number of challenges in Challenge") 5288 return struct.pack(">BBHBBHBBH4LBBH4L", EAP_CODE_REQUEST, ctx['id'], 5289 4 + 1 + 3 + 20 + 20, 5290 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CHALLENGE, 0, 5291 EAP_SIM_AT_RAND, 5, 0, 0, 0, 0, 0, 5292 EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0) 5293 idx += 1 5294 if ctx['num'] == idx: 5295 logger.info("Test: EAP-Failure") 5296 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5297 5298 idx += 1 5299 if ctx['num'] == idx: 5300 logger.info("Test: Too many challenges in Challenge") 5301 return struct.pack(">BBHBBHBBH4L4L4L4LBBH4L", EAP_CODE_REQUEST, 5302 ctx['id'], 5303 4 + 1 + 3 + 4 + 4 * 16 + 20, 5304 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CHALLENGE, 0, 5305 EAP_SIM_AT_RAND, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5306 0, 0, 0, 0, 0, 0, 0, 0, 5307 EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0) 5308 idx += 1 5309 if ctx['num'] == idx: 5310 logger.info("Test: EAP-Failure") 5311 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5312 5313 idx += 1 5314 if ctx['num'] == idx: 5315 logger.info("Test: Same RAND multiple times in Challenge") 5316 return struct.pack(">BBHBBHBBH4L4L4LBBH4L", EAP_CODE_REQUEST, 5317 ctx['id'], 5318 4 + 1 + 3 + 4 + 3 * 16 + 20, 5319 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CHALLENGE, 0, 5320 EAP_SIM_AT_RAND, 13, 0, 0, 0, 0, 0, 0, 0, 0, 1, 5321 0, 0, 0, 0, 5322 EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0) 5323 idx += 1 5324 if ctx['num'] == idx: 5325 logger.info("Test: EAP-Failure") 5326 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5327 5328 idx += 1 5329 if ctx['num'] == idx: 5330 logger.info("Test: Notification with no attributes") 5331 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], 5332 4 + 1 + 3, 5333 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0) 5334 idx += 1 5335 if ctx['num'] == idx: 5336 logger.info("Test: EAP-Failure") 5337 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5338 5339 idx += 1 5340 if ctx['num'] == idx: 5341 logger.info("Test: Notification indicating success, but no MAC") 5342 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 5343 4 + 1 + 3 + 4, 5344 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0, 5345 EAP_SIM_AT_NOTIFICATION, 1, 32768) 5346 idx += 1 5347 if ctx['num'] == idx: 5348 logger.info("Test: EAP-Failure") 5349 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5350 5351 idx += 1 5352 if ctx['num'] == idx: 5353 logger.info("Test: Notification indicating success, but invalid MAC value") 5354 return struct.pack(">BBHBBHBBHBBH4L", EAP_CODE_REQUEST, ctx['id'], 5355 4 + 1 + 3 + 4 + 20, 5356 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0, 5357 EAP_SIM_AT_NOTIFICATION, 1, 32768, 5358 EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0) 5359 idx += 1 5360 if ctx['num'] == idx: 5361 logger.info("Test: EAP-Failure") 5362 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5363 5364 idx += 1 5365 if ctx['num'] == idx: 5366 logger.info("Test: Notification before auth") 5367 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 5368 4 + 1 + 3 + 4, 5369 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0, 5370 EAP_SIM_AT_NOTIFICATION, 1, 16384) 5371 idx += 1 5372 if ctx['num'] == idx: 5373 logger.info("Test: EAP-Failure") 5374 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5375 5376 idx += 1 5377 if ctx['num'] == idx: 5378 logger.info("Test: Notification before auth") 5379 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 5380 4 + 1 + 3 + 4, 5381 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0, 5382 EAP_SIM_AT_NOTIFICATION, 1, 16385) 5383 idx += 1 5384 if ctx['num'] == idx: 5385 logger.info("Test: EAP-Failure") 5386 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5387 5388 idx += 1 5389 if ctx['num'] == idx: 5390 logger.info("Test: Notification with unrecognized non-failure") 5391 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 5392 4 + 1 + 3 + 4, 5393 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0, 5394 EAP_SIM_AT_NOTIFICATION, 1, 0xc000) 5395 idx += 1 5396 if ctx['num'] == idx: 5397 logger.info("Test: Notification before auth (duplicate)") 5398 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'], 5399 4 + 1 + 3 + 4, 5400 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0, 5401 EAP_SIM_AT_NOTIFICATION, 1, 0xc000) 5402 idx += 1 5403 if ctx['num'] == idx: 5404 logger.info("Test: EAP-Failure") 5405 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5406 5407 idx += 1 5408 if ctx['num'] == idx: 5409 logger.info("Test: Re-authentication (unexpected) with no attributes") 5410 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], 5411 4 + 1 + 3, 5412 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_REAUTHENTICATION, 5413 0) 5414 idx += 1 5415 if ctx['num'] == idx: 5416 logger.info("Test: EAP-Failure") 5417 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5418 5419 idx += 1 5420 if ctx['num'] == idx: 5421 logger.info("Test: Client Error") 5422 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], 5423 4 + 1 + 3, 5424 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CLIENT_ERROR, 0) 5425 idx += 1 5426 if ctx['num'] == idx: 5427 logger.info("Test: EAP-Failure") 5428 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5429 5430 idx += 1 5431 if ctx['num'] == idx: 5432 logger.info("Test: Unknown subtype") 5433 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'], 5434 4 + 1 + 3, 5435 EAP_TYPE_SIM, 255, 0) 5436 idx += 1 5437 if ctx['num'] == idx: 5438 logger.info("Test: EAP-Failure") 5439 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 5440 5441 return None 5442 5443 srv = start_radius_server(sim_handler) 5444 5445 try: 5446 hapd = start_ap(apdev[0]) 5447 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 5448 5449 for i in range(0, 25): 5450 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 5451 eap="SIM", identity="1232010000000000", 5452 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581", 5453 wait_connect=False) 5454 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 5455 timeout=15) 5456 if ev is None: 5457 raise Exception("Timeout on EAP start") 5458 if i in [0]: 5459 time.sleep(0.1) 5460 else: 5461 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], 5462 timeout=10) 5463 if ev is None: 5464 raise Exception("Timeout on EAP failure") 5465 dev[0].request("REMOVE_NETWORK all") 5466 dev[0].dump_monitor() 5467 finally: 5468 stop_radius_server(srv) 5469 5470def test_eap_proto_sim_errors(dev, apdev): 5471 """EAP-SIM protocol tests (error paths)""" 5472 check_hlr_auc_gw_support() 5473 params = hostapd.wpa2_eap_params(ssid="eap-test") 5474 hapd = hostapd.add_ap(apdev[0], params) 5475 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 5476 5477 with alloc_fail(dev[0], 1, "eap_sim_init"): 5478 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 5479 eap="SIM", identity="1232010000000000", 5480 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581", 5481 wait_connect=False) 5482 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"], 5483 timeout=15) 5484 if ev is None: 5485 raise Exception("Timeout on EAP start") 5486 dev[0].request("REMOVE_NETWORK all") 5487 dev[0].wait_disconnected() 5488 5489 with fail_test(dev[0], 1, "os_get_random;eap_sim_init"): 5490 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 5491 eap="SIM", identity="1232010000000000", 5492 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581", 5493 wait_connect=False) 5494 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"], 5495 timeout=15) 5496 if ev is None: 5497 raise Exception("Timeout on EAP start") 5498 dev[0].request("REMOVE_NETWORK all") 5499 dev[0].wait_disconnected() 5500 5501 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 5502 eap="SIM", identity="1232010000000000", 5503 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581") 5504 5505 with fail_test(dev[0], 1, "aes_128_cbc_encrypt;eap_sim_response_reauth"): 5506 hapd.request("EAPOL_REAUTH " + dev[0].own_addr()) 5507 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5) 5508 if ev is None: 5509 raise Exception("EAP re-authentication did not start") 5510 wait_fail_trigger(dev[0], "GET_FAIL") 5511 dev[0].request("REMOVE_NETWORK all") 5512 dev[0].dump_monitor() 5513 5514 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 5515 eap="SIM", identity="1232010000000000", 5516 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581") 5517 5518 with fail_test(dev[0], 1, "os_get_random;eap_sim_msg_add_encr_start"): 5519 hapd.request("EAPOL_REAUTH " + dev[0].own_addr()) 5520 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5) 5521 if ev is None: 5522 raise Exception("EAP re-authentication did not start") 5523 wait_fail_trigger(dev[0], "GET_FAIL") 5524 dev[0].request("REMOVE_NETWORK all") 5525 dev[0].dump_monitor() 5526 5527 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 5528 eap="SIM", identity="1232010000000000", 5529 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581") 5530 5531 with fail_test(dev[0], 1, "os_get_random;eap_sim_init_for_reauth"): 5532 hapd.request("EAPOL_REAUTH " + dev[0].own_addr()) 5533 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5) 5534 if ev is None: 5535 raise Exception("EAP re-authentication did not start") 5536 wait_fail_trigger(dev[0], "GET_FAIL") 5537 dev[0].request("REMOVE_NETWORK all") 5538 dev[0].dump_monitor() 5539 5540 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 5541 eap="SIM", identity="1232010000000000", 5542 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581") 5543 5544 with alloc_fail(dev[0], 1, "eap_sim_parse_encr;eap_sim_process_reauthentication"): 5545 hapd.request("EAPOL_REAUTH " + dev[0].own_addr()) 5546 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5) 5547 if ev is None: 5548 raise Exception("EAP re-authentication did not start") 5549 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 5550 dev[0].request("REMOVE_NETWORK all") 5551 dev[0].dump_monitor() 5552 5553 tests = [(1, "eap_sim_verify_mac;eap_sim_process_challenge"), 5554 (1, "eap_sim_parse_encr;eap_sim_process_challenge"), 5555 (1, "eap_sim_msg_init;eap_sim_response_start"), 5556 (1, "wpabuf_alloc;eap_sim_msg_init;eap_sim_response_start"), 5557 (1, "=eap_sim_learn_ids"), 5558 (2, "=eap_sim_learn_ids"), 5559 (2, "eap_sim_learn_ids"), 5560 (3, "eap_sim_learn_ids"), 5561 (1, "eap_sim_process_start"), 5562 (1, "eap_sim_getKey"), 5563 (1, "eap_sim_get_emsk"), 5564 (1, "eap_sim_get_session_id")] 5565 for count, func in tests: 5566 with alloc_fail(dev[0], count, func): 5567 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 5568 eap="SIM", identity="1232010000000000@domain", 5569 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581", 5570 erp="1", wait_connect=False) 5571 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 5572 dev[0].request("REMOVE_NETWORK all") 5573 dev[0].dump_monitor() 5574 5575 tests = [(1, "aes_128_cbc_decrypt;eap_sim_parse_encr")] 5576 for count, func in tests: 5577 with fail_test(dev[0], count, func): 5578 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 5579 eap="SIM", identity="1232010000000000", 5580 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581", 5581 wait_connect=False) 5582 wait_fail_trigger(dev[0], "GET_FAIL") 5583 dev[0].request("REMOVE_NETWORK all") 5584 dev[0].dump_monitor() 5585 5586 params = int_eap_server_params() 5587 params['eap_sim_db'] = "unix:/tmp/hlr_auc_gw.sock" 5588 params['eap_sim_aka_result_ind'] = "1" 5589 hapd2 = hostapd.add_ap(apdev[1], params) 5590 dev[0].scan_for_bss(hapd2.own_addr(), freq=2412) 5591 5592 with alloc_fail(dev[0], 1, 5593 "eap_sim_msg_init;eap_sim_response_notification"): 5594 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", 5595 scan_freq="2412", 5596 eap="SIM", identity="1232010000000000", 5597 phase1="result_ind=1", 5598 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581", 5599 wait_connect=False) 5600 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 5601 dev[0].request("REMOVE_NETWORK all") 5602 dev[0].dump_monitor() 5603 5604 hapd2.dump_monitor() 5605 tests = ["eap_sim_msg_add_encr_start;eap_sim_response_notification", 5606 "aes_128_cbc_encrypt;eap_sim_response_notification"] 5607 for func in tests: 5608 with fail_test(dev[0], 1, func): 5609 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", 5610 scan_freq="2412", 5611 eap="SIM", identity="1232010000000000", 5612 phase1="result_ind=1", 5613 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581") 5614 hapd2.wait_sta() 5615 dev[0].request("REAUTHENTICATE") 5616 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5) 5617 if ev is None: 5618 raise Exception("EAP method not started on reauthentication") 5619 time.sleep(0.1) 5620 wait_fail_trigger(dev[0], "GET_FAIL") 5621 dev[0].request("REMOVE_NETWORK all") 5622 dev[0].dump_monitor() 5623 hapd2.wait_sta_disconnect() 5624 5625 hapd2.dump_monitor() 5626 tests = ["eap_sim_parse_encr;eap_sim_process_notification_reauth"] 5627 for func in tests: 5628 with alloc_fail(dev[0], 1, func): 5629 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", 5630 scan_freq="2412", 5631 eap="SIM", identity="1232010000000000", 5632 phase1="result_ind=1", 5633 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581") 5634 hapd2.wait_sta() 5635 dev[0].request("REAUTHENTICATE") 5636 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5) 5637 if ev is None: 5638 raise Exception("EAP method not started on reauthentication") 5639 time.sleep(0.1) 5640 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 5641 dev[0].request("REMOVE_NETWORK all") 5642 dev[0].dump_monitor() 5643 hapd2.wait_sta_disconnect() 5644 5645def test_eap_proto_aka_errors(dev, apdev): 5646 """EAP-AKA protocol tests (error paths)""" 5647 check_hlr_auc_gw_support() 5648 params = hostapd.wpa2_eap_params(ssid="eap-test") 5649 hapd = hostapd.add_ap(apdev[0], params) 5650 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 5651 5652 with alloc_fail(dev[0], 1, "eap_aka_init"): 5653 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 5654 eap="AKA", identity="0232010000000000", 5655 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123", 5656 wait_connect=False) 5657 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"], 5658 timeout=15) 5659 if ev is None: 5660 raise Exception("Timeout on EAP start") 5661 dev[0].request("REMOVE_NETWORK all") 5662 dev[0].wait_disconnected() 5663 5664 tests = [(1, "=eap_aka_learn_ids"), 5665 (2, "=eap_aka_learn_ids"), 5666 (1, "eap_sim_parse_encr;eap_aka_process_challenge"), 5667 (1, "wpabuf_alloc;eap_aka_add_id_msg"), 5668 (1, "eap_aka_getKey"), 5669 (1, "eap_aka_get_emsk"), 5670 (1, "eap_aka_get_session_id")] 5671 for count, func in tests: 5672 with alloc_fail(dev[0], count, func): 5673 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 5674 eap="AKA", identity="0232010000000000@domain", 5675 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123", 5676 erp="1", wait_connect=False) 5677 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 5678 dev[0].request("REMOVE_NETWORK all") 5679 dev[0].dump_monitor() 5680 5681 params = int_eap_server_params() 5682 params['eap_sim_db'] = "unix:/tmp/hlr_auc_gw.sock" 5683 params['eap_sim_aka_result_ind'] = "1" 5684 hapd2 = hostapd.add_ap(apdev[1], params) 5685 dev[0].scan_for_bss(hapd2.own_addr(), freq=2412) 5686 5687 with alloc_fail(dev[0], 1, 5688 "eap_sim_msg_init;eap_aka_response_notification"): 5689 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412", 5690 eap="AKA", identity="0232010000000000", 5691 phase1="result_ind=1", 5692 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123", 5693 wait_connect=False) 5694 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 5695 dev[0].request("REMOVE_NETWORK all") 5696 dev[0].dump_monitor() 5697 5698 tests = [(1, "aes_128_encrypt_block;milenage_f1;milenage_check", None), 5699 (2, "aes_128_encrypt_block;milenage_f1;milenage_check", None), 5700 (1, "milenage_f2345;milenage_check", None), 5701 (7, "aes_128_encrypt_block;milenage_f2345;milenage_check", 5702 "ff0000000123"), 5703 (1, "aes_128_encrypt_block;milenage_f1;milenage_check", 5704 "fff000000123")] 5705 for count, func, seq in tests: 5706 if not seq: 5707 seq = "000000000123" 5708 with fail_test(dev[0], count, func): 5709 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", 5710 scan_freq="2412", 5711 eap="AKA", identity="0232010000000000", 5712 phase1="result_ind=1", 5713 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:" + seq, 5714 wait_connect=False) 5715 wait_fail_trigger(dev[0], "GET_FAIL") 5716 dev[0].request("REMOVE_NETWORK all") 5717 dev[0].wait_disconnected() 5718 dev[0].dump_monitor() 5719 5720 hapd2.dump_monitor() 5721 tests = ["eap_sim_msg_add_encr_start;eap_aka_response_notification", 5722 "aes_128_cbc_encrypt;eap_aka_response_notification"] 5723 for func in tests: 5724 with fail_test(dev[0], 1, func): 5725 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", 5726 scan_freq="2412", 5727 eap="AKA", identity="0232010000000000", 5728 phase1="result_ind=1", 5729 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123") 5730 hapd2.wait_sta() 5731 dev[0].request("REAUTHENTICATE") 5732 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5) 5733 if ev is None: 5734 raise Exception("EAP method not started on reauthentication") 5735 time.sleep(0.1) 5736 wait_fail_trigger(dev[0], "GET_FAIL") 5737 dev[0].request("REMOVE_NETWORK all") 5738 dev[0].dump_monitor() 5739 hapd2.wait_sta_disconnect() 5740 5741 hapd2.dump_monitor() 5742 tests = ["eap_sim_parse_encr;eap_aka_process_notification_reauth"] 5743 for func in tests: 5744 with alloc_fail(dev[0], 1, func): 5745 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", 5746 scan_freq="2412", 5747 eap="AKA", identity="0232010000000000", 5748 phase1="result_ind=1", 5749 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123") 5750 hapd2.wait_sta() 5751 dev[0].request("REAUTHENTICATE") 5752 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5) 5753 if ev is None: 5754 raise Exception("EAP method not started on reauthentication") 5755 time.sleep(0.1) 5756 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 5757 dev[0].request("REMOVE_NETWORK all") 5758 dev[0].dump_monitor() 5759 hapd2.wait_sta_disconnect() 5760 5761def test_eap_proto_aka_prime_errors(dev, apdev): 5762 """EAP-AKA' protocol tests (error paths)""" 5763 check_hlr_auc_gw_support() 5764 params = hostapd.wpa2_eap_params(ssid="eap-test") 5765 hapd = hostapd.add_ap(apdev[0], params) 5766 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 5767 5768 with alloc_fail(dev[0], 1, "eap_aka_init"): 5769 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 5770 eap="AKA'", identity="6555444333222111", 5771 password="5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123", 5772 wait_connect=False) 5773 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"], 5774 timeout=15) 5775 if ev is None: 5776 raise Exception("Timeout on EAP start") 5777 dev[0].request("REMOVE_NETWORK all") 5778 dev[0].wait_disconnected() 5779 5780 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 5781 eap="AKA'", identity="6555444333222111", 5782 password="5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123") 5783 5784 with fail_test(dev[0], 1, "aes_128_cbc_encrypt;eap_aka_response_reauth"): 5785 hapd.request("EAPOL_REAUTH " + dev[0].own_addr()) 5786 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5) 5787 if ev is None: 5788 raise Exception("EAP re-authentication did not start") 5789 wait_fail_trigger(dev[0], "GET_FAIL") 5790 dev[0].request("REMOVE_NETWORK all") 5791 dev[0].dump_monitor() 5792 5793 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 5794 eap="AKA'", identity="6555444333222111", 5795 password="5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123") 5796 5797 with alloc_fail(dev[0], 1, "eap_sim_parse_encr;eap_aka_process_reauthentication"): 5798 hapd.request("EAPOL_REAUTH " + dev[0].own_addr()) 5799 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5) 5800 if ev is None: 5801 raise Exception("EAP re-authentication did not start") 5802 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 5803 dev[0].request("REMOVE_NETWORK all") 5804 dev[0].dump_monitor() 5805 5806 tests = [(1, "eap_sim_verify_mac_sha256"), 5807 (1, "=eap_aka_process_challenge")] 5808 for count, func in tests: 5809 with alloc_fail(dev[0], count, func): 5810 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 5811 eap="AKA'", identity="6555444333222111", 5812 password="5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123", 5813 erp="1", wait_connect=False) 5814 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 5815 dev[0].request("REMOVE_NETWORK all") 5816 dev[0].dump_monitor() 5817 5818def test_eap_proto_ikev2(dev, apdev): 5819 """EAP-IKEv2 protocol tests""" 5820 check_eap_capa(dev[0], "IKEV2") 5821 5822 global eap_proto_ikev2_test_done 5823 eap_proto_ikev2_test_done = False 5824 5825 def ikev2_handler(ctx, req): 5826 logger.info("ikev2_handler - RX " + binascii.hexlify(req).decode()) 5827 if 'num' not in ctx: 5828 ctx['num'] = 0 5829 ctx['num'] = ctx['num'] + 1 5830 if 'id' not in ctx: 5831 ctx['id'] = 1 5832 ctx['id'] = (ctx['id'] + 1) % 256 5833 5834 idx = 0 5835 5836 idx += 1 5837 if ctx['num'] == idx: 5838 logger.info("Test: Missing payload") 5839 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 5840 4 + 1, 5841 EAP_TYPE_IKEV2) 5842 5843 idx += 1 5844 if ctx['num'] == idx: 5845 logger.info("Test: Truncated Message Length field") 5846 return struct.pack(">BBHBB3B", EAP_CODE_REQUEST, ctx['id'], 5847 4 + 1 + 1 + 3, 5848 EAP_TYPE_IKEV2, 0x80, 0, 0, 0) 5849 5850 idx += 1 5851 if ctx['num'] == idx: 5852 logger.info("Test: Too short Message Length value") 5853 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'], 5854 4 + 1 + 1 + 4 + 1, 5855 EAP_TYPE_IKEV2, 0x80, 0, 1) 5856 5857 idx += 1 5858 if ctx['num'] == idx: 5859 logger.info("Test: Truncated message") 5860 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'], 5861 4 + 1 + 1 + 4, 5862 EAP_TYPE_IKEV2, 0x80, 1) 5863 5864 idx += 1 5865 if ctx['num'] == idx: 5866 logger.info("Test: Truncated message(2)") 5867 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'], 5868 4 + 1 + 1 + 4, 5869 EAP_TYPE_IKEV2, 0x80, 0xffffffff) 5870 5871 idx += 1 5872 if ctx['num'] == idx: 5873 logger.info("Test: Truncated message(3)") 5874 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'], 5875 4 + 1 + 1 + 4, 5876 EAP_TYPE_IKEV2, 0xc0, 0xffffffff) 5877 5878 idx += 1 5879 if ctx['num'] == idx: 5880 logger.info("Test: Truncated message(4)") 5881 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'], 5882 4 + 1 + 1 + 4, 5883 EAP_TYPE_IKEV2, 0xc0, 10000000) 5884 5885 idx += 1 5886 if ctx['num'] == idx: 5887 logger.info("Test: Too long fragments (first fragment)") 5888 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'], 5889 4 + 1 + 1 + 4 + 1, 5890 EAP_TYPE_IKEV2, 0xc0, 2, 1) 5891 5892 idx += 1 5893 if ctx['num'] == idx: 5894 logger.info("Test: Too long fragments (second fragment)") 5895 return struct.pack(">BBHBB2B", EAP_CODE_REQUEST, ctx['id'], 5896 4 + 1 + 1 + 2, 5897 EAP_TYPE_IKEV2, 0x00, 2, 3) 5898 5899 idx += 1 5900 if ctx['num'] == idx: 5901 logger.info("Test: No Message Length field in first fragment") 5902 return struct.pack(">BBHBBB", EAP_CODE_REQUEST, ctx['id'], 5903 4 + 1 + 1 + 1, 5904 EAP_TYPE_IKEV2, 0x40, 1) 5905 5906 idx += 1 5907 if ctx['num'] == idx: 5908 logger.info("Test: ICV before keys") 5909 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 5910 4 + 1 + 1, 5911 EAP_TYPE_IKEV2, 0x20) 5912 5913 idx += 1 5914 if ctx['num'] == idx: 5915 logger.info("Test: Unsupported IKEv2 header version") 5916 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'], 5917 4 + 1 + 1 + 28, 5918 EAP_TYPE_IKEV2, 0x00, 5919 0, 0, 0, 0, 5920 0, 0, 0, 0, 0, 0) 5921 5922 idx += 1 5923 if ctx['num'] == idx: 5924 logger.info("Test: Incorrect IKEv2 header Length") 5925 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'], 5926 4 + 1 + 1 + 28, 5927 EAP_TYPE_IKEV2, 0x00, 5928 0, 0, 0, 0, 5929 0, 0x20, 0, 0, 0, 0) 5930 5931 idx += 1 5932 if ctx['num'] == idx: 5933 logger.info("Test: Unexpected IKEv2 Exchange Type in SA_INIT state") 5934 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'], 5935 4 + 1 + 1 + 28, 5936 EAP_TYPE_IKEV2, 0x00, 5937 0, 0, 0, 0, 5938 0, 0x20, 0, 0, 0, 28) 5939 5940 idx += 1 5941 if ctx['num'] == idx: 5942 logger.info("Test: Unexpected IKEv2 Message ID in SA_INIT state") 5943 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'], 5944 4 + 1 + 1 + 28, 5945 EAP_TYPE_IKEV2, 0x00, 5946 0, 0, 0, 0, 5947 0, 0x20, 34, 0, 1, 28) 5948 5949 idx += 1 5950 if ctx['num'] == idx: 5951 logger.info("Test: Unexpected IKEv2 Flags value") 5952 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'], 5953 4 + 1 + 1 + 28, 5954 EAP_TYPE_IKEV2, 0x00, 5955 0, 0, 0, 0, 5956 0, 0x20, 34, 0, 0, 28) 5957 5958 idx += 1 5959 if ctx['num'] == idx: 5960 logger.info("Test: Unexpected IKEv2 Flags value(2)") 5961 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'], 5962 4 + 1 + 1 + 28, 5963 EAP_TYPE_IKEV2, 0x00, 5964 0, 0, 0, 0, 5965 0, 0x20, 34, 0x20, 0, 28) 5966 5967 idx += 1 5968 if ctx['num'] == idx: 5969 logger.info("Test: No SAi1 in SA_INIT") 5970 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'], 5971 4 + 1 + 1 + 28, 5972 EAP_TYPE_IKEV2, 0x00, 5973 0, 0, 0, 0, 5974 0, 0x20, 34, 0x08, 0, 28) 5975 5976 def build_ike(id, next=0, exch_type=34, flags=0x00, ike=b''): 5977 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, id, 5978 4 + 1 + 1 + 28 + len(ike), 5979 EAP_TYPE_IKEV2, flags, 5980 0, 0, 0, 0, 5981 next, 0x20, exch_type, 0x08, 0, 5982 28 + len(ike)) + ike 5983 5984 idx += 1 5985 if ctx['num'] == idx: 5986 logger.info("Test: Unexpected extra data after payloads") 5987 return build_ike(ctx['id'], ike=struct.pack(">B", 1)) 5988 5989 idx += 1 5990 if ctx['num'] == idx: 5991 logger.info("Test: Truncated payload header") 5992 return build_ike(ctx['id'], next=128, ike=struct.pack(">B", 1)) 5993 5994 idx += 1 5995 if ctx['num'] == idx: 5996 logger.info("Test: Too small payload header length") 5997 ike = struct.pack(">BBH", 0, 0, 3) 5998 return build_ike(ctx['id'], next=128, ike=ike) 5999 6000 idx += 1 6001 if ctx['num'] == idx: 6002 logger.info("Test: Too large payload header length") 6003 ike = struct.pack(">BBH", 0, 0, 5) 6004 return build_ike(ctx['id'], next=128, ike=ike) 6005 6006 idx += 1 6007 if ctx['num'] == idx: 6008 logger.info("Test: Unsupported payload (non-critical and critical)") 6009 ike = struct.pack(">BBHBBH", 129, 0, 4, 0, 0x01, 4) 6010 return build_ike(ctx['id'], next=128, ike=ike) 6011 6012 idx += 1 6013 if ctx['num'] == idx: 6014 logger.info("Test: Certificate and empty SAi1") 6015 ike = struct.pack(">BBHBBH", 33, 0, 4, 0, 0, 4) 6016 return build_ike(ctx['id'], next=37, ike=ike) 6017 6018 idx += 1 6019 if ctx['num'] == idx: 6020 logger.info("Test: Too short proposal") 6021 ike = struct.pack(">BBHBBHBBB", 0, 0, 4 + 7, 6022 0, 0, 7, 0, 0, 0) 6023 return build_ike(ctx['id'], next=33, ike=ike) 6024 6025 idx += 1 6026 if ctx['num'] == idx: 6027 logger.info("Test: Too small proposal length in SAi1") 6028 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8, 6029 0, 0, 7, 0, 0, 0, 0) 6030 return build_ike(ctx['id'], next=33, ike=ike) 6031 6032 idx += 1 6033 if ctx['num'] == idx: 6034 logger.info("Test: Too large proposal length in SAi1") 6035 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8, 6036 0, 0, 9, 0, 0, 0, 0) 6037 return build_ike(ctx['id'], next=33, ike=ike) 6038 6039 idx += 1 6040 if ctx['num'] == idx: 6041 logger.info("Test: Unexpected proposal type in SAi1") 6042 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8, 6043 1, 0, 8, 0, 0, 0, 0) 6044 return build_ike(ctx['id'], next=33, ike=ike) 6045 6046 idx += 1 6047 if ctx['num'] == idx: 6048 logger.info("Test: Unexpected Protocol ID in SAi1") 6049 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8, 6050 0, 0, 8, 0, 0, 0, 0) 6051 return build_ike(ctx['id'], next=33, ike=ike) 6052 6053 idx += 1 6054 if ctx['num'] == idx: 6055 logger.info("Test: Unexpected proposal number in SAi1") 6056 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8, 6057 0, 0, 8, 0, 1, 0, 0) 6058 return build_ike(ctx['id'], next=33, ike=ike) 6059 6060 idx += 1 6061 if ctx['num'] == idx: 6062 logger.info("Test: Not enough room for SPI in SAi1") 6063 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8, 6064 0, 0, 8, 1, 1, 1, 0) 6065 return build_ike(ctx['id'], next=33, ike=ike) 6066 6067 idx += 1 6068 if ctx['num'] == idx: 6069 logger.info("Test: Unexpected SPI in SAi1") 6070 ike = struct.pack(">BBHBBHBBBBB", 0, 0, 4 + 9, 6071 0, 0, 9, 1, 1, 1, 0, 1) 6072 return build_ike(ctx['id'], next=33, ike=ike) 6073 6074 idx += 1 6075 if ctx['num'] == idx: 6076 logger.info("Test: No transforms in SAi1") 6077 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8, 6078 0, 0, 8, 1, 1, 0, 0) 6079 return build_ike(ctx['id'], next=33, ike=ike) 6080 6081 idx += 1 6082 if ctx['num'] == idx: 6083 logger.info("Test: Too short transform in SAi1") 6084 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8, 6085 0, 0, 8, 1, 1, 0, 1) 6086 return build_ike(ctx['id'], next=33, ike=ike) 6087 6088 idx += 1 6089 if ctx['num'] == idx: 6090 logger.info("Test: Too small transform length in SAi1") 6091 ike = struct.pack(">BBHBBHBBBBBBHBBH", 0, 0, 4 + 8 + 8, 6092 0, 0, 8 + 8, 1, 1, 0, 1, 6093 0, 0, 7, 0, 0, 0) 6094 return build_ike(ctx['id'], next=33, ike=ike) 6095 6096 idx += 1 6097 if ctx['num'] == idx: 6098 logger.info("Test: Too large transform length in SAi1") 6099 ike = struct.pack(">BBHBBHBBBBBBHBBH", 0, 0, 4 + 8 + 8, 6100 0, 0, 8 + 8, 1, 1, 0, 1, 6101 0, 0, 9, 0, 0, 0) 6102 return build_ike(ctx['id'], next=33, ike=ike) 6103 6104 idx += 1 6105 if ctx['num'] == idx: 6106 logger.info("Test: Unexpected Transform type in SAi1") 6107 ike = struct.pack(">BBHBBHBBBBBBHBBH", 0, 0, 4 + 8 + 8, 6108 0, 0, 8 + 8, 1, 1, 0, 1, 6109 1, 0, 8, 0, 0, 0) 6110 return build_ike(ctx['id'], next=33, ike=ike) 6111 6112 idx += 1 6113 if ctx['num'] == idx: 6114 logger.info("Test: No transform attributes in SAi1") 6115 ike = struct.pack(">BBHBBHBBBBBBHBBH", 0, 0, 4 + 8 + 8, 6116 0, 0, 8 + 8, 1, 1, 0, 1, 6117 0, 0, 8, 0, 0, 0) 6118 return build_ike(ctx['id'], next=33, ike=ike) 6119 6120 idx += 1 6121 if ctx['num'] == idx: 6122 logger.info("Test: No transform attr for AES and unexpected data after transforms in SAi1") 6123 tlen1 = 8 + 3 6124 tlen2 = 8 + 4 6125 tlen3 = 8 + 4 6126 tlen = tlen1 + tlen2 + tlen3 6127 ike = struct.pack(">BBHBBHBBBBBBHBBH3BBBHBBHHHBBHBBHHHB", 6128 0, 0, 4 + 8 + tlen + 1, 6129 0, 0, 8 + tlen + 1, 1, 1, 0, 3, 6130 3, 0, tlen1, 1, 0, 12, 1, 2, 3, 6131 3, 0, tlen2, 1, 0, 12, 0, 128, 6132 0, 0, tlen3, 1, 0, 12, 0x8000 | 14, 127, 6133 1) 6134 return build_ike(ctx['id'], next=33, ike=ike) 6135 6136 def build_sa(next=0): 6137 tlen = 5 * 8 6138 return struct.pack(">BBHBBHBBBBBBHBBHBBHBBHBBHBBHBBHBBHBBHBBH", 6139 next, 0, 4 + 8 + tlen, 6140 0, 0, 8 + tlen, 1, 1, 0, 5, 6141 3, 0, 8, 1, 0, 3, 6142 3, 0, 8, 2, 0, 1, 6143 3, 0, 8, 3, 0, 1, 6144 3, 0, 8, 4, 0, 5, 6145 0, 0, 8, 241, 0, 0) 6146 6147 idx += 1 6148 if ctx['num'] == idx: 6149 logger.info("Test: Valid proposal, but no KEi in SAi1") 6150 ike = build_sa() 6151 return build_ike(ctx['id'], next=33, ike=ike) 6152 6153 idx += 1 6154 if ctx['num'] == idx: 6155 logger.info("Test: Empty KEi in SAi1") 6156 ike = build_sa(next=34) + struct.pack(">BBH", 0, 0, 4) 6157 return build_ike(ctx['id'], next=33, ike=ike) 6158 6159 idx += 1 6160 if ctx['num'] == idx: 6161 logger.info("Test: Mismatch in DH Group in SAi1") 6162 ike = build_sa(next=34) 6163 ike += struct.pack(">BBHHH", 0, 0, 4 + 4 + 96, 12345, 0) 6164 ike += 96*b'\x00' 6165 return build_ike(ctx['id'], next=33, ike=ike) 6166 idx += 1 6167 if ctx['num'] == idx: 6168 logger.info("Test: EAP-Failure") 6169 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 6170 6171 idx += 1 6172 if ctx['num'] == idx: 6173 logger.info("Test: Invalid DH public value length in SAi1") 6174 ike = build_sa(next=34) 6175 ike += struct.pack(">BBHHH", 0, 0, 4 + 4 + 96, 5, 0) 6176 ike += 96*b'\x00' 6177 return build_ike(ctx['id'], next=33, ike=ike) 6178 6179 def build_ke(next=0): 6180 ke = struct.pack(">BBHHH", next, 0, 4 + 4 + 192, 5, 0) 6181 ke += 191*b'\x00'+b'\x02' 6182 return ke 6183 6184 idx += 1 6185 if ctx['num'] == idx: 6186 logger.info("Test: Valid proposal and KEi, but no Ni in SAi1") 6187 ike = build_sa(next=34) 6188 ike += build_ke() 6189 return build_ike(ctx['id'], next=33, ike=ike) 6190 6191 idx += 1 6192 if ctx['num'] == idx: 6193 logger.info("Test: Too short Ni in SAi1") 6194 ike = build_sa(next=34) 6195 ike += build_ke(next=40) 6196 ike += struct.pack(">BBH", 0, 0, 4) 6197 return build_ike(ctx['id'], next=33, ike=ike) 6198 6199 idx += 1 6200 if ctx['num'] == idx: 6201 logger.info("Test: Too long Ni in SAi1") 6202 ike = build_sa(next=34) 6203 ike += build_ke(next=40) 6204 ike += struct.pack(">BBH", 0, 0, 4 + 257) + 257*b'\x00' 6205 return build_ike(ctx['id'], next=33, ike=ike) 6206 6207 def build_ni(next=0): 6208 return struct.pack(">BBH", next, 0, 4 + 256) + 256*b'\x00' 6209 6210 def build_sai1(id): 6211 ike = build_sa(next=34) 6212 ike += build_ke(next=40) 6213 ike += build_ni() 6214 return build_ike(ctx['id'], next=33, ike=ike) 6215 6216 idx += 1 6217 if ctx['num'] == idx: 6218 logger.info("Test: Valid proposal, KEi, and Ni in SAi1") 6219 return build_sai1(ctx['id']) 6220 idx += 1 6221 if ctx['num'] == idx: 6222 logger.info("Test: EAP-Failure") 6223 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 6224 6225 idx += 1 6226 if ctx['num'] == idx: 6227 logger.info("Test: Valid proposal, KEi, and Ni in SAi1") 6228 return build_sai1(ctx['id']) 6229 idx += 1 6230 if ctx['num'] == idx: 6231 logger.info("Test: No integrity checksum") 6232 ike = b'' 6233 return build_ike(ctx['id'], next=37, ike=ike) 6234 6235 idx += 1 6236 if ctx['num'] == idx: 6237 logger.info("Test: Valid proposal, KEi, and Ni in SAi1") 6238 return build_sai1(ctx['id']) 6239 idx += 1 6240 if ctx['num'] == idx: 6241 logger.info("Test: Truncated integrity checksum") 6242 return struct.pack(">BBHBB", 6243 EAP_CODE_REQUEST, ctx['id'], 6244 4 + 1 + 1, 6245 EAP_TYPE_IKEV2, 0x20) 6246 6247 idx += 1 6248 if ctx['num'] == idx: 6249 logger.info("Test: Valid proposal, KEi, and Ni in SAi1") 6250 return build_sai1(ctx['id']) 6251 idx += 1 6252 if ctx['num'] == idx: 6253 logger.info("Test: Invalid integrity checksum") 6254 ike = b'' 6255 return build_ike(ctx['id'], next=37, flags=0x20, ike=ike) 6256 6257 idx += 1 6258 if ctx['num'] == idx: 6259 logger.info("No more test responses available - test case completed") 6260 global eap_proto_ikev2_test_done 6261 eap_proto_ikev2_test_done = True 6262 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 6263 4 + 1, 6264 EAP_TYPE_IKEV2) 6265 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 6266 6267 srv = start_radius_server(ikev2_handler) 6268 6269 try: 6270 hapd = start_ap(apdev[0]) 6271 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 6272 6273 i = 0 6274 while not eap_proto_ikev2_test_done: 6275 i += 1 6276 logger.info("Running connection iteration %d" % i) 6277 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 6278 eap="IKEV2", identity="user", 6279 password="password", 6280 wait_connect=False) 6281 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=15) 6282 if ev is None: 6283 raise Exception("Timeout on EAP start") 6284 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 6285 timeout=15) 6286 if ev is None: 6287 raise Exception("Timeout on EAP method start") 6288 if i in [41, 46]: 6289 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], 6290 timeout=10) 6291 if ev is None: 6292 raise Exception("Timeout on EAP failure") 6293 else: 6294 time.sleep(0.05) 6295 dev[0].request("REMOVE_NETWORK all") 6296 dev[0].wait_disconnected() 6297 dev[0].dump_monitor() 6298 dev[1].dump_monitor() 6299 dev[2].dump_monitor() 6300 finally: 6301 stop_radius_server(srv) 6302 6303def NtPasswordHash(password): 6304 pw = password.encode('utf_16_le') 6305 return hashlib.new('md4', pw).digest() 6306 6307def HashNtPasswordHash(password_hash): 6308 return hashlib.new('md4', password_hash).digest() 6309 6310def ChallengeHash(peer_challenge, auth_challenge, username): 6311 data = peer_challenge + auth_challenge + username 6312 return hashlib.sha1(data).digest()[0:8] 6313 6314def GenerateAuthenticatorResponse(password, nt_response, peer_challenge, 6315 auth_challenge, username): 6316 magic1 = binascii.unhexlify("4D616769632073657276657220746F20636C69656E74207369676E696E6720636F6E7374616E74") 6317 magic2 = binascii.unhexlify("50616420746F206D616B6520697420646F206D6F7265207468616E206F6E6520697465726174696F6E") 6318 6319 password_hash = NtPasswordHash(password) 6320 password_hash_hash = HashNtPasswordHash(password_hash) 6321 data = password_hash_hash + nt_response + magic1 6322 digest = hashlib.sha1(data).digest() 6323 6324 challenge = ChallengeHash(peer_challenge, auth_challenge, username.encode()) 6325 6326 data = digest + challenge + magic2 6327 resp = hashlib.sha1(data).digest() 6328 return resp 6329 6330def test_eap_proto_ikev2_errors(dev, apdev): 6331 """EAP-IKEv2 local error cases""" 6332 check_eap_capa(dev[0], "IKEV2") 6333 params = hostapd.wpa2_eap_params(ssid="eap-test") 6334 hapd = hostapd.add_ap(apdev[0], params) 6335 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 6336 6337 for i in range(1, 5): 6338 with alloc_fail(dev[0], i, "eap_ikev2_init"): 6339 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 6340 eap="IKEV2", identity="ikev2 user", 6341 password="ike password", 6342 wait_connect=False) 6343 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"], 6344 timeout=15) 6345 if ev is None: 6346 raise Exception("Timeout on EAP start") 6347 dev[0].request("REMOVE_NETWORK all") 6348 dev[0].wait_disconnected() 6349 6350 tests = [(1, "ikev2_encr_encrypt"), 6351 (1, "ikev2_encr_decrypt"), 6352 (1, "ikev2_derive_auth_data"), 6353 (2, "ikev2_derive_auth_data"), 6354 (1, "=ikev2_decrypt_payload"), 6355 (1, "ikev2_encr_decrypt;ikev2_decrypt_payload"), 6356 (1, "ikev2_encr_encrypt;ikev2_build_encrypted"), 6357 (1, "ikev2_derive_sk_keys"), 6358 (2, "ikev2_derive_sk_keys"), 6359 (3, "ikev2_derive_sk_keys"), 6360 (4, "ikev2_derive_sk_keys"), 6361 (5, "ikev2_derive_sk_keys"), 6362 (6, "ikev2_derive_sk_keys"), 6363 (7, "ikev2_derive_sk_keys"), 6364 (8, "ikev2_derive_sk_keys"), 6365 (1, "eap_ikev2_derive_keymat;eap_ikev2_peer_keymat"), 6366 (1, "eap_msg_alloc;eap_ikev2_build_msg"), 6367 (1, "eap_ikev2_getKey"), 6368 (1, "eap_ikev2_get_emsk"), 6369 (1, "eap_ikev2_get_session_id"), 6370 (1, "=ikev2_derive_keys"), 6371 (2, "=ikev2_derive_keys"), 6372 (1, "wpabuf_alloc;ikev2_process_kei"), 6373 (1, "=ikev2_process_idi"), 6374 (1, "ikev2_derive_auth_data;ikev2_build_auth"), 6375 (1, "wpabuf_alloc;ikev2_build_sa_init"), 6376 (2, "wpabuf_alloc;ikev2_build_sa_init"), 6377 (3, "wpabuf_alloc;ikev2_build_sa_init"), 6378 (4, "wpabuf_alloc;ikev2_build_sa_init"), 6379 (5, "wpabuf_alloc;ikev2_build_sa_init"), 6380 (6, "wpabuf_alloc;ikev2_build_sa_init"), 6381 (1, "wpabuf_alloc;ikev2_build_sa_auth"), 6382 (2, "wpabuf_alloc;ikev2_build_sa_auth"), 6383 (1, "ikev2_build_auth;ikev2_build_sa_auth")] 6384 for count, func in tests: 6385 with alloc_fail(dev[0], count, func): 6386 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 6387 eap="IKEV2", identity="ikev2 user@domain", 6388 password="ike password", erp="1", wait_connect=False) 6389 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 6390 timeout=15) 6391 if ev is None: 6392 raise Exception("Timeout on EAP start") 6393 ok = False 6394 for j in range(10): 6395 state = dev[0].request('GET_ALLOC_FAIL') 6396 if state.startswith('0:'): 6397 ok = True 6398 break 6399 time.sleep(0.1) 6400 if not ok: 6401 raise Exception("No allocation failure seen for %d:%s" % (count, func)) 6402 dev[0].request("REMOVE_NETWORK all") 6403 dev[0].wait_disconnected() 6404 6405 tests = [(1, "wpabuf_alloc;ikev2_build_notify"), 6406 (2, "wpabuf_alloc;ikev2_build_notify"), 6407 (1, "ikev2_build_encrypted;ikev2_build_notify")] 6408 for count, func in tests: 6409 with alloc_fail(dev[0], count, func): 6410 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 6411 eap="IKEV2", identity="ikev2 user", 6412 password="wrong password", erp="1", 6413 wait_connect=False) 6414 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 6415 timeout=15) 6416 if ev is None: 6417 raise Exception("Timeout on EAP start") 6418 ok = False 6419 for j in range(10): 6420 state = dev[0].request('GET_ALLOC_FAIL') 6421 if state.startswith('0:'): 6422 ok = True 6423 break 6424 time.sleep(0.1) 6425 if not ok: 6426 raise Exception("No allocation failure seen for %d:%s" % (count, func)) 6427 dev[0].request("REMOVE_NETWORK all") 6428 dev[0].wait_disconnected() 6429 6430 tests = [(1, "ikev2_integ_hash"), 6431 (1, "ikev2_integ_hash;ikev2_decrypt_payload"), 6432 (1, "os_get_random;ikev2_build_encrypted"), 6433 (1, "ikev2_prf_plus;ikev2_derive_sk_keys"), 6434 (1, "eap_ikev2_derive_keymat;eap_ikev2_peer_keymat"), 6435 (1, "os_get_random;ikev2_build_sa_init"), 6436 (2, "os_get_random;ikev2_build_sa_init"), 6437 (1, "ikev2_integ_hash;eap_ikev2_validate_icv"), 6438 (1, "hmac_sha1_vector;?ikev2_prf_hash;ikev2_derive_keys"), 6439 (1, "hmac_sha1_vector;?ikev2_prf_hash;ikev2_derive_auth_data"), 6440 (2, "hmac_sha1_vector;?ikev2_prf_hash;ikev2_derive_auth_data"), 6441 (3, "hmac_sha1_vector;?ikev2_prf_hash;ikev2_derive_auth_data")] 6442 for count, func in tests: 6443 with fail_test(dev[0], count, func): 6444 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 6445 eap="IKEV2", identity="ikev2 user", 6446 password="ike password", wait_connect=False) 6447 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 6448 timeout=15) 6449 if ev is None: 6450 raise Exception("Timeout on EAP start") 6451 ok = False 6452 for j in range(10): 6453 state = dev[0].request('GET_FAIL') 6454 if state.startswith('0:'): 6455 ok = True 6456 break 6457 time.sleep(0.1) 6458 if not ok: 6459 raise Exception("No failure seen for %d:%s" % (count, func)) 6460 dev[0].request("REMOVE_NETWORK all") 6461 dev[0].wait_disconnected() 6462 6463 params = {"ssid": "eap-test2", "wpa": "2", "wpa_key_mgmt": "WPA-EAP", 6464 "rsn_pairwise": "CCMP", "ieee8021x": "1", 6465 "eap_server": "1", "eap_user_file": "auth_serv/eap_user.conf", 6466 "fragment_size": "50"} 6467 hapd2 = hostapd.add_ap(apdev[1], params) 6468 dev[0].scan_for_bss(hapd2.own_addr(), freq=2412) 6469 6470 tests = [(1, "eap_ikev2_build_frag_ack"), 6471 (1, "wpabuf_alloc;eap_ikev2_process_fragment")] 6472 for count, func in tests: 6473 with alloc_fail(dev[0], count, func): 6474 dev[0].connect("eap-test2", key_mgmt="WPA-EAP", scan_freq="2412", 6475 eap="IKEV2", identity="ikev2 user", 6476 password="ike password", erp="1", wait_connect=False) 6477 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 6478 timeout=15) 6479 if ev is None: 6480 raise Exception("Timeout on EAP start") 6481 ok = False 6482 for j in range(10): 6483 state = dev[0].request('GET_ALLOC_FAIL') 6484 if state.startswith('0:'): 6485 ok = True 6486 break 6487 time.sleep(0.1) 6488 if not ok: 6489 raise Exception("No allocation failure seen for %d:%s" % (count, func)) 6490 dev[0].request("REMOVE_NETWORK all") 6491 dev[0].wait_disconnected() 6492 6493def run_eap_ikev2_connect(dev): 6494 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412", 6495 eap="IKEV2", identity="ikev2 user", 6496 password="ike password", 6497 fragment_size="30", wait_connect=False) 6498 ev = dev.wait_event(["CTRL-EVENT-EAP-SUCCESS", "CTRL-EVENT-EAP-FAILURE", 6499 "CTRL-EVENT-DISCONNECTED"], 6500 timeout=1) 6501 dev.request("REMOVE_NETWORK all") 6502 if not ev or "CTRL-EVENT-DISCONNECTED" not in ev: 6503 dev.wait_disconnected() 6504 ev = dev.wait_event(["CTRL-EVENT-NETWORK-REMOVED"], timeout=1) 6505 if ev is None: 6506 raise Exception("Network removal not reported") 6507 time.sleep(0.01) 6508 dev.dump_monitor() 6509 6510def test_eap_proto_ikev2_errors_server(dev, apdev): 6511 """EAP-IKEV2 local error cases on server""" 6512 check_eap_capa(dev[0], "IKEV2") 6513 params = int_eap_server_params() 6514 params['erp_domain'] = 'example.com' 6515 params['eap_server_erp'] = '1' 6516 hapd = hostapd.add_ap(apdev[0], params) 6517 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 6518 6519 tests = [(1, "eap_ikev2_init"), 6520 (2, "=eap_ikev2_init"), 6521 (3, "=eap_ikev2_init"), 6522 (1, "eap_msg_alloc;eap_ikev2_build_msg"), 6523 (1, "ikev2_initiator_build;eap_ikev2_buildReq"), 6524 (1, "eap_ikev2_process_fragment"), 6525 (1, "wpabuf_alloc_copy;ikev2_process_ker"), 6526 (1, "ikev2_process_idr"), 6527 (1, "ikev2_derive_auth_data;ikev2_process_auth_secret"), 6528 (1, "ikev2_decrypt_payload;ikev2_process_sa_auth"), 6529 (1, "ikev2_process_sa_auth_decrypted;ikev2_process_sa_auth"), 6530 (1, "dh_init;ikev2_build_kei"), 6531 (1, "ikev2_build_auth"), 6532 (1, "wpabuf_alloc;ikev2_build_sa_init"), 6533 (1, "ikev2_build_sa_auth"), 6534 (1, "=ikev2_build_sa_auth"), 6535 (2, "=ikev2_derive_auth_data"), 6536 (1, "wpabuf_alloc;ikev2_build_sa_auth"), 6537 (2, "wpabuf_alloc;=ikev2_build_sa_auth"), 6538 (1, "ikev2_decrypt_payload;ikev2_process_sa_init_encr"), 6539 (1, "dh_derive_shared;ikev2_derive_keys"), 6540 (1, "=ikev2_derive_keys"), 6541 (2, "=ikev2_derive_keys"), 6542 (1, "eap_ikev2_getKey"), 6543 (1, "eap_ikev2_get_emsk"), 6544 (1, "eap_ikev2_get_session_id")] 6545 for count, func in tests: 6546 with alloc_fail(hapd, count, func): 6547 run_eap_ikev2_connect(dev[0]) 6548 6549 tests = [(1, "eap_ikev2_validate_icv;eap_ikev2_process_icv"), 6550 (1, "eap_ikev2_server_keymat"), 6551 (1, "ikev2_build_auth"), 6552 (1, "os_get_random;ikev2_build_sa_init"), 6553 (2, "os_get_random;ikev2_build_sa_init"), 6554 (1, "ikev2_derive_keys"), 6555 (2, "ikev2_derive_keys"), 6556 (3, "ikev2_derive_keys"), 6557 (4, "ikev2_derive_keys"), 6558 (5, "ikev2_derive_keys"), 6559 (6, "ikev2_derive_keys"), 6560 (7, "ikev2_derive_keys"), 6561 (8, "ikev2_derive_keys"), 6562 (1, "ikev2_decrypt_payload;ikev2_process_sa_auth"), 6563 (1, "eap_ikev2_process_icv;eap_ikev2_process")] 6564 for count, func in tests: 6565 with fail_test(hapd, count, func): 6566 run_eap_ikev2_connect(dev[0]) 6567 6568def start_ikev2_assoc(dev, hapd): 6569 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412", 6570 eap="IKEV2", identity="ikev2 user", 6571 password="ike password", wait_connect=False) 6572 proxy_msg(hapd, dev) # EAP-Identity/Request 6573 proxy_msg(dev, hapd) # EAP-Identity/Response 6574 proxy_msg(hapd, dev) # IKEV2 1 6575 6576def stop_ikev2_assoc(dev, hapd): 6577 dev.request("REMOVE_NETWORK all") 6578 dev.wait_disconnected() 6579 dev.dump_monitor() 6580 hapd.dump_monitor() 6581 6582def test_eap_proto_ikev2_server(dev, apdev): 6583 """EAP-IKEV2 protocol testing for the server""" 6584 check_eap_capa(dev[0], "IKEV2") 6585 params = int_eap_server_params() 6586 params['erp_domain'] = 'example.com' 6587 params['eap_server_erp'] = '1' 6588 hapd = hostapd.add_ap(apdev[0], params) 6589 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 6590 hapd.request("SET ext_eapol_frame_io 1") 6591 dev[0].request("SET ext_eapol_frame_io 1") 6592 6593 # Successful exchange to verify proxying mechanism 6594 start_ikev2_assoc(dev[0], hapd) 6595 proxy_msg(dev[0], hapd) # IKEV2 2 6596 proxy_msg(hapd, dev[0]) # IKEV2 3 6597 proxy_msg(dev[0], hapd) # IKEV2 4 6598 proxy_msg(hapd, dev[0]) # EAP-Success 6599 proxy_msg(hapd, dev[0]) # EAPOL-Key msg 1/4 6600 proxy_msg(dev[0], hapd) # EAPOL-Key msg 2/4 6601 proxy_msg(hapd, dev[0]) # EAPOL-Key msg 3/4 6602 proxy_msg(dev[0], hapd) # EAPOL-Key msg 4/4 6603 dev[0].wait_connected() 6604 stop_ikev2_assoc(dev[0], hapd) 6605 6606 start_ikev2_assoc(dev[0], hapd) 6607 resp = rx_msg(dev[0]) 6608 # Too short EAP-IKEV2 header 6609 hapd.note("IKEV2: Too short frame to include HDR") 6610 msg = resp[0:4] + "0005" + resp[8:12] + "0005" + "31" 6611 tx_msg(dev[0], hapd, msg) 6612 rx_msg(hapd) 6613 stop_ikev2_assoc(dev[0], hapd) 6614 6615 start_ikev2_assoc(dev[0], hapd) 6616 resp = rx_msg(dev[0]) 6617 # Too short EAP-IKEV2 header - missing Message Length field 6618 hapd.note("EAP-IKEV2: Message underflow") 6619 msg = resp[0:4] + "0006" + resp[8:12] + "0006" + "3180" 6620 tx_msg(dev[0], hapd, msg) 6621 rx_msg(hapd) 6622 stop_ikev2_assoc(dev[0], hapd) 6623 6624 start_ikev2_assoc(dev[0], hapd) 6625 resp = rx_msg(dev[0]) 6626 # Too short EAP-IKEV2 header - too small Message Length 6627 hapd.note("EAP-IKEV2: Invalid Message Length (0; 1 remaining in this msg)") 6628 msg = resp[0:4] + "000b" + resp[8:12] + "000b" + "318000000000ff" 6629 tx_msg(dev[0], hapd, msg) 6630 rx_msg(hapd) 6631 stop_ikev2_assoc(dev[0], hapd) 6632 6633 start_ikev2_assoc(dev[0], hapd) 6634 resp = rx_msg(dev[0]) 6635 # Too short EAP-IKEV2 header - too large Message Length 6636 hapd.note("EAP-IKEV2: Ignore too long message") 6637 msg = resp[0:4] + "000b" + resp[8:12] + "000b" + "31c0bbccddeeff" 6638 tx_msg(dev[0], hapd, msg) 6639 rx_msg(hapd) 6640 stop_ikev2_assoc(dev[0], hapd) 6641 6642 start_ikev2_assoc(dev[0], hapd) 6643 resp = rx_msg(dev[0]) 6644 # No Message Length in first fragment 6645 hapd.note("EAP-IKEV2: No Message Length field in a fragmented packet") 6646 msg = resp[0:4] + "0007" + resp[8:12] + "0007" + "3140ff" 6647 tx_msg(dev[0], hapd, msg) 6648 rx_msg(hapd) 6649 stop_ikev2_assoc(dev[0], hapd) 6650 6651 start_ikev2_assoc(dev[0], hapd) 6652 resp = rx_msg(dev[0]) 6653 # First fragment (valid) 6654 hapd.note("EAP-IKEV2: Received 1 bytes in first fragment, waiting for 255 bytes more") 6655 msg = resp[0:4] + "000b" + resp[8:12] + "000b" + "31c000000100ff" 6656 tx_msg(dev[0], hapd, msg) 6657 req = rx_msg(hapd) 6658 id, = struct.unpack('B', binascii.unhexlify(req)[5:6]) 6659 hapd.note("EAP-IKEV2: Received 1 bytes in first fragment, waiting for 254 bytes more") 6660 payload = struct.pack('BBB', 49, 0x40, 0) 6661 msg = struct.pack('>BBHBBH', 1, 0, 4 + len(payload), 2, id, 4 + len(payload)) + payload 6662 tx_msg(dev[0], hapd, binascii.hexlify(msg).decode()) 6663 req = rx_msg(hapd) 6664 id, = struct.unpack('B', binascii.unhexlify(req)[5:6]) 6665 hapd.note("EAP-IKEV2: Fragment overflow") 6666 payload = struct.pack('BB', 49, 0x40) + 255*b'\x00' 6667 msg = struct.pack('>BBHBBH', 1, 0, 4 + len(payload), 2, id, 4 + len(payload)) + payload 6668 tx_msg(dev[0], hapd, binascii.hexlify(msg).decode()) 6669 rx_msg(hapd) 6670 stop_ikev2_assoc(dev[0], hapd) 6671 6672 start_ikev2_assoc(dev[0], hapd) 6673 proxy_msg(dev[0], hapd) # IKEV2 2 6674 req = proxy_msg(hapd, dev[0]) # IKEV2 3 6675 id, = struct.unpack('B', binascii.unhexlify(req)[5:6]) 6676 # Missing ICV 6677 hapd.note("EAP-IKEV2: The message should have included integrity checksum") 6678 payload = struct.pack('BB', 49, 0) + b'\x00' 6679 msg = struct.pack('>BBHBBH', 1, 0, 4 + len(payload), 2, id, 4 + len(payload)) + payload 6680 tx_msg(dev[0], hapd, binascii.hexlify(msg).decode()) 6681 rx_msg(hapd) 6682 stop_ikev2_assoc(dev[0], hapd) 6683 6684 tests = [("Unsupported HDR version 0x0 (expected 0x20)", 6685 struct.pack('BB', 49, 0) + 16*b'\x00' + 6686 struct.pack('>BBBBLL', 0, 0, 0, 0, 0, 0)), 6687 ("IKEV2: Invalid length (HDR: 0 != RX: 28)", 6688 struct.pack('BB', 49, 0) + 16*b'\x00' + 6689 struct.pack('>BBBBLL', 0, 0x20, 0, 0, 0, 0)), 6690 ("IKEV2: Unexpected Exchange Type 0 in SA_INIT state", 6691 struct.pack('BB', 49, 0) + 16*b'\x00' + 6692 struct.pack('>BBBBLL', 0, 0x20, 0, 0, 0, 28)), 6693 ("IKEV2: Unexpected Flags value 0x0", 6694 struct.pack('BB', 49, 0) + 16*b'\x00' + 6695 struct.pack('>BBBBLL', 0, 0x20, 34, 0, 0, 28)), 6696 ("IKEV2: SAr1 not received", 6697 struct.pack('BB', 49, 0) + 16*b'\x00' + 6698 struct.pack('>BBBBLL', 0, 0x20, 34, 0x20, 0, 28))] 6699 for txt, payload in tests: 6700 start_ikev2_assoc(dev[0], hapd) 6701 resp = rx_msg(dev[0]) 6702 id, = struct.unpack('B', binascii.unhexlify(resp)[5:6]) 6703 hapd.note(txt) 6704 msg = struct.pack('>BBHBBH', 1, 0, 4 + len(payload), 2, id, 4 + len(payload)) + payload 6705 tx_msg(dev[0], hapd, binascii.hexlify(msg).decode()) 6706 rx_msg(hapd) 6707 stop_ikev2_assoc(dev[0], hapd) 6708 6709def test_eap_proto_mschapv2(dev, apdev): 6710 """EAP-MSCHAPv2 protocol tests""" 6711 check_eap_capa(dev[0], "MSCHAPV2") 6712 6713 def mschapv2_handler(ctx, req): 6714 logger.info("mschapv2_handler - RX " + binascii.hexlify(req).decode()) 6715 if 'num' not in ctx: 6716 ctx['num'] = 0 6717 ctx['num'] = ctx['num'] + 1 6718 if 'id' not in ctx: 6719 ctx['id'] = 1 6720 ctx['id'] = (ctx['id'] + 1) % 256 6721 idx = 0 6722 6723 idx += 1 6724 if ctx['num'] == idx: 6725 logger.info("Test: Missing payload") 6726 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 6727 4 + 1, 6728 EAP_TYPE_MSCHAPV2) 6729 6730 idx += 1 6731 if ctx['num'] == idx: 6732 logger.info("Test: Unknown MSCHAPv2 op_code") 6733 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'], 6734 4 + 1 + 4 + 1, 6735 EAP_TYPE_MSCHAPV2, 6736 0, 0, 5, 0) 6737 6738 idx += 1 6739 if ctx['num'] == idx: 6740 logger.info("Test: Invalid ms_len and unknown MSCHAPv2 op_code") 6741 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'], 6742 4 + 1 + 4 + 1, 6743 EAP_TYPE_MSCHAPV2, 6744 255, 0, 0, 0) 6745 6746 idx += 1 6747 if ctx['num'] == idx: 6748 logger.info("Test: Success before challenge") 6749 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'], 6750 4 + 1 + 4 + 1, 6751 EAP_TYPE_MSCHAPV2, 6752 3, 0, 5, 0) 6753 6754 idx += 1 6755 if ctx['num'] == idx: 6756 logger.info("Test: Failure before challenge - required challenge field not present") 6757 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'], 6758 4 + 1 + 4 + 1, 6759 EAP_TYPE_MSCHAPV2, 6760 4, 0, 5, 0) 6761 idx += 1 6762 if ctx['num'] == idx: 6763 logger.info("Test: Failure") 6764 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 6765 6766 idx += 1 6767 if ctx['num'] == idx: 6768 logger.info("Test: Failure before challenge - invalid failure challenge len") 6769 payload = b'C=12' 6770 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'], 6771 4 + 1 + 4 + len(payload), 6772 EAP_TYPE_MSCHAPV2, 6773 4, 0, 4 + len(payload)) + payload 6774 idx += 1 6775 if ctx['num'] == idx: 6776 logger.info("Test: Failure") 6777 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 6778 6779 idx += 1 6780 if ctx['num'] == idx: 6781 logger.info("Test: Failure before challenge - invalid failure challenge len") 6782 payload = b'C=12 V=3' 6783 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'], 6784 4 + 1 + 4 + len(payload), 6785 EAP_TYPE_MSCHAPV2, 6786 4, 0, 4 + len(payload)) + payload 6787 idx += 1 6788 if ctx['num'] == idx: 6789 logger.info("Test: Failure") 6790 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 6791 6792 idx += 1 6793 if ctx['num'] == idx: 6794 logger.info("Test: Failure before challenge - invalid failure challenge") 6795 payload = b'C=00112233445566778899aabbccddeefQ ' 6796 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'], 6797 4 + 1 + 4 + len(payload), 6798 EAP_TYPE_MSCHAPV2, 6799 4, 0, 4 + len(payload)) + payload 6800 idx += 1 6801 if ctx['num'] == idx: 6802 logger.info("Test: Failure") 6803 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 6804 6805 idx += 1 6806 if ctx['num'] == idx: 6807 logger.info("Test: Failure before challenge - password expired") 6808 payload = b'E=648 R=1 C=00112233445566778899aabbccddeeff V=3 M=Password expired' 6809 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'], 6810 4 + 1 + 4 + len(payload), 6811 EAP_TYPE_MSCHAPV2, 6812 4, 0, 4 + len(payload)) + payload 6813 idx += 1 6814 if ctx['num'] == idx: 6815 logger.info("Test: Success after password change") 6816 payload = b"S=1122334455667788990011223344556677889900" 6817 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'], 6818 4 + 1 + 4 + len(payload), 6819 EAP_TYPE_MSCHAPV2, 6820 3, 0, 4 + len(payload)) + payload 6821 6822 idx += 1 6823 if ctx['num'] == idx: 6824 logger.info("Test: Invalid challenge length") 6825 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'], 6826 4 + 1 + 4 + 1, 6827 EAP_TYPE_MSCHAPV2, 6828 1, 0, 4 + 1, 0) 6829 6830 idx += 1 6831 if ctx['num'] == idx: 6832 logger.info("Test: Too short challenge packet") 6833 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'], 6834 4 + 1 + 4 + 1, 6835 EAP_TYPE_MSCHAPV2, 6836 1, 0, 4 + 1, 16) 6837 6838 idx += 1 6839 if ctx['num'] == idx: 6840 logger.info("Test: Challenge") 6841 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'], 6842 4 + 1 + 4 + 1 + 16 + 6, 6843 EAP_TYPE_MSCHAPV2, 6844 1, 0, 4 + 1 + 16 + 6, 16) + 16*b'A' + b'foobar' 6845 idx += 1 6846 if ctx['num'] == idx: 6847 logger.info("Test: Failure - password expired") 6848 payload = b'E=648 R=1 C=00112233445566778899aabbccddeeff V=3 M=Password expired' 6849 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'], 6850 4 + 1 + 4 + len(payload), 6851 EAP_TYPE_MSCHAPV2, 6852 4, 0, 4 + len(payload)) + payload 6853 idx += 1 6854 if ctx['num'] == idx: 6855 logger.info("Test: Success after password change") 6856 if len(req) != 591: 6857 logger.info("Unexpected Change-Password packet length: %s" % len(req)) 6858 return None 6859 data = req[9:] 6860 enc_pw = data[0:516] 6861 data = data[516:] 6862 enc_hash = data[0:16] 6863 data = data[16:] 6864 peer_challenge = data[0:16] 6865 data = data[16:] 6866 # Reserved 6867 data = data[8:] 6868 nt_response = data[0:24] 6869 data = data[24:] 6870 flags = data 6871 logger.info("enc_hash: " + binascii.hexlify(enc_hash).decode()) 6872 logger.info("peer_challenge: " + binascii.hexlify(peer_challenge).decode()) 6873 logger.info("nt_response: " + binascii.hexlify(nt_response).decode()) 6874 logger.info("flags: " + binascii.hexlify(flags).decode()) 6875 6876 auth_challenge = binascii.unhexlify("00112233445566778899aabbccddeeff") 6877 logger.info("auth_challenge: " + binascii.hexlify(auth_challenge).decode()) 6878 6879 auth_resp = GenerateAuthenticatorResponse("new-pw", nt_response, 6880 peer_challenge, 6881 auth_challenge, "user") 6882 payload = b"S=" + binascii.hexlify(auth_resp).decode().upper().encode() 6883 logger.info("Success message payload: " + payload.decode()) 6884 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'], 6885 4 + 1 + 4 + len(payload), 6886 EAP_TYPE_MSCHAPV2, 6887 3, 0, 4 + len(payload)) + payload 6888 idx += 1 6889 if ctx['num'] == idx: 6890 logger.info("Test: EAP-Success") 6891 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4) 6892 6893 idx += 1 6894 if ctx['num'] == idx: 6895 logger.info("Test: Failure - password expired") 6896 payload = b'E=648 R=1 C=00112233445566778899aabbccddeeff V=3 M=Password expired' 6897 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'], 6898 4 + 1 + 4 + len(payload), 6899 EAP_TYPE_MSCHAPV2, 6900 4, 0, 4 + len(payload)) + payload 6901 idx += 1 6902 if ctx['num'] == idx: 6903 logger.info("Test: Success after password change") 6904 if len(req) != 591: 6905 logger.info("Unexpected Change-Password packet length: %s" % len(req)) 6906 return None 6907 data = req[9:] 6908 enc_pw = data[0:516] 6909 data = data[516:] 6910 enc_hash = data[0:16] 6911 data = data[16:] 6912 peer_challenge = data[0:16] 6913 data = data[16:] 6914 # Reserved 6915 data = data[8:] 6916 nt_response = data[0:24] 6917 data = data[24:] 6918 flags = data 6919 logger.info("enc_hash: " + binascii.hexlify(enc_hash).decode()) 6920 logger.info("peer_challenge: " + binascii.hexlify(peer_challenge).decode()) 6921 logger.info("nt_response: " + binascii.hexlify(nt_response).decode()) 6922 logger.info("flags: " + binascii.hexlify(flags).decode()) 6923 6924 auth_challenge = binascii.unhexlify("00112233445566778899aabbccddeeff") 6925 logger.info("auth_challenge: " + binascii.hexlify(auth_challenge).decode()) 6926 6927 auth_resp = GenerateAuthenticatorResponse("new-pw", nt_response, 6928 peer_challenge, 6929 auth_challenge, "user") 6930 payload = b"S=" + binascii.hexlify(auth_resp).decode().upper().encode() 6931 logger.info("Success message payload: " + payload.decode()) 6932 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'], 6933 4 + 1 + 4 + len(payload), 6934 EAP_TYPE_MSCHAPV2, 6935 3, 0, 4 + len(payload)) + payload 6936 idx += 1 6937 if ctx['num'] == idx: 6938 logger.info("Test: EAP-Success") 6939 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4) 6940 6941 idx += 1 6942 if ctx['num'] == idx: 6943 logger.info("Test: Challenge") 6944 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'], 6945 4 + 1 + 4 + 1 + 16 + 6, 6946 EAP_TYPE_MSCHAPV2, 6947 1, 0, 4 + 1 + 16 + 6, 16) + 16*b'A' + b'foobar' 6948 idx += 1 6949 if ctx['num'] == idx: 6950 logger.info("Test: Failure - authentication failure") 6951 payload = b'E=691 R=1 C=00112233445566778899aabbccddeeff V=3 M=Authentication failed' 6952 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'], 6953 4 + 1 + 4 + len(payload), 6954 EAP_TYPE_MSCHAPV2, 6955 4, 0, 4 + len(payload)) + payload 6956 6957 idx += 1 6958 if ctx['num'] == idx: 6959 logger.info("Test: Challenge") 6960 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'], 6961 4 + 1 + 4 + 1 + 16 + 6, 6962 EAP_TYPE_MSCHAPV2, 6963 1, 0, 4 + 1 + 16 + 6, 16) + 16*b'A' + b'foobar' 6964 idx += 1 6965 if ctx['num'] == idx: 6966 logger.info("Test: Failure - authentication failure") 6967 payload = b'E=691 R=1 C=00112233445566778899aabbccddeeff V=3 M=Authentication failed (2)' 6968 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'], 6969 4 + 1 + 4 + len(payload), 6970 EAP_TYPE_MSCHAPV2, 6971 4, 0, 4 + len(payload)) + payload 6972 idx += 1 6973 if ctx['num'] == idx: 6974 logger.info("Test: Failure") 6975 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 6976 6977 idx += 1 6978 if ctx['num'] == idx: 6979 logger.info("Test: Challenge - invalid ms_len and workaround disabled") 6980 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'], 6981 4 + 1 + 4 + 1 + 16 + 6, 6982 EAP_TYPE_MSCHAPV2, 6983 1, 0, 4 + 1 + 16 + 6 + 1, 16) + 16*b'A' + b'foobar' 6984 6985 return None 6986 6987 srv = start_radius_server(mschapv2_handler) 6988 6989 try: 6990 hapd = start_ap(apdev[0]) 6991 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 6992 6993 for i in range(0, 16): 6994 logger.info("RUN: %d" % i) 6995 if i == 12: 6996 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 6997 eap="MSCHAPV2", identity="user", 6998 password_hex="hash:8846f7eaee8fb117ad06bdd830b7586c", 6999 wait_connect=False) 7000 elif i == 14: 7001 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 7002 eap="MSCHAPV2", identity="user", 7003 phase2="mschapv2_retry=0", 7004 password="password", wait_connect=False) 7005 elif i == 15: 7006 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 7007 eap="MSCHAPV2", identity="user", 7008 eap_workaround="0", 7009 password="password", wait_connect=False) 7010 else: 7011 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 7012 eap="MSCHAPV2", identity="user", 7013 password="password", wait_connect=False) 7014 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15) 7015 if ev is None: 7016 raise Exception("Timeout on EAP start") 7017 7018 if i in [8, 11, 12]: 7019 ev = dev[0].wait_event(["CTRL-REQ-NEW_PASSWORD"], 7020 timeout=10) 7021 if ev is None: 7022 raise Exception("Timeout on new password request") 7023 id = ev.split(':')[0].split('-')[-1] 7024 dev[0].request("CTRL-RSP-NEW_PASSWORD-" + id + ":new-pw") 7025 if i in [11, 12]: 7026 ev = dev[0].wait_event(["CTRL-EVENT-PASSWORD-CHANGED"], 7027 timeout=10) 7028 if ev is None: 7029 raise Exception("Timeout on password change") 7030 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], 7031 timeout=10) 7032 if ev is None: 7033 raise Exception("Timeout on EAP success") 7034 else: 7035 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], 7036 timeout=10) 7037 if ev is None: 7038 raise Exception("Timeout on EAP failure") 7039 7040 if i in [13]: 7041 ev = dev[0].wait_event(["CTRL-REQ-IDENTITY"], 7042 timeout=10) 7043 if ev is None: 7044 raise Exception("Timeout on identity request") 7045 id = ev.split(':')[0].split('-')[-1] 7046 dev[0].request("CTRL-RSP-IDENTITY-" + id + ":user") 7047 7048 ev = dev[0].wait_event(["CTRL-REQ-PASSWORD"], 7049 timeout=10) 7050 if ev is None: 7051 raise Exception("Timeout on password request") 7052 id = ev.split(':')[0].split('-')[-1] 7053 dev[0].request("CTRL-RSP-PASSWORD-" + id + ":password") 7054 7055 # TODO: Does this work correctly? 7056 7057 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], 7058 timeout=10) 7059 if ev is None: 7060 raise Exception("Timeout on EAP failure") 7061 7062 if i in [4, 5, 6, 7, 14]: 7063 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], 7064 timeout=10) 7065 if ev is None: 7066 raise Exception("Timeout on EAP failure") 7067 else: 7068 time.sleep(0.05) 7069 dev[0].request("REMOVE_NETWORK all") 7070 dev[0].wait_disconnected(timeout=1) 7071 finally: 7072 stop_radius_server(srv) 7073 7074def test_eap_proto_mschapv2_errors(dev, apdev): 7075 """EAP-MSCHAPv2 protocol tests (error paths)""" 7076 check_eap_capa(dev[0], "MSCHAPV2") 7077 7078 def mschapv2_fail_password_expired(ctx): 7079 logger.info("Test: Failure before challenge - password expired") 7080 payload = b'E=648 R=1 C=00112233445566778899aabbccddeeff V=3 M=Password expired' 7081 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'], 7082 4 + 1 + 4 + len(payload), 7083 EAP_TYPE_MSCHAPV2, 7084 4, 0, 4 + len(payload)) + payload 7085 7086 def mschapv2_success_after_password_change(ctx, req=None): 7087 logger.info("Test: Success after password change") 7088 if req is None or len(req) != 591: 7089 payload = b"S=1122334455667788990011223344556677889900" 7090 else: 7091 data = req[9:] 7092 enc_pw = data[0:516] 7093 data = data[516:] 7094 enc_hash = data[0:16] 7095 data = data[16:] 7096 peer_challenge = data[0:16] 7097 data = data[16:] 7098 # Reserved 7099 data = data[8:] 7100 nt_response = data[0:24] 7101 data = data[24:] 7102 flags = data 7103 logger.info("enc_hash: " + binascii.hexlify(enc_hash).decode()) 7104 logger.info("peer_challenge: " + binascii.hexlify(peer_challenge).decode()) 7105 logger.info("nt_response: " + binascii.hexlify(nt_response).decode()) 7106 logger.info("flags: " + binascii.hexlify(flags).decode()) 7107 7108 auth_challenge = binascii.unhexlify("00112233445566778899aabbccddeeff") 7109 logger.info("auth_challenge: " + binascii.hexlify(auth_challenge).decode()) 7110 7111 auth_resp = GenerateAuthenticatorResponse("new-pw", nt_response, 7112 peer_challenge, 7113 auth_challenge, "user") 7114 payload = b"S=" + binascii.hexlify(auth_resp).decode().upper().encode() 7115 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'], 7116 4 + 1 + 4 + len(payload), 7117 EAP_TYPE_MSCHAPV2, 7118 3, 0, 4 + len(payload)) + payload 7119 7120 def mschapv2_handler(ctx, req): 7121 logger.info("mschapv2_handler - RX " + binascii.hexlify(req).decode()) 7122 if 'num' not in ctx: 7123 ctx['num'] = 0 7124 ctx['num'] = ctx['num'] + 1 7125 if 'id' not in ctx: 7126 ctx['id'] = 1 7127 ctx['id'] = (ctx['id'] + 1) % 256 7128 idx = 0 7129 7130 idx += 1 7131 if ctx['num'] == idx: 7132 return mschapv2_fail_password_expired(ctx) 7133 idx += 1 7134 if ctx['num'] == idx: 7135 return mschapv2_success_after_password_change(ctx, req) 7136 idx += 1 7137 if ctx['num'] == idx: 7138 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 7139 7140 idx += 1 7141 if ctx['num'] == idx: 7142 return mschapv2_fail_password_expired(ctx) 7143 idx += 1 7144 if ctx['num'] == idx: 7145 return mschapv2_success_after_password_change(ctx, req) 7146 idx += 1 7147 if ctx['num'] == idx: 7148 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 7149 7150 idx += 1 7151 if ctx['num'] == idx: 7152 return mschapv2_fail_password_expired(ctx) 7153 idx += 1 7154 if ctx['num'] == idx: 7155 return mschapv2_success_after_password_change(ctx, req) 7156 idx += 1 7157 if ctx['num'] == idx: 7158 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 7159 7160 idx += 1 7161 if ctx['num'] == idx: 7162 return mschapv2_fail_password_expired(ctx) 7163 idx += 1 7164 if ctx['num'] == idx: 7165 return mschapv2_success_after_password_change(ctx, req) 7166 idx += 1 7167 if ctx['num'] == idx: 7168 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 7169 7170 idx += 1 7171 if ctx['num'] == idx: 7172 return mschapv2_fail_password_expired(ctx) 7173 idx += 1 7174 if ctx['num'] == idx: 7175 return mschapv2_success_after_password_change(ctx, req) 7176 idx += 1 7177 if ctx['num'] == idx: 7178 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 7179 7180 idx += 1 7181 if ctx['num'] == idx: 7182 return mschapv2_fail_password_expired(ctx) 7183 idx += 1 7184 if ctx['num'] == idx: 7185 return mschapv2_success_after_password_change(ctx, req) 7186 idx += 1 7187 if ctx['num'] == idx: 7188 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 7189 7190 idx += 1 7191 if ctx['num'] == idx: 7192 return mschapv2_fail_password_expired(ctx) 7193 idx += 1 7194 if ctx['num'] == idx: 7195 return mschapv2_success_after_password_change(ctx, req) 7196 idx += 1 7197 if ctx['num'] == idx: 7198 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 7199 7200 idx += 1 7201 if ctx['num'] == idx: 7202 return mschapv2_fail_password_expired(ctx) 7203 idx += 1 7204 if ctx['num'] == idx: 7205 return mschapv2_success_after_password_change(ctx, req) 7206 idx += 1 7207 if ctx['num'] == idx: 7208 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 7209 7210 idx += 1 7211 if ctx['num'] == idx: 7212 return mschapv2_fail_password_expired(ctx) 7213 idx += 1 7214 if ctx['num'] == idx: 7215 return mschapv2_success_after_password_change(ctx, req) 7216 idx += 1 7217 if ctx['num'] == idx: 7218 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 7219 7220 return None 7221 7222 srv = start_radius_server(mschapv2_handler) 7223 7224 try: 7225 hapd = start_ap(apdev[0]) 7226 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 7227 7228 tests = ["os_get_random;eap_mschapv2_change_password", 7229 "generate_nt_response;eap_mschapv2_change_password", 7230 "get_master_key;eap_mschapv2_change_password", 7231 "nt_password_hash;eap_mschapv2_change_password", 7232 "old_nt_password_hash_encrypted_with_new_nt_password_hash"] 7233 for func in tests: 7234 with fail_test(dev[0], 1, func): 7235 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 7236 eap="MSCHAPV2", identity="user", 7237 password="password", wait_connect=False) 7238 ev = dev[0].wait_event(["CTRL-REQ-NEW_PASSWORD"], timeout=10) 7239 if ev is None: 7240 raise Exception("Timeout on new password request") 7241 id = ev.split(':')[0].split('-')[-1] 7242 dev[0].request("CTRL-RSP-NEW_PASSWORD-" + id + ":new-pw") 7243 time.sleep(0.1) 7244 wait_fail_trigger(dev[0], "GET_FAIL") 7245 dev[0].request("REMOVE_NETWORK all") 7246 dev[0].wait_disconnected(timeout=1) 7247 7248 tests = ["encrypt_pw_block_with_password_hash;eap_mschapv2_change_password", 7249 "nt_password_hash;eap_mschapv2_change_password", 7250 "nt_password_hash;eap_mschapv2_success"] 7251 for func in tests: 7252 with fail_test(dev[0], 1, func): 7253 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 7254 eap="MSCHAPV2", identity="user", 7255 password_hex="hash:8846f7eaee8fb117ad06bdd830b7586c", 7256 wait_connect=False) 7257 ev = dev[0].wait_event(["CTRL-REQ-NEW_PASSWORD"], timeout=10) 7258 if ev is None: 7259 raise Exception("Timeout on new password request") 7260 id = ev.split(':')[0].split('-')[-1] 7261 dev[0].request("CTRL-RSP-NEW_PASSWORD-" + id + ":new-pw") 7262 time.sleep(0.1) 7263 wait_fail_trigger(dev[0], "GET_FAIL") 7264 dev[0].request("REMOVE_NETWORK all") 7265 dev[0].wait_disconnected(timeout=1) 7266 7267 tests = ["eap_msg_alloc;eap_mschapv2_change_password"] 7268 for func in tests: 7269 with alloc_fail(dev[0], 1, func): 7270 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 7271 eap="MSCHAPV2", identity="user", 7272 password="password", wait_connect=False) 7273 ev = dev[0].wait_event(["CTRL-REQ-NEW_PASSWORD"], timeout=10) 7274 if ev is None: 7275 raise Exception("Timeout on new password request") 7276 id = ev.split(':')[0].split('-')[-1] 7277 dev[0].request("CTRL-RSP-NEW_PASSWORD-" + id + ":new-pw") 7278 time.sleep(0.1) 7279 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 7280 dev[0].request("REMOVE_NETWORK all") 7281 dev[0].wait_disconnected(timeout=1) 7282 finally: 7283 stop_radius_server(srv) 7284 7285def test_eap_proto_pwd(dev, apdev): 7286 """EAP-pwd protocol tests""" 7287 check_eap_capa(dev[0], "PWD") 7288 7289 global eap_proto_pwd_test_done, eap_proto_pwd_test_wait 7290 eap_proto_pwd_test_done = False 7291 eap_proto_pwd_test_wait = False 7292 7293 def pwd_handler(ctx, req): 7294 logger.info("pwd_handler - RX " + binascii.hexlify(req).decode()) 7295 if 'num' not in ctx: 7296 ctx['num'] = 0 7297 ctx['num'] = ctx['num'] + 1 7298 if 'id' not in ctx: 7299 ctx['id'] = 1 7300 ctx['id'] = (ctx['id'] + 1) % 256 7301 idx = 0 7302 7303 global eap_proto_pwd_test_wait 7304 eap_proto_pwd_test_wait = False 7305 7306 idx += 1 7307 if ctx['num'] == idx: 7308 logger.info("Test: Missing payload") 7309 # EAP-pwd: Got a frame but pos is not NULL and len is 0 7310 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 4 + 1, 7311 EAP_TYPE_PWD) 7312 7313 idx += 1 7314 if ctx['num'] == idx: 7315 logger.info("Test: Missing Total-Length field") 7316 # EAP-pwd: Frame too short to contain Total-Length field 7317 payload = struct.pack("B", 0x80) 7318 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7319 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7320 7321 idx += 1 7322 if ctx['num'] == idx: 7323 logger.info("Test: Too large Total-Length") 7324 # EAP-pwd: Incoming fragments whose total length = 65535 7325 payload = struct.pack(">BH", 0x80, 65535) 7326 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7327 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7328 7329 idx += 1 7330 if ctx['num'] == idx: 7331 eap_proto_pwd_test_wait = True 7332 logger.info("Test: First fragment") 7333 # EAP-pwd: Incoming fragments whose total length = 10 7334 # EAP-pwd: ACKing a 0 byte fragment 7335 payload = struct.pack(">BH", 0xc0, 10) 7336 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7337 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7338 idx += 1 7339 if ctx['num'] == idx: 7340 logger.info("Test: Unexpected Total-Length value in the second fragment") 7341 # EAP-pwd: Incoming fragments whose total length = 0 7342 # EAP-pwd: Unexpected new fragment start when previous fragment is still in use 7343 payload = struct.pack(">BH", 0x80, 0) 7344 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7345 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7346 7347 idx += 1 7348 if ctx['num'] == idx: 7349 logger.info("Test: First and only fragment") 7350 # EAP-pwd: Incoming fragments whose total length = 0 7351 # EAP-pwd: processing frame: exch 0, len 0 7352 # EAP-pwd: Ignoring message with unknown opcode 128 7353 payload = struct.pack(">BH", 0x80, 0) 7354 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7355 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7356 7357 idx += 1 7358 if ctx['num'] == idx: 7359 logger.info("Test: First and only fragment with extra data") 7360 # EAP-pwd: Incoming fragments whose total length = 0 7361 # EAP-pwd: processing frame: exch 0, len 1 7362 # EAP-pwd: Ignoring message with unknown opcode 128 7363 payload = struct.pack(">BHB", 0x80, 0, 0) 7364 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7365 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7366 7367 idx += 1 7368 if ctx['num'] == idx: 7369 eap_proto_pwd_test_wait = True 7370 logger.info("Test: First fragment") 7371 # EAP-pwd: Incoming fragments whose total length = 2 7372 # EAP-pwd: ACKing a 1 byte fragment 7373 payload = struct.pack(">BHB", 0xc0, 2, 1) 7374 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7375 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7376 idx += 1 7377 if ctx['num'] == idx: 7378 logger.info("Test: Extra data in the second fragment") 7379 # EAP-pwd: Buffer overflow attack detected (3 vs. 1)! 7380 payload = struct.pack(">BBB", 0x0, 2, 3) 7381 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7382 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7383 7384 idx += 1 7385 if ctx['num'] == idx: 7386 logger.info("Test: Too short id exchange") 7387 # EAP-pwd: processing frame: exch 1, len 0 7388 # EAP-PWD: PWD-ID-Req -> FAILURE 7389 payload = struct.pack(">B", 0x01) 7390 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7391 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7392 7393 idx += 1 7394 if ctx['num'] == idx: 7395 logger.info("Test: Unsupported rand func in id exchange") 7396 # EAP-PWD: Server EAP-pwd-ID proposal: group=0 random=0 prf=0 prep=0 7397 # EAP-PWD: PWD-ID-Req -> FAILURE 7398 payload = struct.pack(">BHBBLB", 0x01, 0, 0, 0, 0, 0) 7399 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7400 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7401 7402 idx += 1 7403 if ctx['num'] == idx: 7404 logger.info("Test: Unsupported prf in id exchange") 7405 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=0 prep=0 7406 # EAP-PWD: PWD-ID-Req -> FAILURE 7407 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 0, 0, 0) 7408 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7409 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7410 7411 idx += 1 7412 if ctx['num'] == idx: 7413 logger.info("Test: Unsupported password pre-processing technique in id exchange") 7414 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=255 7415 # EAP-PWD: Unsupported password pre-processing technique (Prep=255) 7416 # EAP-PWD: PWD-ID-Req -> FAILURE 7417 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 255) 7418 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7419 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7420 7421 idx += 1 7422 if ctx['num'] == idx: 7423 eap_proto_pwd_test_wait = True 7424 logger.info("Test: Valid id exchange") 7425 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=0 7426 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0) 7427 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7428 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7429 idx += 1 7430 if ctx['num'] == idx: 7431 logger.info("Test: Unexpected id exchange") 7432 # EAP-pwd: processing frame: exch 1, len 9 7433 # EAP-PWD: PWD-Commit-Req -> FAILURE 7434 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0) 7435 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7436 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7437 7438 idx += 1 7439 if ctx['num'] == idx: 7440 logger.info("Test: Unexpected commit exchange") 7441 # EAP-pwd: processing frame: exch 2, len 0 7442 # EAP-PWD: PWD-ID-Req -> FAILURE 7443 payload = struct.pack(">B", 0x02) 7444 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7445 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7446 7447 idx += 1 7448 if ctx['num'] == idx: 7449 eap_proto_pwd_test_wait = True 7450 logger.info("Test: Valid id exchange") 7451 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=0 7452 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0) 7453 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7454 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7455 idx += 1 7456 if ctx['num'] == idx: 7457 logger.info("Test: Unexpected Commit payload length (prep=None)") 7458 # EAP-pwd commit request, password prep is NONE 7459 # EAP-pwd: Unexpected Commit payload length 0 (expected 96) 7460 payload = struct.pack(">B", 0x02) 7461 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7462 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7463 7464 idx += 1 7465 if ctx['num'] == idx: 7466 eap_proto_pwd_test_wait = True 7467 logger.info("Test: Valid id exchange") 7468 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=0 7469 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0) 7470 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7471 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7472 idx += 1 7473 if ctx['num'] == idx: 7474 logger.info("Test: Commit payload with all zeros values --> Shared key at infinity") 7475 # EAP-pwd: Invalid coordinate in element 7476 payload = struct.pack(">B", 0x02) + 96*b'\0' 7477 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7478 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7479 7480 idx += 1 7481 if ctx['num'] == idx: 7482 eap_proto_pwd_test_wait = True 7483 logger.info("Test: Valid id exchange") 7484 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=0 7485 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0) 7486 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7487 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7488 idx += 1 7489 if ctx['num'] == idx: 7490 eap_proto_pwd_test_wait = True 7491 logger.info("Test: Commit payload with valid values") 7492 # EAP-pwd commit request, password prep is NONE 7493 element = binascii.unhexlify("8dcab2862c5396839a6bac0c689ff03d962863108e7c275bbf1d6eedf634ee832a214db99f0d0a1a6317733eecdd97f0fc4cda19f57e1bb9bb9c8dcf8c60ba6f") 7494 scalar = binascii.unhexlify("450f31e058cf2ac2636a5d6e2b3c70b1fcc301957f0716e77f13aa69f9a2e5bd") 7495 payload = struct.pack(">B", 0x02) + element + scalar 7496 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7497 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7498 idx += 1 7499 if ctx['num'] == idx: 7500 logger.info("Test: Unexpected Confirm payload length 0") 7501 # EAP-pwd: Unexpected Confirm payload length 0 (expected 32) 7502 payload = struct.pack(">B", 0x03) 7503 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7504 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7505 7506 idx += 1 7507 if ctx['num'] == idx: 7508 eap_proto_pwd_test_wait = True 7509 logger.info("Test: Valid id exchange") 7510 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=0 7511 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0) 7512 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7513 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7514 idx += 1 7515 if ctx['num'] == idx: 7516 eap_proto_pwd_test_wait = True 7517 logger.info("Test: Commit payload with valid values") 7518 # EAP-pwd commit request, password prep is NONE 7519 element = binascii.unhexlify("8dcab2862c5396839a6bac0c689ff03d962863108e7c275bbf1d6eedf634ee832a214db99f0d0a1a6317733eecdd97f0fc4cda19f57e1bb9bb9c8dcf8c60ba6f") 7520 scalar = binascii.unhexlify("450f31e058cf2ac2636a5d6e2b3c70b1fcc301957f0716e77f13aa69f9a2e5bd") 7521 payload = struct.pack(">B", 0x02) + element + scalar 7522 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7523 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7524 idx += 1 7525 if ctx['num'] == idx: 7526 logger.info("Test: Confirm payload with incorrect value") 7527 # EAP-PWD (peer): confirm did not verify 7528 payload = struct.pack(">B", 0x03) + 32*b'\0' 7529 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7530 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7531 7532 idx += 1 7533 if ctx['num'] == idx: 7534 logger.info("Test: Unexpected confirm exchange") 7535 # EAP-pwd: processing frame: exch 3, len 0 7536 # EAP-PWD: PWD-ID-Req -> FAILURE 7537 payload = struct.pack(">B", 0x03) 7538 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7539 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7540 7541 idx += 1 7542 if ctx['num'] == idx: 7543 logger.info("Test: Unsupported password pre-processing technique SASLprep in id exchange") 7544 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=2 7545 # EAP-PWD: Unsupported password pre-processing technique (Prep=2) 7546 # EAP-PWD: PWD-ID-Req -> FAILURE 7547 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 2) 7548 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7549 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7550 7551 idx += 1 7552 if ctx['num'] == idx: 7553 eap_proto_pwd_test_wait = True 7554 logger.info("Test: Valid id exchange") 7555 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=1 7556 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 1) 7557 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7558 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7559 idx += 1 7560 if ctx['num'] == idx: 7561 logger.info("Test: Unexpected Commit payload length (prep=MS)") 7562 # EAP-pwd commit request, password prep is MS 7563 # EAP-pwd: Unexpected Commit payload length 0 (expected 96) 7564 payload = struct.pack(">B", 0x02) 7565 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7566 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7567 7568 idx += 1 7569 if ctx['num'] == idx: 7570 eap_proto_pwd_test_wait = True 7571 logger.info("Test: Valid id exchange") 7572 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=3 7573 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 3) 7574 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7575 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7576 idx += 1 7577 if ctx['num'] == idx: 7578 logger.info("Test: Unexpected Commit payload length (prep=ssha1)") 7579 # EAP-pwd commit request, password prep is salted sha1 7580 # EAP-pwd: Invalid Salt-len 7581 payload = struct.pack(">B", 0x02) 7582 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7583 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7584 7585 idx += 1 7586 if ctx['num'] == idx: 7587 eap_proto_pwd_test_wait = True 7588 logger.info("Test: Valid id exchange") 7589 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=3 7590 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 3) 7591 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7592 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7593 idx += 1 7594 if ctx['num'] == idx: 7595 logger.info("Test: Unexpected Commit payload length (prep=ssha1)") 7596 # EAP-pwd commit request, password prep is salted sha1 7597 # EAP-pwd: Invalid Salt-len 7598 payload = struct.pack(">BB", 0x02, 0) 7599 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7600 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7601 7602 idx += 1 7603 if ctx['num'] == idx: 7604 eap_proto_pwd_test_wait = True 7605 logger.info("Test: Valid id exchange") 7606 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=3 7607 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 3) 7608 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7609 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7610 idx += 1 7611 if ctx['num'] == idx: 7612 logger.info("Test: Unexpected Commit payload length (prep=ssha1)") 7613 # EAP-pwd commit request, password prep is salted sha1 7614 # EAP-pwd: Unexpected Commit payload length 1 (expected 98) 7615 payload = struct.pack(">BB", 0x02, 1) 7616 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7617 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7618 7619 idx += 1 7620 if ctx['num'] == idx: 7621 eap_proto_pwd_test_wait = True 7622 logger.info("Test: Valid id exchange") 7623 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=4 7624 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 4) 7625 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7626 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7627 idx += 1 7628 if ctx['num'] == idx: 7629 logger.info("Test: Unexpected Commit payload length (prep=ssha256)") 7630 # EAP-pwd commit request, password prep is salted sha256 7631 # EAP-pwd: Invalid Salt-len 7632 payload = struct.pack(">B", 0x02) 7633 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7634 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7635 7636 idx += 1 7637 if ctx['num'] == idx: 7638 eap_proto_pwd_test_wait = True 7639 logger.info("Test: Valid id exchange") 7640 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=4 7641 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 4) 7642 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7643 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7644 idx += 1 7645 if ctx['num'] == idx: 7646 logger.info("Test: Unexpected Commit payload length (prep=ssha256)") 7647 # EAP-pwd commit request, password prep is salted sha256 7648 # EAP-pwd: Invalid Salt-len 7649 payload = struct.pack(">BB", 0x02, 0) 7650 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7651 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7652 7653 idx += 1 7654 if ctx['num'] == idx: 7655 eap_proto_pwd_test_wait = True 7656 logger.info("Test: Valid id exchange") 7657 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=4 7658 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 4) 7659 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7660 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7661 idx += 1 7662 if ctx['num'] == idx: 7663 logger.info("Test: Unexpected Commit payload length (prep=ssha256)") 7664 # EAP-pwd commit request, password prep is salted sha256 7665 # EAP-pwd: Unexpected Commit payload length 1 (expected 98) 7666 payload = struct.pack(">BB", 0x02, 1) 7667 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7668 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7669 7670 idx += 1 7671 if ctx['num'] == idx: 7672 eap_proto_pwd_test_wait = True 7673 logger.info("Test: Valid id exchange") 7674 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=5 7675 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 5) 7676 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7677 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7678 idx += 1 7679 if ctx['num'] == idx: 7680 logger.info("Test: Unexpected Commit payload length (prep=ssha512)") 7681 # EAP-pwd commit request, password prep is salted sha512 7682 # EAP-pwd: Invalid Salt-len 7683 payload = struct.pack(">B", 0x02) 7684 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7685 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7686 7687 idx += 1 7688 if ctx['num'] == idx: 7689 eap_proto_pwd_test_wait = True 7690 logger.info("Test: Valid id exchange") 7691 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=5 7692 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 5) 7693 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7694 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7695 idx += 1 7696 if ctx['num'] == idx: 7697 logger.info("Test: Unexpected Commit payload length (prep=ssha512)") 7698 # EAP-pwd commit request, password prep is salted sha512 7699 # EAP-pwd: Invalid Salt-len 7700 payload = struct.pack(">BB", 0x02, 0) 7701 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7702 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7703 7704 idx += 1 7705 if ctx['num'] == idx: 7706 eap_proto_pwd_test_wait = True 7707 logger.info("Test: Valid id exchange") 7708 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=5 7709 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 5) 7710 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7711 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7712 idx += 1 7713 if ctx['num'] == idx: 7714 logger.info("Test: Unexpected Commit payload length (prep=ssha512)") 7715 # EAP-pwd commit request, password prep is salted sha512 7716 # EAP-pwd: Unexpected Commit payload length 1 (expected 98) 7717 payload = struct.pack(">BB", 0x02, 1) 7718 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7719 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7720 7721 logger.info("No more test responses available - test case completed") 7722 global eap_proto_pwd_test_done 7723 eap_proto_pwd_test_done = True 7724 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 7725 7726 srv = start_radius_server(pwd_handler) 7727 7728 try: 7729 hapd = start_ap(apdev[0]) 7730 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 7731 7732 i = 0 7733 while not eap_proto_pwd_test_done: 7734 i += 1 7735 logger.info("Running connection iteration %d" % i) 7736 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 7737 eap="PWD", identity="pwd user", 7738 password="secret password", 7739 wait_connect=False) 7740 ok = False 7741 for j in range(5): 7742 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STATUS", 7743 "CTRL-EVENT-EAP-PROPOSED-METHOD"], 7744 timeout=5) 7745 if ev is None: 7746 raise Exception("Timeout on EAP start") 7747 if "CTRL-EVENT-EAP-PROPOSED-METHOD" in ev: 7748 ok = True 7749 break 7750 if "CTRL-EVENT-EAP-STATUS" in ev and "status='completion' parameter='failure'" in ev: 7751 ok = True 7752 break 7753 if not ok: 7754 raise Exception("Expected EAP event not seen") 7755 if eap_proto_pwd_test_wait: 7756 for k in range(20): 7757 time.sleep(0.1) 7758 if not eap_proto_pwd_test_wait: 7759 break 7760 if eap_proto_pwd_test_wait: 7761 raise Exception("eap_proto_pwd_test_wait not cleared") 7762 dev[0].request("REMOVE_NETWORK all") 7763 dev[0].wait_disconnected(timeout=1) 7764 dev[0].dump_monitor() 7765 finally: 7766 stop_radius_server(srv) 7767 7768def test_eap_proto_pwd_invalid_scalar(dev, apdev): 7769 """EAP-pwd protocol tests - invalid server scalar""" 7770 check_eap_capa(dev[0], "PWD") 7771 run_eap_proto_pwd_invalid_scalar(dev, apdev, 32*b'\0') 7772 run_eap_proto_pwd_invalid_scalar(dev, apdev, 31*b'\0' + b'\x01') 7773 # Group Order 7774 val = binascii.unhexlify("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551") 7775 run_eap_proto_pwd_invalid_scalar(dev, apdev, val) 7776 # Group Order - 1 7777 val = binascii.unhexlify("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632550") 7778 run_eap_proto_pwd_invalid_scalar(dev, apdev, val, valid_scalar=True) 7779 7780def run_eap_proto_pwd_invalid_scalar(dev, apdev, scalar, valid_scalar=False): 7781 global eap_proto_pwd_invalid_scalar_fail 7782 eap_proto_pwd_invalid_scalar_fail = False 7783 7784 def pwd_handler(ctx, req): 7785 logger.info("pwd_handler - RX " + binascii.hexlify(req).decode()) 7786 if 'num' not in ctx: 7787 ctx['num'] = 0 7788 ctx['num'] = ctx['num'] + 1 7789 if 'id' not in ctx: 7790 ctx['id'] = 1 7791 ctx['id'] = (ctx['id'] + 1) % 256 7792 idx = 0 7793 7794 idx += 1 7795 if ctx['num'] == idx: 7796 logger.info("Test: Valid id exchange") 7797 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0) 7798 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7799 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7800 idx += 1 7801 if ctx['num'] == idx: 7802 logger.info("Test: Commit payload with invalid scalar") 7803 payload = struct.pack(">B", 0x02) + binascii.unhexlify("67feb2b46d59e6dd3af3a429ec9c04a949337564615d3a2c19bdf6826eb6f5efa303aed86af3a072ed819d518d620adb2659f0e84c4f8b739629db8c93088cfc") + scalar 7804 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7805 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7806 idx += 1 7807 if ctx['num'] == idx: 7808 logger.info("Confirm message next - should not get here") 7809 global eap_proto_pwd_invalid_scalar_fail 7810 eap_proto_pwd_invalid_scalar_fail = True 7811 payload = struct.pack(">B", 0x03) + 32*b'\0' 7812 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7813 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7814 7815 logger.info("No more test responses available - test case completed") 7816 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 7817 7818 srv = start_radius_server(pwd_handler) 7819 7820 try: 7821 hapd = start_ap(apdev[0]) 7822 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 7823 7824 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 7825 eap="PWD", identity="pwd user", 7826 password="secret password", 7827 wait_connect=False) 7828 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5) 7829 if ev is None: 7830 raise Exception("EAP failure not reported") 7831 dev[0].request("REMOVE_NETWORK all") 7832 dev[0].wait_disconnected(timeout=1) 7833 dev[0].dump_monitor() 7834 finally: 7835 stop_radius_server(srv) 7836 7837 if valid_scalar and not eap_proto_pwd_invalid_scalar_fail: 7838 raise Exception("Peer did not accept valid EAP-pwd-Commit scalar") 7839 if not valid_scalar and eap_proto_pwd_invalid_scalar_fail: 7840 raise Exception("Peer did not stop after invalid EAP-pwd-Commit scalar") 7841 7842def test_eap_proto_pwd_invalid_element(dev, apdev): 7843 """EAP-pwd protocol tests - invalid server element""" 7844 check_eap_capa(dev[0], "PWD") 7845 # Invalid x,y coordinates 7846 run_eap_proto_pwd_invalid_element(dev, apdev, 64*b'\x00') 7847 run_eap_proto_pwd_invalid_element(dev, apdev, 32*b'\x00' + 32*b'\x01') 7848 run_eap_proto_pwd_invalid_element(dev, apdev, 32*b'\x01' + 32*b'\x00') 7849 run_eap_proto_pwd_invalid_element(dev, apdev, 32*b'\xff' + 32*b'\x01') 7850 run_eap_proto_pwd_invalid_element(dev, apdev, 32*b'\x01' + 32*b'\xff') 7851 run_eap_proto_pwd_invalid_element(dev, apdev, 64*b'\xff') 7852 # Not on curve 7853 run_eap_proto_pwd_invalid_element(dev, apdev, 64*b'\x01') 7854 7855def run_eap_proto_pwd_invalid_element(dev, apdev, element): 7856 global eap_proto_pwd_invalid_element_fail 7857 eap_proto_pwd_invalid_element_fail = False 7858 7859 def pwd_handler(ctx, req): 7860 logger.info("pwd_handler - RX " + binascii.hexlify(req).decode()) 7861 if 'num' not in ctx: 7862 ctx['num'] = 0 7863 ctx['num'] = ctx['num'] + 1 7864 if 'id' not in ctx: 7865 ctx['id'] = 1 7866 ctx['id'] = (ctx['id'] + 1) % 256 7867 idx = 0 7868 7869 idx += 1 7870 if ctx['num'] == idx: 7871 logger.info("Test: Valid id exchange") 7872 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0) 7873 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7874 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7875 idx += 1 7876 if ctx['num'] == idx: 7877 logger.info("Test: Commit payload with invalid element") 7878 payload = struct.pack(">B", 0x02) + element + 31*b'\0' + b'\x02' 7879 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7880 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7881 idx += 1 7882 if ctx['num'] == idx: 7883 logger.info("Confirm message next - should not get here") 7884 global eap_proto_pwd_invalid_element_fail 7885 eap_proto_pwd_invalid_element_fail = True 7886 payload = struct.pack(">B", 0x03) + 32*b'\0' 7887 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 7888 4 + 1 + len(payload), EAP_TYPE_PWD) + payload 7889 7890 logger.info("No more test responses available - test case completed") 7891 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 7892 7893 srv = start_radius_server(pwd_handler) 7894 7895 try: 7896 hapd = start_ap(apdev[0]) 7897 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 7898 7899 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 7900 eap="PWD", identity="pwd user", 7901 password="secret password", 7902 wait_connect=False) 7903 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5) 7904 if ev is None: 7905 raise Exception("EAP failure not reported") 7906 dev[0].request("REMOVE_NETWORK all") 7907 dev[0].wait_disconnected(timeout=1) 7908 dev[0].dump_monitor() 7909 finally: 7910 stop_radius_server(srv) 7911 7912 if eap_proto_pwd_invalid_element_fail: 7913 raise Exception("Peer did not stop after invalid EAP-pwd-Commit element") 7914 7915def rx_msg(src): 7916 ev = src.wait_event(["EAPOL-TX"], timeout=5) 7917 if ev is None: 7918 raise Exception("No EAPOL-TX") 7919 return ev.split(' ')[2] 7920 7921def tx_msg(src, dst, msg): 7922 dst.request("EAPOL_RX " + src.own_addr() + " " + msg) 7923 7924def proxy_msg(src, dst): 7925 msg = rx_msg(src) 7926 tx_msg(src, dst, msg) 7927 return msg 7928 7929def start_pwd_exchange(dev, ap): 7930 check_eap_capa(dev, "PWD") 7931 params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap") 7932 hapd = hostapd.add_ap(ap, params) 7933 hapd.request("SET ext_eapol_frame_io 1") 7934 dev.request("SET ext_eapol_frame_io 1") 7935 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", 7936 eap="PWD", identity="pwd user", password="secret password", 7937 wait_connect=False, scan_freq="2412") 7938 proxy_msg(hapd, dev) # EAP-Identity/Request 7939 proxy_msg(dev, hapd) # EAP-Identity/Response 7940 proxy_msg(hapd, dev) # EAP-pwd-ID/Request 7941 proxy_msg(dev, hapd) # EAP-pwd-ID/Response 7942 return hapd 7943 7944def test_eap_proto_pwd_unexpected_fragment(dev, apdev): 7945 """EAP-pwd protocol tests - unexpected more-fragment frame""" 7946 hapd = start_pwd_exchange(dev[0], apdev[0]) 7947 7948 # EAP-pwd-Commit/Request 7949 req = rx_msg(hapd) 7950 if req[18:20] != "02": 7951 raise Exception("Unexpected EAP-pwd-Commit/Request flag") 7952 msg = req[0:18] + "42" + req[20:] 7953 tx_msg(hapd, dev[0], msg) 7954 7955def test_eap_proto_pwd_reflection_attack(dev, apdev): 7956 """EAP-pwd protocol tests - reflection attack on the server""" 7957 hapd = start_pwd_exchange(dev[0], apdev[0]) 7958 7959 # EAP-pwd-Commit/Request 7960 req = proxy_msg(hapd, dev[0]) 7961 if len(req) != 212: 7962 raise Exception("Unexpected EAP-pwd-Commit/Response length") 7963 7964 # EAP-pwd-Commit/Response 7965 resp = rx_msg(dev[0]) 7966 # Reflect same Element/Scalar back to the server 7967 msg = resp[0:20] + req[20:] 7968 tx_msg(dev[0], hapd, msg) 7969 7970 # EAP-pwd-Commit/Response or EAP-Failure 7971 req = rx_msg(hapd) 7972 if req[8:10] != "04": 7973 # reflect EAP-pwd-Confirm/Request 7974 msg = req[0:8] + "02" + req[10:] 7975 tx_msg(dev[0], hapd, msg) 7976 req = rx_msg(hapd) 7977 if req[8:10] == "03": 7978 raise Exception("EAP-Success after reflected Element/Scalar") 7979 raise Exception("No EAP-Failure to reject invalid EAP-pwd-Commit/Response") 7980 7981def test_eap_proto_pwd_invalid_scalar_peer(dev, apdev): 7982 """EAP-pwd protocol tests - invalid peer scalar""" 7983 run_eap_proto_pwd_invalid_scalar_peer(dev, apdev, 32*"00") 7984 run_eap_proto_pwd_invalid_scalar_peer(dev, apdev, 31*"00" + "01") 7985 # Group Order 7986 run_eap_proto_pwd_invalid_scalar_peer(dev, apdev, 7987 "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551") 7988 # Group Order - 1 7989 run_eap_proto_pwd_invalid_scalar_peer(dev, apdev, 7990 "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632550", 7991 valid_scalar=True) 7992 7993def run_eap_proto_pwd_invalid_scalar_peer(dev, apdev, scalar, 7994 valid_scalar=False): 7995 hapd = start_pwd_exchange(dev[0], apdev[0]) 7996 proxy_msg(hapd, dev[0]) # EAP-pwd-Commit/Request 7997 7998 # EAP-pwd-Commit/Response 7999 resp = rx_msg(dev[0]) 8000 # Replace scalar with an invalid value 8001 msg = resp[0:20] + resp[20:148] + scalar 8002 tx_msg(dev[0], hapd, msg) 8003 8004 # EAP-pwd-Commit/Response or EAP-Failure 8005 req = rx_msg(hapd) 8006 if valid_scalar and req[8:10] == "04": 8007 raise Exception("Unexpected EAP-Failure with valid scalar") 8008 if not valid_scalar and req[8:10] != "04": 8009 raise Exception("No EAP-Failure to reject invalid scalar") 8010 dev[0].request("REMOVE_NETWORK all") 8011 dev[0].wait_disconnected(timeout=1) 8012 hapd.disable() 8013 8014def test_eap_proto_pwd_invalid_element_peer(dev, apdev): 8015 """EAP-pwd protocol tests - invalid peer element""" 8016 # Invalid x,y coordinates 8017 run_eap_proto_pwd_invalid_element_peer(dev, apdev, 64*'00') 8018 run_eap_proto_pwd_invalid_element_peer(dev, apdev, 32*'00' + 32*'01') 8019 run_eap_proto_pwd_invalid_element_peer(dev, apdev, 32*'01' + 32*'00') 8020 run_eap_proto_pwd_invalid_element_peer(dev, apdev, 32*'ff' + 32*'01') 8021 run_eap_proto_pwd_invalid_element_peer(dev, apdev, 32*'01' + 32*'ff') 8022 run_eap_proto_pwd_invalid_element_peer(dev, apdev, 64*'ff') 8023 # Not on curve 8024 run_eap_proto_pwd_invalid_element_peer(dev, apdev, 64*'01') 8025 8026def run_eap_proto_pwd_invalid_element_peer(dev, apdev, element): 8027 hapd = start_pwd_exchange(dev[0], apdev[0]) 8028 proxy_msg(hapd, dev[0]) # EAP-pwd-Commit/Request 8029 8030 # EAP-pwd-Commit/Response 8031 resp = rx_msg(dev[0]) 8032 # Replace element with an invalid value 8033 msg = resp[0:20] + element + resp[148:] 8034 tx_msg(dev[0], hapd, msg) 8035 8036 # EAP-pwd-Commit/Response or EAP-Failure 8037 req = rx_msg(hapd) 8038 if req[8:10] != "04": 8039 raise Exception("No EAP-Failure to reject invalid element") 8040 dev[0].request("REMOVE_NETWORK all") 8041 dev[0].wait_disconnected(timeout=1) 8042 hapd.disable() 8043 8044def test_eap_proto_pwd_errors(dev, apdev): 8045 """EAP-pwd local error cases""" 8046 check_eap_capa(dev[0], "PWD") 8047 params = hostapd.wpa2_eap_params(ssid="eap-test") 8048 hapd = hostapd.add_ap(apdev[0], params) 8049 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 8050 8051 for i in range(1, 4): 8052 with alloc_fail(dev[0], i, "eap_pwd_init"): 8053 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8054 eap="PWD", identity="pwd user", 8055 password="secret password", 8056 wait_connect=False) 8057 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"], 8058 timeout=15) 8059 if ev is None: 8060 raise Exception("Timeout on EAP start") 8061 dev[0].request("REMOVE_NETWORK all") 8062 dev[0].wait_disconnected() 8063 8064 with alloc_fail(dev[0], 1, "eap_pwd_get_session_id"): 8065 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8066 eap="PWD", identity="pwd user", 8067 fragment_size="0", 8068 password="secret password") 8069 dev[0].request("REMOVE_NETWORK all") 8070 dev[0].wait_disconnected() 8071 8072 funcs = ["eap_pwd_getkey", "eap_pwd_get_emsk", 8073 "=wpabuf_alloc;eap_pwd_perform_commit_exchange", 8074 "=wpabuf_alloc;eap_pwd_perform_confirm_exchange"] 8075 for func in funcs: 8076 with alloc_fail(dev[0], 1, func): 8077 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8078 eap="PWD", identity="pwd user@domain", 8079 password="secret password", erp="1", 8080 wait_connect=False) 8081 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 8082 dev[0].request("REMOVE_NETWORK all") 8083 dev[0].wait_disconnected() 8084 8085 for i in range(1, 5): 8086 with alloc_fail(dev[0], i, "eap_pwd_perform_id_exchange"): 8087 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8088 eap="PWD", identity="pwd user", 8089 password="secret password", 8090 wait_connect=False) 8091 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 8092 timeout=15) 8093 if ev is None: 8094 raise Exception("Timeout on EAP start") 8095 ok = False 8096 for j in range(10): 8097 state = dev[0].request('GET_ALLOC_FAIL') 8098 if state.startswith('0:'): 8099 ok = True 8100 break 8101 time.sleep(0.1) 8102 if not ok: 8103 raise Exception("No allocation failure seen") 8104 dev[0].request("REMOVE_NETWORK all") 8105 dev[0].wait_disconnected() 8106 8107 with alloc_fail(dev[0], 1, "wpabuf_alloc;eap_pwd_perform_id_exchange"): 8108 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8109 eap="PWD", identity="pwd user", 8110 password="secret password", 8111 wait_connect=False) 8112 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 8113 timeout=15) 8114 if ev is None: 8115 raise Exception("Timeout on EAP start") 8116 dev[0].request("REMOVE_NETWORK all") 8117 dev[0].wait_disconnected() 8118 8119 for i in range(1, 9): 8120 with alloc_fail(dev[0], i, "eap_pwd_perform_commit_exchange"): 8121 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8122 eap="PWD", identity="pwd user", 8123 password="secret password", 8124 wait_connect=False) 8125 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 8126 timeout=15) 8127 if ev is None: 8128 raise Exception("Timeout on EAP start") 8129 ok = False 8130 for j in range(10): 8131 state = dev[0].request('GET_ALLOC_FAIL') 8132 if state.startswith('0:'): 8133 ok = True 8134 break 8135 time.sleep(0.1) 8136 if not ok: 8137 raise Exception("No allocation failure seen") 8138 dev[0].request("REMOVE_NETWORK all") 8139 dev[0].wait_disconnected() 8140 8141 for i in range(1, 12): 8142 with alloc_fail(dev[0], i, "eap_pwd_perform_confirm_exchange"): 8143 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8144 eap="PWD", identity="pwd user", 8145 password="secret password", 8146 wait_connect=False) 8147 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 8148 timeout=15) 8149 if ev is None: 8150 raise Exception("Timeout on EAP start") 8151 ok = False 8152 for j in range(10): 8153 state = dev[0].request('GET_ALLOC_FAIL') 8154 if state.startswith('0:'): 8155 ok = True 8156 break 8157 time.sleep(0.1) 8158 if not ok: 8159 raise Exception("No allocation failure seen") 8160 dev[0].request("REMOVE_NETWORK all") 8161 dev[0].wait_disconnected() 8162 8163 for i in range(1, 5): 8164 with alloc_fail(dev[0], i, "eap_msg_alloc;=eap_pwd_process"): 8165 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8166 eap="PWD", identity="pwd user", 8167 password="secret password", fragment_size="50", 8168 wait_connect=False) 8169 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 8170 timeout=15) 8171 if ev is None: 8172 raise Exception("Timeout on EAP start") 8173 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 8174 dev[0].request("REMOVE_NETWORK all") 8175 dev[0].wait_disconnected() 8176 8177 # No password configured 8178 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8179 eap="PWD", identity="pwd user", 8180 wait_connect=False) 8181 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD vendor=0 method=52"], 8182 timeout=15) 8183 if ev is None: 8184 raise Exception("EAP-pwd not started") 8185 dev[0].request("REMOVE_NETWORK all") 8186 dev[0].wait_disconnected() 8187 8188 funcs = [(1, "hash_nt_password_hash;eap_pwd_perform_commit_exchange"), 8189 (1, "=crypto_bignum_init;eap_pwd_perform_commit_exchange"), 8190 (1, "=crypto_ec_point_init;eap_pwd_perform_commit_exchange"), 8191 (2, "=crypto_ec_point_init;eap_pwd_perform_commit_exchange"), 8192 (1, "=crypto_ec_point_mul;eap_pwd_perform_commit_exchange"), 8193 (2, "=crypto_ec_point_mul;eap_pwd_perform_commit_exchange"), 8194 (3, "=crypto_ec_point_mul;eap_pwd_perform_commit_exchange"), 8195 (1, "=crypto_ec_point_add;eap_pwd_perform_commit_exchange"), 8196 (1, "=crypto_ec_point_invert;eap_pwd_perform_commit_exchange"), 8197 (1, "=crypto_ec_point_to_bin;eap_pwd_perform_commit_exchange"), 8198 (1, "crypto_hash_finish;eap_pwd_kdf"), 8199 (1, "crypto_ec_point_from_bin;eap_pwd_get_element"), 8200 (3, "crypto_bignum_init;compute_password_element"), 8201 (4, "crypto_bignum_init;compute_password_element"), 8202 (1, "crypto_bignum_init_set;compute_password_element"), 8203 (2, "crypto_bignum_init_set;compute_password_element"), 8204 (3, "crypto_bignum_init_set;compute_password_element"), 8205 (1, "crypto_bignum_to_bin;compute_password_element"), 8206 (1, "crypto_ec_point_compute_y_sqr;compute_password_element"), 8207 (1, "crypto_bignum_rand;compute_password_element"), 8208 (1, "crypto_bignum_sub;compute_password_element")] 8209 for count, func in funcs: 8210 with fail_test(dev[0], count, func): 8211 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8212 eap="PWD", identity="pwd-hash", 8213 password_hex="hash:e3718ece8ab74792cbbfffd316d2d19a", 8214 wait_connect=False) 8215 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10) 8216 if ev is None: 8217 raise Exception("No EAP-Failure reported") 8218 dev[0].request("REMOVE_NETWORK all") 8219 dev[0].wait_disconnected() 8220 8221 params = {"ssid": "eap-test2", "wpa": "2", "wpa_key_mgmt": "WPA-EAP", 8222 "rsn_pairwise": "CCMP", "ieee8021x": "1", 8223 "eap_server": "1", "eap_user_file": "auth_serv/eap_user.conf", 8224 "pwd_group": "19", "fragment_size": "40"} 8225 hapd2 = hostapd.add_ap(apdev[1], params) 8226 dev[0].scan_for_bss(hapd2.own_addr(), freq=2412) 8227 8228 with alloc_fail(dev[0], 1, "wpabuf_alloc;=eap_pwd_process"): 8229 dev[0].connect("eap-test2", key_mgmt="WPA-EAP", scan_freq="2412", 8230 eap="PWD", identity="pwd user", 8231 password="secret password", 8232 wait_connect=False) 8233 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 8234 dev[0].request("REMOVE_NETWORK all") 8235 dev[0].wait_disconnected() 8236 8237 for i in range(1, 5): 8238 with fail_test(dev[0], i, 8239 "=crypto_ec_point_to_bin;eap_pwd_perform_confirm_exchange"): 8240 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8241 eap="PWD", identity="pwd-hash", 8242 password_hex="hash:e3718ece8ab74792cbbfffd316d2d19a", 8243 wait_connect=False) 8244 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10) 8245 if ev is None: 8246 raise Exception("No EAP-Failure reported") 8247 dev[0].request("REMOVE_NETWORK all") 8248 dev[0].wait_disconnected() 8249 dev[0].dump_monitor() 8250 8251def run_eap_pwd_connect(dev, hash=True, fragment=2000): 8252 if hash: 8253 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", 8254 fragment_size=str(fragment), 8255 eap="PWD", identity="pwd-hash", 8256 password_hex="hash:e3718ece8ab74792cbbfffd316d2d19a", 8257 scan_freq="2412", wait_connect=False) 8258 else: 8259 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", 8260 fragment_size=str(fragment), 8261 eap="PWD", identity="pwd-hash-sha1", 8262 password="secret password", 8263 scan_freq="2412", wait_connect=False) 8264 ev = dev.wait_event(["CTRL-EVENT-EAP-SUCCESS", "CTRL-EVENT-EAP-FAILURE", 8265 "CTRL-EVENT-DISCONNECTED"], 8266 timeout=1) 8267 dev.request("REMOVE_NETWORK all") 8268 if not ev or "CTRL-EVENT-DISCONNECTED" not in ev: 8269 dev.wait_disconnected() 8270 dev.dump_monitor() 8271 8272def test_eap_proto_pwd_errors_server(dev, apdev): 8273 """EAP-pwd local error cases on server""" 8274 check_eap_capa(dev[0], "PWD") 8275 params = int_eap_server_params() 8276 params['erp_domain'] = 'example.com' 8277 params['eap_server_erp'] = '1' 8278 hapd = hostapd.add_ap(apdev[0], params) 8279 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 8280 8281 tests = [(1, "eap_pwd_init"), 8282 (2, "eap_pwd_init"), 8283 (3, "eap_pwd_init"), 8284 (1, "eap_pwd_build_id_req"), 8285 (1, "eap_pwd_build_commit_req"), 8286 (1, "eap_pwd_build_confirm_req"), 8287 (1, "eap_pwd_h_init;eap_pwd_build_confirm_req"), 8288 (1, "wpabuf_alloc;eap_pwd_build_confirm_req"), 8289 (1, "eap_msg_alloc;eap_pwd_build_req"), 8290 (1, "eap_pwd_process_id_resp"), 8291 (1, "get_eap_pwd_group;eap_pwd_process_id_resp"), 8292 (1, "eap_pwd_process_confirm_resp"), 8293 (1, "eap_pwd_h_init;eap_pwd_process_confirm_resp"), 8294 (1, "compute_keys;eap_pwd_process_confirm_resp"), 8295 (1, "eap_pwd_getkey"), 8296 (1, "eap_pwd_get_emsk"), 8297 (1, "eap_pwd_get_session_id")] 8298 for count, func in tests: 8299 with alloc_fail(hapd, count, func): 8300 run_eap_pwd_connect(dev[0], hash=True) 8301 8302 tests = [(1, "eap_msg_alloc;eap_pwd_build_req"), 8303 (2, "eap_msg_alloc;eap_pwd_build_req"), 8304 (1, "wpabuf_alloc;eap_pwd_process")] 8305 for count, func in tests: 8306 with alloc_fail(hapd, count, func): 8307 run_eap_pwd_connect(dev[0], hash=True, fragment=13) 8308 8309 tests = [(4, "eap_pwd_init")] 8310 for count, func in tests: 8311 with alloc_fail(hapd, count, func): 8312 run_eap_pwd_connect(dev[0], hash=False) 8313 8314 tests = [(1, "eap_pwd_build_id_req"), 8315 (1, "eap_pwd_build_commit_req"), 8316 (1, "crypto_ec_point_mul;eap_pwd_build_commit_req"), 8317 (1, "crypto_ec_point_invert;eap_pwd_build_commit_req"), 8318 (1, "crypto_ec_point_to_bin;eap_pwd_build_commit_req"), 8319 (1, "crypto_ec_point_to_bin;eap_pwd_build_confirm_req"), 8320 (2, "=crypto_ec_point_to_bin;eap_pwd_build_confirm_req"), 8321 (1, "hash_nt_password_hash;eap_pwd_process_id_resp"), 8322 (1, "compute_password_element;eap_pwd_process_id_resp"), 8323 (1, "crypto_bignum_init;eap_pwd_process_commit_resp"), 8324 (1, "crypto_ec_point_mul;eap_pwd_process_commit_resp"), 8325 (2, "crypto_ec_point_mul;eap_pwd_process_commit_resp"), 8326 (1, "crypto_ec_point_add;eap_pwd_process_commit_resp"), 8327 (1, "crypto_ec_point_to_bin;eap_pwd_process_confirm_resp"), 8328 (2, "=crypto_ec_point_to_bin;eap_pwd_process_confirm_resp")] 8329 for count, func in tests: 8330 with fail_test(hapd, count, func): 8331 run_eap_pwd_connect(dev[0], hash=True) 8332 8333def start_pwd_assoc(dev, hapd): 8334 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", 8335 eap="PWD", identity="pwd user", password="secret password", 8336 wait_connect=False, scan_freq="2412") 8337 proxy_msg(hapd, dev) # EAP-Identity/Request 8338 proxy_msg(dev, hapd) # EAP-Identity/Response 8339 proxy_msg(hapd, dev) # EAP-pwd-Identity/Request 8340 8341def stop_pwd_assoc(dev, hapd): 8342 dev.request("REMOVE_NETWORK all") 8343 dev.wait_disconnected() 8344 dev.dump_monitor() 8345 hapd.dump_monitor() 8346 8347def test_eap_proto_pwd_server(dev, apdev): 8348 """EAP-pwd protocol testing for the server""" 8349 check_eap_capa(dev[0], "PWD") 8350 params = int_eap_server_params() 8351 hapd = hostapd.add_ap(apdev[0], params) 8352 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 8353 hapd.request("SET ext_eapol_frame_io 1") 8354 dev[0].request("SET ext_eapol_frame_io 1") 8355 8356 start_pwd_assoc(dev[0], hapd) 8357 resp = rx_msg(dev[0]) 8358 # Replace exch field with unexpected value 8359 # --> EAP-pwd: Unexpected opcode=4 in state=0 8360 msg = resp[0:18] + "04" + resp[20:] 8361 tx_msg(dev[0], hapd, msg) 8362 8363 # Too short EAP-pwd header (no flags/exch field) 8364 # --> EAP-pwd: Invalid frame 8365 msg = resp[0:4] + "0005" + resp[8:12] + "0005" + "34" 8366 tx_msg(dev[0], hapd, msg) 8367 8368 # Too short EAP-pwd header (L=1 but only one octet of total length field) 8369 # --> EAP-pwd: Frame too short to contain Total-Length field 8370 msg = resp[0:4] + "0007" + resp[8:12] + "0007" + "34" + "81ff" 8371 tx_msg(dev[0], hapd, msg) 8372 # server continues exchange, so start from scratch for the next step 8373 rx_msg(hapd) 8374 stop_pwd_assoc(dev[0], hapd) 8375 8376 start_pwd_assoc(dev[0], hapd) 8377 resp = rx_msg(dev[0]) 8378 # Too large total length 8379 msg = resp[0:4] + "0008" + resp[8:12] + "0008" + "34" + "c1ffff" 8380 tx_msg(dev[0], hapd, msg) 8381 # server continues exchange, so start from scratch for the next step 8382 rx_msg(hapd) 8383 stop_pwd_assoc(dev[0], hapd) 8384 8385 start_pwd_assoc(dev[0], hapd) 8386 resp = rx_msg(dev[0]) 8387 # First fragment 8388 msg = resp[0:4] + "0009" + resp[8:12] + "0009" + "34" + "c100ff" + "aa" 8389 tx_msg(dev[0], hapd, msg) 8390 # Ack 8391 req = rx_msg(hapd) 8392 # Unexpected first fragment 8393 # --> EAP-pwd: Unexpected new fragment start when previous fragment is still in use 8394 msg = resp[0:4] + "0009" + resp[8:10] + req[10:12] + "0009" + "34" + "c100ee" + "bb" 8395 tx_msg(dev[0], hapd, msg) 8396 # server continues exchange, so start from scratch for the next step 8397 rx_msg(hapd) 8398 stop_pwd_assoc(dev[0], hapd) 8399 8400 start_pwd_assoc(dev[0], hapd) 8401 resp = rx_msg(dev[0]) 8402 # Too much data in first fragment 8403 # --> EAP-pwd: Buffer overflow attack detected! (0+2 > 1) 8404 msg = resp[0:4] + "000a" + resp[8:12] + "000a" + "34" + "c10001" + "aabb" 8405 tx_msg(dev[0], hapd, msg) 8406 # EAP-Failure 8407 rx_msg(hapd) 8408 stop_pwd_assoc(dev[0], hapd) 8409 8410 start_pwd_assoc(dev[0], hapd) 8411 resp = rx_msg(dev[0]) 8412 # Change parameters 8413 # --> EAP-pwd: peer changed parameters 8414 msg = resp[0:20] + "ff" + resp[22:] 8415 tx_msg(dev[0], hapd, msg) 8416 # EAP-Failure 8417 rx_msg(hapd) 8418 stop_pwd_assoc(dev[0], hapd) 8419 8420 start_pwd_assoc(dev[0], hapd) 8421 resp = rx_msg(dev[0]) 8422 # Too short ID response 8423 # --> EAP-pwd: Invalid ID response 8424 msg = resp[0:4] + "000a" + resp[8:12] + "000a" + "34" + "01ffeeddcc" 8425 tx_msg(dev[0], hapd, msg) 8426 # server continues exchange, so start from scratch for the next step 8427 rx_msg(hapd) 8428 stop_pwd_assoc(dev[0], hapd) 8429 8430 start_pwd_assoc(dev[0], hapd) 8431 # EAP-pwd-Identity/Response 8432 resp = rx_msg(dev[0]) 8433 tx_msg(dev[0], hapd, resp) 8434 # EAP-pwd-Commit/Request 8435 req = rx_msg(hapd) 8436 # Unexpected EAP-pwd-Identity/Response 8437 # --> EAP-pwd: Unexpected opcode=1 in state=1 8438 msg = resp[0:10] + req[10:12] + resp[12:] 8439 tx_msg(dev[0], hapd, msg) 8440 # server continues exchange, so start from scratch for the next step 8441 rx_msg(hapd) 8442 stop_pwd_assoc(dev[0], hapd) 8443 8444 start_pwd_assoc(dev[0], hapd) 8445 proxy_msg(dev[0], hapd) # EAP-pwd-Identity/Response 8446 proxy_msg(hapd, dev[0]) # EAP-pwd-Commit/Request 8447 # EAP-pwd-Commit/Response 8448 resp = rx_msg(dev[0]) 8449 # Too short Commit response 8450 # --> EAP-pwd: Unexpected Commit payload length 4 (expected 96) 8451 msg = resp[0:4] + "000a" + resp[8:12] + "000a" + "34" + "02ffeeddcc" 8452 tx_msg(dev[0], hapd, msg) 8453 # EAP-Failure 8454 rx_msg(hapd) 8455 stop_pwd_assoc(dev[0], hapd) 8456 8457 start_pwd_assoc(dev[0], hapd) 8458 proxy_msg(dev[0], hapd) # EAP-pwd-Identity/Response 8459 proxy_msg(hapd, dev[0]) # EAP-pwd-Commit/Request 8460 proxy_msg(dev[0], hapd) # EAP-pwd-Commit/Response 8461 proxy_msg(hapd, dev[0]) # EAP-pwd-Confirm/Request 8462 # EAP-pwd-Confirm/Response 8463 resp = rx_msg(dev[0]) 8464 # Too short Confirm response 8465 # --> EAP-pwd: Unexpected Confirm payload length 4 (expected 32) 8466 msg = resp[0:4] + "000a" + resp[8:12] + "000a" + "34" + "03ffeeddcc" 8467 tx_msg(dev[0], hapd, msg) 8468 # EAP-Failure 8469 rx_msg(hapd) 8470 stop_pwd_assoc(dev[0], hapd) 8471 8472 start_pwd_assoc(dev[0], hapd) 8473 resp = rx_msg(dev[0]) 8474 # Set M=1 8475 # --> EAP-pwd: No buffer for reassembly 8476 msg = resp[0:18] + "41" + resp[20:] 8477 tx_msg(dev[0], hapd, msg) 8478 # EAP-Failure 8479 rx_msg(hapd) 8480 stop_pwd_assoc(dev[0], hapd) 8481 8482def test_eap_proto_erp(dev, apdev): 8483 """ERP protocol tests""" 8484 check_erp_capa(dev[0]) 8485 8486 global eap_proto_erp_test_done 8487 eap_proto_erp_test_done = False 8488 8489 def erp_handler(ctx, req): 8490 logger.info("erp_handler - RX " + binascii.hexlify(req).decode()) 8491 if 'num' not in ctx: 8492 ctx['num'] = 0 8493 ctx['num'] += 1 8494 if 'id' not in ctx: 8495 ctx['id'] = 1 8496 ctx['id'] = (ctx['id'] + 1) % 256 8497 idx = 0 8498 8499 idx += 1 8500 if ctx['num'] == idx: 8501 logger.info("Test: Missing type") 8502 return struct.pack(">BBH", EAP_CODE_INITIATE, ctx['id'], 4) 8503 8504 idx += 1 8505 if ctx['num'] == idx: 8506 logger.info("Test: Unexpected type") 8507 return struct.pack(">BBHB", EAP_CODE_INITIATE, ctx['id'], 4 + 1, 8508 255) 8509 8510 idx += 1 8511 if ctx['num'] == idx: 8512 logger.info("Test: Missing Reserved field") 8513 return struct.pack(">BBHB", EAP_CODE_INITIATE, ctx['id'], 4 + 1, 8514 EAP_ERP_TYPE_REAUTH_START) 8515 8516 idx += 1 8517 if ctx['num'] == idx: 8518 logger.info("Test: Zero-length TVs/TLVs") 8519 payload = b"" 8520 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'], 8521 4 + 1 + 1 + len(payload), 8522 EAP_ERP_TYPE_REAUTH_START, 0) + payload 8523 8524 idx += 1 8525 if ctx['num'] == idx: 8526 logger.info("Test: Too short TLV") 8527 payload = struct.pack("B", 191) 8528 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'], 8529 4 + 1 + 1 + len(payload), 8530 EAP_ERP_TYPE_REAUTH_START, 0) + payload 8531 8532 idx += 1 8533 if ctx['num'] == idx: 8534 logger.info("Test: Truncated TLV") 8535 payload = struct.pack("BB", 191, 1) 8536 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'], 8537 4 + 1 + 1 + len(payload), 8538 EAP_ERP_TYPE_REAUTH_START, 0) + payload 8539 8540 idx += 1 8541 if ctx['num'] == idx: 8542 logger.info("Test: Ignored unknown TLV and unknown TV/TLV terminating parsing") 8543 payload = struct.pack("BBB", 191, 0, 192) 8544 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'], 8545 4 + 1 + 1 + len(payload), 8546 EAP_ERP_TYPE_REAUTH_START, 0) + payload 8547 8548 idx += 1 8549 if ctx['num'] == idx: 8550 logger.info("Test: More than one keyName-NAI") 8551 payload = struct.pack("BBBB", EAP_ERP_TLV_KEYNAME_NAI, 0, 8552 EAP_ERP_TLV_KEYNAME_NAI, 0) 8553 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'], 8554 4 + 1 + 1 + len(payload), 8555 EAP_ERP_TYPE_REAUTH_START, 0) + payload 8556 8557 idx += 1 8558 if ctx['num'] == idx: 8559 logger.info("Test: Too short TLV keyName-NAI") 8560 payload = struct.pack("B", EAP_ERP_TLV_KEYNAME_NAI) 8561 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'], 8562 4 + 1 + 1 + len(payload), 8563 EAP_ERP_TYPE_REAUTH_START, 0) + payload 8564 8565 idx += 1 8566 if ctx['num'] == idx: 8567 logger.info("Test: Truncated TLV keyName-NAI") 8568 payload = struct.pack("BB", EAP_ERP_TLV_KEYNAME_NAI, 1) 8569 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'], 8570 4 + 1 + 1 + len(payload), 8571 EAP_ERP_TYPE_REAUTH_START, 0) + payload 8572 8573 idx += 1 8574 if ctx['num'] == idx: 8575 logger.info("Test: Valid rRK lifetime TV followed by too short rMSK lifetime TV") 8576 payload = struct.pack(">BLBH", EAP_ERP_TV_RRK_LIFETIME, 0, 8577 EAP_ERP_TV_RMSK_LIFETIME, 0) 8578 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'], 8579 4 + 1 + 1 + len(payload), 8580 EAP_ERP_TYPE_REAUTH_START, 0) + payload 8581 8582 idx += 1 8583 if ctx['num'] == idx: 8584 logger.info("Test: Missing type (Finish)") 8585 return struct.pack(">BBH", EAP_CODE_FINISH, ctx['id'], 4) 8586 8587 idx += 1 8588 if ctx['num'] == idx: 8589 logger.info("Test: Unexpected type (Finish)") 8590 return struct.pack(">BBHB", EAP_CODE_FINISH, ctx['id'], 4 + 1, 8591 255) 8592 8593 idx += 1 8594 if ctx['num'] == idx: 8595 logger.info("Test: Missing fields (Finish)") 8596 return struct.pack(">BBHB", EAP_CODE_FINISH, ctx['id'], 4 + 1, 8597 EAP_ERP_TYPE_REAUTH) 8598 8599 idx += 1 8600 if ctx['num'] == idx: 8601 logger.info("Test: Unexpected SEQ (Finish)") 8602 return struct.pack(">BBHBBHB", EAP_CODE_FINISH, ctx['id'], 8603 4 + 1 + 4, 8604 EAP_ERP_TYPE_REAUTH, 0, 0xffff, 0) 8605 8606 logger.info("No more test responses available - test case completed") 8607 global eap_proto_erp_test_done 8608 eap_proto_erp_test_done = True 8609 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 8610 8611 srv = start_radius_server(erp_handler) 8612 8613 try: 8614 hapd = start_ap(apdev[0]) 8615 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 8616 8617 i = 0 8618 while not eap_proto_erp_test_done: 8619 i += 1 8620 logger.info("Running connection iteration %d" % i) 8621 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8622 eap="PAX", identity="pax.user@example.com", 8623 password_hex="0123456789abcdef0123456789abcdef", 8624 wait_connect=False) 8625 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5) 8626 if ev is None: 8627 raise Exception("Timeout on EAP start") 8628 time.sleep(0.1) 8629 dev[0].request("REMOVE_NETWORK all") 8630 dev[0].wait_disconnected(timeout=1) 8631 dev[0].dump_monitor() 8632 finally: 8633 stop_radius_server(srv) 8634 8635def test_eap_proto_fast_errors(dev, apdev): 8636 """EAP-FAST local error cases""" 8637 check_eap_capa(dev[0], "FAST") 8638 params = hostapd.wpa2_eap_params(ssid="eap-test") 8639 hapd = hostapd.add_ap(apdev[0], params) 8640 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 8641 8642 for i in range(1, 5): 8643 with alloc_fail(dev[0], i, "eap_fast_init"): 8644 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8645 eap="FAST", anonymous_identity="FAST", 8646 identity="user", password="password", 8647 ca_cert="auth_serv/ca.pem", phase2="auth=GTC", 8648 phase1="fast_provisioning=2", 8649 pac_file="blob://fast_pac_auth", 8650 wait_connect=False) 8651 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"], 8652 timeout=5) 8653 if ev is None: 8654 raise Exception("Timeout on EAP start") 8655 dev[0].request("REMOVE_NETWORK all") 8656 dev[0].wait_disconnected() 8657 8658 tests = [(1, "wpabuf_alloc;eap_fast_tlv_eap_payload"), 8659 (1, "eap_fast_derive_key;eap_fast_derive_key_auth"), 8660 (1, "eap_msg_alloc;eap_peer_tls_phase2_nak"), 8661 (1, "wpabuf_alloc;eap_fast_tlv_result"), 8662 (1, "wpabuf_alloc;eap_fast_tlv_pac_ack"), 8663 (1, "=eap_peer_tls_derive_session_id;eap_fast_process_crypto_binding"), 8664 (1, "eap_peer_tls_decrypt;eap_fast_decrypt"), 8665 (1, "eap_fast_getKey"), 8666 (1, "eap_fast_get_session_id"), 8667 (1, "eap_fast_get_emsk")] 8668 for count, func in tests: 8669 dev[0].request("SET blob fast_pac_auth_errors ") 8670 with alloc_fail(dev[0], count, func): 8671 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8672 eap="FAST", anonymous_identity="FAST", 8673 identity="user@example.com", password="password", 8674 ca_cert="auth_serv/ca.pem", phase2="auth=GTC", 8675 phase1="fast_provisioning=2", 8676 pac_file="blob://fast_pac_auth_errors", 8677 erp="1", 8678 wait_connect=False) 8679 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 8680 timeout=15) 8681 if ev is None: 8682 raise Exception("Timeout on EAP start") 8683 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 8684 dev[0].request("REMOVE_NETWORK all") 8685 dev[0].wait_disconnected() 8686 8687 tests = [(1, "eap_fast_derive_key;eap_fast_derive_key_provisioning"), 8688 (1, "eap_mschapv2_getKey;eap_fast_get_phase2_key"), 8689 (1, "=eap_fast_use_pac_opaque"), 8690 (1, "eap_fast_copy_buf"), 8691 (1, "=eap_fast_add_pac"), 8692 (1, "=eap_fast_init_pac_data"), 8693 (1, "=eap_fast_write_pac"), 8694 (2, "=eap_fast_write_pac")] 8695 for count, func in tests: 8696 dev[0].request("SET blob fast_pac_errors ") 8697 with alloc_fail(dev[0], count, func): 8698 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8699 eap="FAST", anonymous_identity="FAST", 8700 identity="user", password="password", 8701 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2", 8702 phase1="fast_provisioning=1", 8703 pac_file="blob://fast_pac_errors", 8704 erp="1", 8705 wait_connect=False) 8706 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 8707 timeout=15) 8708 if ev is None: 8709 raise Exception("Timeout on EAP start") 8710 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 8711 dev[0].request("REMOVE_NETWORK all") 8712 dev[0].wait_disconnected() 8713 8714 tests = [(1, "eap_fast_get_cmk;eap_fast_process_crypto_binding"), 8715 (1, "eap_fast_derive_eap_msk;eap_fast_process_crypto_binding"), 8716 (1, "eap_fast_derive_eap_emsk;eap_fast_process_crypto_binding")] 8717 for count, func in tests: 8718 dev[0].request("SET blob fast_pac_auth_errors ") 8719 with fail_test(dev[0], count, func): 8720 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8721 eap="FAST", anonymous_identity="FAST", 8722 identity="user", password="password", 8723 ca_cert="auth_serv/ca.pem", phase2="auth=GTC", 8724 phase1="fast_provisioning=2", 8725 pac_file="blob://fast_pac_auth_errors", 8726 erp="1", 8727 wait_connect=False) 8728 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 8729 timeout=15) 8730 if ev is None: 8731 raise Exception("Timeout on EAP start") 8732 wait_fail_trigger(dev[0], "GET_FAIL") 8733 dev[0].request("REMOVE_NETWORK all") 8734 dev[0].wait_disconnected() 8735 8736 dev[0].request("SET blob fast_pac_errors ") 8737 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8738 eap="FAST", anonymous_identity="FAST", 8739 identity="user", password="password", 8740 ca_cert="auth_serv/ca.pem", phase2="auth=GTC", 8741 phase1="fast_provisioning=1", 8742 pac_file="blob://fast_pac_errors", 8743 wait_connect=False) 8744 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5) 8745 if ev is None: 8746 raise Exception("Timeout on EAP start") 8747 # EAP-FAST: Only EAP-MSCHAPv2 is allowed during unauthenticated 8748 # provisioning; reject phase2 type 6 8749 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5) 8750 if ev is None: 8751 raise Exception("Timeout on EAP failure") 8752 dev[0].request("REMOVE_NETWORK all") 8753 dev[0].wait_disconnected() 8754 8755 logger.info("Wrong password in Phase 2") 8756 dev[0].request("SET blob fast_pac_errors ") 8757 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8758 eap="FAST", anonymous_identity="FAST", 8759 identity="user", password="wrong password", 8760 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2", 8761 phase1="fast_provisioning=1", 8762 pac_file="blob://fast_pac_errors", 8763 wait_connect=False) 8764 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5) 8765 if ev is None: 8766 raise Exception("Timeout on EAP start") 8767 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5) 8768 if ev is None: 8769 raise Exception("Timeout on EAP failure") 8770 dev[0].request("REMOVE_NETWORK all") 8771 dev[0].wait_disconnected() 8772 8773 tests = ["FOOBAR\n", 8774 "wpa_supplicant EAP-FAST PAC file - version 1\nFOOBAR\n", 8775 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\n", 8776 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nSTART\n", 8777 "wpa_supplicant EAP-FAST PAC file - version 1\nEND\n", 8778 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nPAC-Type=12345\nEND\n" 8779 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nPAC-Key=12\nEND\n", 8780 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nPAC-Key=1\nEND\n", 8781 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nPAC-Key=1q\nEND\n", 8782 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nPAC-Opaque=1\nEND\n", 8783 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nA-ID=1\nEND\n", 8784 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nI-ID=1\nEND\n", 8785 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nA-ID-Info=1\nEND\n"] 8786 for pac in tests: 8787 blob = binascii.hexlify(pac.encode()).decode() 8788 dev[0].request("SET blob fast_pac_errors " + blob) 8789 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8790 eap="FAST", anonymous_identity="FAST", 8791 identity="user", password="password", 8792 ca_cert="auth_serv/ca.pem", phase2="auth=GTC", 8793 phase1="fast_provisioning=2", 8794 pac_file="blob://fast_pac_errors", 8795 wait_connect=False) 8796 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"], 8797 timeout=5) 8798 if ev is None: 8799 raise Exception("Timeout on EAP start") 8800 dev[0].request("REMOVE_NETWORK all") 8801 dev[0].wait_disconnected() 8802 8803 tests = ["wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nEND\n", 8804 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nEND\nSTART\nEND\nSTART\nEND\n"] 8805 for pac in tests: 8806 blob = binascii.hexlify(pac.encode()).decode() 8807 dev[0].request("SET blob fast_pac_errors " + blob) 8808 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8809 eap="FAST", anonymous_identity="FAST", 8810 identity="user", password="password", 8811 ca_cert="auth_serv/ca.pem", phase2="auth=GTC", 8812 phase1="fast_provisioning=2", 8813 pac_file="blob://fast_pac_errors") 8814 dev[0].request("REMOVE_NETWORK all") 8815 dev[0].wait_disconnected() 8816 8817 dev[0].request("SET blob fast_pac_errors ") 8818 8819def test_eap_proto_peap_errors_server(dev, apdev): 8820 """EAP-PEAP local error cases on server""" 8821 params = int_eap_server_params() 8822 hapd = hostapd.add_ap(apdev[0], params) 8823 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 8824 8825 tests = [(1, "get_asymetric_start_key;eap_mschapv2_getKey"), 8826 (1, "generate_authenticator_response_pwhash;eap_mschapv2_process_response"), 8827 (1, "hash_nt_password_hash;eap_mschapv2_process_response"), 8828 (1, "get_master_key;eap_mschapv2_process_response")] 8829 for count, func in tests: 8830 with fail_test(hapd, count, func): 8831 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", 8832 scan_freq="2412", 8833 eap="PEAP", anonymous_identity="peap", 8834 identity="user", password="password", 8835 phase1="peapver=0 crypto_binding=2", 8836 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2", 8837 erp="1", wait_connect=False) 8838 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10) 8839 if ev is None: 8840 raise Exception("EAP-Failure not reported") 8841 dev[0].request("REMOVE_NETWORK all") 8842 dev[0].wait_disconnected() 8843 8844def test_eap_proto_peap_errors(dev, apdev): 8845 """EAP-PEAP local error cases""" 8846 check_eap_capa(dev[0], "PEAP") 8847 check_eap_capa(dev[0], "MSCHAPV2") 8848 params = hostapd.wpa2_eap_params(ssid="eap-test") 8849 hapd = hostapd.add_ap(apdev[0], params) 8850 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 8851 8852 for i in range(1, 5): 8853 with alloc_fail(dev[0], i, "eap_peap_init"): 8854 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8855 eap="PEAP", anonymous_identity="peap", 8856 identity="user", password="password", 8857 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2", 8858 wait_connect=False) 8859 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"], 8860 timeout=5) 8861 if ev is None: 8862 raise Exception("Timeout on EAP start") 8863 dev[0].request("REMOVE_NETWORK all") 8864 dev[0].wait_disconnected() 8865 8866 tests = [(1, "eap_mschapv2_getKey;eap_peap_get_isk;eap_peap_derive_cmk"), 8867 (1, "eap_msg_alloc;eap_tlv_build_result"), 8868 (1, "eap_mschapv2_init;eap_peap_phase2_request"), 8869 (1, "eap_peer_tls_decrypt;eap_peap_decrypt"), 8870 (1, "wpabuf_alloc;=eap_peap_decrypt"), 8871 (1, "eap_peer_tls_encrypt;eap_peap_decrypt"), 8872 (1, "eap_peer_tls_process_helper;eap_peap_process"), 8873 (1, "eap_peer_tls_derive_key;eap_peap_process"), 8874 (1, "eap_peer_tls_derive_session_id;eap_peap_process"), 8875 (1, "eap_peap_getKey"), 8876 (1, "eap_peap_get_session_id")] 8877 for count, func in tests: 8878 with alloc_fail(dev[0], count, func): 8879 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8880 eap="PEAP", anonymous_identity="peap", 8881 identity="user", password="password", 8882 phase1="peapver=0 crypto_binding=2", 8883 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2", 8884 erp="1", wait_connect=False) 8885 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 8886 timeout=15) 8887 if ev is None: 8888 raise Exception("Timeout on EAP start") 8889 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 8890 dev[0].request("REMOVE_NETWORK all") 8891 dev[0].wait_disconnected() 8892 8893 tests = [(1, "peap_prfplus;eap_peap_derive_cmk"), 8894 (1, "eap_tlv_add_cryptobinding;eap_tlv_build_result"), 8895 (1, "peap_prfplus;eap_peap_getKey"), 8896 (1, "get_asymetric_start_key;eap_mschapv2_getKey")] 8897 for count, func in tests: 8898 with fail_test(dev[0], count, func): 8899 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8900 eap="PEAP", anonymous_identity="peap", 8901 identity="user", password="password", 8902 phase1="peapver=0 crypto_binding=2", 8903 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2", 8904 erp="1", wait_connect=False) 8905 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 8906 timeout=15) 8907 if ev is None: 8908 raise Exception("Timeout on EAP start") 8909 wait_fail_trigger(dev[0], "GET_FAIL") 8910 dev[0].request("REMOVE_NETWORK all") 8911 dev[0].wait_disconnected() 8912 8913 with alloc_fail(dev[0], 1, 8914 "eap_peer_tls_phase2_nak;eap_peap_phase2_request"): 8915 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8916 eap="PEAP", anonymous_identity="peap", 8917 identity="cert user", password="password", 8918 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2", 8919 wait_connect=False) 8920 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 8921 dev[0].request("REMOVE_NETWORK all") 8922 dev[0].wait_disconnected() 8923 8924def test_eap_proto_ttls_errors(dev, apdev): 8925 """EAP-TTLS local error cases""" 8926 check_eap_capa(dev[0], "TTLS") 8927 check_eap_capa(dev[0], "MSCHAPV2") 8928 params = hostapd.wpa2_eap_params(ssid="eap-test") 8929 hapd = hostapd.add_ap(apdev[0], params) 8930 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 8931 8932 for i in range(1, 5): 8933 with alloc_fail(dev[0], i, "eap_ttls_init"): 8934 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 8935 eap="TTLS", anonymous_identity="ttls", 8936 identity="user", password="password", 8937 ca_cert="auth_serv/ca.pem", 8938 phase2="autheap=MSCHAPV2", 8939 wait_connect=False) 8940 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"], 8941 timeout=5) 8942 if ev is None: 8943 raise Exception("Timeout on EAP start") 8944 dev[0].request("REMOVE_NETWORK all") 8945 dev[0].wait_disconnected() 8946 8947 tests = [(1, "eap_peer_tls_derive_key;eap_ttls_v0_derive_key", 8948 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"), 8949 (1, "eap_peer_tls_derive_session_id;eap_ttls_v0_derive_key", 8950 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"), 8951 (1, "wpabuf_alloc;eap_ttls_phase2_request_mschapv2", 8952 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"), 8953 (1, "eap_peer_tls_derive_key;eap_ttls_phase2_request_mschapv2", 8954 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"), 8955 (1, "eap_peer_tls_encrypt;eap_ttls_encrypt_response;eap_ttls_implicit_identity_request", 8956 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"), 8957 (1, "eap_peer_tls_decrypt;eap_ttls_decrypt", 8958 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"), 8959 (1, "eap_ttls_getKey", 8960 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"), 8961 (1, "eap_ttls_get_session_id", 8962 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"), 8963 (1, "eap_ttls_get_emsk", 8964 "mschapv2 user@domain", "auth=MSCHAPV2"), 8965 (1, "wpabuf_alloc;eap_ttls_phase2_request_mschap", 8966 "mschap user", "auth=MSCHAP"), 8967 (1, "eap_peer_tls_derive_key;eap_ttls_phase2_request_mschap", 8968 "mschap user", "auth=MSCHAP"), 8969 (1, "wpabuf_alloc;eap_ttls_phase2_request_chap", 8970 "chap user", "auth=CHAP"), 8971 (1, "eap_peer_tls_derive_key;eap_ttls_phase2_request_chap", 8972 "chap user", "auth=CHAP"), 8973 (1, "wpabuf_alloc;eap_ttls_phase2_request_pap", 8974 "pap user", "auth=PAP"), 8975 (1, "wpabuf_alloc;eap_ttls_avp_encapsulate", 8976 "user", "autheap=MSCHAPV2"), 8977 (1, "eap_mschapv2_init;eap_ttls_phase2_request_eap_method", 8978 "user", "autheap=MSCHAPV2"), 8979 (1, "eap_sm_buildIdentity;eap_ttls_phase2_request_eap", 8980 "user", "autheap=MSCHAPV2"), 8981 (1, "eap_ttls_avp_encapsulate;eap_ttls_phase2_request_eap", 8982 "user", "autheap=MSCHAPV2"), 8983 (1, "eap_ttls_parse_attr_eap", 8984 "user", "autheap=MSCHAPV2"), 8985 (1, "eap_peer_tls_encrypt;eap_ttls_encrypt_response;eap_ttls_process_decrypted", 8986 "user", "autheap=MSCHAPV2"), 8987 (1, "eap_ttls_fake_identity_request", 8988 "user", "autheap=MSCHAPV2"), 8989 (1, "eap_msg_alloc;eap_tls_process_output", 8990 "user", "autheap=MSCHAPV2"), 8991 (1, "eap_msg_alloc;eap_peer_tls_build_ack", 8992 "user", "autheap=MSCHAPV2"), 8993 (1, "eap_peer_tls_phase2_nak;eap_ttls_phase2_request_eap_method", 8994 "cert user", "autheap=MSCHAPV2")] 8995 tls = dev[0].request("GET tls_library") 8996 if tls.startswith("internal"): 8997 tests += [(1, "tlsv1_client_decrypt;eap_peer_tls_decrypt", 8998 "user", "autheap=MSCHAPV2")] 8999 else: 9000 tests += [(1, "tls_connection_decrypt;eap_peer_tls_decrypt", 9001 "user", "autheap=MSCHAPV2")] 9002 for count, func, identity, phase2 in tests: 9003 with alloc_fail(dev[0], count, func): 9004 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 9005 eap="TTLS", anonymous_identity="ttls", 9006 identity=identity, password="password", 9007 ca_cert="auth_serv/ca.pem", phase2=phase2, 9008 erp="1", wait_connect=False) 9009 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 9010 timeout=15) 9011 if ev is None: 9012 raise Exception("Timeout on EAP start") 9013 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL", 9014 note="Allocation failure not triggered for: %d:%s" % (count, func)) 9015 dev[0].request("REMOVE_NETWORK all") 9016 dev[0].wait_disconnected() 9017 9018 tests = [(1, "os_get_random;eap_ttls_phase2_request_mschapv2"), 9019 (1, "mschapv2_derive_response;eap_ttls_phase2_request_mschapv2")] 9020 for count, func in tests: 9021 with fail_test(dev[0], count, func): 9022 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 9023 eap="TTLS", anonymous_identity="ttls", 9024 identity="DOMAIN\mschapv2 user", password="password", 9025 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2", 9026 erp="1", wait_connect=False) 9027 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 9028 timeout=15) 9029 if ev is None: 9030 raise Exception("Timeout on EAP start") 9031 wait_fail_trigger(dev[0], "GET_FAIL", 9032 note="Test failure not triggered for: %d:%s" % (count, func)) 9033 dev[0].request("REMOVE_NETWORK all") 9034 dev[0].wait_disconnected() 9035 9036 tests = [(1, "nt_challenge_response;eap_ttls_phase2_request_mschap")] 9037 for count, func in tests: 9038 with fail_test(dev[0], count, func): 9039 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 9040 eap="TTLS", anonymous_identity="ttls", 9041 identity="mschap user", password="password", 9042 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAP", 9043 erp="1", wait_connect=False) 9044 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 9045 timeout=15) 9046 if ev is None: 9047 raise Exception("Timeout on EAP start") 9048 wait_fail_trigger(dev[0], "GET_FAIL", 9049 note="Test failure not triggered for: %d:%s" % (count, func)) 9050 dev[0].request("REMOVE_NETWORK all") 9051 dev[0].wait_disconnected() 9052 9053def test_eap_proto_expanded(dev, apdev): 9054 """EAP protocol tests with expanded header""" 9055 global eap_proto_expanded_test_done 9056 eap_proto_expanded_test_done = False 9057 9058 def expanded_handler(ctx, req): 9059 logger.info("expanded_handler - RX " + binascii.hexlify(req).decode()) 9060 if 'num' not in ctx: 9061 ctx['num'] = 0 9062 ctx['num'] += 1 9063 if 'id' not in ctx: 9064 ctx['id'] = 1 9065 ctx['id'] = (ctx['id'] + 1) % 256 9066 idx = 0 9067 9068 idx += 1 9069 if ctx['num'] == idx: 9070 logger.info("Test: MD5 challenge in expanded header") 9071 return struct.pack(">BBHB3BLBBB", EAP_CODE_REQUEST, ctx['id'], 9072 4 + 1 + 3 + 4 + 3, 9073 EAP_TYPE_EXPANDED, 0, 0, 0, EAP_TYPE_MD5, 9074 1, 0xaa, ord('n')) 9075 idx += 1 9076 if ctx['num'] == idx: 9077 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9078 9079 idx += 1 9080 if ctx['num'] == idx: 9081 logger.info("Test: Invalid expanded EAP length") 9082 return struct.pack(">BBHB3BH", EAP_CODE_REQUEST, ctx['id'], 9083 4 + 1 + 3 + 2, 9084 EAP_TYPE_EXPANDED, 0, 0, 0, EAP_TYPE_MD5) 9085 idx += 1 9086 if ctx['num'] == idx: 9087 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9088 9089 idx += 1 9090 if ctx['num'] == idx: 9091 logger.info("Test: Invalid expanded frame type") 9092 return struct.pack(">BBHB3BL", EAP_CODE_REQUEST, ctx['id'], 9093 4 + 1 + 3 + 4, 9094 EAP_TYPE_EXPANDED, 0, 0, 1, EAP_TYPE_MD5) 9095 idx += 1 9096 if ctx['num'] == idx: 9097 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9098 9099 idx += 1 9100 if ctx['num'] == idx: 9101 logger.info("Test: MSCHAPv2 Challenge") 9102 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'], 9103 4 + 1 + 4 + 1 + 16 + 6, 9104 EAP_TYPE_MSCHAPV2, 9105 1, 0, 4 + 1 + 16 + 6, 16) + 16*b'A' + b'foobar' 9106 idx += 1 9107 if ctx['num'] == idx: 9108 logger.info("Test: Invalid expanded frame type") 9109 return struct.pack(">BBHB3BL", EAP_CODE_REQUEST, ctx['id'], 9110 4 + 1 + 3 + 4, 9111 EAP_TYPE_EXPANDED, 0, 0, 1, EAP_TYPE_MSCHAPV2) 9112 9113 logger.info("No more test responses available - test case completed") 9114 global eap_proto_expanded_test_done 9115 eap_proto_expanded_test_done = True 9116 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9117 9118 srv = start_radius_server(expanded_handler) 9119 9120 try: 9121 hapd = start_ap(apdev[0]) 9122 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 9123 9124 i = 0 9125 while not eap_proto_expanded_test_done: 9126 i += 1 9127 logger.info("Running connection iteration %d" % i) 9128 if i == 4: 9129 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 9130 eap="MSCHAPV2", identity="user", 9131 password="password", 9132 wait_connect=False) 9133 else: 9134 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 9135 eap="MD5", identity="user", password="password", 9136 wait_connect=False) 9137 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5) 9138 if ev is None: 9139 raise Exception("Timeout on EAP start") 9140 if i in [1]: 9141 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5) 9142 if ev is None: 9143 raise Exception("Timeout on EAP method start") 9144 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5) 9145 if ev is None: 9146 raise Exception("Timeout on EAP failure") 9147 elif i in [2, 3]: 9148 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], 9149 timeout=5) 9150 if ev is None: 9151 raise Exception("Timeout on EAP proposed method") 9152 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5) 9153 if ev is None: 9154 raise Exception("Timeout on EAP failure") 9155 else: 9156 time.sleep(0.1) 9157 dev[0].request("REMOVE_NETWORK all") 9158 dev[0].wait_disconnected(timeout=1) 9159 dev[0].dump_monitor() 9160 finally: 9161 stop_radius_server(srv) 9162 9163def test_eap_proto_tls(dev, apdev): 9164 """EAP-TLS protocol tests""" 9165 check_eap_capa(dev[0], "TLS") 9166 global eap_proto_tls_test_done, eap_proto_tls_test_wait 9167 eap_proto_tls_test_done = False 9168 eap_proto_tls_test_wait = False 9169 9170 def tls_handler(ctx, req): 9171 logger.info("tls_handler - RX " + binascii.hexlify(req).decode()) 9172 if 'num' not in ctx: 9173 ctx['num'] = 0 9174 ctx['num'] += 1 9175 if 'id' not in ctx: 9176 ctx['id'] = 1 9177 ctx['id'] = (ctx['id'] + 1) % 256 9178 idx = 0 9179 9180 global eap_proto_tls_test_wait 9181 9182 idx += 1 9183 if ctx['num'] == idx: 9184 logger.info("Test: Too much payload in TLS/Start: TLS Message Length (0 bytes) smaller than this fragment (1 bytes)") 9185 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'], 9186 4 + 1 + 1 + 4 + 1, 9187 EAP_TYPE_TLS, 0xa0, 0, 1) 9188 9189 idx += 1 9190 if ctx['num'] == idx: 9191 logger.info("Test: Fragmented TLS/Start") 9192 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'], 9193 4 + 1 + 1 + 4 + 1, 9194 EAP_TYPE_TLS, 0xe0, 2, 1) 9195 idx += 1 9196 if ctx['num'] == idx: 9197 logger.info("Test: Too long fragment of TLS/Start: Invalid reassembly state: tls_in_left=2 tls_in_len=0 in_len=0") 9198 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 9199 4 + 1 + 1 + 2, 9200 EAP_TYPE_TLS, 0x00, 2, 3) 9201 idx += 1 9202 if ctx['num'] == idx: 9203 logger.info("Test: EAP-Failure") 9204 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9205 9206 idx += 1 9207 if ctx['num'] == idx: 9208 logger.info("Test: TLS/Start") 9209 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9210 4 + 1 + 1, 9211 EAP_TYPE_TLS, 0x20) 9212 idx += 1 9213 if ctx['num'] == idx: 9214 logger.info("Test: Fragmented TLS message") 9215 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'], 9216 4 + 1 + 1 + 4 + 1, 9217 EAP_TYPE_TLS, 0xc0, 2, 1) 9218 idx += 1 9219 if ctx['num'] == idx: 9220 logger.info("Test: Invalid TLS message: no Flags octet included + workaround") 9221 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 9222 4 + 1, 9223 EAP_TYPE_TLS) 9224 idx += 1 9225 if ctx['num'] == idx: 9226 logger.info("Test: Too long fragment of TLS message: more data than TLS message length indicated") 9227 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 9228 4 + 1 + 1 + 2, 9229 EAP_TYPE_TLS, 0x00, 2, 3) 9230 idx += 1 9231 if ctx['num'] == idx: 9232 logger.info("Test: EAP-Failure") 9233 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9234 9235 idx += 1 9236 if ctx['num'] == idx: 9237 logger.info("Test: Fragmented TLS/Start and truncated Message Length field") 9238 return struct.pack(">BBHBB3B", EAP_CODE_REQUEST, ctx['id'], 9239 4 + 1 + 1 + 3, 9240 EAP_TYPE_TLS, 0xe0, 1, 2, 3) 9241 9242 idx += 1 9243 if ctx['num'] == idx: 9244 logger.info("Test: TLS/Start") 9245 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9246 4 + 1 + 1, 9247 EAP_TYPE_TLS, 0x20) 9248 idx += 1 9249 if ctx['num'] == idx: 9250 logger.info("Test: Fragmented TLS message") 9251 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'], 9252 4 + 1 + 1 + 4 + 1, 9253 EAP_TYPE_TLS, 0xc0, 2, 1) 9254 idx += 1 9255 if ctx['num'] == idx: 9256 logger.info("Test: Invalid TLS message: no Flags octet included + workaround disabled") 9257 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 9258 4 + 1, 9259 EAP_TYPE_TLS) 9260 9261 idx += 1 9262 if ctx['num'] == idx: 9263 logger.info("Test: TLS/Start") 9264 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9265 4 + 1 + 1, 9266 EAP_TYPE_TLS, 0x20) 9267 idx += 1 9268 if ctx['num'] == idx: 9269 logger.info("Test: Fragmented TLS message (long; first)") 9270 payload = 1450*b'A' 9271 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'], 9272 4 + 1 + 1 + 4 + len(payload), 9273 EAP_TYPE_TLS, 0xc0, 65536) + payload 9274 # "Too long TLS fragment (size over 64 kB)" on the last one 9275 for i in range(44): 9276 idx += 1 9277 if ctx['num'] == idx: 9278 logger.info("Test: Fragmented TLS message (long; cont %d)" % i) 9279 eap_proto_tls_test_wait = True 9280 payload = 1470*b'A' 9281 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9282 4 + 1 + 1 + len(payload), 9283 EAP_TYPE_TLS, 0x40) + payload 9284 eap_proto_tls_test_wait = False 9285 idx += 1 9286 if ctx['num'] == idx: 9287 logger.info("Test: EAP-Failure") 9288 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9289 9290 idx += 1 9291 if ctx['num'] == idx: 9292 logger.info("Test: TLS/Start") 9293 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9294 4 + 1 + 1, 9295 EAP_TYPE_TLS, 0x20) 9296 idx += 1 9297 if ctx['num'] == idx: 9298 logger.info("Test: Non-ACK to more-fragment message") 9299 return struct.pack(">BBHBBB", EAP_CODE_REQUEST, ctx['id'], 9300 4 + 1 + 1 + 1, 9301 EAP_TYPE_TLS, 0x00, 255) 9302 idx += 1 9303 if ctx['num'] == idx: 9304 logger.info("Test: EAP-Failure") 9305 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9306 9307 logger.info("No more test responses available - test case completed") 9308 global eap_proto_tls_test_done 9309 eap_proto_tls_test_done = True 9310 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9311 9312 srv = start_radius_server(tls_handler) 9313 9314 try: 9315 hapd = start_ap(apdev[0]) 9316 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 9317 9318 i = 0 9319 while not eap_proto_tls_test_done: 9320 i += 1 9321 logger.info("Running connection iteration %d" % i) 9322 workaround = "0" if i == 6 else "1" 9323 fragment_size = "100" if i == 8 else "1400" 9324 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 9325 eap="TLS", identity="tls user", 9326 ca_cert="auth_serv/ca.pem", 9327 client_cert="auth_serv/user.pem", 9328 private_key="auth_serv/user.key", 9329 eap_workaround=workaround, 9330 fragment_size=fragment_size, 9331 wait_connect=False) 9332 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5) 9333 if ev is None: 9334 raise Exception("Timeout on EAP start") 9335 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD", 9336 "CTRL-EVENT-EAP-STATUS"], timeout=5) 9337 if ev is None: 9338 raise Exception("Timeout on EAP method start") 9339 time.sleep(0.1) 9340 start = os.times()[4] 9341 while eap_proto_tls_test_wait: 9342 now = os.times()[4] 9343 if now - start > 10: 9344 break 9345 time.sleep(0.1) 9346 dev[0].request("REMOVE_NETWORK all") 9347 dev[0].wait_disconnected(timeout=1) 9348 dev[0].dump_monitor() 9349 finally: 9350 stop_radius_server(srv) 9351 9352def test_eap_proto_tnc(dev, apdev): 9353 """EAP-TNC protocol tests""" 9354 check_eap_capa(dev[0], "TNC") 9355 global eap_proto_tnc_test_done 9356 eap_proto_tnc_test_done = False 9357 9358 def tnc_handler(ctx, req): 9359 logger.info("tnc_handler - RX " + binascii.hexlify(req).decode()) 9360 if 'num' not in ctx: 9361 ctx['num'] = 0 9362 ctx['num'] += 1 9363 if 'id' not in ctx: 9364 ctx['id'] = 1 9365 ctx['id'] = (ctx['id'] + 1) % 256 9366 idx = 0 9367 9368 idx += 1 9369 if ctx['num'] == idx: 9370 logger.info("Test: TNC start with unsupported version") 9371 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9372 4 + 1 + 1, 9373 EAP_TYPE_TNC, 0x20) 9374 9375 idx += 1 9376 if ctx['num'] == idx: 9377 logger.info("Test: TNC without Flags field") 9378 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 9379 4 + 1, 9380 EAP_TYPE_TNC) 9381 9382 idx += 1 9383 if ctx['num'] == idx: 9384 logger.info("Test: Message underflow due to missing Message Length") 9385 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9386 4 + 1 + 1, 9387 EAP_TYPE_TNC, 0xa1) 9388 9389 idx += 1 9390 if ctx['num'] == idx: 9391 logger.info("Test: Invalid Message Length") 9392 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'], 9393 4 + 1 + 1 + 4 + 1, 9394 EAP_TYPE_TNC, 0xa1, 0, 0) 9395 9396 idx += 1 9397 if ctx['num'] == idx: 9398 logger.info("Test: Invalid Message Length") 9399 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'], 9400 4 + 1 + 1 + 4, 9401 EAP_TYPE_TNC, 0xe1, 75001) 9402 9403 idx += 1 9404 if ctx['num'] == idx: 9405 logger.info("Test: Start with Message Length") 9406 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'], 9407 4 + 1 + 1 + 4, 9408 EAP_TYPE_TNC, 0xa1, 1) 9409 idx += 1 9410 if ctx['num'] == idx: 9411 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9412 9413 idx += 1 9414 if ctx['num'] == idx: 9415 logger.info("Test: Server used start flag again") 9416 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9417 4 + 1 + 1, 9418 EAP_TYPE_TNC, 0x21) 9419 idx += 1 9420 if ctx['num'] == idx: 9421 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9422 4 + 1 + 1, 9423 EAP_TYPE_TNC, 0x21) 9424 9425 idx += 1 9426 if ctx['num'] == idx: 9427 logger.info("Test: Fragmentation and unexpected payload in ack") 9428 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9429 4 + 1 + 1, 9430 EAP_TYPE_TNC, 0x21) 9431 idx += 1 9432 if ctx['num'] == idx: 9433 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9434 4 + 1 + 1, 9435 EAP_TYPE_TNC, 0x01) 9436 idx += 1 9437 if ctx['num'] == idx: 9438 return struct.pack(">BBHBBB", EAP_CODE_REQUEST, ctx['id'], 9439 4 + 1 + 1 + 1, 9440 EAP_TYPE_TNC, 0x01, 0) 9441 9442 idx += 1 9443 if ctx['num'] == idx: 9444 logger.info("Test: Server fragmenting and fragment overflow") 9445 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'], 9446 4 + 1 + 1 + 4 + 1, 9447 EAP_TYPE_TNC, 0xe1, 2, 1) 9448 idx += 1 9449 if ctx['num'] == idx: 9450 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'], 9451 4 + 1 + 1 + 2, 9452 EAP_TYPE_TNC, 0x01, 2, 3) 9453 9454 idx += 1 9455 if ctx['num'] == idx: 9456 logger.info("Test: Server fragmenting and no message length in a fragment") 9457 return struct.pack(">BBHBBB", EAP_CODE_REQUEST, ctx['id'], 9458 4 + 1 + 1 + 1, 9459 EAP_TYPE_TNC, 0x61, 2) 9460 9461 idx += 1 9462 if ctx['num'] == idx: 9463 logger.info("Test: TNC start followed by invalid TNCCS-Batch") 9464 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9465 4 + 1 + 1, 9466 EAP_TYPE_TNC, 0x21) 9467 idx += 1 9468 if ctx['num'] == idx: 9469 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode()) 9470 resp = b"FOO" 9471 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9472 4 + 1 + 1 + len(resp), 9473 EAP_TYPE_TNC, 0x01) + resp 9474 9475 idx += 1 9476 if ctx['num'] == idx: 9477 logger.info("Test: TNC start followed by invalid TNCCS-Batch (2)") 9478 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9479 4 + 1 + 1, 9480 EAP_TYPE_TNC, 0x21) 9481 idx += 1 9482 if ctx['num'] == idx: 9483 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode()) 9484 resp = b"</TNCCS-Batch><TNCCS-Batch>" 9485 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9486 4 + 1 + 1 + len(resp), 9487 EAP_TYPE_TNC, 0x01) + resp 9488 9489 idx += 1 9490 if ctx['num'] == idx: 9491 logger.info("Test: TNCCS-Batch missing BatchId attribute") 9492 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9493 4 + 1 + 1, 9494 EAP_TYPE_TNC, 0x21) 9495 idx += 1 9496 if ctx['num'] == idx: 9497 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode()) 9498 resp = b"<TNCCS-Batch foo=3></TNCCS-Batch>" 9499 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9500 4 + 1 + 1 + len(resp), 9501 EAP_TYPE_TNC, 0x01) + resp 9502 9503 idx += 1 9504 if ctx['num'] == idx: 9505 logger.info("Test: Unexpected IF-TNCCS BatchId") 9506 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9507 4 + 1 + 1, 9508 EAP_TYPE_TNC, 0x21) 9509 idx += 1 9510 if ctx['num'] == idx: 9511 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode()) 9512 resp = b"<TNCCS-Batch BatchId=123456789></TNCCS-Batch>" 9513 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9514 4 + 1 + 1 + len(resp), 9515 EAP_TYPE_TNC, 0x01) + resp 9516 9517 idx += 1 9518 if ctx['num'] == idx: 9519 logger.info("Test: Missing IMC-IMV-Message and TNCC-TNCS-Message end tags") 9520 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9521 4 + 1 + 1, 9522 EAP_TYPE_TNC, 0x21) 9523 idx += 1 9524 if ctx['num'] == idx: 9525 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode()) 9526 resp = b"<TNCCS-Batch BatchId=2><IMC-IMV-Message><TNCC-TNCS-Message></TNCCS-Batch>" 9527 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9528 4 + 1 + 1 + len(resp), 9529 EAP_TYPE_TNC, 0x01) + resp 9530 idx += 1 9531 if ctx['num'] == idx: 9532 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9533 9534 idx += 1 9535 if ctx['num'] == idx: 9536 logger.info("Test: Missing IMC-IMV-Message and TNCC-TNCS-Message Type") 9537 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9538 4 + 1 + 1, 9539 EAP_TYPE_TNC, 0x21) 9540 idx += 1 9541 if ctx['num'] == idx: 9542 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode()) 9543 resp = b"<TNCCS-Batch BatchId=2><IMC-IMV-Message></IMC-IMV-Message><TNCC-TNCS-Message></TNCC-TNCS-Message></TNCCS-Batch>" 9544 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9545 4 + 1 + 1 + len(resp), 9546 EAP_TYPE_TNC, 0x01) + resp 9547 idx += 1 9548 if ctx['num'] == idx: 9549 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9550 9551 idx += 1 9552 if ctx['num'] == idx: 9553 logger.info("Test: Missing TNCC-TNCS-Message XML end tag") 9554 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9555 4 + 1 + 1, 9556 EAP_TYPE_TNC, 0x21) 9557 idx += 1 9558 if ctx['num'] == idx: 9559 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode()) 9560 resp = b"<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type><XML></TNCC-TNCS-Message></TNCCS-Batch>" 9561 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9562 4 + 1 + 1 + len(resp), 9563 EAP_TYPE_TNC, 0x01) + resp 9564 idx += 1 9565 if ctx['num'] == idx: 9566 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9567 9568 idx += 1 9569 if ctx['num'] == idx: 9570 logger.info("Test: Missing TNCC-TNCS-Message Base64 start tag") 9571 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9572 4 + 1 + 1, 9573 EAP_TYPE_TNC, 0x21) 9574 idx += 1 9575 if ctx['num'] == idx: 9576 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode()) 9577 resp = b"<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type></TNCC-TNCS-Message></TNCCS-Batch>" 9578 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9579 4 + 1 + 1 + len(resp), 9580 EAP_TYPE_TNC, 0x01) + resp 9581 idx += 1 9582 if ctx['num'] == idx: 9583 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9584 9585 idx += 1 9586 if ctx['num'] == idx: 9587 logger.info("Test: Missing TNCC-TNCS-Message Base64 end tag") 9588 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9589 4 + 1 + 1, 9590 EAP_TYPE_TNC, 0x21) 9591 idx += 1 9592 if ctx['num'] == idx: 9593 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode()) 9594 resp = b"<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type><Base64>abc</TNCC-TNCS-Message></TNCCS-Batch>" 9595 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9596 4 + 1 + 1 + len(resp), 9597 EAP_TYPE_TNC, 0x01) + resp 9598 idx += 1 9599 if ctx['num'] == idx: 9600 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9601 9602 idx += 1 9603 if ctx['num'] == idx: 9604 logger.info("Test: TNCC-TNCS-Message Base64 message") 9605 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9606 4 + 1 + 1, 9607 EAP_TYPE_TNC, 0x21) 9608 idx += 1 9609 if ctx['num'] == idx: 9610 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode()) 9611 resp = b"<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type><Base64>aGVsbG8=</Base64></TNCC-TNCS-Message></TNCCS-Batch>" 9612 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9613 4 + 1 + 1 + len(resp), 9614 EAP_TYPE_TNC, 0x01) + resp 9615 idx += 1 9616 if ctx['num'] == idx: 9617 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9618 9619 idx += 1 9620 if ctx['num'] == idx: 9621 logger.info("Test: Invalid TNCC-TNCS-Message XML message") 9622 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9623 4 + 1 + 1, 9624 EAP_TYPE_TNC, 0x21) 9625 idx += 1 9626 if ctx['num'] == idx: 9627 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode()) 9628 resp = b"<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type><XML>hello</XML></TNCC-TNCS-Message></TNCCS-Batch>" 9629 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9630 4 + 1 + 1 + len(resp), 9631 EAP_TYPE_TNC, 0x01) + resp 9632 idx += 1 9633 if ctx['num'] == idx: 9634 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9635 9636 idx += 1 9637 if ctx['num'] == idx: 9638 logger.info("Test: Missing TNCCS-Recommendation type") 9639 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9640 4 + 1 + 1, 9641 EAP_TYPE_TNC, 0x21) 9642 idx += 1 9643 if ctx['num'] == idx: 9644 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode()) 9645 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>' 9646 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9647 4 + 1 + 1 + len(resp), 9648 EAP_TYPE_TNC, 0x01) + resp 9649 idx += 1 9650 if ctx['num'] == idx: 9651 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9652 9653 idx += 1 9654 if ctx['num'] == idx: 9655 logger.info("Test: TNCCS-Recommendation type=none") 9656 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9657 4 + 1 + 1, 9658 EAP_TYPE_TNC, 0x21) 9659 idx += 1 9660 if ctx['num'] == idx: 9661 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode()) 9662 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>' 9663 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9664 4 + 1 + 1 + len(resp), 9665 EAP_TYPE_TNC, 0x01) + resp 9666 idx += 1 9667 if ctx['num'] == idx: 9668 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9669 9670 idx += 1 9671 if ctx['num'] == idx: 9672 logger.info("Test: TNCCS-Recommendation type=isolate") 9673 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9674 4 + 1 + 1, 9675 EAP_TYPE_TNC, 0x21) 9676 idx += 1 9677 if ctx['num'] == idx: 9678 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode()) 9679 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>' 9680 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 9681 4 + 1 + 1 + len(resp), 9682 EAP_TYPE_TNC, 0x01) + resp 9683 idx += 1 9684 if ctx['num'] == idx: 9685 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9686 9687 logger.info("No more test responses available - test case completed") 9688 global eap_proto_tnc_test_done 9689 eap_proto_tnc_test_done = True 9690 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9691 9692 srv = start_radius_server(tnc_handler) 9693 9694 try: 9695 hapd = start_ap(apdev[0]) 9696 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 9697 9698 i = 0 9699 while not eap_proto_tnc_test_done: 9700 i += 1 9701 logger.info("Running connection iteration %d" % i) 9702 frag = 1400 9703 if i == 8: 9704 frag = 150 9705 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 9706 eap="TNC", identity="tnc", fragment_size=str(frag), 9707 wait_connect=False) 9708 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5) 9709 if ev is None: 9710 raise Exception("Timeout on EAP start") 9711 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD", 9712 "CTRL-EVENT-EAP-STATUS"], timeout=5) 9713 if ev is None: 9714 raise Exception("Timeout on EAP method start") 9715 time.sleep(0.1) 9716 dev[0].request("REMOVE_NETWORK all") 9717 dev[0].wait_disconnected(timeout=1) 9718 dev[0].dump_monitor() 9719 finally: 9720 stop_radius_server(srv) 9721 9722def test_eap_canned_success_after_identity(dev, apdev): 9723 """EAP protocol tests for canned EAP-Success after identity""" 9724 check_eap_capa(dev[0], "MD5") 9725 def eap_canned_success_handler(ctx, req): 9726 logger.info("eap_canned_success_handler - RX " + binascii.hexlify(req).decode()) 9727 if 'num' not in ctx: 9728 ctx['num'] = 0 9729 ctx['num'] = ctx['num'] + 1 9730 if 'id' not in ctx: 9731 ctx['id'] = 1 9732 ctx['id'] = (ctx['id'] + 1) % 256 9733 idx = 0 9734 9735 idx += 1 9736 if ctx['num'] == idx: 9737 logger.info("Test: EAP-Success") 9738 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4) 9739 9740 idx += 1 9741 if ctx['num'] == idx: 9742 logger.info("Test: EAP-Success") 9743 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4) 9744 9745 return None 9746 9747 srv = start_radius_server(eap_canned_success_handler) 9748 9749 try: 9750 hapd = start_ap(apdev[0]) 9751 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 9752 9753 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 9754 phase1="allow_canned_success=1", 9755 eap="MD5", identity="user", password="password", 9756 wait_connect=False) 9757 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15) 9758 if ev is None: 9759 raise Exception("Timeout on EAP success") 9760 dev[0].request("REMOVE_NETWORK all") 9761 dev[0].wait_disconnected() 9762 9763 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 9764 eap="MD5", identity="user", password="password", 9765 wait_connect=False) 9766 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5) 9767 if ev is None: 9768 raise Exception("Timeout on EAP start") 9769 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=0.1) 9770 if ev is not None: 9771 raise Exception("Unexpected EAP success") 9772 dev[0].request("REMOVE_NETWORK all") 9773 dev[0].wait_disconnected() 9774 finally: 9775 stop_radius_server(srv) 9776 9777def test_eap_proto_wsc(dev, apdev): 9778 """EAP-WSC protocol tests""" 9779 global eap_proto_wsc_test_done, eap_proto_wsc_wait_failure 9780 eap_proto_wsc_test_done = False 9781 9782 def wsc_handler(ctx, req): 9783 logger.info("wsc_handler - RX " + binascii.hexlify(req).decode()) 9784 if 'num' not in ctx: 9785 ctx['num'] = 0 9786 ctx['num'] += 1 9787 if 'id' not in ctx: 9788 ctx['id'] = 1 9789 ctx['id'] = (ctx['id'] + 1) % 256 9790 idx = 0 9791 9792 global eap_proto_wsc_wait_failure 9793 eap_proto_wsc_wait_failure = False 9794 9795 idx += 1 9796 if ctx['num'] == idx: 9797 logger.info("Test: Missing Flags field") 9798 return struct.pack(">BBHB3BLB", EAP_CODE_REQUEST, ctx['id'], 9799 4 + 1 + 3 + 4 + 1, 9800 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1, 9801 1) 9802 9803 idx += 1 9804 if ctx['num'] == idx: 9805 logger.info("Test: Message underflow (missing Message Length field)") 9806 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'], 9807 4 + 1 + 3 + 4 + 2, 9808 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1, 9809 1, 0x02) 9810 9811 idx += 1 9812 if ctx['num'] == idx: 9813 logger.info("Test: Invalid Message Length (> 50000)") 9814 return struct.pack(">BBHB3BLBBH", EAP_CODE_REQUEST, ctx['id'], 9815 4 + 1 + 3 + 4 + 4, 9816 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1, 9817 1, 0x02, 65535) 9818 9819 idx += 1 9820 if ctx['num'] == idx: 9821 logger.info("Test: Invalid Message Length (< current payload)") 9822 return struct.pack(">BBHB3BLBBHB", EAP_CODE_REQUEST, ctx['id'], 9823 4 + 1 + 3 + 4 + 5, 9824 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1, 9825 1, 0x02, 0, 0xff) 9826 9827 idx += 1 9828 if ctx['num'] == idx: 9829 logger.info("Test: Unexpected Op-Code 5 in WAIT_START state") 9830 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'], 9831 4 + 1 + 3 + 4 + 2, 9832 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1, 9833 5, 0x00) 9834 9835 idx += 1 9836 if ctx['num'] == idx: 9837 logger.info("Test: Valid WSC Start to start the sequence") 9838 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'], 9839 4 + 1 + 3 + 4 + 2, 9840 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1, 9841 1, 0x00) 9842 idx += 1 9843 if ctx['num'] == idx: 9844 logger.info("Test: No Message Length field in a fragmented packet") 9845 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'], 9846 4 + 1 + 3 + 4 + 2, 9847 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1, 9848 4, 0x01) 9849 9850 idx += 1 9851 if ctx['num'] == idx: 9852 logger.info("Test: Valid WSC Start to start the sequence") 9853 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'], 9854 4 + 1 + 3 + 4 + 2, 9855 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1, 9856 1, 0x00) 9857 idx += 1 9858 if ctx['num'] == idx: 9859 logger.info("Test: Valid first fragmented packet") 9860 return struct.pack(">BBHB3BLBBHB", EAP_CODE_REQUEST, ctx['id'], 9861 4 + 1 + 3 + 4 + 5, 9862 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1, 9863 4, 0x03, 10, 1) 9864 idx += 1 9865 if ctx['num'] == idx: 9866 logger.info("Test: Unexpected Op-Code 5 in fragment (expected 4)") 9867 return struct.pack(">BBHB3BLBBB", EAP_CODE_REQUEST, ctx['id'], 9868 4 + 1 + 3 + 4 + 3, 9869 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1, 9870 5, 0x01, 2) 9871 9872 idx += 1 9873 if ctx['num'] == idx: 9874 logger.info("Test: Valid WSC Start to start the sequence") 9875 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'], 9876 4 + 1 + 3 + 4 + 2, 9877 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1, 9878 1, 0x00) 9879 idx += 1 9880 if ctx['num'] == idx: 9881 logger.info("Test: Valid first fragmented packet") 9882 return struct.pack(">BBHB3BLBBHB", EAP_CODE_REQUEST, ctx['id'], 9883 4 + 1 + 3 + 4 + 5, 9884 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1, 9885 4, 0x03, 2, 1) 9886 idx += 1 9887 if ctx['num'] == idx: 9888 logger.info("Test: Fragment overflow") 9889 return struct.pack(">BBHB3BLBBBB", EAP_CODE_REQUEST, ctx['id'], 9890 4 + 1 + 3 + 4 + 4, 9891 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1, 9892 4, 0x01, 2, 3) 9893 9894 idx += 1 9895 if ctx['num'] == idx: 9896 logger.info("Test: Valid WSC Start to start the sequence") 9897 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'], 9898 4 + 1 + 3 + 4 + 2, 9899 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1, 9900 1, 0x00) 9901 idx += 1 9902 if ctx['num'] == idx: 9903 logger.info("Test: Unexpected Op-Code 5 in WAIT_FRAG_ACK state") 9904 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'], 9905 4 + 1 + 3 + 4 + 2, 9906 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1, 9907 5, 0x00) 9908 9909 idx += 1 9910 if ctx['num'] == idx: 9911 logger.info("Test: Valid WSC Start") 9912 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'], 9913 4 + 1 + 3 + 4 + 2, 9914 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1, 9915 1, 0x00) 9916 idx += 1 9917 if ctx['num'] == idx: 9918 logger.info("No more test responses available - test case completed") 9919 global eap_proto_wsc_test_done 9920 eap_proto_wsc_test_done = True 9921 eap_proto_wsc_wait_failure = True 9922 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9923 9924 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 9925 9926 srv = start_radius_server(wsc_handler) 9927 9928 try: 9929 hapd = start_ap(apdev[0]) 9930 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 9931 9932 i = 0 9933 while not eap_proto_wsc_test_done: 9934 i += 1 9935 logger.info("Running connection iteration %d" % i) 9936 fragment_size = 1398 if i != 9 else 50 9937 dev[0].connect("eap-test", key_mgmt="WPA-EAP", eap="WSC", 9938 fragment_size=str(fragment_size), 9939 identity="WFA-SimpleConfig-Enrollee-1-0", 9940 phase1="pin=12345670", 9941 scan_freq="2412", wait_connect=False) 9942 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5) 9943 if ev is None: 9944 raise Exception("Timeout on EAP method start") 9945 if eap_proto_wsc_wait_failure: 9946 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5) 9947 if ev is None: 9948 raise Exception("Timeout on EAP failure") 9949 else: 9950 time.sleep(0.1) 9951 dev[0].request("REMOVE_NETWORK all") 9952 dev[0].wait_disconnected(timeout=1) 9953 dev[0].dump_monitor() 9954 finally: 9955 stop_radius_server(srv) 9956 9957def test_eap_canned_success_before_method(dev, apdev): 9958 """EAP protocol tests for canned EAP-Success before any method""" 9959 params = int_eap_server_params() 9960 hapd = hostapd.add_ap(apdev[0], params) 9961 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 9962 bssid = apdev[0]['bssid'] 9963 hapd.request("SET ext_eapol_frame_io 1") 9964 9965 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412", 9966 phase1="allow_canned_success=1", 9967 eap="MD5", identity="user", password="password", 9968 wait_connect=False) 9969 9970 ev = hapd.wait_event(["EAPOL-TX"], timeout=10) 9971 if ev is None: 9972 raise Exception("Timeout on EAPOL-TX from hostapd") 9973 9974 res = dev[0].request("EAPOL_RX " + bssid + " 0200000403020004") 9975 if "OK" not in res: 9976 raise Exception("EAPOL_RX to wpa_supplicant failed") 9977 9978 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=5) 9979 if ev is None: 9980 raise Exception("Timeout on EAP success") 9981 dev[0].request("REMOVE_NETWORK all") 9982 dev[0].wait_disconnected() 9983 9984def test_eap_canned_failure_before_method(dev, apdev): 9985 """EAP protocol tests for canned EAP-Failure before any method""" 9986 params = int_eap_server_params() 9987 hapd = hostapd.add_ap(apdev[0], params) 9988 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 9989 bssid = apdev[0]['bssid'] 9990 hapd.request("SET ext_eapol_frame_io 1") 9991 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412", 9992 phase1="allow_canned_success=1", 9993 eap="MD5", identity="user", password="password", 9994 wait_connect=False) 9995 9996 ev = hapd.wait_event(["EAPOL-TX"], timeout=10) 9997 if ev is None: 9998 raise Exception("Timeout on EAPOL-TX from hostapd") 9999 10000 res = dev[0].request("EAPOL_RX " + bssid + " 0200000404020004") 10001 if "OK" not in res: 10002 raise Exception("EAPOL_RX to wpa_supplicant failed") 10003 10004 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5) 10005 if ev is None: 10006 raise Exception("Timeout on EAP failure") 10007 dev[0].request("REMOVE_NETWORK all") 10008 dev[0].wait_disconnected() 10009 10010def test_eap_nak_oom(dev, apdev): 10011 """EAP-Nak OOM""" 10012 check_eap_capa(dev[0], "MD5") 10013 params = hostapd.wpa2_eap_params(ssid="eap-test") 10014 hapd = hostapd.add_ap(apdev[0], params) 10015 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 10016 with alloc_fail(dev[0], 1, "eap_msg_alloc;eap_sm_buildNak"): 10017 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 10018 eap="MD5", identity="sake user", password="password", 10019 wait_connect=False) 10020 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 10021 dev[0].request("REMOVE_NETWORK all") 10022 dev[0].wait_disconnected() 10023 10024def test_eap_nak_expanded(dev, apdev): 10025 """EAP-Nak with expanded method""" 10026 check_eap_capa(dev[0], "MD5") 10027 check_eap_capa(dev[0], "VENDOR-TEST") 10028 params = hostapd.wpa2_eap_params(ssid="eap-test") 10029 hapd = hostapd.add_ap(apdev[0], params) 10030 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 10031 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 10032 eap="VENDOR-TEST WSC", 10033 identity="sake user", password="password", 10034 wait_connect=False) 10035 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=10) 10036 if ev is None or "NAK" not in ev: 10037 raise Exception("No NAK event seen") 10038 10039 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10) 10040 if ev is None: 10041 raise Exception("No EAP-Failure seen") 10042 10043 dev[0].request("REMOVE_NETWORK all") 10044 dev[0].wait_disconnected() 10045 10046EAP_TLV_RESULT_TLV = 3 10047EAP_TLV_NAK_TLV = 4 10048EAP_TLV_ERROR_CODE_TLV = 5 10049EAP_TLV_CONNECTION_BINDING_TLV = 6 10050EAP_TLV_VENDOR_SPECIFIC_TLV = 7 10051EAP_TLV_URI_TLV = 8 10052EAP_TLV_EAP_PAYLOAD_TLV = 9 10053EAP_TLV_INTERMEDIATE_RESULT_TLV = 10 10054EAP_TLV_PAC_TLV = 11 10055EAP_TLV_CRYPTO_BINDING_TLV = 12 10056EAP_TLV_CALLING_STATION_ID_TLV = 13 10057EAP_TLV_CALLED_STATION_ID_TLV = 14 10058EAP_TLV_NAS_PORT_TYPE_TLV = 15 10059EAP_TLV_SERVER_IDENTIFIER_TLV = 16 10060EAP_TLV_IDENTITY_TYPE_TLV = 17 10061EAP_TLV_SERVER_TRUSTED_ROOT_TLV = 18 10062EAP_TLV_REQUEST_ACTION_TLV = 19 10063EAP_TLV_PKCS7_TLV = 20 10064 10065EAP_TLV_RESULT_SUCCESS = 1 10066EAP_TLV_RESULT_FAILURE = 2 10067 10068EAP_TLV_TYPE_MANDATORY = 0x8000 10069EAP_TLV_TYPE_MASK = 0x3fff 10070 10071PAC_TYPE_PAC_KEY = 1 10072PAC_TYPE_PAC_OPAQUE = 2 10073PAC_TYPE_CRED_LIFETIME = 3 10074PAC_TYPE_A_ID = 4 10075PAC_TYPE_I_ID = 5 10076PAC_TYPE_A_ID_INFO = 7 10077PAC_TYPE_PAC_ACKNOWLEDGEMENT = 8 10078PAC_TYPE_PAC_INFO = 9 10079PAC_TYPE_PAC_TYPE = 10 10080 10081def eap_fast_start(ctx): 10082 logger.info("Send EAP-FAST/Start") 10083 return struct.pack(">BBHBBHH", EAP_CODE_REQUEST, ctx['id'], 10084 4 + 1 + 1 + 4 + 16, 10085 EAP_TYPE_FAST, 0x21, 4, 16) + 16*b'A' 10086 10087def test_eap_fast_proto(dev, apdev): 10088 """EAP-FAST Phase protocol testing""" 10089 check_eap_capa(dev[0], "FAST") 10090 global eap_fast_proto_ctx 10091 eap_fast_proto_ctx = None 10092 10093 def eap_handler(ctx, req): 10094 logger.info("eap_handler - RX " + binascii.hexlify(req).decode()) 10095 if 'num' not in ctx: 10096 ctx['num'] = 0 10097 ctx['num'] = ctx['num'] + 1 10098 if 'id' not in ctx: 10099 ctx['id'] = 1 10100 ctx['id'] = (ctx['id'] + 1) % 256 10101 idx = 0 10102 10103 global eap_fast_proto_ctx 10104 eap_fast_proto_ctx = ctx 10105 ctx['test_done'] = False 10106 10107 idx += 1 10108 if ctx['num'] == idx: 10109 return eap_fast_start(ctx) 10110 idx += 1 10111 if ctx['num'] == idx: 10112 logger.info("EAP-FAST: TLS processing failed") 10113 data = b'ABCDEFGHIK' 10114 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 10115 4 + 1 + 1 + len(data), 10116 EAP_TYPE_FAST, 0x01) + data 10117 idx += 1 10118 if ctx['num'] == idx: 10119 ctx['test_done'] = True 10120 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 10121 10122 logger.info("Past last test case") 10123 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 10124 10125 srv = start_radius_server(eap_handler) 10126 try: 10127 hapd = start_ap(apdev[0]) 10128 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 10129 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 10130 eap="FAST", anonymous_identity="FAST", 10131 identity="user", password="password", 10132 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2", 10133 phase1="fast_provisioning=1", 10134 pac_file="blob://fast_pac_proto", 10135 wait_connect=False) 10136 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5) 10137 if ev is None: 10138 raise Exception("Could not start EAP-FAST") 10139 ok = False 10140 for i in range(100): 10141 if eap_fast_proto_ctx: 10142 if eap_fast_proto_ctx['test_done']: 10143 ok = True 10144 break 10145 time.sleep(0.05) 10146 dev[0].request("REMOVE_NETWORK all") 10147 dev[0].wait_disconnected() 10148 finally: 10149 stop_radius_server(srv) 10150 10151def run_eap_fast_phase2(dev, test_payload, test_failure=True): 10152 global eap_fast_proto_ctx 10153 eap_fast_proto_ctx = None 10154 10155 def ssl_info_callback(conn, where, ret): 10156 logger.debug("SSL: info where=%d ret=%d" % (where, ret)) 10157 10158 def log_conn_state(conn): 10159 try: 10160 state = conn.state_string() 10161 except AttributeError: 10162 state = conn.get_state_string() 10163 if state: 10164 logger.info("State: " + str(state)) 10165 10166 def process_clienthello(ctx, payload): 10167 logger.info("Process ClientHello") 10168 ctx['sslctx'] = OpenSSL.SSL.Context(OpenSSL.SSL.TLSv1_METHOD) 10169 ctx['sslctx'].set_info_callback(ssl_info_callback) 10170 ctx['sslctx'].load_tmp_dh("auth_serv/dh.conf") 10171 if OpenSSL.SSL.OPENSSL_VERSION_NUMBER >= 0x10100000: 10172 ctx['sslctx'].set_cipher_list("ADH-AES128-SHA:@SECLEVEL=0") 10173 else: 10174 ctx['sslctx'].set_cipher_list("ADH-AES128-SHA") 10175 ctx['conn'] = OpenSSL.SSL.Connection(ctx['sslctx'], None) 10176 ctx['conn'].set_accept_state() 10177 log_conn_state(ctx['conn']) 10178 ctx['conn'].bio_write(payload) 10179 try: 10180 ctx['conn'].do_handshake() 10181 except OpenSSL.SSL.WantReadError: 10182 pass 10183 log_conn_state(ctx['conn']) 10184 data = ctx['conn'].bio_read(4096) 10185 log_conn_state(ctx['conn']) 10186 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 10187 4 + 1 + 1 + len(data), 10188 EAP_TYPE_FAST, 0x01) + data 10189 10190 def process_clientkeyexchange(ctx, payload, appl_data): 10191 logger.info("Process ClientKeyExchange") 10192 log_conn_state(ctx['conn']) 10193 ctx['conn'].bio_write(payload) 10194 try: 10195 ctx['conn'].do_handshake() 10196 except OpenSSL.SSL.WantReadError: 10197 pass 10198 ctx['conn'].send(appl_data) 10199 log_conn_state(ctx['conn']) 10200 data = ctx['conn'].bio_read(4096) 10201 log_conn_state(ctx['conn']) 10202 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'], 10203 4 + 1 + 1 + len(data), 10204 EAP_TYPE_FAST, 0x01) + data 10205 10206 def eap_handler(ctx, req): 10207 logger.info("eap_handler - RX " + binascii.hexlify(req).decode()) 10208 if 'num' not in ctx: 10209 ctx['num'] = 0 10210 ctx['num'] = ctx['num'] + 1 10211 if 'id' not in ctx: 10212 ctx['id'] = 1 10213 ctx['id'] = (ctx['id'] + 1) % 256 10214 idx = 0 10215 10216 global eap_fast_proto_ctx 10217 eap_fast_proto_ctx = ctx 10218 ctx['test_done'] = False 10219 logger.debug("ctx['num']=%d" % ctx['num']) 10220 10221 idx += 1 10222 if ctx['num'] == idx: 10223 return eap_fast_start(ctx) 10224 idx += 1 10225 if ctx['num'] == idx: 10226 return process_clienthello(ctx, req[6:]) 10227 idx += 1 10228 if ctx['num'] == idx: 10229 if not test_failure: 10230 ctx['test_done'] = True 10231 return process_clientkeyexchange(ctx, req[6:], test_payload) 10232 idx += 1 10233 if ctx['num'] == idx: 10234 ctx['test_done'] = True 10235 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 10236 10237 logger.info("Past last test case") 10238 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4) 10239 10240 srv = start_radius_server(eap_handler) 10241 try: 10242 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412", 10243 eap="FAST", anonymous_identity="FAST", 10244 identity="user", password="password", 10245 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2", 10246 phase1="fast_provisioning=1", 10247 pac_file="blob://fast_pac_proto", 10248 wait_connect=False) 10249 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5) 10250 if ev is None: 10251 raise Exception("Could not start EAP-FAST") 10252 dev[0].dump_monitor() 10253 ok = False 10254 for i in range(100): 10255 if eap_fast_proto_ctx: 10256 if eap_fast_proto_ctx['test_done']: 10257 ok = True 10258 break 10259 time.sleep(0.05) 10260 time.sleep(0.1) 10261 dev[0].request("REMOVE_NETWORK all") 10262 dev[0].wait_disconnected() 10263 if not ok: 10264 raise Exception("EAP-FAST TLS exchange did not complete") 10265 for i in range(3): 10266 dev[i].dump_monitor() 10267 finally: 10268 stop_radius_server(srv) 10269 10270def test_eap_fast_proto_phase2(dev, apdev): 10271 """EAP-FAST Phase 2 protocol testing""" 10272 if not openssl_imported: 10273 raise HwsimSkip("OpenSSL python method not available") 10274 check_eap_capa(dev[0], "FAST") 10275 hapd = start_ap(apdev[0]) 10276 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 10277 10278 tests = [("Too short Phase 2 TLV frame (len=3)", 10279 "ABC", 10280 False), 10281 ("EAP-FAST: TLV overflow", 10282 struct.pack(">HHB", 0, 2, 0xff), 10283 False), 10284 ("EAP-FAST: Unknown TLV (optional and mandatory)", 10285 struct.pack(">HHB", 0, 1, 0xff) + 10286 struct.pack(">HHB", EAP_TLV_TYPE_MANDATORY, 1, 0xff), 10287 True), 10288 ("EAP-FAST: More than one EAP-Payload TLV in the message", 10289 struct.pack(">HHBHHB", 10290 EAP_TLV_EAP_PAYLOAD_TLV, 1, 0xff, 10291 EAP_TLV_EAP_PAYLOAD_TLV, 1, 0xff), 10292 True), 10293 ("EAP-FAST: Unknown Result 255 and More than one Result TLV in the message", 10294 struct.pack(">HHHHHH", 10295 EAP_TLV_RESULT_TLV, 2, 0xff, 10296 EAP_TLV_RESULT_TLV, 2, 0xff), 10297 True), 10298 ("EAP-FAST: Too short Result TLV", 10299 struct.pack(">HHB", EAP_TLV_RESULT_TLV, 1, 0xff), 10300 True), 10301 ("EAP-FAST: Unknown Intermediate Result 255 and More than one Intermediate-Result TLV in the message", 10302 struct.pack(">HHHHHH", 10303 EAP_TLV_INTERMEDIATE_RESULT_TLV, 2, 0xff, 10304 EAP_TLV_INTERMEDIATE_RESULT_TLV, 2, 0xff), 10305 True), 10306 ("EAP-FAST: Too short Intermediate-Result TLV", 10307 struct.pack(">HHB", EAP_TLV_INTERMEDIATE_RESULT_TLV, 1, 0xff), 10308 True), 10309 ("EAP-FAST: More than one Crypto-Binding TLV in the message", 10310 struct.pack(">HH", EAP_TLV_CRYPTO_BINDING_TLV, 60) + 60*b'A' + 10311 struct.pack(">HH", EAP_TLV_CRYPTO_BINDING_TLV, 60) + 60*b'A', 10312 True), 10313 ("EAP-FAST: Too short Crypto-Binding TLV", 10314 struct.pack(">HHB", EAP_TLV_CRYPTO_BINDING_TLV, 1, 0xff), 10315 True), 10316 ("EAP-FAST: More than one Request-Action TLV in the message", 10317 struct.pack(">HHBBHHBB", 10318 EAP_TLV_REQUEST_ACTION_TLV, 2, 0xff, 0xff, 10319 EAP_TLV_REQUEST_ACTION_TLV, 2, 0xff, 0xff), 10320 True), 10321 ("EAP-FAST: Too short Request-Action TLV", 10322 struct.pack(">HHB", EAP_TLV_REQUEST_ACTION_TLV, 1, 0xff), 10323 True), 10324 ("EAP-FAST: More than one PAC TLV in the message", 10325 struct.pack(">HHBHHB", 10326 EAP_TLV_PAC_TLV, 1, 0xff, 10327 EAP_TLV_PAC_TLV, 1, 0xff), 10328 True), 10329 ("EAP-FAST: Too short EAP Payload TLV (Len=3)", 10330 struct.pack(">HH3B", 10331 EAP_TLV_EAP_PAYLOAD_TLV, 3, 0, 0, 0), 10332 False), 10333 ("EAP-FAST: Too short Phase 2 request (Len=0)", 10334 struct.pack(">HHBBH", 10335 EAP_TLV_EAP_PAYLOAD_TLV, 4, 10336 EAP_CODE_REQUEST, 0, 0), 10337 False), 10338 ("EAP-FAST: EAP packet overflow in EAP Payload TLV", 10339 struct.pack(">HHBBH", 10340 EAP_TLV_EAP_PAYLOAD_TLV, 4, 10341 EAP_CODE_REQUEST, 0, 4 + 1), 10342 False), 10343 ("EAP-FAST: Unexpected code=0 in Phase 2 EAP header", 10344 struct.pack(">HHBBH", 10345 EAP_TLV_EAP_PAYLOAD_TLV, 4, 10346 0, 0, 0), 10347 False), 10348 ("EAP-FAST: PAC TLV without Result TLV acknowledging success", 10349 struct.pack(">HHB", EAP_TLV_PAC_TLV, 1, 0xff), 10350 True), 10351 ("EAP-FAST: PAC TLV does not include all the required fields", 10352 struct.pack(">HHH", EAP_TLV_RESULT_TLV, 2, 10353 EAP_TLV_RESULT_SUCCESS) + 10354 struct.pack(">HHB", EAP_TLV_PAC_TLV, 1, 0xff), 10355 True), 10356 ("EAP-FAST: Invalid PAC-Key length 0, Ignored unknown PAC type 0, and PAC TLV overrun (type=0 len=2 left=1)", 10357 struct.pack(">HHH", EAP_TLV_RESULT_TLV, 2, 10358 EAP_TLV_RESULT_SUCCESS) + 10359 struct.pack(">HHHHHHHHB", EAP_TLV_PAC_TLV, 4 + 4 + 5, 10360 PAC_TYPE_PAC_KEY, 0, 0, 0, 0, 2, 0), 10361 True), 10362 ("EAP-FAST: PAC-Info does not include all the required fields", 10363 struct.pack(">HHH", EAP_TLV_RESULT_TLV, 2, 10364 EAP_TLV_RESULT_SUCCESS) + 10365 struct.pack(">HHHHHHHH", EAP_TLV_PAC_TLV, 4 + 4 + 4 + 32, 10366 PAC_TYPE_PAC_OPAQUE, 0, 10367 PAC_TYPE_PAC_INFO, 0, 10368 PAC_TYPE_PAC_KEY, 32) + 32*b'A', 10369 True), 10370 ("EAP-FAST: Invalid CRED_LIFETIME length, Ignored unknown PAC-Info type 0, and Invalid PAC-Type length 1", 10371 struct.pack(">HHH", EAP_TLV_RESULT_TLV, 2, 10372 EAP_TLV_RESULT_SUCCESS) + 10373 struct.pack(">HHHHHHHHHHHHBHH", EAP_TLV_PAC_TLV, 4 + 4 + 13 + 4 + 32, 10374 PAC_TYPE_PAC_OPAQUE, 0, 10375 PAC_TYPE_PAC_INFO, 13, PAC_TYPE_CRED_LIFETIME, 0, 10376 0, 0, PAC_TYPE_PAC_TYPE, 1, 0, 10377 PAC_TYPE_PAC_KEY, 32) + 32*b'A', 10378 True), 10379 ("EAP-FAST: Unsupported PAC-Type 0", 10380 struct.pack(">HHH", EAP_TLV_RESULT_TLV, 2, 10381 EAP_TLV_RESULT_SUCCESS) + 10382 struct.pack(">HHHHHHHHHHH", EAP_TLV_PAC_TLV, 4 + 4 + 6 + 4 + 32, 10383 PAC_TYPE_PAC_OPAQUE, 0, 10384 PAC_TYPE_PAC_INFO, 6, PAC_TYPE_PAC_TYPE, 2, 0, 10385 PAC_TYPE_PAC_KEY, 32) + 32*b'A', 10386 True), 10387 ("EAP-FAST: PAC-Info overrun (type=0 len=2 left=1)", 10388 struct.pack(">HHH", EAP_TLV_RESULT_TLV, 2, 10389 EAP_TLV_RESULT_SUCCESS) + 10390 struct.pack(">HHHHHHHHBHH", EAP_TLV_PAC_TLV, 4 + 4 + 5 + 4 + 32, 10391 PAC_TYPE_PAC_OPAQUE, 0, 10392 PAC_TYPE_PAC_INFO, 5, 0, 2, 1, 10393 PAC_TYPE_PAC_KEY, 32) + 32*b'A', 10394 True), 10395 ("EAP-FAST: Valid PAC", 10396 struct.pack(">HHH", EAP_TLV_RESULT_TLV, 2, 10397 EAP_TLV_RESULT_SUCCESS) + 10398 struct.pack(">HHHHHHHHBHHBHH", EAP_TLV_PAC_TLV, 10399 4 + 4 + 10 + 4 + 32, 10400 PAC_TYPE_PAC_OPAQUE, 0, 10401 PAC_TYPE_PAC_INFO, 10, PAC_TYPE_A_ID, 1, 0x41, 10402 PAC_TYPE_A_ID_INFO, 1, 0x42, 10403 PAC_TYPE_PAC_KEY, 32) + 32*b'A', 10404 True), 10405 ("EAP-FAST: Invalid version/subtype in Crypto-Binding TLV", 10406 struct.pack(">HH", EAP_TLV_CRYPTO_BINDING_TLV, 60) + 60*b'A', 10407 True)] 10408 for title, payload, failure in tests: 10409 logger.info("Phase 2 test: " + title) 10410 run_eap_fast_phase2(dev, payload, failure) 10411 10412def test_eap_fast_tlv_nak_oom(dev, apdev): 10413 """EAP-FAST Phase 2 TLV NAK OOM""" 10414 if not openssl_imported: 10415 raise HwsimSkip("OpenSSL python method not available") 10416 check_eap_capa(dev[0], "FAST") 10417 hapd = start_ap(apdev[0]) 10418 dev[0].scan_for_bss(hapd.own_addr(), freq=2412) 10419 10420 with alloc_fail(dev[0], 1, "eap_fast_tlv_nak"): 10421 run_eap_fast_phase2(dev, struct.pack(">HHB", EAP_TLV_TYPE_MANDATORY, 10422 1, 0xff), False) 10423