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