]> git.ipfire.org Git - thirdparty/hostap.git/blame - tests/hwsim/test_eap_proto.py
tests: EAP-pwd eap_pwd_get_element() local failures
[thirdparty/hostap.git] / tests / hwsim / test_eap_proto.py
CommitLineData
d81731e6 1# EAP protocol tests
e7ac04ce 2# Copyright (c) 2014-2015, Jouni Malinen <j@w1.fi>
d81731e6
JM
3#
4# This software may be distributed under the terms of the BSD license.
5# See README for more details.
6
37211e15
JM
7import binascii
8import hashlib
d81731e6
JM
9import hmac
10import logging
11logger = logging.getLogger()
d4af4d27 12import os
d81731e6
JM
13import select
14import struct
15import threading
16import time
17
18import hostapd
d5482411 19from utils import HwsimSkip, alloc_fail, fail_test, wait_fail_trigger
7843ae44 20from test_ap_eap import check_eap_capa, check_hlr_auc_gw_support, int_eap_server_params
b6f17f2f 21from test_erp import check_erp_capa
d81731e6 22
bccd22f3
JM
23try:
24 import OpenSSL
25 openssl_imported = True
26except ImportError:
27 openssl_imported = False
28
d81731e6
JM
29EAP_CODE_REQUEST = 1
30EAP_CODE_RESPONSE = 2
31EAP_CODE_SUCCESS = 3
32EAP_CODE_FAILURE = 4
b6f17f2f
JM
33EAP_CODE_INITIATE = 5
34EAP_CODE_FINISH = 6
d81731e6
JM
35
36EAP_TYPE_IDENTITY = 1
37EAP_TYPE_NOTIFICATION = 2
38EAP_TYPE_NAK = 3
39EAP_TYPE_MD5 = 4
40EAP_TYPE_OTP = 5
41EAP_TYPE_GTC = 6
42EAP_TYPE_TLS = 13
43EAP_TYPE_LEAP = 17
44EAP_TYPE_SIM = 18
45EAP_TYPE_TTLS = 21
46EAP_TYPE_AKA = 23
47EAP_TYPE_PEAP = 25
48EAP_TYPE_MSCHAPV2 = 26
49EAP_TYPE_TLV = 33
50EAP_TYPE_TNC = 38
51EAP_TYPE_FAST = 43
52EAP_TYPE_PAX = 46
53EAP_TYPE_PSK = 47
54EAP_TYPE_SAKE = 48
55EAP_TYPE_IKEV2 = 49
56EAP_TYPE_AKA_PRIME = 50
57EAP_TYPE_GPSK = 51
58EAP_TYPE_PWD = 52
59EAP_TYPE_EKE = 53
2fd377de 60EAP_TYPE_EXPANDED = 254
d81731e6 61
b6f17f2f
JM
62# Type field in EAP-Initiate and EAP-Finish messages
63EAP_ERP_TYPE_REAUTH_START = 1
64EAP_ERP_TYPE_REAUTH = 2
65
66EAP_ERP_TLV_KEYNAME_NAI = 1
67EAP_ERP_TV_RRK_LIFETIME = 2
68EAP_ERP_TV_RMSK_LIFETIME = 3
69EAP_ERP_TLV_DOMAIN_NAME = 4
70EAP_ERP_TLV_CRYPTOSUITES = 5
71EAP_ERP_TLV_AUTHORIZATION_INDICATION = 6
72EAP_ERP_TLV_CALLED_STATION_ID = 128
73EAP_ERP_TLV_CALLING_STATION_ID = 129
74EAP_ERP_TLV_NAS_IDENTIFIER = 130
75EAP_ERP_TLV_NAS_IP_ADDRESS = 131
76EAP_ERP_TLV_NAS_IPV6_ADDRESS = 132
77
d81731e6
JM
78def run_pyrad_server(srv, t_stop, eap_handler):
79 srv.RunWithStop(t_stop, eap_handler)
80
81def start_radius_server(eap_handler):
82 try:
83 import pyrad.server
84 import pyrad.packet
85 import pyrad.dictionary
86 except ImportError:
81e787b7 87 raise HwsimSkip("No pyrad modules available")
d81731e6
JM
88
89 class TestServer(pyrad.server.Server):
90 def _HandleAuthPacket(self, pkt):
91 pyrad.server.Server._HandleAuthPacket(self, pkt)
55845e19 92 eap = b''
37211e15
JM
93 for p in pkt[79]:
94 eap += p
d81731e6
JM
95 eap_req = self.eap_handler(self.ctx, eap)
96 reply = self.CreateReplyPacket(pkt)
97 if eap_req:
cb0555f7
JM
98 while True:
99 if len(eap_req) > 253:
100 reply.AddAttribute("EAP-Message", eap_req[0:253])
101 eap_req = eap_req[253:]
102 else:
103 reply.AddAttribute("EAP-Message", eap_req)
104 break
18fc8f40
JM
105 else:
106 logger.info("No EAP request available")
d81731e6
JM
107 reply.code = pyrad.packet.AccessChallenge
108
109 hmac_obj = hmac.new(reply.secret)
110 hmac_obj.update(struct.pack("B", reply.code))
111 hmac_obj.update(struct.pack("B", reply.id))
112
113 # reply attributes
55845e19 114 reply.AddAttribute("Message-Authenticator", 16*b'\x00')
d81731e6
JM
115 attrs = reply._PktEncodeAttributes()
116
117 # Length
118 flen = 4 + 16 + len(attrs)
119 hmac_obj.update(struct.pack(">H", flen))
120 hmac_obj.update(pkt.authenticator)
121 hmac_obj.update(attrs)
122 del reply[80]
123 reply.AddAttribute("Message-Authenticator", hmac_obj.digest())
124
125 self.SendReplyPacket(pkt.fd, reply)
126
127 def RunWithStop(self, t_stop, eap_handler):
128 self._poll = select.poll()
129 self._fdmap = {}
130 self._PrepareSockets()
131 self.t_stop = t_stop
132 self.eap_handler = eap_handler
133 self.ctx = {}
134
135 while not t_stop.is_set():
8a848fae 136 for (fd, event) in self._poll.poll(200):
d81731e6
JM
137 if event == select.POLLIN:
138 try:
139 fdo = self._fdmap[fd]
140 self._ProcessInput(fdo)
141 except pyrad.server.ServerPacketError as err:
142 logger.info("pyrad server dropping packet: " + str(err))
143 except pyrad.packet.PacketError as err:
144 logger.info("pyrad server received invalid packet: " + str(err))
145 else:
146 logger.error("Unexpected event in pyrad server main loop")
147
148 srv = TestServer(dict=pyrad.dictionary.Dictionary("dictionary.radius"),
149 authport=18138, acctport=18139)
150 srv.hosts["127.0.0.1"] = pyrad.server.RemoteHost("127.0.0.1",
55845e19 151 b"radius",
d81731e6
JM
152 "localhost")
153 srv.BindToAddress("")
154 t_stop = threading.Event()
155 t = threading.Thread(target=run_pyrad_server, args=(srv, t_stop, eap_handler))
156 t.start()
157
fab49f61 158 return {'srv': srv, 'stop': t_stop, 'thread': t}
d81731e6
JM
159
160def stop_radius_server(srv):
161 srv['stop'].set()
162 srv['thread'].join()
163
5eee514d 164def start_ap(ap):
d81731e6
JM
165 params = hostapd.wpa2_eap_params(ssid="eap-test")
166 params['auth_server_port'] = "18138"
5eee514d 167 hapd = hostapd.add_ap(ap, params)
d81731e6
JM
168 return hapd
169
2eae05f7
JM
170def test_eap_proto(dev, apdev):
171 """EAP protocol tests"""
e7ac04ce 172 check_eap_capa(dev[0], "MD5")
2eae05f7 173 def eap_handler(ctx, req):
55845e19 174 logger.info("eap_handler - RX " + binascii.hexlify(req).decode())
2eae05f7
JM
175 if 'num' not in ctx:
176 ctx['num'] = 0
177 ctx['num'] = ctx['num'] + 1
178 if 'id' not in ctx:
179 ctx['id'] = 1
180 ctx['id'] = (ctx['id'] + 1) % 256
181 idx = 0
182
183 idx += 1
184 if ctx['num'] == idx:
185 logger.info("Test: MD5 challenge")
186 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
187 4 + 1 + 3,
188 EAP_TYPE_MD5,
189 1, 0xaa, ord('n'))
190 idx += 1
191 if ctx['num'] == idx:
192 logger.info("Test: EAP-Success - id off by 2")
193 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'] + 1, 4)
194
195 idx += 1
196 if ctx['num'] == idx:
197 logger.info("Test: MD5 challenge")
198 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
199 4 + 1 + 3,
200 EAP_TYPE_MD5,
201 1, 0xaa, ord('n'))
202 idx += 1
203 if ctx['num'] == idx:
204 logger.info("Test: EAP-Success - id off by 3")
205 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'] + 2, 4)
206
207 idx += 1
208 if ctx['num'] == idx:
209 logger.info("Test: MD5 challenge")
210 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
211 4 + 1 + 3,
212 EAP_TYPE_MD5,
213 1, 0xaa, ord('n'))
214 idx += 1
215 if ctx['num'] == idx:
216 logger.info("Test: EAP-Notification/Request")
217 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
218 4 + 1 + 1,
219 EAP_TYPE_NOTIFICATION,
220 ord('A'))
221 idx += 1
222 if ctx['num'] == idx:
223 logger.info("Test: EAP-Success")
224 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'] - 1, 4)
225
226 idx += 1
227 if ctx['num'] == idx:
228 logger.info("Test: EAP-Notification/Request")
229 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
230 4 + 1 + 1,
231 EAP_TYPE_NOTIFICATION,
232 ord('B'))
233 idx += 1
234 if ctx['num'] == idx:
235 logger.info("Test: MD5 challenge")
236 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
237 4 + 1 + 3,
238 EAP_TYPE_MD5,
239 1, 0xaa, ord('n'))
240 idx += 1
241 if ctx['num'] == idx:
242 logger.info("Test: EAP-Success")
243 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'] - 1, 4)
244
245 idx += 1
246 if ctx['num'] == idx:
247 logger.info("Test: EAP-Notification/Request")
248 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
249 4 + 1 + 1,
250 EAP_TYPE_NOTIFICATION,
251 ord('C'))
252 idx += 1
253 if ctx['num'] == idx:
254 logger.info("Test: MD5 challenge")
255 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
256 4 + 1 + 3,
257 EAP_TYPE_MD5,
258 1, 0xaa, ord('n'))
259 idx += 1
260 if ctx['num'] == idx:
261 logger.info("Test: EAP-Notification/Request")
262 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
263 4 + 1 + 1,
264 EAP_TYPE_NOTIFICATION,
265 ord('D'))
266 idx += 1
267 if ctx['num'] == idx:
268 logger.info("Test: EAP-Success")
269 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'] - 1, 4)
270
271 idx += 1
272 if ctx['num'] == idx:
273 logger.info("Test: EAP-Notification/Request")
274 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
275 4 + 1 + 1,
276 EAP_TYPE_NOTIFICATION,
277 ord('E'))
278 idx += 1
279 if ctx['num'] == idx:
280 logger.info("Test: EAP-Notification/Request (same id)")
281 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'] - 1,
282 4 + 1 + 1,
283 EAP_TYPE_NOTIFICATION,
284 ord('F'))
285 idx += 1
286 if ctx['num'] == idx:
287 logger.info("Test: Unexpected EAP-Success")
288 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'] - 2, 4)
289
290 return None
291
292 srv = start_radius_server(eap_handler)
2eae05f7
JM
293
294 try:
5eee514d 295 hapd = start_ap(apdev[0])
9efd3447 296 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
2eae05f7
JM
297
298 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
299 eap="MD5", identity="user", password="password",
300 wait_connect=False)
301 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15)
302 if ev is None:
303 raise Exception("Timeout on EAP start")
304 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15)
305 if ev is None:
306 raise Exception("Timeout on EAP success")
307 dev[0].request("REMOVE_NETWORK all")
308
309 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
310 eap="MD5", identity="user", password="password",
311 wait_connect=False)
312 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15)
313 if ev is None:
314 raise Exception("Timeout on EAP start")
315 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=1)
316 if ev is not None:
317 raise Exception("Unexpected EAP success")
318 dev[0].request("REMOVE_NETWORK all")
319
320 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
321 eap="MD5", identity="user", password="password",
322 wait_connect=False)
323 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15)
324 if ev is None:
325 raise Exception("Timeout on EAP start")
326 ev = dev[0].wait_event(["CTRL-EVENT-EAP-NOTIFICATION"], timeout=10)
327 if ev is None:
328 raise Exception("Timeout on EAP notification")
329 if ev != "<3>CTRL-EVENT-EAP-NOTIFICATION A":
330 raise Exception("Unexpected notification contents: " + ev)
331 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15)
332 if ev is None:
333 raise Exception("Timeout on EAP success")
334 dev[0].request("REMOVE_NETWORK all")
335
336 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
337 eap="MD5", identity="user", password="password",
338 wait_connect=False)
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 B":
343 raise Exception("Unexpected notification contents: " + ev)
344 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15)
345 if ev is None:
346 raise Exception("Timeout on EAP start")
347 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15)
348 if ev is None:
349 raise Exception("Timeout on EAP success")
350 dev[0].request("REMOVE_NETWORK all")
351
352 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
353 eap="MD5", identity="user", password="password",
354 wait_connect=False)
355 ev = dev[0].wait_event(["CTRL-EVENT-EAP-NOTIFICATION"], timeout=10)
356 if ev is None:
357 raise Exception("Timeout on EAP notification")
358 if ev != "<3>CTRL-EVENT-EAP-NOTIFICATION C":
359 raise Exception("Unexpected notification contents: " + ev)
360 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15)
361 if ev is None:
362 raise Exception("Timeout on EAP start")
363 ev = dev[0].wait_event(["CTRL-EVENT-EAP-NOTIFICATION"], timeout=10)
364 if ev is None:
365 raise Exception("Timeout on EAP notification")
366 if ev != "<3>CTRL-EVENT-EAP-NOTIFICATION D":
367 raise Exception("Unexpected notification contents: " + ev)
368 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15)
369 if ev is None:
370 raise Exception("Timeout on EAP success")
371 dev[0].request("REMOVE_NETWORK all")
372
373 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
374 eap="MD5", identity="user", password="password",
375 wait_connect=False)
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 E":
380 raise Exception("Unexpected notification contents: " + ev)
381 ev = dev[0].wait_event(["CTRL-EVENT-EAP-NOTIFICATION"], timeout=10)
382 if ev is None:
383 raise Exception("Timeout on EAP notification")
384 if ev != "<3>CTRL-EVENT-EAP-NOTIFICATION F":
385 raise Exception("Unexpected notification contents: " + ev)
386 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=15)
387 if ev is None:
388 raise Exception("Timeout on EAP failure")
389 dev[0].request("REMOVE_NETWORK all")
390 finally:
391 stop_radius_server(srv)
392
7dbd2c6c
JM
393def test_eap_proto_notification_errors(dev, apdev):
394 """EAP Notification errors"""
395 def eap_handler(ctx, req):
55845e19 396 logger.info("eap_handler - RX " + binascii.hexlify(req).decode())
7dbd2c6c
JM
397 if 'num' not in ctx:
398 ctx['num'] = 0
399 ctx['num'] = ctx['num'] + 1
400 if 'id' not in ctx:
401 ctx['id'] = 1
402 ctx['id'] = (ctx['id'] + 1) % 256
403 idx = 0
404
405 idx += 1
406 if ctx['num'] == idx:
407 logger.info("Test: MD5 challenge")
408 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
409 4 + 1 + 3,
410 EAP_TYPE_MD5,
411 1, 0xaa, ord('n'))
412 idx += 1
413 if ctx['num'] == idx:
414 logger.info("Test: EAP-Notification/Request")
415 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
416 4 + 1 + 1,
417 EAP_TYPE_NOTIFICATION,
418 ord('A'))
419
420 idx += 1
421 if ctx['num'] == idx:
422 logger.info("Test: MD5 challenge")
423 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
424 4 + 1 + 3,
425 EAP_TYPE_MD5,
426 1, 0xaa, ord('n'))
427 idx += 1
428 if ctx['num'] == idx:
429 logger.info("Test: EAP-Notification/Request")
430 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
431 4 + 1 + 1,
432 EAP_TYPE_NOTIFICATION,
433 ord('A'))
434
435 return None
436
437 srv = start_radius_server(eap_handler)
438
439 try:
5eee514d 440 hapd = start_ap(apdev[0])
9efd3447 441 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
7dbd2c6c
JM
442
443 with alloc_fail(dev[0], 1, "eap_sm_processNotify"):
444 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
445 eap="MD5", identity="user", password="password",
446 wait_connect=False)
447 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
448 dev[0].request("REMOVE_NETWORK all")
449 dev[0].wait_disconnected()
450
451 with alloc_fail(dev[0], 1, "eap_msg_alloc;sm_EAP_NOTIFICATION_Enter"):
452 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
453 eap="MD5", identity="user", password="password",
454 wait_connect=False)
455 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
456 dev[0].request("REMOVE_NETWORK all")
457 dev[0].wait_disconnected()
458 finally:
459 stop_radius_server(srv)
460
d81731e6
JM
461EAP_SAKE_VERSION = 2
462
463EAP_SAKE_SUBTYPE_CHALLENGE = 1
464EAP_SAKE_SUBTYPE_CONFIRM = 2
465EAP_SAKE_SUBTYPE_AUTH_REJECT = 3
466EAP_SAKE_SUBTYPE_IDENTITY = 4
467
468EAP_SAKE_AT_RAND_S = 1
469EAP_SAKE_AT_RAND_P = 2
470EAP_SAKE_AT_MIC_S = 3
471EAP_SAKE_AT_MIC_P = 4
472EAP_SAKE_AT_SERVERID = 5
473EAP_SAKE_AT_PEERID = 6
474EAP_SAKE_AT_SPI_S = 7
475EAP_SAKE_AT_SPI_P = 8
476EAP_SAKE_AT_ANY_ID_REQ = 9
477EAP_SAKE_AT_PERM_ID_REQ = 10
478EAP_SAKE_AT_ENCR_DATA = 128
479EAP_SAKE_AT_IV = 129
480EAP_SAKE_AT_PADDING = 130
481EAP_SAKE_AT_NEXT_TMPID = 131
482EAP_SAKE_AT_MSK_LIFE = 132
483
484def test_eap_proto_sake(dev, apdev):
485 """EAP-SAKE protocol tests"""
c49b383f
JM
486 global eap_proto_sake_test_done
487 eap_proto_sake_test_done = False
488
d81731e6
JM
489 def sake_challenge(ctx):
490 logger.info("Test: Challenge subtype")
491 return struct.pack(">BBHBBBBBBLLLL", EAP_CODE_REQUEST, ctx['id'],
492 4 + 1 + 3 + 18,
493 EAP_TYPE_SAKE,
494 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_CHALLENGE,
495 EAP_SAKE_AT_RAND_S, 18, 0, 0, 0, 0)
496
497 def sake_handler(ctx, req):
55845e19 498 logger.info("sake_handler - RX " + binascii.hexlify(req).decode())
d81731e6
JM
499 if 'num' not in ctx:
500 ctx['num'] = 0
c49b383f 501 ctx['num'] += 1
d81731e6
JM
502 if 'id' not in ctx:
503 ctx['id'] = 1
504 ctx['id'] = (ctx['id'] + 1) % 256
c49b383f 505 idx = 0
d81731e6 506
c49b383f
JM
507 idx += 1
508 if ctx['num'] == idx:
d81731e6
JM
509 logger.info("Test: Missing payload")
510 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 4 + 1,
511 EAP_TYPE_SAKE)
512
c49b383f
JM
513 idx += 1
514 if ctx['num'] == idx:
d81731e6
JM
515 logger.info("Test: Identity subtype without any attributes")
516 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
517 4 + 1 + 3,
518 EAP_TYPE_SAKE,
519 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_IDENTITY)
520
c49b383f
JM
521 idx += 1
522 if ctx['num'] == idx:
d81731e6
JM
523 logger.info("Test: Identity subtype")
524 return struct.pack(">BBHBBBBBBH", EAP_CODE_REQUEST, ctx['id'],
525 4 + 1 + 3 + 4,
526 EAP_TYPE_SAKE,
527 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_IDENTITY,
528 EAP_SAKE_AT_ANY_ID_REQ, 4, 0)
c49b383f
JM
529 idx += 1
530 if ctx['num'] == idx:
d81731e6
JM
531 logger.info("Test: Identity subtype (different session id)")
532 return struct.pack(">BBHBBBBBBH", EAP_CODE_REQUEST, ctx['id'],
533 4 + 1 + 3 + 4,
534 EAP_TYPE_SAKE,
535 EAP_SAKE_VERSION, 1, EAP_SAKE_SUBTYPE_IDENTITY,
536 EAP_SAKE_AT_PERM_ID_REQ, 4, 0)
537
c49b383f
JM
538 idx += 1
539 if ctx['num'] == idx:
d81731e6
JM
540 logger.info("Test: Identity subtype with too short attribute")
541 return struct.pack(">BBHBBBBBB", EAP_CODE_REQUEST, ctx['id'],
542 4 + 1 + 3 + 2,
543 EAP_TYPE_SAKE,
544 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_IDENTITY,
545 EAP_SAKE_AT_ANY_ID_REQ, 2)
546
c49b383f
JM
547 idx += 1
548 if ctx['num'] == idx:
d81731e6
JM
549 logger.info("Test: Identity subtype with truncated attribute")
550 return struct.pack(">BBHBBBBBB", EAP_CODE_REQUEST, ctx['id'],
551 4 + 1 + 3 + 2,
552 EAP_TYPE_SAKE,
553 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_IDENTITY,
554 EAP_SAKE_AT_ANY_ID_REQ, 4)
555
288b6f8b
JM
556 idx += 1
557 if ctx['num'] == idx:
558 logger.info("Test: Identity subtype with too short attribute header")
559 payload = struct.pack("B", EAP_SAKE_AT_ANY_ID_REQ)
560 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
561 4 + 1 + 3 + len(payload),
562 EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0,
563 EAP_SAKE_SUBTYPE_IDENTITY) + payload
564
565 idx += 1
566 if ctx['num'] == idx:
567 logger.info("Test: Identity subtype with AT_IV but not AT_ENCR_DATA")
568 payload = struct.pack("BB", EAP_SAKE_AT_IV, 2)
569 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
570 4 + 1 + 3 + len(payload),
571 EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0,
572 EAP_SAKE_SUBTYPE_IDENTITY) + payload
573
574 idx += 1
575 if ctx['num'] == idx:
576 logger.info("Test: Identity subtype with skippable and non-skippable unknown attribute")
577 payload = struct.pack("BBBB", 255, 2, 127, 2)
578 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
579 4 + 1 + 3 + len(payload),
580 EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0,
581 EAP_SAKE_SUBTYPE_IDENTITY) + payload
582
583 idx += 1
584 if ctx['num'] == idx:
585 logger.info("Test: Identity subtype: AT_RAND_P with invalid payload length")
586 payload = struct.pack("BB", EAP_SAKE_AT_RAND_P, 2)
587 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
588 4 + 1 + 3 + len(payload),
589 EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0,
590 EAP_SAKE_SUBTYPE_IDENTITY) + payload
591
592 idx += 1
593 if ctx['num'] == idx:
594 logger.info("Test: Identity subtype: AT_MIC_P with invalid payload length")
595 payload = struct.pack("BB", EAP_SAKE_AT_MIC_P, 2)
596 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
597 4 + 1 + 3 + len(payload),
598 EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0,
599 EAP_SAKE_SUBTYPE_IDENTITY) + payload
600
601 idx += 1
602 if ctx['num'] == idx:
603 logger.info("Test: Identity subtype: AT_PERM_ID_REQ with invalid payload length")
604 payload = struct.pack("BBBBBBBBBBBBBB",
605 EAP_SAKE_AT_SPI_S, 2,
606 EAP_SAKE_AT_SPI_P, 2,
607 EAP_SAKE_AT_ENCR_DATA, 2,
608 EAP_SAKE_AT_NEXT_TMPID, 2,
609 EAP_SAKE_AT_PERM_ID_REQ, 4, 0, 0,
610 EAP_SAKE_AT_PERM_ID_REQ, 2)
611 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
612 4 + 1 + 3 + len(payload),
613 EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0,
614 EAP_SAKE_SUBTYPE_IDENTITY) + payload
615
616 idx += 1
617 if ctx['num'] == idx:
618 logger.info("Test: Identity subtype: AT_PADDING")
619 payload = struct.pack("BBBBBB",
620 EAP_SAKE_AT_PADDING, 3, 0,
621 EAP_SAKE_AT_PADDING, 3, 1)
622 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
623 4 + 1 + 3 + len(payload),
624 EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0,
625 EAP_SAKE_SUBTYPE_IDENTITY) + payload
626
627 idx += 1
628 if ctx['num'] == idx:
629 logger.info("Test: Identity subtype: AT_MSK_LIFE")
630 payload = struct.pack(">BBLBBH",
631 EAP_SAKE_AT_MSK_LIFE, 6, 0,
632 EAP_SAKE_AT_MSK_LIFE, 4, 0)
633 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
634 4 + 1 + 3 + len(payload),
635 EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0,
636 EAP_SAKE_SUBTYPE_IDENTITY) + payload
637
638 idx += 1
639 if ctx['num'] == idx:
640 logger.info("Test: Identity subtype with invalid attribute length")
641 payload = struct.pack("BB", EAP_SAKE_AT_ANY_ID_REQ, 0)
642 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
643 4 + 1 + 3 + len(payload),
644 EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0,
645 EAP_SAKE_SUBTYPE_IDENTITY) + payload
646
c49b383f
JM
647 idx += 1
648 if ctx['num'] == idx:
d81731e6
JM
649 logger.info("Test: Unknown subtype")
650 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
651 4 + 1 + 3,
652 EAP_TYPE_SAKE,
653 EAP_SAKE_VERSION, 0, 123)
654
c49b383f
JM
655 idx += 1
656 if ctx['num'] == idx:
d81731e6
JM
657 logger.info("Test: Challenge subtype without any attributes")
658 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
659 4 + 1 + 3,
660 EAP_TYPE_SAKE,
661 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_CHALLENGE)
662
c49b383f
JM
663 idx += 1
664 if ctx['num'] == idx:
d81731e6
JM
665 logger.info("Test: Challenge subtype with too short AT_RAND_S")
666 return struct.pack(">BBHBBBBBB", EAP_CODE_REQUEST, ctx['id'],
667 4 + 1 + 3 + 2,
668 EAP_TYPE_SAKE,
669 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_CHALLENGE,
670 EAP_SAKE_AT_RAND_S, 2)
671
c49b383f
JM
672 idx += 1
673 if ctx['num'] == idx:
d81731e6 674 return sake_challenge(ctx)
c49b383f
JM
675 idx += 1
676 if ctx['num'] == idx:
d81731e6
JM
677 logger.info("Test: Unexpected Identity subtype")
678 return struct.pack(">BBHBBBBBBH", EAP_CODE_REQUEST, ctx['id'],
679 4 + 1 + 3 + 4,
680 EAP_TYPE_SAKE,
681 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_IDENTITY,
682 EAP_SAKE_AT_ANY_ID_REQ, 4, 0)
683
c49b383f
JM
684 idx += 1
685 if ctx['num'] == idx:
d81731e6 686 return sake_challenge(ctx)
c49b383f
JM
687 idx += 1
688 if ctx['num'] == idx:
d81731e6
JM
689 logger.info("Test: Unexpected Challenge subtype")
690 return struct.pack(">BBHBBBBBBLLLL", EAP_CODE_REQUEST, ctx['id'],
691 4 + 1 + 3 + 18,
692 EAP_TYPE_SAKE,
693 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_CHALLENGE,
694 EAP_SAKE_AT_RAND_S, 18, 0, 0, 0, 0)
695
c49b383f
JM
696 idx += 1
697 if ctx['num'] == idx:
d81731e6 698 return sake_challenge(ctx)
c49b383f
JM
699 idx += 1
700 if ctx['num'] == idx:
d81731e6
JM
701 logger.info("Test: Confirm subtype without any attributes")
702 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
703 4 + 1 + 3,
704 EAP_TYPE_SAKE,
705 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_CONFIRM)
706
c49b383f
JM
707 idx += 1
708 if ctx['num'] == idx:
d81731e6 709 return sake_challenge(ctx)
c49b383f
JM
710 idx += 1
711 if ctx['num'] == idx:
d81731e6
JM
712 logger.info("Test: Confirm subtype with too short AT_MIC_S")
713 return struct.pack(">BBHBBBBBB", EAP_CODE_REQUEST, ctx['id'],
714 4 + 1 + 3 + 2,
715 EAP_TYPE_SAKE,
716 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_CONFIRM,
717 EAP_SAKE_AT_MIC_S, 2)
718
c49b383f
JM
719 idx += 1
720 if ctx['num'] == idx:
d81731e6
JM
721 logger.info("Test: Unexpected Confirm subtype")
722 return struct.pack(">BBHBBBBBBLLLL", EAP_CODE_REQUEST, ctx['id'],
723 4 + 1 + 3 + 18,
724 EAP_TYPE_SAKE,
725 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_CONFIRM,
726 EAP_SAKE_AT_MIC_S, 18, 0, 0, 0, 0)
727
c49b383f
JM
728 idx += 1
729 if ctx['num'] == idx:
d81731e6 730 return sake_challenge(ctx)
c49b383f
JM
731 idx += 1
732 if ctx['num'] == idx:
d81731e6
JM
733 logger.info("Test: Confirm subtype with incorrect AT_MIC_S")
734 return struct.pack(">BBHBBBBBBLLLL", EAP_CODE_REQUEST, ctx['id'],
735 4 + 1 + 3 + 18,
736 EAP_TYPE_SAKE,
737 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_CONFIRM,
738 EAP_SAKE_AT_MIC_S, 18, 0, 0, 0, 0)
739
c49b383f
JM
740 global eap_proto_sake_test_done
741 if eap_proto_sake_test_done:
742 return sake_challenge(ctx)
743
744 logger.info("No more test responses available - test case completed")
745 eap_proto_sake_test_done = True
746 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
d81731e6
JM
747
748 srv = start_radius_server(sake_handler)
d81731e6
JM
749
750 try:
5eee514d 751 hapd = start_ap(apdev[0])
9efd3447 752 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
d81731e6 753
c49b383f 754 while not eap_proto_sake_test_done:
d81731e6
JM
755 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
756 eap="SAKE", identity="sake user",
757 password_hex="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
758 wait_connect=False)
759 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15)
760 if ev is None:
761 raise Exception("Timeout on EAP start")
762 time.sleep(0.1)
763 dev[0].request("REMOVE_NETWORK all")
764
765 logger.info("Too short password")
766 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
767 eap="SAKE", identity="sake user",
768 password_hex="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcd",
769 wait_connect=False)
770 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15)
771 if ev is None:
772 raise Exception("Timeout on EAP start")
773 time.sleep(0.1)
774 finally:
775 stop_radius_server(srv)
18fc8f40 776
ab4ea0e9
JM
777def test_eap_proto_sake_errors(dev, apdev):
778 """EAP-SAKE local error cases"""
779 check_eap_capa(dev[0], "SAKE")
780 params = hostapd.wpa2_eap_params(ssid="eap-test")
8b8a1864 781 hapd = hostapd.add_ap(apdev[0], params)
9efd3447 782 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
ab4ea0e9
JM
783
784 for i in range(1, 3):
785 with alloc_fail(dev[0], i, "eap_sake_init"):
786 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
787 eap="SAKE", identity="sake user",
788 password_hex="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
789 wait_connect=False)
790 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
791 timeout=15)
792 if ev is None:
793 raise Exception("Timeout on EAP start")
794 dev[0].request("REMOVE_NETWORK all")
795 dev[0].wait_disconnected()
796
fab49f61
JM
797 tests = [(1, "eap_msg_alloc;eap_sake_build_msg;eap_sake_process_challenge"),
798 (1, "=eap_sake_process_challenge"),
799 (1, "eap_sake_compute_mic;eap_sake_process_challenge"),
800 (1, "eap_sake_build_msg;eap_sake_process_confirm"),
801 (1, "eap_sake_compute_mic;eap_sake_process_confirm"),
802 (2, "eap_sake_compute_mic;eap_sake_process_confirm"),
803 (1, "eap_sake_getKey"),
804 (1, "eap_sake_get_emsk"),
805 (1, "eap_sake_get_session_id")]
ab4ea0e9
JM
806 for count, func in tests:
807 with alloc_fail(dev[0], count, func):
808 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
0a0c4dc1 809 eap="SAKE", identity="sake user@domain",
ab4ea0e9
JM
810 password_hex="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
811 erp="1",
812 wait_connect=False)
813 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
814 timeout=15)
815 if ev is None:
816 raise Exception("Timeout on EAP start")
817 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
818 dev[0].request("REMOVE_NETWORK all")
819 dev[0].wait_disconnected()
820
821 with fail_test(dev[0], 1, "os_get_random;eap_sake_process_challenge"):
822 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
823 eap="SAKE", identity="sake user",
824 password_hex="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
825 wait_connect=False)
826 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15)
827 if ev is None:
828 raise Exception("Timeout on EAP start")
829 wait_fail_trigger(dev[0], "GET_FAIL")
830 dev[0].request("REMOVE_NETWORK all")
831 dev[0].wait_disconnected()
832
833def test_eap_proto_sake_errors2(dev, apdev):
834 """EAP-SAKE protocol tests (2)"""
835 def sake_handler(ctx, req):
55845e19 836 logger.info("sake_handler - RX " + binascii.hexlify(req).decode())
ab4ea0e9
JM
837 if 'num' not in ctx:
838 ctx['num'] = 0
839 ctx['num'] += 1
840 if 'id' not in ctx:
841 ctx['id'] = 1
842 ctx['id'] = (ctx['id'] + 1) % 256
843 idx = 0
844
845 idx += 1
846 if ctx['num'] == idx:
847 logger.info("Test: Identity subtype")
848 return struct.pack(">BBHBBBBBBH", EAP_CODE_REQUEST, ctx['id'],
849 4 + 1 + 3 + 4,
850 EAP_TYPE_SAKE,
851 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_IDENTITY,
852 EAP_SAKE_AT_ANY_ID_REQ, 4, 0)
853
854 srv = start_radius_server(sake_handler)
855
856 try:
5eee514d 857 hapd = start_ap(apdev[0])
9efd3447 858 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
ab4ea0e9
JM
859
860 with alloc_fail(dev[0], 1, "eap_msg_alloc;eap_sake_build_msg;eap_sake_process_identity"):
861 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
862 eap="SAKE", identity="sake user",
863 password_hex="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
864 wait_connect=False)
865 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
866 timeout=15)
867 if ev is None:
868 raise Exception("Timeout on EAP start")
869 dev[0].request("REMOVE_NETWORK all")
870 dev[0].wait_disconnected()
871
872 finally:
873 stop_radius_server(srv)
874
18fc8f40
JM
875def test_eap_proto_leap(dev, apdev):
876 """EAP-LEAP protocol tests"""
597516df 877 check_eap_capa(dev[0], "LEAP")
18fc8f40 878 def leap_handler(ctx, req):
55845e19 879 logger.info("leap_handler - RX " + binascii.hexlify(req).decode())
18fc8f40
JM
880 if 'num' not in ctx:
881 ctx['num'] = 0
882 ctx['num'] = ctx['num'] + 1
883 if 'id' not in ctx:
884 ctx['id'] = 1
885 ctx['id'] = (ctx['id'] + 1) % 256
886
887 if ctx['num'] == 1:
888 logger.info("Test: Missing payload")
889 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
890 4 + 1,
891 EAP_TYPE_LEAP)
892
893 if ctx['num'] == 2:
894 logger.info("Test: Unexpected version")
895 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
896 4 + 1 + 3,
897 EAP_TYPE_LEAP,
898 0, 0, 0)
899
900 if ctx['num'] == 3:
901 logger.info("Test: Invalid challenge length")
902 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
903 4 + 1 + 3,
904 EAP_TYPE_LEAP,
905 1, 0, 0)
906
907 if ctx['num'] == 4:
908 logger.info("Test: Truncated challenge")
909 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
910 4 + 1 + 3,
911 EAP_TYPE_LEAP,
912 1, 0, 8)
913
914 if ctx['num'] == 5:
915 logger.info("Test: Valid challenge")
916 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
917 4 + 1 + 3 + 8,
918 EAP_TYPE_LEAP,
919 1, 0, 8, 0, 0)
920 if ctx['num'] == 6:
921 logger.info("Test: Missing payload in Response")
922 return struct.pack(">BBHB", EAP_CODE_RESPONSE, ctx['id'],
923 4 + 1,
924 EAP_TYPE_LEAP)
925
926 if ctx['num'] == 7:
927 logger.info("Test: Valid challenge")
928 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
929 4 + 1 + 3 + 8,
930 EAP_TYPE_LEAP,
931 1, 0, 8, 0, 0)
932 if ctx['num'] == 8:
933 logger.info("Test: Unexpected version in Response")
934 return struct.pack(">BBHBBBB", EAP_CODE_RESPONSE, ctx['id'],
935 4 + 1 + 3,
936 EAP_TYPE_LEAP,
937 0, 0, 8)
938
939 if ctx['num'] == 9:
940 logger.info("Test: Valid challenge")
941 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
942 4 + 1 + 3 + 8,
943 EAP_TYPE_LEAP,
944 1, 0, 8, 0, 0)
945 if ctx['num'] == 10:
946 logger.info("Test: Invalid challenge length in Response")
947 return struct.pack(">BBHBBBB", EAP_CODE_RESPONSE, ctx['id'],
948 4 + 1 + 3,
949 EAP_TYPE_LEAP,
950 1, 0, 0)
951
952 if ctx['num'] == 11:
953 logger.info("Test: Valid challenge")
954 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
955 4 + 1 + 3 + 8,
956 EAP_TYPE_LEAP,
957 1, 0, 8, 0, 0)
958 if ctx['num'] == 12:
959 logger.info("Test: Truncated challenge in Response")
960 return struct.pack(">BBHBBBB", EAP_CODE_RESPONSE, ctx['id'],
961 4 + 1 + 3,
962 EAP_TYPE_LEAP,
963 1, 0, 24)
964
965 if ctx['num'] == 13:
966 logger.info("Test: Valid challenge")
967 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
968 4 + 1 + 3 + 8,
969 EAP_TYPE_LEAP,
970 1, 0, 8, 0, 0)
971 if ctx['num'] == 14:
972 logger.info("Test: Invalid challange value in Response")
973 return struct.pack(">BBHBBBB6L", EAP_CODE_RESPONSE, ctx['id'],
974 4 + 1 + 3 + 24,
975 EAP_TYPE_LEAP,
976 1, 0, 24,
977 0, 0, 0, 0, 0, 0)
978
979 if ctx['num'] == 15:
980 logger.info("Test: Valid challenge")
981 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
982 4 + 1 + 3 + 8,
983 EAP_TYPE_LEAP,
984 1, 0, 8, 0, 0)
985 if ctx['num'] == 16:
986 logger.info("Test: Valid challange value in Response")
987 return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'],
988 4 + 1 + 3 + 24,
989 EAP_TYPE_LEAP,
990 1, 0, 24,
991 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd,
992 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04,
993 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66)
994
995 if ctx['num'] == 17:
996 logger.info("Test: Valid challenge")
997 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
998 4 + 1 + 3 + 8,
999 EAP_TYPE_LEAP,
1000 1, 0, 8, 0, 0)
1001 if ctx['num'] == 18:
1002 logger.info("Test: Success")
1003 return struct.pack(">BBHB", EAP_CODE_SUCCESS, ctx['id'],
1004 4 + 1,
1005 EAP_TYPE_LEAP)
1006 # hostapd will drop the next frame in the sequence
1007
1008 if ctx['num'] == 19:
1009 logger.info("Test: Valid challenge")
1010 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
1011 4 + 1 + 3 + 8,
1012 EAP_TYPE_LEAP,
1013 1, 0, 8, 0, 0)
1014 if ctx['num'] == 20:
1015 logger.info("Test: Failure")
1016 return struct.pack(">BBHB", EAP_CODE_FAILURE, ctx['id'],
1017 4 + 1,
1018 EAP_TYPE_LEAP)
1019
1020 return None
1021
1022 srv = start_radius_server(leap_handler)
18fc8f40
JM
1023
1024 try:
5eee514d 1025 hapd = start_ap(apdev[0])
9efd3447 1026 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
18fc8f40
JM
1027
1028 for i in range(0, 12):
1029 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1030 eap="LEAP", identity="user", password="password",
1031 wait_connect=False)
1032 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15)
1033 if ev is None:
1034 raise Exception("Timeout on EAP start")
1035 time.sleep(0.1)
1036 if i == 10:
1037 logger.info("Wait for additional roundtrip")
1038 time.sleep(1)
1039 dev[0].request("REMOVE_NETWORK all")
1040 finally:
1041 stop_radius_server(srv)
8604a68e 1042
e114e999
JM
1043def test_eap_proto_leap_errors(dev, apdev):
1044 """EAP-LEAP protocol tests (error paths)"""
1045 check_eap_capa(dev[0], "LEAP")
1046
1047 def leap_handler2(ctx, req):
55845e19 1048 logger.info("leap_handler2 - RX " + binascii.hexlify(req).decode())
e114e999
JM
1049 if 'num' not in ctx:
1050 ctx['num'] = 0
1051 ctx['num'] = ctx['num'] + 1
1052 if 'id' not in ctx:
1053 ctx['id'] = 1
1054 ctx['id'] = (ctx['id'] + 1) % 256
1055 idx = 0
1056
1057 idx += 1
1058 if ctx['num'] == idx:
1059 logger.info("Test: Valid challenge")
1060 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
1061 4 + 1 + 3 + 8,
1062 EAP_TYPE_LEAP,
1063 1, 0, 8, 0, 0)
1064 idx += 1
1065 if ctx['num'] == idx:
1066 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
1067
1068 idx += 1
1069 if ctx['num'] == idx:
1070 logger.info("Test: Valid challenge")
1071 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
1072 4 + 1 + 3 + 8,
1073 EAP_TYPE_LEAP,
1074 1, 0, 8, 0, 0)
1075
1076 idx += 1
1077 if ctx['num'] == idx:
1078 logger.info("Test: Valid challenge")
1079 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
1080 4 + 1 + 3 + 8,
1081 EAP_TYPE_LEAP,
1082 1, 0, 8, 0, 0)
1083 idx += 1
1084 if ctx['num'] == idx:
1085 logger.info("Test: Success")
1086 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4)
1087
1088 idx += 1
1089 if ctx['num'] == idx:
1090 logger.info("Test: Valid challenge")
1091 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
1092 4 + 1 + 3 + 8,
1093 EAP_TYPE_LEAP,
1094 1, 0, 8, 0, 0)
1095 idx += 1
1096 if ctx['num'] == idx:
1097 logger.info("Test: Success")
1098 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4)
1099
1100 idx += 1
1101 if ctx['num'] == idx:
1102 logger.info("Test: Valid challenge")
1103 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
1104 4 + 1 + 3 + 8,
1105 EAP_TYPE_LEAP,
1106 1, 0, 8, 0, 0)
1107 idx += 1
1108 if ctx['num'] == idx:
1109 logger.info("Test: Valid challange value in Response")
1110 return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'],
1111 4 + 1 + 3 + 24,
1112 EAP_TYPE_LEAP,
1113 1, 0, 24,
1114 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd,
1115 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04,
1116 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66)
1117
1118 idx += 1
1119 if ctx['num'] == idx:
1120 logger.info("Test: Valid challenge")
1121 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
1122 4 + 1 + 3 + 8,
1123 EAP_TYPE_LEAP,
1124 1, 0, 8, 0, 0)
1125 idx += 1
1126 if ctx['num'] == idx:
1127 logger.info("Test: Valid challange value in Response")
1128 return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'],
1129 4 + 1 + 3 + 24,
1130 EAP_TYPE_LEAP,
1131 1, 0, 24,
1132 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd,
1133 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04,
1134 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66)
1135
1136 idx += 1
1137 if ctx['num'] == idx:
1138 logger.info("Test: Valid challenge")
1139 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
1140 4 + 1 + 3 + 8,
1141 EAP_TYPE_LEAP,
1142 1, 0, 8, 0, 0)
1143 idx += 1
1144 if ctx['num'] == idx:
1145 logger.info("Test: Valid challange value in Response")
1146 return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'],
1147 4 + 1 + 3 + 24,
1148 EAP_TYPE_LEAP,
1149 1, 0, 24,
1150 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd,
1151 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04,
1152 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66)
1153
1154 idx += 1
1155 if ctx['num'] == idx:
1156 logger.info("Test: Valid challenge")
1157 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
1158 4 + 1 + 3 + 8,
1159 EAP_TYPE_LEAP,
1160 1, 0, 8, 0, 0)
1161 idx += 1
1162 if ctx['num'] == idx:
1163 logger.info("Test: Valid challange value in Response")
1164 return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'],
1165 4 + 1 + 3 + 24,
1166 EAP_TYPE_LEAP,
1167 1, 0, 24,
1168 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd,
1169 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04,
1170 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66)
1171
1172 idx += 1
1173 if ctx['num'] == idx:
1174 logger.info("Test: Valid challenge")
1175 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
1176 4 + 1 + 3 + 8,
1177 EAP_TYPE_LEAP,
1178 1, 0, 8, 0, 0)
1179 idx += 1
1180 if ctx['num'] == idx:
1181 logger.info("Test: Valid challange value in Response")
1182 return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'],
1183 4 + 1 + 3 + 24,
1184 EAP_TYPE_LEAP,
1185 1, 0, 24,
1186 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd,
1187 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04,
1188 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66)
1189
1190 idx += 1
1191 if ctx['num'] == idx:
1192 logger.info("Test: Valid challenge")
1193 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
1194 4 + 1 + 3 + 8,
1195 EAP_TYPE_LEAP,
1196 1, 0, 8, 0, 0)
1197 idx += 1
1198 if ctx['num'] == idx:
1199 logger.info("Test: Valid challange value in Response")
1200 return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'],
1201 4 + 1 + 3 + 24,
1202 EAP_TYPE_LEAP,
1203 1, 0, 24,
1204 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd,
1205 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04,
1206 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66)
1207
1208 idx += 1
1209 if ctx['num'] == idx:
1210 logger.info("Test: Valid challenge")
1211 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
1212 4 + 1 + 3 + 8,
1213 EAP_TYPE_LEAP,
1214 1, 0, 8, 0, 0)
1215 idx += 1
1216 if ctx['num'] == idx:
1217 logger.info("Test: Valid challange value in Response")
1218 return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'],
1219 4 + 1 + 3 + 24,
1220 EAP_TYPE_LEAP,
1221 1, 0, 24,
1222 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd,
1223 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04,
1224 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66)
1225
e4e99927
JM
1226 idx += 1
1227 if ctx['num'] == idx:
1228 logger.info("Test: Valid challenge")
1229 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
1230 4 + 1 + 3 + 8,
1231 EAP_TYPE_LEAP,
1232 1, 0, 8, 0, 0)
1233
e114e999
JM
1234 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
1235
1236 srv = start_radius_server(leap_handler2)
1237
1238 try:
5eee514d 1239 hapd = start_ap(apdev[0])
9efd3447 1240 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
e114e999
JM
1241
1242 with alloc_fail(dev[0], 1, "eap_leap_init"):
1243 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1244 eap="LEAP", identity="user", password="password",
1245 wait_connect=False)
1246 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
1247 dev[0].request("REMOVE_NETWORK all")
1248 dev[0].wait_disconnected()
1249
1250 with alloc_fail(dev[0], 1, "eap_msg_alloc;eap_leap_process_request"):
1251 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1252 eap="LEAP", identity="user",
1253 password_hex="hash:8846f7eaee8fb117ad06bdd830b7586c",
1254 wait_connect=False)
1255 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
1256 dev[0].request("REMOVE_NETWORK all")
1257 dev[0].wait_disconnected()
1258
1259 with alloc_fail(dev[0], 1, "eap_leap_process_success"):
1260 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1261 eap="LEAP", identity="user", password="password",
1262 wait_connect=False)
1263 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
1264 dev[0].request("REMOVE_NETWORK all")
1265 dev[0].wait_disconnected()
1266
1267 with fail_test(dev[0], 1, "os_get_random;eap_leap_process_success"):
1268 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1269 eap="LEAP", identity="user", password="password",
1270 wait_connect=False)
1271 wait_fail_trigger(dev[0], "GET_FAIL")
1272 dev[0].request("REMOVE_NETWORK all")
1273 dev[0].wait_disconnected()
1274
1275 with fail_test(dev[0], 1, "eap_leap_process_response"):
1276 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1277 eap="LEAP", identity="user",
1278 password_hex="hash:8846f7eaee8fb117ad06bdd830b7586c",
1279 wait_connect=False)
1280 wait_fail_trigger(dev[0], "GET_FAIL")
1281 dev[0].request("REMOVE_NETWORK all")
1282 dev[0].wait_disconnected()
1283
1284 with fail_test(dev[0], 1, "nt_password_hash;eap_leap_process_response"):
1285 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1286 eap="LEAP", identity="user", password="password",
1287 wait_connect=False)
1288 wait_fail_trigger(dev[0], "GET_FAIL")
1289 dev[0].request("REMOVE_NETWORK all")
1290 dev[0].wait_disconnected()
1291
1292 with fail_test(dev[0], 1, "hash_nt_password_hash;eap_leap_process_response"):
1293 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1294 eap="LEAP", identity="user", password="password",
1295 wait_connect=False)
1296 wait_fail_trigger(dev[0], "GET_FAIL")
1297 dev[0].request("REMOVE_NETWORK all")
1298 dev[0].wait_disconnected()
1299
1300 with alloc_fail(dev[0], 1, "eap_leap_getKey"):
1301 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1302 eap="LEAP", identity="user",
1303 password_hex="hash:8846f7eaee8fb117ad06bdd830b7586c",
1304 wait_connect=False)
1305 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
1306 dev[0].request("REMOVE_NETWORK all")
1307 dev[0].wait_disconnected()
1308
1309 with fail_test(dev[0], 1, "eap_leap_getKey"):
1310 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1311 eap="LEAP", identity="user",
1312 password_hex="hash:8846f7eaee8fb117ad06bdd830b7586c",
1313 wait_connect=False)
1314 wait_fail_trigger(dev[0], "GET_FAIL")
1315 dev[0].request("REMOVE_NETWORK all")
1316 dev[0].wait_disconnected()
1317
1318 with fail_test(dev[0], 1, "nt_password_hash;eap_leap_getKey"):
1319 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1320 eap="LEAP", identity="user", password="password",
1321 wait_connect=False)
1322 wait_fail_trigger(dev[0], "GET_FAIL")
1323 dev[0].request("REMOVE_NETWORK all")
1324 dev[0].wait_disconnected()
1325
1326 with fail_test(dev[0], 1, "hash_nt_password_hash;eap_leap_getKey"):
e4e99927
JM
1327 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1328 eap="LEAP", identity="user", password="password",
1329 wait_connect=False)
1330 wait_fail_trigger(dev[0], "GET_FAIL")
1331 dev[0].request("REMOVE_NETWORK all")
1332 dev[0].wait_disconnected()
1333
1334 with fail_test(dev[0], 1,
1335 "nt_challenge_response;eap_leap_process_request"):
e114e999
JM
1336 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1337 eap="LEAP", identity="user", password="password",
1338 wait_connect=False)
1339 wait_fail_trigger(dev[0], "GET_FAIL")
1340 dev[0].request("REMOVE_NETWORK all")
1341 dev[0].wait_disconnected()
1342 finally:
1343 stop_radius_server(srv)
1344
8604a68e
JM
1345def test_eap_proto_md5(dev, apdev):
1346 """EAP-MD5 protocol tests"""
e7ac04ce
JM
1347 check_eap_capa(dev[0], "MD5")
1348
8604a68e 1349 def md5_handler(ctx, req):
55845e19 1350 logger.info("md5_handler - RX " + binascii.hexlify(req).decode())
8604a68e
JM
1351 if 'num' not in ctx:
1352 ctx['num'] = 0
1353 ctx['num'] = ctx['num'] + 1
1354 if 'id' not in ctx:
1355 ctx['id'] = 1
1356 ctx['id'] = (ctx['id'] + 1) % 256
1357
1358 if ctx['num'] == 1:
1359 logger.info("Test: Missing payload")
1360 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
1361 4 + 1,
1362 EAP_TYPE_MD5)
1363
1364 if ctx['num'] == 2:
1365 logger.info("Test: Zero-length challenge")
1366 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1367 4 + 1 + 1,
1368 EAP_TYPE_MD5,
1369 0)
1370
1371 if ctx['num'] == 3:
1372 logger.info("Test: Truncated challenge")
1373 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1374 4 + 1 + 1,
1375 EAP_TYPE_MD5,
1376 1)
1377
1378 if ctx['num'] == 4:
1379 logger.info("Test: Shortest possible challenge and name")
1380 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
1381 4 + 1 + 3,
1382 EAP_TYPE_MD5,
1383 1, 0xaa, ord('n'))
1384
1385 return None
1386
1387 srv = start_radius_server(md5_handler)
8604a68e
JM
1388
1389 try:
5eee514d 1390 hapd = start_ap(apdev[0])
9efd3447 1391 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
8604a68e
JM
1392
1393 for i in range(0, 4):
1394 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1395 eap="MD5", identity="user", password="password",
1396 wait_connect=False)
1397 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15)
1398 if ev is None:
1399 raise Exception("Timeout on EAP start")
1400 time.sleep(0.1)
1401 dev[0].request("REMOVE_NETWORK all")
1402 finally:
1403 stop_radius_server(srv)
d5c14b25 1404
d5482411
JM
1405def test_eap_proto_md5_errors(dev, apdev):
1406 """EAP-MD5 local error cases"""
1407 check_eap_capa(dev[0], "MD5")
1408 params = hostapd.wpa2_eap_params(ssid="eap-test")
8b8a1864 1409 hapd = hostapd.add_ap(apdev[0], params)
9efd3447 1410 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
d5482411
JM
1411
1412 with fail_test(dev[0], 1, "chap_md5"):
1413 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1414 eap="MD5", identity="phase1-user", password="password",
1415 wait_connect=False)
1416 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=15)
1417 if ev is None:
1418 raise Exception("Timeout on EAP start")
1419 dev[0].request("REMOVE_NETWORK all")
1420 dev[0].wait_disconnected()
1421
1422 with alloc_fail(dev[0], 1, "eap_msg_alloc;eap_md5_process"):
1423 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1424 eap="MD5", identity="phase1-user", password="password",
1425 wait_connect=False)
1426 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=15)
1427 if ev is None:
1428 raise Exception("Timeout on EAP start")
1429 time.sleep(0.1)
1430 dev[0].request("REMOVE_NETWORK all")
1431
d5c14b25
JM
1432def test_eap_proto_otp(dev, apdev):
1433 """EAP-OTP protocol tests"""
1434 def otp_handler(ctx, req):
55845e19 1435 logger.info("otp_handler - RX " + binascii.hexlify(req).decode())
d5c14b25
JM
1436 if 'num' not in ctx:
1437 ctx['num'] = 0
1438 ctx['num'] = ctx['num'] + 1
1439 if 'id' not in ctx:
1440 ctx['id'] = 1
1441 ctx['id'] = (ctx['id'] + 1) % 256
1442
1443 if ctx['num'] == 1:
1444 logger.info("Test: Empty payload")
1445 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
1446 4 + 1,
1447 EAP_TYPE_OTP)
1448 if ctx['num'] == 2:
1449 logger.info("Test: Success")
1450 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'],
1451 4)
1452
1453 if ctx['num'] == 3:
1454 logger.info("Test: Challenge included")
1455 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1456 4 + 1 + 1,
1457 EAP_TYPE_OTP,
1458 ord('A'))
1459 if ctx['num'] == 4:
1460 logger.info("Test: Success")
1461 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'],
1462 4)
1463
1464 return None
1465
1466 srv = start_radius_server(otp_handler)
d5c14b25
JM
1467
1468 try:
5eee514d 1469 hapd = start_ap(apdev[0])
9efd3447 1470 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
d5c14b25
JM
1471
1472 for i in range(0, 1):
1473 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1474 eap="OTP", identity="user", password="password",
1475 wait_connect=False)
1476 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
1477 timeout=15)
1478 if ev is None:
1479 raise Exception("Timeout on EAP start")
1480 time.sleep(0.1)
1481 dev[0].request("REMOVE_NETWORK all")
1482
1483 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1484 eap="OTP", identity="user", wait_connect=False)
1485 ev = dev[0].wait_event(["CTRL-REQ-OTP"])
1486 if ev is None:
1487 raise Exception("Request for password timed out")
1488 id = ev.split(':')[0].split('-')[-1]
1489 dev[0].request("CTRL-RSP-OTP-" + id + ":password")
1490 ev = dev[0].wait_event("CTRL-EVENT-EAP-SUCCESS")
1491 if ev is None:
1492 raise Exception("Success not reported")
1493 finally:
1494 stop_radius_server(srv)
2e9f8ee7 1495
2386bb97
JM
1496def test_eap_proto_otp_errors(dev, apdev):
1497 """EAP-OTP local error cases"""
1498 def otp_handler2(ctx, req):
55845e19 1499 logger.info("otp_handler2 - RX " + binascii.hexlify(req).decode())
2386bb97
JM
1500 if 'num' not in ctx:
1501 ctx['num'] = 0
1502 ctx['num'] = ctx['num'] + 1
1503 if 'id' not in ctx:
1504 ctx['id'] = 1
1505 ctx['id'] = (ctx['id'] + 1) % 256
1506 idx = 0
1507
1508 idx += 1
1509 if ctx['num'] == idx:
1510 logger.info("Test: Challenge included")
1511 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1512 4 + 1 + 1,
1513 EAP_TYPE_OTP,
1514 ord('A'))
1515
1516 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
1517
1518 srv = start_radius_server(otp_handler2)
1519
1520 try:
5eee514d 1521 hapd = start_ap(apdev[0])
9efd3447 1522 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
2386bb97
JM
1523
1524 with alloc_fail(dev[0], 1, "eap_msg_alloc;eap_otp_process"):
1525 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1526 eap="OTP", identity="user", password="password",
1527 wait_connect=False)
1528 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
1529 dev[0].request("REMOVE_NETWORK all")
1530 dev[0].wait_disconnected()
1531 finally:
1532 stop_radius_server(srv)
1533
2e9f8ee7
JM
1534EAP_GPSK_OPCODE_GPSK_1 = 1
1535EAP_GPSK_OPCODE_GPSK_2 = 2
1536EAP_GPSK_OPCODE_GPSK_3 = 3
1537EAP_GPSK_OPCODE_GPSK_4 = 4
1538EAP_GPSK_OPCODE_FAIL = 5
1539EAP_GPSK_OPCODE_PROTECTED_FAIL = 6
1540
1541def test_eap_proto_gpsk(dev, apdev):
1542 """EAP-GPSK protocol tests"""
1543 def gpsk_handler(ctx, req):
55845e19 1544 logger.info("gpsk_handler - RX " + binascii.hexlify(req).decode())
2e9f8ee7
JM
1545 if 'num' not in ctx:
1546 ctx['num'] = 0
1547 ctx['num'] = ctx['num'] + 1
1548 if 'id' not in ctx:
1549 ctx['id'] = 1
1550 ctx['id'] = (ctx['id'] + 1) % 256
1551
1552 idx = 0
1553
1554 idx += 1
1555 if ctx['num'] == idx:
1556 logger.info("Test: Missing payload")
1557 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
1558 4 + 1,
1559 EAP_TYPE_GPSK)
1560
1561 idx += 1
1562 if ctx['num'] == idx:
1563 logger.info("Test: Unknown opcode")
1564 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1565 4 + 1 + 1,
1566 EAP_TYPE_GPSK,
1567 255)
1568
1569 idx += 1
1570 if ctx['num'] == idx:
1571 logger.info("Test: Unexpected GPSK-3")
1572 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1573 4 + 1 + 1,
1574 EAP_TYPE_GPSK,
1575 EAP_GPSK_OPCODE_GPSK_3)
1576
1577 idx += 1
1578 if ctx['num'] == idx:
1579 logger.info("Test: GPSK-1 Too short GPSK-1")
1580 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1581 4 + 1 + 1,
1582 EAP_TYPE_GPSK,
1583 EAP_GPSK_OPCODE_GPSK_1)
1584
1585 idx += 1
1586 if ctx['num'] == idx:
1587 logger.info("Test: GPSK-1 Truncated ID_Server")
1588 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
1589 4 + 1 + 1 + 2,
1590 EAP_TYPE_GPSK,
1591 EAP_GPSK_OPCODE_GPSK_1, 1)
1592
1593 idx += 1
1594 if ctx['num'] == idx:
1595 logger.info("Test: GPSK-1 Missing RAND_Server")
1596 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
1597 4 + 1 + 1 + 2,
1598 EAP_TYPE_GPSK,
1599 EAP_GPSK_OPCODE_GPSK_1, 0)
1600
1601 idx += 1
1602 if ctx['num'] == idx:
1603 logger.info("Test: GPSK-1 Missing CSuite_List")
1604 return struct.pack(">BBHBBH8L", EAP_CODE_REQUEST, ctx['id'],
1605 4 + 1 + 1 + 2 + 32,
1606 EAP_TYPE_GPSK,
1607 EAP_GPSK_OPCODE_GPSK_1, 0,
1608 0, 0, 0, 0, 0, 0, 0, 0)
1609
1610 idx += 1
1611 if ctx['num'] == idx:
1612 logger.info("Test: GPSK-1 Truncated CSuite_List")
1613 return struct.pack(">BBHBBH8LH", EAP_CODE_REQUEST, ctx['id'],
1614 4 + 1 + 1 + 2 + 32 + 2,
1615 EAP_TYPE_GPSK,
1616 EAP_GPSK_OPCODE_GPSK_1, 0,
1617 0, 0, 0, 0, 0, 0, 0, 0,
1618 1)
1619
1620 idx += 1
1621 if ctx['num'] == idx:
1622 logger.info("Test: GPSK-1 Empty CSuite_List")
1623 return struct.pack(">BBHBBH8LH", EAP_CODE_REQUEST, ctx['id'],
1624 4 + 1 + 1 + 2 + 32 + 2,
1625 EAP_TYPE_GPSK,
1626 EAP_GPSK_OPCODE_GPSK_1, 0,
1627 0, 0, 0, 0, 0, 0, 0, 0,
1628 0)
1629
1630 idx += 1
1631 if ctx['num'] == idx:
1632 logger.info("Test: GPSK-1 Invalid CSuite_List")
1633 return struct.pack(">BBHBBH8LHB", EAP_CODE_REQUEST, ctx['id'],
1634 4 + 1 + 1 + 2 + 32 + 2 + 1,
1635 EAP_TYPE_GPSK,
1636 EAP_GPSK_OPCODE_GPSK_1, 0,
1637 0, 0, 0, 0, 0, 0, 0, 0,
1638 1, 0)
1639
1640 idx += 1
1641 if ctx['num'] == idx:
1642 logger.info("Test: GPSK-1 No supported CSuite")
1643 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
1644 4 + 1 + 1 + 2 + 32 + 2 + 6,
1645 EAP_TYPE_GPSK,
1646 EAP_GPSK_OPCODE_GPSK_1, 0,
1647 0, 0, 0, 0, 0, 0, 0, 0,
1648 6, 0, 0)
1649
1650 idx += 1
1651 if ctx['num'] == idx:
1652 logger.info("Test: GPSK-1 Supported CSuite")
1653 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
1654 4 + 1 + 1 + 2 + 32 + 2 + 6,
1655 EAP_TYPE_GPSK,
1656 EAP_GPSK_OPCODE_GPSK_1, 0,
1657 0, 0, 0, 0, 0, 0, 0, 0,
1658 6, 0, 1)
1659 idx += 1
1660 if ctx['num'] == idx:
1661 logger.info("Test: Unexpected GPSK-1")
1662 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
1663 4 + 1 + 1 + 2 + 32 + 2 + 6,
1664 EAP_TYPE_GPSK,
1665 EAP_GPSK_OPCODE_GPSK_1, 0,
1666 0, 0, 0, 0, 0, 0, 0, 0,
1667 6, 0, 1)
1668
1669 idx += 1
1670 if ctx['num'] == idx:
1671 logger.info("Test: GPSK-1 Supported CSuite but too short key")
1672 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
1673 4 + 1 + 1 + 2 + 32 + 2 + 6,
1674 EAP_TYPE_GPSK,
1675 EAP_GPSK_OPCODE_GPSK_1, 0,
1676 0, 0, 0, 0, 0, 0, 0, 0,
1677 6, 0, 1)
1678
1679 idx += 1
1680 if ctx['num'] == idx:
1681 logger.info("Test: GPSK-1 Supported CSuite")
1682 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
1683 4 + 1 + 1 + 2 + 32 + 2 + 6,
1684 EAP_TYPE_GPSK,
1685 EAP_GPSK_OPCODE_GPSK_1, 0,
1686 0, 0, 0, 0, 0, 0, 0, 0,
1687 6, 0, 1)
1688 idx += 1
1689 if ctx['num'] == idx:
1690 logger.info("Test: Too short GPSK-3")
1691 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1692 4 + 1 + 1,
1693 EAP_TYPE_GPSK,
1694 EAP_GPSK_OPCODE_GPSK_3)
1695
1696 idx += 1
1697 if ctx['num'] == idx:
1698 logger.info("Test: GPSK-1 Supported CSuite")
1699 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
1700 4 + 1 + 1 + 2 + 32 + 2 + 6,
1701 EAP_TYPE_GPSK,
1702 EAP_GPSK_OPCODE_GPSK_1, 0,
1703 0, 0, 0, 0, 0, 0, 0, 0,
1704 6, 0, 1)
1705 idx += 1
1706 if ctx['num'] == idx:
1707 logger.info("Test: GPSK-3 Mismatch in RAND_Peer")
1708 return struct.pack(">BBHBB8L", EAP_CODE_REQUEST, ctx['id'],
1709 4 + 1 + 1 + 32,
1710 EAP_TYPE_GPSK,
1711 EAP_GPSK_OPCODE_GPSK_3,
1712 0, 0, 0, 0, 0, 0, 0, 0)
1713
1714 idx += 1
1715 if ctx['num'] == idx:
1716 logger.info("Test: GPSK-1 Supported CSuite")
1717 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
1718 4 + 1 + 1 + 2 + 32 + 2 + 6,
1719 EAP_TYPE_GPSK,
1720 EAP_GPSK_OPCODE_GPSK_1, 0,
1721 0, 0, 0, 0, 0, 0, 0, 0,
1722 6, 0, 1)
1723 idx += 1
1724 if ctx['num'] == idx:
1725 logger.info("Test: GPSK-3 Missing RAND_Server")
1726 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1727 4 + 1 + 1 + 32,
1728 EAP_TYPE_GPSK,
1729 EAP_GPSK_OPCODE_GPSK_3)
1730 msg += req[14:46]
1731 return msg
1732
1733 idx += 1
1734 if ctx['num'] == idx:
1735 logger.info("Test: GPSK-1 Supported CSuite")
1736 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
1737 4 + 1 + 1 + 2 + 32 + 2 + 6,
1738 EAP_TYPE_GPSK,
1739 EAP_GPSK_OPCODE_GPSK_1, 0,
1740 0, 0, 0, 0, 0, 0, 0, 0,
1741 6, 0, 1)
1742 idx += 1
1743 if ctx['num'] == idx:
1744 logger.info("Test: GPSK-3 Mismatch in RAND_Server")
1745 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1746 4 + 1 + 1 + 32 + 32,
1747 EAP_TYPE_GPSK,
1748 EAP_GPSK_OPCODE_GPSK_3)
1749 msg += req[14:46]
1750 msg += struct.pack(">8L", 1, 1, 1, 1, 1, 1, 1, 1)
1751 return msg
1752
1753 idx += 1
1754 if ctx['num'] == idx:
1755 logger.info("Test: GPSK-1 Supported CSuite")
1756 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
1757 4 + 1 + 1 + 2 + 32 + 2 + 6,
1758 EAP_TYPE_GPSK,
1759 EAP_GPSK_OPCODE_GPSK_1, 0,
1760 0, 0, 0, 0, 0, 0, 0, 0,
1761 6, 0, 1)
1762 idx += 1
1763 if ctx['num'] == idx:
1764 logger.info("Test: GPSK-3 Missing ID_Server")
1765 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1766 4 + 1 + 1 + 32 + 32,
1767 EAP_TYPE_GPSK,
1768 EAP_GPSK_OPCODE_GPSK_3)
1769 msg += req[14:46]
1770 msg += struct.pack(">8L", 0, 0, 0, 0, 0, 0, 0, 0)
1771 return msg
1772
1773 idx += 1
1774 if ctx['num'] == idx:
1775 logger.info("Test: GPSK-1 Supported CSuite")
1776 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
1777 4 + 1 + 1 + 2 + 32 + 2 + 6,
1778 EAP_TYPE_GPSK,
1779 EAP_GPSK_OPCODE_GPSK_1, 0,
1780 0, 0, 0, 0, 0, 0, 0, 0,
1781 6, 0, 1)
1782 idx += 1
1783 if ctx['num'] == idx:
1784 logger.info("Test: GPSK-3 Truncated ID_Server")
1785 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1786 4 + 1 + 1 + 32 + 32 + 2,
1787 EAP_TYPE_GPSK,
1788 EAP_GPSK_OPCODE_GPSK_3)
1789 msg += req[14:46]
1790 msg += struct.pack(">8LH", 0, 0, 0, 0, 0, 0, 0, 0, 1)
1791 return msg
1792
1793 idx += 1
1794 if ctx['num'] == idx:
1795 logger.info("Test: GPSK-1 Supported CSuite")
1796 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
1797 4 + 1 + 1 + 2 + 32 + 2 + 6,
1798 EAP_TYPE_GPSK,
1799 EAP_GPSK_OPCODE_GPSK_1, 0,
1800 0, 0, 0, 0, 0, 0, 0, 0,
1801 6, 0, 1)
1802 idx += 1
1803 if ctx['num'] == idx:
1804 logger.info("Test: GPSK-3 Mismatch in ID_Server")
1805 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1806 4 + 1 + 1 + 32 + 32 + 3,
1807 EAP_TYPE_GPSK,
1808 EAP_GPSK_OPCODE_GPSK_3)
1809 msg += req[14:46]
1810 msg += struct.pack(">8LHB", 0, 0, 0, 0, 0, 0, 0, 0, 1, ord('B'))
1811 return msg
1812
1813 idx += 1
1814 if ctx['num'] == idx:
1815 logger.info("Test: GPSK-1 Supported CSuite")
1816 return struct.pack(">BBHBBHB8LHLH", EAP_CODE_REQUEST, ctx['id'],
1817 4 + 1 + 1 + 3 + 32 + 2 + 6,
1818 EAP_TYPE_GPSK,
1819 EAP_GPSK_OPCODE_GPSK_1, 1, ord('A'),
1820 0, 0, 0, 0, 0, 0, 0, 0,
1821 6, 0, 1)
1822 idx += 1
1823 if ctx['num'] == idx:
1824 logger.info("Test: GPSK-3 Mismatch in ID_Server (same length)")
1825 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1826 4 + 1 + 1 + 32 + 32 + 3,
1827 EAP_TYPE_GPSK,
1828 EAP_GPSK_OPCODE_GPSK_3)
1829 msg += req[15:47]
1830 msg += struct.pack(">8LHB", 0, 0, 0, 0, 0, 0, 0, 0, 1, ord('B'))
1831 return msg
1832
1833 idx += 1
1834 if ctx['num'] == idx:
1835 logger.info("Test: GPSK-1 Supported CSuite")
1836 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
1837 4 + 1 + 1 + 2 + 32 + 2 + 6,
1838 EAP_TYPE_GPSK,
1839 EAP_GPSK_OPCODE_GPSK_1, 0,
1840 0, 0, 0, 0, 0, 0, 0, 0,
1841 6, 0, 1)
1842 idx += 1
1843 if ctx['num'] == idx:
1844 logger.info("Test: GPSK-3 Missing CSuite_Sel")
1845 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1846 4 + 1 + 1 + 32 + 32 + 2,
1847 EAP_TYPE_GPSK,
1848 EAP_GPSK_OPCODE_GPSK_3)
1849 msg += req[14:46]
1850 msg += struct.pack(">8LH", 0, 0, 0, 0, 0, 0, 0, 0, 0)
1851 return msg
1852
1853 idx += 1
1854 if ctx['num'] == idx:
1855 logger.info("Test: GPSK-1 Supported CSuite")
1856 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
1857 4 + 1 + 1 + 2 + 32 + 2 + 6,
1858 EAP_TYPE_GPSK,
1859 EAP_GPSK_OPCODE_GPSK_1, 0,
1860 0, 0, 0, 0, 0, 0, 0, 0,
1861 6, 0, 1)
1862 idx += 1
1863 if ctx['num'] == idx:
1864 logger.info("Test: GPSK-3 Mismatch in CSuite_Sel")
1865 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1866 4 + 1 + 1 + 32 + 32 + 2 + 6,
1867 EAP_TYPE_GPSK,
1868 EAP_GPSK_OPCODE_GPSK_3)
1869 msg += req[14:46]
1870 msg += struct.pack(">8LHLH", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2)
1871 return msg
1872
1873 idx += 1
1874 if ctx['num'] == idx:
1875 logger.info("Test: GPSK-1 Supported CSuite")
1876 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
1877 4 + 1 + 1 + 2 + 32 + 2 + 6,
1878 EAP_TYPE_GPSK,
1879 EAP_GPSK_OPCODE_GPSK_1, 0,
1880 0, 0, 0, 0, 0, 0, 0, 0,
1881 6, 0, 1)
1882 idx += 1
1883 if ctx['num'] == idx:
1884 logger.info("Test: GPSK-3 Missing len(PD_Payload_Block)")
1885 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1886 4 + 1 + 1 + 32 + 32 + 2 + 6,
1887 EAP_TYPE_GPSK,
1888 EAP_GPSK_OPCODE_GPSK_3)
1889 msg += req[14:46]
1890 msg += struct.pack(">8LHLH", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1)
1891 return msg
1892
1893 idx += 1
1894 if ctx['num'] == idx:
1895 logger.info("Test: GPSK-1 Supported CSuite")
1896 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
1897 4 + 1 + 1 + 2 + 32 + 2 + 6,
1898 EAP_TYPE_GPSK,
1899 EAP_GPSK_OPCODE_GPSK_1, 0,
1900 0, 0, 0, 0, 0, 0, 0, 0,
1901 6, 0, 1)
1902 idx += 1
1903 if ctx['num'] == idx:
1904 logger.info("Test: GPSK-3 Truncated PD_Payload_Block")
1905 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1906 4 + 1 + 1 + 32 + 32 + 2 + 6 + 2,
1907 EAP_TYPE_GPSK,
1908 EAP_GPSK_OPCODE_GPSK_3)
1909 msg += req[14:46]
1910 msg += struct.pack(">8LHLHH", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1)
1911 return msg
1912
1913 idx += 1
1914 if ctx['num'] == idx:
1915 logger.info("Test: GPSK-1 Supported CSuite")
1916 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
1917 4 + 1 + 1 + 2 + 32 + 2 + 6,
1918 EAP_TYPE_GPSK,
1919 EAP_GPSK_OPCODE_GPSK_1, 0,
1920 0, 0, 0, 0, 0, 0, 0, 0,
1921 6, 0, 1)
1922 idx += 1
1923 if ctx['num'] == idx:
1924 logger.info("Test: GPSK-3 Missing MAC")
1925 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1926 4 + 1 + 1 + 32 + 32 + 2 + 6 + 3,
1927 EAP_TYPE_GPSK,
1928 EAP_GPSK_OPCODE_GPSK_3)
1929 msg += req[14:46]
1930 msg += struct.pack(">8LHLHHB",
1931 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 123)
1932 return msg
1933
1934 idx += 1
1935 if ctx['num'] == idx:
1936 logger.info("Test: GPSK-1 Supported CSuite")
1937 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
1938 4 + 1 + 1 + 2 + 32 + 2 + 6,
1939 EAP_TYPE_GPSK,
1940 EAP_GPSK_OPCODE_GPSK_1, 0,
1941 0, 0, 0, 0, 0, 0, 0, 0,
1942 6, 0, 1)
1943 idx += 1
1944 if ctx['num'] == idx:
1945 logger.info("Test: GPSK-3 Incorrect MAC")
1946 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1947 4 + 1 + 1 + 32 + 32 + 2 + 6 + 3 + 16,
1948 EAP_TYPE_GPSK,
1949 EAP_GPSK_OPCODE_GPSK_3)
1950 msg += req[14:46]
1951 msg += struct.pack(">8LHLHHB4L",
1952 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 123,
1953 0, 0, 0, 0)
1954 return msg
1955
1956 return None
1957
1958 srv = start_radius_server(gpsk_handler)
2e9f8ee7
JM
1959
1960 try:
5eee514d 1961 hapd = start_ap(apdev[0])
9efd3447 1962 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
2e9f8ee7
JM
1963
1964 for i in range(0, 27):
1965 if i == 12:
1966 pw = "short"
1967 else:
1968 pw = "abcdefghijklmnop0123456789abcdef"
1969 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1970 eap="GPSK", identity="user", password=pw,
1971 wait_connect=False)
1972 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
1973 timeout=15)
1974 if ev is None:
1975 raise Exception("Timeout on EAP start")
1976 time.sleep(0.05)
1977 dev[0].request("REMOVE_NETWORK all")
1978 finally:
1979 stop_radius_server(srv)
30d62b7a
JM
1980
1981EAP_EKE_ID = 1
1982EAP_EKE_COMMIT = 2
1983EAP_EKE_CONFIRM = 3
1984EAP_EKE_FAILURE = 4
1985
1986def test_eap_proto_eke(dev, apdev):
1987 """EAP-EKE protocol tests"""
1988 def eke_handler(ctx, req):
55845e19 1989 logger.info("eke_handler - RX " + binascii.hexlify(req).decode())
30d62b7a
JM
1990 if 'num' not in ctx:
1991 ctx['num'] = 0
1992 ctx['num'] = ctx['num'] + 1
1993 if 'id' not in ctx:
1994 ctx['id'] = 1
1995 ctx['id'] = (ctx['id'] + 1) % 256
1996
1997 idx = 0
1998
1999 idx += 1
2000 if ctx['num'] == idx:
2001 logger.info("Test: Missing payload")
2002 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
2003 4 + 1,
2004 EAP_TYPE_EKE)
2005
2006 idx += 1
2007 if ctx['num'] == idx:
2008 logger.info("Test: Unknown exchange")
2009 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
2010 4 + 1 + 1,
2011 EAP_TYPE_EKE,
2012 255)
2013
2014 idx += 1
2015 if ctx['num'] == idx:
2016 logger.info("Test: No NumProposals in EAP-EKE-ID/Request")
2017 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
2018 4 + 1 + 1,
2019 EAP_TYPE_EKE,
2020 EAP_EKE_ID)
2021 idx += 1
2022 if ctx['num'] == idx:
2023 logger.info("Test: EAP-Failure")
2024 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
2025
2026 idx += 1
2027 if ctx['num'] == idx:
2028 logger.info("Test: NumProposals=0 in EAP-EKE-ID/Request")
2029 return struct.pack(">BBHBBB", EAP_CODE_REQUEST, ctx['id'],
2030 4 + 1 + 1 + 1,
2031 EAP_TYPE_EKE,
2032 EAP_EKE_ID,
2033 0)
2034 idx += 1
2035 if ctx['num'] == idx:
2036 logger.info("Test: EAP-Failure")
2037 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
2038
2039 idx += 1
2040 if ctx['num'] == idx:
2041 logger.info("Test: Truncated Proposals list in EAP-EKE-ID/Request")
2042 return struct.pack(">BBHBBBB4B", EAP_CODE_REQUEST, ctx['id'],
2043 4 + 1 + 1 + 2 + 4,
2044 EAP_TYPE_EKE,
2045 EAP_EKE_ID,
2046 2, 0, 0, 0, 0, 0)
2047 idx += 1
2048 if ctx['num'] == idx:
2049 logger.info("Test: EAP-Failure")
2050 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
2051
2052 idx += 1
2053 if ctx['num'] == idx:
2054 logger.info("Test: Unsupported proposals in EAP-EKE-ID/Request")
2055 return struct.pack(">BBHBBBB4B4B4B4B", EAP_CODE_REQUEST, ctx['id'],
2056 4 + 1 + 1 + 2 + 4 * 4,
2057 EAP_TYPE_EKE,
2058 EAP_EKE_ID,
2059 4, 0,
2060 0, 0, 0, 0,
2061 3, 0, 0, 0,
2062 3, 1, 0, 0,
2063 3, 1, 1, 0)
2064 idx += 1
2065 if ctx['num'] == idx:
2066 logger.info("Test: EAP-Failure")
2067 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
2068
2069 idx += 1
2070 if ctx['num'] == idx:
2071 logger.info("Test: Missing IDType/Identity in EAP-EKE-ID/Request")
2072 return struct.pack(">BBHBBBB4B4B4B4B4B",
2073 EAP_CODE_REQUEST, ctx['id'],
2074 4 + 1 + 1 + 2 + 5 * 4,
2075 EAP_TYPE_EKE,
2076 EAP_EKE_ID,
2077 5, 0,
2078 0, 0, 0, 0,
2079 3, 0, 0, 0,
2080 3, 1, 0, 0,
2081 3, 1, 1, 0,
2082 3, 1, 1, 1)
2083 idx += 1
2084 if ctx['num'] == idx:
2085 logger.info("Test: EAP-Failure")
2086 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
2087
2088 idx += 1
2089 if ctx['num'] == idx:
2090 logger.info("Test: Valid EAP-EKE-ID/Request")
2091 return struct.pack(">BBHBBBB4BB",
2092 EAP_CODE_REQUEST, ctx['id'],
2093 4 + 1 + 1 + 2 + 4 + 1,
2094 EAP_TYPE_EKE,
2095 EAP_EKE_ID,
2096 1, 0,
2097 3, 1, 1, 1,
2098 255)
2099 idx += 1
2100 if ctx['num'] == idx:
2101 logger.info("Test: Unexpected EAP-EKE-ID/Request")
2102 return struct.pack(">BBHBBBB4BB",
2103 EAP_CODE_REQUEST, ctx['id'],
2104 4 + 1 + 1 + 2 + 4 + 1,
2105 EAP_TYPE_EKE,
2106 EAP_EKE_ID,
2107 1, 0,
2108 3, 1, 1, 1,
2109 255)
2110 idx += 1
2111 if ctx['num'] == idx:
2112 logger.info("Test: EAP-Failure")
2113 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
2114
2115 idx += 1
2116 if ctx['num'] == idx:
2117 logger.info("Test: Valid EAP-EKE-ID/Request")
2118 return struct.pack(">BBHBBBB4BB",
2119 EAP_CODE_REQUEST, ctx['id'],
2120 4 + 1 + 1 + 2 + 4 + 1,
2121 EAP_TYPE_EKE,
2122 EAP_EKE_ID,
2123 1, 0,
2124 3, 1, 1, 1,
2125 255)
2126 idx += 1
2127 if ctx['num'] == idx:
2128 logger.info("Test: Unexpected EAP-EKE-Confirm/Request")
2129 return struct.pack(">BBHBB",
2130 EAP_CODE_REQUEST, ctx['id'],
2131 4 + 1 + 1,
2132 EAP_TYPE_EKE,
2133 EAP_EKE_CONFIRM)
2134 idx += 1
2135 if ctx['num'] == idx:
2136 logger.info("Test: EAP-Failure")
2137 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
2138
2139 idx += 1
2140 if ctx['num'] == idx:
2141 logger.info("Test: Too short EAP-EKE-Failure/Request")
2142 return struct.pack(">BBHBB",
2143 EAP_CODE_REQUEST, ctx['id'],
2144 4 + 1 + 1,
2145 EAP_TYPE_EKE,
2146 EAP_EKE_FAILURE)
2147 idx += 1
2148 if ctx['num'] == idx:
2149 logger.info("Test: EAP-Failure")
2150 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
2151
2152 idx += 1
2153 if ctx['num'] == idx:
2154 logger.info("Test: Unexpected EAP-EKE-Commit/Request")
2155 return struct.pack(">BBHBB",
2156 EAP_CODE_REQUEST, ctx['id'],
2157 4 + 1 + 1,
2158 EAP_TYPE_EKE,
2159 EAP_EKE_COMMIT)
2160 idx += 1
2161 if ctx['num'] == idx:
2162 logger.info("Test: EAP-Failure")
2163 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
2164
2165 idx += 1
2166 if ctx['num'] == idx:
2167 logger.info("Test: Valid EAP-EKE-ID/Request")
2168 return struct.pack(">BBHBBBB4BB",
2169 EAP_CODE_REQUEST, ctx['id'],
2170 4 + 1 + 1 + 2 + 4 + 1,
2171 EAP_TYPE_EKE,
2172 EAP_EKE_ID,
2173 1, 0,
2174 3, 1, 1, 1,
2175 255)
2176 idx += 1
2177 if ctx['num'] == idx:
2178 logger.info("Test: Too short EAP-EKE-Commit/Request")
2179 return struct.pack(">BBHBB",
2180 EAP_CODE_REQUEST, ctx['id'],
2181 4 + 1 + 1,
2182 EAP_TYPE_EKE,
2183 EAP_EKE_COMMIT)
2184 idx += 1
2185 if ctx['num'] == idx:
2186 logger.info("Test: EAP-Failure")
2187 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
2188
2189 idx += 1
2190 if ctx['num'] == idx:
2191 logger.info("Test: Valid EAP-EKE-ID/Request")
2192 return struct.pack(">BBHBBBB4BB",
2193 EAP_CODE_REQUEST, ctx['id'],
2194 4 + 1 + 1 + 2 + 4 + 1,
2195 EAP_TYPE_EKE,
2196 EAP_EKE_ID,
2197 1, 0,
2198 1, 1, 1, 1,
2199 255)
2200 idx += 1
2201 if ctx['num'] == idx:
2202 logger.info("Test: All zeroes DHComponent_S and empty CBvalue in EAP-EKE-Commit/Request")
2203 return struct.pack(">BBHBB4L32L",
2204 EAP_CODE_REQUEST, ctx['id'],
2205 4 + 1 + 1 + 16 + 128,
2206 EAP_TYPE_EKE,
2207 EAP_EKE_COMMIT,
2208 0, 0, 0, 0,
2209 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2210 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
2211 idx += 1
2212 if ctx['num'] == idx:
2213 logger.info("Test: Too short EAP-EKE-Confirm/Request")
2214 return struct.pack(">BBHBB",
2215 EAP_CODE_REQUEST, ctx['id'],
2216 4 + 1 + 1,
2217 EAP_TYPE_EKE,
2218 EAP_EKE_CONFIRM)
2219 idx += 1
2220 if ctx['num'] == idx:
2221 logger.info("Test: EAP-Failure")
2222 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
2223
2224 idx += 1
2225 if ctx['num'] == idx:
2226 logger.info("Test: Valid EAP-EKE-ID/Request")
2227 return struct.pack(">BBHBBBB4BB",
2228 EAP_CODE_REQUEST, ctx['id'],
2229 4 + 1 + 1 + 2 + 4 + 1,
2230 EAP_TYPE_EKE,
2231 EAP_EKE_ID,
2232 1, 0,
2233 1, 1, 1, 1,
2234 255)
2235 idx += 1
2236 if ctx['num'] == idx:
2237 logger.info("Test: All zeroes DHComponent_S and empty CBvalue in EAP-EKE-Commit/Request")
2238 return struct.pack(">BBHBB4L32L",
2239 EAP_CODE_REQUEST, ctx['id'],
2240 4 + 1 + 1 + 16 + 128,
2241 EAP_TYPE_EKE,
2242 EAP_EKE_COMMIT,
2243 0, 0, 0, 0,
2244 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2245 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
2246 idx += 1
2247 if ctx['num'] == idx:
2248 logger.info("Test: Invalid PNonce_PS and Auth_S values in EAP-EKE-Confirm/Request")
2249 return struct.pack(">BBHBB4L8L5L5L",
2250 EAP_CODE_REQUEST, ctx['id'],
2251 4 + 1 + 1 + 16 + 2 * 16 + 20 + 20,
2252 EAP_TYPE_EKE,
2253 EAP_EKE_CONFIRM,
2254 0, 0, 0, 0,
2255 0, 0, 0, 0, 0, 0, 0, 0,
2256 0, 0, 0, 0, 0,
2257 0, 0, 0, 0, 0)
2258 idx += 1
2259 if ctx['num'] == idx:
2260 logger.info("Test: EAP-Failure")
2261 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
2262
2263 return None
2264
2265 srv = start_radius_server(eke_handler)
30d62b7a
JM
2266
2267 try:
5eee514d 2268 hapd = start_ap(apdev[0])
9efd3447 2269 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
30d62b7a
JM
2270
2271 for i in range(0, 14):
2272 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
2273 eap="EKE", identity="user", password="password",
2274 wait_connect=False)
2275 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
2276 timeout=15)
2277 if ev is None:
2278 raise Exception("Timeout on EAP start")
fab49f61 2279 if i in [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]:
30d62b7a
JM
2280 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"],
2281 timeout=10)
2282 if ev is None:
2283 raise Exception("Timeout on EAP failure")
2284 else:
2285 time.sleep(0.05)
2286 dev[0].request("REMOVE_NETWORK all")
2287 dev[0].dump_monitor()
2288 finally:
2289 stop_radius_server(srv)
09544316 2290
850e054c
JM
2291def eap_eke_test_fail(dev, phase1=None, success=False):
2292 dev.connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
0a0c4dc1 2293 eap="EKE", identity="eke user@domain", password="hello",
850e054c 2294 phase1=phase1, erp="1", wait_connect=False)
fab49f61
JM
2295 ev = dev.wait_event(["CTRL-EVENT-EAP-FAILURE",
2296 "CTRL-EVENT-EAP-SUCCESS"], timeout=5)
850e054c
JM
2297 if ev is None:
2298 raise Exception("Timeout on EAP failure")
2299 if not success and "CTRL-EVENT-EAP-FAILURE" not in ev:
2300 raise Exception("EAP did not fail during failure test")
2301 dev.request("REMOVE_NETWORK all")
2302 dev.wait_disconnected()
2303
2304def test_eap_proto_eke_errors(dev, apdev):
2305 """EAP-EKE local error cases"""
2306 check_eap_capa(dev[0], "EKE")
2307 params = hostapd.wpa2_eap_params(ssid="eap-test")
8b8a1864 2308 hapd = hostapd.add_ap(apdev[0], params)
9efd3447 2309 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
850e054c
JM
2310
2311 for i in range(1, 3):
2312 with alloc_fail(dev[0], i, "eap_eke_init"):
2313 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
2314 eap="EKE", identity="eke user", password="hello",
2315 wait_connect=False)
2316 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
2317 timeout=15)
2318 if ev is None:
2319 raise Exception("Timeout on EAP start")
2320 dev[0].request("REMOVE_NETWORK all")
2321 dev[0].wait_disconnected()
2322
fab49f61
JM
2323 tests = [(1, "eap_eke_dh_init", None),
2324 (1, "eap_eke_prf_hmac_sha1", "dhgroup=3 encr=1 prf=1 mac=1"),
2325 (1, "eap_eke_prf_hmac_sha256", "dhgroup=5 encr=1 prf=2 mac=2"),
2326 (1, "eap_eke_prf", None),
2327 (1, "os_get_random;eap_eke_dhcomp", None),
2328 (1, "aes_128_cbc_encrypt;eap_eke_dhcomp", None),
2329 (1, "aes_128_cbc_decrypt;eap_eke_shared_secret", None),
2330 (1, "eap_eke_prf;eap_eke_shared_secret", None),
2331 (1, "eap_eke_prfplus;eap_eke_derive_ke_ki", None),
2332 (1, "eap_eke_prfplus;eap_eke_derive_ka", None),
2333 (1, "eap_eke_prfplus;eap_eke_derive_msk", None),
2334 (1, "os_get_random;eap_eke_prot", None),
2335 (1, "aes_128_cbc_decrypt;eap_eke_decrypt_prot", None),
2336 (1, "eap_eke_derive_key;eap_eke_process_commit", None),
2337 (1, "eap_eke_dh_init;eap_eke_process_commit", None),
2338 (1, "eap_eke_shared_secret;eap_eke_process_commit", None),
2339 (1, "eap_eke_derive_ke_ki;eap_eke_process_commit", None),
2340 (1, "eap_eke_dhcomp;eap_eke_process_commit", None),
2341 (1, "os_get_random;eap_eke_process_commit", None),
2342 (1, "os_get_random;=eap_eke_process_commit", None),
2343 (1, "eap_eke_prot;eap_eke_process_commit", None),
2344 (1, "eap_eke_decrypt_prot;eap_eke_process_confirm", None),
2345 (1, "eap_eke_derive_ka;eap_eke_process_confirm", None),
2346 (1, "eap_eke_auth;eap_eke_process_confirm", None),
2347 (2, "eap_eke_auth;eap_eke_process_confirm", None),
2348 (1, "eap_eke_prot;eap_eke_process_confirm", None),
2349 (1, "eap_eke_derive_msk;eap_eke_process_confirm", None)]
850e054c
JM
2350 for count, func, phase1 in tests:
2351 with fail_test(dev[0], count, func):
2352 eap_eke_test_fail(dev[0], phase1)
2353
fab49f61
JM
2354 tests = [(1, "=eap_eke_derive_ke_ki", None),
2355 (1, "=eap_eke_derive_ka", None),
2356 (1, "=eap_eke_derive_msk", None),
2357 (1, "eap_eke_build_msg;eap_eke_process_id", None),
2358 (1, "wpabuf_alloc;eap_eke_process_id", None),
2359 (1, "=eap_eke_process_id", None),
2360 (1, "wpabuf_alloc;=eap_eke_process_id", None),
2361 (1, "wpabuf_alloc;eap_eke_process_id", None),
2362 (1, "eap_eke_build_msg;eap_eke_process_commit", None),
2363 (1, "wpabuf_resize;eap_eke_process_commit", None),
2364 (1, "eap_eke_build_msg;eap_eke_process_confirm", None)]
850e054c
JM
2365 for count, func, phase1 in tests:
2366 with alloc_fail(dev[0], count, func):
2367 eap_eke_test_fail(dev[0], phase1)
2368
fab49f61
JM
2369 tests = [(1, "eap_eke_getKey", None),
2370 (1, "eap_eke_get_emsk", None),
2371 (1, "eap_eke_get_session_id", None)]
850e054c
JM
2372 for count, func, phase1 in tests:
2373 with alloc_fail(dev[0], count, func):
2374 eap_eke_test_fail(dev[0], phase1, success=True)
2375
09544316
JM
2376EAP_PAX_OP_STD_1 = 0x01
2377EAP_PAX_OP_STD_2 = 0x02
2378EAP_PAX_OP_STD_3 = 0x03
2379EAP_PAX_OP_SEC_1 = 0x11
2380EAP_PAX_OP_SEC_2 = 0x12
2381EAP_PAX_OP_SEC_3 = 0x13
2382EAP_PAX_OP_SEC_4 = 0x14
2383EAP_PAX_OP_SEC_5 = 0x15
2384EAP_PAX_OP_ACK = 0x21
2385
2386EAP_PAX_FLAGS_MF = 0x01
2387EAP_PAX_FLAGS_CE = 0x02
2388EAP_PAX_FLAGS_AI = 0x04
2389
2390EAP_PAX_MAC_HMAC_SHA1_128 = 0x01
2391EAP_PAX_HMAC_SHA256_128 = 0x02
2392
2393EAP_PAX_DH_GROUP_NONE = 0x00
2394EAP_PAX_DH_GROUP_2048_MODP = 0x01
2395EAP_PAX_DH_GROUP_3072_MODP = 0x02
2396EAP_PAX_DH_GROUP_NIST_ECC_P_256 = 0x03
2397
2398EAP_PAX_PUBLIC_KEY_NONE = 0x00
2399EAP_PAX_PUBLIC_KEY_RSAES_OAEP = 0x01
2400EAP_PAX_PUBLIC_KEY_RSA_PKCS1_V1_5 = 0x02
2401EAP_PAX_PUBLIC_KEY_EL_GAMAL_NIST_ECC = 0x03
2402
2403EAP_PAX_ADE_VENDOR_SPECIFIC = 0x01
2404EAP_PAX_ADE_CLIENT_CHANNEL_BINDING = 0x02
2405EAP_PAX_ADE_SERVER_CHANNEL_BINDING = 0x03
2406
2407def test_eap_proto_pax(dev, apdev):
2408 """EAP-PAX protocol tests"""
2409 def pax_std_1(ctx):
2410 logger.info("Test: STD-1")
2411 ctx['id'] = 10
2412 return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'],
2413 4 + 1 + 5 + 2 + 32 + 16,
2414 EAP_TYPE_PAX,
2415 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128,
2416 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE,
2417 32, 0, 0, 0, 0, 0, 0, 0, 0,
2418 0x16, 0xc9, 0x08, 0x9d, 0x98, 0xa5, 0x6e, 0x1f,
2419 0xf0, 0xac, 0xcf, 0xc4, 0x66, 0xcd, 0x2d, 0xbf)
2420
2421 def pax_handler(ctx, req):
55845e19 2422 logger.info("pax_handler - RX " + binascii.hexlify(req).decode())
09544316
JM
2423 if 'num' not in ctx:
2424 ctx['num'] = 0
2425 ctx['num'] = ctx['num'] + 1
2426 if 'id' not in ctx:
2427 ctx['id'] = 1
2428 ctx['id'] = (ctx['id'] + 1) % 256
2429
2430 idx = 0
2431
2432 idx += 1
2433 if ctx['num'] == idx:
2434 logger.info("Test: Missing payload")
2435 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
2436 4 + 1,
2437 EAP_TYPE_PAX)
2438
2439 idx += 1
2440 if ctx['num'] == idx:
2441 logger.info("Test: Minimum length payload")
2442 return struct.pack(">BBHB4L", EAP_CODE_REQUEST, ctx['id'],
2443 4 + 1 + 16,
2444 EAP_TYPE_PAX,
2445 0, 0, 0, 0)
2446
2447 idx += 1
2448 if ctx['num'] == idx:
2449 logger.info("Test: Unsupported MAC ID")
2450 return struct.pack(">BBHBBBBBB4L", EAP_CODE_REQUEST, ctx['id'],
2451 4 + 1 + 5 + 16,
2452 EAP_TYPE_PAX,
2453 EAP_PAX_OP_STD_1, 0, 255, EAP_PAX_DH_GROUP_NONE,
2454 EAP_PAX_PUBLIC_KEY_NONE,
2455 0, 0, 0, 0)
2456
2457 idx += 1
2458 if ctx['num'] == idx:
2459 logger.info("Test: Unsupported DH Group ID")
2460 return struct.pack(">BBHBBBBBB4L", EAP_CODE_REQUEST, ctx['id'],
2461 4 + 1 + 5 + 16,
2462 EAP_TYPE_PAX,
2463 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128,
2464 255, EAP_PAX_PUBLIC_KEY_NONE,
2465 0, 0, 0, 0)
2466
2467 idx += 1
2468 if ctx['num'] == idx:
2469 logger.info("Test: Unsupported Public Key ID")
2470 return struct.pack(">BBHBBBBBB4L", EAP_CODE_REQUEST, ctx['id'],
2471 4 + 1 + 5 + 16,
2472 EAP_TYPE_PAX,
2473 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128,
2474 EAP_PAX_DH_GROUP_NONE, 255,
2475 0, 0, 0, 0)
2476
2477 idx += 1
2478 if ctx['num'] == idx:
2479 logger.info("Test: More fragments")
2480 return struct.pack(">BBHBBBBBB4L", EAP_CODE_REQUEST, ctx['id'],
2481 4 + 1 + 5 + 16,
2482 EAP_TYPE_PAX,
2483 EAP_PAX_OP_STD_1, EAP_PAX_FLAGS_MF,
2484 EAP_PAX_MAC_HMAC_SHA1_128,
2485 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE,
2486 0, 0, 0, 0)
2487
2488 idx += 1
2489 if ctx['num'] == idx:
2490 logger.info("Test: Invalid ICV")
2491 return struct.pack(">BBHBBBBBB4L", EAP_CODE_REQUEST, ctx['id'],
2492 4 + 1 + 5 + 16,
2493 EAP_TYPE_PAX,
2494 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128,
2495 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE,
2496 0, 0, 0, 0)
2497
2498 idx += 1
2499 if ctx['num'] == idx:
2500 logger.info("Test: Invalid ICV in short frame")
2501 return struct.pack(">BBHBBBBBB3L", EAP_CODE_REQUEST, ctx['id'],
2502 4 + 1 + 5 + 12,
2503 EAP_TYPE_PAX,
2504 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128,
2505 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE,
2506 0, 0, 0)
2507
2508 idx += 1
2509 if ctx['num'] == idx:
2510 logger.info("Test: Correct ICV - unsupported op_code")
2511 ctx['id'] = 10
2512 return struct.pack(">BBHBBBBBB16B", EAP_CODE_REQUEST, ctx['id'],
2513 4 + 1 + 5 + 16,
2514 EAP_TYPE_PAX,
2515 255, 0, EAP_PAX_MAC_HMAC_SHA1_128,
2516 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE,
2517 0x90, 0x78, 0x97, 0x38, 0x29, 0x94, 0x32, 0xd4,
2518 0x81, 0x27, 0xe0, 0xf6, 0x3b, 0x0d, 0xb2, 0xb2)
2519
2520 idx += 1
2521 if ctx['num'] == idx:
2522 logger.info("Test: Correct ICV - CE flag in STD-1")
2523 ctx['id'] = 10
2524 return struct.pack(">BBHBBBBBB16B", EAP_CODE_REQUEST, ctx['id'],
2525 4 + 1 + 5 + 16,
2526 EAP_TYPE_PAX,
2527 EAP_PAX_OP_STD_1, EAP_PAX_FLAGS_CE,
2528 EAP_PAX_MAC_HMAC_SHA1_128,
2529 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE,
2530 0x9c, 0x98, 0xb4, 0x0b, 0x94, 0x90, 0xde, 0x88,
2531 0xb7, 0x72, 0x63, 0x44, 0x1d, 0xe3, 0x7c, 0x5c)
2532
2533 idx += 1
2534 if ctx['num'] == idx:
2535 logger.info("Test: Correct ICV - too short STD-1 payload")
2536 ctx['id'] = 10
2537 return struct.pack(">BBHBBBBBB16B", EAP_CODE_REQUEST, ctx['id'],
2538 4 + 1 + 5 + 16,
2539 EAP_TYPE_PAX,
2540 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128,
2541 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE,
2542 0xda, 0xab, 0x2c, 0xe7, 0x84, 0x41, 0xb5, 0x5c,
2543 0xee, 0xcf, 0x62, 0x03, 0xc5, 0x69, 0xcb, 0xf4)
2544
2545 idx += 1
2546 if ctx['num'] == idx:
2547 logger.info("Test: Correct ICV - incorrect A length in STD-1")
2548 ctx['id'] = 10
2549 return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'],
2550 4 + 1 + 5 + 2 + 32 + 16,
2551 EAP_TYPE_PAX,
2552 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128,
2553 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE,
2554 0, 0, 0, 0, 0, 0, 0, 0, 0,
2555 0xc4, 0xb0, 0x81, 0xe4, 0x6c, 0x8c, 0x20, 0x23,
2556 0x60, 0x46, 0x89, 0xea, 0x94, 0x60, 0xf3, 0x2a)
2557
2558 idx += 1
2559 if ctx['num'] == idx:
2560 logger.info("Test: Correct ICV - extra data in STD-1")
2561 ctx['id'] = 10
2562 return struct.pack(">BBHBBBBBBH8LB16B", EAP_CODE_REQUEST, ctx['id'],
2563 4 + 1 + 5 + 2 + 32 + 1 + 16,
2564 EAP_TYPE_PAX,
2565 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128,
2566 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE,
2567 32, 0, 0, 0, 0, 0, 0, 0, 0,
2568 1,
2569 0x61, 0x49, 0x65, 0x37, 0x21, 0xe8, 0xd8, 0xbf,
2570 0xf3, 0x02, 0x01, 0xe5, 0x42, 0x51, 0xd3, 0x34)
2571 idx += 1
2572 if ctx['num'] == idx:
2573 logger.info("Test: Unexpected STD-1")
2574 return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'],
2575 4 + 1 + 5 + 2 + 32 + 16,
2576 EAP_TYPE_PAX,
2577 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128,
2578 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE,
2579 32, 0, 0, 0, 0, 0, 0, 0, 0,
2580 0xe5, 0x1d, 0xbf, 0xb8, 0x70, 0x20, 0x5c, 0xba,
2581 0x41, 0xbb, 0x34, 0xda, 0x1a, 0x08, 0xe6, 0x8d)
2582
2583 idx += 1
2584 if ctx['num'] == idx:
2585 return pax_std_1(ctx)
2586 idx += 1
2587 if ctx['num'] == idx:
2588 logger.info("Test: MAC ID changed during session")
2589 return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'],
2590 4 + 1 + 5 + 2 + 32 + 16,
2591 EAP_TYPE_PAX,
2592 EAP_PAX_OP_STD_1, 0, EAP_PAX_HMAC_SHA256_128,
2593 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE,
2594 32, 0, 0, 0, 0, 0, 0, 0, 0,
2595 0xee, 0x00, 0xbf, 0xb8, 0x70, 0x20, 0x5c, 0xba,
2596 0x41, 0xbb, 0x34, 0xda, 0x1a, 0x08, 0xe6, 0x8d)
2597
2598 idx += 1
2599 if ctx['num'] == idx:
2600 return pax_std_1(ctx)
2601 idx += 1
2602 if ctx['num'] == idx:
2603 logger.info("Test: DH Group ID changed during session")
2604 return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'],
2605 4 + 1 + 5 + 2 + 32 + 16,
2606 EAP_TYPE_PAX,
2607 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128,
2608 EAP_PAX_DH_GROUP_2048_MODP,
2609 EAP_PAX_PUBLIC_KEY_NONE,
2610 32, 0, 0, 0, 0, 0, 0, 0, 0,
2611 0xee, 0x01, 0xbf, 0xb8, 0x70, 0x20, 0x5c, 0xba,
2612 0x41, 0xbb, 0x34, 0xda, 0x1a, 0x08, 0xe6, 0x8d)
2613
2614 idx += 1
2615 if ctx['num'] == idx:
2616 return pax_std_1(ctx)
2617 idx += 1
2618 if ctx['num'] == idx:
2619 logger.info("Test: Public Key ID changed during session")
2620 return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'],
2621 4 + 1 + 5 + 2 + 32 + 16,
2622 EAP_TYPE_PAX,
2623 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128,
2624 EAP_PAX_DH_GROUP_NONE,
2625 EAP_PAX_PUBLIC_KEY_RSAES_OAEP,
2626 32, 0, 0, 0, 0, 0, 0, 0, 0,
2627 0xee, 0x02, 0xbf, 0xb8, 0x70, 0x20, 0x5c, 0xba,
2628 0x41, 0xbb, 0x34, 0xda, 0x1a, 0x08, 0xe6, 0x8d)
2629
2630 idx += 1
2631 if ctx['num'] == idx:
2632 logger.info("Test: Unexpected STD-3")
2633 ctx['id'] = 10
2634 return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'],
2635 4 + 1 + 5 + 2 + 32 + 16,
2636 EAP_TYPE_PAX,
2637 EAP_PAX_OP_STD_3, 0, EAP_PAX_MAC_HMAC_SHA1_128,
2638 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE,
2639 32, 0, 0, 0, 0, 0, 0, 0, 0,
2640 0x47, 0xbb, 0xc0, 0xf9, 0xb9, 0x69, 0xf5, 0xcb,
2641 0x3a, 0xe8, 0xe7, 0xd6, 0x80, 0x28, 0xf2, 0x59)
2642
2643 idx += 1
2644 if ctx['num'] == idx:
2645 return pax_std_1(ctx)
2646 idx += 1
2647 if ctx['num'] == idx:
2648 # TODO: MAC calculation; for now, this gets dropped due to incorrect
2649 # ICV
2650 logger.info("Test: STD-3 with CE flag")
2651 return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'],
2652 4 + 1 + 5 + 2 + 32 + 16,
2653 EAP_TYPE_PAX,
2654 EAP_PAX_OP_STD_3, EAP_PAX_FLAGS_CE,
2655 EAP_PAX_MAC_HMAC_SHA1_128,
2656 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE,
2657 32, 0, 0, 0, 0, 0, 0, 0, 0,
2658 0x8a, 0xc2, 0xf9, 0xf4, 0x8b, 0x75, 0x72, 0xa2,
2659 0x4d, 0xd3, 0x1e, 0x54, 0x77, 0x04, 0x05, 0xe2)
2660
2661 idx += 1
2662 if ctx['num'] & 0x1 == idx & 0x1:
2663 logger.info("Test: Default request")
2664 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
2665 4 + 1,
2666 EAP_TYPE_PAX)
2667 else:
2668 logger.info("Test: Default EAP-Failure")
2669 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
2670
2671 srv = start_radius_server(pax_handler)
09544316
JM
2672
2673 try:
5eee514d 2674 hapd = start_ap(apdev[0])
9efd3447 2675 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
09544316
JM
2676
2677 for i in range(0, 18):
2678 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
2679 eap="PAX", identity="user",
2680 password_hex="0123456789abcdef0123456789abcdef",
2681 wait_connect=False)
2682 logger.info("Waiting for EAP method to start")
2683 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
2684 timeout=15)
2685 if ev is None:
2686 raise Exception("Timeout on EAP start")
2687 time.sleep(0.05)
2688 dev[0].request("REMOVE_NETWORK all")
2689 dev[0].dump_monitor()
2690
2691 logger.info("Too short password")
2692 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
2693 eap="PAX", identity="user",
2694 password_hex="0123456789abcdef0123456789abcd",
2695 wait_connect=False)
2696 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15)
2697 if ev is None:
2698 raise Exception("Timeout on EAP start")
2699 time.sleep(0.1)
2700 dev[0].request("REMOVE_NETWORK all")
2701 dev[0].dump_monitor()
2702
2703 logger.info("No password")
2704 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
2705 eap="PAX", identity="user",
2706 wait_connect=False)
2707 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15)
2708 if ev is None:
2709 raise Exception("Timeout on EAP start")
2710 time.sleep(0.1)
2711 dev[0].request("REMOVE_NETWORK all")
2712 dev[0].dump_monitor()
2713 finally:
2714 stop_radius_server(srv)
e0534ecf 2715
2626666a
JM
2716def test_eap_proto_pax_errors(dev, apdev):
2717 """EAP-PAX local error cases"""
2718 check_eap_capa(dev[0], "PAX")
2719 params = hostapd.wpa2_eap_params(ssid="eap-test")
8b8a1864 2720 hapd = hostapd.add_ap(apdev[0], params)
9efd3447 2721 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
2626666a
JM
2722
2723 for i in range(1, 3):
2724 with alloc_fail(dev[0], i, "eap_pax_init"):
2725 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
2726 eap="PAX", identity="pax.user@example.com",
2727 password_hex="0123456789abcdef0123456789abcdef",
2728 wait_connect=False)
2729 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
2730 timeout=15)
2731 if ev is None:
2732 raise Exception("Timeout on EAP start")
2733 dev[0].request("REMOVE_NETWORK all")
2734 dev[0].wait_disconnected()
2735
fab49f61
JM
2736 tests = ["eap_msg_alloc;eap_pax_alloc_resp;eap_pax_process_std_1",
2737 "eap_msg_alloc;eap_pax_alloc_resp;eap_pax_process_std_3",
2738 "eap_pax_getKey",
2739 "eap_pax_get_emsk",
2740 "eap_pax_get_session_id"]
2626666a
JM
2741 for func in tests:
2742 with alloc_fail(dev[0], 1, func):
2743 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
2744 eap="PAX", identity="pax.user@example.com",
2745 password_hex="0123456789abcdef0123456789abcdef",
2746 erp="1", wait_connect=False)
2747 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
2748 dev[0].request("REMOVE_NETWORK all")
2749 dev[0].wait_disconnected()
2750
fab49f61
JM
2751 tests = [(1, "os_get_random;eap_pax_process_std_1"),
2752 (1, "eap_pax_initial_key_derivation"),
2753 (1, "eap_pax_mac;eap_pax_process_std_3"),
2754 (2, "eap_pax_mac;eap_pax_process_std_3"),
2755 (1, "eap_pax_kdf;eap_pax_getKey"),
2756 (1, "eap_pax_kdf;eap_pax_get_emsk")]
2626666a
JM
2757 for count, func in tests:
2758 with fail_test(dev[0], count, func):
2759 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
2760 eap="PAX", identity="pax.user@example.com",
2761 password_hex="0123456789abcdef0123456789abcdef",
2762 erp="1", wait_connect=False)
2763 wait_fail_trigger(dev[0], "GET_FAIL")
2764 dev[0].request("REMOVE_NETWORK all")
2765 dev[0].wait_disconnected()
2766
e0534ecf
JM
2767def test_eap_proto_psk(dev, apdev):
2768 """EAP-PSK protocol tests"""
2769 def psk_handler(ctx, req):
55845e19 2770 logger.info("psk_handler - RX " + binascii.hexlify(req).decode())
e0534ecf
JM
2771 if 'num' not in ctx:
2772 ctx['num'] = 0
2773 ctx['num'] = ctx['num'] + 1
2774 if 'id' not in ctx:
2775 ctx['id'] = 1
2776 ctx['id'] = (ctx['id'] + 1) % 256
2777
2778 idx = 0
2779
2780 idx += 1
2781 if ctx['num'] == idx:
2782 logger.info("Test: Missing payload")
2783 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
2784 4 + 1,
2785 EAP_TYPE_PSK)
2786
2787 idx += 1
2788 if ctx['num'] == idx:
2789 logger.info("Test: Non-zero T in first message")
2790 return struct.pack(">BBHBB4L", EAP_CODE_REQUEST, ctx['id'],
2791 4 + 1 + 1 + 16,
2792 EAP_TYPE_PSK, 0xc0, 0, 0, 0, 0)
2793
2794 idx += 1
2795 if ctx['num'] == idx:
2796 logger.info("Test: Valid first message")
2797 return struct.pack(">BBHBB4L", EAP_CODE_REQUEST, ctx['id'],
2798 4 + 1 + 1 + 16,
2799 EAP_TYPE_PSK, 0, 0, 0, 0, 0)
2800 idx += 1
2801 if ctx['num'] == idx:
2802 logger.info("Test: Too short third message")
2803 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
2804 4 + 1,
2805 EAP_TYPE_PSK)
2806
2807 idx += 1
2808 if ctx['num'] == idx:
2809 logger.info("Test: Valid first message")
2810 return struct.pack(">BBHBB4L", EAP_CODE_REQUEST, ctx['id'],
2811 4 + 1 + 1 + 16,
2812 EAP_TYPE_PSK, 0, 0, 0, 0, 0)
2813 idx += 1
2814 if ctx['num'] == idx:
2815 logger.info("Test: Incorrect T in third message")
2816 return struct.pack(">BBHBB4L4L", EAP_CODE_REQUEST, ctx['id'],
2817 4 + 1 + 1 + 16 + 16,
2818 EAP_TYPE_PSK, 0, 0, 0, 0, 0, 0, 0, 0, 0)
2819
2820 idx += 1
2821 if ctx['num'] == idx:
2822 logger.info("Test: Valid first message")
2823 return struct.pack(">BBHBB4L", EAP_CODE_REQUEST, ctx['id'],
2824 4 + 1 + 1 + 16,
2825 EAP_TYPE_PSK, 0, 0, 0, 0, 0)
2826 idx += 1
2827 if ctx['num'] == idx:
2828 logger.info("Test: Missing PCHANNEL in third message")
2829 return struct.pack(">BBHBB4L4L", EAP_CODE_REQUEST, ctx['id'],
2830 4 + 1 + 1 + 16 + 16,
2831 EAP_TYPE_PSK, 0x80, 0, 0, 0, 0, 0, 0, 0, 0)
2832
2833 idx += 1
2834 if ctx['num'] == idx:
2835 logger.info("Test: Valid first message")
2836 return struct.pack(">BBHBB4L", EAP_CODE_REQUEST, ctx['id'],
2837 4 + 1 + 1 + 16,
2838 EAP_TYPE_PSK, 0, 0, 0, 0, 0)
2839 idx += 1
2840 if ctx['num'] == idx:
2841 logger.info("Test: Invalic MAC_S in third message")
2842 return struct.pack(">BBHBB4L4L5LB", EAP_CODE_REQUEST, ctx['id'],
2843 4 + 1 + 1 + 16 + 16 + 21,
2844 EAP_TYPE_PSK, 0x80, 0, 0, 0, 0, 0, 0, 0, 0,
2845 0, 0, 0, 0, 0, 0)
2846
2847 idx += 1
2848 if ctx['num'] == idx:
2849 logger.info("Test: Valid first message")
2850 return struct.pack(">BBHBB4L", EAP_CODE_REQUEST, ctx['id'],
2851 4 + 1 + 1 + 16,
2852 EAP_TYPE_PSK, 0, 0, 0, 0, 0)
2853 idx += 1
2854 if ctx['num'] == idx:
2855 logger.info("Test: EAP-Failure")
2856 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
2857
2858 return None
2859
2860 srv = start_radius_server(psk_handler)
e0534ecf
JM
2861
2862 try:
5eee514d 2863 hapd = start_ap(apdev[0])
9efd3447 2864 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
e0534ecf
JM
2865
2866 for i in range(0, 6):
2867 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
2868 eap="PSK", identity="user",
2869 password_hex="0123456789abcdef0123456789abcdef",
2870 wait_connect=False)
2871 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
2872 timeout=15)
2873 if ev is None:
2874 raise Exception("Timeout on EAP start")
2875 time.sleep(0.1)
2876 dev[0].request("REMOVE_NETWORK all")
2877
2878 logger.info("Test: Invalid PSK length")
2879 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
2880 eap="PSK", identity="user",
2881 password_hex="0123456789abcdef0123456789abcd",
2882 wait_connect=False)
2883 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
2884 timeout=15)
2885 if ev is None:
2886 raise Exception("Timeout on EAP start")
2887 time.sleep(0.1)
2888 dev[0].request("REMOVE_NETWORK all")
2889 finally:
2890 stop_radius_server(srv)
6c080dfa 2891
b4e1e995
JM
2892def test_eap_proto_psk_errors(dev, apdev):
2893 """EAP-PSK local error cases"""
2894 check_eap_capa(dev[0], "PSK")
2895 params = hostapd.wpa2_eap_params(ssid="eap-test")
8b8a1864 2896 hapd = hostapd.add_ap(apdev[0], params)
9efd3447 2897 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
b4e1e995 2898
7cbc8e67 2899 for i in range(1, 3):
b4e1e995
JM
2900 with alloc_fail(dev[0], i, "eap_psk_init"):
2901 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
2902 eap="PSK", identity="psk.user@example.com",
2903 password_hex="0123456789abcdef0123456789abcdef",
2904 wait_connect=False)
2905 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
2906 timeout=15)
2907 if ev is None:
2908 raise Exception("Timeout on EAP start")
2909 dev[0].request("REMOVE_NETWORK all")
2910 dev[0].wait_disconnected()
2911
7cbc8e67
JM
2912 for i in range(1, 4):
2913 with fail_test(dev[0], i, "eap_psk_key_setup;eap_psk_init"):
2914 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
2915 eap="PSK", identity="psk.user@example.com",
2916 password_hex="0123456789abcdef0123456789abcdef",
2917 wait_connect=False)
2918 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
2919 timeout=15)
2920 if ev is None:
2921 raise Exception("Timeout on EAP start")
2922 dev[0].request("REMOVE_NETWORK all")
2923 dev[0].wait_disconnected()
2924
fab49f61
JM
2925 tests = [(1, "=eap_psk_process_1"),
2926 (2, "=eap_psk_process_1"),
2927 (1, "eap_msg_alloc;eap_psk_process_1"),
2928 (1, "=eap_psk_process_3"),
2929 (2, "=eap_psk_process_3"),
2930 (1, "eap_msg_alloc;eap_psk_process_3"),
2931 (1, "eap_psk_getKey"),
2932 (1, "eap_psk_get_session_id"),
2933 (1, "eap_psk_get_emsk")]
b4e1e995
JM
2934 for count, func in tests:
2935 with alloc_fail(dev[0], count, func):
2936 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
2937 eap="PSK", identity="psk.user@example.com",
2938 password_hex="0123456789abcdef0123456789abcdef",
2939 erp="1", wait_connect=False)
2940 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
2941 timeout=15)
2942 if ev is None:
2943 raise Exception("Timeout on EAP start")
7cbc8e67
JM
2944 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL",
2945 note="No allocation failure seen for %d:%s" % (count, func))
b4e1e995
JM
2946 dev[0].request("REMOVE_NETWORK all")
2947 dev[0].wait_disconnected()
2948
fab49f61
JM
2949 tests = [(1, "os_get_random;eap_psk_process_1"),
2950 (1, "omac1_aes_128;eap_psk_process_3"),
2951 (1, "aes_128_eax_decrypt;eap_psk_process_3"),
2952 (2, "aes_128_eax_decrypt;eap_psk_process_3"),
2953 (3, "aes_128_eax_decrypt;eap_psk_process_3"),
2954 (1, "aes_128_eax_encrypt;eap_psk_process_3"),
2955 (2, "aes_128_eax_encrypt;eap_psk_process_3"),
2956 (3, "aes_128_eax_encrypt;eap_psk_process_3"),
2957 (1, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"),
2958 (2, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"),
2959 (3, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"),
2960 (4, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"),
2961 (5, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"),
2962 (6, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"),
2963 (7, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"),
2964 (8, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"),
2965 (9, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"),
2966 (10, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"),
2967 (1, "aes_ctr_encrypt;aes_128_eax_decrypt;eap_psk_process_3"),
2968 (1, "aes_ctr_encrypt;aes_128_eax_encrypt;eap_psk_process_3")]
b4e1e995
JM
2969 for count, func in tests:
2970 with fail_test(dev[0], count, func):
2971 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
2972 eap="PSK", identity="psk.user@example.com",
2973 password_hex="0123456789abcdef0123456789abcdef",
2974 wait_connect=False)
2975 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
2976 timeout=15)
2977 if ev is None:
2978 raise Exception("Timeout on EAP start")
7cbc8e67
JM
2979 wait_fail_trigger(dev[0], "GET_FAIL",
2980 note="No failure seen for %d:%s" % (count, func))
b4e1e995
JM
2981 dev[0].request("REMOVE_NETWORK all")
2982 dev[0].wait_disconnected()
2983
6c080dfa
JM
2984EAP_SIM_SUBTYPE_START = 10
2985EAP_SIM_SUBTYPE_CHALLENGE = 11
2986EAP_SIM_SUBTYPE_NOTIFICATION = 12
2987EAP_SIM_SUBTYPE_REAUTHENTICATION = 13
2988EAP_SIM_SUBTYPE_CLIENT_ERROR = 14
2989
2990EAP_AKA_SUBTYPE_CHALLENGE = 1
2991EAP_AKA_SUBTYPE_AUTHENTICATION_REJECT = 2
2992EAP_AKA_SUBTYPE_SYNCHRONIZATION_FAILURE = 4
2993EAP_AKA_SUBTYPE_IDENTITY = 5
2994EAP_AKA_SUBTYPE_NOTIFICATION = 12
2995EAP_AKA_SUBTYPE_REAUTHENTICATION = 13
2996EAP_AKA_SUBTYPE_CLIENT_ERROR = 14
2997
2998EAP_SIM_AT_RAND = 1
2999EAP_SIM_AT_AUTN = 2
3000EAP_SIM_AT_RES = 3
3001EAP_SIM_AT_AUTS = 4
3002EAP_SIM_AT_PADDING = 6
3003EAP_SIM_AT_NONCE_MT = 7
3004EAP_SIM_AT_PERMANENT_ID_REQ = 10
3005EAP_SIM_AT_MAC = 11
3006EAP_SIM_AT_NOTIFICATION = 12
3007EAP_SIM_AT_ANY_ID_REQ = 13
3008EAP_SIM_AT_IDENTITY = 14
3009EAP_SIM_AT_VERSION_LIST = 15
3010EAP_SIM_AT_SELECTED_VERSION = 16
3011EAP_SIM_AT_FULLAUTH_ID_REQ = 17
3012EAP_SIM_AT_COUNTER = 19
3013EAP_SIM_AT_COUNTER_TOO_SMALL = 20
3014EAP_SIM_AT_NONCE_S = 21
3015EAP_SIM_AT_CLIENT_ERROR_CODE = 22
3016EAP_SIM_AT_KDF_INPUT = 23
3017EAP_SIM_AT_KDF = 24
3018EAP_SIM_AT_IV = 129
3019EAP_SIM_AT_ENCR_DATA = 130
3020EAP_SIM_AT_NEXT_PSEUDONYM = 132
3021EAP_SIM_AT_NEXT_REAUTH_ID = 133
3022EAP_SIM_AT_CHECKCODE = 134
3023EAP_SIM_AT_RESULT_IND = 135
3024EAP_SIM_AT_BIDDING = 136
3025
3026def test_eap_proto_aka(dev, apdev):
3027 """EAP-AKA protocol tests"""
3028 def aka_handler(ctx, req):
55845e19 3029 logger.info("aka_handler - RX " + binascii.hexlify(req).decode())
6c080dfa
JM
3030 if 'num' not in ctx:
3031 ctx['num'] = 0
3032 ctx['num'] = ctx['num'] + 1
3033 if 'id' not in ctx:
3034 ctx['id'] = 1
3035 ctx['id'] = (ctx['id'] + 1) % 256
3036
3037 idx = 0
3038
3039 idx += 1
3040 if ctx['num'] == idx:
3041 logger.info("Test: Missing payload")
3042 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
3043 4 + 1,
3044 EAP_TYPE_AKA)
3045
3046 idx += 1
3047 if ctx['num'] == idx:
3048 logger.info("Test: Unknown subtype")
f0174bff
JM
3049 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
3050 4 + 1 + 3,
3051 EAP_TYPE_AKA, 255, 0)
6c080dfa
JM
3052 idx += 1
3053 if ctx['num'] == idx:
3054 logger.info("Test: EAP-Failure")
3055 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3056
3057 idx += 1
3058 if ctx['num'] == idx:
3059 logger.info("Test: Client Error")
f0174bff
JM
3060 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
3061 4 + 1 + 3,
3062 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CLIENT_ERROR, 0)
6c080dfa
JM
3063 idx += 1
3064 if ctx['num'] == idx:
3065 logger.info("Test: EAP-Failure")
3066 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3067
3068 idx += 1
3069 if ctx['num'] == idx:
3070 logger.info("Test: Too short attribute header")
3071 return struct.pack(">BBHBBHB", EAP_CODE_REQUEST, ctx['id'],
3072 4 + 1 + 1 + 3,
3073 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 255)
3074 idx += 1
3075 if ctx['num'] == idx:
3076 logger.info("Test: EAP-Failure")
3077 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3078
3079 idx += 1
3080 if ctx['num'] == idx:
3081 logger.info("Test: Truncated attribute")
3082 return struct.pack(">BBHBBHBB", EAP_CODE_REQUEST, ctx['id'],
3083 4 + 1 + 1 + 4,
3084 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 255,
3085 255)
3086 idx += 1
3087 if ctx['num'] == idx:
3088 logger.info("Test: EAP-Failure")
3089 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3090
3091 idx += 1
3092 if ctx['num'] == idx:
3093 logger.info("Test: Too short attribute data")
3094 return struct.pack(">BBHBBHBB", EAP_CODE_REQUEST, ctx['id'],
3095 4 + 1 + 1 + 4,
3096 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 255,
3097 0)
3098 idx += 1
3099 if ctx['num'] == idx:
3100 logger.info("Test: EAP-Failure")
3101 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3102
3103 idx += 1
3104 if ctx['num'] == idx:
3105 logger.info("Test: Skippable/non-skippable unrecognzized attribute")
3106 return struct.pack(">BBHBBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3107 4 + 1 + 1 + 10,
3108 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3109 255, 1, 0, 127, 1, 0)
3110 idx += 1
3111 if ctx['num'] == idx:
3112 logger.info("Test: EAP-Failure")
3113 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3114
3115 idx += 1
3116 if ctx['num'] == idx:
3117 logger.info("Test: Identity request without ID type")
3118 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
3119 4 + 1 + 3,
3120 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0)
3121 idx += 1
3122 if ctx['num'] == idx:
3123 logger.info("Test: Identity request ANY_ID")
3124 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3125 4 + 1 + 3 + 4,
3126 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3127 EAP_SIM_AT_ANY_ID_REQ, 1, 0)
3128 idx += 1
3129 if ctx['num'] == idx:
3130 logger.info("Test: Identity request ANY_ID (duplicate)")
3131 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3132 4 + 1 + 3 + 4,
3133 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3134 EAP_SIM_AT_ANY_ID_REQ, 1, 0)
3135 idx += 1
3136 if ctx['num'] == idx:
3137 logger.info("Test: EAP-Failure")
3138 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3139
3140 idx += 1
3141 if ctx['num'] == idx:
3142 logger.info("Test: Identity request ANY_ID")
3143 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3144 4 + 1 + 3 + 4,
3145 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3146 EAP_SIM_AT_ANY_ID_REQ, 1, 0)
3147 idx += 1
3148 if ctx['num'] == idx:
3149 logger.info("Test: Identity request FULLAUTH_ID")
3150 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3151 4 + 1 + 3 + 4,
3152 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3153 EAP_SIM_AT_FULLAUTH_ID_REQ, 1, 0)
3154 idx += 1
3155 if ctx['num'] == idx:
3156 logger.info("Test: Identity request FULLAUTH_ID (duplicate)")
3157 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3158 4 + 1 + 3 + 4,
3159 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3160 EAP_SIM_AT_FULLAUTH_ID_REQ, 1, 0)
3161 idx += 1
3162 if ctx['num'] == idx:
3163 logger.info("Test: EAP-Failure")
3164 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3165
3166 idx += 1
3167 if ctx['num'] == idx:
3168 logger.info("Test: Identity request ANY_ID")
3169 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3170 4 + 1 + 3 + 4,
3171 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3172 EAP_SIM_AT_ANY_ID_REQ, 1, 0)
3173 idx += 1
3174 if ctx['num'] == idx:
3175 logger.info("Test: Identity request FULLAUTH_ID")
3176 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3177 4 + 1 + 3 + 4,
3178 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3179 EAP_SIM_AT_FULLAUTH_ID_REQ, 1, 0)
3180 idx += 1
3181 if ctx['num'] == idx:
3182 logger.info("Test: Identity request PERMANENT_ID")
3183 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3184 4 + 1 + 3 + 4,
3185 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3186 EAP_SIM_AT_PERMANENT_ID_REQ, 1, 0)
3187 idx += 1
3188 if ctx['num'] == idx:
3189 logger.info("Test: Identity request PERMANENT_ID (duplicate)")
3190 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3191 4 + 1 + 3 + 4,
3192 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3193 EAP_SIM_AT_PERMANENT_ID_REQ, 1, 0)
3194 idx += 1
3195 if ctx['num'] == idx:
3196 logger.info("Test: EAP-Failure")
3197 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3198
3199 idx += 1
3200 if ctx['num'] == idx:
3201 logger.info("Test: Challenge with no attributes")
3202 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
3203 4 + 1 + 3,
3204 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CHALLENGE, 0)
3205 idx += 1
3206 if ctx['num'] == idx:
3207 logger.info("Test: EAP-Failure")
3208 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3209
3210 idx += 1
3211 if ctx['num'] == idx:
3212 logger.info("Test: AKA Challenge with BIDDING")
3213 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3214 4 + 1 + 3 + 4,
3215 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3216 EAP_SIM_AT_BIDDING, 1, 0x8000)
3217 idx += 1
3218 if ctx['num'] == idx:
3219 logger.info("Test: EAP-Failure")
3220 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3221
3222 idx += 1
3223 if ctx['num'] == idx:
3224 logger.info("Test: Notification with no attributes")
3225 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
3226 4 + 1 + 3,
3227 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0)
3228 idx += 1
3229 if ctx['num'] == idx:
3230 logger.info("Test: EAP-Failure")
3231 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3232
3233 idx += 1
3234 if ctx['num'] == idx:
3235 logger.info("Test: Notification indicating success, but no MAC")
3236 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3237 4 + 1 + 3 + 4,
3238 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0,
3239 EAP_SIM_AT_NOTIFICATION, 1, 32768)
3240 idx += 1
3241 if ctx['num'] == idx:
3242 logger.info("Test: EAP-Failure")
3243 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3244
3245 idx += 1
3246 if ctx['num'] == idx:
3247 logger.info("Test: Notification indicating success, but invalid MAC value")
3248 return struct.pack(">BBHBBHBBHBBH4L", EAP_CODE_REQUEST, ctx['id'],
3249 4 + 1 + 3 + 4 + 20,
3250 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0,
3251 EAP_SIM_AT_NOTIFICATION, 1, 32768,
3252 EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0)
3253 idx += 1
3254 if ctx['num'] == idx:
3255 logger.info("Test: EAP-Failure")
3256 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3257
3258 idx += 1
3259 if ctx['num'] == idx:
3260 logger.info("Test: Notification indicating success with zero-key MAC")
3261 return struct.pack(">BBHBBHBBHBBH16B", EAP_CODE_REQUEST,
3262 ctx['id'] - 2,
3263 4 + 1 + 3 + 4 + 20,
3264 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0,
3265 EAP_SIM_AT_NOTIFICATION, 1, 32768,
3266 EAP_SIM_AT_MAC, 5, 0,
3267 0xbe, 0x2e, 0xbb, 0xa9, 0xfa, 0x2e, 0x82, 0x36,
3268 0x37, 0x8c, 0x32, 0x41, 0xb7, 0xc7, 0x58, 0xa3)
3269 idx += 1
3270 if ctx['num'] == idx:
3271 logger.info("Test: EAP-Success")
3272 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4)
3273
3274 idx += 1
3275 if ctx['num'] == idx:
3276 logger.info("Test: Notification before auth")
3277 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3278 4 + 1 + 3 + 4,
3279 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0,
3280 EAP_SIM_AT_NOTIFICATION, 1, 16384)
3281 idx += 1
3282 if ctx['num'] == idx:
3283 logger.info("Test: EAP-Failure")
3284 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3285
3286 idx += 1
3287 if ctx['num'] == idx:
3288 logger.info("Test: Notification before auth")
3289 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3290 4 + 1 + 3 + 4,
3291 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0,
3292 EAP_SIM_AT_NOTIFICATION, 1, 16385)
3293 idx += 1
3294 if ctx['num'] == idx:
3295 logger.info("Test: EAP-Failure")
3296 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3297
3298 idx += 1
3299 if ctx['num'] == idx:
3300 logger.info("Test: Notification with unrecognized non-failure")
3301 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3302 4 + 1 + 3 + 4,
3303 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0,
3304 EAP_SIM_AT_NOTIFICATION, 1, 0xc000)
3305 idx += 1
3306 if ctx['num'] == idx:
3307 logger.info("Test: Notification before auth (duplicate)")
3308 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3309 4 + 1 + 3 + 4,
3310 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0,
3311 EAP_SIM_AT_NOTIFICATION, 1, 0xc000)
3312 idx += 1
3313 if ctx['num'] == idx:
3314 logger.info("Test: EAP-Failure")
3315 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3316
3317 idx += 1
3318 if ctx['num'] == idx:
3319 logger.info("Test: Re-authentication (unexpected) with no attributes")
3320 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
3321 4 + 1 + 3,
3322 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_REAUTHENTICATION,
3323 0)
3324 idx += 1
3325 if ctx['num'] == idx:
3326 logger.info("Test: EAP-Failure")
3327 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3328
3329 idx += 1
3330 if ctx['num'] == idx:
3331 logger.info("Test: AKA Challenge with Checkcode claiming identity round was used")
3332 return struct.pack(">BBHBBHBBH5L", EAP_CODE_REQUEST, ctx['id'],
3333 4 + 1 + 3 + 24,
3334 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3335 EAP_SIM_AT_CHECKCODE, 6, 0, 0, 0, 0, 0, 0)
3336 idx += 1
3337 if ctx['num'] == idx:
3338 logger.info("Test: EAP-Failure")
3339 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3340
3341 idx += 1
3342 if ctx['num'] == idx:
3343 logger.info("Test: Identity request ANY_ID")
3344 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3345 4 + 1 + 3 + 4,
3346 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3347 EAP_SIM_AT_ANY_ID_REQ, 1, 0)
3348 idx += 1
3349 if ctx['num'] == idx:
3350 logger.info("Test: AKA Challenge with Checkcode claiming no identity round was used")
3351 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3352 4 + 1 + 3 + 4,
3353 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3354 EAP_SIM_AT_CHECKCODE, 1, 0)
3355 idx += 1
3356 if ctx['num'] == idx:
3357 logger.info("Test: EAP-Failure")
3358 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3359
3360 idx += 1
3361 if ctx['num'] == idx:
3362 logger.info("Test: Identity request ANY_ID")
3363 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3364 4 + 1 + 3 + 4,
3365 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3366 EAP_SIM_AT_ANY_ID_REQ, 1, 0)
3367 idx += 1
3368 if ctx['num'] == idx:
3369 logger.info("Test: AKA Challenge with mismatching Checkcode value")
3370 return struct.pack(">BBHBBHBBH5L", EAP_CODE_REQUEST, ctx['id'],
3371 4 + 1 + 3 + 24,
3372 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3373 EAP_SIM_AT_CHECKCODE, 6, 0, 0, 0, 0, 0, 0)
3374 idx += 1
3375 if ctx['num'] == idx:
3376 logger.info("Test: EAP-Failure")
3377 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3378
3379 idx += 1
3380 if ctx['num'] == idx:
3381 logger.info("Test: Re-authentication (unexpected) with Checkcode claimin identity round was used")
3382 return struct.pack(">BBHBBHBBH5L", EAP_CODE_REQUEST, ctx['id'],
3383 4 + 1 + 3 + 24,
3384 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_REAUTHENTICATION,
3385 0,
3386 EAP_SIM_AT_CHECKCODE, 6, 0, 0, 0, 0, 0, 0)
3387 idx += 1
3388 if ctx['num'] == idx:
3389 logger.info("Test: EAP-Failure")
3390 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3391
3392 idx += 1
3393 if ctx['num'] == idx:
3394 logger.info("Test: Invalid AT_RAND length")
3395 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3396 4 + 1 + 3 + 4,
3397 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3398 EAP_SIM_AT_RAND, 1, 0)
3399 idx += 1
3400 if ctx['num'] == idx:
3401 logger.info("Test: EAP-Failure")
3402 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3403
3404 idx += 1
3405 if ctx['num'] == idx:
3406 logger.info("Test: Invalid AT_AUTN length")
3407 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3408 4 + 1 + 3 + 4,
3409 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3410 EAP_SIM_AT_AUTN, 1, 0)
3411 idx += 1
3412 if ctx['num'] == idx:
3413 logger.info("Test: EAP-Failure")
3414 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3415
3416 idx += 1
3417 if ctx['num'] == idx:
3418 logger.info("Test: Unencrypted AT_PADDING")
3419 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3420 4 + 1 + 3 + 4,
3421 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3422 EAP_SIM_AT_PADDING, 1, 0)
3423 idx += 1
3424 if ctx['num'] == idx:
3425 logger.info("Test: EAP-Failure")
3426 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3427
3428 idx += 1
3429 if ctx['num'] == idx:
3430 logger.info("Test: Invalid AT_NONCE_MT length")
3431 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3432 4 + 1 + 3 + 4,
3433 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3434 EAP_SIM_AT_NONCE_MT, 1, 0)
3435 idx += 1
3436 if ctx['num'] == idx:
3437 logger.info("Test: EAP-Failure")
3438 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3439
3440 idx += 1
3441 if ctx['num'] == idx:
3442 logger.info("Test: Invalid AT_MAC length")
3443 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3444 4 + 1 + 3 + 4,
3445 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3446 EAP_SIM_AT_MAC, 1, 0)
3447 idx += 1
3448 if ctx['num'] == idx:
3449 logger.info("Test: EAP-Failure")
3450 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3451
3452 idx += 1
3453 if ctx['num'] == idx:
3454 logger.info("Test: Invalid AT_NOTIFICATION length")
3455 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
3456 4 + 1 + 3 + 8,
3457 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3458 EAP_SIM_AT_NOTIFICATION, 2, 0, 0)
3459 idx += 1
3460 if ctx['num'] == idx:
3461 logger.info("Test: EAP-Failure")
3462 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3463
3464 idx += 1
3465 if ctx['num'] == idx:
3466 logger.info("Test: AT_IDENTITY overflow")
3467 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3468 4 + 1 + 3 + 4,
3469 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3470 EAP_SIM_AT_IDENTITY, 1, 0xffff)
3471 idx += 1
3472 if ctx['num'] == idx:
3473 logger.info("Test: EAP-Failure")
3474 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3475
3476 idx += 1
3477 if ctx['num'] == idx:
3478 logger.info("Test: Unexpected AT_VERSION_LIST")
3479 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3480 4 + 1 + 3 + 4,
3481 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3482 EAP_SIM_AT_VERSION_LIST, 1, 0)
3483 idx += 1
3484 if ctx['num'] == idx:
3485 logger.info("Test: EAP-Failure")
3486 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3487
3488 idx += 1
3489 if ctx['num'] == idx:
3490 logger.info("Test: Invalid AT_SELECTED_VERSION length")
3491 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
3492 4 + 1 + 3 + 8,
3493 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3494 EAP_SIM_AT_SELECTED_VERSION, 2, 0, 0)
3495 idx += 1
3496 if ctx['num'] == idx:
3497 logger.info("Test: EAP-Failure")
3498 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3499
3500 idx += 1
3501 if ctx['num'] == idx:
3502 logger.info("Test: Unencrypted AT_COUNTER")
3503 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3504 4 + 1 + 3 + 4,
3505 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3506 EAP_SIM_AT_COUNTER, 1, 0)
3507 idx += 1
3508 if ctx['num'] == idx:
3509 logger.info("Test: EAP-Failure")
3510 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3511
3512 idx += 1
3513 if ctx['num'] == idx:
3514 logger.info("Test: Unencrypted AT_COUNTER_TOO_SMALL")
3515 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3516 4 + 1 + 3 + 4,
3517 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3518 EAP_SIM_AT_COUNTER_TOO_SMALL, 1, 0)
3519 idx += 1
3520 if ctx['num'] == idx:
3521 logger.info("Test: EAP-Failure")
3522 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3523
3524 idx += 1
3525 if ctx['num'] == idx:
3526 logger.info("Test: Unencrypted AT_NONCE_S")
3527 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3528 4 + 1 + 3 + 4,
3529 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3530 EAP_SIM_AT_NONCE_S, 1, 0)
3531 idx += 1
3532 if ctx['num'] == idx:
3533 logger.info("Test: EAP-Failure")
3534 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3535
3536 idx += 1
3537 if ctx['num'] == idx:
3538 logger.info("Test: Invalid AT_CLIENT_ERROR_CODE length")
3539 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
3540 4 + 1 + 3 + 8,
3541 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3542 EAP_SIM_AT_CLIENT_ERROR_CODE, 2, 0, 0)
3543 idx += 1
3544 if ctx['num'] == idx:
3545 logger.info("Test: EAP-Failure")
3546 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3547
3548 idx += 1
3549 if ctx['num'] == idx:
3550 logger.info("Test: Invalid AT_IV length")
3551 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3552 4 + 1 + 3 + 4,
3553 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3554 EAP_SIM_AT_IV, 1, 0)
3555 idx += 1
3556 if ctx['num'] == idx:
3557 logger.info("Test: EAP-Failure")
3558 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3559
3560 idx += 1
3561 if ctx['num'] == idx:
3562 logger.info("Test: Invalid AT_ENCR_DATA length")
3563 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
3564 4 + 1 + 3 + 8,
3565 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3566 EAP_SIM_AT_ENCR_DATA, 2, 0, 0)
3567 idx += 1
3568 if ctx['num'] == idx:
3569 logger.info("Test: EAP-Failure")
3570 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3571
3572 idx += 1
3573 if ctx['num'] == idx:
3574 logger.info("Test: Unencrypted AT_NEXT_PSEUDONYM")
3575 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3576 4 + 1 + 3 + 4,
3577 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3578 EAP_SIM_AT_NEXT_PSEUDONYM, 1, 0)
3579 idx += 1
3580 if ctx['num'] == idx:
3581 logger.info("Test: EAP-Failure")
3582 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3583
3584 idx += 1
3585 if ctx['num'] == idx:
3586 logger.info("Test: Unencrypted AT_NEXT_REAUTH_ID")
3587 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3588 4 + 1 + 3 + 4,
3589 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3590 EAP_SIM_AT_NEXT_REAUTH_ID, 1, 0)
3591 idx += 1
3592 if ctx['num'] == idx:
3593 logger.info("Test: EAP-Failure")
3594 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3595
3596 idx += 1
3597 if ctx['num'] == idx:
3598 logger.info("Test: Invalid AT_RES length")
3599 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3600 4 + 1 + 3 + 4,
3601 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3602 EAP_SIM_AT_RES, 1, 0)
3603 idx += 1
3604 if ctx['num'] == idx:
3605 logger.info("Test: EAP-Failure")
3606 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3607
3608 idx += 1
3609 if ctx['num'] == idx:
3610 logger.info("Test: Invalid AT_RES length")
3611 return struct.pack(">BBHBBHBBH5L", EAP_CODE_REQUEST, ctx['id'],
3612 4 + 1 + 3 + 24,
3613 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3614 EAP_SIM_AT_RES, 6, 0xffff, 0, 0, 0, 0, 0)
3615 idx += 1
3616 if ctx['num'] == idx:
3617 logger.info("Test: EAP-Failure")
3618 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3619
3620 idx += 1
3621 if ctx['num'] == idx:
3622 logger.info("Test: Invalid AT_AUTS length")
3623 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
3624 4 + 1 + 3 + 8,
3625 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3626 EAP_SIM_AT_AUTS, 2, 0, 0)
3627 idx += 1
3628 if ctx['num'] == idx:
3629 logger.info("Test: EAP-Failure")
3630 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3631
3632 idx += 1
3633 if ctx['num'] == idx:
3634 logger.info("Test: Invalid AT_CHECKCODE length")
3635 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
3636 4 + 1 + 3 + 8,
3637 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3638 EAP_SIM_AT_CHECKCODE, 2, 0, 0)
3639 idx += 1
3640 if ctx['num'] == idx:
3641 logger.info("Test: EAP-Failure")
3642 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3643
3644 idx += 1
3645 if ctx['num'] == idx:
3646 logger.info("Test: Invalid AT_RESULT_IND length")
3647 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
3648 4 + 1 + 3 + 8,
3649 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3650 EAP_SIM_AT_RESULT_IND, 2, 0, 0)
3651 idx += 1
3652 if ctx['num'] == idx:
3653 logger.info("Test: EAP-Failure")
3654 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3655
3656 idx += 1
3657 if ctx['num'] == idx:
3658 logger.info("Test: Unexpected AT_KDF_INPUT")
3659 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
3660 4 + 1 + 3 + 8,
3661 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3662 EAP_SIM_AT_KDF_INPUT, 2, 0, 0)
3663 idx += 1
3664 if ctx['num'] == idx:
3665 logger.info("Test: EAP-Failure")
3666 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3667
3668 idx += 1
3669 if ctx['num'] == idx:
3670 logger.info("Test: Unexpected AT_KDF")
3671 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
3672 4 + 1 + 3 + 8,
3673 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3674 EAP_SIM_AT_KDF, 2, 0, 0)
3675 idx += 1
3676 if ctx['num'] == idx:
3677 logger.info("Test: EAP-Failure")
3678 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3679
3680 idx += 1
3681 if ctx['num'] == idx:
3682 logger.info("Test: Invalid AT_BIDDING length")
3683 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
3684 4 + 1 + 3 + 8,
3685 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3686 EAP_SIM_AT_BIDDING, 2, 0, 0)
3687 idx += 1
3688 if ctx['num'] == idx:
3689 logger.info("Test: EAP-Failure")
3690 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3691
3692 return None
3693
3694 srv = start_radius_server(aka_handler)
6c080dfa
JM
3695
3696 try:
5eee514d 3697 hapd = start_ap(apdev[0])
9efd3447 3698 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
6c080dfa
JM
3699
3700 for i in range(0, 49):
3701 eap = "AKA AKA'" if i == 11 else "AKA"
3702 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
3703 eap=eap, identity="0232010000000000",
3704 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123",
3705 wait_connect=False)
3706 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
3707 timeout=15)
3708 if ev is None:
3709 raise Exception("Timeout on EAP start")
fab49f61 3710 if i in [0, 15]:
6c080dfa
JM
3711 time.sleep(0.1)
3712 else:
3713 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"],
3714 timeout=10)
3715 if ev is None:
3716 raise Exception("Timeout on EAP failure")
3717 dev[0].request("REMOVE_NETWORK all")
f0174bff 3718 dev[0].dump_monitor()
6c080dfa
JM
3719 finally:
3720 stop_radius_server(srv)
3721
3722def test_eap_proto_aka_prime(dev, apdev):
3723 """EAP-AKA' protocol tests"""
3724 def aka_prime_handler(ctx, req):
55845e19 3725 logger.info("aka_prime_handler - RX " + binascii.hexlify(req).decode())
6c080dfa
JM
3726 if 'num' not in ctx:
3727 ctx['num'] = 0
3728 ctx['num'] = ctx['num'] + 1
3729 if 'id' not in ctx:
3730 ctx['id'] = 1
3731 ctx['id'] = (ctx['id'] + 1) % 256
3732
3733 idx = 0
3734
3735 idx += 1
3736 if ctx['num'] == idx:
3737 logger.info("Test: Missing payload")
0a374295 3738 dev[0].note("Missing payload")
6c080dfa
JM
3739 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
3740 4 + 1,
3741 EAP_TYPE_AKA_PRIME)
3742
3743 idx += 1
3744 if ctx['num'] == idx:
3745 logger.info("Test: Challenge with no attributes")
0a374295 3746 dev[0].note("Challenge with no attributes")
6c080dfa
JM
3747 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
3748 4 + 1 + 3,
3749 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0)
3750 idx += 1
3751 if ctx['num'] == idx:
3752 logger.info("Test: EAP-Failure")
3753 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3754
3755 idx += 1
3756 if ctx['num'] == idx:
3757 logger.info("Test: Challenge with empty AT_KDF_INPUT")
0a374295 3758 dev[0].note("Challenge with empty AT_KDF_INPUT")
6c080dfa
JM
3759 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3760 4 + 1 + 3 + 4,
3761 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3762 EAP_SIM_AT_KDF_INPUT, 1, 0)
3763 idx += 1
3764 if ctx['num'] == idx:
3765 logger.info("Test: EAP-Failure")
3766 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3767
3768 idx += 1
3769 if ctx['num'] == idx:
3770 logger.info("Test: Challenge with AT_KDF_INPUT")
0a374295 3771 dev[0].note("Test: Challenge with AT_KDF_INPUT")
6c080dfa
JM
3772 return struct.pack(">BBHBBHBBHBBBB", EAP_CODE_REQUEST, ctx['id'],
3773 4 + 1 + 3 + 8,
3774 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3775 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
3776 ord('c'), ord('d'))
3777 idx += 1
3778 if ctx['num'] == idx:
3779 logger.info("Test: EAP-Failure")
3780 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3781
3782 idx += 1
3783 if ctx['num'] == idx:
3784 logger.info("Test: Challenge with duplicated KDF")
0a374295 3785 dev[0].note("Challenge with duplicated KDF")
6c080dfa
JM
3786 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH",
3787 EAP_CODE_REQUEST, ctx['id'],
3788 4 + 1 + 3 + 8 + 3 * 4,
3789 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3790 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
3791 ord('c'), ord('d'),
3792 EAP_SIM_AT_KDF, 1, 1,
3793 EAP_SIM_AT_KDF, 1, 2,
3794 EAP_SIM_AT_KDF, 1, 1)
3795 idx += 1
3796 if ctx['num'] == idx:
3797 logger.info("Test: EAP-Failure")
3798 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3799
3800 idx += 1
3801 if ctx['num'] == idx:
3802 logger.info("Test: Challenge with multiple KDF proposals")
0a374295 3803 dev[0].note("Challenge with multiple KDF proposals (preparation)")
6c080dfa
JM
3804 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH",
3805 EAP_CODE_REQUEST, ctx['id'],
3806 4 + 1 + 3 + 8 + 3 * 4,
3807 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3808 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
3809 ord('c'), ord('d'),
3810 EAP_SIM_AT_KDF, 1, 255,
3811 EAP_SIM_AT_KDF, 1, 254,
3812 EAP_SIM_AT_KDF, 1, 1)
3813 idx += 1
3814 if ctx['num'] == idx:
3815 logger.info("Test: Challenge with incorrect KDF selected")
0a374295 3816 dev[0].note("Challenge with incorrect KDF selected")
6c080dfa
JM
3817 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBHBBH",
3818 EAP_CODE_REQUEST, ctx['id'],
3819 4 + 1 + 3 + 8 + 4 * 4,
3820 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3821 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
3822 ord('c'), ord('d'),
3823 EAP_SIM_AT_KDF, 1, 255,
3824 EAP_SIM_AT_KDF, 1, 255,
3825 EAP_SIM_AT_KDF, 1, 254,
3826 EAP_SIM_AT_KDF, 1, 1)
3827 idx += 1
3828 if ctx['num'] == idx:
3829 logger.info("Test: EAP-Failure")
3830 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3831
3832 idx += 1
3833 if ctx['num'] == idx:
3834 logger.info("Test: Challenge with multiple KDF proposals")
0a374295 3835 dev[0].note("Challenge with multiple KDF proposals (preparation)")
6c080dfa
JM
3836 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH",
3837 EAP_CODE_REQUEST, ctx['id'],
3838 4 + 1 + 3 + 8 + 3 * 4,
3839 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3840 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
3841 ord('c'), ord('d'),
3842 EAP_SIM_AT_KDF, 1, 255,
3843 EAP_SIM_AT_KDF, 1, 254,
3844 EAP_SIM_AT_KDF, 1, 1)
3845 idx += 1
3846 if ctx['num'] == idx:
3847 logger.info("Test: Challenge with selected KDF not duplicated")
0a374295 3848 dev[0].note("Challenge with selected KDF not duplicated")
6c080dfa
JM
3849 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH",
3850 EAP_CODE_REQUEST, ctx['id'],
3851 4 + 1 + 3 + 8 + 3 * 4,
3852 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3853 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
3854 ord('c'), ord('d'),
3855 EAP_SIM_AT_KDF, 1, 1,
3856 EAP_SIM_AT_KDF, 1, 255,
3857 EAP_SIM_AT_KDF, 1, 254)
3858 idx += 1
3859 if ctx['num'] == idx:
3860 logger.info("Test: EAP-Failure")
3861 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3862
3863 idx += 1
3864 if ctx['num'] == idx:
3865 logger.info("Test: Challenge with multiple KDF proposals")
0a374295 3866 dev[0].note("Challenge with multiple KDF proposals (preparation)")
6c080dfa
JM
3867 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH",
3868 EAP_CODE_REQUEST, ctx['id'],
3869 4 + 1 + 3 + 8 + 3 * 4,
3870 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3871 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
3872 ord('c'), ord('d'),
3873 EAP_SIM_AT_KDF, 1, 255,
3874 EAP_SIM_AT_KDF, 1, 254,
3875 EAP_SIM_AT_KDF, 1, 1)
3876 idx += 1
3877 if ctx['num'] == idx:
3878 logger.info("Test: Challenge with selected KDF duplicated (missing MAC, RAND, AUTN)")
0a374295 3879 dev[0].note("Challenge with selected KDF duplicated (missing MAC, RAND, AUTN)")
6c080dfa
JM
3880 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBHBBH",
3881 EAP_CODE_REQUEST, ctx['id'],
3882 4 + 1 + 3 + 8 + 4 * 4,
3883 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3884 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
3885 ord('c'), ord('d'),
3886 EAP_SIM_AT_KDF, 1, 1,
3887 EAP_SIM_AT_KDF, 1, 255,
3888 EAP_SIM_AT_KDF, 1, 254,
3889 EAP_SIM_AT_KDF, 1, 1)
3890 idx += 1
3891 if ctx['num'] == idx:
3892 logger.info("Test: EAP-Failure")
3893 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3894
3895 idx += 1
3896 if ctx['num'] == idx:
3897 logger.info("Test: Challenge with multiple unsupported KDF proposals")
0a374295 3898 dev[0].note("Challenge with multiple unsupported KDF proposals")
6c080dfa
JM
3899 return struct.pack(">BBHBBHBBHBBBBBBHBBH",
3900 EAP_CODE_REQUEST, ctx['id'],
3901 4 + 1 + 3 + 8 + 2 * 4,
3902 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3903 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
3904 ord('c'), ord('d'),
3905 EAP_SIM_AT_KDF, 1, 255,
3906 EAP_SIM_AT_KDF, 1, 254)
3907 idx += 1
3908 if ctx['num'] == idx:
3909 logger.info("Test: EAP-Failure")
3910 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3911
3912 idx += 1
3913 if ctx['num'] == idx:
3914 logger.info("Test: Challenge with multiple KDF proposals")
0a374295 3915 dev[0].note("Challenge with multiple KDF proposals (preparation)")
6c080dfa
JM
3916 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH",
3917 EAP_CODE_REQUEST, ctx['id'],
3918 4 + 1 + 3 + 8 + 3 * 4,
3919 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3920 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
3921 ord('c'), ord('d'),
3922 EAP_SIM_AT_KDF, 1, 255,
3923 EAP_SIM_AT_KDF, 1, 254,
3924 EAP_SIM_AT_KDF, 1, 1)
3925 idx += 1
3926 if ctx['num'] == idx:
3927 logger.info("Test: Challenge with invalid MAC, RAND, AUTN values)")
0a374295 3928 dev[0].note("Challenge with invalid MAC, RAND, AUTN values)")
6c080dfa
JM
3929 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBHBBHBBH4LBBH4LBBH4L",
3930 EAP_CODE_REQUEST, ctx['id'],
3931 4 + 1 + 3 + 8 + 4 * 4 + 20 + 20 + 20,
3932 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3933 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
3934 ord('c'), ord('d'),
3935 EAP_SIM_AT_KDF, 1, 1,
3936 EAP_SIM_AT_KDF, 1, 255,
3937 EAP_SIM_AT_KDF, 1, 254,
3938 EAP_SIM_AT_KDF, 1, 1,
3939 EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0,
3940 EAP_SIM_AT_RAND, 5, 0, 0, 0, 0, 0,
3941 EAP_SIM_AT_AUTN, 5, 0, 0, 0, 0, 0)
3942 idx += 1
3943 if ctx['num'] == idx:
3944 logger.info("Test: EAP-Failure")
3945 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3946
3947 idx += 1
3948 if ctx['num'] == idx:
3949 logger.info("Test: Challenge - AMF separation bit not set)")
0a374295 3950 dev[0].note("Challenge - AMF separation bit not set)")
6c080dfa
JM
3951 return struct.pack(">BBHBBHBBHBBBBBBHBBH4LBBH4LBBH4L",
3952 EAP_CODE_REQUEST, ctx['id'],
3953 4 + 1 + 3 + 8 + 4 + 20 + 20 + 20,
3954 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3955 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
3956 ord('c'), ord('d'),
3957 EAP_SIM_AT_KDF, 1, 1,
3958 EAP_SIM_AT_MAC, 5, 0, 1, 2, 3, 4,
3959 EAP_SIM_AT_RAND, 5, 0, 5, 6, 7, 8,
3960 EAP_SIM_AT_AUTN, 5, 0, 9, 10,
3961 0x2fda8ef7, 0xbba518cc)
3962 idx += 1
3963 if ctx['num'] == idx:
3964 logger.info("Test: EAP-Failure")
3965 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3966
3967 idx += 1
3968 if ctx['num'] == idx:
3969 logger.info("Test: Challenge - Invalid MAC")
0a374295 3970 dev[0].note("Challenge - Invalid MAC")
6c080dfa
JM
3971 return struct.pack(">BBHBBHBBHBBBBBBHBBH4LBBH4LBBH4L",
3972 EAP_CODE_REQUEST, ctx['id'],
3973 4 + 1 + 3 + 8 + 4 + 20 + 20 + 20,
3974 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3975 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
3976 ord('c'), ord('d'),
3977 EAP_SIM_AT_KDF, 1, 1,
3978 EAP_SIM_AT_MAC, 5, 0, 1, 2, 3, 4,
3979 EAP_SIM_AT_RAND, 5, 0, 5, 6, 7, 8,
3980 EAP_SIM_AT_AUTN, 5, 0, 0xffffffff, 0xffffffff,
3981 0xd1f90322, 0x40514cb4)
3982 idx += 1
3983 if ctx['num'] == idx:
3984 logger.info("Test: EAP-Failure")
3985 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3986
3987 idx += 1
3988 if ctx['num'] == idx:
3989 logger.info("Test: Challenge - Valid MAC")
0a374295 3990 dev[0].note("Challenge - Valid MAC")
6c080dfa
JM
3991 return struct.pack(">BBHBBHBBHBBBBBBHBBH4LBBH4LBBH4L",
3992 EAP_CODE_REQUEST, ctx['id'],
3993 4 + 1 + 3 + 8 + 4 + 20 + 20 + 20,
3994 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3995 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
3996 ord('c'), ord('d'),
3997 EAP_SIM_AT_KDF, 1, 1,
3998 EAP_SIM_AT_MAC, 5, 0,
3999 0xf4a3c1d3, 0x7c901401, 0x34bd8b01, 0x6f7fa32f,
4000 EAP_SIM_AT_RAND, 5, 0, 5, 6, 7, 8,
4001 EAP_SIM_AT_AUTN, 5, 0, 0xffffffff, 0xffffffff,
4002 0xd1f90322, 0x40514cb4)
4003 idx += 1
4004 if ctx['num'] == idx:
4005 logger.info("Test: EAP-Failure")
4006 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4007
4008 idx += 1
4009 if ctx['num'] == idx:
4010 logger.info("Test: Invalid AT_KDF_INPUT length")
0a374295 4011 dev[0].note("Invalid AT_KDF_INPUT length")
6c080dfa
JM
4012 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
4013 4 + 1 + 3 + 8,
4014 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_IDENTITY, 0,
4015 EAP_SIM_AT_KDF_INPUT, 2, 0xffff, 0)
4016 idx += 1
4017 if ctx['num'] == idx:
4018 logger.info("Test: EAP-Failure")
4019 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4020
4021 idx += 1
4022 if ctx['num'] == idx:
4023 logger.info("Test: Invalid AT_KDF length")
0a374295 4024 dev[0].note("Invalid AT_KDF length")
6c080dfa
JM
4025 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
4026 4 + 1 + 3 + 8,
4027 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_IDENTITY, 0,
4028 EAP_SIM_AT_KDF, 2, 0, 0)
4029 idx += 1
4030 if ctx['num'] == idx:
4031 logger.info("Test: EAP-Failure")
4032 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4033
4034 idx += 1
4035 if ctx['num'] == idx:
4036 logger.info("Test: Challenge with large number of KDF proposals")
0a374295 4037 dev[0].note("Challenge with large number of KDF proposals")
6c080dfa
JM
4038 return struct.pack(">BBHBBHBBHBBHBBHBBHBBHBBHBBHBBHBBHBBHBBHBBH",
4039 EAP_CODE_REQUEST, ctx['id'],
4040 4 + 1 + 3 + 12 * 4,
4041 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
4042 EAP_SIM_AT_KDF, 1, 255,
4043 EAP_SIM_AT_KDF, 1, 254,
4044 EAP_SIM_AT_KDF, 1, 253,
4045 EAP_SIM_AT_KDF, 1, 252,
4046 EAP_SIM_AT_KDF, 1, 251,
4047 EAP_SIM_AT_KDF, 1, 250,
4048 EAP_SIM_AT_KDF, 1, 249,
4049 EAP_SIM_AT_KDF, 1, 248,
4050 EAP_SIM_AT_KDF, 1, 247,
4051 EAP_SIM_AT_KDF, 1, 246,
4052 EAP_SIM_AT_KDF, 1, 245,
4053 EAP_SIM_AT_KDF, 1, 244)
4054 idx += 1
4055 if ctx['num'] == idx:
4056 logger.info("Test: EAP-Failure")
4057 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4058
0a374295
JM
4059 idx += 1
4060 if ctx['num'] == idx:
4061 logger.info("Test: Challenge with multiple KDF proposals")
4062 dev[0].note("Challenge with multiple KDF proposals (preparation)")
4063 return struct.pack(">BBHBBHBBHBBBBBBHBBH",
4064 EAP_CODE_REQUEST, ctx['id'],
4065 4 + 1 + 3 + 8 + 2 * 4,
4066 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
4067 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
4068 ord('c'), ord('d'),
4069 EAP_SIM_AT_KDF, 1, 2,
4070 EAP_SIM_AT_KDF, 1, 1)
4071 idx += 1
4072 if ctx['num'] == idx:
4073 logger.info("Test: Challenge with an extra KDF appended")
4074 dev[0].note("Challenge with an extra KDF appended")
4075 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBHBBH",
4076 EAP_CODE_REQUEST, ctx['id'],
4077 4 + 1 + 3 + 8 + 4 * 4,
4078 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
4079 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
4080 ord('c'), ord('d'),
4081 EAP_SIM_AT_KDF, 1, 1,
4082 EAP_SIM_AT_KDF, 1, 2,
4083 EAP_SIM_AT_KDF, 1, 1,
4084 EAP_SIM_AT_KDF, 1, 0)
4085 idx += 1
4086 if ctx['num'] == idx:
4087 logger.info("Test: EAP-Failure")
4088 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4089
4090 idx += 1
4091 if ctx['num'] == idx:
4092 logger.info("Test: Challenge with multiple KDF proposals")
4093 dev[0].note("Challenge with multiple KDF proposals (preparation)")
4094 return struct.pack(">BBHBBHBBHBBBBBBHBBH",
4095 EAP_CODE_REQUEST, ctx['id'],
4096 4 + 1 + 3 + 8 + 2 * 4,
4097 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
4098 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
4099 ord('c'), ord('d'),
4100 EAP_SIM_AT_KDF, 1, 2,
4101 EAP_SIM_AT_KDF, 1, 1)
4102 idx += 1
4103 if ctx['num'] == idx:
4104 logger.info("Test: Challenge with a modified KDF")
4105 dev[0].note("Challenge with a modified KDF")
4106 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH",
4107 EAP_CODE_REQUEST, ctx['id'],
4108 4 + 1 + 3 + 8 + 3 * 4,
4109 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
4110 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
4111 ord('c'), ord('d'),
4112 EAP_SIM_AT_KDF, 1, 1,
4113 EAP_SIM_AT_KDF, 1, 0,
4114 EAP_SIM_AT_KDF, 1, 1)
4115 idx += 1
4116 if ctx['num'] == idx:
4117 logger.info("Test: EAP-Failure")
4118 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4119
6c080dfa
JM
4120 return None
4121
4122 srv = start_radius_server(aka_prime_handler)
6c080dfa
JM
4123
4124 try:
5eee514d 4125 hapd = start_ap(apdev[0])
9efd3447 4126 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
6c080dfa 4127
0a374295 4128 for i in range(0, 18):
6c080dfa
JM
4129 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4130 eap="AKA'", identity="6555444333222111",
4131 password="5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123",
4132 wait_connect=False)
4133 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
4134 timeout=15)
4135 if ev is None:
4136 raise Exception("Timeout on EAP start")
fab49f61 4137 if i in [0]:
6c080dfa
JM
4138 time.sleep(0.1)
4139 else:
4140 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"],
4141 timeout=10)
4142 if ev is None:
4143 raise Exception("Timeout on EAP failure")
4144 dev[0].request("REMOVE_NETWORK all")
f0174bff 4145 dev[0].dump_monitor()
6c080dfa
JM
4146 finally:
4147 stop_radius_server(srv)
4148
4149def test_eap_proto_sim(dev, apdev):
4150 """EAP-SIM protocol tests"""
4151 def sim_handler(ctx, req):
55845e19 4152 logger.info("sim_handler - RX " + binascii.hexlify(req).decode())
6c080dfa
JM
4153 if 'num' not in ctx:
4154 ctx['num'] = 0
4155 ctx['num'] = ctx['num'] + 1
4156 if 'id' not in ctx:
4157 ctx['id'] = 1
4158 ctx['id'] = (ctx['id'] + 1) % 256
4159
4160 idx = 0
4161
4162 idx += 1
4163 if ctx['num'] == idx:
4164 logger.info("Test: Missing payload")
4165 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
4166 4 + 1,
4167 EAP_TYPE_SIM)
4168
4169 idx += 1
4170 if ctx['num'] == idx:
4171 logger.info("Test: Unexpected AT_AUTN")
4172 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
4173 4 + 1 + 3 + 8,
4174 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
4175 EAP_SIM_AT_AUTN, 2, 0, 0)
4176 idx += 1
4177 if ctx['num'] == idx:
4178 logger.info("Test: EAP-Failure")
4179 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4180
4181 idx += 1
4182 if ctx['num'] == idx:
4183 logger.info("Test: Too short AT_VERSION_LIST")
4184 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4185 4 + 1 + 3 + 4,
4186 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
4187 EAP_SIM_AT_VERSION_LIST, 1, 0)
4188 idx += 1
4189 if ctx['num'] == idx:
4190 logger.info("Test: EAP-Failure")
4191 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4192
4193 idx += 1
4194 if ctx['num'] == idx:
4195 logger.info("Test: AT_VERSION_LIST overflow")
4196 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4197 4 + 1 + 3 + 4,
4198 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
4199 EAP_SIM_AT_VERSION_LIST, 1, 0xffff)
4200 idx += 1
4201 if ctx['num'] == idx:
4202 logger.info("Test: EAP-Failure")
4203 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4204
4205 idx += 1
4206 if ctx['num'] == idx:
4207 logger.info("Test: Unexpected AT_AUTS")
4208 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
4209 4 + 1 + 3 + 8,
4210 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
4211 EAP_SIM_AT_AUTS, 2, 0, 0)
4212 idx += 1
4213 if ctx['num'] == idx:
4214 logger.info("Test: EAP-Failure")
4215 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4216
4217 idx += 1
4218 if ctx['num'] == idx:
4219 logger.info("Test: Unexpected AT_CHECKCODE")
4220 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
4221 4 + 1 + 3 + 8,
4222 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
4223 EAP_SIM_AT_CHECKCODE, 2, 0, 0)
4224 idx += 1
4225 if ctx['num'] == idx:
4226 logger.info("Test: EAP-Failure")
4227 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4228
4229 idx += 1
4230 if ctx['num'] == idx:
4231 logger.info("Test: No AT_VERSION_LIST in Start")
4232 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
4233 4 + 1 + 3,
4234 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0)
4235 idx += 1
4236 if ctx['num'] == idx:
4237 logger.info("Test: EAP-Failure")
4238 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4239
4240 idx += 1
4241 if ctx['num'] == idx:
4242 logger.info("Test: No support version in AT_VERSION_LIST")
4243 return struct.pack(">BBHBBHBBH4B", EAP_CODE_REQUEST, ctx['id'],
4244 4 + 1 + 3 + 8,
4245 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
4246 EAP_SIM_AT_VERSION_LIST, 2, 3, 2, 3, 4, 5)
4247 idx += 1
4248 if ctx['num'] == idx:
4249 logger.info("Test: EAP-Failure")
4250 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4251
4252
4253 idx += 1
4254 if ctx['num'] == idx:
4255 logger.info("Test: Identity request without ID type")
4256 return struct.pack(">BBHBBHBBH2H", EAP_CODE_REQUEST, ctx['id'],
4257 4 + 1 + 3 + 8,
4258 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
4259 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0)
4260 idx += 1
4261 if ctx['num'] == idx:
4262 logger.info("Test: Identity request ANY_ID")
4263 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'],
4264 4 + 1 + 3 + 8 + 4,
4265 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
4266 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0,
4267 EAP_SIM_AT_ANY_ID_REQ, 1, 0)
4268 idx += 1
4269 if ctx['num'] == idx:
4270 logger.info("Test: Identity request ANY_ID (duplicate)")
4271 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'],
4272 4 + 1 + 3 + 8 + 4,
4273 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
4274 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0,
4275 EAP_SIM_AT_ANY_ID_REQ, 1, 0)
4276 idx += 1
4277 if ctx['num'] == idx:
4278 logger.info("Test: EAP-Failure")
4279 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4280
4281 idx += 1
4282 if ctx['num'] == idx:
4283 logger.info("Test: Identity request ANY_ID")
4284 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'],
4285 4 + 1 + 3 + 8 + 4,
4286 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
4287 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0,
4288 EAP_SIM_AT_ANY_ID_REQ, 1, 0)
4289 idx += 1
4290 if ctx['num'] == idx:
4291 logger.info("Test: Identity request FULLAUTH_ID")
4292 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'],
4293 4 + 1 + 3 + 8 + 4,
4294 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
4295 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0,
4296 EAP_SIM_AT_FULLAUTH_ID_REQ, 1, 0)
4297 idx += 1
4298 if ctx['num'] == idx:
4299 logger.info("Test: Identity request FULLAUTH_ID (duplicate)")
4300 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'],
4301 4 + 1 + 3 + 8 + 4,
4302 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
4303 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0,
4304 EAP_SIM_AT_FULLAUTH_ID_REQ, 1, 0)
4305 idx += 1
4306 if ctx['num'] == idx:
4307 logger.info("Test: EAP-Failure")
4308 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4309
4310 idx += 1
4311 if ctx['num'] == idx:
4312 logger.info("Test: Identity request ANY_ID")
4313 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'],
4314 4 + 1 + 3 + 8 + 4,
4315 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
4316 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0,
4317 EAP_SIM_AT_ANY_ID_REQ, 1, 0)
4318 idx += 1
4319 if ctx['num'] == idx:
4320 logger.info("Test: Identity request FULLAUTH_ID")
4321 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'],
4322 4 + 1 + 3 + 8 + 4,
4323 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
4324 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0,
4325 EAP_SIM_AT_FULLAUTH_ID_REQ, 1, 0)
4326 idx += 1
4327 if ctx['num'] == idx:
4328 logger.info("Test: Identity request PERMANENT_ID")
4329 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'],
4330 4 + 1 + 3 + 8 + 4,
4331 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
4332 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0,
4333 EAP_SIM_AT_PERMANENT_ID_REQ, 1, 0)
4334 idx += 1
4335 if ctx['num'] == idx:
4336 logger.info("Test: Identity request PERMANENT_ID (duplicate)")
4337 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'],
4338 4 + 1 + 3 + 8 + 4,
4339 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
4340 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0,
4341 EAP_SIM_AT_PERMANENT_ID_REQ, 1, 0)
4342 idx += 1
4343 if ctx['num'] == idx:
4344 logger.info("Test: EAP-Failure")
4345 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4346
4347 idx += 1
4348 if ctx['num'] == idx:
4349 logger.info("Test: No AT_MAC and AT_RAND in Challenge")
4350 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
4351 4 + 1 + 3,
4352 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CHALLENGE, 0)
4353 idx += 1
4354 if ctx['num'] == idx:
4355 logger.info("Test: EAP-Failure")
4356 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4357
4358 idx += 1
4359 if ctx['num'] == idx:
4360 logger.info("Test: No AT_RAND in Challenge")
4361 return struct.pack(">BBHBBHBBH4L", EAP_CODE_REQUEST, ctx['id'],
4362 4 + 1 + 3 + 20,
4363 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CHALLENGE, 0,
4364 EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0)
4365 idx += 1
4366 if ctx['num'] == idx:
4367 logger.info("Test: EAP-Failure")
4368 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4369
4370 idx += 1
4371 if ctx['num'] == idx:
4372 logger.info("Test: Insufficient number of challenges in Challenge")
4373 return struct.pack(">BBHBBHBBH4LBBH4L", EAP_CODE_REQUEST, ctx['id'],
4374 4 + 1 + 3 + 20 + 20,
4375 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CHALLENGE, 0,
4376 EAP_SIM_AT_RAND, 5, 0, 0, 0, 0, 0,
4377 EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0)
4378 idx += 1
4379 if ctx['num'] == idx:
4380 logger.info("Test: EAP-Failure")
4381 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4382
4383 idx += 1
4384 if ctx['num'] == idx:
4385 logger.info("Test: Too many challenges in Challenge")
4386 return struct.pack(">BBHBBHBBH4L4L4L4LBBH4L", EAP_CODE_REQUEST,
4387 ctx['id'],
4388 4 + 1 + 3 + 4 + 4 * 16 + 20,
4389 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CHALLENGE, 0,
4390 EAP_SIM_AT_RAND, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4391 0, 0, 0, 0, 0, 0, 0, 0,
4392 EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0)
4393 idx += 1
4394 if ctx['num'] == idx:
4395 logger.info("Test: EAP-Failure")
4396 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4397
4398 idx += 1
4399 if ctx['num'] == idx:
4400 logger.info("Test: Same RAND multiple times in Challenge")
4401 return struct.pack(">BBHBBHBBH4L4L4LBBH4L", EAP_CODE_REQUEST,
4402 ctx['id'],
4403 4 + 1 + 3 + 4 + 3 * 16 + 20,
4404 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CHALLENGE, 0,
4405 EAP_SIM_AT_RAND, 13, 0, 0, 0, 0, 0, 0, 0, 0, 1,
4406 0, 0, 0, 0,
4407 EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0)
4408 idx += 1
4409 if ctx['num'] == idx:
4410 logger.info("Test: EAP-Failure")
4411 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4412
4413 idx += 1
4414 if ctx['num'] == idx:
4415 logger.info("Test: Notification with no attributes")
4416 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
4417 4 + 1 + 3,
4418 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0)
4419 idx += 1
4420 if ctx['num'] == idx:
4421 logger.info("Test: EAP-Failure")
4422 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4423
4424 idx += 1
4425 if ctx['num'] == idx:
4426 logger.info("Test: Notification indicating success, but no MAC")
4427 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4428 4 + 1 + 3 + 4,
4429 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0,
4430 EAP_SIM_AT_NOTIFICATION, 1, 32768)
4431 idx += 1
4432 if ctx['num'] == idx:
4433 logger.info("Test: EAP-Failure")
4434 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4435
4436 idx += 1
4437 if ctx['num'] == idx:
4438 logger.info("Test: Notification indicating success, but invalid MAC value")
4439 return struct.pack(">BBHBBHBBHBBH4L", EAP_CODE_REQUEST, ctx['id'],
4440 4 + 1 + 3 + 4 + 20,
4441 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0,
4442 EAP_SIM_AT_NOTIFICATION, 1, 32768,
4443 EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0)
4444 idx += 1
4445 if ctx['num'] == idx:
4446 logger.info("Test: EAP-Failure")
4447 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4448
4449 idx += 1
4450 if ctx['num'] == idx:
4451 logger.info("Test: Notification before auth")
4452 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4453 4 + 1 + 3 + 4,
4454 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0,
4455 EAP_SIM_AT_NOTIFICATION, 1, 16384)
4456 idx += 1
4457 if ctx['num'] == idx:
4458 logger.info("Test: EAP-Failure")
4459 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4460
4461 idx += 1
4462 if ctx['num'] == idx:
4463 logger.info("Test: Notification before auth")
4464 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4465 4 + 1 + 3 + 4,
4466 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0,
4467 EAP_SIM_AT_NOTIFICATION, 1, 16385)
4468 idx += 1
4469 if ctx['num'] == idx:
4470 logger.info("Test: EAP-Failure")
4471 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4472
4473 idx += 1
4474 if ctx['num'] == idx:
4475 logger.info("Test: Notification with unrecognized non-failure")
4476 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4477 4 + 1 + 3 + 4,
4478 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0,
4479 EAP_SIM_AT_NOTIFICATION, 1, 0xc000)
4480 idx += 1
4481 if ctx['num'] == idx:
4482 logger.info("Test: Notification before auth (duplicate)")
4483 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4484 4 + 1 + 3 + 4,
4485 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0,
4486 EAP_SIM_AT_NOTIFICATION, 1, 0xc000)
4487 idx += 1
4488 if ctx['num'] == idx:
4489 logger.info("Test: EAP-Failure")
4490 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4491
4492 idx += 1
4493 if ctx['num'] == idx:
4494 logger.info("Test: Re-authentication (unexpected) with no attributes")
4495 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
4496 4 + 1 + 3,
4497 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_REAUTHENTICATION,
4498 0)
4499 idx += 1
4500 if ctx['num'] == idx:
4501 logger.info("Test: EAP-Failure")
4502 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4503
4504 idx += 1
4505 if ctx['num'] == idx:
4506 logger.info("Test: Client Error")
f0174bff
JM
4507 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
4508 4 + 1 + 3,
4509 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CLIENT_ERROR, 0)
6c080dfa
JM
4510 idx += 1
4511 if ctx['num'] == idx:
4512 logger.info("Test: EAP-Failure")
4513 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4514
4515 idx += 1
4516 if ctx['num'] == idx:
4517 logger.info("Test: Unknown subtype")
f0174bff
JM
4518 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
4519 4 + 1 + 3,
4520 EAP_TYPE_SIM, 255, 0)
6c080dfa
JM
4521 idx += 1
4522 if ctx['num'] == idx:
4523 logger.info("Test: EAP-Failure")
4524 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4525
4526 return None
4527
4528 srv = start_radius_server(sim_handler)
6c080dfa
JM
4529
4530 try:
5eee514d 4531 hapd = start_ap(apdev[0])
9efd3447 4532 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
6c080dfa
JM
4533
4534 for i in range(0, 25):
4535 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4536 eap="SIM", identity="1232010000000000",
4537 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581",
4538 wait_connect=False)
4539 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
4540 timeout=15)
4541 if ev is None:
4542 raise Exception("Timeout on EAP start")
fab49f61 4543 if i in [0]:
6c080dfa
JM
4544 time.sleep(0.1)
4545 else:
4546 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"],
4547 timeout=10)
4548 if ev is None:
4549 raise Exception("Timeout on EAP failure")
4550 dev[0].request("REMOVE_NETWORK all")
f0174bff 4551 dev[0].dump_monitor()
6c080dfa
JM
4552 finally:
4553 stop_radius_server(srv)
cb0555f7 4554
d36ae376
JM
4555def test_eap_proto_sim_errors(dev, apdev):
4556 """EAP-SIM protocol tests (error paths)"""
4557 check_hlr_auc_gw_support()
4558 params = hostapd.wpa2_eap_params(ssid="eap-test")
8b8a1864 4559 hapd = hostapd.add_ap(apdev[0], params)
9efd3447 4560 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
d36ae376
JM
4561
4562 with alloc_fail(dev[0], 1, "eap_sim_init"):
4563 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4564 eap="SIM", identity="1232010000000000",
4565 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581",
4566 wait_connect=False)
4567 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
4568 timeout=15)
4569 if ev is None:
4570 raise Exception("Timeout on EAP start")
4571 dev[0].request("REMOVE_NETWORK all")
4572 dev[0].wait_disconnected()
4573
4574 with fail_test(dev[0], 1, "os_get_random;eap_sim_init"):
4575 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4576 eap="SIM", identity="1232010000000000",
4577 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581",
4578 wait_connect=False)
4579 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
4580 timeout=15)
4581 if ev is None:
4582 raise Exception("Timeout on EAP start")
4583 dev[0].request("REMOVE_NETWORK all")
4584 dev[0].wait_disconnected()
4585
4586 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4587 eap="SIM", identity="1232010000000000",
4588 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581")
4589
4590 with fail_test(dev[0], 1, "aes_128_cbc_encrypt;eap_sim_response_reauth"):
4591 hapd.request("EAPOL_REAUTH " + dev[0].own_addr())
4592 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
4593 if ev is None:
4594 raise Exception("EAP re-authentication did not start")
4595 wait_fail_trigger(dev[0], "GET_FAIL")
4596 dev[0].request("REMOVE_NETWORK all")
4597 dev[0].dump_monitor()
4598
4599 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4600 eap="SIM", identity="1232010000000000",
4601 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581")
4602
4603 with fail_test(dev[0], 1, "os_get_random;eap_sim_msg_add_encr_start"):
4604 hapd.request("EAPOL_REAUTH " + dev[0].own_addr())
4605 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
4606 if ev is None:
4607 raise Exception("EAP re-authentication did not start")
4608 wait_fail_trigger(dev[0], "GET_FAIL")
4609 dev[0].request("REMOVE_NETWORK all")
4610 dev[0].dump_monitor()
4611
4612 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4613 eap="SIM", identity="1232010000000000",
4614 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581")
4615
4616 with fail_test(dev[0], 1, "os_get_random;eap_sim_init_for_reauth"):
4617 hapd.request("EAPOL_REAUTH " + dev[0].own_addr())
4618 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
4619 if ev is None:
4620 raise Exception("EAP re-authentication did not start")
4621 wait_fail_trigger(dev[0], "GET_FAIL")
4622 dev[0].request("REMOVE_NETWORK all")
4623 dev[0].dump_monitor()
4624
4625 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4626 eap="SIM", identity="1232010000000000",
4627 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581")
4628
4629 with alloc_fail(dev[0], 1, "eap_sim_parse_encr;eap_sim_process_reauthentication"):
4630 hapd.request("EAPOL_REAUTH " + dev[0].own_addr())
4631 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
4632 if ev is None:
4633 raise Exception("EAP re-authentication did not start")
4634 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
4635 dev[0].request("REMOVE_NETWORK all")
4636 dev[0].dump_monitor()
4637
fab49f61
JM
4638 tests = [(1, "eap_sim_verify_mac;eap_sim_process_challenge"),
4639 (1, "eap_sim_parse_encr;eap_sim_process_challenge"),
4640 (1, "eap_sim_msg_init;eap_sim_response_start"),
4641 (1, "wpabuf_alloc;eap_sim_msg_init;eap_sim_response_start"),
4642 (1, "=eap_sim_learn_ids"),
4643 (2, "=eap_sim_learn_ids"),
4644 (2, "eap_sim_learn_ids"),
4645 (3, "eap_sim_learn_ids"),
4646 (1, "eap_sim_process_start"),
4647 (1, "eap_sim_getKey"),
4648 (1, "eap_sim_get_emsk"),
4649 (1, "eap_sim_get_session_id")]
d36ae376
JM
4650 for count, func in tests:
4651 with alloc_fail(dev[0], count, func):
4652 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
0a0c4dc1 4653 eap="SIM", identity="1232010000000000@domain",
d36ae376
JM
4654 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581",
4655 erp="1", wait_connect=False)
4656 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
4657 dev[0].request("REMOVE_NETWORK all")
4658 dev[0].dump_monitor()
4659
fab49f61 4660 tests = [(1, "aes_128_cbc_decrypt;eap_sim_parse_encr")]
d36ae376
JM
4661 for count, func in tests:
4662 with fail_test(dev[0], count, func):
4663 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4664 eap="SIM", identity="1232010000000000",
4665 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581",
4666 wait_connect=False)
4667 wait_fail_trigger(dev[0], "GET_FAIL")
4668 dev[0].request("REMOVE_NETWORK all")
4669 dev[0].dump_monitor()
4670
7843ae44
JM
4671 params = int_eap_server_params()
4672 params['eap_sim_db'] = "unix:/tmp/hlr_auc_gw.sock"
4673 params['eap_sim_aka_result_ind'] = "1"
9efd3447
JM
4674 hapd2 = hostapd.add_ap(apdev[1], params)
4675 dev[0].scan_for_bss(hapd2.own_addr(), freq=2412)
7843ae44
JM
4676
4677 with alloc_fail(dev[0], 1,
4678 "eap_sim_msg_init;eap_sim_response_notification"):
4679 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP",
4680 scan_freq="2412",
4681 eap="SIM", identity="1232010000000000",
4682 phase1="result_ind=1",
4683 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581",
4684 wait_connect=False)
4685 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
4686 dev[0].request("REMOVE_NETWORK all")
4687 dev[0].dump_monitor()
4688
fab49f61
JM
4689 tests = ["eap_sim_msg_add_encr_start;eap_sim_response_notification",
4690 "aes_128_cbc_encrypt;eap_sim_response_notification"]
7843ae44
JM
4691 for func in tests:
4692 with fail_test(dev[0], 1, func):
4693 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP",
4694 scan_freq="2412",
4695 eap="SIM", identity="1232010000000000",
4696 phase1="result_ind=1",
4697 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581")
4698 dev[0].request("REAUTHENTICATE")
4699 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5)
4700 if ev is None:
4701 raise Exception("EAP method not started on reauthentication")
4702 time.sleep(0.1)
4703 wait_fail_trigger(dev[0], "GET_FAIL")
4704 dev[0].request("REMOVE_NETWORK all")
4705 dev[0].dump_monitor()
4706
fab49f61 4707 tests = ["eap_sim_parse_encr;eap_sim_process_notification_reauth"]
7843ae44
JM
4708 for func in tests:
4709 with alloc_fail(dev[0], 1, func):
4710 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP",
4711 scan_freq="2412",
4712 eap="SIM", identity="1232010000000000",
4713 phase1="result_ind=1",
4714 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581")
4715 dev[0].request("REAUTHENTICATE")
4716 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5)
4717 if ev is None:
4718 raise Exception("EAP method not started on reauthentication")
4719 time.sleep(0.1)
4720 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
4721 dev[0].request("REMOVE_NETWORK all")
4722 dev[0].dump_monitor()
4723
d36ae376
JM
4724def test_eap_proto_aka_errors(dev, apdev):
4725 """EAP-AKA protocol tests (error paths)"""
4726 check_hlr_auc_gw_support()
4727 params = hostapd.wpa2_eap_params(ssid="eap-test")
8b8a1864 4728 hapd = hostapd.add_ap(apdev[0], params)
9efd3447 4729 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
d36ae376
JM
4730
4731 with alloc_fail(dev[0], 1, "eap_aka_init"):
4732 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4733 eap="AKA", identity="0232010000000000",
4734 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123",
4735 wait_connect=False)
4736 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
4737 timeout=15)
4738 if ev is None:
4739 raise Exception("Timeout on EAP start")
4740 dev[0].request("REMOVE_NETWORK all")
4741 dev[0].wait_disconnected()
4742
fab49f61
JM
4743 tests = [(1, "=eap_aka_learn_ids"),
4744 (2, "=eap_aka_learn_ids"),
4745 (1, "eap_sim_parse_encr;eap_aka_process_challenge"),
4746 (1, "wpabuf_dup;eap_aka_add_id_msg"),
4747 (1, "wpabuf_resize;eap_aka_add_id_msg"),
4748 (1, "eap_aka_getKey"),
4749 (1, "eap_aka_get_emsk"),
4750 (1, "eap_aka_get_session_id")]
d36ae376
JM
4751 for count, func in tests:
4752 with alloc_fail(dev[0], count, func):
4753 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
0a0c4dc1 4754 eap="AKA", identity="0232010000000000@domain",
d36ae376
JM
4755 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123",
4756 erp="1", wait_connect=False)
4757 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
4758 dev[0].request("REMOVE_NETWORK all")
4759 dev[0].dump_monitor()
4760
7843ae44
JM
4761 params = int_eap_server_params()
4762 params['eap_sim_db'] = "unix:/tmp/hlr_auc_gw.sock"
4763 params['eap_sim_aka_result_ind'] = "1"
9efd3447
JM
4764 hapd2 = hostapd.add_ap(apdev[1], params)
4765 dev[0].scan_for_bss(hapd2.own_addr(), freq=2412)
7843ae44
JM
4766
4767 with alloc_fail(dev[0], 1,
4768 "eap_sim_msg_init;eap_aka_response_notification"):
4769 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412",
4770 eap="AKA", identity="0232010000000000",
4771 phase1="result_ind=1",
4772 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123",
4773 wait_connect=False)
4774 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
4775 dev[0].request("REMOVE_NETWORK all")
4776 dev[0].dump_monitor()
4777
fab49f61
JM
4778 tests = ["eap_sim_msg_add_encr_start;eap_aka_response_notification",
4779 "aes_128_cbc_encrypt;eap_aka_response_notification"]
7843ae44
JM
4780 for func in tests:
4781 with fail_test(dev[0], 1, func):
4782 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP",
4783 scan_freq="2412",
4784 eap="AKA", identity="0232010000000000",
4785 phase1="result_ind=1",
4786 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123")
4787 dev[0].request("REAUTHENTICATE")
4788 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5)
4789 if ev is None:
4790 raise Exception("EAP method not started on reauthentication")
4791 time.sleep(0.1)
4792 wait_fail_trigger(dev[0], "GET_FAIL")
4793 dev[0].request("REMOVE_NETWORK all")
4794 dev[0].dump_monitor()
4795
fab49f61 4796 tests = ["eap_sim_parse_encr;eap_aka_process_notification_reauth"]
7843ae44
JM
4797 for func in tests:
4798 with alloc_fail(dev[0], 1, func):
4799 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP",
4800 scan_freq="2412",
4801 eap="AKA", identity="0232010000000000",
4802 phase1="result_ind=1",
4803 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123")
4804 dev[0].request("REAUTHENTICATE")
4805 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5)
4806 if ev is None:
4807 raise Exception("EAP method not started on reauthentication")
4808 time.sleep(0.1)
4809 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
4810 dev[0].request("REMOVE_NETWORK all")
4811 dev[0].dump_monitor()
4812
d36ae376
JM
4813def test_eap_proto_aka_prime_errors(dev, apdev):
4814 """EAP-AKA' protocol tests (error paths)"""
4815 check_hlr_auc_gw_support()
4816 params = hostapd.wpa2_eap_params(ssid="eap-test")
8b8a1864 4817 hapd = hostapd.add_ap(apdev[0], params)
9efd3447 4818 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
d36ae376
JM
4819
4820 with alloc_fail(dev[0], 1, "eap_aka_init"):
4821 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4822 eap="AKA'", identity="6555444333222111",
4823 password="5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123",
4824 wait_connect=False)
4825 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
4826 timeout=15)
4827 if ev is None:
4828 raise Exception("Timeout on EAP start")
4829 dev[0].request("REMOVE_NETWORK all")
4830 dev[0].wait_disconnected()
4831
4832 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4833 eap="AKA'", identity="6555444333222111",
4834 password="5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123")
4835
4836 with fail_test(dev[0], 1, "aes_128_cbc_encrypt;eap_aka_response_reauth"):
4837 hapd.request("EAPOL_REAUTH " + dev[0].own_addr())
4838 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
4839 if ev is None:
4840 raise Exception("EAP re-authentication did not start")
4841 wait_fail_trigger(dev[0], "GET_FAIL")
4842 dev[0].request("REMOVE_NETWORK all")
4843 dev[0].dump_monitor()
4844
4845 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4846 eap="AKA'", identity="6555444333222111",
4847 password="5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123")
4848
4849 with alloc_fail(dev[0], 1, "eap_sim_parse_encr;eap_aka_process_reauthentication"):
4850 hapd.request("EAPOL_REAUTH " + dev[0].own_addr())
4851 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
4852 if ev is None:
4853 raise Exception("EAP re-authentication did not start")
4854 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
4855 dev[0].request("REMOVE_NETWORK all")
4856 dev[0].dump_monitor()
4857
fab49f61
JM
4858 tests = [(1, "eap_sim_verify_mac_sha256"),
4859 (1, "=eap_aka_process_challenge")]
d36ae376
JM
4860 for count, func in tests:
4861 with alloc_fail(dev[0], count, func):
4862 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4863 eap="AKA'", identity="6555444333222111",
4864 password="5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123",
4865 erp="1", wait_connect=False)
4866 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
4867 dev[0].request("REMOVE_NETWORK all")
4868 dev[0].dump_monitor()
4869
cb0555f7
JM
4870def test_eap_proto_ikev2(dev, apdev):
4871 """EAP-IKEv2 protocol tests"""
c8e82c94 4872 check_eap_capa(dev[0], "IKEV2")
1a6f8659
JM
4873
4874 global eap_proto_ikev2_test_done
4875 eap_proto_ikev2_test_done = False
4876
cb0555f7 4877 def ikev2_handler(ctx, req):
55845e19 4878 logger.info("ikev2_handler - RX " + binascii.hexlify(req).decode())
cb0555f7
JM
4879 if 'num' not in ctx:
4880 ctx['num'] = 0
4881 ctx['num'] = ctx['num'] + 1
4882 if 'id' not in ctx:
4883 ctx['id'] = 1
4884 ctx['id'] = (ctx['id'] + 1) % 256
4885
4886 idx = 0
4887
4888 idx += 1
4889 if ctx['num'] == idx:
4890 logger.info("Test: Missing payload")
4891 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
4892 4 + 1,
4893 EAP_TYPE_IKEV2)
4894
4895 idx += 1
4896 if ctx['num'] == idx:
4897 logger.info("Test: Truncated Message Length field")
4898 return struct.pack(">BBHBB3B", EAP_CODE_REQUEST, ctx['id'],
4899 4 + 1 + 1 + 3,
4900 EAP_TYPE_IKEV2, 0x80, 0, 0, 0)
4901
4902 idx += 1
4903 if ctx['num'] == idx:
4904 logger.info("Test: Too short Message Length value")
4905 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'],
4906 4 + 1 + 1 + 4 + 1,
4907 EAP_TYPE_IKEV2, 0x80, 0, 1)
4908
4909 idx += 1
4910 if ctx['num'] == idx:
4911 logger.info("Test: Truncated message")
4912 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'],
4913 4 + 1 + 1 + 4,
4914 EAP_TYPE_IKEV2, 0x80, 1)
4915
4916 idx += 1
4917 if ctx['num'] == idx:
4918 logger.info("Test: Truncated message(2)")
4919 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'],
4920 4 + 1 + 1 + 4,
4921 EAP_TYPE_IKEV2, 0x80, 0xffffffff)
4922
4923 idx += 1
4924 if ctx['num'] == idx:
4925 logger.info("Test: Truncated message(3)")
4926 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'],
4927 4 + 1 + 1 + 4,
4928 EAP_TYPE_IKEV2, 0xc0, 0xffffffff)
4929
4930 idx += 1
4931 if ctx['num'] == idx:
4932 logger.info("Test: Truncated message(4)")
4933 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'],
4934 4 + 1 + 1 + 4,
4935 EAP_TYPE_IKEV2, 0xc0, 10000000)
4936
4937 idx += 1
4938 if ctx['num'] == idx:
4939 logger.info("Test: Too long fragments (first fragment)")
4940 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'],
4941 4 + 1 + 1 + 4 + 1,
4942 EAP_TYPE_IKEV2, 0xc0, 2, 1)
4943
4944 idx += 1
4945 if ctx['num'] == idx:
4946 logger.info("Test: Too long fragments (second fragment)")
4947 return struct.pack(">BBHBB2B", EAP_CODE_REQUEST, ctx['id'],
4948 4 + 1 + 1 + 2,
4949 EAP_TYPE_IKEV2, 0x00, 2, 3)
4950
4951 idx += 1
4952 if ctx['num'] == idx:
4953 logger.info("Test: No Message Length field in first fragment")
4954 return struct.pack(">BBHBBB", EAP_CODE_REQUEST, ctx['id'],
4955 4 + 1 + 1 + 1,
4956 EAP_TYPE_IKEV2, 0x40, 1)
4957
4958 idx += 1
4959 if ctx['num'] == idx:
4960 logger.info("Test: ICV before keys")
4961 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
4962 4 + 1 + 1,
4963 EAP_TYPE_IKEV2, 0x20)
4964
4965 idx += 1
4966 if ctx['num'] == idx:
4967 logger.info("Test: Unsupported IKEv2 header version")
4968 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'],
4969 4 + 1 + 1 + 28,
4970 EAP_TYPE_IKEV2, 0x00,
4971 0, 0, 0, 0,
4972 0, 0, 0, 0, 0, 0)
4973
4974 idx += 1
4975 if ctx['num'] == idx:
4976 logger.info("Test: Incorrect IKEv2 header Length")
4977 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'],
4978 4 + 1 + 1 + 28,
4979 EAP_TYPE_IKEV2, 0x00,
4980 0, 0, 0, 0,
4981 0, 0x20, 0, 0, 0, 0)
4982
4983 idx += 1
4984 if ctx['num'] == idx:
4985 logger.info("Test: Unexpected IKEv2 Exchange Type in SA_INIT state")
4986 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'],
4987 4 + 1 + 1 + 28,
4988 EAP_TYPE_IKEV2, 0x00,
4989 0, 0, 0, 0,
4990 0, 0x20, 0, 0, 0, 28)
4991
4992 idx += 1
4993 if ctx['num'] == idx:
4994 logger.info("Test: Unexpected IKEv2 Message ID in SA_INIT state")
4995 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'],
4996 4 + 1 + 1 + 28,
4997 EAP_TYPE_IKEV2, 0x00,
4998 0, 0, 0, 0,
4999 0, 0x20, 34, 0, 1, 28)
5000
5001 idx += 1
5002 if ctx['num'] == idx:
5003 logger.info("Test: Unexpected IKEv2 Flags value")
5004 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'],
5005 4 + 1 + 1 + 28,
5006 EAP_TYPE_IKEV2, 0x00,
5007 0, 0, 0, 0,
5008 0, 0x20, 34, 0, 0, 28)
5009
5010 idx += 1
5011 if ctx['num'] == idx:
5012 logger.info("Test: Unexpected IKEv2 Flags value(2)")
5013 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'],
5014 4 + 1 + 1 + 28,
5015 EAP_TYPE_IKEV2, 0x00,
5016 0, 0, 0, 0,
5017 0, 0x20, 34, 0x20, 0, 28)
5018
5019 idx += 1
5020 if ctx['num'] == idx:
5021 logger.info("Test: No SAi1 in SA_INIT")
5022 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'],
5023 4 + 1 + 1 + 28,
5024 EAP_TYPE_IKEV2, 0x00,
5025 0, 0, 0, 0,
5026 0, 0x20, 34, 0x08, 0, 28)
5027
55845e19 5028 def build_ike(id, next=0, exch_type=34, flags=0x00, ike=b''):
cb0555f7
JM
5029 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, id,
5030 4 + 1 + 1 + 28 + len(ike),
5031 EAP_TYPE_IKEV2, flags,
5032 0, 0, 0, 0,
5033 next, 0x20, exch_type, 0x08, 0,
5034 28 + len(ike)) + ike
5035
5036 idx += 1
5037 if ctx['num'] == idx:
5038 logger.info("Test: Unexpected extra data after payloads")
5039 return build_ike(ctx['id'], ike=struct.pack(">B", 1))
5040
5041 idx += 1
5042 if ctx['num'] == idx:
5043 logger.info("Test: Truncated payload header")
5044 return build_ike(ctx['id'], next=128, ike=struct.pack(">B", 1))
5045
5046 idx += 1
5047 if ctx['num'] == idx:
5048 logger.info("Test: Too small payload header length")
5049 ike = struct.pack(">BBH", 0, 0, 3)
5050 return build_ike(ctx['id'], next=128, ike=ike)
5051
5052 idx += 1
5053 if ctx['num'] == idx:
5054 logger.info("Test: Too large payload header length")
5055 ike = struct.pack(">BBH", 0, 0, 5)
5056 return build_ike(ctx['id'], next=128, ike=ike)
5057
5058 idx += 1
5059 if ctx['num'] == idx:
5060 logger.info("Test: Unsupported payload (non-critical and critical)")
5061 ike = struct.pack(">BBHBBH", 129, 0, 4, 0, 0x01, 4)
5062 return build_ike(ctx['id'], next=128, ike=ike)
5063
5064 idx += 1
5065 if ctx['num'] == idx:
5066 logger.info("Test: Certificate and empty SAi1")
5067 ike = struct.pack(">BBHBBH", 33, 0, 4, 0, 0, 4)
5068 return build_ike(ctx['id'], next=37, ike=ike)
5069
5070 idx += 1
5071 if ctx['num'] == idx:
5072 logger.info("Test: Too short proposal")
5073 ike = struct.pack(">BBHBBHBBB", 0, 0, 4 + 7,
5074 0, 0, 7, 0, 0, 0)
5075 return build_ike(ctx['id'], next=33, ike=ike)
5076
5077 idx += 1
5078 if ctx['num'] == idx:
5079 logger.info("Test: Too small proposal length in SAi1")
5080 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8,
5081 0, 0, 7, 0, 0, 0, 0)
5082 return build_ike(ctx['id'], next=33, ike=ike)
5083
5084 idx += 1
5085 if ctx['num'] == idx:
5086 logger.info("Test: Too large proposal length in SAi1")
5087 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8,
5088 0, 0, 9, 0, 0, 0, 0)
5089 return build_ike(ctx['id'], next=33, ike=ike)
5090
5091 idx += 1
5092 if ctx['num'] == idx:
5093 logger.info("Test: Unexpected proposal type in SAi1")
5094 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8,
5095 1, 0, 8, 0, 0, 0, 0)
5096 return build_ike(ctx['id'], next=33, ike=ike)
5097
5098 idx += 1
5099 if ctx['num'] == idx:
5100 logger.info("Test: Unexpected Protocol ID in SAi1")
5101 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8,
5102 0, 0, 8, 0, 0, 0, 0)
5103 return build_ike(ctx['id'], next=33, ike=ike)
5104
5105 idx += 1
5106 if ctx['num'] == idx:
5107 logger.info("Test: Unexpected proposal number in SAi1")
5108 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8,
5109 0, 0, 8, 0, 1, 0, 0)
5110 return build_ike(ctx['id'], next=33, ike=ike)
5111
5112 idx += 1
5113 if ctx['num'] == idx:
5114 logger.info("Test: Not enough room for SPI in SAi1")
5115 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8,
5116 0, 0, 8, 1, 1, 1, 0)
5117 return build_ike(ctx['id'], next=33, ike=ike)
5118
5119 idx += 1
5120 if ctx['num'] == idx:
5121 logger.info("Test: Unexpected SPI in SAi1")
5122 ike = struct.pack(">BBHBBHBBBBB", 0, 0, 4 + 9,
5123 0, 0, 9, 1, 1, 1, 0, 1)
5124 return build_ike(ctx['id'], next=33, ike=ike)
5125
5126 idx += 1
5127 if ctx['num'] == idx:
5128 logger.info("Test: No transforms in SAi1")
5129 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8,
5130 0, 0, 8, 1, 1, 0, 0)
5131 return build_ike(ctx['id'], next=33, ike=ike)
5132
5133 idx += 1
5134 if ctx['num'] == idx:
5135 logger.info("Test: Too short transform in SAi1")
5136 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8,
5137 0, 0, 8, 1, 1, 0, 1)
5138 return build_ike(ctx['id'], next=33, ike=ike)
5139
5140 idx += 1
5141 if ctx['num'] == idx:
5142 logger.info("Test: Too small transform length in SAi1")
5143 ike = struct.pack(">BBHBBHBBBBBBHBBH", 0, 0, 4 + 8 + 8,
5144 0, 0, 8 + 8, 1, 1, 0, 1,
5145 0, 0, 7, 0, 0, 0)
5146 return build_ike(ctx['id'], next=33, ike=ike)
5147
5148 idx += 1
5149 if ctx['num'] == idx:
5150 logger.info("Test: Too large transform length in SAi1")
5151 ike = struct.pack(">BBHBBHBBBBBBHBBH", 0, 0, 4 + 8 + 8,
5152 0, 0, 8 + 8, 1, 1, 0, 1,
5153 0, 0, 9, 0, 0, 0)
5154 return build_ike(ctx['id'], next=33, ike=ike)
5155
5156 idx += 1
5157 if ctx['num'] == idx:
5158 logger.info("Test: Unexpected Transform type in SAi1")
5159 ike = struct.pack(">BBHBBHBBBBBBHBBH", 0, 0, 4 + 8 + 8,
5160 0, 0, 8 + 8, 1, 1, 0, 1,
5161 1, 0, 8, 0, 0, 0)
5162 return build_ike(ctx['id'], next=33, ike=ike)
5163
5164 idx += 1
5165 if ctx['num'] == idx:
5166 logger.info("Test: No transform attributes in SAi1")
5167 ike = struct.pack(">BBHBBHBBBBBBHBBH", 0, 0, 4 + 8 + 8,
5168 0, 0, 8 + 8, 1, 1, 0, 1,
5169 0, 0, 8, 0, 0, 0)
5170 return build_ike(ctx['id'], next=33, ike=ike)
5171
5172 idx += 1
5173 if ctx['num'] == idx:
5174 logger.info("Test: No transform attr for AES and unexpected data after transforms in SAi1")
5175 tlen1 = 8 + 3
5176 tlen2 = 8 + 4
5177 tlen3 = 8 + 4
5178 tlen = tlen1 + tlen2 + tlen3
5179 ike = struct.pack(">BBHBBHBBBBBBHBBH3BBBHBBHHHBBHBBHHHB",
5180 0, 0, 4 + 8 + tlen + 1,
5181 0, 0, 8 + tlen + 1, 1, 1, 0, 3,
5182 3, 0, tlen1, 1, 0, 12, 1, 2, 3,
5183 3, 0, tlen2, 1, 0, 12, 0, 128,
5184 0, 0, tlen3, 1, 0, 12, 0x8000 | 14, 127,
5185 1)
5186 return build_ike(ctx['id'], next=33, ike=ike)
5187
5188 def build_sa(next=0):
5189 tlen = 5 * 8
5190 return struct.pack(">BBHBBHBBBBBBHBBHBBHBBHBBHBBHBBHBBHBBHBBH",
5191 next, 0, 4 + 8 + tlen,
5192 0, 0, 8 + tlen, 1, 1, 0, 5,
5193 3, 0, 8, 1, 0, 3,
5194 3, 0, 8, 2, 0, 1,
5195 3, 0, 8, 3, 0, 1,
5196 3, 0, 8, 4, 0, 5,
5197 0, 0, 8, 241, 0, 0)
5198
5199 idx += 1
5200 if ctx['num'] == idx:
5201 logger.info("Test: Valid proposal, but no KEi in SAi1")
5202 ike = build_sa()
5203 return build_ike(ctx['id'], next=33, ike=ike)
5204
5205 idx += 1
5206 if ctx['num'] == idx:
5207 logger.info("Test: Empty KEi in SAi1")
5208 ike = build_sa(next=34) + struct.pack(">BBH", 0, 0, 4)
5209 return build_ike(ctx['id'], next=33, ike=ike)
5210
5211 idx += 1
5212 if ctx['num'] == idx:
5213 logger.info("Test: Mismatch in DH Group in SAi1")
5214 ike = build_sa(next=34)
5215 ike += struct.pack(">BBHHH", 0, 0, 4 + 4 + 96, 12345, 0)
55845e19 5216 ike += 96*b'\x00'
cb0555f7
JM
5217 return build_ike(ctx['id'], next=33, ike=ike)
5218 idx += 1
5219 if ctx['num'] == idx:
5220 logger.info("Test: EAP-Failure")
5221 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5222
5223 idx += 1
5224 if ctx['num'] == idx:
5225 logger.info("Test: Invalid DH public value length in SAi1")
5226 ike = build_sa(next=34)
5227 ike += struct.pack(">BBHHH", 0, 0, 4 + 4 + 96, 5, 0)
55845e19 5228 ike += 96*b'\x00'
cb0555f7
JM
5229 return build_ike(ctx['id'], next=33, ike=ike)
5230
5231 def build_ke(next=0):
5232 ke = struct.pack(">BBHHH", next, 0, 4 + 4 + 192, 5, 0)
55845e19 5233 ke += 191*b'\x00'+b'\x02'
cb0555f7
JM
5234 return ke
5235
5236 idx += 1
5237 if ctx['num'] == idx:
5238 logger.info("Test: Valid proposal and KEi, but no Ni in SAi1")
5239 ike = build_sa(next=34)
5240 ike += build_ke()
5241 return build_ike(ctx['id'], next=33, ike=ike)
5242
5243 idx += 1
5244 if ctx['num'] == idx:
5245 logger.info("Test: Too short Ni in SAi1")
5246 ike = build_sa(next=34)
5247 ike += build_ke(next=40)
5248 ike += struct.pack(">BBH", 0, 0, 4)
5249 return build_ike(ctx['id'], next=33, ike=ike)
5250
5251 idx += 1
5252 if ctx['num'] == idx:
5253 logger.info("Test: Too long Ni in SAi1")
5254 ike = build_sa(next=34)
5255 ike += build_ke(next=40)
55845e19 5256 ike += struct.pack(">BBH", 0, 0, 4 + 257) + 257*b'\x00'
cb0555f7
JM
5257 return build_ike(ctx['id'], next=33, ike=ike)
5258
5259 def build_ni(next=0):
55845e19 5260 return struct.pack(">BBH", next, 0, 4 + 256) + 256*b'\x00'
cb0555f7
JM
5261
5262 def build_sai1(id):
5263 ike = build_sa(next=34)
5264 ike += build_ke(next=40)
5265 ike += build_ni()
5266 return build_ike(ctx['id'], next=33, ike=ike)
5267
5268 idx += 1
5269 if ctx['num'] == idx:
5270 logger.info("Test: Valid proposal, KEi, and Ni in SAi1")
5271 return build_sai1(ctx['id'])
5272 idx += 1
5273 if ctx['num'] == idx:
5274 logger.info("Test: EAP-Failure")
5275 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5276
5277 idx += 1
5278 if ctx['num'] == idx:
5279 logger.info("Test: Valid proposal, KEi, and Ni in SAi1")
5280 return build_sai1(ctx['id'])
5281 idx += 1
5282 if ctx['num'] == idx:
5283 logger.info("Test: No integrity checksum")
55845e19 5284 ike = b''
cb0555f7
JM
5285 return build_ike(ctx['id'], next=37, ike=ike)
5286
5287 idx += 1
5288 if ctx['num'] == idx:
5289 logger.info("Test: Valid proposal, KEi, and Ni in SAi1")
5290 return build_sai1(ctx['id'])
5291 idx += 1
5292 if ctx['num'] == idx:
5293 logger.info("Test: Truncated integrity checksum")
5294 return struct.pack(">BBHBB",
5295 EAP_CODE_REQUEST, ctx['id'],
5296 4 + 1 + 1,
5297 EAP_TYPE_IKEV2, 0x20)
5298
5299 idx += 1
5300 if ctx['num'] == idx:
5301 logger.info("Test: Valid proposal, KEi, and Ni in SAi1")
5302 return build_sai1(ctx['id'])
5303 idx += 1
5304 if ctx['num'] == idx:
5305 logger.info("Test: Invalid integrity checksum")
55845e19 5306 ike = b''
cb0555f7
JM
5307 return build_ike(ctx['id'], next=37, flags=0x20, ike=ike)
5308
1a6f8659
JM
5309 idx += 1
5310 if ctx['num'] == idx:
5311 logger.info("No more test responses available - test case completed")
5312 global eap_proto_ikev2_test_done
5313 eap_proto_ikev2_test_done = True
5314 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
5315 4 + 1,
5316 EAP_TYPE_IKEV2)
5317 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
cb0555f7
JM
5318
5319 srv = start_radius_server(ikev2_handler)
cb0555f7
JM
5320
5321 try:
5eee514d 5322 hapd = start_ap(apdev[0])
9efd3447 5323 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
cb0555f7 5324
1a6f8659
JM
5325 i = 0
5326 while not eap_proto_ikev2_test_done:
5327 i += 1
5328 logger.info("Running connection iteration %d" % i)
cb0555f7
JM
5329 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5330 eap="IKEV2", identity="user",
5331 password="password",
5332 wait_connect=False)
1a6f8659
JM
5333 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=15)
5334 if ev is None:
5335 raise Exception("Timeout on EAP start")
cb0555f7
JM
5336 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
5337 timeout=15)
5338 if ev is None:
1a6f8659 5339 raise Exception("Timeout on EAP method start")
fab49f61 5340 if i in [41, 46]:
cb0555f7
JM
5341 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"],
5342 timeout=10)
5343 if ev is None:
5344 raise Exception("Timeout on EAP failure")
5345 else:
5346 time.sleep(0.05)
5347 dev[0].request("REMOVE_NETWORK all")
1a6f8659
JM
5348 dev[0].wait_disconnected()
5349 dev[0].dump_monitor()
5350 dev[1].dump_monitor()
5351 dev[2].dump_monitor()
cb0555f7
JM
5352 finally:
5353 stop_radius_server(srv)
37211e15
JM
5354
5355def NtPasswordHash(password):
5356 pw = password.encode('utf_16_le')
5357 return hashlib.new('md4', pw).digest()
5358
5359def HashNtPasswordHash(password_hash):
5360 return hashlib.new('md4', password_hash).digest()
5361
5362def ChallengeHash(peer_challenge, auth_challenge, username):
5363 data = peer_challenge + auth_challenge + username
5364 return hashlib.sha1(data).digest()[0:8]
5365
5366def GenerateAuthenticatorResponse(password, nt_response, peer_challenge,
5367 auth_challenge, username):
5368 magic1 = binascii.unhexlify("4D616769632073657276657220746F20636C69656E74207369676E696E6720636F6E7374616E74")
5369 magic2 = binascii.unhexlify("50616420746F206D616B6520697420646F206D6F7265207468616E206F6E6520697465726174696F6E")
5370
5371 password_hash = NtPasswordHash(password)
5372 password_hash_hash = HashNtPasswordHash(password_hash)
5373 data = password_hash_hash + nt_response + magic1
5374 digest = hashlib.sha1(data).digest()
5375
55845e19 5376 challenge = ChallengeHash(peer_challenge, auth_challenge, username.encode())
37211e15
JM
5377
5378 data = digest + challenge + magic2
5379 resp = hashlib.sha1(data).digest()
5380 return resp
5381
4073ef22
JM
5382def test_eap_proto_ikev2_errors(dev, apdev):
5383 """EAP-IKEv2 local error cases"""
5384 check_eap_capa(dev[0], "IKEV2")
5385 params = hostapd.wpa2_eap_params(ssid="eap-test")
8b8a1864 5386 hapd = hostapd.add_ap(apdev[0], params)
9efd3447 5387 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
4073ef22
JM
5388
5389 for i in range(1, 5):
5390 with alloc_fail(dev[0], i, "eap_ikev2_init"):
5391 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5392 eap="IKEV2", identity="ikev2 user",
5393 password="ike password",
5394 wait_connect=False)
5395 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
5396 timeout=15)
5397 if ev is None:
5398 raise Exception("Timeout on EAP start")
5399 dev[0].request("REMOVE_NETWORK all")
5400 dev[0].wait_disconnected()
5401
fab49f61
JM
5402 tests = [(1, "ikev2_encr_encrypt"),
5403 (1, "ikev2_encr_decrypt"),
5404 (1, "ikev2_derive_auth_data"),
5405 (2, "ikev2_derive_auth_data"),
5406 (1, "=ikev2_decrypt_payload"),
5407 (1, "ikev2_encr_decrypt;ikev2_decrypt_payload"),
5408 (1, "ikev2_encr_encrypt;ikev2_build_encrypted"),
5409 (1, "ikev2_derive_sk_keys"),
5410 (2, "ikev2_derive_sk_keys"),
5411 (3, "ikev2_derive_sk_keys"),
5412 (4, "ikev2_derive_sk_keys"),
5413 (5, "ikev2_derive_sk_keys"),
5414 (6, "ikev2_derive_sk_keys"),
5415 (7, "ikev2_derive_sk_keys"),
5416 (8, "ikev2_derive_sk_keys"),
5417 (1, "eap_ikev2_derive_keymat;eap_ikev2_peer_keymat"),
5418 (1, "eap_msg_alloc;eap_ikev2_build_msg"),
5419 (1, "eap_ikev2_getKey"),
5420 (1, "eap_ikev2_get_emsk"),
5421 (1, "eap_ikev2_get_session_id"),
5422 (1, "=ikev2_derive_keys"),
5423 (2, "=ikev2_derive_keys"),
5424 (1, "wpabuf_alloc;ikev2_process_kei"),
5425 (1, "=ikev2_process_idi"),
5426 (1, "ikev2_derive_auth_data;ikev2_build_auth"),
5427 (1, "wpabuf_alloc;ikev2_build_sa_init"),
5428 (2, "wpabuf_alloc;ikev2_build_sa_init"),
5429 (3, "wpabuf_alloc;ikev2_build_sa_init"),
5430 (4, "wpabuf_alloc;ikev2_build_sa_init"),
5431 (5, "wpabuf_alloc;ikev2_build_sa_init"),
5432 (6, "wpabuf_alloc;ikev2_build_sa_init"),
5433 (1, "wpabuf_alloc;ikev2_build_sa_auth"),
5434 (2, "wpabuf_alloc;ikev2_build_sa_auth"),
5435 (1, "ikev2_build_auth;ikev2_build_sa_auth")]
4073ef22
JM
5436 for count, func in tests:
5437 with alloc_fail(dev[0], count, func):
5438 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
0a0c4dc1 5439 eap="IKEV2", identity="ikev2 user@domain",
4073ef22
JM
5440 password="ike password", erp="1", wait_connect=False)
5441 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
5442 timeout=15)
5443 if ev is None:
5444 raise Exception("Timeout on EAP start")
5445 ok = False
5446 for j in range(10):
5447 state = dev[0].request('GET_ALLOC_FAIL')
5448 if state.startswith('0:'):
5449 ok = True
5450 break
5451 time.sleep(0.1)
5452 if not ok:
5453 raise Exception("No allocation failure seen for %d:%s" % (count, func))
5454 dev[0].request("REMOVE_NETWORK all")
5455 dev[0].wait_disconnected()
5456
fab49f61
JM
5457 tests = [(1, "wpabuf_alloc;ikev2_build_notify"),
5458 (2, "wpabuf_alloc;ikev2_build_notify"),
5459 (1, "ikev2_build_encrypted;ikev2_build_notify")]
4073ef22
JM
5460 for count, func in tests:
5461 with alloc_fail(dev[0], count, func):
5462 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5463 eap="IKEV2", identity="ikev2 user",
5464 password="wrong password", erp="1",
5465 wait_connect=False)
5466 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
5467 timeout=15)
5468 if ev is None:
5469 raise Exception("Timeout on EAP start")
5470 ok = False
5471 for j in range(10):
5472 state = dev[0].request('GET_ALLOC_FAIL')
5473 if state.startswith('0:'):
5474 ok = True
5475 break
5476 time.sleep(0.1)
5477 if not ok:
5478 raise Exception("No allocation failure seen for %d:%s" % (count, func))
5479 dev[0].request("REMOVE_NETWORK all")
5480 dev[0].wait_disconnected()
5481
fab49f61
JM
5482 tests = [(1, "ikev2_integ_hash"),
5483 (1, "ikev2_integ_hash;ikev2_decrypt_payload"),
5484 (1, "os_get_random;ikev2_build_encrypted"),
5485 (1, "ikev2_prf_plus;ikev2_derive_sk_keys"),
5486 (1, "eap_ikev2_derive_keymat;eap_ikev2_peer_keymat"),
5487 (1, "os_get_random;ikev2_build_sa_init"),
5488 (2, "os_get_random;ikev2_build_sa_init"),
5489 (1, "ikev2_integ_hash;eap_ikev2_validate_icv"),
5490 (1, "hmac_sha1_vector;?ikev2_prf_hash;ikev2_derive_keys"),
5491 (1, "hmac_sha1_vector;?ikev2_prf_hash;ikev2_derive_auth_data"),
5492 (2, "hmac_sha1_vector;?ikev2_prf_hash;ikev2_derive_auth_data"),
5493 (3, "hmac_sha1_vector;?ikev2_prf_hash;ikev2_derive_auth_data")]
4073ef22
JM
5494 for count, func in tests:
5495 with fail_test(dev[0], count, func):
5496 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5497 eap="IKEV2", identity="ikev2 user",
5498 password="ike password", wait_connect=False)
5499 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
5500 timeout=15)
5501 if ev is None:
5502 raise Exception("Timeout on EAP start")
5503 ok = False
5504 for j in range(10):
5505 state = dev[0].request('GET_FAIL')
5506 if state.startswith('0:'):
5507 ok = True
5508 break
5509 time.sleep(0.1)
5510 if not ok:
5511 raise Exception("No failure seen for %d:%s" % (count, func))
5512 dev[0].request("REMOVE_NETWORK all")
5513 dev[0].wait_disconnected()
5514
fab49f61
JM
5515 params = {"ssid": "eap-test2", "wpa": "2", "wpa_key_mgmt": "WPA-EAP",
5516 "rsn_pairwise": "CCMP", "ieee8021x": "1",
5517 "eap_server": "1", "eap_user_file": "auth_serv/eap_user.conf",
5518 "fragment_size": "50"}
9efd3447
JM
5519 hapd2 = hostapd.add_ap(apdev[1], params)
5520 dev[0].scan_for_bss(hapd2.own_addr(), freq=2412)
4073ef22 5521
fab49f61
JM
5522 tests = [(1, "eap_ikev2_build_frag_ack"),
5523 (1, "wpabuf_alloc;eap_ikev2_process_fragment")]
4073ef22
JM
5524 for count, func in tests:
5525 with alloc_fail(dev[0], count, func):
5526 dev[0].connect("eap-test2", key_mgmt="WPA-EAP", scan_freq="2412",
5527 eap="IKEV2", identity="ikev2 user",
5528 password="ike password", erp="1", wait_connect=False)
5529 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
5530 timeout=15)
5531 if ev is None:
5532 raise Exception("Timeout on EAP start")
5533 ok = False
5534 for j in range(10):
5535 state = dev[0].request('GET_ALLOC_FAIL')
5536 if state.startswith('0:'):
5537 ok = True
5538 break
5539 time.sleep(0.1)
5540 if not ok:
5541 raise Exception("No allocation failure seen for %d:%s" % (count, func))
5542 dev[0].request("REMOVE_NETWORK all")
5543 dev[0].wait_disconnected()
5544
37211e15
JM
5545def test_eap_proto_mschapv2(dev, apdev):
5546 """EAP-MSCHAPv2 protocol tests"""
5547 check_eap_capa(dev[0], "MSCHAPV2")
5548
5549 def mschapv2_handler(ctx, req):
55845e19 5550 logger.info("mschapv2_handler - RX " + binascii.hexlify(req).decode())
37211e15
JM
5551 if 'num' not in ctx:
5552 ctx['num'] = 0
5553 ctx['num'] = ctx['num'] + 1
5554 if 'id' not in ctx:
5555 ctx['id'] = 1
5556 ctx['id'] = (ctx['id'] + 1) % 256
5557 idx = 0
5558
5559 idx += 1
5560 if ctx['num'] == idx:
5561 logger.info("Test: Missing payload")
5562 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
5563 4 + 1,
5564 EAP_TYPE_MSCHAPV2)
5565
5566 idx += 1
5567 if ctx['num'] == idx:
5568 logger.info("Test: Unknown MSCHAPv2 op_code")
5569 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
5570 4 + 1 + 4 + 1,
5571 EAP_TYPE_MSCHAPV2,
5572 0, 0, 5, 0)
5573
5574 idx += 1
5575 if ctx['num'] == idx:
5576 logger.info("Test: Invalid ms_len and unknown MSCHAPv2 op_code")
5577 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
5578 4 + 1 + 4 + 1,
5579 EAP_TYPE_MSCHAPV2,
5580 255, 0, 0, 0)
5581
5582 idx += 1
5583 if ctx['num'] == idx:
5584 logger.info("Test: Success before challenge")
5585 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
5586 4 + 1 + 4 + 1,
5587 EAP_TYPE_MSCHAPV2,
5588 3, 0, 5, 0)
5589
5590 idx += 1
5591 if ctx['num'] == idx:
5592 logger.info("Test: Failure before challenge - required challenge field not present")
5593 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
5594 4 + 1 + 4 + 1,
5595 EAP_TYPE_MSCHAPV2,
5596 4, 0, 5, 0)
5597 idx += 1
5598 if ctx['num'] == idx:
5599 logger.info("Test: Failure")
5600 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5601
5602 idx += 1
5603 if ctx['num'] == idx:
5604 logger.info("Test: Failure before challenge - invalid failure challenge len")
55845e19 5605 payload = b'C=12'
37211e15
JM
5606 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
5607 4 + 1 + 4 + len(payload),
5608 EAP_TYPE_MSCHAPV2,
5609 4, 0, 4 + len(payload)) + payload
5610 idx += 1
5611 if ctx['num'] == idx:
5612 logger.info("Test: Failure")
5613 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5614
5615 idx += 1
5616 if ctx['num'] == idx:
5617 logger.info("Test: Failure before challenge - invalid failure challenge len")
55845e19 5618 payload = b'C=12 V=3'
37211e15
JM
5619 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
5620 4 + 1 + 4 + len(payload),
5621 EAP_TYPE_MSCHAPV2,
5622 4, 0, 4 + len(payload)) + payload
5623 idx += 1
5624 if ctx['num'] == idx:
5625 logger.info("Test: Failure")
5626 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5627
5628 idx += 1
5629 if ctx['num'] == idx:
5630 logger.info("Test: Failure before challenge - invalid failure challenge")
55845e19 5631 payload = b'C=00112233445566778899aabbccddeefQ '
37211e15
JM
5632 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
5633 4 + 1 + 4 + len(payload),
5634 EAP_TYPE_MSCHAPV2,
5635 4, 0, 4 + len(payload)) + payload
5636 idx += 1
5637 if ctx['num'] == idx:
5638 logger.info("Test: Failure")
5639 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5640
5641 idx += 1
5642 if ctx['num'] == idx:
5643 logger.info("Test: Failure before challenge - password expired")
55845e19 5644 payload = b'E=648 R=1 C=00112233445566778899aabbccddeeff V=3 M=Password expired'
37211e15
JM
5645 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
5646 4 + 1 + 4 + len(payload),
5647 EAP_TYPE_MSCHAPV2,
5648 4, 0, 4 + len(payload)) + payload
5649 idx += 1
5650 if ctx['num'] == idx:
5651 logger.info("Test: Success after password change")
55845e19 5652 payload = b"S=1122334455667788990011223344556677889900"
37211e15
JM
5653 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
5654 4 + 1 + 4 + len(payload),
5655 EAP_TYPE_MSCHAPV2,
5656 3, 0, 4 + len(payload)) + payload
5657
5658 idx += 1
5659 if ctx['num'] == idx:
5660 logger.info("Test: Invalid challenge length")
5661 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
5662 4 + 1 + 4 + 1,
5663 EAP_TYPE_MSCHAPV2,
5664 1, 0, 4 + 1, 0)
5665
5666 idx += 1
5667 if ctx['num'] == idx:
5668 logger.info("Test: Too short challenge packet")
5669 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
5670 4 + 1 + 4 + 1,
5671 EAP_TYPE_MSCHAPV2,
5672 1, 0, 4 + 1, 16)
5673
5674 idx += 1
5675 if ctx['num'] == idx:
5676 logger.info("Test: Challenge")
5677 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
5678 4 + 1 + 4 + 1 + 16 + 6,
5679 EAP_TYPE_MSCHAPV2,
55845e19 5680 1, 0, 4 + 1 + 16 + 6, 16) + 16*b'A' + b'foobar'
37211e15
JM
5681 idx += 1
5682 if ctx['num'] == idx:
5683 logger.info("Test: Failure - password expired")
55845e19 5684 payload = b'E=648 R=1 C=00112233445566778899aabbccddeeff V=3 M=Password expired'
37211e15
JM
5685 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
5686 4 + 1 + 4 + len(payload),
5687 EAP_TYPE_MSCHAPV2,
5688 4, 0, 4 + len(payload)) + payload
5689 idx += 1
5690 if ctx['num'] == idx:
5691 logger.info("Test: Success after password change")
5692 if len(req) != 591:
5693 logger.info("Unexpected Change-Password packet length: %s" % len(req))
5694 return None
5695 data = req[9:]
5696 enc_pw = data[0:516]
5697 data = data[516:]
5698 enc_hash = data[0:16]
5699 data = data[16:]
5700 peer_challenge = data[0:16]
5701 data = data[16:]
5702 # Reserved
5703 data = data[8:]
5704 nt_response = data[0:24]
5705 data = data[24:]
5706 flags = data
55845e19
JM
5707 logger.info("enc_hash: " + binascii.hexlify(enc_hash).decode())
5708 logger.info("peer_challenge: " + binascii.hexlify(peer_challenge).decode())
5709 logger.info("nt_response: " + binascii.hexlify(nt_response).decode())
5710 logger.info("flags: " + binascii.hexlify(flags).decode())
37211e15
JM
5711
5712 auth_challenge = binascii.unhexlify("00112233445566778899aabbccddeeff")
55845e19 5713 logger.info("auth_challenge: " + binascii.hexlify(auth_challenge).decode())
db98b587 5714
37211e15
JM
5715 auth_resp = GenerateAuthenticatorResponse("new-pw", nt_response,
5716 peer_challenge,
5717 auth_challenge, "user")
55845e19
JM
5718 payload = b"S=" + binascii.hexlify(auth_resp).decode().upper().encode()
5719 logger.info("Success message payload: " + payload.decode())
37211e15
JM
5720 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
5721 4 + 1 + 4 + len(payload),
5722 EAP_TYPE_MSCHAPV2,
5723 3, 0, 4 + len(payload)) + payload
5724 idx += 1
5725 if ctx['num'] == idx:
5726 logger.info("Test: EAP-Success")
5727 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4)
5728
5729 idx += 1
5730 if ctx['num'] == idx:
5731 logger.info("Test: Failure - password expired")
55845e19 5732 payload = b'E=648 R=1 C=00112233445566778899aabbccddeeff V=3 M=Password expired'
37211e15
JM
5733 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
5734 4 + 1 + 4 + len(payload),
5735 EAP_TYPE_MSCHAPV2,
5736 4, 0, 4 + len(payload)) + payload
5737 idx += 1
5738 if ctx['num'] == idx:
5739 logger.info("Test: Success after password change")
5740 if len(req) != 591:
5741 logger.info("Unexpected Change-Password packet length: %s" % len(req))
5742 return None
5743 data = req[9:]
5744 enc_pw = data[0:516]
5745 data = data[516:]
5746 enc_hash = data[0:16]
5747 data = data[16:]
5748 peer_challenge = data[0:16]
5749 data = data[16:]
5750 # Reserved
5751 data = data[8:]
5752 nt_response = data[0:24]
5753 data = data[24:]
5754 flags = data
55845e19
JM
5755 logger.info("enc_hash: " + binascii.hexlify(enc_hash).decode())
5756 logger.info("peer_challenge: " + binascii.hexlify(peer_challenge).decode())
5757 logger.info("nt_response: " + binascii.hexlify(nt_response).decode())
5758 logger.info("flags: " + binascii.hexlify(flags).decode())
37211e15
JM
5759
5760 auth_challenge = binascii.unhexlify("00112233445566778899aabbccddeeff")
55845e19 5761 logger.info("auth_challenge: " + binascii.hexlify(auth_challenge).decode())
db98b587 5762
37211e15
JM
5763 auth_resp = GenerateAuthenticatorResponse("new-pw", nt_response,
5764 peer_challenge,
5765 auth_challenge, "user")
55845e19
JM
5766 payload = b"S=" + binascii.hexlify(auth_resp).decode().upper().encode()
5767 logger.info("Success message payload: " + payload.decode())
37211e15
JM
5768 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
5769 4 + 1 + 4 + len(payload),
5770 EAP_TYPE_MSCHAPV2,
5771 3, 0, 4 + len(payload)) + payload
5772 idx += 1
5773 if ctx['num'] == idx:
5774 logger.info("Test: EAP-Success")
5775 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4)
5776
5777 idx += 1
5778 if ctx['num'] == idx:
5779 logger.info("Test: Challenge")
5780 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
5781 4 + 1 + 4 + 1 + 16 + 6,
5782 EAP_TYPE_MSCHAPV2,
55845e19 5783 1, 0, 4 + 1 + 16 + 6, 16) + 16*b'A' + b'foobar'
37211e15
JM
5784 idx += 1
5785 if ctx['num'] == idx:
5786 logger.info("Test: Failure - authentication failure")
55845e19 5787 payload = b'E=691 R=1 C=00112233445566778899aabbccddeeff V=3 M=Authentication failed'
37211e15
JM
5788 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
5789 4 + 1 + 4 + len(payload),
5790 EAP_TYPE_MSCHAPV2,
5791 4, 0, 4 + len(payload)) + payload
5792
5793 idx += 1
5794 if ctx['num'] == idx:
5795 logger.info("Test: Challenge")
5796 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
5797 4 + 1 + 4 + 1 + 16 + 6,
5798 EAP_TYPE_MSCHAPV2,
55845e19 5799 1, 0, 4 + 1 + 16 + 6, 16) + 16*b'A' + b'foobar'
37211e15
JM
5800 idx += 1
5801 if ctx['num'] == idx:
5802 logger.info("Test: Failure - authentication failure")
55845e19 5803 payload = b'E=691 R=1 C=00112233445566778899aabbccddeeff V=3 M=Authentication failed (2)'
37211e15
JM
5804 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
5805 4 + 1 + 4 + len(payload),
5806 EAP_TYPE_MSCHAPV2,
5807 4, 0, 4 + len(payload)) + payload
5808 idx += 1
5809 if ctx['num'] == idx:
5810 logger.info("Test: Failure")
5811 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5812
5b0ec907
JM
5813 idx += 1
5814 if ctx['num'] == idx:
5815 logger.info("Test: Challenge - invalid ms_len and workaround disabled")
5816 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
5817 4 + 1 + 4 + 1 + 16 + 6,
5818 EAP_TYPE_MSCHAPV2,
55845e19 5819 1, 0, 4 + 1 + 16 + 6 + 1, 16) + 16*b'A' + b'foobar'
5b0ec907 5820
37211e15
JM
5821 return None
5822
5823 srv = start_radius_server(mschapv2_handler)
5824
5825 try:
5eee514d 5826 hapd = start_ap(apdev[0])
9efd3447 5827 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
37211e15 5828
5b0ec907 5829 for i in range(0, 16):
37211e15
JM
5830 logger.info("RUN: %d" % i)
5831 if i == 12:
5832 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5833 eap="MSCHAPV2", identity="user",
5834 password_hex="hash:8846f7eaee8fb117ad06bdd830b7586c",
5835 wait_connect=False)
5836 elif i == 14:
5837 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5838 eap="MSCHAPV2", identity="user",
5839 phase2="mschapv2_retry=0",
5840 password="password", wait_connect=False)
5b0ec907
JM
5841 elif i == 15:
5842 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5843 eap="MSCHAPV2", identity="user",
5844 eap_workaround="0",
5845 password="password", wait_connect=False)
37211e15
JM
5846 else:
5847 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5848 eap="MSCHAPV2", identity="user",
5849 password="password", wait_connect=False)
5850 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15)
5851 if ev is None:
5852 raise Exception("Timeout on EAP start")
5853
fab49f61 5854 if i in [8, 11, 12]:
37211e15
JM
5855 ev = dev[0].wait_event(["CTRL-REQ-NEW_PASSWORD"],
5856 timeout=10)
5857 if ev is None:
5858 raise Exception("Timeout on new password request")
5859 id = ev.split(':')[0].split('-')[-1]
5860 dev[0].request("CTRL-RSP-NEW_PASSWORD-" + id + ":new-pw")
fab49f61 5861 if i in [11, 12]:
37211e15
JM
5862 ev = dev[0].wait_event(["CTRL-EVENT-PASSWORD-CHANGED"],
5863 timeout=10)
5864 if ev is None:
5865 raise Exception("Timeout on password change")
5866 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"],
5867 timeout=10)
5868 if ev is None:
5869 raise Exception("Timeout on EAP success")
5870 else:
5871 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"],
5872 timeout=10)
5873 if ev is None:
5874 raise Exception("Timeout on EAP failure")
5875
fab49f61 5876 if i in [13]:
37211e15
JM
5877 ev = dev[0].wait_event(["CTRL-REQ-IDENTITY"],
5878 timeout=10)
5879 if ev is None:
5880 raise Exception("Timeout on identity request")
5881 id = ev.split(':')[0].split('-')[-1]
5882 dev[0].request("CTRL-RSP-IDENTITY-" + id + ":user")
5883
5884 ev = dev[0].wait_event(["CTRL-REQ-PASSWORD"],
5885 timeout=10)
5886 if ev is None:
5887 raise Exception("Timeout on password request")
5888 id = ev.split(':')[0].split('-')[-1]
5889 dev[0].request("CTRL-RSP-PASSWORD-" + id + ":password")
5890
5891 # TODO: Does this work correctly?
5892
5893 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"],
5894 timeout=10)
5895 if ev is None:
5896 raise Exception("Timeout on EAP failure")
5897
fab49f61 5898 if i in [4, 5, 6, 7, 14]:
37211e15
JM
5899 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"],
5900 timeout=10)
5901 if ev is None:
5902 raise Exception("Timeout on EAP failure")
5903 else:
5904 time.sleep(0.05)
5905 dev[0].request("REMOVE_NETWORK all")
5906 dev[0].wait_disconnected(timeout=1)
5907 finally:
5908 stop_radius_server(srv)
7c0d66cf
JM
5909
5910def test_eap_proto_mschapv2_errors(dev, apdev):
5911 """EAP-MSCHAPv2 protocol tests (error paths)"""
5912 check_eap_capa(dev[0], "MSCHAPV2")
5913
5b0ec907
JM
5914 def mschapv2_fail_password_expired(ctx):
5915 logger.info("Test: Failure before challenge - password expired")
55845e19 5916 payload = b'E=648 R=1 C=00112233445566778899aabbccddeeff V=3 M=Password expired'
5b0ec907
JM
5917 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
5918 4 + 1 + 4 + len(payload),
5919 EAP_TYPE_MSCHAPV2,
5920 4, 0, 4 + len(payload)) + payload
5921
5922 def mschapv2_success_after_password_change(ctx, req=None):
5923 logger.info("Test: Success after password change")
5924 if req is None or len(req) != 591:
55845e19 5925 payload = b"S=1122334455667788990011223344556677889900"
5b0ec907
JM
5926 else:
5927 data = req[9:]
5928 enc_pw = data[0:516]
5929 data = data[516:]
5930 enc_hash = data[0:16]
5931 data = data[16:]
5932 peer_challenge = data[0:16]
5933 data = data[16:]
5934 # Reserved
5935 data = data[8:]
5936 nt_response = data[0:24]
5937 data = data[24:]
5938 flags = data
55845e19
JM
5939 logger.info("enc_hash: " + binascii.hexlify(enc_hash).decode())
5940 logger.info("peer_challenge: " + binascii.hexlify(peer_challenge).decode())
5941 logger.info("nt_response: " + binascii.hexlify(nt_response).decode())
5942 logger.info("flags: " + binascii.hexlify(flags).decode())
5b0ec907
JM
5943
5944 auth_challenge = binascii.unhexlify("00112233445566778899aabbccddeeff")
55845e19 5945 logger.info("auth_challenge: " + binascii.hexlify(auth_challenge).decode())
5b0ec907
JM
5946
5947 auth_resp = GenerateAuthenticatorResponse("new-pw", nt_response,
5948 peer_challenge,
5949 auth_challenge, "user")
55845e19 5950 payload = b"S=" + binascii.hexlify(auth_resp).decode().upper().encode()
5b0ec907
JM
5951 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
5952 4 + 1 + 4 + len(payload),
5953 EAP_TYPE_MSCHAPV2,
5954 3, 0, 4 + len(payload)) + payload
5955
7c0d66cf 5956 def mschapv2_handler(ctx, req):
55845e19 5957 logger.info("mschapv2_handler - RX " + binascii.hexlify(req).decode())
7c0d66cf
JM
5958 if 'num' not in ctx:
5959 ctx['num'] = 0
5960 ctx['num'] = ctx['num'] + 1
5961 if 'id' not in ctx:
5962 ctx['id'] = 1
5963 ctx['id'] = (ctx['id'] + 1) % 256
5964 idx = 0
5965
5966 idx += 1
5967 if ctx['num'] == idx:
5b0ec907 5968 return mschapv2_fail_password_expired(ctx)
7c0d66cf
JM
5969 idx += 1
5970 if ctx['num'] == idx:
5b0ec907
JM
5971 return mschapv2_success_after_password_change(ctx, req)
5972 idx += 1
5973 if ctx['num'] == idx:
5974 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7c0d66cf
JM
5975
5976 idx += 1
5977 if ctx['num'] == idx:
5b0ec907 5978 return mschapv2_fail_password_expired(ctx)
7c0d66cf
JM
5979 idx += 1
5980 if ctx['num'] == idx:
5b0ec907
JM
5981 return mschapv2_success_after_password_change(ctx, req)
5982 idx += 1
5983 if ctx['num'] == idx:
5984 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5985
5986 idx += 1
5987 if ctx['num'] == idx:
5988 return mschapv2_fail_password_expired(ctx)
5989 idx += 1
5990 if ctx['num'] == idx:
5991 return mschapv2_success_after_password_change(ctx, req)
5992 idx += 1
5993 if ctx['num'] == idx:
5994 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5995
5996 idx += 1
5997 if ctx['num'] == idx:
5998 return mschapv2_fail_password_expired(ctx)
5999 idx += 1
6000 if ctx['num'] == idx:
6001 return mschapv2_success_after_password_change(ctx, req)
6002 idx += 1
6003 if ctx['num'] == idx:
6004 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6005
6006 idx += 1
6007 if ctx['num'] == idx:
6008 return mschapv2_fail_password_expired(ctx)
6009 idx += 1
6010 if ctx['num'] == idx:
6011 return mschapv2_success_after_password_change(ctx, req)
6012 idx += 1
6013 if ctx['num'] == idx:
6014 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6015
6016 idx += 1
6017 if ctx['num'] == idx:
6018 return mschapv2_fail_password_expired(ctx)
6019 idx += 1
6020 if ctx['num'] == idx:
6021 return mschapv2_success_after_password_change(ctx, req)
6022 idx += 1
6023 if ctx['num'] == idx:
6024 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6025
6026 idx += 1
6027 if ctx['num'] == idx:
6028 return mschapv2_fail_password_expired(ctx)
6029 idx += 1
6030 if ctx['num'] == idx:
6031 return mschapv2_success_after_password_change(ctx, req)
6032 idx += 1
6033 if ctx['num'] == idx:
6034 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6035
6036 idx += 1
6037 if ctx['num'] == idx:
6038 return mschapv2_fail_password_expired(ctx)
6039 idx += 1
6040 if ctx['num'] == idx:
6041 return mschapv2_success_after_password_change(ctx, req)
6042 idx += 1
6043 if ctx['num'] == idx:
6044 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6045
6046 idx += 1
6047 if ctx['num'] == idx:
6048 return mschapv2_fail_password_expired(ctx)
6049 idx += 1
6050 if ctx['num'] == idx:
6051 return mschapv2_success_after_password_change(ctx, req)
6052 idx += 1
6053 if ctx['num'] == idx:
6054 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7c0d66cf
JM
6055
6056 return None
6057
6058 srv = start_radius_server(mschapv2_handler)
6059
6060 try:
5eee514d 6061 hapd = start_ap(apdev[0])
9efd3447 6062 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
7c0d66cf 6063
fab49f61
JM
6064 tests = ["os_get_random;eap_mschapv2_change_password",
6065 "generate_nt_response;eap_mschapv2_change_password",
6066 "get_master_key;eap_mschapv2_change_password",
6067 "nt_password_hash;eap_mschapv2_change_password",
6068 "old_nt_password_hash_encrypted_with_new_nt_password_hash"]
5b0ec907
JM
6069 for func in tests:
6070 with fail_test(dev[0], 1, func):
6071 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6072 eap="MSCHAPV2", identity="user",
6073 password="password", wait_connect=False)
6074 ev = dev[0].wait_event(["CTRL-REQ-NEW_PASSWORD"], timeout=10)
6075 if ev is None:
6076 raise Exception("Timeout on new password request")
6077 id = ev.split(':')[0].split('-')[-1]
6078 dev[0].request("CTRL-RSP-NEW_PASSWORD-" + id + ":new-pw")
6079 time.sleep(0.1)
6080 wait_fail_trigger(dev[0], "GET_FAIL")
6081 dev[0].request("REMOVE_NETWORK all")
6082 dev[0].wait_disconnected(timeout=1)
7c0d66cf 6083
fab49f61
JM
6084 tests = ["encrypt_pw_block_with_password_hash;eap_mschapv2_change_password",
6085 "nt_password_hash;eap_mschapv2_change_password",
6086 "nt_password_hash;eap_mschapv2_success"]
5b0ec907
JM
6087 for func in tests:
6088 with fail_test(dev[0], 1, func):
6089 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6090 eap="MSCHAPV2", identity="user",
6091 password_hex="hash:8846f7eaee8fb117ad06bdd830b7586c",
6092 wait_connect=False)
6093 ev = dev[0].wait_event(["CTRL-REQ-NEW_PASSWORD"], timeout=10)
6094 if ev is None:
6095 raise Exception("Timeout on new password request")
6096 id = ev.split(':')[0].split('-')[-1]
6097 dev[0].request("CTRL-RSP-NEW_PASSWORD-" + id + ":new-pw")
6098 time.sleep(0.1)
6099 wait_fail_trigger(dev[0], "GET_FAIL")
6100 dev[0].request("REMOVE_NETWORK all")
6101 dev[0].wait_disconnected(timeout=1)
6102
fab49f61 6103 tests = ["eap_msg_alloc;eap_mschapv2_change_password"]
5b0ec907
JM
6104 for func in tests:
6105 with alloc_fail(dev[0], 1, func):
6106 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6107 eap="MSCHAPV2", identity="user",
6108 password="password", wait_connect=False)
6109 ev = dev[0].wait_event(["CTRL-REQ-NEW_PASSWORD"], timeout=10)
6110 if ev is None:
6111 raise Exception("Timeout on new password request")
6112 id = ev.split(':')[0].split('-')[-1]
6113 dev[0].request("CTRL-RSP-NEW_PASSWORD-" + id + ":new-pw")
6114 time.sleep(0.1)
6115 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
6116 dev[0].request("REMOVE_NETWORK all")
6117 dev[0].wait_disconnected(timeout=1)
7c0d66cf
JM
6118 finally:
6119 stop_radius_server(srv)
8a848fae
JM
6120
6121def test_eap_proto_pwd(dev, apdev):
6122 """EAP-pwd protocol tests"""
6123 check_eap_capa(dev[0], "PWD")
6124
6125 global eap_proto_pwd_test_done, eap_proto_pwd_test_wait
6126 eap_proto_pwd_test_done = False
6127 eap_proto_pwd_test_wait = False
6128
6129 def pwd_handler(ctx, req):
55845e19 6130 logger.info("pwd_handler - RX " + binascii.hexlify(req).decode())
8a848fae
JM
6131 if 'num' not in ctx:
6132 ctx['num'] = 0
6133 ctx['num'] = ctx['num'] + 1
6134 if 'id' not in ctx:
6135 ctx['id'] = 1
6136 ctx['id'] = (ctx['id'] + 1) % 256
6137 idx = 0
6138
6139 global eap_proto_pwd_test_wait
6140 eap_proto_pwd_test_wait = False
6141
6142 idx += 1
6143 if ctx['num'] == idx:
6144 logger.info("Test: Missing payload")
6145 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 4 + 1,
6146 EAP_TYPE_PWD)
6147
6148 idx += 1
6149 if ctx['num'] == idx:
6150 logger.info("Test: Missing Total-Length field")
6151 payload = struct.pack("B", 0x80)
6152 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6153 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6154
6155 idx += 1
6156 if ctx['num'] == idx:
6157 logger.info("Test: Too large Total-Length")
6158 payload = struct.pack(">BH", 0x80, 65535)
6159 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6160 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6161
6162 idx += 1
6163 if ctx['num'] == idx:
6164 eap_proto_pwd_test_wait = True
6165 logger.info("Test: First fragment")
6166 payload = struct.pack(">BH", 0xc0, 10)
6167 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6168 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6169 idx += 1
6170 if ctx['num'] == idx:
6171 logger.info("Test: Unexpected Total-Length value in the second fragment")
6172 payload = struct.pack(">BH", 0x80, 0)
6173 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6174 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6175
6176 idx += 1
6177 if ctx['num'] == idx:
6178 logger.info("Test: First and only fragment")
6179 payload = struct.pack(">BH", 0x80, 0)
6180 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6181 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6182
6183 idx += 1
6184 if ctx['num'] == idx:
6185 logger.info("Test: First and only fragment with extra data")
6186 payload = struct.pack(">BHB", 0x80, 0, 0)
6187 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6188 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6189
6190 idx += 1
6191 if ctx['num'] == idx:
6192 eap_proto_pwd_test_wait = True
6193 logger.info("Test: First fragment")
6194 payload = struct.pack(">BHB", 0xc0, 2, 1)
6195 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6196 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6197 idx += 1
6198 if ctx['num'] == idx:
6199 logger.info("Test: Extra data in the second fragment")
6200 payload = struct.pack(">BBB", 0x0, 2, 3)
6201 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6202 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6203
6204 idx += 1
6205 if ctx['num'] == idx:
6206 logger.info("Test: Too short id exchange")
6207 payload = struct.pack(">B", 0x01)
6208 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6209 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6210
6211 idx += 1
6212 if ctx['num'] == idx:
6213 logger.info("Test: Unsupported rand func in id exchange")
6214 payload = struct.pack(">BHBBLB", 0x01, 0, 0, 0, 0, 0)
6215 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6216 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6217
6218 idx += 1
6219 if ctx['num'] == idx:
6220 logger.info("Test: Unsupported prf in id exchange")
6221 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 0, 0, 0)
6222 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6223 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6224
6225 idx += 1
6226 if ctx['num'] == idx:
6227 logger.info("Test: Unsupported password pre-processing technique in id exchange")
6228 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 255)
6229 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6230 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6231
6232 idx += 1
6233 if ctx['num'] == idx:
6234 eap_proto_pwd_test_wait = True
6235 logger.info("Test: Valid id exchange")
6236 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0)
6237 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6238 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6239 idx += 1
6240 if ctx['num'] == idx:
6241 logger.info("Test: Unexpected id exchange")
6242 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0)
6243 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6244 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6245
6246 idx += 1
6247 if ctx['num'] == idx:
6248 logger.info("Test: Unexpected commit exchange")
6249 payload = struct.pack(">B", 0x02)
6250 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6251 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6252
6253 idx += 1
6254 if ctx['num'] == idx:
6255 eap_proto_pwd_test_wait = True
6256 logger.info("Test: Valid id exchange")
6257 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0)
6258 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6259 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6260 idx += 1
6261 if ctx['num'] == idx:
6262 logger.info("Test: Unexpected Commit payload length")
6263 payload = struct.pack(">B", 0x02)
6264 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6265 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6266
6267 idx += 1
6268 if ctx['num'] == idx:
6269 eap_proto_pwd_test_wait = True
6270 logger.info("Test: Valid id exchange")
6271 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0)
6272 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6273 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6274 idx += 1
6275 if ctx['num'] == idx:
6276 logger.info("Test: Commit payload with all zeros values --> Shared key at infinity")
55845e19 6277 payload = struct.pack(">B", 0x02) + 96*b'\0'
8a848fae
JM
6278 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6279 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6280
6281 idx += 1
6282 if ctx['num'] == idx:
6283 eap_proto_pwd_test_wait = True
6284 logger.info("Test: Valid id exchange")
6285 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0)
6286 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6287 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6288 idx += 1
6289 if ctx['num'] == idx:
6290 eap_proto_pwd_test_wait = True
6291 logger.info("Test: Commit payload with valid values")
6292 element = binascii.unhexlify("8dcab2862c5396839a6bac0c689ff03d962863108e7c275bbf1d6eedf634ee832a214db99f0d0a1a6317733eecdd97f0fc4cda19f57e1bb9bb9c8dcf8c60ba6f")
6293 scalar = binascii.unhexlify("450f31e058cf2ac2636a5d6e2b3c70b1fcc301957f0716e77f13aa69f9a2e5bd")
6294 payload = struct.pack(">B", 0x02) + element + scalar
6295 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6296 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6297 idx += 1
6298 if ctx['num'] == idx:
6299 logger.info("Test: Unexpected Confirm payload length 0")
6300 payload = struct.pack(">B", 0x03)
6301 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6302 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6303
6304 idx += 1
6305 if ctx['num'] == idx:
6306 eap_proto_pwd_test_wait = True
6307 logger.info("Test: Valid id exchange")
6308 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0)
6309 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6310 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6311 idx += 1
6312 if ctx['num'] == idx:
6313 eap_proto_pwd_test_wait = True
6314 logger.info("Test: Commit payload with valid values")
6315 element = binascii.unhexlify("8dcab2862c5396839a6bac0c689ff03d962863108e7c275bbf1d6eedf634ee832a214db99f0d0a1a6317733eecdd97f0fc4cda19f57e1bb9bb9c8dcf8c60ba6f")
6316 scalar = binascii.unhexlify("450f31e058cf2ac2636a5d6e2b3c70b1fcc301957f0716e77f13aa69f9a2e5bd")
6317 payload = struct.pack(">B", 0x02) + element + scalar
6318 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6319 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6320 idx += 1
6321 if ctx['num'] == idx:
6322 logger.info("Test: Confirm payload with incorrect value")
55845e19 6323 payload = struct.pack(">B", 0x03) + 32*b'\0'
8a848fae
JM
6324 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6325 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6326
6327 idx += 1
6328 if ctx['num'] == idx:
6329 logger.info("Test: Unexpected confirm exchange")
6330 payload = struct.pack(">B", 0x03)
6331 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6332 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6333
6334 logger.info("No more test responses available - test case completed")
6335 global eap_proto_pwd_test_done
6336 eap_proto_pwd_test_done = True
6337 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6338
6339 srv = start_radius_server(pwd_handler)
6340
6341 try:
5eee514d 6342 hapd = start_ap(apdev[0])
9efd3447 6343 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
8a848fae
JM
6344
6345 i = 0
6346 while not eap_proto_pwd_test_done:
6347 i += 1
6348 logger.info("Running connection iteration %d" % i)
6349 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6350 eap="PWD", identity="pwd user",
6351 password="secret password",
6352 wait_connect=False)
6353 ok = False
6354 for j in range(5):
6355 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STATUS",
6356 "CTRL-EVENT-EAP-PROPOSED-METHOD"],
6357 timeout=5)
6358 if ev is None:
6359 raise Exception("Timeout on EAP start")
6360 if "CTRL-EVENT-EAP-PROPOSED-METHOD" in ev:
6361 ok = True
6362 break
6363 if "CTRL-EVENT-EAP-STATUS" in ev and "status='completion' parameter='failure'" in ev:
6364 ok = True
6365 break
6366 if not ok:
6367 raise Exception("Expected EAP event not seen")
6368 if eap_proto_pwd_test_wait:
6369 for k in range(10):
6370 time.sleep(0.1)
6371 if not eap_proto_pwd_test_wait:
6372 break
6373 dev[0].request("REMOVE_NETWORK all")
6374 dev[0].wait_disconnected(timeout=1)
6375 dev[0].dump_monitor()
6376 finally:
6377 stop_radius_server(srv)
fe5aa8cb 6378
2e3849bc
JM
6379def test_eap_proto_pwd_invalid_scalar(dev, apdev):
6380 """EAP-pwd protocol tests - invalid server scalar"""
6381 check_eap_capa(dev[0], "PWD")
6382 run_eap_proto_pwd_invalid_scalar(dev, apdev, 32*b'\0')
6383 run_eap_proto_pwd_invalid_scalar(dev, apdev, 31*b'\0' + b'\x01')
6384 # Group Order
6385 val = binascii.unhexlify("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551")
6386 run_eap_proto_pwd_invalid_scalar(dev, apdev, val)
6387 # Group Order - 1
6388 val = binascii.unhexlify("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632550")
6389 run_eap_proto_pwd_invalid_scalar(dev, apdev, val, valid_scalar=True)
6390
6391def run_eap_proto_pwd_invalid_scalar(dev, apdev, scalar, valid_scalar=False):
6392 global eap_proto_pwd_invalid_scalar_fail
6393 eap_proto_pwd_invalid_scalar_fail = False
6394
6395 def pwd_handler(ctx, req):
6396 logger.info("pwd_handler - RX " + binascii.hexlify(req).decode())
6397 if 'num' not in ctx:
6398 ctx['num'] = 0
6399 ctx['num'] = ctx['num'] + 1
6400 if 'id' not in ctx:
6401 ctx['id'] = 1
6402 ctx['id'] = (ctx['id'] + 1) % 256
6403 idx = 0
6404
6405 idx += 1
6406 if ctx['num'] == idx:
6407 logger.info("Test: Valid id exchange")
6408 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0)
6409 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6410 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6411 idx += 1
6412 if ctx['num'] == idx:
6413 logger.info("Test: Commit payload with invalid scalar")
6414 payload = struct.pack(">B", 0x02) + binascii.unhexlify("67feb2b46d59e6dd3af3a429ec9c04a949337564615d3a2c19bdf6826eb6f5efa303aed86af3a072ed819d518d620adb2659f0e84c4f8b739629db8c93088cfc") + scalar
6415 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6416 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6417 idx += 1
6418 if ctx['num'] == idx:
6419 logger.info("Confirm message next - should not get here")
6420 global eap_proto_pwd_invalid_scalar_fail
6421 eap_proto_pwd_invalid_scalar_fail = True
6422 payload = struct.pack(">B", 0x03) + 32*b'\0'
6423 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6424 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6425
6426 logger.info("No more test responses available - test case completed")
6427 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6428
6429 srv = start_radius_server(pwd_handler)
6430
6431 try:
6432 hapd = start_ap(apdev[0])
6433 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
6434
6435 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6436 eap="PWD", identity="pwd user",
6437 password="secret password",
6438 wait_connect=False)
6439 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
6440 if ev is None:
6441 raise Exception("EAP failure not reported")
6442 dev[0].request("REMOVE_NETWORK all")
6443 dev[0].wait_disconnected(timeout=1)
6444 dev[0].dump_monitor()
6445 finally:
6446 stop_radius_server(srv)
6447
6448 if valid_scalar and not eap_proto_pwd_invalid_scalar_fail:
6449 raise Exception("Peer did not accept valid EAP-pwd-Commit scalar")
6450 if not valid_scalar and eap_proto_pwd_invalid_scalar_fail:
6451 raise Exception("Peer did not stop after invalid EAP-pwd-Commit scalar")
6452
6453def test_eap_proto_pwd_invalid_element(dev, apdev):
6454 """EAP-pwd protocol tests - invalid server element"""
6455 check_eap_capa(dev[0], "PWD")
6456 # Invalid x,y coordinates
6457 run_eap_proto_pwd_invalid_element(dev, apdev, 64*b'\x00')
6458 run_eap_proto_pwd_invalid_element(dev, apdev, 32*b'\x00' + 32*b'\x01')
6459 run_eap_proto_pwd_invalid_element(dev, apdev, 32*b'\x01' + 32*b'\x00')
6460 run_eap_proto_pwd_invalid_element(dev, apdev, 32*b'\xff' + 32*b'\x01')
6461 run_eap_proto_pwd_invalid_element(dev, apdev, 32*b'\x01' + 32*b'\xff')
6462 run_eap_proto_pwd_invalid_element(dev, apdev, 64*b'\xff')
6463 # Not on curve
6464 run_eap_proto_pwd_invalid_element(dev, apdev, 64*b'\x01')
6465
6466def run_eap_proto_pwd_invalid_element(dev, apdev, element):
6467 global eap_proto_pwd_invalid_element_fail
6468 eap_proto_pwd_invalid_element_fail = False
6469
6470 def pwd_handler(ctx, req):
6471 logger.info("pwd_handler - RX " + binascii.hexlify(req).decode())
6472 if 'num' not in ctx:
6473 ctx['num'] = 0
6474 ctx['num'] = ctx['num'] + 1
6475 if 'id' not in ctx:
6476 ctx['id'] = 1
6477 ctx['id'] = (ctx['id'] + 1) % 256
6478 idx = 0
6479
6480 idx += 1
6481 if ctx['num'] == idx:
6482 logger.info("Test: Valid id exchange")
6483 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0)
6484 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6485 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6486 idx += 1
6487 if ctx['num'] == idx:
6488 logger.info("Test: Commit payload with invalid element")
6489 payload = struct.pack(">B", 0x02) + element + 31*b'\0' + b'\x02'
6490 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6491 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6492 idx += 1
6493 if ctx['num'] == idx:
6494 logger.info("Confirm message next - should not get here")
6495 global eap_proto_pwd_invalid_element_fail
6496 eap_proto_pwd_invalid_element_fail = True
6497 payload = struct.pack(">B", 0x03) + 32*b'\0'
6498 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6499 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6500
6501 logger.info("No more test responses available - test case completed")
6502 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6503
6504 srv = start_radius_server(pwd_handler)
6505
6506 try:
6507 hapd = start_ap(apdev[0])
6508 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
6509
6510 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6511 eap="PWD", identity="pwd user",
6512 password="secret password",
6513 wait_connect=False)
6514 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
6515 if ev is None:
6516 raise Exception("EAP failure not reported")
6517 dev[0].request("REMOVE_NETWORK all")
6518 dev[0].wait_disconnected(timeout=1)
6519 dev[0].dump_monitor()
6520 finally:
6521 stop_radius_server(srv)
6522
6523 if eap_proto_pwd_invalid_element_fail:
6524 raise Exception("Peer did not stop after invalid EAP-pwd-Commit element")
6525
6526def rx_msg(src):
6527 ev = src.wait_event(["EAPOL-TX"], timeout=5)
6528 if ev is None:
6529 raise Exception("No EAPOL-TX")
6530 return ev.split(' ')[2]
6531
6532def tx_msg(src, dst, msg):
6533 dst.request("EAPOL_RX " + src.own_addr() + " " + msg)
6534
6535def proxy_msg(src, dst):
6536 msg = rx_msg(src)
6537 tx_msg(src, dst, msg)
6538 return msg
6539
6540def start_pwd_exchange(dev, ap):
6541 check_eap_capa(dev, "PWD")
6542 params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap")
6543 hapd = hostapd.add_ap(ap, params)
6544 hapd.request("SET ext_eapol_frame_io 1")
6545 dev.request("SET ext_eapol_frame_io 1")
6546 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP",
6547 eap="PWD", identity="pwd user", password="secret password",
6548 wait_connect=False, scan_freq="2412")
6549 proxy_msg(hapd, dev) # EAP-Identity/Request
6550 proxy_msg(dev, hapd) # EAP-Identity/Response
6551 proxy_msg(hapd, dev) # EAP-pwd-ID/Request
6552 proxy_msg(dev, hapd) # EAP-pwd-ID/Response
6553 return hapd
6554
6555def test_eap_proto_pwd_reflection_attack(dev, apdev):
6556 """EAP-pwd protocol tests - reflection attack on the server"""
6557 hapd = start_pwd_exchange(dev[0], apdev[0])
6558
6559 # EAP-pwd-Commit/Request
6560 req = proxy_msg(hapd, dev[0])
6561 if len(req) != 212:
6562 raise Exception("Unexpected EAP-pwd-Commit/Response length")
6563
6564 # EAP-pwd-Commit/Response
6565 resp = rx_msg(dev[0])
6566 # Reflect same Element/Scalar back to the server
6567 msg = resp[0:20] + req[20:]
6568 tx_msg(dev[0], hapd, msg)
6569
6570 # EAP-pwd-Commit/Response or EAP-Failure
6571 req = rx_msg(hapd)
6572 if req[8:10] != "04":
6573 # reflect EAP-pwd-Confirm/Request
6574 msg = req[0:8] + "02" + req[10:]
6575 tx_msg(dev[0], hapd, msg)
6576 req = rx_msg(hapd)
6577 if req[8:10] == "03":
6578 raise Exception("EAP-Success after reflected Element/Scalar")
6579 raise Exception("No EAP-Failure to reject invalid EAP-pwd-Commit/Response")
6580
6581def test_eap_proto_pwd_invalid_scalar_peer(dev, apdev):
6582 """EAP-pwd protocol tests - invalid peer scalar"""
6583 run_eap_proto_pwd_invalid_scalar_peer(dev, apdev, 32*"00")
6584 run_eap_proto_pwd_invalid_scalar_peer(dev, apdev, 31*"00" + "01")
6585 # Group Order
6586 run_eap_proto_pwd_invalid_scalar_peer(dev, apdev,
6587 "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551")
6588 # Group Order - 1
6589 run_eap_proto_pwd_invalid_scalar_peer(dev, apdev,
6590 "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632550",
6591 valid_scalar=True)
6592
6593def run_eap_proto_pwd_invalid_scalar_peer(dev, apdev, scalar,
6594 valid_scalar=False):
6595 hapd = start_pwd_exchange(dev[0], apdev[0])
6596 proxy_msg(hapd, dev[0]) # EAP-pwd-Commit/Request
6597
6598 # EAP-pwd-Commit/Response
6599 resp = rx_msg(dev[0])
6600 # Replace scalar with an invalid value
6601 msg = resp[0:20] + resp[20:148] + scalar
6602 tx_msg(dev[0], hapd, msg)
6603
6604 # EAP-pwd-Commit/Response or EAP-Failure
6605 req = rx_msg(hapd)
6606 if valid_scalar and req[8:10] == "04":
6607 raise Exception("Unexpected EAP-Failure with valid scalar")
6608 if not valid_scalar and req[8:10] != "04":
6609 raise Exception("No EAP-Failure to reject invalid scalar")
6610 dev[0].request("REMOVE_NETWORK all")
6611 dev[0].wait_disconnected(timeout=1)
6612 hapd.disable()
6613
6614def test_eap_proto_pwd_invalid_element_peer(dev, apdev):
6615 """EAP-pwd protocol tests - invalid peer element"""
6616 # Invalid x,y coordinates
6617 run_eap_proto_pwd_invalid_element_peer(dev, apdev, 64*'00')
6618 run_eap_proto_pwd_invalid_element_peer(dev, apdev, 32*'00' + 32*'01')
6619 run_eap_proto_pwd_invalid_element_peer(dev, apdev, 32*'01' + 32*'00')
6620 run_eap_proto_pwd_invalid_element_peer(dev, apdev, 32*'ff' + 32*'01')
6621 run_eap_proto_pwd_invalid_element_peer(dev, apdev, 32*'01' + 32*'ff')
6622 run_eap_proto_pwd_invalid_element_peer(dev, apdev, 64*'ff')
6623 # Not on curve
6624 run_eap_proto_pwd_invalid_element_peer(dev, apdev, 64*'01')
6625
6626def run_eap_proto_pwd_invalid_element_peer(dev, apdev, element):
6627 hapd = start_pwd_exchange(dev[0], apdev[0])
6628 proxy_msg(hapd, dev[0]) # EAP-pwd-Commit/Request
6629
6630 # EAP-pwd-Commit/Response
6631 resp = rx_msg(dev[0])
6632 # Replace element with an invalid value
6633 msg = resp[0:20] + element + resp[148:]
6634 tx_msg(dev[0], hapd, msg)
6635
6636 # EAP-pwd-Commit/Response or EAP-Failure
6637 req = rx_msg(hapd)
6638 if req[8:10] != "04":
6639 raise Exception("No EAP-Failure to reject invalid element")
6640 dev[0].request("REMOVE_NETWORK all")
6641 dev[0].wait_disconnected(timeout=1)
6642 hapd.disable()
6643
fe5aa8cb
JM
6644def test_eap_proto_pwd_errors(dev, apdev):
6645 """EAP-pwd local error cases"""
6646 check_eap_capa(dev[0], "PWD")
6647 params = hostapd.wpa2_eap_params(ssid="eap-test")
8b8a1864 6648 hapd = hostapd.add_ap(apdev[0], params)
9efd3447 6649 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
fe5aa8cb
JM
6650
6651 for i in range(1, 4):
6652 with alloc_fail(dev[0], i, "eap_pwd_init"):
6653 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6654 eap="PWD", identity="pwd user",
6655 password="secret password",
6656 wait_connect=False)
6657 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
6658 timeout=15)
6659 if ev is None:
6660 raise Exception("Timeout on EAP start")
6661 dev[0].request("REMOVE_NETWORK all")
6662 dev[0].wait_disconnected()
6663
6664 with alloc_fail(dev[0], 1, "eap_pwd_get_session_id"):
6665 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6666 eap="PWD", identity="pwd user",
72a4c5ce 6667 fragment_size="0",
fe5aa8cb
JM
6668 password="secret password")
6669 dev[0].request("REMOVE_NETWORK all")
6670 dev[0].wait_disconnected()
6671
fab49f61 6672 funcs = ["eap_pwd_getkey", "eap_pwd_get_emsk"]
72a4c5ce
JM
6673 for func in funcs:
6674 with alloc_fail(dev[0], 1, func):
6675 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
0a0c4dc1 6676 eap="PWD", identity="pwd user@domain",
72a4c5ce
JM
6677 password="secret password", erp="1",
6678 wait_connect=False)
6679 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
6680 dev[0].request("REMOVE_NETWORK all")
6681 dev[0].wait_disconnected()
6682
b30639b7 6683 for i in range(1, 5):
fe5aa8cb
JM
6684 with alloc_fail(dev[0], i, "eap_pwd_perform_id_exchange"):
6685 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6686 eap="PWD", identity="pwd user",
6687 password="secret password",
6688 wait_connect=False)
6689 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
6690 timeout=15)
6691 if ev is None:
6692 raise Exception("Timeout on EAP start")
6693 ok = False
6694 for j in range(10):
6695 state = dev[0].request('GET_ALLOC_FAIL')
6696 if state.startswith('0:'):
6697 ok = True
6698 break
6699 time.sleep(0.1)
6700 if not ok:
6701 raise Exception("No allocation failure seen")
6702 dev[0].request("REMOVE_NETWORK all")
6703 dev[0].wait_disconnected()
6704
6705 with alloc_fail(dev[0], 1, "wpabuf_alloc;eap_pwd_perform_id_exchange"):
6706 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6707 eap="PWD", identity="pwd user",
6708 password="secret password",
6709 wait_connect=False)
6710 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
6711 timeout=15)
6712 if ev is None:
6713 raise Exception("Timeout on EAP start")
6714 dev[0].request("REMOVE_NETWORK all")
6715 dev[0].wait_disconnected()
6716
b30639b7 6717 for i in range(1, 9):
fe5aa8cb
JM
6718 with alloc_fail(dev[0], i, "eap_pwd_perform_commit_exchange"):
6719 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6720 eap="PWD", identity="pwd user",
6721 password="secret password",
6722 wait_connect=False)
6723 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
6724 timeout=15)
6725 if ev is None:
6726 raise Exception("Timeout on EAP start")
6727 ok = False
6728 for j in range(10):
6729 state = dev[0].request('GET_ALLOC_FAIL')
6730 if state.startswith('0:'):
6731 ok = True
6732 break
6733 time.sleep(0.1)
6734 if not ok:
6735 raise Exception("No allocation failure seen")
6736 dev[0].request("REMOVE_NETWORK all")
6737 dev[0].wait_disconnected()
6738
6739 for i in range(1, 12):
6740 with alloc_fail(dev[0], i, "eap_pwd_perform_confirm_exchange"):
6741 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6742 eap="PWD", identity="pwd user",
6743 password="secret password",
6744 wait_connect=False)
6745 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
6746 timeout=15)
6747 if ev is None:
6748 raise Exception("Timeout on EAP start")
6749 ok = False
6750 for j in range(10):
6751 state = dev[0].request('GET_ALLOC_FAIL')
6752 if state.startswith('0:'):
6753 ok = True
6754 break
6755 time.sleep(0.1)
6756 if not ok:
6757 raise Exception("No allocation failure seen")
6758 dev[0].request("REMOVE_NETWORK all")
6759 dev[0].wait_disconnected()
6760
72a4c5ce 6761 for i in range(1, 5):
fe5aa8cb
JM
6762 with alloc_fail(dev[0], i, "eap_msg_alloc;=eap_pwd_process"):
6763 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6764 eap="PWD", identity="pwd user",
72a4c5ce 6765 password="secret password", fragment_size="50",
fe5aa8cb
JM
6766 wait_connect=False)
6767 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
6768 timeout=15)
6769 if ev is None:
6770 raise Exception("Timeout on EAP start")
72a4c5ce 6771 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
fe5aa8cb
JM
6772 dev[0].request("REMOVE_NETWORK all")
6773 dev[0].wait_disconnected()
6774
6775 # No password configured
6776 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6777 eap="PWD", identity="pwd user",
6778 wait_connect=False)
6779 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD vendor=0 method=52"],
6780 timeout=15)
6781 if ev is None:
6782 raise Exception("EAP-pwd not started")
6783 dev[0].request("REMOVE_NETWORK all")
6784 dev[0].wait_disconnected()
b6f17f2f 6785
4f183bec
JM
6786 funcs = [(1, "hash_nt_password_hash;eap_pwd_perform_commit_exchange"),
6787 (1, "crypto_hash_finish;eap_pwd_kdf"),
8ff2401d 6788 (1, "crypto_ec_point_from_bin;eap_pwd_get_element"),
4f183bec
JM
6789 (3, "crypto_bignum_init;compute_password_element"),
6790 (4, "crypto_bignum_init;compute_password_element"),
6791 (1, "crypto_bignum_init_set;compute_password_element"),
6792 (2, "crypto_bignum_init_set;compute_password_element"),
6793 (3, "crypto_bignum_init_set;compute_password_element"),
6794 (1, "crypto_bignum_to_bin;compute_password_element"),
6795 (1, "crypto_ec_point_compute_y_sqr;compute_password_element"),
6796 (1, "crypto_ec_point_solve_y_coord;compute_password_element"),
6797 (1, "crypto_bignum_sub;compute_password_element")]
6798 for count, func in funcs:
6799 with fail_test(dev[0], count, func):
52b1cb5d
JM
6800 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6801 eap="PWD", identity="pwd-hash",
6802 password_hex="hash:e3718ece8ab74792cbbfffd316d2d19a",
6803 wait_connect=False)
6804 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
6805 if ev is None:
6806 raise Exception("No EAP-Failure reported")
6807 dev[0].request("REMOVE_NETWORK all")
6808 dev[0].wait_disconnected()
72a4c5ce 6809
fab49f61
JM
6810 params = {"ssid": "eap-test2", "wpa": "2", "wpa_key_mgmt": "WPA-EAP",
6811 "rsn_pairwise": "CCMP", "ieee8021x": "1",
6812 "eap_server": "1", "eap_user_file": "auth_serv/eap_user.conf",
6813 "pwd_group": "19", "fragment_size": "40"}
9efd3447
JM
6814 hapd2 = hostapd.add_ap(apdev[1], params)
6815 dev[0].scan_for_bss(hapd2.own_addr(), freq=2412)
72a4c5ce
JM
6816
6817 with alloc_fail(dev[0], 1, "wpabuf_alloc;=eap_pwd_process"):
6818 dev[0].connect("eap-test2", key_mgmt="WPA-EAP", scan_freq="2412",
6819 eap="PWD", identity="pwd user",
6820 password="secret password",
6821 wait_connect=False)
6822 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
6823 dev[0].request("REMOVE_NETWORK all")
6824 dev[0].wait_disconnected()
6825
182a0b4d
JM
6826 for i in range(1, 5):
6827 with fail_test(dev[0], i,
6828 "=crypto_ec_point_to_bin;eap_pwd_perform_confirm_exchange"):
6829 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6830 eap="PWD", identity="pwd-hash",
6831 password_hex="hash:e3718ece8ab74792cbbfffd316d2d19a",
6832 wait_connect=False)
6833 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
6834 if ev is None:
6835 raise Exception("No EAP-Failure reported")
6836 dev[0].request("REMOVE_NETWORK all")
6837 dev[0].wait_disconnected()
6838 dev[0].dump_monitor()
6839
b6f17f2f
JM
6840def test_eap_proto_erp(dev, apdev):
6841 """ERP protocol tests"""
6842 check_erp_capa(dev[0])
6843
6844 global eap_proto_erp_test_done
6845 eap_proto_erp_test_done = False
6846
6847 def erp_handler(ctx, req):
55845e19 6848 logger.info("erp_handler - RX " + binascii.hexlify(req).decode())
b6f17f2f
JM
6849 if 'num' not in ctx:
6850 ctx['num'] = 0
6851 ctx['num'] += 1
6852 if 'id' not in ctx:
6853 ctx['id'] = 1
6854 ctx['id'] = (ctx['id'] + 1) % 256
6855 idx = 0
6856
6857 idx += 1
6858 if ctx['num'] == idx:
6859 logger.info("Test: Missing type")
6860 return struct.pack(">BBH", EAP_CODE_INITIATE, ctx['id'], 4)
6861
6862 idx += 1
6863 if ctx['num'] == idx:
6864 logger.info("Test: Unexpected type")
6865 return struct.pack(">BBHB", EAP_CODE_INITIATE, ctx['id'], 4 + 1,
6866 255)
6867
6868 idx += 1
6869 if ctx['num'] == idx:
6870 logger.info("Test: Missing Reserved field")
6871 return struct.pack(">BBHB", EAP_CODE_INITIATE, ctx['id'], 4 + 1,
6872 EAP_ERP_TYPE_REAUTH_START)
6873
6874 idx += 1
6875 if ctx['num'] == idx:
6876 logger.info("Test: Zero-length TVs/TLVs")
55845e19 6877 payload = b""
b6f17f2f
JM
6878 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'],
6879 4 + 1 + 1 + len(payload),
6880 EAP_ERP_TYPE_REAUTH_START, 0) + payload
6881
6882 idx += 1
6883 if ctx['num'] == idx:
6884 logger.info("Test: Too short TLV")
6885 payload = struct.pack("B", 191)
6886 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'],
6887 4 + 1 + 1 + len(payload),
6888 EAP_ERP_TYPE_REAUTH_START, 0) + payload
6889
6890 idx += 1
6891 if ctx['num'] == idx:
6892 logger.info("Test: Truncated TLV")
6893 payload = struct.pack("BB", 191, 1)
6894 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'],
6895 4 + 1 + 1 + len(payload),
6896 EAP_ERP_TYPE_REAUTH_START, 0) + payload
6897
6898 idx += 1
6899 if ctx['num'] == idx:
6900 logger.info("Test: Ignored unknown TLV and unknown TV/TLV terminating parsing")
6901 payload = struct.pack("BBB", 191, 0, 192)
6902 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'],
6903 4 + 1 + 1 + len(payload),
6904 EAP_ERP_TYPE_REAUTH_START, 0) + payload
6905
6906 idx += 1
6907 if ctx['num'] == idx:
6908 logger.info("Test: More than one keyName-NAI")
6909 payload = struct.pack("BBBB", EAP_ERP_TLV_KEYNAME_NAI, 0,
6910 EAP_ERP_TLV_KEYNAME_NAI, 0)
6911 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'],
6912 4 + 1 + 1 + len(payload),
6913 EAP_ERP_TYPE_REAUTH_START, 0) + payload
6914
6915 idx += 1
6916 if ctx['num'] == idx:
6917 logger.info("Test: Too short TLV keyName-NAI")
6918 payload = struct.pack("B", EAP_ERP_TLV_KEYNAME_NAI)
6919 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'],
6920 4 + 1 + 1 + len(payload),
6921 EAP_ERP_TYPE_REAUTH_START, 0) + payload
6922
6923 idx += 1
6924 if ctx['num'] == idx:
6925 logger.info("Test: Truncated TLV keyName-NAI")
6926 payload = struct.pack("BB", EAP_ERP_TLV_KEYNAME_NAI, 1)
6927 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'],
6928 4 + 1 + 1 + len(payload),
6929 EAP_ERP_TYPE_REAUTH_START, 0) + payload
6930
6931 idx += 1
6932 if ctx['num'] == idx:
6933 logger.info("Test: Valid rRK lifetime TV followed by too short rMSK lifetime TV")
6934 payload = struct.pack(">BLBH", EAP_ERP_TV_RRK_LIFETIME, 0,
6935 EAP_ERP_TV_RMSK_LIFETIME, 0)
6936 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'],
6937 4 + 1 + 1 + len(payload),
6938 EAP_ERP_TYPE_REAUTH_START, 0) + payload
6939
6940 idx += 1
6941 if ctx['num'] == idx:
6942 logger.info("Test: Missing type (Finish)")
6943 return struct.pack(">BBH", EAP_CODE_FINISH, ctx['id'], 4)
6944
6945 idx += 1
6946 if ctx['num'] == idx:
6947 logger.info("Test: Unexpected type (Finish)")
6948 return struct.pack(">BBHB", EAP_CODE_FINISH, ctx['id'], 4 + 1,
6949 255)
6950
6951 idx += 1
6952 if ctx['num'] == idx:
6953 logger.info("Test: Missing fields (Finish)")
6954 return struct.pack(">BBHB", EAP_CODE_FINISH, ctx['id'], 4 + 1,
6955 EAP_ERP_TYPE_REAUTH)
6956
6957 idx += 1
6958 if ctx['num'] == idx:
6959 logger.info("Test: Unexpected SEQ (Finish)")
6960 return struct.pack(">BBHBBHB", EAP_CODE_FINISH, ctx['id'],
6961 4 + 1 + 4,
6962 EAP_ERP_TYPE_REAUTH, 0, 0xffff, 0)
6963
6964 logger.info("No more test responses available - test case completed")
6965 global eap_proto_erp_test_done
6966 eap_proto_erp_test_done = True
6967 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6968
6969 srv = start_radius_server(erp_handler)
6970
6971 try:
5eee514d 6972 hapd = start_ap(apdev[0])
9efd3447 6973 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
b6f17f2f
JM
6974
6975 i = 0
6976 while not eap_proto_erp_test_done:
6977 i += 1
6978 logger.info("Running connection iteration %d" % i)
6979 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6980 eap="PAX", identity="pax.user@example.com",
6981 password_hex="0123456789abcdef0123456789abcdef",
6982 wait_connect=False)
6983 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
6984 if ev is None:
6985 raise Exception("Timeout on EAP start")
6986 time.sleep(0.1)
6987 dev[0].request("REMOVE_NETWORK all")
6988 dev[0].wait_disconnected(timeout=1)
6989 dev[0].dump_monitor()
6990 finally:
6991 stop_radius_server(srv)
5b7784a8
JM
6992
6993def test_eap_proto_fast_errors(dev, apdev):
6994 """EAP-FAST local error cases"""
6995 check_eap_capa(dev[0], "FAST")
6996 params = hostapd.wpa2_eap_params(ssid="eap-test")
8b8a1864 6997 hapd = hostapd.add_ap(apdev[0], params)
9efd3447 6998 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
5b7784a8
JM
6999
7000 for i in range(1, 5):
7001 with alloc_fail(dev[0], i, "eap_fast_init"):
7002 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7003 eap="FAST", anonymous_identity="FAST",
7004 identity="user", password="password",
7005 ca_cert="auth_serv/ca.pem", phase2="auth=GTC",
7006 phase1="fast_provisioning=2",
7007 pac_file="blob://fast_pac_auth",
7008 wait_connect=False)
7009 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
7010 timeout=5)
7011 if ev is None:
7012 raise Exception("Timeout on EAP start")
7013 dev[0].request("REMOVE_NETWORK all")
7014 dev[0].wait_disconnected()
7015
fab49f61
JM
7016 tests = [(1, "wpabuf_alloc;eap_fast_tlv_eap_payload"),
7017 (1, "eap_fast_derive_key;eap_fast_derive_key_auth"),
7018 (1, "eap_msg_alloc;eap_peer_tls_phase2_nak"),
7019 (1, "wpabuf_alloc;eap_fast_tlv_result"),
7020 (1, "wpabuf_alloc;eap_fast_tlv_pac_ack"),
7021 (1, "=eap_peer_tls_derive_session_id;eap_fast_process_crypto_binding"),
7022 (1, "eap_peer_tls_decrypt;eap_fast_decrypt"),
7023 (1, "eap_fast_getKey"),
7024 (1, "eap_fast_get_session_id"),
7025 (1, "eap_fast_get_emsk")]
5b7784a8
JM
7026 for count, func in tests:
7027 dev[0].request("SET blob fast_pac_auth_errors ")
7028 with alloc_fail(dev[0], count, func):
7029 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7030 eap="FAST", anonymous_identity="FAST",
0a0c4dc1 7031 identity="user@example.com", password="password",
5b7784a8
JM
7032 ca_cert="auth_serv/ca.pem", phase2="auth=GTC",
7033 phase1="fast_provisioning=2",
7034 pac_file="blob://fast_pac_auth_errors",
7035 erp="1",
7036 wait_connect=False)
7037 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
7038 timeout=15)
7039 if ev is None:
7040 raise Exception("Timeout on EAP start")
7041 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
7042 dev[0].request("REMOVE_NETWORK all")
7043 dev[0].wait_disconnected()
7044
fab49f61
JM
7045 tests = [(1, "eap_fast_derive_key;eap_fast_derive_key_provisioning"),
7046 (1, "eap_mschapv2_getKey;eap_fast_get_phase2_key"),
7047 (1, "=eap_fast_use_pac_opaque"),
7048 (1, "eap_fast_copy_buf"),
7049 (1, "=eap_fast_add_pac"),
7050 (1, "=eap_fast_init_pac_data"),
7051 (1, "=eap_fast_write_pac"),
7052 (2, "=eap_fast_write_pac")]
5b7784a8
JM
7053 for count, func in tests:
7054 dev[0].request("SET blob fast_pac_errors ")
7055 with alloc_fail(dev[0], count, func):
7056 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7057 eap="FAST", anonymous_identity="FAST",
7058 identity="user", password="password",
7059 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
7060 phase1="fast_provisioning=1",
7061 pac_file="blob://fast_pac_errors",
7062 erp="1",
7063 wait_connect=False)
7064 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
7065 timeout=15)
7066 if ev is None:
7067 raise Exception("Timeout on EAP start")
7068 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
7069 dev[0].request("REMOVE_NETWORK all")
7070 dev[0].wait_disconnected()
7071
fab49f61
JM
7072 tests = [(1, "eap_fast_get_cmk;eap_fast_process_crypto_binding"),
7073 (1, "eap_fast_derive_eap_msk;eap_fast_process_crypto_binding"),
7074 (1, "eap_fast_derive_eap_emsk;eap_fast_process_crypto_binding")]
5b7784a8
JM
7075 for count, func in tests:
7076 dev[0].request("SET blob fast_pac_auth_errors ")
7077 with fail_test(dev[0], count, func):
7078 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7079 eap="FAST", anonymous_identity="FAST",
7080 identity="user", password="password",
7081 ca_cert="auth_serv/ca.pem", phase2="auth=GTC",
7082 phase1="fast_provisioning=2",
7083 pac_file="blob://fast_pac_auth_errors",
7084 erp="1",
7085 wait_connect=False)
7086 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
7087 timeout=15)
7088 if ev is None:
7089 raise Exception("Timeout on EAP start")
7090 wait_fail_trigger(dev[0], "GET_FAIL")
7091 dev[0].request("REMOVE_NETWORK all")
7092 dev[0].wait_disconnected()
7093
7094 dev[0].request("SET blob fast_pac_errors ")
7095 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7096 eap="FAST", anonymous_identity="FAST",
7097 identity="user", password="password",
7098 ca_cert="auth_serv/ca.pem", phase2="auth=GTC",
7099 phase1="fast_provisioning=1",
7100 pac_file="blob://fast_pac_errors",
7101 wait_connect=False)
7102 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5)
7103 if ev is None:
7104 raise Exception("Timeout on EAP start")
7105 # EAP-FAST: Only EAP-MSCHAPv2 is allowed during unauthenticated
7106 # provisioning; reject phase2 type 6
7107 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
7108 if ev is None:
7109 raise Exception("Timeout on EAP failure")
7110 dev[0].request("REMOVE_NETWORK all")
7111 dev[0].wait_disconnected()
7112
7113 logger.info("Wrong password in Phase 2")
7114 dev[0].request("SET blob fast_pac_errors ")
7115 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7116 eap="FAST", anonymous_identity="FAST",
7117 identity="user", password="wrong password",
7118 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
7119 phase1="fast_provisioning=1",
7120 pac_file="blob://fast_pac_errors",
7121 wait_connect=False)
7122 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5)
7123 if ev is None:
7124 raise Exception("Timeout on EAP start")
7125 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
7126 if ev is None:
7127 raise Exception("Timeout on EAP failure")
7128 dev[0].request("REMOVE_NETWORK all")
7129 dev[0].wait_disconnected()
7130
fab49f61
JM
7131 tests = ["FOOBAR\n",
7132 "wpa_supplicant EAP-FAST PAC file - version 1\nFOOBAR\n",
7133 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\n",
7134 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nSTART\n",
7135 "wpa_supplicant EAP-FAST PAC file - version 1\nEND\n",
7136 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nPAC-Type=12345\nEND\n"
7137 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nPAC-Key=12\nEND\n",
7138 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nPAC-Key=1\nEND\n",
7139 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nPAC-Key=1q\nEND\n",
7140 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nPAC-Opaque=1\nEND\n",
7141 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nA-ID=1\nEND\n",
7142 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nI-ID=1\nEND\n",
7143 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nA-ID-Info=1\nEND\n"]
5b7784a8 7144 for pac in tests:
f94df3c0 7145 blob = binascii.hexlify(pac.encode()).decode()
5b7784a8
JM
7146 dev[0].request("SET blob fast_pac_errors " + blob)
7147 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7148 eap="FAST", anonymous_identity="FAST",
7149 identity="user", password="password",
7150 ca_cert="auth_serv/ca.pem", phase2="auth=GTC",
7151 phase1="fast_provisioning=2",
7152 pac_file="blob://fast_pac_errors",
7153 wait_connect=False)
7154 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
7155 timeout=5)
7156 if ev is None:
7157 raise Exception("Timeout on EAP start")
7158 dev[0].request("REMOVE_NETWORK all")
7159 dev[0].wait_disconnected()
7160
fab49f61
JM
7161 tests = ["wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nEND\n",
7162 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nEND\nSTART\nEND\nSTART\nEND\n"]
5b7784a8 7163 for pac in tests:
f94df3c0 7164 blob = binascii.hexlify(pac.encode()).decode()
5b7784a8
JM
7165 dev[0].request("SET blob fast_pac_errors " + blob)
7166 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7167 eap="FAST", anonymous_identity="FAST",
7168 identity="user", password="password",
7169 ca_cert="auth_serv/ca.pem", phase2="auth=GTC",
7170 phase1="fast_provisioning=2",
7171 pac_file="blob://fast_pac_errors")
7172 dev[0].request("REMOVE_NETWORK all")
7173 dev[0].wait_disconnected()
7174
7175 dev[0].request("SET blob fast_pac_errors ")
a551da6a
JM
7176
7177def test_eap_proto_peap_errors(dev, apdev):
7178 """EAP-PEAP local error cases"""
7179 check_eap_capa(dev[0], "PEAP")
7180 check_eap_capa(dev[0], "MSCHAPV2")
7181 params = hostapd.wpa2_eap_params(ssid="eap-test")
8b8a1864 7182 hapd = hostapd.add_ap(apdev[0], params)
9efd3447 7183 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
a551da6a
JM
7184
7185 for i in range(1, 5):
7186 with alloc_fail(dev[0], i, "eap_peap_init"):
7187 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7188 eap="PEAP", anonymous_identity="peap",
7189 identity="user", password="password",
7190 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
7191 wait_connect=False)
7192 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
7193 timeout=5)
7194 if ev is None:
7195 raise Exception("Timeout on EAP start")
7196 dev[0].request("REMOVE_NETWORK all")
7197 dev[0].wait_disconnected()
7198
fab49f61
JM
7199 tests = [(1, "eap_mschapv2_getKey;eap_peap_get_isk;eap_peap_derive_cmk"),
7200 (1, "eap_msg_alloc;eap_tlv_build_result"),
7201 (1, "eap_mschapv2_init;eap_peap_phase2_request"),
7202 (1, "eap_peer_tls_decrypt;eap_peap_decrypt"),
7203 (1, "wpabuf_alloc;=eap_peap_decrypt"),
7204 (1, "eap_peer_tls_encrypt;eap_peap_decrypt"),
7205 (1, "eap_peer_tls_process_helper;eap_peap_process"),
7206 (1, "eap_peer_tls_derive_key;eap_peap_process"),
7207 (1, "eap_peer_tls_derive_session_id;eap_peap_process"),
7208 (1, "eap_peap_getKey"),
7209 (1, "eap_peap_get_session_id")]
a551da6a
JM
7210 for count, func in tests:
7211 with alloc_fail(dev[0], count, func):
7212 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7213 eap="PEAP", anonymous_identity="peap",
7214 identity="user", password="password",
7215 phase1="peapver=0 crypto_binding=2",
7216 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
7217 erp="1", wait_connect=False)
7218 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
7219 timeout=15)
7220 if ev is None:
7221 raise Exception("Timeout on EAP start")
7222 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
7223 dev[0].request("REMOVE_NETWORK all")
7224 dev[0].wait_disconnected()
7225
fab49f61
JM
7226 tests = [(1, "peap_prfplus;eap_peap_derive_cmk"),
7227 (1, "eap_tlv_add_cryptobinding;eap_tlv_build_result"),
7228 (1, "peap_prfplus;eap_peap_getKey")]
a551da6a
JM
7229 for count, func in tests:
7230 with fail_test(dev[0], count, func):
7231 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7232 eap="PEAP", anonymous_identity="peap",
7233 identity="user", password="password",
7234 phase1="peapver=0 crypto_binding=2",
7235 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
7236 erp="1", wait_connect=False)
7237 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
7238 timeout=15)
7239 if ev is None:
7240 raise Exception("Timeout on EAP start")
7241 wait_fail_trigger(dev[0], "GET_FAIL")
7242 dev[0].request("REMOVE_NETWORK all")
7243 dev[0].wait_disconnected()
7244
7245 with alloc_fail(dev[0], 1,
7246 "eap_peer_tls_phase2_nak;eap_peap_phase2_request"):
7247 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7248 eap="PEAP", anonymous_identity="peap",
7249 identity="cert user", password="password",
7250 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
7251 wait_connect=False)
7252 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
7253 dev[0].request("REMOVE_NETWORK all")
7254 dev[0].wait_disconnected()
c44e4994
JM
7255
7256def test_eap_proto_ttls_errors(dev, apdev):
7257 """EAP-TTLS local error cases"""
7258 check_eap_capa(dev[0], "TTLS")
7259 check_eap_capa(dev[0], "MSCHAPV2")
7260 params = hostapd.wpa2_eap_params(ssid="eap-test")
8b8a1864 7261 hapd = hostapd.add_ap(apdev[0], params)
9efd3447 7262 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
c44e4994
JM
7263
7264 for i in range(1, 5):
7265 with alloc_fail(dev[0], i, "eap_ttls_init"):
7266 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7267 eap="TTLS", anonymous_identity="ttls",
7268 identity="user", password="password",
7269 ca_cert="auth_serv/ca.pem",
7270 phase2="autheap=MSCHAPV2",
7271 wait_connect=False)
7272 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
7273 timeout=5)
7274 if ev is None:
7275 raise Exception("Timeout on EAP start")
7276 dev[0].request("REMOVE_NETWORK all")
7277 dev[0].wait_disconnected()
7278
fab49f61
JM
7279 tests = [(1, "eap_peer_tls_derive_key;eap_ttls_v0_derive_key",
7280 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"),
7281 (1, "eap_peer_tls_derive_session_id;eap_ttls_v0_derive_key",
7282 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"),
7283 (1, "wpabuf_alloc;eap_ttls_phase2_request_mschapv2",
7284 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"),
7285 (1, "eap_peer_tls_derive_key;eap_ttls_phase2_request_mschapv2",
7286 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"),
7287 (1, "eap_peer_tls_encrypt;eap_ttls_encrypt_response;eap_ttls_implicit_identity_request",
7288 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"),
7289 (1, "eap_peer_tls_decrypt;eap_ttls_decrypt",
7290 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"),
7291 (1, "eap_ttls_getKey",
7292 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"),
7293 (1, "eap_ttls_get_session_id",
7294 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"),
7295 (1, "eap_ttls_get_emsk",
7296 "mschapv2 user@domain", "auth=MSCHAPV2"),
7297 (1, "wpabuf_alloc;eap_ttls_phase2_request_mschap",
7298 "mschap user", "auth=MSCHAP"),
7299 (1, "eap_peer_tls_derive_key;eap_ttls_phase2_request_mschap",
7300 "mschap user", "auth=MSCHAP"),
7301 (1, "wpabuf_alloc;eap_ttls_phase2_request_chap",
7302 "chap user", "auth=CHAP"),
7303 (1, "eap_peer_tls_derive_key;eap_ttls_phase2_request_chap",
7304 "chap user", "auth=CHAP"),
7305 (1, "wpabuf_alloc;eap_ttls_phase2_request_pap",
7306 "pap user", "auth=PAP"),
7307 (1, "wpabuf_alloc;eap_ttls_avp_encapsulate",
7308 "user", "autheap=MSCHAPV2"),
7309 (1, "eap_mschapv2_init;eap_ttls_phase2_request_eap_method",
7310 "user", "autheap=MSCHAPV2"),
7311 (1, "eap_sm_buildIdentity;eap_ttls_phase2_request_eap",
7312 "user", "autheap=MSCHAPV2"),
7313 (1, "eap_ttls_avp_encapsulate;eap_ttls_phase2_request_eap",
7314 "user", "autheap=MSCHAPV2"),
7315 (1, "eap_ttls_parse_attr_eap",
7316 "user", "autheap=MSCHAPV2"),
7317 (1, "eap_peer_tls_encrypt;eap_ttls_encrypt_response;eap_ttls_process_decrypted",
7318 "user", "autheap=MSCHAPV2"),
7319 (1, "eap_ttls_fake_identity_request",
7320 "user", "autheap=MSCHAPV2"),
7321 (1, "eap_msg_alloc;eap_tls_process_output",
7322 "user", "autheap=MSCHAPV2"),
7323 (1, "eap_msg_alloc;eap_peer_tls_build_ack",
7324 "user", "autheap=MSCHAPV2"),
7325 (1, "tls_connection_decrypt;eap_peer_tls_decrypt",
7326 "user", "autheap=MSCHAPV2"),
7327 (1, "eap_peer_tls_phase2_nak;eap_ttls_phase2_request_eap_method",
7328 "cert user", "autheap=MSCHAPV2")]
c44e4994
JM
7329 for count, func, identity, phase2 in tests:
7330 with alloc_fail(dev[0], count, func):
7331 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7332 eap="TTLS", anonymous_identity="ttls",
7333 identity=identity, password="password",
7334 ca_cert="auth_serv/ca.pem", phase2=phase2,
7335 erp="1", wait_connect=False)
7336 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
7337 timeout=15)
7338 if ev is None:
7339 raise Exception("Timeout on EAP start")
7340 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL",
7341 note="Allocation failure not triggered for: %d:%s" % (count, func))
7342 dev[0].request("REMOVE_NETWORK all")
7343 dev[0].wait_disconnected()
7344
fab49f61
JM
7345 tests = [(1, "os_get_random;eap_ttls_phase2_request_mschapv2"),
7346 (1, "mschapv2_derive_response;eap_ttls_phase2_request_mschapv2")]
c44e4994
JM
7347 for count, func in tests:
7348 with fail_test(dev[0], count, func):
7349 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7350 eap="TTLS", anonymous_identity="ttls",
7351 identity="DOMAIN\mschapv2 user", password="password",
7352 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
7353 erp="1", wait_connect=False)
7354 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
7355 timeout=15)
7356 if ev is None:
7357 raise Exception("Timeout on EAP start")
7358 wait_fail_trigger(dev[0], "GET_FAIL",
7359 note="Test failure not triggered for: %d:%s" % (count, func))
7360 dev[0].request("REMOVE_NETWORK all")
7361 dev[0].wait_disconnected()
2fd377de 7362
fab49f61 7363 tests = [(1, "nt_challenge_response;eap_ttls_phase2_request_mschap")]
c1361765
JM
7364 for count, func in tests:
7365 with fail_test(dev[0], count, func):
7366 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7367 eap="TTLS", anonymous_identity="ttls",
7368 identity="mschap user", password="password",
7369 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAP",
7370 erp="1", wait_connect=False)
7371 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
7372 timeout=15)
7373 if ev is None:
7374 raise Exception("Timeout on EAP start")
7375 wait_fail_trigger(dev[0], "GET_FAIL",
7376 note="Test failure not triggered for: %d:%s" % (count, func))
7377 dev[0].request("REMOVE_NETWORK all")
7378 dev[0].wait_disconnected()
7379
2fd377de
JM
7380def test_eap_proto_expanded(dev, apdev):
7381 """EAP protocol tests with expanded header"""
7382 global eap_proto_expanded_test_done
7383 eap_proto_expanded_test_done = False
7384
7385 def expanded_handler(ctx, req):
55845e19 7386 logger.info("expanded_handler - RX " + binascii.hexlify(req).decode())
2fd377de
JM
7387 if 'num' not in ctx:
7388 ctx['num'] = 0
7389 ctx['num'] += 1
7390 if 'id' not in ctx:
7391 ctx['id'] = 1
7392 ctx['id'] = (ctx['id'] + 1) % 256
7393 idx = 0
7394
7395 idx += 1
7396 if ctx['num'] == idx:
7397 logger.info("Test: MD5 challenge in expanded header")
7398 return struct.pack(">BBHB3BLBBB", EAP_CODE_REQUEST, ctx['id'],
7399 4 + 1 + 3 + 4 + 3,
7400 EAP_TYPE_EXPANDED, 0, 0, 0, EAP_TYPE_MD5,
7401 1, 0xaa, ord('n'))
7402 idx += 1
7403 if ctx['num'] == idx:
7404 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7405
7406 idx += 1
7407 if ctx['num'] == idx:
7408 logger.info("Test: Invalid expanded EAP length")
7409 return struct.pack(">BBHB3BH", EAP_CODE_REQUEST, ctx['id'],
7410 4 + 1 + 3 + 2,
7411 EAP_TYPE_EXPANDED, 0, 0, 0, EAP_TYPE_MD5)
7412 idx += 1
7413 if ctx['num'] == idx:
7414 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7415
7416 idx += 1
7417 if ctx['num'] == idx:
7418 logger.info("Test: Invalid expanded frame type")
7419 return struct.pack(">BBHB3BL", EAP_CODE_REQUEST, ctx['id'],
7420 4 + 1 + 3 + 4,
7421 EAP_TYPE_EXPANDED, 0, 0, 1, EAP_TYPE_MD5)
7422 idx += 1
7423 if ctx['num'] == idx:
7424 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7425
7426 idx += 1
7427 if ctx['num'] == idx:
7428 logger.info("Test: MSCHAPv2 Challenge")
7429 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
7430 4 + 1 + 4 + 1 + 16 + 6,
7431 EAP_TYPE_MSCHAPV2,
55845e19 7432 1, 0, 4 + 1 + 16 + 6, 16) + 16*b'A' + b'foobar'
2fd377de
JM
7433 idx += 1
7434 if ctx['num'] == idx:
7435 logger.info("Test: Invalid expanded frame type")
7436 return struct.pack(">BBHB3BL", EAP_CODE_REQUEST, ctx['id'],
7437 4 + 1 + 3 + 4,
7438 EAP_TYPE_EXPANDED, 0, 0, 1, EAP_TYPE_MSCHAPV2)
7439
7440 logger.info("No more test responses available - test case completed")
7441 global eap_proto_expanded_test_done
7442 eap_proto_expanded_test_done = True
7443 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7444
7445 srv = start_radius_server(expanded_handler)
7446
7447 try:
5eee514d 7448 hapd = start_ap(apdev[0])
9efd3447 7449 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
2fd377de
JM
7450
7451 i = 0
7452 while not eap_proto_expanded_test_done:
7453 i += 1
7454 logger.info("Running connection iteration %d" % i)
7455 if i == 4:
7456 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7457 eap="MSCHAPV2", identity="user",
7458 password="password",
7459 wait_connect=False)
7460 else:
7461 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7462 eap="MD5", identity="user", password="password",
7463 wait_connect=False)
7464 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
7465 if ev is None:
7466 raise Exception("Timeout on EAP start")
fab49f61 7467 if i in [1]:
2fd377de
JM
7468 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5)
7469 if ev is None:
7470 raise Exception("Timeout on EAP method start")
7471 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
7472 if ev is None:
7473 raise Exception("Timeout on EAP failure")
fab49f61 7474 elif i in [2, 3]:
2fd377de
JM
7475 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
7476 timeout=5)
7477 if ev is None:
7478 raise Exception("Timeout on EAP proposed method")
7479 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
7480 if ev is None:
7481 raise Exception("Timeout on EAP failure")
7482 else:
7483 time.sleep(0.1)
7484 dev[0].request("REMOVE_NETWORK all")
7485 dev[0].wait_disconnected(timeout=1)
7486 dev[0].dump_monitor()
7487 finally:
7488 stop_radius_server(srv)
0c8eacd1 7489
d4af4d27
JM
7490def test_eap_proto_tls(dev, apdev):
7491 """EAP-TLS protocol tests"""
7492 check_eap_capa(dev[0], "TLS")
7493 global eap_proto_tls_test_done, eap_proto_tls_test_wait
7494 eap_proto_tls_test_done = False
7495 eap_proto_tls_test_wait = False
7496
7497 def tls_handler(ctx, req):
55845e19 7498 logger.info("tls_handler - RX " + binascii.hexlify(req).decode())
d4af4d27
JM
7499 if 'num' not in ctx:
7500 ctx['num'] = 0
7501 ctx['num'] += 1
7502 if 'id' not in ctx:
7503 ctx['id'] = 1
7504 ctx['id'] = (ctx['id'] + 1) % 256
7505 idx = 0
7506
7507 global eap_proto_tls_test_wait
7508
7509 idx += 1
7510 if ctx['num'] == idx:
7511 logger.info("Test: Too much payload in TLS/Start: TLS Message Length (0 bytes) smaller than this fragment (1 bytes)")
7512 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'],
7513 4 + 1 + 1 + 4 + 1,
7514 EAP_TYPE_TLS, 0xa0, 0, 1)
7515
7516 idx += 1
7517 if ctx['num'] == idx:
7518 logger.info("Test: Fragmented TLS/Start")
7519 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'],
7520 4 + 1 + 1 + 4 + 1,
7521 EAP_TYPE_TLS, 0xe0, 2, 1)
7522 idx += 1
7523 if ctx['num'] == idx:
7524 logger.info("Test: Too long fragment of TLS/Start: Invalid reassembly state: tls_in_left=2 tls_in_len=0 in_len=0")
7525 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
7526 4 + 1 + 1 + 2,
7527 EAP_TYPE_TLS, 0x00, 2, 3)
7528 idx += 1
7529 if ctx['num'] == idx:
7530 logger.info("Test: EAP-Failure")
7531 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7532
7533 idx += 1
7534 if ctx['num'] == idx:
7535 logger.info("Test: TLS/Start")
7536 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7537 4 + 1 + 1,
7538 EAP_TYPE_TLS, 0x20)
7539 idx += 1
7540 if ctx['num'] == idx:
7541 logger.info("Test: Fragmented TLS message")
7542 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'],
7543 4 + 1 + 1 + 4 + 1,
7544 EAP_TYPE_TLS, 0xc0, 2, 1)
7545 idx += 1
7546 if ctx['num'] == idx:
7547 logger.info("Test: Invalid TLS message: no Flags octet included + workaround")
7548 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7549 4 + 1,
7550 EAP_TYPE_TLS)
7551 idx += 1
7552 if ctx['num'] == idx:
7553 logger.info("Test: Too long fragment of TLS message: more data than TLS message length indicated")
7554 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
7555 4 + 1 + 1 + 2,
7556 EAP_TYPE_TLS, 0x00, 2, 3)
7557 idx += 1
7558 if ctx['num'] == idx:
7559 logger.info("Test: EAP-Failure")
7560 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7561
7562 idx += 1
7563 if ctx['num'] == idx:
7564 logger.info("Test: Fragmented TLS/Start and truncated Message Length field")
7565 return struct.pack(">BBHBB3B", EAP_CODE_REQUEST, ctx['id'],
7566 4 + 1 + 1 + 3,
7567 EAP_TYPE_TLS, 0xe0, 1, 2, 3)
7568
7569 idx += 1
7570 if ctx['num'] == idx:
7571 logger.info("Test: TLS/Start")
7572 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7573 4 + 1 + 1,
7574 EAP_TYPE_TLS, 0x20)
7575 idx += 1
7576 if ctx['num'] == idx:
7577 logger.info("Test: Fragmented TLS message")
7578 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'],
7579 4 + 1 + 1 + 4 + 1,
7580 EAP_TYPE_TLS, 0xc0, 2, 1)
7581 idx += 1
7582 if ctx['num'] == idx:
7583 logger.info("Test: Invalid TLS message: no Flags octet included + workaround disabled")
7584 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7585 4 + 1,
7586 EAP_TYPE_TLS)
7587
7588 idx += 1
7589 if ctx['num'] == idx:
7590 logger.info("Test: TLS/Start")
7591 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7592 4 + 1 + 1,
7593 EAP_TYPE_TLS, 0x20)
7594 idx += 1
7595 if ctx['num'] == idx:
7596 logger.info("Test: Fragmented TLS message (long; first)")
55845e19 7597 payload = 1450*b'A'
d4af4d27
JM
7598 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'],
7599 4 + 1 + 1 + 4 + len(payload),
7600 EAP_TYPE_TLS, 0xc0, 65536) + payload
7601 # "Too long TLS fragment (size over 64 kB)" on the last one
7602 for i in range(44):
7603 idx += 1
7604 if ctx['num'] == idx:
7605 logger.info("Test: Fragmented TLS message (long; cont %d)" % i)
7606 eap_proto_tls_test_wait = True
55845e19 7607 payload = 1470*b'A'
d4af4d27
JM
7608 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7609 4 + 1 + 1 + len(payload),
7610 EAP_TYPE_TLS, 0x40) + payload
7611 eap_proto_tls_test_wait = False
7612 idx += 1
7613 if ctx['num'] == idx:
7614 logger.info("Test: EAP-Failure")
7615 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7616
7617 idx += 1
7618 if ctx['num'] == idx:
7619 logger.info("Test: TLS/Start")
7620 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7621 4 + 1 + 1,
7622 EAP_TYPE_TLS, 0x20)
7623 idx += 1
7624 if ctx['num'] == idx:
7625 logger.info("Test: Non-ACK to more-fragment message")
7626 return struct.pack(">BBHBBB", EAP_CODE_REQUEST, ctx['id'],
7627 4 + 1 + 1 + 1,
7628 EAP_TYPE_TLS, 0x00, 255)
7629 idx += 1
7630 if ctx['num'] == idx:
7631 logger.info("Test: EAP-Failure")
7632 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7633
7634 logger.info("No more test responses available - test case completed")
7635 global eap_proto_tls_test_done
7636 eap_proto_tls_test_done = True
7637 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7638
7639 srv = start_radius_server(tls_handler)
7640
7641 try:
5eee514d 7642 hapd = start_ap(apdev[0])
9efd3447 7643 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
d4af4d27
JM
7644
7645 i = 0
7646 while not eap_proto_tls_test_done:
7647 i += 1
7648 logger.info("Running connection iteration %d" % i)
7649 workaround = "0" if i == 6 else "1"
7650 fragment_size = "100" if i == 8 else "1400"
7651 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7652 eap="TLS", identity="tls user",
7653 ca_cert="auth_serv/ca.pem",
7654 client_cert="auth_serv/user.pem",
7655 private_key="auth_serv/user.key",
7656 eap_workaround=workaround,
7657 fragment_size=fragment_size,
7658 wait_connect=False)
7659 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
7660 if ev is None:
7661 raise Exception("Timeout on EAP start")
7662 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD",
7663 "CTRL-EVENT-EAP-STATUS"], timeout=5)
7664 if ev is None:
7665 raise Exception("Timeout on EAP method start")
7666 time.sleep(0.1)
7667 start = os.times()[4]
7668 while eap_proto_tls_test_wait:
7669 now = os.times()[4]
7670 if now - start > 10:
7671 break
7672 time.sleep(0.1)
7673 dev[0].request("REMOVE_NETWORK all")
7674 dev[0].wait_disconnected(timeout=1)
7675 dev[0].dump_monitor()
7676 finally:
7677 stop_radius_server(srv)
7678
0c8eacd1
JM
7679def test_eap_proto_tnc(dev, apdev):
7680 """EAP-TNC protocol tests"""
7681 check_eap_capa(dev[0], "TNC")
7682 global eap_proto_tnc_test_done
7683 eap_proto_tnc_test_done = False
7684
7685 def tnc_handler(ctx, req):
55845e19 7686 logger.info("tnc_handler - RX " + binascii.hexlify(req).decode())
0c8eacd1
JM
7687 if 'num' not in ctx:
7688 ctx['num'] = 0
7689 ctx['num'] += 1
7690 if 'id' not in ctx:
7691 ctx['id'] = 1
7692 ctx['id'] = (ctx['id'] + 1) % 256
7693 idx = 0
7694
7695 idx += 1
7696 if ctx['num'] == idx:
7697 logger.info("Test: TNC start with unsupported version")
7698 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7699 4 + 1 + 1,
7700 EAP_TYPE_TNC, 0x20)
7701
7702 idx += 1
7703 if ctx['num'] == idx:
7704 logger.info("Test: TNC without Flags field")
7705 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7706 4 + 1,
7707 EAP_TYPE_TNC)
7708
7709 idx += 1
7710 if ctx['num'] == idx:
7711 logger.info("Test: Message underflow due to missing Message Length")
7712 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7713 4 + 1 + 1,
7714 EAP_TYPE_TNC, 0xa1)
7715
7716 idx += 1
7717 if ctx['num'] == idx:
7718 logger.info("Test: Invalid Message Length")
7719 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'],
7720 4 + 1 + 1 + 4 + 1,
7721 EAP_TYPE_TNC, 0xa1, 0, 0)
7722
7723 idx += 1
7724 if ctx['num'] == idx:
7725 logger.info("Test: Invalid Message Length")
7726 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'],
7727 4 + 1 + 1 + 4,
7728 EAP_TYPE_TNC, 0xe1, 75001)
7729
7730 idx += 1
7731 if ctx['num'] == idx:
7732 logger.info("Test: Start with Message Length")
7733 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'],
7734 4 + 1 + 1 + 4,
7735 EAP_TYPE_TNC, 0xa1, 1)
7736 idx += 1
7737 if ctx['num'] == idx:
7738 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7739
7740 idx += 1
7741 if ctx['num'] == idx:
7742 logger.info("Test: Server used start flag again")
7743 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7744 4 + 1 + 1,
7745 EAP_TYPE_TNC, 0x21)
7746 idx += 1
7747 if ctx['num'] == idx:
7748 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7749 4 + 1 + 1,
7750 EAP_TYPE_TNC, 0x21)
7751
7752 idx += 1
7753 if ctx['num'] == idx:
7754 logger.info("Test: Fragmentation and unexpected payload in ack")
7755 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7756 4 + 1 + 1,
7757 EAP_TYPE_TNC, 0x21)
7758 idx += 1
7759 if ctx['num'] == idx:
7760 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7761 4 + 1 + 1,
7762 EAP_TYPE_TNC, 0x01)
7763 idx += 1
7764 if ctx['num'] == idx:
7765 return struct.pack(">BBHBBB", EAP_CODE_REQUEST, ctx['id'],
7766 4 + 1 + 1 + 1,
7767 EAP_TYPE_TNC, 0x01, 0)
7768
7769 idx += 1
7770 if ctx['num'] == idx:
7771 logger.info("Test: Server fragmenting and fragment overflow")
7772 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'],
7773 4 + 1 + 1 + 4 + 1,
7774 EAP_TYPE_TNC, 0xe1, 2, 1)
7775 idx += 1
7776 if ctx['num'] == idx:
7777 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
7778 4 + 1 + 1 + 2,
7779 EAP_TYPE_TNC, 0x01, 2, 3)
7780
7781 idx += 1
7782 if ctx['num'] == idx:
7783 logger.info("Test: Server fragmenting and no message length in a fragment")
7784 return struct.pack(">BBHBBB", EAP_CODE_REQUEST, ctx['id'],
7785 4 + 1 + 1 + 1,
7786 EAP_TYPE_TNC, 0x61, 2)
7787
7788 idx += 1
7789 if ctx['num'] == idx:
7790 logger.info("Test: TNC start followed by invalid TNCCS-Batch")
7791 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7792 4 + 1 + 1,
7793 EAP_TYPE_TNC, 0x21)
7794 idx += 1
7795 if ctx['num'] == idx:
55845e19
JM
7796 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
7797 resp = b"FOO"
0c8eacd1
JM
7798 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7799 4 + 1 + 1 + len(resp),
7800 EAP_TYPE_TNC, 0x01) + resp
7801
7802 idx += 1
7803 if ctx['num'] == idx:
7804 logger.info("Test: TNC start followed by invalid TNCCS-Batch (2)")
7805 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7806 4 + 1 + 1,
7807 EAP_TYPE_TNC, 0x21)
7808 idx += 1
7809 if ctx['num'] == idx:
55845e19
JM
7810 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
7811 resp = b"</TNCCS-Batch><TNCCS-Batch>"
0c8eacd1
JM
7812 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7813 4 + 1 + 1 + len(resp),
7814 EAP_TYPE_TNC, 0x01) + resp
7815
7816 idx += 1
7817 if ctx['num'] == idx:
7818 logger.info("Test: TNCCS-Batch missing BatchId attribute")
7819 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7820 4 + 1 + 1,
7821 EAP_TYPE_TNC, 0x21)
7822 idx += 1
7823 if ctx['num'] == idx:
55845e19
JM
7824 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
7825 resp = b"<TNCCS-Batch foo=3></TNCCS-Batch>"
0c8eacd1
JM
7826 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7827 4 + 1 + 1 + len(resp),
7828 EAP_TYPE_TNC, 0x01) + resp
7829
7830 idx += 1
7831 if ctx['num'] == idx:
7832 logger.info("Test: Unexpected IF-TNCCS BatchId")
7833 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7834 4 + 1 + 1,
7835 EAP_TYPE_TNC, 0x21)
7836 idx += 1
7837 if ctx['num'] == idx:
55845e19
JM
7838 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
7839 resp = b"<TNCCS-Batch BatchId=123456789></TNCCS-Batch>"
0c8eacd1
JM
7840 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7841 4 + 1 + 1 + len(resp),
7842 EAP_TYPE_TNC, 0x01) + resp
7843
7844 idx += 1
7845 if ctx['num'] == idx:
7846 logger.info("Test: Missing IMC-IMV-Message and TNCC-TNCS-Message end tags")
7847 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7848 4 + 1 + 1,
7849 EAP_TYPE_TNC, 0x21)
7850 idx += 1
7851 if ctx['num'] == idx:
55845e19
JM
7852 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
7853 resp = b"<TNCCS-Batch BatchId=2><IMC-IMV-Message><TNCC-TNCS-Message></TNCCS-Batch>"
0c8eacd1
JM
7854 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7855 4 + 1 + 1 + len(resp),
7856 EAP_TYPE_TNC, 0x01) + resp
7857 idx += 1
7858 if ctx['num'] == idx:
7859 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7860
7861 idx += 1
7862 if ctx['num'] == idx:
7863 logger.info("Test: Missing IMC-IMV-Message and TNCC-TNCS-Message Type")
7864 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7865 4 + 1 + 1,
7866 EAP_TYPE_TNC, 0x21)
7867 idx += 1
7868 if ctx['num'] == idx:
55845e19
JM
7869 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
7870 resp = b"<TNCCS-Batch BatchId=2><IMC-IMV-Message></IMC-IMV-Message><TNCC-TNCS-Message></TNCC-TNCS-Message></TNCCS-Batch>"
0c8eacd1
JM
7871 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7872 4 + 1 + 1 + len(resp),
7873 EAP_TYPE_TNC, 0x01) + resp
7874 idx += 1
7875 if ctx['num'] == idx:
7876 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7877
7878 idx += 1
7879 if ctx['num'] == idx:
7880 logger.info("Test: Missing TNCC-TNCS-Message XML end tag")
7881 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7882 4 + 1 + 1,
7883 EAP_TYPE_TNC, 0x21)
7884 idx += 1
7885 if ctx['num'] == idx:
55845e19
JM
7886 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
7887 resp = b"<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type><XML></TNCC-TNCS-Message></TNCCS-Batch>"
0c8eacd1
JM
7888 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7889 4 + 1 + 1 + len(resp),
7890 EAP_TYPE_TNC, 0x01) + resp
7891 idx += 1
7892 if ctx['num'] == idx:
7893 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7894
7895 idx += 1
7896 if ctx['num'] == idx:
7897 logger.info("Test: Missing TNCC-TNCS-Message Base64 start tag")
7898 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7899 4 + 1 + 1,
7900 EAP_TYPE_TNC, 0x21)
7901 idx += 1
7902 if ctx['num'] == idx:
55845e19
JM
7903 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
7904 resp = b"<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type></TNCC-TNCS-Message></TNCCS-Batch>"
0c8eacd1
JM
7905 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7906 4 + 1 + 1 + len(resp),
7907 EAP_TYPE_TNC, 0x01) + resp
7908 idx += 1
7909 if ctx['num'] == idx:
7910 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7911
7912 idx += 1
7913 if ctx['num'] == idx:
7914 logger.info("Test: Missing TNCC-TNCS-Message Base64 end tag")
7915 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7916 4 + 1 + 1,
7917 EAP_TYPE_TNC, 0x21)
7918 idx += 1
7919 if ctx['num'] == idx:
55845e19
JM
7920 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
7921 resp = b"<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type><Base64>abc</TNCC-TNCS-Message></TNCCS-Batch>"
0c8eacd1
JM
7922 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7923 4 + 1 + 1 + len(resp),
7924 EAP_TYPE_TNC, 0x01) + resp
7925 idx += 1
7926 if ctx['num'] == idx:
7927 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7928
7929 idx += 1
7930 if ctx['num'] == idx:
7931 logger.info("Test: TNCC-TNCS-Message Base64 message")
7932 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7933 4 + 1 + 1,
7934 EAP_TYPE_TNC, 0x21)
7935 idx += 1
7936 if ctx['num'] == idx:
55845e19
JM
7937 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
7938 resp = b"<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type><Base64>aGVsbG8=</Base64></TNCC-TNCS-Message></TNCCS-Batch>"
0c8eacd1
JM
7939 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7940 4 + 1 + 1 + len(resp),
7941 EAP_TYPE_TNC, 0x01) + resp
7942 idx += 1
7943 if ctx['num'] == idx:
7944 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7945
7946 idx += 1
7947 if ctx['num'] == idx:
7948 logger.info("Test: Invalid TNCC-TNCS-Message XML message")
7949 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7950 4 + 1 + 1,
7951 EAP_TYPE_TNC, 0x21)
7952 idx += 1
7953 if ctx['num'] == idx:
55845e19
JM
7954 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
7955 resp = b"<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type><XML>hello</XML></TNCC-TNCS-Message></TNCCS-Batch>"
0c8eacd1
JM
7956 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7957 4 + 1 + 1 + len(resp),
7958 EAP_TYPE_TNC, 0x01) + resp
7959 idx += 1
7960 if ctx['num'] == idx:
7961 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7962
7963 idx += 1
7964 if ctx['num'] == idx:
7965 logger.info("Test: Missing TNCCS-Recommendation type")
7966 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7967 4 + 1 + 1,
7968 EAP_TYPE_TNC, 0x21)
7969 idx += 1
7970 if ctx['num'] == idx:
55845e19
JM
7971 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
7972 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>'
0c8eacd1
JM
7973 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7974 4 + 1 + 1 + len(resp),
7975 EAP_TYPE_TNC, 0x01) + resp
7976 idx += 1
7977 if ctx['num'] == idx:
7978 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7979
7980 idx += 1
7981 if ctx['num'] == idx:
7982 logger.info("Test: TNCCS-Recommendation type=none")
7983 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7984 4 + 1 + 1,
7985 EAP_TYPE_TNC, 0x21)
7986 idx += 1
7987 if ctx['num'] == idx:
55845e19
JM
7988 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
7989 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>'
0c8eacd1
JM
7990 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7991 4 + 1 + 1 + len(resp),
7992 EAP_TYPE_TNC, 0x01) + resp
7993 idx += 1
7994 if ctx['num'] == idx:
7995 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7996
7997 idx += 1
7998 if ctx['num'] == idx:
7999 logger.info("Test: TNCCS-Recommendation type=isolate")
8000 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
8001 4 + 1 + 1,
8002 EAP_TYPE_TNC, 0x21)
8003 idx += 1
8004 if ctx['num'] == idx:
55845e19
JM
8005 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
8006 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>'
0c8eacd1
JM
8007 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
8008 4 + 1 + 1 + len(resp),
8009 EAP_TYPE_TNC, 0x01) + resp
8010 idx += 1
8011 if ctx['num'] == idx:
8012 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
8013
8014 logger.info("No more test responses available - test case completed")
8015 global eap_proto_tnc_test_done
8016 eap_proto_tnc_test_done = True
8017 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
8018
8019 srv = start_radius_server(tnc_handler)
8020
8021 try:
5eee514d 8022 hapd = start_ap(apdev[0])
9efd3447 8023 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
0c8eacd1
JM
8024
8025 i = 0
8026 while not eap_proto_tnc_test_done:
8027 i += 1
8028 logger.info("Running connection iteration %d" % i)
8029 frag = 1400
8030 if i == 8:
8031 frag = 150
8032 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8033 eap="TNC", identity="tnc", fragment_size=str(frag),
8034 wait_connect=False)
8035 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
8036 if ev is None:
8037 raise Exception("Timeout on EAP start")
8038 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD",
8039 "CTRL-EVENT-EAP-STATUS"], timeout=5)
8040 if ev is None:
8041 raise Exception("Timeout on EAP method start")
8042 time.sleep(0.1)
8043 dev[0].request("REMOVE_NETWORK all")
8044 dev[0].wait_disconnected(timeout=1)
8045 dev[0].dump_monitor()
8046 finally:
8047 stop_radius_server(srv)
dc441c0f
JM
8048
8049def test_eap_canned_success_after_identity(dev, apdev):
8050 """EAP protocol tests for canned EAP-Success after identity"""
8051 check_eap_capa(dev[0], "MD5")
8052 def eap_canned_success_handler(ctx, req):
55845e19 8053 logger.info("eap_canned_success_handler - RX " + binascii.hexlify(req).decode())
dc441c0f
JM
8054 if 'num' not in ctx:
8055 ctx['num'] = 0
8056 ctx['num'] = ctx['num'] + 1
8057 if 'id' not in ctx:
8058 ctx['id'] = 1
8059 ctx['id'] = (ctx['id'] + 1) % 256
8060 idx = 0
8061
8062 idx += 1
8063 if ctx['num'] == idx:
8064 logger.info("Test: EAP-Success")
8065 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4)
8066
8067 idx += 1
8068 if ctx['num'] == idx:
8069 logger.info("Test: EAP-Success")
8070 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4)
8071
8072 return None
8073
8074 srv = start_radius_server(eap_canned_success_handler)
8075
8076 try:
5eee514d 8077 hapd = start_ap(apdev[0])
9efd3447 8078 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
dc441c0f
JM
8079
8080 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8081 phase1="allow_canned_success=1",
8082 eap="MD5", identity="user", password="password",
8083 wait_connect=False)
8084 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15)
8085 if ev is None:
8086 raise Exception("Timeout on EAP success")
8087 dev[0].request("REMOVE_NETWORK all")
8088 dev[0].wait_disconnected()
8089
8090 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8091 eap="MD5", identity="user", password="password",
8092 wait_connect=False)
8093 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
8094 if ev is None:
8095 raise Exception("Timeout on EAP start")
8096 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=0.1)
8097 if ev is not None:
8098 raise Exception("Unexpected EAP success")
8099 dev[0].request("REMOVE_NETWORK all")
8100 dev[0].wait_disconnected()
8101 finally:
8102 stop_radius_server(srv)
6a95f5e2
JM
8103
8104def test_eap_proto_wsc(dev, apdev):
8105 """EAP-WSC protocol tests"""
8106 global eap_proto_wsc_test_done, eap_proto_wsc_wait_failure
8107 eap_proto_wsc_test_done = False
8108
8109 def wsc_handler(ctx, req):
55845e19 8110 logger.info("wsc_handler - RX " + binascii.hexlify(req).decode())
6a95f5e2
JM
8111 if 'num' not in ctx:
8112 ctx['num'] = 0
8113 ctx['num'] += 1
8114 if 'id' not in ctx:
8115 ctx['id'] = 1
8116 ctx['id'] = (ctx['id'] + 1) % 256
8117 idx = 0
8118
8119 global eap_proto_wsc_wait_failure
8120 eap_proto_wsc_wait_failure = False
8121
8122 idx += 1
8123 if ctx['num'] == idx:
8124 logger.info("Test: Missing Flags field")
8125 return struct.pack(">BBHB3BLB", EAP_CODE_REQUEST, ctx['id'],
8126 4 + 1 + 3 + 4 + 1,
8127 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
8128 1)
8129
8130 idx += 1
8131 if ctx['num'] == idx:
8132 logger.info("Test: Message underflow (missing Message Length field)")
8133 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'],
8134 4 + 1 + 3 + 4 + 2,
8135 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
8136 1, 0x02)
8137
8138 idx += 1
8139 if ctx['num'] == idx:
8140 logger.info("Test: Invalid Message Length (> 50000)")
8141 return struct.pack(">BBHB3BLBBH", EAP_CODE_REQUEST, ctx['id'],
8142 4 + 1 + 3 + 4 + 4,
8143 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
8144 1, 0x02, 65535)
8145
8146 idx += 1
8147 if ctx['num'] == idx:
8148 logger.info("Test: Invalid Message Length (< current payload)")
8149 return struct.pack(">BBHB3BLBBHB", EAP_CODE_REQUEST, ctx['id'],
8150 4 + 1 + 3 + 4 + 5,
8151 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
8152 1, 0x02, 0, 0xff)
8153
8154 idx += 1
8155 if ctx['num'] == idx:
8156 logger.info("Test: Unexpected Op-Code 5 in WAIT_START state")
8157 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'],
8158 4 + 1 + 3 + 4 + 2,
8159 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
8160 5, 0x00)
8161
8162 idx += 1
8163 if ctx['num'] == idx:
8164 logger.info("Test: Valid WSC Start to start the sequence")
8165 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'],
8166 4 + 1 + 3 + 4 + 2,
8167 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
8168 1, 0x00)
8169 idx += 1
8170 if ctx['num'] == idx:
8171 logger.info("Test: No Message Length field in a fragmented packet")
8172 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'],
8173 4 + 1 + 3 + 4 + 2,
8174 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
8175 4, 0x01)
8176
8177 idx += 1
8178 if ctx['num'] == idx:
8179 logger.info("Test: Valid WSC Start to start the sequence")
8180 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'],
8181 4 + 1 + 3 + 4 + 2,
8182 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
8183 1, 0x00)
8184 idx += 1
8185 if ctx['num'] == idx:
8186 logger.info("Test: Valid first fragmented packet")
8187 return struct.pack(">BBHB3BLBBHB", EAP_CODE_REQUEST, ctx['id'],
8188 4 + 1 + 3 + 4 + 5,
8189 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
8190 4, 0x03, 10, 1)
8191 idx += 1
8192 if ctx['num'] == idx:
8193 logger.info("Test: Unexpected Op-Code 5 in fragment (expected 4)")
8194 return struct.pack(">BBHB3BLBBB", EAP_CODE_REQUEST, ctx['id'],
8195 4 + 1 + 3 + 4 + 3,
8196 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
8197 5, 0x01, 2)
8198
8199 idx += 1
8200 if ctx['num'] == idx:
8201 logger.info("Test: Valid WSC Start to start the sequence")
8202 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'],
8203 4 + 1 + 3 + 4 + 2,
8204 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
8205 1, 0x00)
8206 idx += 1
8207 if ctx['num'] == idx:
8208 logger.info("Test: Valid first fragmented packet")
8209 return struct.pack(">BBHB3BLBBHB", EAP_CODE_REQUEST, ctx['id'],
8210 4 + 1 + 3 + 4 + 5,
8211 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
8212 4, 0x03, 2, 1)
8213 idx += 1
8214 if ctx['num'] == idx:
8215 logger.info("Test: Fragment overflow")
8216 return struct.pack(">BBHB3BLBBBB", EAP_CODE_REQUEST, ctx['id'],
8217 4 + 1 + 3 + 4 + 4,
8218 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
8219 4, 0x01, 2, 3)
8220
8221 idx += 1
8222 if ctx['num'] == idx:
8223 logger.info("Test: Valid WSC Start to start the sequence")
8224 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'],
8225 4 + 1 + 3 + 4 + 2,
8226 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
8227 1, 0x00)
8228 idx += 1
8229 if ctx['num'] == idx:
8230 logger.info("Test: Unexpected Op-Code 5 in WAIT_FRAG_ACK state")
8231 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'],
8232 4 + 1 + 3 + 4 + 2,
8233 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
8234 5, 0x00)
8235
8236 idx += 1
8237 if ctx['num'] == idx:
8238 logger.info("Test: Valid WSC Start")
8239 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'],
8240 4 + 1 + 3 + 4 + 2,
8241 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
8242 1, 0x00)
8243 idx += 1
8244 if ctx['num'] == idx:
8245 logger.info("No more test responses available - test case completed")
8246 global eap_proto_wsc_test_done
8247 eap_proto_wsc_test_done = True
8248 eap_proto_wsc_wait_failure = True
8249 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
8250
8251 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
8252
8253 srv = start_radius_server(wsc_handler)
8254
8255 try:
5eee514d 8256 hapd = start_ap(apdev[0])
9efd3447 8257 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
6a95f5e2
JM
8258
8259 i = 0
8260 while not eap_proto_wsc_test_done:
8261 i += 1
8262 logger.info("Running connection iteration %d" % i)
8263 fragment_size = 1398 if i != 9 else 50
8264 dev[0].connect("eap-test", key_mgmt="WPA-EAP", eap="WSC",
8265 fragment_size=str(fragment_size),
8266 identity="WFA-SimpleConfig-Enrollee-1-0",
8267 phase1="pin=12345670",
8268 scan_freq="2412", wait_connect=False)
8269 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5)
8270 if ev is None:
8271 raise Exception("Timeout on EAP method start")
8272 if eap_proto_wsc_wait_failure:
8273 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
8274 if ev is None:
8275 raise Exception("Timeout on EAP failure")
8276 else:
8277 time.sleep(0.1)
8278 dev[0].request("REMOVE_NETWORK all")
8279 dev[0].wait_disconnected(timeout=1)
8280 dev[0].dump_monitor()
8281 finally:
8282 stop_radius_server(srv)
3d85fd5a
JM
8283
8284def test_eap_canned_success_before_method(dev, apdev):
8285 """EAP protocol tests for canned EAP-Success before any method"""
8286 params = int_eap_server_params()
8b8a1864 8287 hapd = hostapd.add_ap(apdev[0], params)
9efd3447 8288 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
3d85fd5a
JM
8289 bssid = apdev[0]['bssid']
8290 hapd.request("SET ext_eapol_frame_io 1")
8291
8292 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412",
8293 phase1="allow_canned_success=1",
8294 eap="MD5", identity="user", password="password",
8295 wait_connect=False)
8296
8297 ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
8298 if ev is None:
8299 raise Exception("Timeout on EAPOL-TX from hostapd")
8300
8301 res = dev[0].request("EAPOL_RX " + bssid + " 0200000403020004")
8302 if "OK" not in res:
8303 raise Exception("EAPOL_RX to wpa_supplicant failed")
8304
8305 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=5)
8306 if ev is None:
8307 raise Exception("Timeout on EAP success")
8308 dev[0].request("REMOVE_NETWORK all")
8309 dev[0].wait_disconnected()
8310
8311def test_eap_canned_failure_before_method(dev, apdev):
8312 """EAP protocol tests for canned EAP-Failure before any method"""
8313 params = int_eap_server_params()
8b8a1864 8314 hapd = hostapd.add_ap(apdev[0], params)
9efd3447 8315 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
3d85fd5a
JM
8316 bssid = apdev[0]['bssid']
8317 hapd.request("SET ext_eapol_frame_io 1")
8318 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412",
8319 phase1="allow_canned_success=1",
8320 eap="MD5", identity="user", password="password",
8321 wait_connect=False)
8322
8323 ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
8324 if ev is None:
8325 raise Exception("Timeout on EAPOL-TX from hostapd")
8326
8327 res = dev[0].request("EAPOL_RX " + bssid + " 0200000404020004")
8328 if "OK" not in res:
8329 raise Exception("EAPOL_RX to wpa_supplicant failed")
8330
8331 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
8332 if ev is None:
8333 raise Exception("Timeout on EAP failure")
8334 dev[0].request("REMOVE_NETWORK all")
8335 dev[0].wait_disconnected()
b81e50cd
JM
8336
8337def test_eap_nak_oom(dev, apdev):
8338 """EAP-Nak OOM"""
8339 check_eap_capa(dev[0], "MD5")
8340 params = hostapd.wpa2_eap_params(ssid="eap-test")
8b8a1864 8341 hapd = hostapd.add_ap(apdev[0], params)
9efd3447 8342 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
b81e50cd
JM
8343 with alloc_fail(dev[0], 1, "eap_msg_alloc;eap_sm_buildNak"):
8344 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8345 eap="MD5", identity="sake user", password="password",
8346 wait_connect=False)
8347 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
8348 dev[0].request("REMOVE_NETWORK all")
8349 dev[0].wait_disconnected()
8350
8351def test_eap_nak_expanded(dev, apdev):
8352 """EAP-Nak with expanded method"""
8353 check_eap_capa(dev[0], "MD5")
8354 check_eap_capa(dev[0], "VENDOR-TEST")
8355 params = hostapd.wpa2_eap_params(ssid="eap-test")
8b8a1864 8356 hapd = hostapd.add_ap(apdev[0], params)
9efd3447 8357 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
b81e50cd
JM
8358 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8359 eap="VENDOR-TEST WSC",
8360 identity="sake user", password="password",
8361 wait_connect=False)
8362 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=10)
8363 if ev is None or "NAK" not in ev:
8364 raise Exception("No NAK event seen")
8365
8366 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
8367 if ev is None:
8368 raise Exception("No EAP-Failure seen")
8369
8370 dev[0].request("REMOVE_NETWORK all")
8371 dev[0].wait_disconnected()
bccd22f3
JM
8372
8373EAP_TLV_RESULT_TLV = 3
8374EAP_TLV_NAK_TLV = 4
8375EAP_TLV_ERROR_CODE_TLV = 5
8376EAP_TLV_CONNECTION_BINDING_TLV = 6
8377EAP_TLV_VENDOR_SPECIFIC_TLV = 7
8378EAP_TLV_URI_TLV = 8
8379EAP_TLV_EAP_PAYLOAD_TLV = 9
8380EAP_TLV_INTERMEDIATE_RESULT_TLV = 10
8381EAP_TLV_PAC_TLV = 11
8382EAP_TLV_CRYPTO_BINDING_TLV = 12
8383EAP_TLV_CALLING_STATION_ID_TLV = 13
8384EAP_TLV_CALLED_STATION_ID_TLV = 14
8385EAP_TLV_NAS_PORT_TYPE_TLV = 15
8386EAP_TLV_SERVER_IDENTIFIER_TLV = 16
8387EAP_TLV_IDENTITY_TYPE_TLV = 17
8388EAP_TLV_SERVER_TRUSTED_ROOT_TLV = 18
8389EAP_TLV_REQUEST_ACTION_TLV = 19
8390EAP_TLV_PKCS7_TLV = 20
8391
8392EAP_TLV_RESULT_SUCCESS = 1
8393EAP_TLV_RESULT_FAILURE = 2
8394
8395EAP_TLV_TYPE_MANDATORY = 0x8000
8396EAP_TLV_TYPE_MASK = 0x3fff
8397
8398PAC_TYPE_PAC_KEY = 1
8399PAC_TYPE_PAC_OPAQUE = 2
8400PAC_TYPE_CRED_LIFETIME = 3
8401PAC_TYPE_A_ID = 4
8402PAC_TYPE_I_ID = 5
8403PAC_TYPE_A_ID_INFO = 7
8404PAC_TYPE_PAC_ACKNOWLEDGEMENT = 8
8405PAC_TYPE_PAC_INFO = 9
8406PAC_TYPE_PAC_TYPE = 10
8407
8408def eap_fast_start(ctx):
8409 logger.info("Send EAP-FAST/Start")
8410 return struct.pack(">BBHBBHH", EAP_CODE_REQUEST, ctx['id'],
8411 4 + 1 + 1 + 4 + 16,
55845e19 8412 EAP_TYPE_FAST, 0x21, 4, 16) + 16*b'A'
bccd22f3
JM
8413
8414def test_eap_fast_proto(dev, apdev):
8415 """EAP-FAST Phase protocol testing"""
8416 check_eap_capa(dev[0], "FAST")
8417 global eap_fast_proto_ctx
8418 eap_fast_proto_ctx = None
8419
8420 def eap_handler(ctx, req):
55845e19 8421 logger.info("eap_handler - RX " + binascii.hexlify(req).decode())
bccd22f3
JM
8422 if 'num' not in ctx:
8423 ctx['num'] = 0
8424 ctx['num'] = ctx['num'] + 1
8425 if 'id' not in ctx:
8426 ctx['id'] = 1
8427 ctx['id'] = (ctx['id'] + 1) % 256
8428 idx = 0
8429
8430 global eap_fast_proto_ctx
8431 eap_fast_proto_ctx = ctx
8432 ctx['test_done'] = False
8433
8434 idx += 1
8435 if ctx['num'] == idx:
8436 return eap_fast_start(ctx)
8437 idx += 1
8438 if ctx['num'] == idx:
8439 logger.info("EAP-FAST: TLS processing failed")
55845e19 8440 data = b'ABCDEFGHIK'
bccd22f3
JM
8441 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
8442 4 + 1 + 1 + len(data),
8443 EAP_TYPE_FAST, 0x01) + data
8444 idx += 1
8445 if ctx['num'] == idx:
8446 ctx['test_done'] = True
8447 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
8448
8449 logger.info("Past last test case")
8450 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
8451
8452 srv = start_radius_server(eap_handler)
8453 try:
5eee514d 8454 hapd = start_ap(apdev[0])
9efd3447 8455 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
bccd22f3
JM
8456 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8457 eap="FAST", anonymous_identity="FAST",
8458 identity="user", password="password",
8459 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
8460 phase1="fast_provisioning=1",
8461 pac_file="blob://fast_pac_proto",
8462 wait_connect=False)
8463 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5)
8464 if ev is None:
8465 raise Exception("Could not start EAP-FAST")
8466 ok = False
8467 for i in range(100):
8468 if eap_fast_proto_ctx:
8469 if eap_fast_proto_ctx['test_done']:
8470 ok = True
8471 break
8472 time.sleep(0.05)
8473 dev[0].request("REMOVE_NETWORK all")
8474 dev[0].wait_disconnected()
8475 finally:
8476 stop_radius_server(srv)
8477
8478def run_eap_fast_phase2(dev, test_payload, test_failure=True):
8479 global eap_fast_proto_ctx
8480 eap_fast_proto_ctx = None
8481
8482 def ssl_info_callback(conn, where, ret):
8483 logger.debug("SSL: info where=%d ret=%d" % (where, ret))
8484
33a6da69
JM
8485 def log_conn_state(conn):
8486 try:
8487 state = conn.state_string()
8488 except AttributeError:
8489 state = conn.get_state_string()
8490 if state:
43e3114c 8491 logger.info("State: " + str(state))
33a6da69 8492
bccd22f3
JM
8493 def process_clienthello(ctx, payload):
8494 logger.info("Process ClientHello")
8495 ctx['sslctx'] = OpenSSL.SSL.Context(OpenSSL.SSL.TLSv1_METHOD)
8496 ctx['sslctx'].set_info_callback(ssl_info_callback)
8497 ctx['sslctx'].load_tmp_dh("auth_serv/dh.conf")
8498 ctx['sslctx'].set_cipher_list("ADH-AES128-SHA")
8499 ctx['conn'] = OpenSSL.SSL.Connection(ctx['sslctx'], None)
8500 ctx['conn'].set_accept_state()
33a6da69 8501 log_conn_state(ctx['conn'])
bccd22f3
JM
8502 ctx['conn'].bio_write(payload)
8503 try:
8504 ctx['conn'].do_handshake()
8505 except OpenSSL.SSL.WantReadError:
8506 pass
33a6da69 8507 log_conn_state(ctx['conn'])
bccd22f3 8508 data = ctx['conn'].bio_read(4096)
33a6da69 8509 log_conn_state(ctx['conn'])
bccd22f3
JM
8510 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
8511 4 + 1 + 1 + len(data),
8512 EAP_TYPE_FAST, 0x01) + data
8513
8514 def process_clientkeyexchange(ctx, payload, appl_data):
8515 logger.info("Process ClientKeyExchange")
33a6da69 8516 log_conn_state(ctx['conn'])
bccd22f3
JM
8517 ctx['conn'].bio_write(payload)
8518 try:
8519 ctx['conn'].do_handshake()
8520 except OpenSSL.SSL.WantReadError:
8521 pass
8522 ctx['conn'].send(appl_data)
33a6da69 8523 log_conn_state(ctx['conn'])
bccd22f3 8524 data = ctx['conn'].bio_read(4096)
33a6da69 8525 log_conn_state(ctx['conn'])
bccd22f3
JM
8526 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
8527 4 + 1 + 1 + len(data),
8528 EAP_TYPE_FAST, 0x01) + data
8529
8530 def eap_handler(ctx, req):
55845e19 8531 logger.info("eap_handler - RX " + binascii.hexlify(req).decode())
bccd22f3
JM
8532 if 'num' not in ctx:
8533 ctx['num'] = 0
8534 ctx['num'] = ctx['num'] + 1
8535 if 'id' not in ctx:
8536 ctx['id'] = 1
8537 ctx['id'] = (ctx['id'] + 1) % 256
8538 idx = 0
8539
8540 global eap_fast_proto_ctx
8541 eap_fast_proto_ctx = ctx
8542 ctx['test_done'] = False
8543 logger.debug("ctx['num']=%d" % ctx['num'])
8544
8545 idx += 1
8546 if ctx['num'] == idx:
8547 return eap_fast_start(ctx)
8548 idx += 1
8549 if ctx['num'] == idx:
8550 return process_clienthello(ctx, req[6:])
8551 idx += 1
8552 if ctx['num'] == idx:
8553 if not test_failure:
8554 ctx['test_done'] = True
8555 return process_clientkeyexchange(ctx, req[6:], test_payload)
8556 idx += 1
8557 if ctx['num'] == idx:
8558 ctx['test_done'] = True
8559 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
8560
8561 logger.info("Past last test case")
8562 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
8563
8564 srv = start_radius_server(eap_handler)
8565 try:
8566 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8567 eap="FAST", anonymous_identity="FAST",
8568 identity="user", password="password",
8569 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
8570 phase1="fast_provisioning=1",
8571 pac_file="blob://fast_pac_proto",
8572 wait_connect=False)
8573 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5)
8574 if ev is None:
8575 raise Exception("Could not start EAP-FAST")
8576 dev[0].dump_monitor()
8577 ok = False
8578 for i in range(100):
8579 if eap_fast_proto_ctx:
8580 if eap_fast_proto_ctx['test_done']:
8581 ok = True
8582 break
8583 time.sleep(0.05)
8584 time.sleep(0.1)
8585 dev[0].request("REMOVE_NETWORK all")
8586 dev[0].wait_disconnected()
8587 if not ok:
8588 raise Exception("EAP-FAST TLS exchange did not complete")
8589 for i in range(3):
8590 dev[i].dump_monitor()
8591 finally:
8592 stop_radius_server(srv)
8593
8594def test_eap_fast_proto_phase2(dev, apdev):
8595 """EAP-FAST Phase 2 protocol testing"""
8596 if not openssl_imported:
8597 raise HwsimSkip("OpenSSL python method not available")
8598 check_eap_capa(dev[0], "FAST")
5eee514d 8599 hapd = start_ap(apdev[0])
9efd3447 8600 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
bccd22f3 8601
fab49f61
JM
8602 tests = [("Too short Phase 2 TLV frame (len=3)",
8603 "ABC",
8604 False),
8605 ("EAP-FAST: TLV overflow",
8606 struct.pack(">HHB", 0, 2, 0xff),
8607 False),
8608 ("EAP-FAST: Unknown TLV (optional and mandatory)",
8609 struct.pack(">HHB", 0, 1, 0xff) +
8610 struct.pack(">HHB", EAP_TLV_TYPE_MANDATORY, 1, 0xff),
8611 True),
8612 ("EAP-FAST: More than one EAP-Payload TLV in the message",
8613 struct.pack(">HHBHHB",
8614 EAP_TLV_EAP_PAYLOAD_TLV, 1, 0xff,
8615 EAP_TLV_EAP_PAYLOAD_TLV, 1, 0xff),
8616 True),
8617 ("EAP-FAST: Unknown Result 255 and More than one Result TLV in the message",
8618 struct.pack(">HHHHHH",
8619 EAP_TLV_RESULT_TLV, 2, 0xff,
8620 EAP_TLV_RESULT_TLV, 2, 0xff),
8621 True),
8622 ("EAP-FAST: Too short Result TLV",
8623 struct.pack(">HHB", EAP_TLV_RESULT_TLV, 1, 0xff),
8624 True),
8625 ("EAP-FAST: Unknown Intermediate Result 255 and More than one Intermediate-Result TLV in the message",
8626 struct.pack(">HHHHHH",
8627 EAP_TLV_INTERMEDIATE_RESULT_TLV, 2, 0xff,
8628 EAP_TLV_INTERMEDIATE_RESULT_TLV, 2, 0xff),
8629 True),
8630 ("EAP-FAST: Too short Intermediate-Result TLV",
8631 struct.pack(">HHB", EAP_TLV_INTERMEDIATE_RESULT_TLV, 1, 0xff),
8632 True),
8633 ("EAP-FAST: More than one Crypto-Binding TLV in the message",
8634 struct.pack(">HH", EAP_TLV_CRYPTO_BINDING_TLV, 60) + 60*b'A' +
8635 struct.pack(">HH", EAP_TLV_CRYPTO_BINDING_TLV, 60) + 60*b'A',
8636 True),
8637 ("EAP-FAST: Too short Crypto-Binding TLV",
8638 struct.pack(">HHB", EAP_TLV_CRYPTO_BINDING_TLV, 1, 0xff),
8639 True),
8640 ("EAP-FAST: More than one Request-Action TLV in the message",
8641 struct.pack(">HHBBHHBB",
8642 EAP_TLV_REQUEST_ACTION_TLV, 2, 0xff, 0xff,
8643 EAP_TLV_REQUEST_ACTION_TLV, 2, 0xff, 0xff),
8644 True),
8645 ("EAP-FAST: Too short Request-Action TLV",
8646 struct.pack(">HHB", EAP_TLV_REQUEST_ACTION_TLV, 1, 0xff),
8647 True),
8648 ("EAP-FAST: More than one PAC TLV in the message",
8649 struct.pack(">HHBHHB",
8650 EAP_TLV_PAC_TLV, 1, 0xff,
8651 EAP_TLV_PAC_TLV, 1, 0xff),
8652 True),
8653 ("EAP-FAST: Too short EAP Payload TLV (Len=3)",
8654 struct.pack(">HH3B",
8655 EAP_TLV_EAP_PAYLOAD_TLV, 3, 0, 0, 0),
8656 False),
8657 ("EAP-FAST: Too short Phase 2 request (Len=0)",
8658 struct.pack(">HHBBH",
8659 EAP_TLV_EAP_PAYLOAD_TLV, 4,
8660 EAP_CODE_REQUEST, 0, 0),
8661 False),
8662 ("EAP-FAST: EAP packet overflow in EAP Payload TLV",
8663 struct.pack(">HHBBH",
8664 EAP_TLV_EAP_PAYLOAD_TLV, 4,
8665 EAP_CODE_REQUEST, 0, 4 + 1),
8666 False),
8667 ("EAP-FAST: Unexpected code=0 in Phase 2 EAP header",
8668 struct.pack(">HHBBH",
8669 EAP_TLV_EAP_PAYLOAD_TLV, 4,
8670 0, 0, 0),
8671 False),
8672 ("EAP-FAST: PAC TLV without Result TLV acknowledging success",
8673 struct.pack(">HHB", EAP_TLV_PAC_TLV, 1, 0xff),
8674 True),
8675 ("EAP-FAST: PAC TLV does not include all the required fields",
8676 struct.pack(">HHH", EAP_TLV_RESULT_TLV, 2,
8677 EAP_TLV_RESULT_SUCCESS) +
8678 struct.pack(">HHB", EAP_TLV_PAC_TLV, 1, 0xff),
8679 True),
8680 ("EAP-FAST: Invalid PAC-Key length 0, Ignored unknown PAC type 0, and PAC TLV overrun (type=0 len=2 left=1)",
8681 struct.pack(">HHH", EAP_TLV_RESULT_TLV, 2,
8682 EAP_TLV_RESULT_SUCCESS) +
8683 struct.pack(">HHHHHHHHB", EAP_TLV_PAC_TLV, 4 + 4 + 5,
8684 PAC_TYPE_PAC_KEY, 0, 0, 0, 0, 2, 0),
8685 True),
8686 ("EAP-FAST: PAC-Info does not include all the required fields",
8687 struct.pack(">HHH", EAP_TLV_RESULT_TLV, 2,
8688 EAP_TLV_RESULT_SUCCESS) +
8689 struct.pack(">HHHHHHHH", EAP_TLV_PAC_TLV, 4 + 4 + 4 + 32,
8690 PAC_TYPE_PAC_OPAQUE, 0,
8691 PAC_TYPE_PAC_INFO, 0,
8692 PAC_TYPE_PAC_KEY, 32) + 32*b'A',
8693 True),
8694 ("EAP-FAST: Invalid CRED_LIFETIME length, Ignored unknown PAC-Info type 0, and Invalid PAC-Type length 1",
8695 struct.pack(">HHH", EAP_TLV_RESULT_TLV, 2,
8696 EAP_TLV_RESULT_SUCCESS) +
8697 struct.pack(">HHHHHHHHHHHHBHH", EAP_TLV_PAC_TLV, 4 + 4 + 13 + 4 + 32,
8698 PAC_TYPE_PAC_OPAQUE, 0,
8699 PAC_TYPE_PAC_INFO, 13, PAC_TYPE_CRED_LIFETIME, 0,
8700 0, 0, PAC_TYPE_PAC_TYPE, 1, 0,
8701 PAC_TYPE_PAC_KEY, 32) + 32*b'A',
8702 True),
8703 ("EAP-FAST: Unsupported PAC-Type 0",
8704 struct.pack(">HHH", EAP_TLV_RESULT_TLV, 2,
8705 EAP_TLV_RESULT_SUCCESS) +
8706 struct.pack(">HHHHHHHHHHH", EAP_TLV_PAC_TLV, 4 + 4 + 6 + 4 + 32,
8707 PAC_TYPE_PAC_OPAQUE, 0,
8708 PAC_TYPE_PAC_INFO, 6, PAC_TYPE_PAC_TYPE, 2, 0,
8709 PAC_TYPE_PAC_KEY, 32) + 32*b'A',
8710 True),
8711 ("EAP-FAST: PAC-Info overrun (type=0 len=2 left=1)",
8712 struct.pack(">HHH", EAP_TLV_RESULT_TLV, 2,
8713 EAP_TLV_RESULT_SUCCESS) +
8714 struct.pack(">HHHHHHHHBHH", EAP_TLV_PAC_TLV, 4 + 4 + 5 + 4 + 32,
8715 PAC_TYPE_PAC_OPAQUE, 0,
8716 PAC_TYPE_PAC_INFO, 5, 0, 2, 1,
8717 PAC_TYPE_PAC_KEY, 32) + 32*b'A',
8718 True),
8719 ("EAP-FAST: Valid PAC",
8720 struct.pack(">HHH", EAP_TLV_RESULT_TLV, 2,
8721 EAP_TLV_RESULT_SUCCESS) +
8722 struct.pack(">HHHHHHHHBHHBHH", EAP_TLV_PAC_TLV,
8723 4 + 4 + 10 + 4 + 32,
8724 PAC_TYPE_PAC_OPAQUE, 0,
8725 PAC_TYPE_PAC_INFO, 10, PAC_TYPE_A_ID, 1, 0x41,
8726 PAC_TYPE_A_ID_INFO, 1, 0x42,
8727 PAC_TYPE_PAC_KEY, 32) + 32*b'A',
8728 True),
8729 ("EAP-FAST: Invalid version/subtype in Crypto-Binding TLV",
8730 struct.pack(">HH", EAP_TLV_CRYPTO_BINDING_TLV, 60) + 60*b'A',
8731 True)]
bccd22f3
JM
8732 for title, payload, failure in tests:
8733 logger.info("Phase 2 test: " + title)
8734 run_eap_fast_phase2(dev, payload, failure)
8735
8736def test_eap_fast_tlv_nak_oom(dev, apdev):
8737 """EAP-FAST Phase 2 TLV NAK OOM"""
8738 if not openssl_imported:
8739 raise HwsimSkip("OpenSSL python method not available")
8740 check_eap_capa(dev[0], "FAST")
5eee514d 8741 hapd = start_ap(apdev[0])
9efd3447 8742 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
bccd22f3
JM
8743
8744 with alloc_fail(dev[0], 1, "eap_fast_tlv_nak"):
8745 run_eap_fast_phase2(dev, struct.pack(">HHB", EAP_TLV_TYPE_MANDATORY,
8746 1, 0xff), False)