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