]> git.ipfire.org Git - thirdparty/hostap.git/blob - tests/hwsim/test_eap_proto.py
50fe5df0362486ea84fd402b9a57a33ee8c5bc54
[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, "=omac1_aes_vector;omac1_aes_128;aes_128_eax_encrypt"),
2952 (2, "=omac1_aes_vector;omac1_aes_128;aes_128_eax_encrypt"),
2953 (3, "=omac1_aes_vector;omac1_aes_128;aes_128_eax_encrypt"),
2954 (1, "=omac1_aes_vector;omac1_aes_128;aes_128_eax_decrypt"),
2955 (2, "=omac1_aes_vector;omac1_aes_128;aes_128_eax_decrypt"),
2956 (3, "=omac1_aes_vector;omac1_aes_128;aes_128_eax_decrypt"),
2957 (1, "aes_128_eax_decrypt;eap_psk_process_3"),
2958 (2, "aes_128_eax_decrypt;eap_psk_process_3"),
2959 (3, "aes_128_eax_decrypt;eap_psk_process_3"),
2960 (1, "aes_128_eax_encrypt;eap_psk_process_3"),
2961 (2, "aes_128_eax_encrypt;eap_psk_process_3"),
2962 (3, "aes_128_eax_encrypt;eap_psk_process_3"),
2963 (1, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"),
2964 (2, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"),
2965 (3, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"),
2966 (4, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"),
2967 (5, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"),
2968 (6, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"),
2969 (7, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"),
2970 (8, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"),
2971 (9, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"),
2972 (10, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"),
2973 (1, "aes_ctr_encrypt;aes_128_eax_decrypt;eap_psk_process_3"),
2974 (1, "aes_ctr_encrypt;aes_128_eax_encrypt;eap_psk_process_3")]
2975 for count, func in tests:
2976 with fail_test(dev[0], count, func):
2977 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
2978 eap="PSK", identity="psk.user@example.com",
2979 password_hex="0123456789abcdef0123456789abcdef",
2980 wait_connect=False)
2981 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
2982 timeout=15)
2983 if ev is None:
2984 raise Exception("Timeout on EAP start")
2985 wait_fail_trigger(dev[0], "GET_FAIL",
2986 note="No failure seen for %d:%s" % (count, func))
2987 dev[0].request("REMOVE_NETWORK all")
2988 dev[0].wait_disconnected()
2989 dev[0].dump_monitor()
2990
2991 EAP_SIM_SUBTYPE_START = 10
2992 EAP_SIM_SUBTYPE_CHALLENGE = 11
2993 EAP_SIM_SUBTYPE_NOTIFICATION = 12
2994 EAP_SIM_SUBTYPE_REAUTHENTICATION = 13
2995 EAP_SIM_SUBTYPE_CLIENT_ERROR = 14
2996
2997 EAP_AKA_SUBTYPE_CHALLENGE = 1
2998 EAP_AKA_SUBTYPE_AUTHENTICATION_REJECT = 2
2999 EAP_AKA_SUBTYPE_SYNCHRONIZATION_FAILURE = 4
3000 EAP_AKA_SUBTYPE_IDENTITY = 5
3001 EAP_AKA_SUBTYPE_NOTIFICATION = 12
3002 EAP_AKA_SUBTYPE_REAUTHENTICATION = 13
3003 EAP_AKA_SUBTYPE_CLIENT_ERROR = 14
3004
3005 EAP_SIM_AT_RAND = 1
3006 EAP_SIM_AT_AUTN = 2
3007 EAP_SIM_AT_RES = 3
3008 EAP_SIM_AT_AUTS = 4
3009 EAP_SIM_AT_PADDING = 6
3010 EAP_SIM_AT_NONCE_MT = 7
3011 EAP_SIM_AT_PERMANENT_ID_REQ = 10
3012 EAP_SIM_AT_MAC = 11
3013 EAP_SIM_AT_NOTIFICATION = 12
3014 EAP_SIM_AT_ANY_ID_REQ = 13
3015 EAP_SIM_AT_IDENTITY = 14
3016 EAP_SIM_AT_VERSION_LIST = 15
3017 EAP_SIM_AT_SELECTED_VERSION = 16
3018 EAP_SIM_AT_FULLAUTH_ID_REQ = 17
3019 EAP_SIM_AT_COUNTER = 19
3020 EAP_SIM_AT_COUNTER_TOO_SMALL = 20
3021 EAP_SIM_AT_NONCE_S = 21
3022 EAP_SIM_AT_CLIENT_ERROR_CODE = 22
3023 EAP_SIM_AT_KDF_INPUT = 23
3024 EAP_SIM_AT_KDF = 24
3025 EAP_SIM_AT_IV = 129
3026 EAP_SIM_AT_ENCR_DATA = 130
3027 EAP_SIM_AT_NEXT_PSEUDONYM = 132
3028 EAP_SIM_AT_NEXT_REAUTH_ID = 133
3029 EAP_SIM_AT_CHECKCODE = 134
3030 EAP_SIM_AT_RESULT_IND = 135
3031 EAP_SIM_AT_BIDDING = 136
3032
3033 def test_eap_proto_aka(dev, apdev):
3034 """EAP-AKA protocol tests"""
3035 def aka_handler(ctx, req):
3036 logger.info("aka_handler - RX " + binascii.hexlify(req).decode())
3037 if 'num' not in ctx:
3038 ctx['num'] = 0
3039 ctx['num'] = ctx['num'] + 1
3040 if 'id' not in ctx:
3041 ctx['id'] = 1
3042 ctx['id'] = (ctx['id'] + 1) % 256
3043
3044 idx = 0
3045
3046 idx += 1
3047 if ctx['num'] == idx:
3048 logger.info("Test: Missing payload")
3049 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
3050 4 + 1,
3051 EAP_TYPE_AKA)
3052
3053 idx += 1
3054 if ctx['num'] == idx:
3055 logger.info("Test: Unknown subtype")
3056 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
3057 4 + 1 + 3,
3058 EAP_TYPE_AKA, 255, 0)
3059 idx += 1
3060 if ctx['num'] == idx:
3061 logger.info("Test: EAP-Failure")
3062 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3063
3064 idx += 1
3065 if ctx['num'] == idx:
3066 logger.info("Test: Client Error")
3067 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
3068 4 + 1 + 3,
3069 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CLIENT_ERROR, 0)
3070 idx += 1
3071 if ctx['num'] == idx:
3072 logger.info("Test: EAP-Failure")
3073 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3074
3075 idx += 1
3076 if ctx['num'] == idx:
3077 logger.info("Test: Too short attribute header")
3078 return struct.pack(">BBHBBHB", EAP_CODE_REQUEST, ctx['id'],
3079 4 + 1 + 1 + 3,
3080 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 255)
3081 idx += 1
3082 if ctx['num'] == idx:
3083 logger.info("Test: EAP-Failure")
3084 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3085
3086 idx += 1
3087 if ctx['num'] == idx:
3088 logger.info("Test: Truncated attribute")
3089 return struct.pack(">BBHBBHBB", EAP_CODE_REQUEST, ctx['id'],
3090 4 + 1 + 1 + 4,
3091 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 255,
3092 255)
3093 idx += 1
3094 if ctx['num'] == idx:
3095 logger.info("Test: EAP-Failure")
3096 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3097
3098 idx += 1
3099 if ctx['num'] == idx:
3100 logger.info("Test: Too short attribute data")
3101 return struct.pack(">BBHBBHBB", EAP_CODE_REQUEST, ctx['id'],
3102 4 + 1 + 1 + 4,
3103 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 255,
3104 0)
3105 idx += 1
3106 if ctx['num'] == idx:
3107 logger.info("Test: EAP-Failure")
3108 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3109
3110 idx += 1
3111 if ctx['num'] == idx:
3112 logger.info("Test: Skippable/non-skippable unrecognzized attribute")
3113 return struct.pack(">BBHBBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3114 4 + 1 + 1 + 10,
3115 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3116 255, 1, 0, 127, 1, 0)
3117 idx += 1
3118 if ctx['num'] == idx:
3119 logger.info("Test: EAP-Failure")
3120 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3121
3122 idx += 1
3123 if ctx['num'] == idx:
3124 logger.info("Test: Identity request without ID type")
3125 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
3126 4 + 1 + 3,
3127 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0)
3128 idx += 1
3129 if ctx['num'] == idx:
3130 logger.info("Test: Identity request ANY_ID")
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: Identity request ANY_ID (duplicate)")
3138 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3139 4 + 1 + 3 + 4,
3140 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3141 EAP_SIM_AT_ANY_ID_REQ, 1, 0)
3142 idx += 1
3143 if ctx['num'] == idx:
3144 logger.info("Test: EAP-Failure")
3145 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3146
3147 idx += 1
3148 if ctx['num'] == idx:
3149 logger.info("Test: Identity request ANY_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_ANY_ID_REQ, 1, 0)
3154 idx += 1
3155 if ctx['num'] == idx:
3156 logger.info("Test: Identity request FULLAUTH_ID")
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: Identity request FULLAUTH_ID (duplicate)")
3164 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3165 4 + 1 + 3 + 4,
3166 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3167 EAP_SIM_AT_FULLAUTH_ID_REQ, 1, 0)
3168 idx += 1
3169 if ctx['num'] == idx:
3170 logger.info("Test: EAP-Failure")
3171 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3172
3173 idx += 1
3174 if ctx['num'] == idx:
3175 logger.info("Test: Identity request ANY_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_ANY_ID_REQ, 1, 0)
3180 idx += 1
3181 if ctx['num'] == idx:
3182 logger.info("Test: Identity request FULLAUTH_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_FULLAUTH_ID_REQ, 1, 0)
3187 idx += 1
3188 if ctx['num'] == idx:
3189 logger.info("Test: Identity request PERMANENT_ID")
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: Identity request PERMANENT_ID (duplicate)")
3197 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3198 4 + 1 + 3 + 4,
3199 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3200 EAP_SIM_AT_PERMANENT_ID_REQ, 1, 0)
3201 idx += 1
3202 if ctx['num'] == idx:
3203 logger.info("Test: EAP-Failure")
3204 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3205
3206 idx += 1
3207 if ctx['num'] == idx:
3208 logger.info("Test: Challenge with no attributes")
3209 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
3210 4 + 1 + 3,
3211 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CHALLENGE, 0)
3212 idx += 1
3213 if ctx['num'] == idx:
3214 logger.info("Test: EAP-Failure")
3215 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3216
3217 idx += 1
3218 if ctx['num'] == idx:
3219 logger.info("Test: AKA Challenge with BIDDING")
3220 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3221 4 + 1 + 3 + 4,
3222 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3223 EAP_SIM_AT_BIDDING, 1, 0x8000)
3224 idx += 1
3225 if ctx['num'] == idx:
3226 logger.info("Test: EAP-Failure")
3227 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3228
3229 idx += 1
3230 if ctx['num'] == idx:
3231 logger.info("Test: Notification with no attributes")
3232 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
3233 4 + 1 + 3,
3234 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0)
3235 idx += 1
3236 if ctx['num'] == idx:
3237 logger.info("Test: EAP-Failure")
3238 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3239
3240 idx += 1
3241 if ctx['num'] == idx:
3242 logger.info("Test: Notification indicating success, but no MAC")
3243 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3244 4 + 1 + 3 + 4,
3245 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0,
3246 EAP_SIM_AT_NOTIFICATION, 1, 32768)
3247 idx += 1
3248 if ctx['num'] == idx:
3249 logger.info("Test: EAP-Failure")
3250 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3251
3252 idx += 1
3253 if ctx['num'] == idx:
3254 logger.info("Test: Notification indicating success, but invalid MAC value")
3255 return struct.pack(">BBHBBHBBHBBH4L", EAP_CODE_REQUEST, ctx['id'],
3256 4 + 1 + 3 + 4 + 20,
3257 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0,
3258 EAP_SIM_AT_NOTIFICATION, 1, 32768,
3259 EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0)
3260 idx += 1
3261 if ctx['num'] == idx:
3262 logger.info("Test: EAP-Failure")
3263 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3264
3265 idx += 1
3266 if ctx['num'] == idx:
3267 logger.info("Test: Notification indicating success with zero-key MAC")
3268 return struct.pack(">BBHBBHBBHBBH16B", EAP_CODE_REQUEST,
3269 ctx['id'] - 2,
3270 4 + 1 + 3 + 4 + 20,
3271 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0,
3272 EAP_SIM_AT_NOTIFICATION, 1, 32768,
3273 EAP_SIM_AT_MAC, 5, 0,
3274 0xbe, 0x2e, 0xbb, 0xa9, 0xfa, 0x2e, 0x82, 0x36,
3275 0x37, 0x8c, 0x32, 0x41, 0xb7, 0xc7, 0x58, 0xa3)
3276 idx += 1
3277 if ctx['num'] == idx:
3278 logger.info("Test: EAP-Success")
3279 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4)
3280
3281 idx += 1
3282 if ctx['num'] == idx:
3283 logger.info("Test: Notification before auth")
3284 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3285 4 + 1 + 3 + 4,
3286 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0,
3287 EAP_SIM_AT_NOTIFICATION, 1, 16384)
3288 idx += 1
3289 if ctx['num'] == idx:
3290 logger.info("Test: EAP-Failure")
3291 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3292
3293 idx += 1
3294 if ctx['num'] == idx:
3295 logger.info("Test: Notification before auth")
3296 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3297 4 + 1 + 3 + 4,
3298 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0,
3299 EAP_SIM_AT_NOTIFICATION, 1, 16385)
3300 idx += 1
3301 if ctx['num'] == idx:
3302 logger.info("Test: EAP-Failure")
3303 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3304
3305 idx += 1
3306 if ctx['num'] == idx:
3307 logger.info("Test: Notification with unrecognized non-failure")
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: Notification before auth (duplicate)")
3315 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3316 4 + 1 + 3 + 4,
3317 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0,
3318 EAP_SIM_AT_NOTIFICATION, 1, 0xc000)
3319 idx += 1
3320 if ctx['num'] == idx:
3321 logger.info("Test: EAP-Failure")
3322 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3323
3324 idx += 1
3325 if ctx['num'] == idx:
3326 logger.info("Test: Re-authentication (unexpected) with no attributes")
3327 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
3328 4 + 1 + 3,
3329 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_REAUTHENTICATION,
3330 0)
3331 idx += 1
3332 if ctx['num'] == idx:
3333 logger.info("Test: EAP-Failure")
3334 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3335
3336 idx += 1
3337 if ctx['num'] == idx:
3338 logger.info("Test: AKA Challenge with Checkcode claiming identity round was used")
3339 return struct.pack(">BBHBBHBBH5L", EAP_CODE_REQUEST, ctx['id'],
3340 4 + 1 + 3 + 24,
3341 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3342 EAP_SIM_AT_CHECKCODE, 6, 0, 0, 0, 0, 0, 0)
3343 idx += 1
3344 if ctx['num'] == idx:
3345 logger.info("Test: EAP-Failure")
3346 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3347
3348 idx += 1
3349 if ctx['num'] == idx:
3350 logger.info("Test: Identity request ANY_ID")
3351 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3352 4 + 1 + 3 + 4,
3353 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3354 EAP_SIM_AT_ANY_ID_REQ, 1, 0)
3355 idx += 1
3356 if ctx['num'] == idx:
3357 logger.info("Test: AKA Challenge with Checkcode claiming no identity round was used")
3358 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3359 4 + 1 + 3 + 4,
3360 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3361 EAP_SIM_AT_CHECKCODE, 1, 0)
3362 idx += 1
3363 if ctx['num'] == idx:
3364 logger.info("Test: EAP-Failure")
3365 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3366
3367 idx += 1
3368 if ctx['num'] == idx:
3369 logger.info("Test: Identity request ANY_ID")
3370 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3371 4 + 1 + 3 + 4,
3372 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3373 EAP_SIM_AT_ANY_ID_REQ, 1, 0)
3374 idx += 1
3375 if ctx['num'] == idx:
3376 logger.info("Test: AKA Challenge with mismatching Checkcode value")
3377 return struct.pack(">BBHBBHBBH5L", EAP_CODE_REQUEST, ctx['id'],
3378 4 + 1 + 3 + 24,
3379 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3380 EAP_SIM_AT_CHECKCODE, 6, 0, 0, 0, 0, 0, 0)
3381 idx += 1
3382 if ctx['num'] == idx:
3383 logger.info("Test: EAP-Failure")
3384 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3385
3386 idx += 1
3387 if ctx['num'] == idx:
3388 logger.info("Test: Re-authentication (unexpected) with Checkcode claimin identity round was used")
3389 return struct.pack(">BBHBBHBBH5L", EAP_CODE_REQUEST, ctx['id'],
3390 4 + 1 + 3 + 24,
3391 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_REAUTHENTICATION,
3392 0,
3393 EAP_SIM_AT_CHECKCODE, 6, 0, 0, 0, 0, 0, 0)
3394 idx += 1
3395 if ctx['num'] == idx:
3396 logger.info("Test: EAP-Failure")
3397 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3398
3399 idx += 1
3400 if ctx['num'] == idx:
3401 logger.info("Test: Invalid AT_RAND length")
3402 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3403 4 + 1 + 3 + 4,
3404 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3405 EAP_SIM_AT_RAND, 1, 0)
3406 idx += 1
3407 if ctx['num'] == idx:
3408 logger.info("Test: EAP-Failure")
3409 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3410
3411 idx += 1
3412 if ctx['num'] == idx:
3413 logger.info("Test: Invalid AT_AUTN length")
3414 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3415 4 + 1 + 3 + 4,
3416 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3417 EAP_SIM_AT_AUTN, 1, 0)
3418 idx += 1
3419 if ctx['num'] == idx:
3420 logger.info("Test: EAP-Failure")
3421 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3422
3423 idx += 1
3424 if ctx['num'] == idx:
3425 logger.info("Test: Unencrypted AT_PADDING")
3426 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3427 4 + 1 + 3 + 4,
3428 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3429 EAP_SIM_AT_PADDING, 1, 0)
3430 idx += 1
3431 if ctx['num'] == idx:
3432 logger.info("Test: EAP-Failure")
3433 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3434
3435 idx += 1
3436 if ctx['num'] == idx:
3437 logger.info("Test: Invalid AT_NONCE_MT length")
3438 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3439 4 + 1 + 3 + 4,
3440 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3441 EAP_SIM_AT_NONCE_MT, 1, 0)
3442 idx += 1
3443 if ctx['num'] == idx:
3444 logger.info("Test: EAP-Failure")
3445 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3446
3447 idx += 1
3448 if ctx['num'] == idx:
3449 logger.info("Test: Invalid AT_MAC length")
3450 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3451 4 + 1 + 3 + 4,
3452 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3453 EAP_SIM_AT_MAC, 1, 0)
3454 idx += 1
3455 if ctx['num'] == idx:
3456 logger.info("Test: EAP-Failure")
3457 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3458
3459 idx += 1
3460 if ctx['num'] == idx:
3461 logger.info("Test: Invalid AT_NOTIFICATION length")
3462 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
3463 4 + 1 + 3 + 8,
3464 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3465 EAP_SIM_AT_NOTIFICATION, 2, 0, 0)
3466 idx += 1
3467 if ctx['num'] == idx:
3468 logger.info("Test: EAP-Failure")
3469 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3470
3471 idx += 1
3472 if ctx['num'] == idx:
3473 logger.info("Test: AT_IDENTITY overflow")
3474 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3475 4 + 1 + 3 + 4,
3476 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3477 EAP_SIM_AT_IDENTITY, 1, 0xffff)
3478 idx += 1
3479 if ctx['num'] == idx:
3480 logger.info("Test: EAP-Failure")
3481 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3482
3483 idx += 1
3484 if ctx['num'] == idx:
3485 logger.info("Test: Unexpected AT_VERSION_LIST")
3486 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3487 4 + 1 + 3 + 4,
3488 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3489 EAP_SIM_AT_VERSION_LIST, 1, 0)
3490 idx += 1
3491 if ctx['num'] == idx:
3492 logger.info("Test: EAP-Failure")
3493 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3494
3495 idx += 1
3496 if ctx['num'] == idx:
3497 logger.info("Test: Invalid AT_SELECTED_VERSION length")
3498 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
3499 4 + 1 + 3 + 8,
3500 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3501 EAP_SIM_AT_SELECTED_VERSION, 2, 0, 0)
3502 idx += 1
3503 if ctx['num'] == idx:
3504 logger.info("Test: EAP-Failure")
3505 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3506
3507 idx += 1
3508 if ctx['num'] == idx:
3509 logger.info("Test: Unencrypted AT_COUNTER")
3510 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3511 4 + 1 + 3 + 4,
3512 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3513 EAP_SIM_AT_COUNTER, 1, 0)
3514 idx += 1
3515 if ctx['num'] == idx:
3516 logger.info("Test: EAP-Failure")
3517 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3518
3519 idx += 1
3520 if ctx['num'] == idx:
3521 logger.info("Test: Unencrypted AT_COUNTER_TOO_SMALL")
3522 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3523 4 + 1 + 3 + 4,
3524 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3525 EAP_SIM_AT_COUNTER_TOO_SMALL, 1, 0)
3526 idx += 1
3527 if ctx['num'] == idx:
3528 logger.info("Test: EAP-Failure")
3529 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3530
3531 idx += 1
3532 if ctx['num'] == idx:
3533 logger.info("Test: Unencrypted AT_NONCE_S")
3534 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3535 4 + 1 + 3 + 4,
3536 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3537 EAP_SIM_AT_NONCE_S, 1, 0)
3538 idx += 1
3539 if ctx['num'] == idx:
3540 logger.info("Test: EAP-Failure")
3541 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3542
3543 idx += 1
3544 if ctx['num'] == idx:
3545 logger.info("Test: Invalid AT_CLIENT_ERROR_CODE length")
3546 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
3547 4 + 1 + 3 + 8,
3548 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3549 EAP_SIM_AT_CLIENT_ERROR_CODE, 2, 0, 0)
3550 idx += 1
3551 if ctx['num'] == idx:
3552 logger.info("Test: EAP-Failure")
3553 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3554
3555 idx += 1
3556 if ctx['num'] == idx:
3557 logger.info("Test: Invalid AT_IV length")
3558 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3559 4 + 1 + 3 + 4,
3560 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3561 EAP_SIM_AT_IV, 1, 0)
3562 idx += 1
3563 if ctx['num'] == idx:
3564 logger.info("Test: EAP-Failure")
3565 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3566
3567 idx += 1
3568 if ctx['num'] == idx:
3569 logger.info("Test: Invalid AT_ENCR_DATA length")
3570 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
3571 4 + 1 + 3 + 8,
3572 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3573 EAP_SIM_AT_ENCR_DATA, 2, 0, 0)
3574 idx += 1
3575 if ctx['num'] == idx:
3576 logger.info("Test: EAP-Failure")
3577 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3578
3579 idx += 1
3580 if ctx['num'] == idx:
3581 logger.info("Test: Unencrypted AT_NEXT_PSEUDONYM")
3582 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3583 4 + 1 + 3 + 4,
3584 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3585 EAP_SIM_AT_NEXT_PSEUDONYM, 1, 0)
3586 idx += 1
3587 if ctx['num'] == idx:
3588 logger.info("Test: EAP-Failure")
3589 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3590
3591 idx += 1
3592 if ctx['num'] == idx:
3593 logger.info("Test: Unencrypted AT_NEXT_REAUTH_ID")
3594 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3595 4 + 1 + 3 + 4,
3596 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3597 EAP_SIM_AT_NEXT_REAUTH_ID, 1, 0)
3598 idx += 1
3599 if ctx['num'] == idx:
3600 logger.info("Test: EAP-Failure")
3601 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3602
3603 idx += 1
3604 if ctx['num'] == idx:
3605 logger.info("Test: Invalid AT_RES length")
3606 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3607 4 + 1 + 3 + 4,
3608 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3609 EAP_SIM_AT_RES, 1, 0)
3610 idx += 1
3611 if ctx['num'] == idx:
3612 logger.info("Test: EAP-Failure")
3613 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3614
3615 idx += 1
3616 if ctx['num'] == idx:
3617 logger.info("Test: Invalid AT_RES length")
3618 return struct.pack(">BBHBBHBBH5L", EAP_CODE_REQUEST, ctx['id'],
3619 4 + 1 + 3 + 24,
3620 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3621 EAP_SIM_AT_RES, 6, 0xffff, 0, 0, 0, 0, 0)
3622 idx += 1
3623 if ctx['num'] == idx:
3624 logger.info("Test: EAP-Failure")
3625 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3626
3627 idx += 1
3628 if ctx['num'] == idx:
3629 logger.info("Test: Invalid AT_AUTS length")
3630 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
3631 4 + 1 + 3 + 8,
3632 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3633 EAP_SIM_AT_AUTS, 2, 0, 0)
3634 idx += 1
3635 if ctx['num'] == idx:
3636 logger.info("Test: EAP-Failure")
3637 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3638
3639 idx += 1
3640 if ctx['num'] == idx:
3641 logger.info("Test: Invalid AT_CHECKCODE length")
3642 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
3643 4 + 1 + 3 + 8,
3644 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3645 EAP_SIM_AT_CHECKCODE, 2, 0, 0)
3646 idx += 1
3647 if ctx['num'] == idx:
3648 logger.info("Test: EAP-Failure")
3649 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3650
3651 idx += 1
3652 if ctx['num'] == idx:
3653 logger.info("Test: Invalid AT_RESULT_IND length")
3654 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
3655 4 + 1 + 3 + 8,
3656 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3657 EAP_SIM_AT_RESULT_IND, 2, 0, 0)
3658 idx += 1
3659 if ctx['num'] == idx:
3660 logger.info("Test: EAP-Failure")
3661 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3662
3663 idx += 1
3664 if ctx['num'] == idx:
3665 logger.info("Test: Unexpected AT_KDF_INPUT")
3666 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
3667 4 + 1 + 3 + 8,
3668 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3669 EAP_SIM_AT_KDF_INPUT, 2, 0, 0)
3670 idx += 1
3671 if ctx['num'] == idx:
3672 logger.info("Test: EAP-Failure")
3673 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3674
3675 idx += 1
3676 if ctx['num'] == idx:
3677 logger.info("Test: Unexpected AT_KDF")
3678 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
3679 4 + 1 + 3 + 8,
3680 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3681 EAP_SIM_AT_KDF, 2, 0, 0)
3682 idx += 1
3683 if ctx['num'] == idx:
3684 logger.info("Test: EAP-Failure")
3685 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3686
3687 idx += 1
3688 if ctx['num'] == idx:
3689 logger.info("Test: Invalid AT_BIDDING length")
3690 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
3691 4 + 1 + 3 + 8,
3692 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3693 EAP_SIM_AT_BIDDING, 2, 0, 0)
3694 idx += 1
3695 if ctx['num'] == idx:
3696 logger.info("Test: EAP-Failure")
3697 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3698
3699 return None
3700
3701 srv = start_radius_server(aka_handler)
3702
3703 try:
3704 hapd = start_ap(apdev[0])
3705 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
3706
3707 for i in range(0, 49):
3708 eap = "AKA AKA'" if i == 11 else "AKA"
3709 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
3710 eap=eap, identity="0232010000000000",
3711 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123",
3712 wait_connect=False)
3713 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
3714 timeout=15)
3715 if ev is None:
3716 raise Exception("Timeout on EAP start")
3717 if i in [0, 15]:
3718 time.sleep(0.1)
3719 else:
3720 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"],
3721 timeout=10)
3722 if ev is None:
3723 raise Exception("Timeout on EAP failure")
3724 dev[0].request("REMOVE_NETWORK all")
3725 dev[0].dump_monitor()
3726 finally:
3727 stop_radius_server(srv)
3728
3729 def test_eap_proto_aka_prime(dev, apdev):
3730 """EAP-AKA' protocol tests"""
3731 def aka_prime_handler(ctx, req):
3732 logger.info("aka_prime_handler - RX " + binascii.hexlify(req).decode())
3733 if 'num' not in ctx:
3734 ctx['num'] = 0
3735 ctx['num'] = ctx['num'] + 1
3736 if 'id' not in ctx:
3737 ctx['id'] = 1
3738 ctx['id'] = (ctx['id'] + 1) % 256
3739
3740 idx = 0
3741
3742 idx += 1
3743 if ctx['num'] == idx:
3744 logger.info("Test: Missing payload")
3745 dev[0].note("Missing payload")
3746 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
3747 4 + 1,
3748 EAP_TYPE_AKA_PRIME)
3749
3750 idx += 1
3751 if ctx['num'] == idx:
3752 logger.info("Test: Challenge with no attributes")
3753 dev[0].note("Challenge with no attributes")
3754 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
3755 4 + 1 + 3,
3756 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0)
3757 idx += 1
3758 if ctx['num'] == idx:
3759 logger.info("Test: EAP-Failure")
3760 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3761
3762 idx += 1
3763 if ctx['num'] == idx:
3764 logger.info("Test: Challenge with empty AT_KDF_INPUT")
3765 dev[0].note("Challenge with empty AT_KDF_INPUT")
3766 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3767 4 + 1 + 3 + 4,
3768 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3769 EAP_SIM_AT_KDF_INPUT, 1, 0)
3770 idx += 1
3771 if ctx['num'] == idx:
3772 logger.info("Test: EAP-Failure")
3773 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3774
3775 idx += 1
3776 if ctx['num'] == idx:
3777 logger.info("Test: Challenge with AT_KDF_INPUT")
3778 dev[0].note("Test: Challenge with AT_KDF_INPUT")
3779 return struct.pack(">BBHBBHBBHBBBB", EAP_CODE_REQUEST, ctx['id'],
3780 4 + 1 + 3 + 8,
3781 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3782 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
3783 ord('c'), ord('d'))
3784 idx += 1
3785 if ctx['num'] == idx:
3786 logger.info("Test: EAP-Failure")
3787 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3788
3789 idx += 1
3790 if ctx['num'] == idx:
3791 logger.info("Test: Challenge with duplicated KDF")
3792 dev[0].note("Challenge with duplicated KDF")
3793 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH",
3794 EAP_CODE_REQUEST, ctx['id'],
3795 4 + 1 + 3 + 8 + 3 * 4,
3796 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3797 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
3798 ord('c'), ord('d'),
3799 EAP_SIM_AT_KDF, 1, 1,
3800 EAP_SIM_AT_KDF, 1, 2,
3801 EAP_SIM_AT_KDF, 1, 1)
3802 idx += 1
3803 if ctx['num'] == idx:
3804 logger.info("Test: EAP-Failure")
3805 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3806
3807 idx += 1
3808 if ctx['num'] == idx:
3809 logger.info("Test: Challenge with multiple KDF proposals")
3810 dev[0].note("Challenge with multiple KDF proposals (preparation)")
3811 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH",
3812 EAP_CODE_REQUEST, ctx['id'],
3813 4 + 1 + 3 + 8 + 3 * 4,
3814 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3815 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
3816 ord('c'), ord('d'),
3817 EAP_SIM_AT_KDF, 1, 255,
3818 EAP_SIM_AT_KDF, 1, 254,
3819 EAP_SIM_AT_KDF, 1, 1)
3820 idx += 1
3821 if ctx['num'] == idx:
3822 logger.info("Test: Challenge with incorrect KDF selected")
3823 dev[0].note("Challenge with incorrect KDF selected")
3824 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBHBBH",
3825 EAP_CODE_REQUEST, ctx['id'],
3826 4 + 1 + 3 + 8 + 4 * 4,
3827 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3828 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
3829 ord('c'), ord('d'),
3830 EAP_SIM_AT_KDF, 1, 255,
3831 EAP_SIM_AT_KDF, 1, 255,
3832 EAP_SIM_AT_KDF, 1, 254,
3833 EAP_SIM_AT_KDF, 1, 1)
3834 idx += 1
3835 if ctx['num'] == idx:
3836 logger.info("Test: EAP-Failure")
3837 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3838
3839 idx += 1
3840 if ctx['num'] == idx:
3841 logger.info("Test: Challenge with multiple KDF proposals")
3842 dev[0].note("Challenge with multiple KDF proposals (preparation)")
3843 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH",
3844 EAP_CODE_REQUEST, ctx['id'],
3845 4 + 1 + 3 + 8 + 3 * 4,
3846 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3847 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
3848 ord('c'), ord('d'),
3849 EAP_SIM_AT_KDF, 1, 255,
3850 EAP_SIM_AT_KDF, 1, 254,
3851 EAP_SIM_AT_KDF, 1, 1)
3852 idx += 1
3853 if ctx['num'] == idx:
3854 logger.info("Test: Challenge with selected KDF not duplicated")
3855 dev[0].note("Challenge with selected KDF not duplicated")
3856 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH",
3857 EAP_CODE_REQUEST, ctx['id'],
3858 4 + 1 + 3 + 8 + 3 * 4,
3859 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3860 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
3861 ord('c'), ord('d'),
3862 EAP_SIM_AT_KDF, 1, 1,
3863 EAP_SIM_AT_KDF, 1, 255,
3864 EAP_SIM_AT_KDF, 1, 254)
3865 idx += 1
3866 if ctx['num'] == idx:
3867 logger.info("Test: EAP-Failure")
3868 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3869
3870 idx += 1
3871 if ctx['num'] == idx:
3872 logger.info("Test: Challenge with multiple KDF proposals")
3873 dev[0].note("Challenge with multiple KDF proposals (preparation)")
3874 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH",
3875 EAP_CODE_REQUEST, ctx['id'],
3876 4 + 1 + 3 + 8 + 3 * 4,
3877 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3878 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
3879 ord('c'), ord('d'),
3880 EAP_SIM_AT_KDF, 1, 255,
3881 EAP_SIM_AT_KDF, 1, 254,
3882 EAP_SIM_AT_KDF, 1, 1)
3883 idx += 1
3884 if ctx['num'] == idx:
3885 logger.info("Test: Challenge with selected KDF duplicated (missing MAC, RAND, AUTN)")
3886 dev[0].note("Challenge with selected KDF duplicated (missing MAC, RAND, AUTN)")
3887 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBHBBH",
3888 EAP_CODE_REQUEST, ctx['id'],
3889 4 + 1 + 3 + 8 + 4 * 4,
3890 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3891 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
3892 ord('c'), ord('d'),
3893 EAP_SIM_AT_KDF, 1, 1,
3894 EAP_SIM_AT_KDF, 1, 255,
3895 EAP_SIM_AT_KDF, 1, 254,
3896 EAP_SIM_AT_KDF, 1, 1)
3897 idx += 1
3898 if ctx['num'] == idx:
3899 logger.info("Test: EAP-Failure")
3900 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3901
3902 idx += 1
3903 if ctx['num'] == idx:
3904 logger.info("Test: Challenge with multiple unsupported KDF proposals")
3905 dev[0].note("Challenge with multiple unsupported KDF proposals")
3906 return struct.pack(">BBHBBHBBHBBBBBBHBBH",
3907 EAP_CODE_REQUEST, ctx['id'],
3908 4 + 1 + 3 + 8 + 2 * 4,
3909 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3910 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
3911 ord('c'), ord('d'),
3912 EAP_SIM_AT_KDF, 1, 255,
3913 EAP_SIM_AT_KDF, 1, 254)
3914 idx += 1
3915 if ctx['num'] == idx:
3916 logger.info("Test: EAP-Failure")
3917 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3918
3919 idx += 1
3920 if ctx['num'] == idx:
3921 logger.info("Test: Challenge with multiple KDF proposals")
3922 dev[0].note("Challenge with multiple KDF proposals (preparation)")
3923 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH",
3924 EAP_CODE_REQUEST, ctx['id'],
3925 4 + 1 + 3 + 8 + 3 * 4,
3926 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3927 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
3928 ord('c'), ord('d'),
3929 EAP_SIM_AT_KDF, 1, 255,
3930 EAP_SIM_AT_KDF, 1, 254,
3931 EAP_SIM_AT_KDF, 1, 1)
3932 idx += 1
3933 if ctx['num'] == idx:
3934 logger.info("Test: Challenge with invalid MAC, RAND, AUTN values)")
3935 dev[0].note("Challenge with invalid MAC, RAND, AUTN values)")
3936 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBHBBHBBH4LBBH4LBBH4L",
3937 EAP_CODE_REQUEST, ctx['id'],
3938 4 + 1 + 3 + 8 + 4 * 4 + 20 + 20 + 20,
3939 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3940 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
3941 ord('c'), ord('d'),
3942 EAP_SIM_AT_KDF, 1, 1,
3943 EAP_SIM_AT_KDF, 1, 255,
3944 EAP_SIM_AT_KDF, 1, 254,
3945 EAP_SIM_AT_KDF, 1, 1,
3946 EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0,
3947 EAP_SIM_AT_RAND, 5, 0, 0, 0, 0, 0,
3948 EAP_SIM_AT_AUTN, 5, 0, 0, 0, 0, 0)
3949 idx += 1
3950 if ctx['num'] == idx:
3951 logger.info("Test: EAP-Failure")
3952 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3953
3954 idx += 1
3955 if ctx['num'] == idx:
3956 logger.info("Test: Challenge - AMF separation bit not set)")
3957 dev[0].note("Challenge - AMF separation bit not set)")
3958 return struct.pack(">BBHBBHBBHBBBBBBHBBH4LBBH4LBBH4L",
3959 EAP_CODE_REQUEST, ctx['id'],
3960 4 + 1 + 3 + 8 + 4 + 20 + 20 + 20,
3961 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3962 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
3963 ord('c'), ord('d'),
3964 EAP_SIM_AT_KDF, 1, 1,
3965 EAP_SIM_AT_MAC, 5, 0, 1, 2, 3, 4,
3966 EAP_SIM_AT_RAND, 5, 0, 5, 6, 7, 8,
3967 EAP_SIM_AT_AUTN, 5, 0, 9, 10,
3968 0x2fda8ef7, 0xbba518cc)
3969 idx += 1
3970 if ctx['num'] == idx:
3971 logger.info("Test: EAP-Failure")
3972 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3973
3974 idx += 1
3975 if ctx['num'] == idx:
3976 logger.info("Test: Challenge - Invalid MAC")
3977 dev[0].note("Challenge - Invalid MAC")
3978 return struct.pack(">BBHBBHBBHBBBBBBHBBH4LBBH4LBBH4L",
3979 EAP_CODE_REQUEST, ctx['id'],
3980 4 + 1 + 3 + 8 + 4 + 20 + 20 + 20,
3981 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3982 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
3983 ord('c'), ord('d'),
3984 EAP_SIM_AT_KDF, 1, 1,
3985 EAP_SIM_AT_MAC, 5, 0, 1, 2, 3, 4,
3986 EAP_SIM_AT_RAND, 5, 0, 5, 6, 7, 8,
3987 EAP_SIM_AT_AUTN, 5, 0, 0xffffffff, 0xffffffff,
3988 0xd1f90322, 0x40514cb4)
3989 idx += 1
3990 if ctx['num'] == idx:
3991 logger.info("Test: EAP-Failure")
3992 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3993
3994 idx += 1
3995 if ctx['num'] == idx:
3996 logger.info("Test: Challenge - Valid MAC")
3997 dev[0].note("Challenge - Valid MAC")
3998 return struct.pack(">BBHBBHBBHBBBBBBHBBH4LBBH4LBBH4L",
3999 EAP_CODE_REQUEST, ctx['id'],
4000 4 + 1 + 3 + 8 + 4 + 20 + 20 + 20,
4001 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
4002 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
4003 ord('c'), ord('d'),
4004 EAP_SIM_AT_KDF, 1, 1,
4005 EAP_SIM_AT_MAC, 5, 0,
4006 0xf4a3c1d3, 0x7c901401, 0x34bd8b01, 0x6f7fa32f,
4007 EAP_SIM_AT_RAND, 5, 0, 5, 6, 7, 8,
4008 EAP_SIM_AT_AUTN, 5, 0, 0xffffffff, 0xffffffff,
4009 0xd1f90322, 0x40514cb4)
4010 idx += 1
4011 if ctx['num'] == idx:
4012 logger.info("Test: EAP-Failure")
4013 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4014
4015 idx += 1
4016 if ctx['num'] == idx:
4017 logger.info("Test: Invalid AT_KDF_INPUT length")
4018 dev[0].note("Invalid AT_KDF_INPUT length")
4019 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
4020 4 + 1 + 3 + 8,
4021 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_IDENTITY, 0,
4022 EAP_SIM_AT_KDF_INPUT, 2, 0xffff, 0)
4023 idx += 1
4024 if ctx['num'] == idx:
4025 logger.info("Test: EAP-Failure")
4026 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4027
4028 idx += 1
4029 if ctx['num'] == idx:
4030 logger.info("Test: Invalid AT_KDF length")
4031 dev[0].note("Invalid AT_KDF length")
4032 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
4033 4 + 1 + 3 + 8,
4034 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_IDENTITY, 0,
4035 EAP_SIM_AT_KDF, 2, 0, 0)
4036 idx += 1
4037 if ctx['num'] == idx:
4038 logger.info("Test: EAP-Failure")
4039 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4040
4041 idx += 1
4042 if ctx['num'] == idx:
4043 logger.info("Test: Challenge with large number of KDF proposals")
4044 dev[0].note("Challenge with large number of KDF proposals")
4045 return struct.pack(">BBHBBHBBHBBHBBHBBHBBHBBHBBHBBHBBHBBHBBHBBH",
4046 EAP_CODE_REQUEST, ctx['id'],
4047 4 + 1 + 3 + 12 * 4,
4048 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
4049 EAP_SIM_AT_KDF, 1, 255,
4050 EAP_SIM_AT_KDF, 1, 254,
4051 EAP_SIM_AT_KDF, 1, 253,
4052 EAP_SIM_AT_KDF, 1, 252,
4053 EAP_SIM_AT_KDF, 1, 251,
4054 EAP_SIM_AT_KDF, 1, 250,
4055 EAP_SIM_AT_KDF, 1, 249,
4056 EAP_SIM_AT_KDF, 1, 248,
4057 EAP_SIM_AT_KDF, 1, 247,
4058 EAP_SIM_AT_KDF, 1, 246,
4059 EAP_SIM_AT_KDF, 1, 245,
4060 EAP_SIM_AT_KDF, 1, 244)
4061 idx += 1
4062 if ctx['num'] == idx:
4063 logger.info("Test: EAP-Failure")
4064 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4065
4066 idx += 1
4067 if ctx['num'] == idx:
4068 logger.info("Test: Challenge with multiple KDF proposals")
4069 dev[0].note("Challenge with multiple KDF proposals (preparation)")
4070 return struct.pack(">BBHBBHBBHBBBBBBHBBH",
4071 EAP_CODE_REQUEST, ctx['id'],
4072 4 + 1 + 3 + 8 + 2 * 4,
4073 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
4074 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
4075 ord('c'), ord('d'),
4076 EAP_SIM_AT_KDF, 1, 2,
4077 EAP_SIM_AT_KDF, 1, 1)
4078 idx += 1
4079 if ctx['num'] == idx:
4080 logger.info("Test: Challenge with an extra KDF appended")
4081 dev[0].note("Challenge with an extra KDF appended")
4082 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBHBBH",
4083 EAP_CODE_REQUEST, ctx['id'],
4084 4 + 1 + 3 + 8 + 4 * 4,
4085 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
4086 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
4087 ord('c'), ord('d'),
4088 EAP_SIM_AT_KDF, 1, 1,
4089 EAP_SIM_AT_KDF, 1, 2,
4090 EAP_SIM_AT_KDF, 1, 1,
4091 EAP_SIM_AT_KDF, 1, 0)
4092 idx += 1
4093 if ctx['num'] == idx:
4094 logger.info("Test: EAP-Failure")
4095 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4096
4097 idx += 1
4098 if ctx['num'] == idx:
4099 logger.info("Test: Challenge with multiple KDF proposals")
4100 dev[0].note("Challenge with multiple KDF proposals (preparation)")
4101 return struct.pack(">BBHBBHBBHBBBBBBHBBH",
4102 EAP_CODE_REQUEST, ctx['id'],
4103 4 + 1 + 3 + 8 + 2 * 4,
4104 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
4105 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
4106 ord('c'), ord('d'),
4107 EAP_SIM_AT_KDF, 1, 2,
4108 EAP_SIM_AT_KDF, 1, 1)
4109 idx += 1
4110 if ctx['num'] == idx:
4111 logger.info("Test: Challenge with a modified KDF")
4112 dev[0].note("Challenge with a modified KDF")
4113 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH",
4114 EAP_CODE_REQUEST, ctx['id'],
4115 4 + 1 + 3 + 8 + 3 * 4,
4116 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
4117 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
4118 ord('c'), ord('d'),
4119 EAP_SIM_AT_KDF, 1, 1,
4120 EAP_SIM_AT_KDF, 1, 0,
4121 EAP_SIM_AT_KDF, 1, 1)
4122 idx += 1
4123 if ctx['num'] == idx:
4124 logger.info("Test: EAP-Failure")
4125 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4126
4127 return None
4128
4129 srv = start_radius_server(aka_prime_handler)
4130
4131 try:
4132 hapd = start_ap(apdev[0])
4133 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
4134
4135 for i in range(0, 18):
4136 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4137 eap="AKA'", identity="6555444333222111",
4138 password="5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123",
4139 wait_connect=False)
4140 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
4141 timeout=15)
4142 if ev is None:
4143 raise Exception("Timeout on EAP start")
4144 if i in [0]:
4145 time.sleep(0.1)
4146 else:
4147 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"],
4148 timeout=10)
4149 if ev is None:
4150 raise Exception("Timeout on EAP failure")
4151 dev[0].request("REMOVE_NETWORK all")
4152 dev[0].dump_monitor()
4153 finally:
4154 stop_radius_server(srv)
4155
4156 def test_eap_proto_sim(dev, apdev):
4157 """EAP-SIM protocol tests"""
4158 def sim_handler(ctx, req):
4159 logger.info("sim_handler - RX " + binascii.hexlify(req).decode())
4160 if 'num' not in ctx:
4161 ctx['num'] = 0
4162 ctx['num'] = ctx['num'] + 1
4163 if 'id' not in ctx:
4164 ctx['id'] = 1
4165 ctx['id'] = (ctx['id'] + 1) % 256
4166
4167 idx = 0
4168
4169 idx += 1
4170 if ctx['num'] == idx:
4171 logger.info("Test: Missing payload")
4172 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
4173 4 + 1,
4174 EAP_TYPE_SIM)
4175
4176 idx += 1
4177 if ctx['num'] == idx:
4178 logger.info("Test: Unexpected AT_AUTN")
4179 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
4180 4 + 1 + 3 + 8,
4181 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
4182 EAP_SIM_AT_AUTN, 2, 0, 0)
4183 idx += 1
4184 if ctx['num'] == idx:
4185 logger.info("Test: EAP-Failure")
4186 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4187
4188 idx += 1
4189 if ctx['num'] == idx:
4190 logger.info("Test: Too short AT_VERSION_LIST")
4191 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4192 4 + 1 + 3 + 4,
4193 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
4194 EAP_SIM_AT_VERSION_LIST, 1, 0)
4195 idx += 1
4196 if ctx['num'] == idx:
4197 logger.info("Test: EAP-Failure")
4198 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4199
4200 idx += 1
4201 if ctx['num'] == idx:
4202 logger.info("Test: AT_VERSION_LIST overflow")
4203 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4204 4 + 1 + 3 + 4,
4205 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
4206 EAP_SIM_AT_VERSION_LIST, 1, 0xffff)
4207 idx += 1
4208 if ctx['num'] == idx:
4209 logger.info("Test: EAP-Failure")
4210 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4211
4212 idx += 1
4213 if ctx['num'] == idx:
4214 logger.info("Test: Unexpected AT_AUTS")
4215 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
4216 4 + 1 + 3 + 8,
4217 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
4218 EAP_SIM_AT_AUTS, 2, 0, 0)
4219 idx += 1
4220 if ctx['num'] == idx:
4221 logger.info("Test: EAP-Failure")
4222 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4223
4224 idx += 1
4225 if ctx['num'] == idx:
4226 logger.info("Test: Unexpected AT_CHECKCODE")
4227 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
4228 4 + 1 + 3 + 8,
4229 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
4230 EAP_SIM_AT_CHECKCODE, 2, 0, 0)
4231 idx += 1
4232 if ctx['num'] == idx:
4233 logger.info("Test: EAP-Failure")
4234 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4235
4236 idx += 1
4237 if ctx['num'] == idx:
4238 logger.info("Test: No AT_VERSION_LIST in Start")
4239 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
4240 4 + 1 + 3,
4241 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0)
4242 idx += 1
4243 if ctx['num'] == idx:
4244 logger.info("Test: EAP-Failure")
4245 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4246
4247 idx += 1
4248 if ctx['num'] == idx:
4249 logger.info("Test: No support version in AT_VERSION_LIST")
4250 return struct.pack(">BBHBBHBBH4B", EAP_CODE_REQUEST, ctx['id'],
4251 4 + 1 + 3 + 8,
4252 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
4253 EAP_SIM_AT_VERSION_LIST, 2, 3, 2, 3, 4, 5)
4254 idx += 1
4255 if ctx['num'] == idx:
4256 logger.info("Test: EAP-Failure")
4257 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4258
4259
4260 idx += 1
4261 if ctx['num'] == idx:
4262 logger.info("Test: Identity request without ID type")
4263 return struct.pack(">BBHBBHBBH2H", EAP_CODE_REQUEST, ctx['id'],
4264 4 + 1 + 3 + 8,
4265 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
4266 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0)
4267 idx += 1
4268 if ctx['num'] == idx:
4269 logger.info("Test: Identity request ANY_ID")
4270 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'],
4271 4 + 1 + 3 + 8 + 4,
4272 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
4273 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0,
4274 EAP_SIM_AT_ANY_ID_REQ, 1, 0)
4275 idx += 1
4276 if ctx['num'] == idx:
4277 logger.info("Test: Identity request ANY_ID (duplicate)")
4278 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'],
4279 4 + 1 + 3 + 8 + 4,
4280 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
4281 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0,
4282 EAP_SIM_AT_ANY_ID_REQ, 1, 0)
4283 idx += 1
4284 if ctx['num'] == idx:
4285 logger.info("Test: EAP-Failure")
4286 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4287
4288 idx += 1
4289 if ctx['num'] == idx:
4290 logger.info("Test: Identity request ANY_ID")
4291 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'],
4292 4 + 1 + 3 + 8 + 4,
4293 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
4294 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0,
4295 EAP_SIM_AT_ANY_ID_REQ, 1, 0)
4296 idx += 1
4297 if ctx['num'] == idx:
4298 logger.info("Test: Identity request FULLAUTH_ID")
4299 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'],
4300 4 + 1 + 3 + 8 + 4,
4301 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
4302 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0,
4303 EAP_SIM_AT_FULLAUTH_ID_REQ, 1, 0)
4304 idx += 1
4305 if ctx['num'] == idx:
4306 logger.info("Test: Identity request FULLAUTH_ID (duplicate)")
4307 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'],
4308 4 + 1 + 3 + 8 + 4,
4309 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
4310 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0,
4311 EAP_SIM_AT_FULLAUTH_ID_REQ, 1, 0)
4312 idx += 1
4313 if ctx['num'] == idx:
4314 logger.info("Test: EAP-Failure")
4315 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4316
4317 idx += 1
4318 if ctx['num'] == idx:
4319 logger.info("Test: Identity request ANY_ID")
4320 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'],
4321 4 + 1 + 3 + 8 + 4,
4322 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
4323 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0,
4324 EAP_SIM_AT_ANY_ID_REQ, 1, 0)
4325 idx += 1
4326 if ctx['num'] == idx:
4327 logger.info("Test: Identity request FULLAUTH_ID")
4328 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'],
4329 4 + 1 + 3 + 8 + 4,
4330 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
4331 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0,
4332 EAP_SIM_AT_FULLAUTH_ID_REQ, 1, 0)
4333 idx += 1
4334 if ctx['num'] == idx:
4335 logger.info("Test: Identity request PERMANENT_ID")
4336 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'],
4337 4 + 1 + 3 + 8 + 4,
4338 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
4339 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0,
4340 EAP_SIM_AT_PERMANENT_ID_REQ, 1, 0)
4341 idx += 1
4342 if ctx['num'] == idx:
4343 logger.info("Test: Identity request PERMANENT_ID (duplicate)")
4344 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'],
4345 4 + 1 + 3 + 8 + 4,
4346 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
4347 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0,
4348 EAP_SIM_AT_PERMANENT_ID_REQ, 1, 0)
4349 idx += 1
4350 if ctx['num'] == idx:
4351 logger.info("Test: EAP-Failure")
4352 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4353
4354 idx += 1
4355 if ctx['num'] == idx:
4356 logger.info("Test: No AT_MAC and AT_RAND in Challenge")
4357 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
4358 4 + 1 + 3,
4359 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CHALLENGE, 0)
4360 idx += 1
4361 if ctx['num'] == idx:
4362 logger.info("Test: EAP-Failure")
4363 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4364
4365 idx += 1
4366 if ctx['num'] == idx:
4367 logger.info("Test: No AT_RAND in Challenge")
4368 return struct.pack(">BBHBBHBBH4L", EAP_CODE_REQUEST, ctx['id'],
4369 4 + 1 + 3 + 20,
4370 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CHALLENGE, 0,
4371 EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0)
4372 idx += 1
4373 if ctx['num'] == idx:
4374 logger.info("Test: EAP-Failure")
4375 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4376
4377 idx += 1
4378 if ctx['num'] == idx:
4379 logger.info("Test: Insufficient number of challenges in Challenge")
4380 return struct.pack(">BBHBBHBBH4LBBH4L", EAP_CODE_REQUEST, ctx['id'],
4381 4 + 1 + 3 + 20 + 20,
4382 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CHALLENGE, 0,
4383 EAP_SIM_AT_RAND, 5, 0, 0, 0, 0, 0,
4384 EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0)
4385 idx += 1
4386 if ctx['num'] == idx:
4387 logger.info("Test: EAP-Failure")
4388 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4389
4390 idx += 1
4391 if ctx['num'] == idx:
4392 logger.info("Test: Too many challenges in Challenge")
4393 return struct.pack(">BBHBBHBBH4L4L4L4LBBH4L", EAP_CODE_REQUEST,
4394 ctx['id'],
4395 4 + 1 + 3 + 4 + 4 * 16 + 20,
4396 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CHALLENGE, 0,
4397 EAP_SIM_AT_RAND, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4398 0, 0, 0, 0, 0, 0, 0, 0,
4399 EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0)
4400 idx += 1
4401 if ctx['num'] == idx:
4402 logger.info("Test: EAP-Failure")
4403 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4404
4405 idx += 1
4406 if ctx['num'] == idx:
4407 logger.info("Test: Same RAND multiple times in Challenge")
4408 return struct.pack(">BBHBBHBBH4L4L4LBBH4L", EAP_CODE_REQUEST,
4409 ctx['id'],
4410 4 + 1 + 3 + 4 + 3 * 16 + 20,
4411 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CHALLENGE, 0,
4412 EAP_SIM_AT_RAND, 13, 0, 0, 0, 0, 0, 0, 0, 0, 1,
4413 0, 0, 0, 0,
4414 EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0)
4415 idx += 1
4416 if ctx['num'] == idx:
4417 logger.info("Test: EAP-Failure")
4418 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4419
4420 idx += 1
4421 if ctx['num'] == idx:
4422 logger.info("Test: Notification with no attributes")
4423 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
4424 4 + 1 + 3,
4425 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0)
4426 idx += 1
4427 if ctx['num'] == idx:
4428 logger.info("Test: EAP-Failure")
4429 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4430
4431 idx += 1
4432 if ctx['num'] == idx:
4433 logger.info("Test: Notification indicating success, but no MAC")
4434 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4435 4 + 1 + 3 + 4,
4436 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0,
4437 EAP_SIM_AT_NOTIFICATION, 1, 32768)
4438 idx += 1
4439 if ctx['num'] == idx:
4440 logger.info("Test: EAP-Failure")
4441 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4442
4443 idx += 1
4444 if ctx['num'] == idx:
4445 logger.info("Test: Notification indicating success, but invalid MAC value")
4446 return struct.pack(">BBHBBHBBHBBH4L", EAP_CODE_REQUEST, ctx['id'],
4447 4 + 1 + 3 + 4 + 20,
4448 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0,
4449 EAP_SIM_AT_NOTIFICATION, 1, 32768,
4450 EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0)
4451 idx += 1
4452 if ctx['num'] == idx:
4453 logger.info("Test: EAP-Failure")
4454 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4455
4456 idx += 1
4457 if ctx['num'] == idx:
4458 logger.info("Test: Notification before auth")
4459 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4460 4 + 1 + 3 + 4,
4461 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0,
4462 EAP_SIM_AT_NOTIFICATION, 1, 16384)
4463 idx += 1
4464 if ctx['num'] == idx:
4465 logger.info("Test: EAP-Failure")
4466 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4467
4468 idx += 1
4469 if ctx['num'] == idx:
4470 logger.info("Test: Notification before auth")
4471 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4472 4 + 1 + 3 + 4,
4473 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0,
4474 EAP_SIM_AT_NOTIFICATION, 1, 16385)
4475 idx += 1
4476 if ctx['num'] == idx:
4477 logger.info("Test: EAP-Failure")
4478 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4479
4480 idx += 1
4481 if ctx['num'] == idx:
4482 logger.info("Test: Notification with unrecognized non-failure")
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: Notification before auth (duplicate)")
4490 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4491 4 + 1 + 3 + 4,
4492 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0,
4493 EAP_SIM_AT_NOTIFICATION, 1, 0xc000)
4494 idx += 1
4495 if ctx['num'] == idx:
4496 logger.info("Test: EAP-Failure")
4497 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4498
4499 idx += 1
4500 if ctx['num'] == idx:
4501 logger.info("Test: Re-authentication (unexpected) with no attributes")
4502 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
4503 4 + 1 + 3,
4504 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_REAUTHENTICATION,
4505 0)
4506 idx += 1
4507 if ctx['num'] == idx:
4508 logger.info("Test: EAP-Failure")
4509 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4510
4511 idx += 1
4512 if ctx['num'] == idx:
4513 logger.info("Test: Client Error")
4514 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
4515 4 + 1 + 3,
4516 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CLIENT_ERROR, 0)
4517 idx += 1
4518 if ctx['num'] == idx:
4519 logger.info("Test: EAP-Failure")
4520 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4521
4522 idx += 1
4523 if ctx['num'] == idx:
4524 logger.info("Test: Unknown subtype")
4525 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
4526 4 + 1 + 3,
4527 EAP_TYPE_SIM, 255, 0)
4528 idx += 1
4529 if ctx['num'] == idx:
4530 logger.info("Test: EAP-Failure")
4531 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4532
4533 return None
4534
4535 srv = start_radius_server(sim_handler)
4536
4537 try:
4538 hapd = start_ap(apdev[0])
4539 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
4540
4541 for i in range(0, 25):
4542 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4543 eap="SIM", identity="1232010000000000",
4544 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581",
4545 wait_connect=False)
4546 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
4547 timeout=15)
4548 if ev is None:
4549 raise Exception("Timeout on EAP start")
4550 if i in [0]:
4551 time.sleep(0.1)
4552 else:
4553 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"],
4554 timeout=10)
4555 if ev is None:
4556 raise Exception("Timeout on EAP failure")
4557 dev[0].request("REMOVE_NETWORK all")
4558 dev[0].dump_monitor()
4559 finally:
4560 stop_radius_server(srv)
4561
4562 def test_eap_proto_sim_errors(dev, apdev):
4563 """EAP-SIM protocol tests (error paths)"""
4564 check_hlr_auc_gw_support()
4565 params = hostapd.wpa2_eap_params(ssid="eap-test")
4566 hapd = hostapd.add_ap(apdev[0], params)
4567 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
4568
4569 with alloc_fail(dev[0], 1, "eap_sim_init"):
4570 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4571 eap="SIM", identity="1232010000000000",
4572 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581",
4573 wait_connect=False)
4574 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
4575 timeout=15)
4576 if ev is None:
4577 raise Exception("Timeout on EAP start")
4578 dev[0].request("REMOVE_NETWORK all")
4579 dev[0].wait_disconnected()
4580
4581 with fail_test(dev[0], 1, "os_get_random;eap_sim_init"):
4582 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4583 eap="SIM", identity="1232010000000000",
4584 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581",
4585 wait_connect=False)
4586 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
4587 timeout=15)
4588 if ev is None:
4589 raise Exception("Timeout on EAP start")
4590 dev[0].request("REMOVE_NETWORK all")
4591 dev[0].wait_disconnected()
4592
4593 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4594 eap="SIM", identity="1232010000000000",
4595 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581")
4596
4597 with fail_test(dev[0], 1, "aes_128_cbc_encrypt;eap_sim_response_reauth"):
4598 hapd.request("EAPOL_REAUTH " + dev[0].own_addr())
4599 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
4600 if ev is None:
4601 raise Exception("EAP re-authentication did not start")
4602 wait_fail_trigger(dev[0], "GET_FAIL")
4603 dev[0].request("REMOVE_NETWORK all")
4604 dev[0].dump_monitor()
4605
4606 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4607 eap="SIM", identity="1232010000000000",
4608 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581")
4609
4610 with fail_test(dev[0], 1, "os_get_random;eap_sim_msg_add_encr_start"):
4611 hapd.request("EAPOL_REAUTH " + dev[0].own_addr())
4612 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
4613 if ev is None:
4614 raise Exception("EAP re-authentication did not start")
4615 wait_fail_trigger(dev[0], "GET_FAIL")
4616 dev[0].request("REMOVE_NETWORK all")
4617 dev[0].dump_monitor()
4618
4619 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4620 eap="SIM", identity="1232010000000000",
4621 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581")
4622
4623 with fail_test(dev[0], 1, "os_get_random;eap_sim_init_for_reauth"):
4624 hapd.request("EAPOL_REAUTH " + dev[0].own_addr())
4625 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
4626 if ev is None:
4627 raise Exception("EAP re-authentication did not start")
4628 wait_fail_trigger(dev[0], "GET_FAIL")
4629 dev[0].request("REMOVE_NETWORK all")
4630 dev[0].dump_monitor()
4631
4632 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4633 eap="SIM", identity="1232010000000000",
4634 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581")
4635
4636 with alloc_fail(dev[0], 1, "eap_sim_parse_encr;eap_sim_process_reauthentication"):
4637 hapd.request("EAPOL_REAUTH " + dev[0].own_addr())
4638 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
4639 if ev is None:
4640 raise Exception("EAP re-authentication did not start")
4641 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
4642 dev[0].request("REMOVE_NETWORK all")
4643 dev[0].dump_monitor()
4644
4645 tests = [(1, "eap_sim_verify_mac;eap_sim_process_challenge"),
4646 (1, "eap_sim_parse_encr;eap_sim_process_challenge"),
4647 (1, "eap_sim_msg_init;eap_sim_response_start"),
4648 (1, "wpabuf_alloc;eap_sim_msg_init;eap_sim_response_start"),
4649 (1, "=eap_sim_learn_ids"),
4650 (2, "=eap_sim_learn_ids"),
4651 (2, "eap_sim_learn_ids"),
4652 (3, "eap_sim_learn_ids"),
4653 (1, "eap_sim_process_start"),
4654 (1, "eap_sim_getKey"),
4655 (1, "eap_sim_get_emsk"),
4656 (1, "eap_sim_get_session_id")]
4657 for count, func in tests:
4658 with alloc_fail(dev[0], count, func):
4659 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4660 eap="SIM", identity="1232010000000000@domain",
4661 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581",
4662 erp="1", wait_connect=False)
4663 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
4664 dev[0].request("REMOVE_NETWORK all")
4665 dev[0].dump_monitor()
4666
4667 tests = [(1, "aes_128_cbc_decrypt;eap_sim_parse_encr")]
4668 for count, func in tests:
4669 with fail_test(dev[0], count, func):
4670 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4671 eap="SIM", identity="1232010000000000",
4672 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581",
4673 wait_connect=False)
4674 wait_fail_trigger(dev[0], "GET_FAIL")
4675 dev[0].request("REMOVE_NETWORK all")
4676 dev[0].dump_monitor()
4677
4678 params = int_eap_server_params()
4679 params['eap_sim_db'] = "unix:/tmp/hlr_auc_gw.sock"
4680 params['eap_sim_aka_result_ind'] = "1"
4681 hapd2 = hostapd.add_ap(apdev[1], params)
4682 dev[0].scan_for_bss(hapd2.own_addr(), freq=2412)
4683
4684 with alloc_fail(dev[0], 1,
4685 "eap_sim_msg_init;eap_sim_response_notification"):
4686 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP",
4687 scan_freq="2412",
4688 eap="SIM", identity="1232010000000000",
4689 phase1="result_ind=1",
4690 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581",
4691 wait_connect=False)
4692 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
4693 dev[0].request("REMOVE_NETWORK all")
4694 dev[0].dump_monitor()
4695
4696 tests = ["eap_sim_msg_add_encr_start;eap_sim_response_notification",
4697 "aes_128_cbc_encrypt;eap_sim_response_notification"]
4698 for func in tests:
4699 with fail_test(dev[0], 1, func):
4700 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP",
4701 scan_freq="2412",
4702 eap="SIM", identity="1232010000000000",
4703 phase1="result_ind=1",
4704 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581")
4705 dev[0].request("REAUTHENTICATE")
4706 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5)
4707 if ev is None:
4708 raise Exception("EAP method not started on reauthentication")
4709 time.sleep(0.1)
4710 wait_fail_trigger(dev[0], "GET_FAIL")
4711 dev[0].request("REMOVE_NETWORK all")
4712 dev[0].dump_monitor()
4713
4714 tests = ["eap_sim_parse_encr;eap_sim_process_notification_reauth"]
4715 for func in tests:
4716 with alloc_fail(dev[0], 1, func):
4717 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP",
4718 scan_freq="2412",
4719 eap="SIM", identity="1232010000000000",
4720 phase1="result_ind=1",
4721 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581")
4722 dev[0].request("REAUTHENTICATE")
4723 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5)
4724 if ev is None:
4725 raise Exception("EAP method not started on reauthentication")
4726 time.sleep(0.1)
4727 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
4728 dev[0].request("REMOVE_NETWORK all")
4729 dev[0].dump_monitor()
4730
4731 def test_eap_proto_aka_errors(dev, apdev):
4732 """EAP-AKA protocol tests (error paths)"""
4733 check_hlr_auc_gw_support()
4734 params = hostapd.wpa2_eap_params(ssid="eap-test")
4735 hapd = hostapd.add_ap(apdev[0], params)
4736 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
4737
4738 with alloc_fail(dev[0], 1, "eap_aka_init"):
4739 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4740 eap="AKA", identity="0232010000000000",
4741 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123",
4742 wait_connect=False)
4743 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
4744 timeout=15)
4745 if ev is None:
4746 raise Exception("Timeout on EAP start")
4747 dev[0].request("REMOVE_NETWORK all")
4748 dev[0].wait_disconnected()
4749
4750 tests = [(1, "=eap_aka_learn_ids"),
4751 (2, "=eap_aka_learn_ids"),
4752 (1, "eap_sim_parse_encr;eap_aka_process_challenge"),
4753 (1, "wpabuf_dup;eap_aka_add_id_msg"),
4754 (1, "wpabuf_resize;eap_aka_add_id_msg"),
4755 (1, "eap_aka_getKey"),
4756 (1, "eap_aka_get_emsk"),
4757 (1, "eap_aka_get_session_id")]
4758 for count, func in tests:
4759 with alloc_fail(dev[0], count, func):
4760 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4761 eap="AKA", identity="0232010000000000@domain",
4762 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123",
4763 erp="1", wait_connect=False)
4764 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
4765 dev[0].request("REMOVE_NETWORK all")
4766 dev[0].dump_monitor()
4767
4768 params = int_eap_server_params()
4769 params['eap_sim_db'] = "unix:/tmp/hlr_auc_gw.sock"
4770 params['eap_sim_aka_result_ind'] = "1"
4771 hapd2 = hostapd.add_ap(apdev[1], params)
4772 dev[0].scan_for_bss(hapd2.own_addr(), freq=2412)
4773
4774 with alloc_fail(dev[0], 1,
4775 "eap_sim_msg_init;eap_aka_response_notification"):
4776 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412",
4777 eap="AKA", identity="0232010000000000",
4778 phase1="result_ind=1",
4779 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123",
4780 wait_connect=False)
4781 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
4782 dev[0].request("REMOVE_NETWORK all")
4783 dev[0].dump_monitor()
4784
4785 tests = [(1, "aes_128_encrypt_block;milenage_f1;milenage_check", None),
4786 (2, "aes_128_encrypt_block;milenage_f1;milenage_check", None),
4787 (1, "milenage_f2345;milenage_check", None),
4788 (7, "aes_128_encrypt_block;milenage_f2345;milenage_check",
4789 "ff0000000123"),
4790 (1, "aes_128_encrypt_block;milenage_f1;milenage_check",
4791 "fff000000123")]
4792 for count, func, seq in tests:
4793 if not seq:
4794 seq = "000000000123"
4795 with fail_test(dev[0], count, func):
4796 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP",
4797 scan_freq="2412",
4798 eap="AKA", identity="0232010000000000",
4799 phase1="result_ind=1",
4800 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:" + seq,
4801 wait_connect=False)
4802 wait_fail_trigger(dev[0], "GET_FAIL")
4803 dev[0].request("REMOVE_NETWORK all")
4804 dev[0].wait_disconnected()
4805 dev[0].dump_monitor()
4806
4807 tests = ["eap_sim_msg_add_encr_start;eap_aka_response_notification",
4808 "aes_128_cbc_encrypt;eap_aka_response_notification"]
4809 for func in tests:
4810 with fail_test(dev[0], 1, func):
4811 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP",
4812 scan_freq="2412",
4813 eap="AKA", identity="0232010000000000",
4814 phase1="result_ind=1",
4815 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123")
4816 dev[0].request("REAUTHENTICATE")
4817 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5)
4818 if ev is None:
4819 raise Exception("EAP method not started on reauthentication")
4820 time.sleep(0.1)
4821 wait_fail_trigger(dev[0], "GET_FAIL")
4822 dev[0].request("REMOVE_NETWORK all")
4823 dev[0].dump_monitor()
4824
4825 tests = ["eap_sim_parse_encr;eap_aka_process_notification_reauth"]
4826 for func in tests:
4827 with alloc_fail(dev[0], 1, func):
4828 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP",
4829 scan_freq="2412",
4830 eap="AKA", identity="0232010000000000",
4831 phase1="result_ind=1",
4832 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123")
4833 dev[0].request("REAUTHENTICATE")
4834 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5)
4835 if ev is None:
4836 raise Exception("EAP method not started on reauthentication")
4837 time.sleep(0.1)
4838 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
4839 dev[0].request("REMOVE_NETWORK all")
4840 dev[0].dump_monitor()
4841
4842 def test_eap_proto_aka_prime_errors(dev, apdev):
4843 """EAP-AKA' protocol tests (error paths)"""
4844 check_hlr_auc_gw_support()
4845 params = hostapd.wpa2_eap_params(ssid="eap-test")
4846 hapd = hostapd.add_ap(apdev[0], params)
4847 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
4848
4849 with alloc_fail(dev[0], 1, "eap_aka_init"):
4850 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4851 eap="AKA'", identity="6555444333222111",
4852 password="5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123",
4853 wait_connect=False)
4854 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
4855 timeout=15)
4856 if ev is None:
4857 raise Exception("Timeout on EAP start")
4858 dev[0].request("REMOVE_NETWORK all")
4859 dev[0].wait_disconnected()
4860
4861 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4862 eap="AKA'", identity="6555444333222111",
4863 password="5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123")
4864
4865 with fail_test(dev[0], 1, "aes_128_cbc_encrypt;eap_aka_response_reauth"):
4866 hapd.request("EAPOL_REAUTH " + dev[0].own_addr())
4867 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
4868 if ev is None:
4869 raise Exception("EAP re-authentication did not start")
4870 wait_fail_trigger(dev[0], "GET_FAIL")
4871 dev[0].request("REMOVE_NETWORK all")
4872 dev[0].dump_monitor()
4873
4874 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4875 eap="AKA'", identity="6555444333222111",
4876 password="5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123")
4877
4878 with alloc_fail(dev[0], 1, "eap_sim_parse_encr;eap_aka_process_reauthentication"):
4879 hapd.request("EAPOL_REAUTH " + dev[0].own_addr())
4880 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
4881 if ev is None:
4882 raise Exception("EAP re-authentication did not start")
4883 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
4884 dev[0].request("REMOVE_NETWORK all")
4885 dev[0].dump_monitor()
4886
4887 tests = [(1, "eap_sim_verify_mac_sha256"),
4888 (1, "=eap_aka_process_challenge")]
4889 for count, func in tests:
4890 with alloc_fail(dev[0], count, func):
4891 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4892 eap="AKA'", identity="6555444333222111",
4893 password="5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123",
4894 erp="1", wait_connect=False)
4895 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
4896 dev[0].request("REMOVE_NETWORK all")
4897 dev[0].dump_monitor()
4898
4899 def test_eap_proto_ikev2(dev, apdev):
4900 """EAP-IKEv2 protocol tests"""
4901 check_eap_capa(dev[0], "IKEV2")
4902
4903 global eap_proto_ikev2_test_done
4904 eap_proto_ikev2_test_done = False
4905
4906 def ikev2_handler(ctx, req):
4907 logger.info("ikev2_handler - RX " + binascii.hexlify(req).decode())
4908 if 'num' not in ctx:
4909 ctx['num'] = 0
4910 ctx['num'] = ctx['num'] + 1
4911 if 'id' not in ctx:
4912 ctx['id'] = 1
4913 ctx['id'] = (ctx['id'] + 1) % 256
4914
4915 idx = 0
4916
4917 idx += 1
4918 if ctx['num'] == idx:
4919 logger.info("Test: Missing payload")
4920 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
4921 4 + 1,
4922 EAP_TYPE_IKEV2)
4923
4924 idx += 1
4925 if ctx['num'] == idx:
4926 logger.info("Test: Truncated Message Length field")
4927 return struct.pack(">BBHBB3B", EAP_CODE_REQUEST, ctx['id'],
4928 4 + 1 + 1 + 3,
4929 EAP_TYPE_IKEV2, 0x80, 0, 0, 0)
4930
4931 idx += 1
4932 if ctx['num'] == idx:
4933 logger.info("Test: Too short Message Length value")
4934 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'],
4935 4 + 1 + 1 + 4 + 1,
4936 EAP_TYPE_IKEV2, 0x80, 0, 1)
4937
4938 idx += 1
4939 if ctx['num'] == idx:
4940 logger.info("Test: Truncated message")
4941 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'],
4942 4 + 1 + 1 + 4,
4943 EAP_TYPE_IKEV2, 0x80, 1)
4944
4945 idx += 1
4946 if ctx['num'] == idx:
4947 logger.info("Test: Truncated message(2)")
4948 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'],
4949 4 + 1 + 1 + 4,
4950 EAP_TYPE_IKEV2, 0x80, 0xffffffff)
4951
4952 idx += 1
4953 if ctx['num'] == idx:
4954 logger.info("Test: Truncated message(3)")
4955 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'],
4956 4 + 1 + 1 + 4,
4957 EAP_TYPE_IKEV2, 0xc0, 0xffffffff)
4958
4959 idx += 1
4960 if ctx['num'] == idx:
4961 logger.info("Test: Truncated message(4)")
4962 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'],
4963 4 + 1 + 1 + 4,
4964 EAP_TYPE_IKEV2, 0xc0, 10000000)
4965
4966 idx += 1
4967 if ctx['num'] == idx:
4968 logger.info("Test: Too long fragments (first fragment)")
4969 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'],
4970 4 + 1 + 1 + 4 + 1,
4971 EAP_TYPE_IKEV2, 0xc0, 2, 1)
4972
4973 idx += 1
4974 if ctx['num'] == idx:
4975 logger.info("Test: Too long fragments (second fragment)")
4976 return struct.pack(">BBHBB2B", EAP_CODE_REQUEST, ctx['id'],
4977 4 + 1 + 1 + 2,
4978 EAP_TYPE_IKEV2, 0x00, 2, 3)
4979
4980 idx += 1
4981 if ctx['num'] == idx:
4982 logger.info("Test: No Message Length field in first fragment")
4983 return struct.pack(">BBHBBB", EAP_CODE_REQUEST, ctx['id'],
4984 4 + 1 + 1 + 1,
4985 EAP_TYPE_IKEV2, 0x40, 1)
4986
4987 idx += 1
4988 if ctx['num'] == idx:
4989 logger.info("Test: ICV before keys")
4990 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
4991 4 + 1 + 1,
4992 EAP_TYPE_IKEV2, 0x20)
4993
4994 idx += 1
4995 if ctx['num'] == idx:
4996 logger.info("Test: Unsupported IKEv2 header version")
4997 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'],
4998 4 + 1 + 1 + 28,
4999 EAP_TYPE_IKEV2, 0x00,
5000 0, 0, 0, 0,
5001 0, 0, 0, 0, 0, 0)
5002
5003 idx += 1
5004 if ctx['num'] == idx:
5005 logger.info("Test: Incorrect IKEv2 header Length")
5006 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'],
5007 4 + 1 + 1 + 28,
5008 EAP_TYPE_IKEV2, 0x00,
5009 0, 0, 0, 0,
5010 0, 0x20, 0, 0, 0, 0)
5011
5012 idx += 1
5013 if ctx['num'] == idx:
5014 logger.info("Test: Unexpected IKEv2 Exchange Type in SA_INIT state")
5015 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'],
5016 4 + 1 + 1 + 28,
5017 EAP_TYPE_IKEV2, 0x00,
5018 0, 0, 0, 0,
5019 0, 0x20, 0, 0, 0, 28)
5020
5021 idx += 1
5022 if ctx['num'] == idx:
5023 logger.info("Test: Unexpected IKEv2 Message ID in SA_INIT state")
5024 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'],
5025 4 + 1 + 1 + 28,
5026 EAP_TYPE_IKEV2, 0x00,
5027 0, 0, 0, 0,
5028 0, 0x20, 34, 0, 1, 28)
5029
5030 idx += 1
5031 if ctx['num'] == idx:
5032 logger.info("Test: Unexpected IKEv2 Flags value")
5033 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'],
5034 4 + 1 + 1 + 28,
5035 EAP_TYPE_IKEV2, 0x00,
5036 0, 0, 0, 0,
5037 0, 0x20, 34, 0, 0, 28)
5038
5039 idx += 1
5040 if ctx['num'] == idx:
5041 logger.info("Test: Unexpected IKEv2 Flags value(2)")
5042 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'],
5043 4 + 1 + 1 + 28,
5044 EAP_TYPE_IKEV2, 0x00,
5045 0, 0, 0, 0,
5046 0, 0x20, 34, 0x20, 0, 28)
5047
5048 idx += 1
5049 if ctx['num'] == idx:
5050 logger.info("Test: No SAi1 in SA_INIT")
5051 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'],
5052 4 + 1 + 1 + 28,
5053 EAP_TYPE_IKEV2, 0x00,
5054 0, 0, 0, 0,
5055 0, 0x20, 34, 0x08, 0, 28)
5056
5057 def build_ike(id, next=0, exch_type=34, flags=0x00, ike=b''):
5058 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, id,
5059 4 + 1 + 1 + 28 + len(ike),
5060 EAP_TYPE_IKEV2, flags,
5061 0, 0, 0, 0,
5062 next, 0x20, exch_type, 0x08, 0,
5063 28 + len(ike)) + ike
5064
5065 idx += 1
5066 if ctx['num'] == idx:
5067 logger.info("Test: Unexpected extra data after payloads")
5068 return build_ike(ctx['id'], ike=struct.pack(">B", 1))
5069
5070 idx += 1
5071 if ctx['num'] == idx:
5072 logger.info("Test: Truncated payload header")
5073 return build_ike(ctx['id'], next=128, ike=struct.pack(">B", 1))
5074
5075 idx += 1
5076 if ctx['num'] == idx:
5077 logger.info("Test: Too small payload header length")
5078 ike = struct.pack(">BBH", 0, 0, 3)
5079 return build_ike(ctx['id'], next=128, ike=ike)
5080
5081 idx += 1
5082 if ctx['num'] == idx:
5083 logger.info("Test: Too large payload header length")
5084 ike = struct.pack(">BBH", 0, 0, 5)
5085 return build_ike(ctx['id'], next=128, ike=ike)
5086
5087 idx += 1
5088 if ctx['num'] == idx:
5089 logger.info("Test: Unsupported payload (non-critical and critical)")
5090 ike = struct.pack(">BBHBBH", 129, 0, 4, 0, 0x01, 4)
5091 return build_ike(ctx['id'], next=128, ike=ike)
5092
5093 idx += 1
5094 if ctx['num'] == idx:
5095 logger.info("Test: Certificate and empty SAi1")
5096 ike = struct.pack(">BBHBBH", 33, 0, 4, 0, 0, 4)
5097 return build_ike(ctx['id'], next=37, ike=ike)
5098
5099 idx += 1
5100 if ctx['num'] == idx:
5101 logger.info("Test: Too short proposal")
5102 ike = struct.pack(">BBHBBHBBB", 0, 0, 4 + 7,
5103 0, 0, 7, 0, 0, 0)
5104 return build_ike(ctx['id'], next=33, ike=ike)
5105
5106 idx += 1
5107 if ctx['num'] == idx:
5108 logger.info("Test: Too small proposal length in SAi1")
5109 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8,
5110 0, 0, 7, 0, 0, 0, 0)
5111 return build_ike(ctx['id'], next=33, ike=ike)
5112
5113 idx += 1
5114 if ctx['num'] == idx:
5115 logger.info("Test: Too large proposal length in SAi1")
5116 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8,
5117 0, 0, 9, 0, 0, 0, 0)
5118 return build_ike(ctx['id'], next=33, ike=ike)
5119
5120 idx += 1
5121 if ctx['num'] == idx:
5122 logger.info("Test: Unexpected proposal type in SAi1")
5123 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8,
5124 1, 0, 8, 0, 0, 0, 0)
5125 return build_ike(ctx['id'], next=33, ike=ike)
5126
5127 idx += 1
5128 if ctx['num'] == idx:
5129 logger.info("Test: Unexpected Protocol ID in SAi1")
5130 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8,
5131 0, 0, 8, 0, 0, 0, 0)
5132 return build_ike(ctx['id'], next=33, ike=ike)
5133
5134 idx += 1
5135 if ctx['num'] == idx:
5136 logger.info("Test: Unexpected proposal number in SAi1")
5137 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8,
5138 0, 0, 8, 0, 1, 0, 0)
5139 return build_ike(ctx['id'], next=33, ike=ike)
5140
5141 idx += 1
5142 if ctx['num'] == idx:
5143 logger.info("Test: Not enough room for SPI in SAi1")
5144 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8,
5145 0, 0, 8, 1, 1, 1, 0)
5146 return build_ike(ctx['id'], next=33, ike=ike)
5147
5148 idx += 1
5149 if ctx['num'] == idx:
5150 logger.info("Test: Unexpected SPI in SAi1")
5151 ike = struct.pack(">BBHBBHBBBBB", 0, 0, 4 + 9,
5152 0, 0, 9, 1, 1, 1, 0, 1)
5153 return build_ike(ctx['id'], next=33, ike=ike)
5154
5155 idx += 1
5156 if ctx['num'] == idx:
5157 logger.info("Test: No transforms in SAi1")
5158 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8,
5159 0, 0, 8, 1, 1, 0, 0)
5160 return build_ike(ctx['id'], next=33, ike=ike)
5161
5162 idx += 1
5163 if ctx['num'] == idx:
5164 logger.info("Test: Too short transform in SAi1")
5165 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8,
5166 0, 0, 8, 1, 1, 0, 1)
5167 return build_ike(ctx['id'], next=33, ike=ike)
5168
5169 idx += 1
5170 if ctx['num'] == idx:
5171 logger.info("Test: Too small transform length in SAi1")
5172 ike = struct.pack(">BBHBBHBBBBBBHBBH", 0, 0, 4 + 8 + 8,
5173 0, 0, 8 + 8, 1, 1, 0, 1,
5174 0, 0, 7, 0, 0, 0)
5175 return build_ike(ctx['id'], next=33, ike=ike)
5176
5177 idx += 1
5178 if ctx['num'] == idx:
5179 logger.info("Test: Too large transform length in SAi1")
5180 ike = struct.pack(">BBHBBHBBBBBBHBBH", 0, 0, 4 + 8 + 8,
5181 0, 0, 8 + 8, 1, 1, 0, 1,
5182 0, 0, 9, 0, 0, 0)
5183 return build_ike(ctx['id'], next=33, ike=ike)
5184
5185 idx += 1
5186 if ctx['num'] == idx:
5187 logger.info("Test: Unexpected Transform type in SAi1")
5188 ike = struct.pack(">BBHBBHBBBBBBHBBH", 0, 0, 4 + 8 + 8,
5189 0, 0, 8 + 8, 1, 1, 0, 1,
5190 1, 0, 8, 0, 0, 0)
5191 return build_ike(ctx['id'], next=33, ike=ike)
5192
5193 idx += 1
5194 if ctx['num'] == idx:
5195 logger.info("Test: No transform attributes in SAi1")
5196 ike = struct.pack(">BBHBBHBBBBBBHBBH", 0, 0, 4 + 8 + 8,
5197 0, 0, 8 + 8, 1, 1, 0, 1,
5198 0, 0, 8, 0, 0, 0)
5199 return build_ike(ctx['id'], next=33, ike=ike)
5200
5201 idx += 1
5202 if ctx['num'] == idx:
5203 logger.info("Test: No transform attr for AES and unexpected data after transforms in SAi1")
5204 tlen1 = 8 + 3
5205 tlen2 = 8 + 4
5206 tlen3 = 8 + 4
5207 tlen = tlen1 + tlen2 + tlen3
5208 ike = struct.pack(">BBHBBHBBBBBBHBBH3BBBHBBHHHBBHBBHHHB",
5209 0, 0, 4 + 8 + tlen + 1,
5210 0, 0, 8 + tlen + 1, 1, 1, 0, 3,
5211 3, 0, tlen1, 1, 0, 12, 1, 2, 3,
5212 3, 0, tlen2, 1, 0, 12, 0, 128,
5213 0, 0, tlen3, 1, 0, 12, 0x8000 | 14, 127,
5214 1)
5215 return build_ike(ctx['id'], next=33, ike=ike)
5216
5217 def build_sa(next=0):
5218 tlen = 5 * 8
5219 return struct.pack(">BBHBBHBBBBBBHBBHBBHBBHBBHBBHBBHBBHBBHBBH",
5220 next, 0, 4 + 8 + tlen,
5221 0, 0, 8 + tlen, 1, 1, 0, 5,
5222 3, 0, 8, 1, 0, 3,
5223 3, 0, 8, 2, 0, 1,
5224 3, 0, 8, 3, 0, 1,
5225 3, 0, 8, 4, 0, 5,
5226 0, 0, 8, 241, 0, 0)
5227
5228 idx += 1
5229 if ctx['num'] == idx:
5230 logger.info("Test: Valid proposal, but no KEi in SAi1")
5231 ike = build_sa()
5232 return build_ike(ctx['id'], next=33, ike=ike)
5233
5234 idx += 1
5235 if ctx['num'] == idx:
5236 logger.info("Test: Empty KEi in SAi1")
5237 ike = build_sa(next=34) + struct.pack(">BBH", 0, 0, 4)
5238 return build_ike(ctx['id'], next=33, ike=ike)
5239
5240 idx += 1
5241 if ctx['num'] == idx:
5242 logger.info("Test: Mismatch in DH Group in SAi1")
5243 ike = build_sa(next=34)
5244 ike += struct.pack(">BBHHH", 0, 0, 4 + 4 + 96, 12345, 0)
5245 ike += 96*b'\x00'
5246 return build_ike(ctx['id'], next=33, ike=ike)
5247 idx += 1
5248 if ctx['num'] == idx:
5249 logger.info("Test: EAP-Failure")
5250 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5251
5252 idx += 1
5253 if ctx['num'] == idx:
5254 logger.info("Test: Invalid DH public value length in SAi1")
5255 ike = build_sa(next=34)
5256 ike += struct.pack(">BBHHH", 0, 0, 4 + 4 + 96, 5, 0)
5257 ike += 96*b'\x00'
5258 return build_ike(ctx['id'], next=33, ike=ike)
5259
5260 def build_ke(next=0):
5261 ke = struct.pack(">BBHHH", next, 0, 4 + 4 + 192, 5, 0)
5262 ke += 191*b'\x00'+b'\x02'
5263 return ke
5264
5265 idx += 1
5266 if ctx['num'] == idx:
5267 logger.info("Test: Valid proposal and KEi, but no Ni in SAi1")
5268 ike = build_sa(next=34)
5269 ike += build_ke()
5270 return build_ike(ctx['id'], next=33, ike=ike)
5271
5272 idx += 1
5273 if ctx['num'] == idx:
5274 logger.info("Test: Too short Ni in SAi1")
5275 ike = build_sa(next=34)
5276 ike += build_ke(next=40)
5277 ike += struct.pack(">BBH", 0, 0, 4)
5278 return build_ike(ctx['id'], next=33, ike=ike)
5279
5280 idx += 1
5281 if ctx['num'] == idx:
5282 logger.info("Test: Too long Ni in SAi1")
5283 ike = build_sa(next=34)
5284 ike += build_ke(next=40)
5285 ike += struct.pack(">BBH", 0, 0, 4 + 257) + 257*b'\x00'
5286 return build_ike(ctx['id'], next=33, ike=ike)
5287
5288 def build_ni(next=0):
5289 return struct.pack(">BBH", next, 0, 4 + 256) + 256*b'\x00'
5290
5291 def build_sai1(id):
5292 ike = build_sa(next=34)
5293 ike += build_ke(next=40)
5294 ike += build_ni()
5295 return build_ike(ctx['id'], next=33, ike=ike)
5296
5297 idx += 1
5298 if ctx['num'] == idx:
5299 logger.info("Test: Valid proposal, KEi, and Ni in SAi1")
5300 return build_sai1(ctx['id'])
5301 idx += 1
5302 if ctx['num'] == idx:
5303 logger.info("Test: EAP-Failure")
5304 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5305
5306 idx += 1
5307 if ctx['num'] == idx:
5308 logger.info("Test: Valid proposal, KEi, and Ni in SAi1")
5309 return build_sai1(ctx['id'])
5310 idx += 1
5311 if ctx['num'] == idx:
5312 logger.info("Test: No integrity checksum")
5313 ike = b''
5314 return build_ike(ctx['id'], next=37, ike=ike)
5315
5316 idx += 1
5317 if ctx['num'] == idx:
5318 logger.info("Test: Valid proposal, KEi, and Ni in SAi1")
5319 return build_sai1(ctx['id'])
5320 idx += 1
5321 if ctx['num'] == idx:
5322 logger.info("Test: Truncated integrity checksum")
5323 return struct.pack(">BBHBB",
5324 EAP_CODE_REQUEST, ctx['id'],
5325 4 + 1 + 1,
5326 EAP_TYPE_IKEV2, 0x20)
5327
5328 idx += 1
5329 if ctx['num'] == idx:
5330 logger.info("Test: Valid proposal, KEi, and Ni in SAi1")
5331 return build_sai1(ctx['id'])
5332 idx += 1
5333 if ctx['num'] == idx:
5334 logger.info("Test: Invalid integrity checksum")
5335 ike = b''
5336 return build_ike(ctx['id'], next=37, flags=0x20, ike=ike)
5337
5338 idx += 1
5339 if ctx['num'] == idx:
5340 logger.info("No more test responses available - test case completed")
5341 global eap_proto_ikev2_test_done
5342 eap_proto_ikev2_test_done = True
5343 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
5344 4 + 1,
5345 EAP_TYPE_IKEV2)
5346 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5347
5348 srv = start_radius_server(ikev2_handler)
5349
5350 try:
5351 hapd = start_ap(apdev[0])
5352 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
5353
5354 i = 0
5355 while not eap_proto_ikev2_test_done:
5356 i += 1
5357 logger.info("Running connection iteration %d" % i)
5358 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5359 eap="IKEV2", identity="user",
5360 password="password",
5361 wait_connect=False)
5362 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=15)
5363 if ev is None:
5364 raise Exception("Timeout on EAP start")
5365 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
5366 timeout=15)
5367 if ev is None:
5368 raise Exception("Timeout on EAP method start")
5369 if i in [41, 46]:
5370 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"],
5371 timeout=10)
5372 if ev is None:
5373 raise Exception("Timeout on EAP failure")
5374 else:
5375 time.sleep(0.05)
5376 dev[0].request("REMOVE_NETWORK all")
5377 dev[0].wait_disconnected()
5378 dev[0].dump_monitor()
5379 dev[1].dump_monitor()
5380 dev[2].dump_monitor()
5381 finally:
5382 stop_radius_server(srv)
5383
5384 def NtPasswordHash(password):
5385 pw = password.encode('utf_16_le')
5386 return hashlib.new('md4', pw).digest()
5387
5388 def HashNtPasswordHash(password_hash):
5389 return hashlib.new('md4', password_hash).digest()
5390
5391 def ChallengeHash(peer_challenge, auth_challenge, username):
5392 data = peer_challenge + auth_challenge + username
5393 return hashlib.sha1(data).digest()[0:8]
5394
5395 def GenerateAuthenticatorResponse(password, nt_response, peer_challenge,
5396 auth_challenge, username):
5397 magic1 = binascii.unhexlify("4D616769632073657276657220746F20636C69656E74207369676E696E6720636F6E7374616E74")
5398 magic2 = binascii.unhexlify("50616420746F206D616B6520697420646F206D6F7265207468616E206F6E6520697465726174696F6E")
5399
5400 password_hash = NtPasswordHash(password)
5401 password_hash_hash = HashNtPasswordHash(password_hash)
5402 data = password_hash_hash + nt_response + magic1
5403 digest = hashlib.sha1(data).digest()
5404
5405 challenge = ChallengeHash(peer_challenge, auth_challenge, username.encode())
5406
5407 data = digest + challenge + magic2
5408 resp = hashlib.sha1(data).digest()
5409 return resp
5410
5411 def test_eap_proto_ikev2_errors(dev, apdev):
5412 """EAP-IKEv2 local error cases"""
5413 check_eap_capa(dev[0], "IKEV2")
5414 params = hostapd.wpa2_eap_params(ssid="eap-test")
5415 hapd = hostapd.add_ap(apdev[0], params)
5416 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
5417
5418 for i in range(1, 5):
5419 with alloc_fail(dev[0], i, "eap_ikev2_init"):
5420 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5421 eap="IKEV2", identity="ikev2 user",
5422 password="ike password",
5423 wait_connect=False)
5424 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
5425 timeout=15)
5426 if ev is None:
5427 raise Exception("Timeout on EAP start")
5428 dev[0].request("REMOVE_NETWORK all")
5429 dev[0].wait_disconnected()
5430
5431 tests = [(1, "ikev2_encr_encrypt"),
5432 (1, "ikev2_encr_decrypt"),
5433 (1, "ikev2_derive_auth_data"),
5434 (2, "ikev2_derive_auth_data"),
5435 (1, "=ikev2_decrypt_payload"),
5436 (1, "ikev2_encr_decrypt;ikev2_decrypt_payload"),
5437 (1, "ikev2_encr_encrypt;ikev2_build_encrypted"),
5438 (1, "ikev2_derive_sk_keys"),
5439 (2, "ikev2_derive_sk_keys"),
5440 (3, "ikev2_derive_sk_keys"),
5441 (4, "ikev2_derive_sk_keys"),
5442 (5, "ikev2_derive_sk_keys"),
5443 (6, "ikev2_derive_sk_keys"),
5444 (7, "ikev2_derive_sk_keys"),
5445 (8, "ikev2_derive_sk_keys"),
5446 (1, "eap_ikev2_derive_keymat;eap_ikev2_peer_keymat"),
5447 (1, "eap_msg_alloc;eap_ikev2_build_msg"),
5448 (1, "eap_ikev2_getKey"),
5449 (1, "eap_ikev2_get_emsk"),
5450 (1, "eap_ikev2_get_session_id"),
5451 (1, "=ikev2_derive_keys"),
5452 (2, "=ikev2_derive_keys"),
5453 (1, "wpabuf_alloc;ikev2_process_kei"),
5454 (1, "=ikev2_process_idi"),
5455 (1, "ikev2_derive_auth_data;ikev2_build_auth"),
5456 (1, "wpabuf_alloc;ikev2_build_sa_init"),
5457 (2, "wpabuf_alloc;ikev2_build_sa_init"),
5458 (3, "wpabuf_alloc;ikev2_build_sa_init"),
5459 (4, "wpabuf_alloc;ikev2_build_sa_init"),
5460 (5, "wpabuf_alloc;ikev2_build_sa_init"),
5461 (6, "wpabuf_alloc;ikev2_build_sa_init"),
5462 (1, "wpabuf_alloc;ikev2_build_sa_auth"),
5463 (2, "wpabuf_alloc;ikev2_build_sa_auth"),
5464 (1, "ikev2_build_auth;ikev2_build_sa_auth")]
5465 for count, func in tests:
5466 with alloc_fail(dev[0], count, func):
5467 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5468 eap="IKEV2", identity="ikev2 user@domain",
5469 password="ike password", erp="1", wait_connect=False)
5470 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
5471 timeout=15)
5472 if ev is None:
5473 raise Exception("Timeout on EAP start")
5474 ok = False
5475 for j in range(10):
5476 state = dev[0].request('GET_ALLOC_FAIL')
5477 if state.startswith('0:'):
5478 ok = True
5479 break
5480 time.sleep(0.1)
5481 if not ok:
5482 raise Exception("No allocation failure seen for %d:%s" % (count, func))
5483 dev[0].request("REMOVE_NETWORK all")
5484 dev[0].wait_disconnected()
5485
5486 tests = [(1, "wpabuf_alloc;ikev2_build_notify"),
5487 (2, "wpabuf_alloc;ikev2_build_notify"),
5488 (1, "ikev2_build_encrypted;ikev2_build_notify")]
5489 for count, func in tests:
5490 with alloc_fail(dev[0], count, func):
5491 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5492 eap="IKEV2", identity="ikev2 user",
5493 password="wrong password", erp="1",
5494 wait_connect=False)
5495 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
5496 timeout=15)
5497 if ev is None:
5498 raise Exception("Timeout on EAP start")
5499 ok = False
5500 for j in range(10):
5501 state = dev[0].request('GET_ALLOC_FAIL')
5502 if state.startswith('0:'):
5503 ok = True
5504 break
5505 time.sleep(0.1)
5506 if not ok:
5507 raise Exception("No allocation failure seen for %d:%s" % (count, func))
5508 dev[0].request("REMOVE_NETWORK all")
5509 dev[0].wait_disconnected()
5510
5511 tests = [(1, "ikev2_integ_hash"),
5512 (1, "ikev2_integ_hash;ikev2_decrypt_payload"),
5513 (1, "os_get_random;ikev2_build_encrypted"),
5514 (1, "ikev2_prf_plus;ikev2_derive_sk_keys"),
5515 (1, "eap_ikev2_derive_keymat;eap_ikev2_peer_keymat"),
5516 (1, "os_get_random;ikev2_build_sa_init"),
5517 (2, "os_get_random;ikev2_build_sa_init"),
5518 (1, "ikev2_integ_hash;eap_ikev2_validate_icv"),
5519 (1, "hmac_sha1_vector;?ikev2_prf_hash;ikev2_derive_keys"),
5520 (1, "hmac_sha1_vector;?ikev2_prf_hash;ikev2_derive_auth_data"),
5521 (2, "hmac_sha1_vector;?ikev2_prf_hash;ikev2_derive_auth_data"),
5522 (3, "hmac_sha1_vector;?ikev2_prf_hash;ikev2_derive_auth_data")]
5523 for count, func in tests:
5524 with fail_test(dev[0], count, func):
5525 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5526 eap="IKEV2", identity="ikev2 user",
5527 password="ike password", wait_connect=False)
5528 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
5529 timeout=15)
5530 if ev is None:
5531 raise Exception("Timeout on EAP start")
5532 ok = False
5533 for j in range(10):
5534 state = dev[0].request('GET_FAIL')
5535 if state.startswith('0:'):
5536 ok = True
5537 break
5538 time.sleep(0.1)
5539 if not ok:
5540 raise Exception("No failure seen for %d:%s" % (count, func))
5541 dev[0].request("REMOVE_NETWORK all")
5542 dev[0].wait_disconnected()
5543
5544 params = {"ssid": "eap-test2", "wpa": "2", "wpa_key_mgmt": "WPA-EAP",
5545 "rsn_pairwise": "CCMP", "ieee8021x": "1",
5546 "eap_server": "1", "eap_user_file": "auth_serv/eap_user.conf",
5547 "fragment_size": "50"}
5548 hapd2 = hostapd.add_ap(apdev[1], params)
5549 dev[0].scan_for_bss(hapd2.own_addr(), freq=2412)
5550
5551 tests = [(1, "eap_ikev2_build_frag_ack"),
5552 (1, "wpabuf_alloc;eap_ikev2_process_fragment")]
5553 for count, func in tests:
5554 with alloc_fail(dev[0], count, func):
5555 dev[0].connect("eap-test2", key_mgmt="WPA-EAP", scan_freq="2412",
5556 eap="IKEV2", identity="ikev2 user",
5557 password="ike password", erp="1", wait_connect=False)
5558 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
5559 timeout=15)
5560 if ev is None:
5561 raise Exception("Timeout on EAP start")
5562 ok = False
5563 for j in range(10):
5564 state = dev[0].request('GET_ALLOC_FAIL')
5565 if state.startswith('0:'):
5566 ok = True
5567 break
5568 time.sleep(0.1)
5569 if not ok:
5570 raise Exception("No allocation failure seen for %d:%s" % (count, func))
5571 dev[0].request("REMOVE_NETWORK all")
5572 dev[0].wait_disconnected()
5573
5574 def test_eap_proto_mschapv2(dev, apdev):
5575 """EAP-MSCHAPv2 protocol tests"""
5576 check_eap_capa(dev[0], "MSCHAPV2")
5577
5578 def mschapv2_handler(ctx, req):
5579 logger.info("mschapv2_handler - RX " + binascii.hexlify(req).decode())
5580 if 'num' not in ctx:
5581 ctx['num'] = 0
5582 ctx['num'] = ctx['num'] + 1
5583 if 'id' not in ctx:
5584 ctx['id'] = 1
5585 ctx['id'] = (ctx['id'] + 1) % 256
5586 idx = 0
5587
5588 idx += 1
5589 if ctx['num'] == idx:
5590 logger.info("Test: Missing payload")
5591 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
5592 4 + 1,
5593 EAP_TYPE_MSCHAPV2)
5594
5595 idx += 1
5596 if ctx['num'] == idx:
5597 logger.info("Test: Unknown MSCHAPv2 op_code")
5598 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
5599 4 + 1 + 4 + 1,
5600 EAP_TYPE_MSCHAPV2,
5601 0, 0, 5, 0)
5602
5603 idx += 1
5604 if ctx['num'] == idx:
5605 logger.info("Test: Invalid ms_len and unknown MSCHAPv2 op_code")
5606 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
5607 4 + 1 + 4 + 1,
5608 EAP_TYPE_MSCHAPV2,
5609 255, 0, 0, 0)
5610
5611 idx += 1
5612 if ctx['num'] == idx:
5613 logger.info("Test: Success before challenge")
5614 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
5615 4 + 1 + 4 + 1,
5616 EAP_TYPE_MSCHAPV2,
5617 3, 0, 5, 0)
5618
5619 idx += 1
5620 if ctx['num'] == idx:
5621 logger.info("Test: Failure before challenge - required challenge field not present")
5622 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
5623 4 + 1 + 4 + 1,
5624 EAP_TYPE_MSCHAPV2,
5625 4, 0, 5, 0)
5626 idx += 1
5627 if ctx['num'] == idx:
5628 logger.info("Test: Failure")
5629 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5630
5631 idx += 1
5632 if ctx['num'] == idx:
5633 logger.info("Test: Failure before challenge - invalid failure challenge len")
5634 payload = b'C=12'
5635 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
5636 4 + 1 + 4 + len(payload),
5637 EAP_TYPE_MSCHAPV2,
5638 4, 0, 4 + len(payload)) + payload
5639 idx += 1
5640 if ctx['num'] == idx:
5641 logger.info("Test: Failure")
5642 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5643
5644 idx += 1
5645 if ctx['num'] == idx:
5646 logger.info("Test: Failure before challenge - invalid failure challenge len")
5647 payload = b'C=12 V=3'
5648 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
5649 4 + 1 + 4 + len(payload),
5650 EAP_TYPE_MSCHAPV2,
5651 4, 0, 4 + len(payload)) + payload
5652 idx += 1
5653 if ctx['num'] == idx:
5654 logger.info("Test: Failure")
5655 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5656
5657 idx += 1
5658 if ctx['num'] == idx:
5659 logger.info("Test: Failure before challenge - invalid failure challenge")
5660 payload = b'C=00112233445566778899aabbccddeefQ '
5661 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
5662 4 + 1 + 4 + len(payload),
5663 EAP_TYPE_MSCHAPV2,
5664 4, 0, 4 + len(payload)) + payload
5665 idx += 1
5666 if ctx['num'] == idx:
5667 logger.info("Test: Failure")
5668 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5669
5670 idx += 1
5671 if ctx['num'] == idx:
5672 logger.info("Test: Failure before challenge - password expired")
5673 payload = b'E=648 R=1 C=00112233445566778899aabbccddeeff V=3 M=Password expired'
5674 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
5675 4 + 1 + 4 + len(payload),
5676 EAP_TYPE_MSCHAPV2,
5677 4, 0, 4 + len(payload)) + payload
5678 idx += 1
5679 if ctx['num'] == idx:
5680 logger.info("Test: Success after password change")
5681 payload = b"S=1122334455667788990011223344556677889900"
5682 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
5683 4 + 1 + 4 + len(payload),
5684 EAP_TYPE_MSCHAPV2,
5685 3, 0, 4 + len(payload)) + payload
5686
5687 idx += 1
5688 if ctx['num'] == idx:
5689 logger.info("Test: Invalid challenge length")
5690 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
5691 4 + 1 + 4 + 1,
5692 EAP_TYPE_MSCHAPV2,
5693 1, 0, 4 + 1, 0)
5694
5695 idx += 1
5696 if ctx['num'] == idx:
5697 logger.info("Test: Too short challenge packet")
5698 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
5699 4 + 1 + 4 + 1,
5700 EAP_TYPE_MSCHAPV2,
5701 1, 0, 4 + 1, 16)
5702
5703 idx += 1
5704 if ctx['num'] == idx:
5705 logger.info("Test: Challenge")
5706 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
5707 4 + 1 + 4 + 1 + 16 + 6,
5708 EAP_TYPE_MSCHAPV2,
5709 1, 0, 4 + 1 + 16 + 6, 16) + 16*b'A' + b'foobar'
5710 idx += 1
5711 if ctx['num'] == idx:
5712 logger.info("Test: Failure - password expired")
5713 payload = b'E=648 R=1 C=00112233445566778899aabbccddeeff V=3 M=Password expired'
5714 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
5715 4 + 1 + 4 + len(payload),
5716 EAP_TYPE_MSCHAPV2,
5717 4, 0, 4 + len(payload)) + payload
5718 idx += 1
5719 if ctx['num'] == idx:
5720 logger.info("Test: Success after password change")
5721 if len(req) != 591:
5722 logger.info("Unexpected Change-Password packet length: %s" % len(req))
5723 return None
5724 data = req[9:]
5725 enc_pw = data[0:516]
5726 data = data[516:]
5727 enc_hash = data[0:16]
5728 data = data[16:]
5729 peer_challenge = data[0:16]
5730 data = data[16:]
5731 # Reserved
5732 data = data[8:]
5733 nt_response = data[0:24]
5734 data = data[24:]
5735 flags = data
5736 logger.info("enc_hash: " + binascii.hexlify(enc_hash).decode())
5737 logger.info("peer_challenge: " + binascii.hexlify(peer_challenge).decode())
5738 logger.info("nt_response: " + binascii.hexlify(nt_response).decode())
5739 logger.info("flags: " + binascii.hexlify(flags).decode())
5740
5741 auth_challenge = binascii.unhexlify("00112233445566778899aabbccddeeff")
5742 logger.info("auth_challenge: " + binascii.hexlify(auth_challenge).decode())
5743
5744 auth_resp = GenerateAuthenticatorResponse("new-pw", nt_response,
5745 peer_challenge,
5746 auth_challenge, "user")
5747 payload = b"S=" + binascii.hexlify(auth_resp).decode().upper().encode()
5748 logger.info("Success message payload: " + payload.decode())
5749 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
5750 4 + 1 + 4 + len(payload),
5751 EAP_TYPE_MSCHAPV2,
5752 3, 0, 4 + len(payload)) + payload
5753 idx += 1
5754 if ctx['num'] == idx:
5755 logger.info("Test: EAP-Success")
5756 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4)
5757
5758 idx += 1
5759 if ctx['num'] == idx:
5760 logger.info("Test: Failure - password expired")
5761 payload = b'E=648 R=1 C=00112233445566778899aabbccddeeff V=3 M=Password expired'
5762 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
5763 4 + 1 + 4 + len(payload),
5764 EAP_TYPE_MSCHAPV2,
5765 4, 0, 4 + len(payload)) + payload
5766 idx += 1
5767 if ctx['num'] == idx:
5768 logger.info("Test: Success after password change")
5769 if len(req) != 591:
5770 logger.info("Unexpected Change-Password packet length: %s" % len(req))
5771 return None
5772 data = req[9:]
5773 enc_pw = data[0:516]
5774 data = data[516:]
5775 enc_hash = data[0:16]
5776 data = data[16:]
5777 peer_challenge = data[0:16]
5778 data = data[16:]
5779 # Reserved
5780 data = data[8:]
5781 nt_response = data[0:24]
5782 data = data[24:]
5783 flags = data
5784 logger.info("enc_hash: " + binascii.hexlify(enc_hash).decode())
5785 logger.info("peer_challenge: " + binascii.hexlify(peer_challenge).decode())
5786 logger.info("nt_response: " + binascii.hexlify(nt_response).decode())
5787 logger.info("flags: " + binascii.hexlify(flags).decode())
5788
5789 auth_challenge = binascii.unhexlify("00112233445566778899aabbccddeeff")
5790 logger.info("auth_challenge: " + binascii.hexlify(auth_challenge).decode())
5791
5792 auth_resp = GenerateAuthenticatorResponse("new-pw", nt_response,
5793 peer_challenge,
5794 auth_challenge, "user")
5795 payload = b"S=" + binascii.hexlify(auth_resp).decode().upper().encode()
5796 logger.info("Success message payload: " + payload.decode())
5797 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
5798 4 + 1 + 4 + len(payload),
5799 EAP_TYPE_MSCHAPV2,
5800 3, 0, 4 + len(payload)) + payload
5801 idx += 1
5802 if ctx['num'] == idx:
5803 logger.info("Test: EAP-Success")
5804 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4)
5805
5806 idx += 1
5807 if ctx['num'] == idx:
5808 logger.info("Test: Challenge")
5809 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
5810 4 + 1 + 4 + 1 + 16 + 6,
5811 EAP_TYPE_MSCHAPV2,
5812 1, 0, 4 + 1 + 16 + 6, 16) + 16*b'A' + b'foobar'
5813 idx += 1
5814 if ctx['num'] == idx:
5815 logger.info("Test: Failure - authentication failure")
5816 payload = b'E=691 R=1 C=00112233445566778899aabbccddeeff V=3 M=Authentication failed'
5817 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
5818 4 + 1 + 4 + len(payload),
5819 EAP_TYPE_MSCHAPV2,
5820 4, 0, 4 + len(payload)) + payload
5821
5822 idx += 1
5823 if ctx['num'] == idx:
5824 logger.info("Test: Challenge")
5825 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
5826 4 + 1 + 4 + 1 + 16 + 6,
5827 EAP_TYPE_MSCHAPV2,
5828 1, 0, 4 + 1 + 16 + 6, 16) + 16*b'A' + b'foobar'
5829 idx += 1
5830 if ctx['num'] == idx:
5831 logger.info("Test: Failure - authentication failure")
5832 payload = b'E=691 R=1 C=00112233445566778899aabbccddeeff V=3 M=Authentication failed (2)'
5833 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
5834 4 + 1 + 4 + len(payload),
5835 EAP_TYPE_MSCHAPV2,
5836 4, 0, 4 + len(payload)) + payload
5837 idx += 1
5838 if ctx['num'] == idx:
5839 logger.info("Test: Failure")
5840 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5841
5842 idx += 1
5843 if ctx['num'] == idx:
5844 logger.info("Test: Challenge - invalid ms_len and workaround disabled")
5845 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
5846 4 + 1 + 4 + 1 + 16 + 6,
5847 EAP_TYPE_MSCHAPV2,
5848 1, 0, 4 + 1 + 16 + 6 + 1, 16) + 16*b'A' + b'foobar'
5849
5850 return None
5851
5852 srv = start_radius_server(mschapv2_handler)
5853
5854 try:
5855 hapd = start_ap(apdev[0])
5856 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
5857
5858 for i in range(0, 16):
5859 logger.info("RUN: %d" % i)
5860 if i == 12:
5861 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5862 eap="MSCHAPV2", identity="user",
5863 password_hex="hash:8846f7eaee8fb117ad06bdd830b7586c",
5864 wait_connect=False)
5865 elif i == 14:
5866 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5867 eap="MSCHAPV2", identity="user",
5868 phase2="mschapv2_retry=0",
5869 password="password", wait_connect=False)
5870 elif i == 15:
5871 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5872 eap="MSCHAPV2", identity="user",
5873 eap_workaround="0",
5874 password="password", wait_connect=False)
5875 else:
5876 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5877 eap="MSCHAPV2", identity="user",
5878 password="password", wait_connect=False)
5879 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15)
5880 if ev is None:
5881 raise Exception("Timeout on EAP start")
5882
5883 if i in [8, 11, 12]:
5884 ev = dev[0].wait_event(["CTRL-REQ-NEW_PASSWORD"],
5885 timeout=10)
5886 if ev is None:
5887 raise Exception("Timeout on new password request")
5888 id = ev.split(':')[0].split('-')[-1]
5889 dev[0].request("CTRL-RSP-NEW_PASSWORD-" + id + ":new-pw")
5890 if i in [11, 12]:
5891 ev = dev[0].wait_event(["CTRL-EVENT-PASSWORD-CHANGED"],
5892 timeout=10)
5893 if ev is None:
5894 raise Exception("Timeout on password change")
5895 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"],
5896 timeout=10)
5897 if ev is None:
5898 raise Exception("Timeout on EAP success")
5899 else:
5900 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"],
5901 timeout=10)
5902 if ev is None:
5903 raise Exception("Timeout on EAP failure")
5904
5905 if i in [13]:
5906 ev = dev[0].wait_event(["CTRL-REQ-IDENTITY"],
5907 timeout=10)
5908 if ev is None:
5909 raise Exception("Timeout on identity request")
5910 id = ev.split(':')[0].split('-')[-1]
5911 dev[0].request("CTRL-RSP-IDENTITY-" + id + ":user")
5912
5913 ev = dev[0].wait_event(["CTRL-REQ-PASSWORD"],
5914 timeout=10)
5915 if ev is None:
5916 raise Exception("Timeout on password request")
5917 id = ev.split(':')[0].split('-')[-1]
5918 dev[0].request("CTRL-RSP-PASSWORD-" + id + ":password")
5919
5920 # TODO: Does this work correctly?
5921
5922 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"],
5923 timeout=10)
5924 if ev is None:
5925 raise Exception("Timeout on EAP failure")
5926
5927 if i in [4, 5, 6, 7, 14]:
5928 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"],
5929 timeout=10)
5930 if ev is None:
5931 raise Exception("Timeout on EAP failure")
5932 else:
5933 time.sleep(0.05)
5934 dev[0].request("REMOVE_NETWORK all")
5935 dev[0].wait_disconnected(timeout=1)
5936 finally:
5937 stop_radius_server(srv)
5938
5939 def test_eap_proto_mschapv2_errors(dev, apdev):
5940 """EAP-MSCHAPv2 protocol tests (error paths)"""
5941 check_eap_capa(dev[0], "MSCHAPV2")
5942
5943 def mschapv2_fail_password_expired(ctx):
5944 logger.info("Test: Failure before challenge - password expired")
5945 payload = b'E=648 R=1 C=00112233445566778899aabbccddeeff V=3 M=Password expired'
5946 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
5947 4 + 1 + 4 + len(payload),
5948 EAP_TYPE_MSCHAPV2,
5949 4, 0, 4 + len(payload)) + payload
5950
5951 def mschapv2_success_after_password_change(ctx, req=None):
5952 logger.info("Test: Success after password change")
5953 if req is None or len(req) != 591:
5954 payload = b"S=1122334455667788990011223344556677889900"
5955 else:
5956 data = req[9:]
5957 enc_pw = data[0:516]
5958 data = data[516:]
5959 enc_hash = data[0:16]
5960 data = data[16:]
5961 peer_challenge = data[0:16]
5962 data = data[16:]
5963 # Reserved
5964 data = data[8:]
5965 nt_response = data[0:24]
5966 data = data[24:]
5967 flags = data
5968 logger.info("enc_hash: " + binascii.hexlify(enc_hash).decode())
5969 logger.info("peer_challenge: " + binascii.hexlify(peer_challenge).decode())
5970 logger.info("nt_response: " + binascii.hexlify(nt_response).decode())
5971 logger.info("flags: " + binascii.hexlify(flags).decode())
5972
5973 auth_challenge = binascii.unhexlify("00112233445566778899aabbccddeeff")
5974 logger.info("auth_challenge: " + binascii.hexlify(auth_challenge).decode())
5975
5976 auth_resp = GenerateAuthenticatorResponse("new-pw", nt_response,
5977 peer_challenge,
5978 auth_challenge, "user")
5979 payload = b"S=" + binascii.hexlify(auth_resp).decode().upper().encode()
5980 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
5981 4 + 1 + 4 + len(payload),
5982 EAP_TYPE_MSCHAPV2,
5983 3, 0, 4 + len(payload)) + payload
5984
5985 def mschapv2_handler(ctx, req):
5986 logger.info("mschapv2_handler - RX " + binascii.hexlify(req).decode())
5987 if 'num' not in ctx:
5988 ctx['num'] = 0
5989 ctx['num'] = ctx['num'] + 1
5990 if 'id' not in ctx:
5991 ctx['id'] = 1
5992 ctx['id'] = (ctx['id'] + 1) % 256
5993 idx = 0
5994
5995 idx += 1
5996 if ctx['num'] == idx:
5997 return mschapv2_fail_password_expired(ctx)
5998 idx += 1
5999 if ctx['num'] == idx:
6000 return mschapv2_success_after_password_change(ctx, req)
6001 idx += 1
6002 if ctx['num'] == idx:
6003 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6004
6005 idx += 1
6006 if ctx['num'] == idx:
6007 return mschapv2_fail_password_expired(ctx)
6008 idx += 1
6009 if ctx['num'] == idx:
6010 return mschapv2_success_after_password_change(ctx, req)
6011 idx += 1
6012 if ctx['num'] == idx:
6013 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6014
6015 idx += 1
6016 if ctx['num'] == idx:
6017 return mschapv2_fail_password_expired(ctx)
6018 idx += 1
6019 if ctx['num'] == idx:
6020 return mschapv2_success_after_password_change(ctx, req)
6021 idx += 1
6022 if ctx['num'] == idx:
6023 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6024
6025 idx += 1
6026 if ctx['num'] == idx:
6027 return mschapv2_fail_password_expired(ctx)
6028 idx += 1
6029 if ctx['num'] == idx:
6030 return mschapv2_success_after_password_change(ctx, req)
6031 idx += 1
6032 if ctx['num'] == idx:
6033 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6034
6035 idx += 1
6036 if ctx['num'] == idx:
6037 return mschapv2_fail_password_expired(ctx)
6038 idx += 1
6039 if ctx['num'] == idx:
6040 return mschapv2_success_after_password_change(ctx, req)
6041 idx += 1
6042 if ctx['num'] == idx:
6043 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6044
6045 idx += 1
6046 if ctx['num'] == idx:
6047 return mschapv2_fail_password_expired(ctx)
6048 idx += 1
6049 if ctx['num'] == idx:
6050 return mschapv2_success_after_password_change(ctx, req)
6051 idx += 1
6052 if ctx['num'] == idx:
6053 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6054
6055 idx += 1
6056 if ctx['num'] == idx:
6057 return mschapv2_fail_password_expired(ctx)
6058 idx += 1
6059 if ctx['num'] == idx:
6060 return mschapv2_success_after_password_change(ctx, req)
6061 idx += 1
6062 if ctx['num'] == idx:
6063 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6064
6065 idx += 1
6066 if ctx['num'] == idx:
6067 return mschapv2_fail_password_expired(ctx)
6068 idx += 1
6069 if ctx['num'] == idx:
6070 return mschapv2_success_after_password_change(ctx, req)
6071 idx += 1
6072 if ctx['num'] == idx:
6073 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6074
6075 idx += 1
6076 if ctx['num'] == idx:
6077 return mschapv2_fail_password_expired(ctx)
6078 idx += 1
6079 if ctx['num'] == idx:
6080 return mschapv2_success_after_password_change(ctx, req)
6081 idx += 1
6082 if ctx['num'] == idx:
6083 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6084
6085 return None
6086
6087 srv = start_radius_server(mschapv2_handler)
6088
6089 try:
6090 hapd = start_ap(apdev[0])
6091 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
6092
6093 tests = ["os_get_random;eap_mschapv2_change_password",
6094 "generate_nt_response;eap_mschapv2_change_password",
6095 "get_master_key;eap_mschapv2_change_password",
6096 "nt_password_hash;eap_mschapv2_change_password",
6097 "old_nt_password_hash_encrypted_with_new_nt_password_hash"]
6098 for func in tests:
6099 with fail_test(dev[0], 1, func):
6100 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6101 eap="MSCHAPV2", identity="user",
6102 password="password", wait_connect=False)
6103 ev = dev[0].wait_event(["CTRL-REQ-NEW_PASSWORD"], timeout=10)
6104 if ev is None:
6105 raise Exception("Timeout on new password request")
6106 id = ev.split(':')[0].split('-')[-1]
6107 dev[0].request("CTRL-RSP-NEW_PASSWORD-" + id + ":new-pw")
6108 time.sleep(0.1)
6109 wait_fail_trigger(dev[0], "GET_FAIL")
6110 dev[0].request("REMOVE_NETWORK all")
6111 dev[0].wait_disconnected(timeout=1)
6112
6113 tests = ["encrypt_pw_block_with_password_hash;eap_mschapv2_change_password",
6114 "nt_password_hash;eap_mschapv2_change_password",
6115 "nt_password_hash;eap_mschapv2_success"]
6116 for func in tests:
6117 with fail_test(dev[0], 1, func):
6118 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6119 eap="MSCHAPV2", identity="user",
6120 password_hex="hash:8846f7eaee8fb117ad06bdd830b7586c",
6121 wait_connect=False)
6122 ev = dev[0].wait_event(["CTRL-REQ-NEW_PASSWORD"], timeout=10)
6123 if ev is None:
6124 raise Exception("Timeout on new password request")
6125 id = ev.split(':')[0].split('-')[-1]
6126 dev[0].request("CTRL-RSP-NEW_PASSWORD-" + id + ":new-pw")
6127 time.sleep(0.1)
6128 wait_fail_trigger(dev[0], "GET_FAIL")
6129 dev[0].request("REMOVE_NETWORK all")
6130 dev[0].wait_disconnected(timeout=1)
6131
6132 tests = ["eap_msg_alloc;eap_mschapv2_change_password"]
6133 for func in tests:
6134 with alloc_fail(dev[0], 1, func):
6135 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6136 eap="MSCHAPV2", identity="user",
6137 password="password", wait_connect=False)
6138 ev = dev[0].wait_event(["CTRL-REQ-NEW_PASSWORD"], timeout=10)
6139 if ev is None:
6140 raise Exception("Timeout on new password request")
6141 id = ev.split(':')[0].split('-')[-1]
6142 dev[0].request("CTRL-RSP-NEW_PASSWORD-" + id + ":new-pw")
6143 time.sleep(0.1)
6144 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
6145 dev[0].request("REMOVE_NETWORK all")
6146 dev[0].wait_disconnected(timeout=1)
6147 finally:
6148 stop_radius_server(srv)
6149
6150 def test_eap_proto_pwd(dev, apdev):
6151 """EAP-pwd protocol tests"""
6152 check_eap_capa(dev[0], "PWD")
6153
6154 global eap_proto_pwd_test_done, eap_proto_pwd_test_wait
6155 eap_proto_pwd_test_done = False
6156 eap_proto_pwd_test_wait = False
6157
6158 def pwd_handler(ctx, req):
6159 logger.info("pwd_handler - RX " + binascii.hexlify(req).decode())
6160 if 'num' not in ctx:
6161 ctx['num'] = 0
6162 ctx['num'] = ctx['num'] + 1
6163 if 'id' not in ctx:
6164 ctx['id'] = 1
6165 ctx['id'] = (ctx['id'] + 1) % 256
6166 idx = 0
6167
6168 global eap_proto_pwd_test_wait
6169 eap_proto_pwd_test_wait = False
6170
6171 idx += 1
6172 if ctx['num'] == idx:
6173 logger.info("Test: Missing payload")
6174 # EAP-pwd: Got a frame but pos is not NULL and len is 0
6175 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 4 + 1,
6176 EAP_TYPE_PWD)
6177
6178 idx += 1
6179 if ctx['num'] == idx:
6180 logger.info("Test: Missing Total-Length field")
6181 # EAP-pwd: Frame too short to contain Total-Length field
6182 payload = struct.pack("B", 0x80)
6183 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6184 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6185
6186 idx += 1
6187 if ctx['num'] == idx:
6188 logger.info("Test: Too large Total-Length")
6189 # EAP-pwd: Incoming fragments whose total length = 65535
6190 payload = struct.pack(">BH", 0x80, 65535)
6191 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6192 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6193
6194 idx += 1
6195 if ctx['num'] == idx:
6196 eap_proto_pwd_test_wait = True
6197 logger.info("Test: First fragment")
6198 # EAP-pwd: Incoming fragments whose total length = 10
6199 # EAP-pwd: ACKing a 0 byte fragment
6200 payload = struct.pack(">BH", 0xc0, 10)
6201 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6202 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6203 idx += 1
6204 if ctx['num'] == idx:
6205 logger.info("Test: Unexpected Total-Length value in the second fragment")
6206 # EAP-pwd: Incoming fragments whose total length = 0
6207 # EAP-pwd: Unexpected new fragment start when previous fragment is still in use
6208 payload = struct.pack(">BH", 0x80, 0)
6209 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6210 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6211
6212 idx += 1
6213 if ctx['num'] == idx:
6214 logger.info("Test: First and only fragment")
6215 # EAP-pwd: Incoming fragments whose total length = 0
6216 # EAP-pwd: processing frame: exch 0, len 0
6217 # EAP-pwd: Ignoring message with unknown opcode 128
6218 payload = struct.pack(">BH", 0x80, 0)
6219 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6220 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6221
6222 idx += 1
6223 if ctx['num'] == idx:
6224 logger.info("Test: First and only fragment with extra data")
6225 # EAP-pwd: Incoming fragments whose total length = 0
6226 # EAP-pwd: processing frame: exch 0, len 1
6227 # EAP-pwd: Ignoring message with unknown opcode 128
6228 payload = struct.pack(">BHB", 0x80, 0, 0)
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: First fragment")
6236 # EAP-pwd: Incoming fragments whose total length = 2
6237 # EAP-pwd: ACKing a 1 byte fragment
6238 payload = struct.pack(">BHB", 0xc0, 2, 1)
6239 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6240 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6241 idx += 1
6242 if ctx['num'] == idx:
6243 logger.info("Test: Extra data in the second fragment")
6244 # EAP-pwd: Buffer overflow attack detected (3 vs. 1)!
6245 payload = struct.pack(">BBB", 0x0, 2, 3)
6246 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6247 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6248
6249 idx += 1
6250 if ctx['num'] == idx:
6251 logger.info("Test: Too short id exchange")
6252 # EAP-pwd: processing frame: exch 1, len 0
6253 # EAP-PWD: PWD-ID-Req -> FAILURE
6254 payload = struct.pack(">B", 0x01)
6255 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6256 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6257
6258 idx += 1
6259 if ctx['num'] == idx:
6260 logger.info("Test: Unsupported rand func in id exchange")
6261 # EAP-PWD: Server EAP-pwd-ID proposal: group=0 random=0 prf=0 prep=0
6262 # EAP-PWD: PWD-ID-Req -> FAILURE
6263 payload = struct.pack(">BHBBLB", 0x01, 0, 0, 0, 0, 0)
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 logger.info("Test: Unsupported prf in id exchange")
6270 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=0 prep=0
6271 # EAP-PWD: PWD-ID-Req -> FAILURE
6272 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 0, 0, 0)
6273 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6274 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6275
6276 idx += 1
6277 if ctx['num'] == idx:
6278 logger.info("Test: Unsupported password pre-processing technique in id exchange")
6279 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=255
6280 # EAP-PWD: Unsupported password pre-processing technique (Prep=255)
6281 # EAP-PWD: PWD-ID-Req -> FAILURE
6282 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 255)
6283 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6284 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6285
6286 idx += 1
6287 if ctx['num'] == idx:
6288 eap_proto_pwd_test_wait = True
6289 logger.info("Test: Valid id exchange")
6290 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=0
6291 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0)
6292 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6293 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6294 idx += 1
6295 if ctx['num'] == idx:
6296 logger.info("Test: Unexpected id exchange")
6297 # EAP-pwd: processing frame: exch 1, len 9
6298 # EAP-PWD: PWD-Commit-Req -> FAILURE
6299 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0)
6300 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6301 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6302
6303 idx += 1
6304 if ctx['num'] == idx:
6305 logger.info("Test: Unexpected commit exchange")
6306 # EAP-pwd: processing frame: exch 2, len 0
6307 # EAP-PWD: PWD-ID-Req -> FAILURE
6308 payload = struct.pack(">B", 0x02)
6309 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6310 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6311
6312 idx += 1
6313 if ctx['num'] == idx:
6314 eap_proto_pwd_test_wait = True
6315 logger.info("Test: Valid id exchange")
6316 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=0
6317 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0)
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: Unexpected Commit payload length (prep=None)")
6323 # EAP-pwd commit request, password prep is NONE
6324 # EAP-pwd: Unexpected Commit payload length 0 (expected 96)
6325 payload = struct.pack(">B", 0x02)
6326 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6327 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6328
6329 idx += 1
6330 if ctx['num'] == idx:
6331 eap_proto_pwd_test_wait = True
6332 logger.info("Test: Valid id exchange")
6333 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=0
6334 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0)
6335 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6336 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6337 idx += 1
6338 if ctx['num'] == idx:
6339 logger.info("Test: Commit payload with all zeros values --> Shared key at infinity")
6340 # EAP-pwd: Invalid coordinate in element
6341 payload = struct.pack(">B", 0x02) + 96*b'\0'
6342 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6343 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6344
6345 idx += 1
6346 if ctx['num'] == idx:
6347 eap_proto_pwd_test_wait = True
6348 logger.info("Test: Valid id exchange")
6349 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=0
6350 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0)
6351 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6352 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6353 idx += 1
6354 if ctx['num'] == idx:
6355 eap_proto_pwd_test_wait = True
6356 logger.info("Test: Commit payload with valid values")
6357 # EAP-pwd commit request, password prep is NONE
6358 element = binascii.unhexlify("8dcab2862c5396839a6bac0c689ff03d962863108e7c275bbf1d6eedf634ee832a214db99f0d0a1a6317733eecdd97f0fc4cda19f57e1bb9bb9c8dcf8c60ba6f")
6359 scalar = binascii.unhexlify("450f31e058cf2ac2636a5d6e2b3c70b1fcc301957f0716e77f13aa69f9a2e5bd")
6360 payload = struct.pack(">B", 0x02) + element + scalar
6361 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6362 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6363 idx += 1
6364 if ctx['num'] == idx:
6365 logger.info("Test: Unexpected Confirm payload length 0")
6366 # EAP-pwd: Unexpected Confirm payload length 0 (expected 32)
6367 payload = struct.pack(">B", 0x03)
6368 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6369 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6370
6371 idx += 1
6372 if ctx['num'] == idx:
6373 eap_proto_pwd_test_wait = True
6374 logger.info("Test: Valid id exchange")
6375 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=0
6376 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0)
6377 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6378 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6379 idx += 1
6380 if ctx['num'] == idx:
6381 eap_proto_pwd_test_wait = True
6382 logger.info("Test: Commit payload with valid values")
6383 # EAP-pwd commit request, password prep is NONE
6384 element = binascii.unhexlify("8dcab2862c5396839a6bac0c689ff03d962863108e7c275bbf1d6eedf634ee832a214db99f0d0a1a6317733eecdd97f0fc4cda19f57e1bb9bb9c8dcf8c60ba6f")
6385 scalar = binascii.unhexlify("450f31e058cf2ac2636a5d6e2b3c70b1fcc301957f0716e77f13aa69f9a2e5bd")
6386 payload = struct.pack(">B", 0x02) + element + scalar
6387 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6388 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6389 idx += 1
6390 if ctx['num'] == idx:
6391 logger.info("Test: Confirm payload with incorrect value")
6392 # EAP-PWD (peer): confirm did not verify
6393 payload = struct.pack(">B", 0x03) + 32*b'\0'
6394 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6395 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6396
6397 idx += 1
6398 if ctx['num'] == idx:
6399 logger.info("Test: Unexpected confirm exchange")
6400 # EAP-pwd: processing frame: exch 3, len 0
6401 # EAP-PWD: PWD-ID-Req -> FAILURE
6402 payload = struct.pack(">B", 0x03)
6403 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6404 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6405
6406 idx += 1
6407 if ctx['num'] == idx:
6408 logger.info("Test: Unsupported password pre-processing technique SASLprep in id exchange")
6409 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=2
6410 # EAP-PWD: Unsupported password pre-processing technique (Prep=2)
6411 # EAP-PWD: PWD-ID-Req -> FAILURE
6412 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 2)
6413 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6414 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6415
6416 idx += 1
6417 if ctx['num'] == idx:
6418 eap_proto_pwd_test_wait = True
6419 logger.info("Test: Valid id exchange")
6420 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=1
6421 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 1)
6422 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6423 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6424 idx += 1
6425 if ctx['num'] == idx:
6426 logger.info("Test: Unexpected Commit payload length (prep=MS)")
6427 # EAP-pwd commit request, password prep is MS
6428 # EAP-pwd: Unexpected Commit payload length 0 (expected 96)
6429 payload = struct.pack(">B", 0x02)
6430 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6431 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6432
6433 idx += 1
6434 if ctx['num'] == idx:
6435 eap_proto_pwd_test_wait = True
6436 logger.info("Test: Valid id exchange")
6437 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=3
6438 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 3)
6439 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6440 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6441 idx += 1
6442 if ctx['num'] == idx:
6443 logger.info("Test: Unexpected Commit payload length (prep=ssha1)")
6444 # EAP-pwd commit request, password prep is salted sha1
6445 # EAP-pwd: Invalid Salt-len
6446 payload = struct.pack(">B", 0x02)
6447 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6448 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6449
6450 idx += 1
6451 if ctx['num'] == idx:
6452 eap_proto_pwd_test_wait = True
6453 logger.info("Test: Valid id exchange")
6454 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=3
6455 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 3)
6456 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6457 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6458 idx += 1
6459 if ctx['num'] == idx:
6460 logger.info("Test: Unexpected Commit payload length (prep=ssha1)")
6461 # EAP-pwd commit request, password prep is salted sha1
6462 # EAP-pwd: Invalid Salt-len
6463 payload = struct.pack(">BB", 0x02, 0)
6464 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6465 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6466
6467 idx += 1
6468 if ctx['num'] == idx:
6469 eap_proto_pwd_test_wait = True
6470 logger.info("Test: Valid id exchange")
6471 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=3
6472 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 3)
6473 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6474 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6475 idx += 1
6476 if ctx['num'] == idx:
6477 logger.info("Test: Unexpected Commit payload length (prep=ssha1)")
6478 # EAP-pwd commit request, password prep is salted sha1
6479 # EAP-pwd: Unexpected Commit payload length 1 (expected 98)
6480 payload = struct.pack(">BB", 0x02, 1)
6481 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6482 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6483
6484 idx += 1
6485 if ctx['num'] == idx:
6486 eap_proto_pwd_test_wait = True
6487 logger.info("Test: Valid id exchange")
6488 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=4
6489 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 4)
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("Test: Unexpected Commit payload length (prep=ssha256)")
6495 # EAP-pwd commit request, password prep is salted sha256
6496 # EAP-pwd: Invalid Salt-len
6497 payload = struct.pack(">B", 0x02)
6498 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6499 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6500
6501 idx += 1
6502 if ctx['num'] == idx:
6503 eap_proto_pwd_test_wait = True
6504 logger.info("Test: Valid id exchange")
6505 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=4
6506 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 4)
6507 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6508 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6509 idx += 1
6510 if ctx['num'] == idx:
6511 logger.info("Test: Unexpected Commit payload length (prep=ssha256)")
6512 # EAP-pwd commit request, password prep is salted sha256
6513 # EAP-pwd: Invalid Salt-len
6514 payload = struct.pack(">BB", 0x02, 0)
6515 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6516 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6517
6518 idx += 1
6519 if ctx['num'] == idx:
6520 eap_proto_pwd_test_wait = True
6521 logger.info("Test: Valid id exchange")
6522 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=4
6523 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 4)
6524 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6525 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6526 idx += 1
6527 if ctx['num'] == idx:
6528 logger.info("Test: Unexpected Commit payload length (prep=ssha256)")
6529 # EAP-pwd commit request, password prep is salted sha256
6530 # EAP-pwd: Unexpected Commit payload length 1 (expected 98)
6531 payload = struct.pack(">BB", 0x02, 1)
6532 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6533 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6534
6535 idx += 1
6536 if ctx['num'] == idx:
6537 eap_proto_pwd_test_wait = True
6538 logger.info("Test: Valid id exchange")
6539 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=5
6540 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 5)
6541 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6542 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6543 idx += 1
6544 if ctx['num'] == idx:
6545 logger.info("Test: Unexpected Commit payload length (prep=ssha512)")
6546 # EAP-pwd commit request, password prep is salted sha512
6547 # EAP-pwd: Invalid Salt-len
6548 payload = struct.pack(">B", 0x02)
6549 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6550 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6551
6552 idx += 1
6553 if ctx['num'] == idx:
6554 eap_proto_pwd_test_wait = True
6555 logger.info("Test: Valid id exchange")
6556 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=5
6557 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 5)
6558 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6559 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6560 idx += 1
6561 if ctx['num'] == idx:
6562 logger.info("Test: Unexpected Commit payload length (prep=ssha512)")
6563 # EAP-pwd commit request, password prep is salted sha512
6564 # EAP-pwd: Invalid Salt-len
6565 payload = struct.pack(">BB", 0x02, 0)
6566 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6567 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6568
6569 idx += 1
6570 if ctx['num'] == idx:
6571 eap_proto_pwd_test_wait = True
6572 logger.info("Test: Valid id exchange")
6573 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=5
6574 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 5)
6575 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6576 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6577 idx += 1
6578 if ctx['num'] == idx:
6579 logger.info("Test: Unexpected Commit payload length (prep=ssha512)")
6580 # EAP-pwd commit request, password prep is salted sha512
6581 # EAP-pwd: Unexpected Commit payload length 1 (expected 98)
6582 payload = struct.pack(">BB", 0x02, 1)
6583 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6584 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6585
6586 logger.info("No more test responses available - test case completed")
6587 global eap_proto_pwd_test_done
6588 eap_proto_pwd_test_done = True
6589 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6590
6591 srv = start_radius_server(pwd_handler)
6592
6593 try:
6594 hapd = start_ap(apdev[0])
6595 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
6596
6597 i = 0
6598 while not eap_proto_pwd_test_done:
6599 i += 1
6600 logger.info("Running connection iteration %d" % i)
6601 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6602 eap="PWD", identity="pwd user",
6603 password="secret password",
6604 wait_connect=False)
6605 ok = False
6606 for j in range(5):
6607 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STATUS",
6608 "CTRL-EVENT-EAP-PROPOSED-METHOD"],
6609 timeout=5)
6610 if ev is None:
6611 raise Exception("Timeout on EAP start")
6612 if "CTRL-EVENT-EAP-PROPOSED-METHOD" in ev:
6613 ok = True
6614 break
6615 if "CTRL-EVENT-EAP-STATUS" in ev and "status='completion' parameter='failure'" in ev:
6616 ok = True
6617 break
6618 if not ok:
6619 raise Exception("Expected EAP event not seen")
6620 if eap_proto_pwd_test_wait:
6621 for k in range(20):
6622 time.sleep(0.1)
6623 if not eap_proto_pwd_test_wait:
6624 break
6625 if eap_proto_pwd_test_wait:
6626 raise Exception("eap_proto_pwd_test_wait not cleared")
6627 dev[0].request("REMOVE_NETWORK all")
6628 dev[0].wait_disconnected(timeout=1)
6629 dev[0].dump_monitor()
6630 finally:
6631 stop_radius_server(srv)
6632
6633 def test_eap_proto_pwd_invalid_scalar(dev, apdev):
6634 """EAP-pwd protocol tests - invalid server scalar"""
6635 check_eap_capa(dev[0], "PWD")
6636 run_eap_proto_pwd_invalid_scalar(dev, apdev, 32*b'\0')
6637 run_eap_proto_pwd_invalid_scalar(dev, apdev, 31*b'\0' + b'\x01')
6638 # Group Order
6639 val = binascii.unhexlify("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551")
6640 run_eap_proto_pwd_invalid_scalar(dev, apdev, val)
6641 # Group Order - 1
6642 val = binascii.unhexlify("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632550")
6643 run_eap_proto_pwd_invalid_scalar(dev, apdev, val, valid_scalar=True)
6644
6645 def run_eap_proto_pwd_invalid_scalar(dev, apdev, scalar, valid_scalar=False):
6646 global eap_proto_pwd_invalid_scalar_fail
6647 eap_proto_pwd_invalid_scalar_fail = False
6648
6649 def pwd_handler(ctx, req):
6650 logger.info("pwd_handler - RX " + binascii.hexlify(req).decode())
6651 if 'num' not in ctx:
6652 ctx['num'] = 0
6653 ctx['num'] = ctx['num'] + 1
6654 if 'id' not in ctx:
6655 ctx['id'] = 1
6656 ctx['id'] = (ctx['id'] + 1) % 256
6657 idx = 0
6658
6659 idx += 1
6660 if ctx['num'] == idx:
6661 logger.info("Test: Valid id exchange")
6662 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0)
6663 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6664 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6665 idx += 1
6666 if ctx['num'] == idx:
6667 logger.info("Test: Commit payload with invalid scalar")
6668 payload = struct.pack(">B", 0x02) + binascii.unhexlify("67feb2b46d59e6dd3af3a429ec9c04a949337564615d3a2c19bdf6826eb6f5efa303aed86af3a072ed819d518d620adb2659f0e84c4f8b739629db8c93088cfc") + scalar
6669 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6670 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6671 idx += 1
6672 if ctx['num'] == idx:
6673 logger.info("Confirm message next - should not get here")
6674 global eap_proto_pwd_invalid_scalar_fail
6675 eap_proto_pwd_invalid_scalar_fail = True
6676 payload = struct.pack(">B", 0x03) + 32*b'\0'
6677 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6678 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6679
6680 logger.info("No more test responses available - test case completed")
6681 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6682
6683 srv = start_radius_server(pwd_handler)
6684
6685 try:
6686 hapd = start_ap(apdev[0])
6687 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
6688
6689 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6690 eap="PWD", identity="pwd user",
6691 password="secret password",
6692 wait_connect=False)
6693 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
6694 if ev is None:
6695 raise Exception("EAP failure not reported")
6696 dev[0].request("REMOVE_NETWORK all")
6697 dev[0].wait_disconnected(timeout=1)
6698 dev[0].dump_monitor()
6699 finally:
6700 stop_radius_server(srv)
6701
6702 if valid_scalar and not eap_proto_pwd_invalid_scalar_fail:
6703 raise Exception("Peer did not accept valid EAP-pwd-Commit scalar")
6704 if not valid_scalar and eap_proto_pwd_invalid_scalar_fail:
6705 raise Exception("Peer did not stop after invalid EAP-pwd-Commit scalar")
6706
6707 def test_eap_proto_pwd_invalid_element(dev, apdev):
6708 """EAP-pwd protocol tests - invalid server element"""
6709 check_eap_capa(dev[0], "PWD")
6710 # Invalid x,y coordinates
6711 run_eap_proto_pwd_invalid_element(dev, apdev, 64*b'\x00')
6712 run_eap_proto_pwd_invalid_element(dev, apdev, 32*b'\x00' + 32*b'\x01')
6713 run_eap_proto_pwd_invalid_element(dev, apdev, 32*b'\x01' + 32*b'\x00')
6714 run_eap_proto_pwd_invalid_element(dev, apdev, 32*b'\xff' + 32*b'\x01')
6715 run_eap_proto_pwd_invalid_element(dev, apdev, 32*b'\x01' + 32*b'\xff')
6716 run_eap_proto_pwd_invalid_element(dev, apdev, 64*b'\xff')
6717 # Not on curve
6718 run_eap_proto_pwd_invalid_element(dev, apdev, 64*b'\x01')
6719
6720 def run_eap_proto_pwd_invalid_element(dev, apdev, element):
6721 global eap_proto_pwd_invalid_element_fail
6722 eap_proto_pwd_invalid_element_fail = False
6723
6724 def pwd_handler(ctx, req):
6725 logger.info("pwd_handler - RX " + binascii.hexlify(req).decode())
6726 if 'num' not in ctx:
6727 ctx['num'] = 0
6728 ctx['num'] = ctx['num'] + 1
6729 if 'id' not in ctx:
6730 ctx['id'] = 1
6731 ctx['id'] = (ctx['id'] + 1) % 256
6732 idx = 0
6733
6734 idx += 1
6735 if ctx['num'] == idx:
6736 logger.info("Test: Valid id exchange")
6737 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0)
6738 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6739 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6740 idx += 1
6741 if ctx['num'] == idx:
6742 logger.info("Test: Commit payload with invalid element")
6743 payload = struct.pack(">B", 0x02) + element + 31*b'\0' + b'\x02'
6744 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6745 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6746 idx += 1
6747 if ctx['num'] == idx:
6748 logger.info("Confirm message next - should not get here")
6749 global eap_proto_pwd_invalid_element_fail
6750 eap_proto_pwd_invalid_element_fail = True
6751 payload = struct.pack(">B", 0x03) + 32*b'\0'
6752 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6753 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
6754
6755 logger.info("No more test responses available - test case completed")
6756 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6757
6758 srv = start_radius_server(pwd_handler)
6759
6760 try:
6761 hapd = start_ap(apdev[0])
6762 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
6763
6764 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6765 eap="PWD", identity="pwd user",
6766 password="secret password",
6767 wait_connect=False)
6768 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
6769 if ev is None:
6770 raise Exception("EAP failure not reported")
6771 dev[0].request("REMOVE_NETWORK all")
6772 dev[0].wait_disconnected(timeout=1)
6773 dev[0].dump_monitor()
6774 finally:
6775 stop_radius_server(srv)
6776
6777 if eap_proto_pwd_invalid_element_fail:
6778 raise Exception("Peer did not stop after invalid EAP-pwd-Commit element")
6779
6780 def rx_msg(src):
6781 ev = src.wait_event(["EAPOL-TX"], timeout=5)
6782 if ev is None:
6783 raise Exception("No EAPOL-TX")
6784 return ev.split(' ')[2]
6785
6786 def tx_msg(src, dst, msg):
6787 dst.request("EAPOL_RX " + src.own_addr() + " " + msg)
6788
6789 def proxy_msg(src, dst):
6790 msg = rx_msg(src)
6791 tx_msg(src, dst, msg)
6792 return msg
6793
6794 def start_pwd_exchange(dev, ap):
6795 check_eap_capa(dev, "PWD")
6796 params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap")
6797 hapd = hostapd.add_ap(ap, params)
6798 hapd.request("SET ext_eapol_frame_io 1")
6799 dev.request("SET ext_eapol_frame_io 1")
6800 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP",
6801 eap="PWD", identity="pwd user", password="secret password",
6802 wait_connect=False, scan_freq="2412")
6803 proxy_msg(hapd, dev) # EAP-Identity/Request
6804 proxy_msg(dev, hapd) # EAP-Identity/Response
6805 proxy_msg(hapd, dev) # EAP-pwd-ID/Request
6806 proxy_msg(dev, hapd) # EAP-pwd-ID/Response
6807 return hapd
6808
6809 def test_eap_proto_pwd_reflection_attack(dev, apdev):
6810 """EAP-pwd protocol tests - reflection attack on the server"""
6811 hapd = start_pwd_exchange(dev[0], apdev[0])
6812
6813 # EAP-pwd-Commit/Request
6814 req = proxy_msg(hapd, dev[0])
6815 if len(req) != 212:
6816 raise Exception("Unexpected EAP-pwd-Commit/Response length")
6817
6818 # EAP-pwd-Commit/Response
6819 resp = rx_msg(dev[0])
6820 # Reflect same Element/Scalar back to the server
6821 msg = resp[0:20] + req[20:]
6822 tx_msg(dev[0], hapd, msg)
6823
6824 # EAP-pwd-Commit/Response or EAP-Failure
6825 req = rx_msg(hapd)
6826 if req[8:10] != "04":
6827 # reflect EAP-pwd-Confirm/Request
6828 msg = req[0:8] + "02" + req[10:]
6829 tx_msg(dev[0], hapd, msg)
6830 req = rx_msg(hapd)
6831 if req[8:10] == "03":
6832 raise Exception("EAP-Success after reflected Element/Scalar")
6833 raise Exception("No EAP-Failure to reject invalid EAP-pwd-Commit/Response")
6834
6835 def test_eap_proto_pwd_invalid_scalar_peer(dev, apdev):
6836 """EAP-pwd protocol tests - invalid peer scalar"""
6837 run_eap_proto_pwd_invalid_scalar_peer(dev, apdev, 32*"00")
6838 run_eap_proto_pwd_invalid_scalar_peer(dev, apdev, 31*"00" + "01")
6839 # Group Order
6840 run_eap_proto_pwd_invalid_scalar_peer(dev, apdev,
6841 "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551")
6842 # Group Order - 1
6843 run_eap_proto_pwd_invalid_scalar_peer(dev, apdev,
6844 "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632550",
6845 valid_scalar=True)
6846
6847 def run_eap_proto_pwd_invalid_scalar_peer(dev, apdev, scalar,
6848 valid_scalar=False):
6849 hapd = start_pwd_exchange(dev[0], apdev[0])
6850 proxy_msg(hapd, dev[0]) # EAP-pwd-Commit/Request
6851
6852 # EAP-pwd-Commit/Response
6853 resp = rx_msg(dev[0])
6854 # Replace scalar with an invalid value
6855 msg = resp[0:20] + resp[20:148] + scalar
6856 tx_msg(dev[0], hapd, msg)
6857
6858 # EAP-pwd-Commit/Response or EAP-Failure
6859 req = rx_msg(hapd)
6860 if valid_scalar and req[8:10] == "04":
6861 raise Exception("Unexpected EAP-Failure with valid scalar")
6862 if not valid_scalar and req[8:10] != "04":
6863 raise Exception("No EAP-Failure to reject invalid scalar")
6864 dev[0].request("REMOVE_NETWORK all")
6865 dev[0].wait_disconnected(timeout=1)
6866 hapd.disable()
6867
6868 def test_eap_proto_pwd_invalid_element_peer(dev, apdev):
6869 """EAP-pwd protocol tests - invalid peer element"""
6870 # Invalid x,y coordinates
6871 run_eap_proto_pwd_invalid_element_peer(dev, apdev, 64*'00')
6872 run_eap_proto_pwd_invalid_element_peer(dev, apdev, 32*'00' + 32*'01')
6873 run_eap_proto_pwd_invalid_element_peer(dev, apdev, 32*'01' + 32*'00')
6874 run_eap_proto_pwd_invalid_element_peer(dev, apdev, 32*'ff' + 32*'01')
6875 run_eap_proto_pwd_invalid_element_peer(dev, apdev, 32*'01' + 32*'ff')
6876 run_eap_proto_pwd_invalid_element_peer(dev, apdev, 64*'ff')
6877 # Not on curve
6878 run_eap_proto_pwd_invalid_element_peer(dev, apdev, 64*'01')
6879
6880 def run_eap_proto_pwd_invalid_element_peer(dev, apdev, element):
6881 hapd = start_pwd_exchange(dev[0], apdev[0])
6882 proxy_msg(hapd, dev[0]) # EAP-pwd-Commit/Request
6883
6884 # EAP-pwd-Commit/Response
6885 resp = rx_msg(dev[0])
6886 # Replace element with an invalid value
6887 msg = resp[0:20] + element + resp[148:]
6888 tx_msg(dev[0], hapd, msg)
6889
6890 # EAP-pwd-Commit/Response or EAP-Failure
6891 req = rx_msg(hapd)
6892 if req[8:10] != "04":
6893 raise Exception("No EAP-Failure to reject invalid element")
6894 dev[0].request("REMOVE_NETWORK all")
6895 dev[0].wait_disconnected(timeout=1)
6896 hapd.disable()
6897
6898 def test_eap_proto_pwd_errors(dev, apdev):
6899 """EAP-pwd local error cases"""
6900 check_eap_capa(dev[0], "PWD")
6901 params = hostapd.wpa2_eap_params(ssid="eap-test")
6902 hapd = hostapd.add_ap(apdev[0], params)
6903 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
6904
6905 for i in range(1, 4):
6906 with alloc_fail(dev[0], i, "eap_pwd_init"):
6907 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6908 eap="PWD", identity="pwd user",
6909 password="secret password",
6910 wait_connect=False)
6911 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
6912 timeout=15)
6913 if ev is None:
6914 raise Exception("Timeout on EAP start")
6915 dev[0].request("REMOVE_NETWORK all")
6916 dev[0].wait_disconnected()
6917
6918 with alloc_fail(dev[0], 1, "eap_pwd_get_session_id"):
6919 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6920 eap="PWD", identity="pwd user",
6921 fragment_size="0",
6922 password="secret password")
6923 dev[0].request("REMOVE_NETWORK all")
6924 dev[0].wait_disconnected()
6925
6926 funcs = ["eap_pwd_getkey", "eap_pwd_get_emsk",
6927 "=wpabuf_alloc;eap_pwd_perform_commit_exchange",
6928 "=wpabuf_alloc;eap_pwd_perform_confirm_exchange"]
6929 for func in funcs:
6930 with alloc_fail(dev[0], 1, func):
6931 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6932 eap="PWD", identity="pwd user@domain",
6933 password="secret password", erp="1",
6934 wait_connect=False)
6935 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
6936 dev[0].request("REMOVE_NETWORK all")
6937 dev[0].wait_disconnected()
6938
6939 for i in range(1, 5):
6940 with alloc_fail(dev[0], i, "eap_pwd_perform_id_exchange"):
6941 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6942 eap="PWD", identity="pwd user",
6943 password="secret password",
6944 wait_connect=False)
6945 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
6946 timeout=15)
6947 if ev is None:
6948 raise Exception("Timeout on EAP start")
6949 ok = False
6950 for j in range(10):
6951 state = dev[0].request('GET_ALLOC_FAIL')
6952 if state.startswith('0:'):
6953 ok = True
6954 break
6955 time.sleep(0.1)
6956 if not ok:
6957 raise Exception("No allocation failure seen")
6958 dev[0].request("REMOVE_NETWORK all")
6959 dev[0].wait_disconnected()
6960
6961 with alloc_fail(dev[0], 1, "wpabuf_alloc;eap_pwd_perform_id_exchange"):
6962 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6963 eap="PWD", identity="pwd user",
6964 password="secret password",
6965 wait_connect=False)
6966 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
6967 timeout=15)
6968 if ev is None:
6969 raise Exception("Timeout on EAP start")
6970 dev[0].request("REMOVE_NETWORK all")
6971 dev[0].wait_disconnected()
6972
6973 for i in range(1, 9):
6974 with alloc_fail(dev[0], i, "eap_pwd_perform_commit_exchange"):
6975 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6976 eap="PWD", identity="pwd user",
6977 password="secret password",
6978 wait_connect=False)
6979 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
6980 timeout=15)
6981 if ev is None:
6982 raise Exception("Timeout on EAP start")
6983 ok = False
6984 for j in range(10):
6985 state = dev[0].request('GET_ALLOC_FAIL')
6986 if state.startswith('0:'):
6987 ok = True
6988 break
6989 time.sleep(0.1)
6990 if not ok:
6991 raise Exception("No allocation failure seen")
6992 dev[0].request("REMOVE_NETWORK all")
6993 dev[0].wait_disconnected()
6994
6995 for i in range(1, 12):
6996 with alloc_fail(dev[0], i, "eap_pwd_perform_confirm_exchange"):
6997 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6998 eap="PWD", identity="pwd user",
6999 password="secret password",
7000 wait_connect=False)
7001 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
7002 timeout=15)
7003 if ev is None:
7004 raise Exception("Timeout on EAP start")
7005 ok = False
7006 for j in range(10):
7007 state = dev[0].request('GET_ALLOC_FAIL')
7008 if state.startswith('0:'):
7009 ok = True
7010 break
7011 time.sleep(0.1)
7012 if not ok:
7013 raise Exception("No allocation failure seen")
7014 dev[0].request("REMOVE_NETWORK all")
7015 dev[0].wait_disconnected()
7016
7017 for i in range(1, 5):
7018 with alloc_fail(dev[0], i, "eap_msg_alloc;=eap_pwd_process"):
7019 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7020 eap="PWD", identity="pwd user",
7021 password="secret password", fragment_size="50",
7022 wait_connect=False)
7023 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
7024 timeout=15)
7025 if ev is None:
7026 raise Exception("Timeout on EAP start")
7027 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
7028 dev[0].request("REMOVE_NETWORK all")
7029 dev[0].wait_disconnected()
7030
7031 # No password configured
7032 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7033 eap="PWD", identity="pwd user",
7034 wait_connect=False)
7035 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD vendor=0 method=52"],
7036 timeout=15)
7037 if ev is None:
7038 raise Exception("EAP-pwd not started")
7039 dev[0].request("REMOVE_NETWORK all")
7040 dev[0].wait_disconnected()
7041
7042 funcs = [(1, "hash_nt_password_hash;eap_pwd_perform_commit_exchange"),
7043 (1, "=crypto_bignum_init;eap_pwd_perform_commit_exchange"),
7044 (1, "=crypto_ec_point_init;eap_pwd_perform_commit_exchange"),
7045 (2, "=crypto_ec_point_init;eap_pwd_perform_commit_exchange"),
7046 (1, "=crypto_ec_point_mul;eap_pwd_perform_commit_exchange"),
7047 (2, "=crypto_ec_point_mul;eap_pwd_perform_commit_exchange"),
7048 (3, "=crypto_ec_point_mul;eap_pwd_perform_commit_exchange"),
7049 (1, "=crypto_ec_point_add;eap_pwd_perform_commit_exchange"),
7050 (1, "=crypto_ec_point_invert;eap_pwd_perform_commit_exchange"),
7051 (1, "=crypto_ec_point_to_bin;eap_pwd_perform_commit_exchange"),
7052 (1, "crypto_hash_finish;eap_pwd_kdf"),
7053 (1, "crypto_ec_point_from_bin;eap_pwd_get_element"),
7054 (3, "crypto_bignum_init;compute_password_element"),
7055 (4, "crypto_bignum_init;compute_password_element"),
7056 (1, "crypto_bignum_init_set;compute_password_element"),
7057 (2, "crypto_bignum_init_set;compute_password_element"),
7058 (3, "crypto_bignum_init_set;compute_password_element"),
7059 (1, "crypto_bignum_to_bin;compute_password_element"),
7060 (1, "crypto_ec_point_compute_y_sqr;compute_password_element"),
7061 (1, "crypto_ec_point_solve_y_coord;compute_password_element"),
7062 (1, "crypto_bignum_rand;compute_password_element"),
7063 (1, "crypto_bignum_sub;compute_password_element")]
7064 for count, func in funcs:
7065 with fail_test(dev[0], count, func):
7066 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7067 eap="PWD", identity="pwd-hash",
7068 password_hex="hash:e3718ece8ab74792cbbfffd316d2d19a",
7069 wait_connect=False)
7070 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
7071 if ev is None:
7072 raise Exception("No EAP-Failure reported")
7073 dev[0].request("REMOVE_NETWORK all")
7074 dev[0].wait_disconnected()
7075
7076 params = {"ssid": "eap-test2", "wpa": "2", "wpa_key_mgmt": "WPA-EAP",
7077 "rsn_pairwise": "CCMP", "ieee8021x": "1",
7078 "eap_server": "1", "eap_user_file": "auth_serv/eap_user.conf",
7079 "pwd_group": "19", "fragment_size": "40"}
7080 hapd2 = hostapd.add_ap(apdev[1], params)
7081 dev[0].scan_for_bss(hapd2.own_addr(), freq=2412)
7082
7083 with alloc_fail(dev[0], 1, "wpabuf_alloc;=eap_pwd_process"):
7084 dev[0].connect("eap-test2", key_mgmt="WPA-EAP", scan_freq="2412",
7085 eap="PWD", identity="pwd user",
7086 password="secret password",
7087 wait_connect=False)
7088 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
7089 dev[0].request("REMOVE_NETWORK all")
7090 dev[0].wait_disconnected()
7091
7092 for i in range(1, 5):
7093 with fail_test(dev[0], i,
7094 "=crypto_ec_point_to_bin;eap_pwd_perform_confirm_exchange"):
7095 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7096 eap="PWD", identity="pwd-hash",
7097 password_hex="hash:e3718ece8ab74792cbbfffd316d2d19a",
7098 wait_connect=False)
7099 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
7100 if ev is None:
7101 raise Exception("No EAP-Failure reported")
7102 dev[0].request("REMOVE_NETWORK all")
7103 dev[0].wait_disconnected()
7104 dev[0].dump_monitor()
7105
7106 def test_eap_proto_erp(dev, apdev):
7107 """ERP protocol tests"""
7108 check_erp_capa(dev[0])
7109
7110 global eap_proto_erp_test_done
7111 eap_proto_erp_test_done = False
7112
7113 def erp_handler(ctx, req):
7114 logger.info("erp_handler - RX " + binascii.hexlify(req).decode())
7115 if 'num' not in ctx:
7116 ctx['num'] = 0
7117 ctx['num'] += 1
7118 if 'id' not in ctx:
7119 ctx['id'] = 1
7120 ctx['id'] = (ctx['id'] + 1) % 256
7121 idx = 0
7122
7123 idx += 1
7124 if ctx['num'] == idx:
7125 logger.info("Test: Missing type")
7126 return struct.pack(">BBH", EAP_CODE_INITIATE, ctx['id'], 4)
7127
7128 idx += 1
7129 if ctx['num'] == idx:
7130 logger.info("Test: Unexpected type")
7131 return struct.pack(">BBHB", EAP_CODE_INITIATE, ctx['id'], 4 + 1,
7132 255)
7133
7134 idx += 1
7135 if ctx['num'] == idx:
7136 logger.info("Test: Missing Reserved field")
7137 return struct.pack(">BBHB", EAP_CODE_INITIATE, ctx['id'], 4 + 1,
7138 EAP_ERP_TYPE_REAUTH_START)
7139
7140 idx += 1
7141 if ctx['num'] == idx:
7142 logger.info("Test: Zero-length TVs/TLVs")
7143 payload = b""
7144 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'],
7145 4 + 1 + 1 + len(payload),
7146 EAP_ERP_TYPE_REAUTH_START, 0) + payload
7147
7148 idx += 1
7149 if ctx['num'] == idx:
7150 logger.info("Test: Too short TLV")
7151 payload = struct.pack("B", 191)
7152 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'],
7153 4 + 1 + 1 + len(payload),
7154 EAP_ERP_TYPE_REAUTH_START, 0) + payload
7155
7156 idx += 1
7157 if ctx['num'] == idx:
7158 logger.info("Test: Truncated TLV")
7159 payload = struct.pack("BB", 191, 1)
7160 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'],
7161 4 + 1 + 1 + len(payload),
7162 EAP_ERP_TYPE_REAUTH_START, 0) + payload
7163
7164 idx += 1
7165 if ctx['num'] == idx:
7166 logger.info("Test: Ignored unknown TLV and unknown TV/TLV terminating parsing")
7167 payload = struct.pack("BBB", 191, 0, 192)
7168 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'],
7169 4 + 1 + 1 + len(payload),
7170 EAP_ERP_TYPE_REAUTH_START, 0) + payload
7171
7172 idx += 1
7173 if ctx['num'] == idx:
7174 logger.info("Test: More than one keyName-NAI")
7175 payload = struct.pack("BBBB", EAP_ERP_TLV_KEYNAME_NAI, 0,
7176 EAP_ERP_TLV_KEYNAME_NAI, 0)
7177 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'],
7178 4 + 1 + 1 + len(payload),
7179 EAP_ERP_TYPE_REAUTH_START, 0) + payload
7180
7181 idx += 1
7182 if ctx['num'] == idx:
7183 logger.info("Test: Too short TLV keyName-NAI")
7184 payload = struct.pack("B", EAP_ERP_TLV_KEYNAME_NAI)
7185 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'],
7186 4 + 1 + 1 + len(payload),
7187 EAP_ERP_TYPE_REAUTH_START, 0) + payload
7188
7189 idx += 1
7190 if ctx['num'] == idx:
7191 logger.info("Test: Truncated TLV keyName-NAI")
7192 payload = struct.pack("BB", EAP_ERP_TLV_KEYNAME_NAI, 1)
7193 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'],
7194 4 + 1 + 1 + len(payload),
7195 EAP_ERP_TYPE_REAUTH_START, 0) + payload
7196
7197 idx += 1
7198 if ctx['num'] == idx:
7199 logger.info("Test: Valid rRK lifetime TV followed by too short rMSK lifetime TV")
7200 payload = struct.pack(">BLBH", EAP_ERP_TV_RRK_LIFETIME, 0,
7201 EAP_ERP_TV_RMSK_LIFETIME, 0)
7202 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'],
7203 4 + 1 + 1 + len(payload),
7204 EAP_ERP_TYPE_REAUTH_START, 0) + payload
7205
7206 idx += 1
7207 if ctx['num'] == idx:
7208 logger.info("Test: Missing type (Finish)")
7209 return struct.pack(">BBH", EAP_CODE_FINISH, ctx['id'], 4)
7210
7211 idx += 1
7212 if ctx['num'] == idx:
7213 logger.info("Test: Unexpected type (Finish)")
7214 return struct.pack(">BBHB", EAP_CODE_FINISH, ctx['id'], 4 + 1,
7215 255)
7216
7217 idx += 1
7218 if ctx['num'] == idx:
7219 logger.info("Test: Missing fields (Finish)")
7220 return struct.pack(">BBHB", EAP_CODE_FINISH, ctx['id'], 4 + 1,
7221 EAP_ERP_TYPE_REAUTH)
7222
7223 idx += 1
7224 if ctx['num'] == idx:
7225 logger.info("Test: Unexpected SEQ (Finish)")
7226 return struct.pack(">BBHBBHB", EAP_CODE_FINISH, ctx['id'],
7227 4 + 1 + 4,
7228 EAP_ERP_TYPE_REAUTH, 0, 0xffff, 0)
7229
7230 logger.info("No more test responses available - test case completed")
7231 global eap_proto_erp_test_done
7232 eap_proto_erp_test_done = True
7233 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7234
7235 srv = start_radius_server(erp_handler)
7236
7237 try:
7238 hapd = start_ap(apdev[0])
7239 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
7240
7241 i = 0
7242 while not eap_proto_erp_test_done:
7243 i += 1
7244 logger.info("Running connection iteration %d" % i)
7245 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7246 eap="PAX", identity="pax.user@example.com",
7247 password_hex="0123456789abcdef0123456789abcdef",
7248 wait_connect=False)
7249 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
7250 if ev is None:
7251 raise Exception("Timeout on EAP start")
7252 time.sleep(0.1)
7253 dev[0].request("REMOVE_NETWORK all")
7254 dev[0].wait_disconnected(timeout=1)
7255 dev[0].dump_monitor()
7256 finally:
7257 stop_radius_server(srv)
7258
7259 def test_eap_proto_fast_errors(dev, apdev):
7260 """EAP-FAST local error cases"""
7261 check_eap_capa(dev[0], "FAST")
7262 params = hostapd.wpa2_eap_params(ssid="eap-test")
7263 hapd = hostapd.add_ap(apdev[0], params)
7264 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
7265
7266 for i in range(1, 5):
7267 with alloc_fail(dev[0], i, "eap_fast_init"):
7268 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7269 eap="FAST", anonymous_identity="FAST",
7270 identity="user", password="password",
7271 ca_cert="auth_serv/ca.pem", phase2="auth=GTC",
7272 phase1="fast_provisioning=2",
7273 pac_file="blob://fast_pac_auth",
7274 wait_connect=False)
7275 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
7276 timeout=5)
7277 if ev is None:
7278 raise Exception("Timeout on EAP start")
7279 dev[0].request("REMOVE_NETWORK all")
7280 dev[0].wait_disconnected()
7281
7282 tests = [(1, "wpabuf_alloc;eap_fast_tlv_eap_payload"),
7283 (1, "eap_fast_derive_key;eap_fast_derive_key_auth"),
7284 (1, "eap_msg_alloc;eap_peer_tls_phase2_nak"),
7285 (1, "wpabuf_alloc;eap_fast_tlv_result"),
7286 (1, "wpabuf_alloc;eap_fast_tlv_pac_ack"),
7287 (1, "=eap_peer_tls_derive_session_id;eap_fast_process_crypto_binding"),
7288 (1, "eap_peer_tls_decrypt;eap_fast_decrypt"),
7289 (1, "eap_fast_getKey"),
7290 (1, "eap_fast_get_session_id"),
7291 (1, "eap_fast_get_emsk")]
7292 for count, func in tests:
7293 dev[0].request("SET blob fast_pac_auth_errors ")
7294 with alloc_fail(dev[0], count, func):
7295 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7296 eap="FAST", anonymous_identity="FAST",
7297 identity="user@example.com", password="password",
7298 ca_cert="auth_serv/ca.pem", phase2="auth=GTC",
7299 phase1="fast_provisioning=2",
7300 pac_file="blob://fast_pac_auth_errors",
7301 erp="1",
7302 wait_connect=False)
7303 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
7304 timeout=15)
7305 if ev is None:
7306 raise Exception("Timeout on EAP start")
7307 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
7308 dev[0].request("REMOVE_NETWORK all")
7309 dev[0].wait_disconnected()
7310
7311 tests = [(1, "eap_fast_derive_key;eap_fast_derive_key_provisioning"),
7312 (1, "eap_mschapv2_getKey;eap_fast_get_phase2_key"),
7313 (1, "=eap_fast_use_pac_opaque"),
7314 (1, "eap_fast_copy_buf"),
7315 (1, "=eap_fast_add_pac"),
7316 (1, "=eap_fast_init_pac_data"),
7317 (1, "=eap_fast_write_pac"),
7318 (2, "=eap_fast_write_pac")]
7319 for count, func in tests:
7320 dev[0].request("SET blob fast_pac_errors ")
7321 with alloc_fail(dev[0], count, func):
7322 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7323 eap="FAST", anonymous_identity="FAST",
7324 identity="user", password="password",
7325 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
7326 phase1="fast_provisioning=1",
7327 pac_file="blob://fast_pac_errors",
7328 erp="1",
7329 wait_connect=False)
7330 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
7331 timeout=15)
7332 if ev is None:
7333 raise Exception("Timeout on EAP start")
7334 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
7335 dev[0].request("REMOVE_NETWORK all")
7336 dev[0].wait_disconnected()
7337
7338 tests = [(1, "eap_fast_get_cmk;eap_fast_process_crypto_binding"),
7339 (1, "eap_fast_derive_eap_msk;eap_fast_process_crypto_binding"),
7340 (1, "eap_fast_derive_eap_emsk;eap_fast_process_crypto_binding")]
7341 for count, func in tests:
7342 dev[0].request("SET blob fast_pac_auth_errors ")
7343 with fail_test(dev[0], count, func):
7344 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7345 eap="FAST", anonymous_identity="FAST",
7346 identity="user", password="password",
7347 ca_cert="auth_serv/ca.pem", phase2="auth=GTC",
7348 phase1="fast_provisioning=2",
7349 pac_file="blob://fast_pac_auth_errors",
7350 erp="1",
7351 wait_connect=False)
7352 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
7353 timeout=15)
7354 if ev is None:
7355 raise Exception("Timeout on EAP start")
7356 wait_fail_trigger(dev[0], "GET_FAIL")
7357 dev[0].request("REMOVE_NETWORK all")
7358 dev[0].wait_disconnected()
7359
7360 dev[0].request("SET blob fast_pac_errors ")
7361 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7362 eap="FAST", anonymous_identity="FAST",
7363 identity="user", password="password",
7364 ca_cert="auth_serv/ca.pem", phase2="auth=GTC",
7365 phase1="fast_provisioning=1",
7366 pac_file="blob://fast_pac_errors",
7367 wait_connect=False)
7368 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5)
7369 if ev is None:
7370 raise Exception("Timeout on EAP start")
7371 # EAP-FAST: Only EAP-MSCHAPv2 is allowed during unauthenticated
7372 # provisioning; reject phase2 type 6
7373 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
7374 if ev is None:
7375 raise Exception("Timeout on EAP failure")
7376 dev[0].request("REMOVE_NETWORK all")
7377 dev[0].wait_disconnected()
7378
7379 logger.info("Wrong password in Phase 2")
7380 dev[0].request("SET blob fast_pac_errors ")
7381 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7382 eap="FAST", anonymous_identity="FAST",
7383 identity="user", password="wrong password",
7384 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
7385 phase1="fast_provisioning=1",
7386 pac_file="blob://fast_pac_errors",
7387 wait_connect=False)
7388 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5)
7389 if ev is None:
7390 raise Exception("Timeout on EAP start")
7391 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
7392 if ev is None:
7393 raise Exception("Timeout on EAP failure")
7394 dev[0].request("REMOVE_NETWORK all")
7395 dev[0].wait_disconnected()
7396
7397 tests = ["FOOBAR\n",
7398 "wpa_supplicant EAP-FAST PAC file - version 1\nFOOBAR\n",
7399 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\n",
7400 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nSTART\n",
7401 "wpa_supplicant EAP-FAST PAC file - version 1\nEND\n",
7402 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nPAC-Type=12345\nEND\n"
7403 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nPAC-Key=12\nEND\n",
7404 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nPAC-Key=1\nEND\n",
7405 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nPAC-Key=1q\nEND\n",
7406 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nPAC-Opaque=1\nEND\n",
7407 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nA-ID=1\nEND\n",
7408 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nI-ID=1\nEND\n",
7409 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nA-ID-Info=1\nEND\n"]
7410 for pac in tests:
7411 blob = binascii.hexlify(pac.encode()).decode()
7412 dev[0].request("SET blob fast_pac_errors " + blob)
7413 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7414 eap="FAST", anonymous_identity="FAST",
7415 identity="user", password="password",
7416 ca_cert="auth_serv/ca.pem", phase2="auth=GTC",
7417 phase1="fast_provisioning=2",
7418 pac_file="blob://fast_pac_errors",
7419 wait_connect=False)
7420 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
7421 timeout=5)
7422 if ev is None:
7423 raise Exception("Timeout on EAP start")
7424 dev[0].request("REMOVE_NETWORK all")
7425 dev[0].wait_disconnected()
7426
7427 tests = ["wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nEND\n",
7428 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nEND\nSTART\nEND\nSTART\nEND\n"]
7429 for pac in tests:
7430 blob = binascii.hexlify(pac.encode()).decode()
7431 dev[0].request("SET blob fast_pac_errors " + blob)
7432 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7433 eap="FAST", anonymous_identity="FAST",
7434 identity="user", password="password",
7435 ca_cert="auth_serv/ca.pem", phase2="auth=GTC",
7436 phase1="fast_provisioning=2",
7437 pac_file="blob://fast_pac_errors")
7438 dev[0].request("REMOVE_NETWORK all")
7439 dev[0].wait_disconnected()
7440
7441 dev[0].request("SET blob fast_pac_errors ")
7442
7443 def test_eap_proto_peap_errors(dev, apdev):
7444 """EAP-PEAP local error cases"""
7445 check_eap_capa(dev[0], "PEAP")
7446 check_eap_capa(dev[0], "MSCHAPV2")
7447 params = hostapd.wpa2_eap_params(ssid="eap-test")
7448 hapd = hostapd.add_ap(apdev[0], params)
7449 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
7450
7451 for i in range(1, 5):
7452 with alloc_fail(dev[0], i, "eap_peap_init"):
7453 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7454 eap="PEAP", anonymous_identity="peap",
7455 identity="user", password="password",
7456 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
7457 wait_connect=False)
7458 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
7459 timeout=5)
7460 if ev is None:
7461 raise Exception("Timeout on EAP start")
7462 dev[0].request("REMOVE_NETWORK all")
7463 dev[0].wait_disconnected()
7464
7465 tests = [(1, "eap_mschapv2_getKey;eap_peap_get_isk;eap_peap_derive_cmk"),
7466 (1, "eap_msg_alloc;eap_tlv_build_result"),
7467 (1, "eap_mschapv2_init;eap_peap_phase2_request"),
7468 (1, "eap_peer_tls_decrypt;eap_peap_decrypt"),
7469 (1, "wpabuf_alloc;=eap_peap_decrypt"),
7470 (1, "eap_peer_tls_encrypt;eap_peap_decrypt"),
7471 (1, "eap_peer_tls_process_helper;eap_peap_process"),
7472 (1, "eap_peer_tls_derive_key;eap_peap_process"),
7473 (1, "eap_peer_tls_derive_session_id;eap_peap_process"),
7474 (1, "eap_peap_getKey"),
7475 (1, "eap_peap_get_session_id")]
7476 for count, func in tests:
7477 with alloc_fail(dev[0], count, func):
7478 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7479 eap="PEAP", anonymous_identity="peap",
7480 identity="user", password="password",
7481 phase1="peapver=0 crypto_binding=2",
7482 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
7483 erp="1", wait_connect=False)
7484 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
7485 timeout=15)
7486 if ev is None:
7487 raise Exception("Timeout on EAP start")
7488 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
7489 dev[0].request("REMOVE_NETWORK all")
7490 dev[0].wait_disconnected()
7491
7492 tests = [(1, "peap_prfplus;eap_peap_derive_cmk"),
7493 (1, "eap_tlv_add_cryptobinding;eap_tlv_build_result"),
7494 (1, "peap_prfplus;eap_peap_getKey")]
7495 for count, func in tests:
7496 with fail_test(dev[0], count, func):
7497 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7498 eap="PEAP", anonymous_identity="peap",
7499 identity="user", password="password",
7500 phase1="peapver=0 crypto_binding=2",
7501 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
7502 erp="1", wait_connect=False)
7503 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
7504 timeout=15)
7505 if ev is None:
7506 raise Exception("Timeout on EAP start")
7507 wait_fail_trigger(dev[0], "GET_FAIL")
7508 dev[0].request("REMOVE_NETWORK all")
7509 dev[0].wait_disconnected()
7510
7511 with alloc_fail(dev[0], 1,
7512 "eap_peer_tls_phase2_nak;eap_peap_phase2_request"):
7513 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7514 eap="PEAP", anonymous_identity="peap",
7515 identity="cert user", password="password",
7516 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
7517 wait_connect=False)
7518 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
7519 dev[0].request("REMOVE_NETWORK all")
7520 dev[0].wait_disconnected()
7521
7522 def test_eap_proto_ttls_errors(dev, apdev):
7523 """EAP-TTLS local error cases"""
7524 check_eap_capa(dev[0], "TTLS")
7525 check_eap_capa(dev[0], "MSCHAPV2")
7526 params = hostapd.wpa2_eap_params(ssid="eap-test")
7527 hapd = hostapd.add_ap(apdev[0], params)
7528 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
7529
7530 for i in range(1, 5):
7531 with alloc_fail(dev[0], i, "eap_ttls_init"):
7532 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7533 eap="TTLS", anonymous_identity="ttls",
7534 identity="user", password="password",
7535 ca_cert="auth_serv/ca.pem",
7536 phase2="autheap=MSCHAPV2",
7537 wait_connect=False)
7538 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
7539 timeout=5)
7540 if ev is None:
7541 raise Exception("Timeout on EAP start")
7542 dev[0].request("REMOVE_NETWORK all")
7543 dev[0].wait_disconnected()
7544
7545 tests = [(1, "eap_peer_tls_derive_key;eap_ttls_v0_derive_key",
7546 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"),
7547 (1, "eap_peer_tls_derive_session_id;eap_ttls_v0_derive_key",
7548 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"),
7549 (1, "wpabuf_alloc;eap_ttls_phase2_request_mschapv2",
7550 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"),
7551 (1, "eap_peer_tls_derive_key;eap_ttls_phase2_request_mschapv2",
7552 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"),
7553 (1, "eap_peer_tls_encrypt;eap_ttls_encrypt_response;eap_ttls_implicit_identity_request",
7554 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"),
7555 (1, "eap_peer_tls_decrypt;eap_ttls_decrypt",
7556 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"),
7557 (1, "eap_ttls_getKey",
7558 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"),
7559 (1, "eap_ttls_get_session_id",
7560 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"),
7561 (1, "eap_ttls_get_emsk",
7562 "mschapv2 user@domain", "auth=MSCHAPV2"),
7563 (1, "wpabuf_alloc;eap_ttls_phase2_request_mschap",
7564 "mschap user", "auth=MSCHAP"),
7565 (1, "eap_peer_tls_derive_key;eap_ttls_phase2_request_mschap",
7566 "mschap user", "auth=MSCHAP"),
7567 (1, "wpabuf_alloc;eap_ttls_phase2_request_chap",
7568 "chap user", "auth=CHAP"),
7569 (1, "eap_peer_tls_derive_key;eap_ttls_phase2_request_chap",
7570 "chap user", "auth=CHAP"),
7571 (1, "wpabuf_alloc;eap_ttls_phase2_request_pap",
7572 "pap user", "auth=PAP"),
7573 (1, "wpabuf_alloc;eap_ttls_avp_encapsulate",
7574 "user", "autheap=MSCHAPV2"),
7575 (1, "eap_mschapv2_init;eap_ttls_phase2_request_eap_method",
7576 "user", "autheap=MSCHAPV2"),
7577 (1, "eap_sm_buildIdentity;eap_ttls_phase2_request_eap",
7578 "user", "autheap=MSCHAPV2"),
7579 (1, "eap_ttls_avp_encapsulate;eap_ttls_phase2_request_eap",
7580 "user", "autheap=MSCHAPV2"),
7581 (1, "eap_ttls_parse_attr_eap",
7582 "user", "autheap=MSCHAPV2"),
7583 (1, "eap_peer_tls_encrypt;eap_ttls_encrypt_response;eap_ttls_process_decrypted",
7584 "user", "autheap=MSCHAPV2"),
7585 (1, "eap_ttls_fake_identity_request",
7586 "user", "autheap=MSCHAPV2"),
7587 (1, "eap_msg_alloc;eap_tls_process_output",
7588 "user", "autheap=MSCHAPV2"),
7589 (1, "eap_msg_alloc;eap_peer_tls_build_ack",
7590 "user", "autheap=MSCHAPV2"),
7591 (1, "tls_connection_decrypt;eap_peer_tls_decrypt",
7592 "user", "autheap=MSCHAPV2"),
7593 (1, "eap_peer_tls_phase2_nak;eap_ttls_phase2_request_eap_method",
7594 "cert user", "autheap=MSCHAPV2")]
7595 for count, func, identity, phase2 in tests:
7596 with alloc_fail(dev[0], count, func):
7597 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7598 eap="TTLS", anonymous_identity="ttls",
7599 identity=identity, password="password",
7600 ca_cert="auth_serv/ca.pem", phase2=phase2,
7601 erp="1", wait_connect=False)
7602 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
7603 timeout=15)
7604 if ev is None:
7605 raise Exception("Timeout on EAP start")
7606 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL",
7607 note="Allocation failure not triggered for: %d:%s" % (count, func))
7608 dev[0].request("REMOVE_NETWORK all")
7609 dev[0].wait_disconnected()
7610
7611 tests = [(1, "os_get_random;eap_ttls_phase2_request_mschapv2"),
7612 (1, "mschapv2_derive_response;eap_ttls_phase2_request_mschapv2")]
7613 for count, func in tests:
7614 with fail_test(dev[0], count, func):
7615 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7616 eap="TTLS", anonymous_identity="ttls",
7617 identity="DOMAIN\mschapv2 user", password="password",
7618 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
7619 erp="1", wait_connect=False)
7620 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
7621 timeout=15)
7622 if ev is None:
7623 raise Exception("Timeout on EAP start")
7624 wait_fail_trigger(dev[0], "GET_FAIL",
7625 note="Test failure not triggered for: %d:%s" % (count, func))
7626 dev[0].request("REMOVE_NETWORK all")
7627 dev[0].wait_disconnected()
7628
7629 tests = [(1, "nt_challenge_response;eap_ttls_phase2_request_mschap")]
7630 for count, func in tests:
7631 with fail_test(dev[0], count, func):
7632 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7633 eap="TTLS", anonymous_identity="ttls",
7634 identity="mschap user", password="password",
7635 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAP",
7636 erp="1", wait_connect=False)
7637 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
7638 timeout=15)
7639 if ev is None:
7640 raise Exception("Timeout on EAP start")
7641 wait_fail_trigger(dev[0], "GET_FAIL",
7642 note="Test failure not triggered for: %d:%s" % (count, func))
7643 dev[0].request("REMOVE_NETWORK all")
7644 dev[0].wait_disconnected()
7645
7646 def test_eap_proto_expanded(dev, apdev):
7647 """EAP protocol tests with expanded header"""
7648 global eap_proto_expanded_test_done
7649 eap_proto_expanded_test_done = False
7650
7651 def expanded_handler(ctx, req):
7652 logger.info("expanded_handler - RX " + binascii.hexlify(req).decode())
7653 if 'num' not in ctx:
7654 ctx['num'] = 0
7655 ctx['num'] += 1
7656 if 'id' not in ctx:
7657 ctx['id'] = 1
7658 ctx['id'] = (ctx['id'] + 1) % 256
7659 idx = 0
7660
7661 idx += 1
7662 if ctx['num'] == idx:
7663 logger.info("Test: MD5 challenge in expanded header")
7664 return struct.pack(">BBHB3BLBBB", EAP_CODE_REQUEST, ctx['id'],
7665 4 + 1 + 3 + 4 + 3,
7666 EAP_TYPE_EXPANDED, 0, 0, 0, EAP_TYPE_MD5,
7667 1, 0xaa, ord('n'))
7668 idx += 1
7669 if ctx['num'] == idx:
7670 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7671
7672 idx += 1
7673 if ctx['num'] == idx:
7674 logger.info("Test: Invalid expanded EAP length")
7675 return struct.pack(">BBHB3BH", EAP_CODE_REQUEST, ctx['id'],
7676 4 + 1 + 3 + 2,
7677 EAP_TYPE_EXPANDED, 0, 0, 0, EAP_TYPE_MD5)
7678 idx += 1
7679 if ctx['num'] == idx:
7680 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7681
7682 idx += 1
7683 if ctx['num'] == idx:
7684 logger.info("Test: Invalid expanded frame type")
7685 return struct.pack(">BBHB3BL", EAP_CODE_REQUEST, ctx['id'],
7686 4 + 1 + 3 + 4,
7687 EAP_TYPE_EXPANDED, 0, 0, 1, EAP_TYPE_MD5)
7688 idx += 1
7689 if ctx['num'] == idx:
7690 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7691
7692 idx += 1
7693 if ctx['num'] == idx:
7694 logger.info("Test: MSCHAPv2 Challenge")
7695 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
7696 4 + 1 + 4 + 1 + 16 + 6,
7697 EAP_TYPE_MSCHAPV2,
7698 1, 0, 4 + 1 + 16 + 6, 16) + 16*b'A' + b'foobar'
7699 idx += 1
7700 if ctx['num'] == idx:
7701 logger.info("Test: Invalid expanded frame type")
7702 return struct.pack(">BBHB3BL", EAP_CODE_REQUEST, ctx['id'],
7703 4 + 1 + 3 + 4,
7704 EAP_TYPE_EXPANDED, 0, 0, 1, EAP_TYPE_MSCHAPV2)
7705
7706 logger.info("No more test responses available - test case completed")
7707 global eap_proto_expanded_test_done
7708 eap_proto_expanded_test_done = True
7709 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7710
7711 srv = start_radius_server(expanded_handler)
7712
7713 try:
7714 hapd = start_ap(apdev[0])
7715 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
7716
7717 i = 0
7718 while not eap_proto_expanded_test_done:
7719 i += 1
7720 logger.info("Running connection iteration %d" % i)
7721 if i == 4:
7722 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7723 eap="MSCHAPV2", identity="user",
7724 password="password",
7725 wait_connect=False)
7726 else:
7727 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7728 eap="MD5", identity="user", password="password",
7729 wait_connect=False)
7730 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
7731 if ev is None:
7732 raise Exception("Timeout on EAP start")
7733 if i in [1]:
7734 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5)
7735 if ev is None:
7736 raise Exception("Timeout on EAP method start")
7737 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
7738 if ev is None:
7739 raise Exception("Timeout on EAP failure")
7740 elif i in [2, 3]:
7741 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
7742 timeout=5)
7743 if ev is None:
7744 raise Exception("Timeout on EAP proposed method")
7745 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
7746 if ev is None:
7747 raise Exception("Timeout on EAP failure")
7748 else:
7749 time.sleep(0.1)
7750 dev[0].request("REMOVE_NETWORK all")
7751 dev[0].wait_disconnected(timeout=1)
7752 dev[0].dump_monitor()
7753 finally:
7754 stop_radius_server(srv)
7755
7756 def test_eap_proto_tls(dev, apdev):
7757 """EAP-TLS protocol tests"""
7758 check_eap_capa(dev[0], "TLS")
7759 global eap_proto_tls_test_done, eap_proto_tls_test_wait
7760 eap_proto_tls_test_done = False
7761 eap_proto_tls_test_wait = False
7762
7763 def tls_handler(ctx, req):
7764 logger.info("tls_handler - RX " + binascii.hexlify(req).decode())
7765 if 'num' not in ctx:
7766 ctx['num'] = 0
7767 ctx['num'] += 1
7768 if 'id' not in ctx:
7769 ctx['id'] = 1
7770 ctx['id'] = (ctx['id'] + 1) % 256
7771 idx = 0
7772
7773 global eap_proto_tls_test_wait
7774
7775 idx += 1
7776 if ctx['num'] == idx:
7777 logger.info("Test: Too much payload in TLS/Start: TLS Message Length (0 bytes) smaller than this fragment (1 bytes)")
7778 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'],
7779 4 + 1 + 1 + 4 + 1,
7780 EAP_TYPE_TLS, 0xa0, 0, 1)
7781
7782 idx += 1
7783 if ctx['num'] == idx:
7784 logger.info("Test: Fragmented TLS/Start")
7785 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'],
7786 4 + 1 + 1 + 4 + 1,
7787 EAP_TYPE_TLS, 0xe0, 2, 1)
7788 idx += 1
7789 if ctx['num'] == idx:
7790 logger.info("Test: Too long fragment of TLS/Start: Invalid reassembly state: tls_in_left=2 tls_in_len=0 in_len=0")
7791 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
7792 4 + 1 + 1 + 2,
7793 EAP_TYPE_TLS, 0x00, 2, 3)
7794 idx += 1
7795 if ctx['num'] == idx:
7796 logger.info("Test: EAP-Failure")
7797 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7798
7799 idx += 1
7800 if ctx['num'] == idx:
7801 logger.info("Test: TLS/Start")
7802 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7803 4 + 1 + 1,
7804 EAP_TYPE_TLS, 0x20)
7805 idx += 1
7806 if ctx['num'] == idx:
7807 logger.info("Test: Fragmented TLS message")
7808 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'],
7809 4 + 1 + 1 + 4 + 1,
7810 EAP_TYPE_TLS, 0xc0, 2, 1)
7811 idx += 1
7812 if ctx['num'] == idx:
7813 logger.info("Test: Invalid TLS message: no Flags octet included + workaround")
7814 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7815 4 + 1,
7816 EAP_TYPE_TLS)
7817 idx += 1
7818 if ctx['num'] == idx:
7819 logger.info("Test: Too long fragment of TLS message: more data than TLS message length indicated")
7820 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
7821 4 + 1 + 1 + 2,
7822 EAP_TYPE_TLS, 0x00, 2, 3)
7823 idx += 1
7824 if ctx['num'] == idx:
7825 logger.info("Test: EAP-Failure")
7826 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7827
7828 idx += 1
7829 if ctx['num'] == idx:
7830 logger.info("Test: Fragmented TLS/Start and truncated Message Length field")
7831 return struct.pack(">BBHBB3B", EAP_CODE_REQUEST, ctx['id'],
7832 4 + 1 + 1 + 3,
7833 EAP_TYPE_TLS, 0xe0, 1, 2, 3)
7834
7835 idx += 1
7836 if ctx['num'] == idx:
7837 logger.info("Test: TLS/Start")
7838 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7839 4 + 1 + 1,
7840 EAP_TYPE_TLS, 0x20)
7841 idx += 1
7842 if ctx['num'] == idx:
7843 logger.info("Test: Fragmented TLS message")
7844 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'],
7845 4 + 1 + 1 + 4 + 1,
7846 EAP_TYPE_TLS, 0xc0, 2, 1)
7847 idx += 1
7848 if ctx['num'] == idx:
7849 logger.info("Test: Invalid TLS message: no Flags octet included + workaround disabled")
7850 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7851 4 + 1,
7852 EAP_TYPE_TLS)
7853
7854 idx += 1
7855 if ctx['num'] == idx:
7856 logger.info("Test: TLS/Start")
7857 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7858 4 + 1 + 1,
7859 EAP_TYPE_TLS, 0x20)
7860 idx += 1
7861 if ctx['num'] == idx:
7862 logger.info("Test: Fragmented TLS message (long; first)")
7863 payload = 1450*b'A'
7864 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'],
7865 4 + 1 + 1 + 4 + len(payload),
7866 EAP_TYPE_TLS, 0xc0, 65536) + payload
7867 # "Too long TLS fragment (size over 64 kB)" on the last one
7868 for i in range(44):
7869 idx += 1
7870 if ctx['num'] == idx:
7871 logger.info("Test: Fragmented TLS message (long; cont %d)" % i)
7872 eap_proto_tls_test_wait = True
7873 payload = 1470*b'A'
7874 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7875 4 + 1 + 1 + len(payload),
7876 EAP_TYPE_TLS, 0x40) + payload
7877 eap_proto_tls_test_wait = False
7878 idx += 1
7879 if ctx['num'] == idx:
7880 logger.info("Test: EAP-Failure")
7881 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7882
7883 idx += 1
7884 if ctx['num'] == idx:
7885 logger.info("Test: TLS/Start")
7886 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7887 4 + 1 + 1,
7888 EAP_TYPE_TLS, 0x20)
7889 idx += 1
7890 if ctx['num'] == idx:
7891 logger.info("Test: Non-ACK to more-fragment message")
7892 return struct.pack(">BBHBBB", EAP_CODE_REQUEST, ctx['id'],
7893 4 + 1 + 1 + 1,
7894 EAP_TYPE_TLS, 0x00, 255)
7895 idx += 1
7896 if ctx['num'] == idx:
7897 logger.info("Test: EAP-Failure")
7898 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7899
7900 logger.info("No more test responses available - test case completed")
7901 global eap_proto_tls_test_done
7902 eap_proto_tls_test_done = True
7903 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7904
7905 srv = start_radius_server(tls_handler)
7906
7907 try:
7908 hapd = start_ap(apdev[0])
7909 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
7910
7911 i = 0
7912 while not eap_proto_tls_test_done:
7913 i += 1
7914 logger.info("Running connection iteration %d" % i)
7915 workaround = "0" if i == 6 else "1"
7916 fragment_size = "100" if i == 8 else "1400"
7917 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7918 eap="TLS", identity="tls user",
7919 ca_cert="auth_serv/ca.pem",
7920 client_cert="auth_serv/user.pem",
7921 private_key="auth_serv/user.key",
7922 eap_workaround=workaround,
7923 fragment_size=fragment_size,
7924 wait_connect=False)
7925 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
7926 if ev is None:
7927 raise Exception("Timeout on EAP start")
7928 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD",
7929 "CTRL-EVENT-EAP-STATUS"], timeout=5)
7930 if ev is None:
7931 raise Exception("Timeout on EAP method start")
7932 time.sleep(0.1)
7933 start = os.times()[4]
7934 while eap_proto_tls_test_wait:
7935 now = os.times()[4]
7936 if now - start > 10:
7937 break
7938 time.sleep(0.1)
7939 dev[0].request("REMOVE_NETWORK all")
7940 dev[0].wait_disconnected(timeout=1)
7941 dev[0].dump_monitor()
7942 finally:
7943 stop_radius_server(srv)
7944
7945 def test_eap_proto_tnc(dev, apdev):
7946 """EAP-TNC protocol tests"""
7947 check_eap_capa(dev[0], "TNC")
7948 global eap_proto_tnc_test_done
7949 eap_proto_tnc_test_done = False
7950
7951 def tnc_handler(ctx, req):
7952 logger.info("tnc_handler - RX " + binascii.hexlify(req).decode())
7953 if 'num' not in ctx:
7954 ctx['num'] = 0
7955 ctx['num'] += 1
7956 if 'id' not in ctx:
7957 ctx['id'] = 1
7958 ctx['id'] = (ctx['id'] + 1) % 256
7959 idx = 0
7960
7961 idx += 1
7962 if ctx['num'] == idx:
7963 logger.info("Test: TNC start with unsupported version")
7964 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7965 4 + 1 + 1,
7966 EAP_TYPE_TNC, 0x20)
7967
7968 idx += 1
7969 if ctx['num'] == idx:
7970 logger.info("Test: TNC without Flags field")
7971 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7972 4 + 1,
7973 EAP_TYPE_TNC)
7974
7975 idx += 1
7976 if ctx['num'] == idx:
7977 logger.info("Test: Message underflow due to missing Message Length")
7978 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
7979 4 + 1 + 1,
7980 EAP_TYPE_TNC, 0xa1)
7981
7982 idx += 1
7983 if ctx['num'] == idx:
7984 logger.info("Test: Invalid Message Length")
7985 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'],
7986 4 + 1 + 1 + 4 + 1,
7987 EAP_TYPE_TNC, 0xa1, 0, 0)
7988
7989 idx += 1
7990 if ctx['num'] == idx:
7991 logger.info("Test: Invalid Message Length")
7992 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'],
7993 4 + 1 + 1 + 4,
7994 EAP_TYPE_TNC, 0xe1, 75001)
7995
7996 idx += 1
7997 if ctx['num'] == idx:
7998 logger.info("Test: Start with Message Length")
7999 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'],
8000 4 + 1 + 1 + 4,
8001 EAP_TYPE_TNC, 0xa1, 1)
8002 idx += 1
8003 if ctx['num'] == idx:
8004 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
8005
8006 idx += 1
8007 if ctx['num'] == idx:
8008 logger.info("Test: Server used start flag again")
8009 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
8010 4 + 1 + 1,
8011 EAP_TYPE_TNC, 0x21)
8012 idx += 1
8013 if ctx['num'] == idx:
8014 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
8015 4 + 1 + 1,
8016 EAP_TYPE_TNC, 0x21)
8017
8018 idx += 1
8019 if ctx['num'] == idx:
8020 logger.info("Test: Fragmentation and unexpected payload in ack")
8021 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
8022 4 + 1 + 1,
8023 EAP_TYPE_TNC, 0x21)
8024 idx += 1
8025 if ctx['num'] == idx:
8026 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
8027 4 + 1 + 1,
8028 EAP_TYPE_TNC, 0x01)
8029 idx += 1
8030 if ctx['num'] == idx:
8031 return struct.pack(">BBHBBB", EAP_CODE_REQUEST, ctx['id'],
8032 4 + 1 + 1 + 1,
8033 EAP_TYPE_TNC, 0x01, 0)
8034
8035 idx += 1
8036 if ctx['num'] == idx:
8037 logger.info("Test: Server fragmenting and fragment overflow")
8038 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'],
8039 4 + 1 + 1 + 4 + 1,
8040 EAP_TYPE_TNC, 0xe1, 2, 1)
8041 idx += 1
8042 if ctx['num'] == idx:
8043 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
8044 4 + 1 + 1 + 2,
8045 EAP_TYPE_TNC, 0x01, 2, 3)
8046
8047 idx += 1
8048 if ctx['num'] == idx:
8049 logger.info("Test: Server fragmenting and no message length in a fragment")
8050 return struct.pack(">BBHBBB", EAP_CODE_REQUEST, ctx['id'],
8051 4 + 1 + 1 + 1,
8052 EAP_TYPE_TNC, 0x61, 2)
8053
8054 idx += 1
8055 if ctx['num'] == idx:
8056 logger.info("Test: TNC start followed by invalid TNCCS-Batch")
8057 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
8058 4 + 1 + 1,
8059 EAP_TYPE_TNC, 0x21)
8060 idx += 1
8061 if ctx['num'] == idx:
8062 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
8063 resp = b"FOO"
8064 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
8065 4 + 1 + 1 + len(resp),
8066 EAP_TYPE_TNC, 0x01) + resp
8067
8068 idx += 1
8069 if ctx['num'] == idx:
8070 logger.info("Test: TNC start followed by invalid TNCCS-Batch (2)")
8071 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
8072 4 + 1 + 1,
8073 EAP_TYPE_TNC, 0x21)
8074 idx += 1
8075 if ctx['num'] == idx:
8076 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
8077 resp = b"</TNCCS-Batch><TNCCS-Batch>"
8078 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
8079 4 + 1 + 1 + len(resp),
8080 EAP_TYPE_TNC, 0x01) + resp
8081
8082 idx += 1
8083 if ctx['num'] == idx:
8084 logger.info("Test: TNCCS-Batch missing BatchId attribute")
8085 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
8086 4 + 1 + 1,
8087 EAP_TYPE_TNC, 0x21)
8088 idx += 1
8089 if ctx['num'] == idx:
8090 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
8091 resp = b"<TNCCS-Batch foo=3></TNCCS-Batch>"
8092 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
8093 4 + 1 + 1 + len(resp),
8094 EAP_TYPE_TNC, 0x01) + resp
8095
8096 idx += 1
8097 if ctx['num'] == idx:
8098 logger.info("Test: Unexpected IF-TNCCS BatchId")
8099 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
8100 4 + 1 + 1,
8101 EAP_TYPE_TNC, 0x21)
8102 idx += 1
8103 if ctx['num'] == idx:
8104 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
8105 resp = b"<TNCCS-Batch BatchId=123456789></TNCCS-Batch>"
8106 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
8107 4 + 1 + 1 + len(resp),
8108 EAP_TYPE_TNC, 0x01) + resp
8109
8110 idx += 1
8111 if ctx['num'] == idx:
8112 logger.info("Test: Missing IMC-IMV-Message and TNCC-TNCS-Message end tags")
8113 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
8114 4 + 1 + 1,
8115 EAP_TYPE_TNC, 0x21)
8116 idx += 1
8117 if ctx['num'] == idx:
8118 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
8119 resp = b"<TNCCS-Batch BatchId=2><IMC-IMV-Message><TNCC-TNCS-Message></TNCCS-Batch>"
8120 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
8121 4 + 1 + 1 + len(resp),
8122 EAP_TYPE_TNC, 0x01) + resp
8123 idx += 1
8124 if ctx['num'] == idx:
8125 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
8126
8127 idx += 1
8128 if ctx['num'] == idx:
8129 logger.info("Test: Missing IMC-IMV-Message and TNCC-TNCS-Message Type")
8130 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
8131 4 + 1 + 1,
8132 EAP_TYPE_TNC, 0x21)
8133 idx += 1
8134 if ctx['num'] == idx:
8135 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
8136 resp = b"<TNCCS-Batch BatchId=2><IMC-IMV-Message></IMC-IMV-Message><TNCC-TNCS-Message></TNCC-TNCS-Message></TNCCS-Batch>"
8137 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
8138 4 + 1 + 1 + len(resp),
8139 EAP_TYPE_TNC, 0x01) + resp
8140 idx += 1
8141 if ctx['num'] == idx:
8142 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
8143
8144 idx += 1
8145 if ctx['num'] == idx:
8146 logger.info("Test: Missing TNCC-TNCS-Message XML end tag")
8147 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
8148 4 + 1 + 1,
8149 EAP_TYPE_TNC, 0x21)
8150 idx += 1
8151 if ctx['num'] == idx:
8152 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
8153 resp = b"<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type><XML></TNCC-TNCS-Message></TNCCS-Batch>"
8154 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
8155 4 + 1 + 1 + len(resp),
8156 EAP_TYPE_TNC, 0x01) + resp
8157 idx += 1
8158 if ctx['num'] == idx:
8159 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
8160
8161 idx += 1
8162 if ctx['num'] == idx:
8163 logger.info("Test: Missing TNCC-TNCS-Message Base64 start tag")
8164 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
8165 4 + 1 + 1,
8166 EAP_TYPE_TNC, 0x21)
8167 idx += 1
8168 if ctx['num'] == idx:
8169 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
8170 resp = b"<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type></TNCC-TNCS-Message></TNCCS-Batch>"
8171 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
8172 4 + 1 + 1 + len(resp),
8173 EAP_TYPE_TNC, 0x01) + resp
8174 idx += 1
8175 if ctx['num'] == idx:
8176 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
8177
8178 idx += 1
8179 if ctx['num'] == idx:
8180 logger.info("Test: Missing TNCC-TNCS-Message Base64 end tag")
8181 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
8182 4 + 1 + 1,
8183 EAP_TYPE_TNC, 0x21)
8184 idx += 1
8185 if ctx['num'] == idx:
8186 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
8187 resp = b"<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type><Base64>abc</TNCC-TNCS-Message></TNCCS-Batch>"
8188 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
8189 4 + 1 + 1 + len(resp),
8190 EAP_TYPE_TNC, 0x01) + resp
8191 idx += 1
8192 if ctx['num'] == idx:
8193 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
8194
8195 idx += 1
8196 if ctx['num'] == idx:
8197 logger.info("Test: TNCC-TNCS-Message Base64 message")
8198 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
8199 4 + 1 + 1,
8200 EAP_TYPE_TNC, 0x21)
8201 idx += 1
8202 if ctx['num'] == idx:
8203 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
8204 resp = b"<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type><Base64>aGVsbG8=</Base64></TNCC-TNCS-Message></TNCCS-Batch>"
8205 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
8206 4 + 1 + 1 + len(resp),
8207 EAP_TYPE_TNC, 0x01) + resp
8208 idx += 1
8209 if ctx['num'] == idx:
8210 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
8211
8212 idx += 1
8213 if ctx['num'] == idx:
8214 logger.info("Test: Invalid TNCC-TNCS-Message XML message")
8215 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
8216 4 + 1 + 1,
8217 EAP_TYPE_TNC, 0x21)
8218 idx += 1
8219 if ctx['num'] == idx:
8220 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
8221 resp = b"<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type><XML>hello</XML></TNCC-TNCS-Message></TNCCS-Batch>"
8222 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
8223 4 + 1 + 1 + len(resp),
8224 EAP_TYPE_TNC, 0x01) + resp
8225 idx += 1
8226 if ctx['num'] == idx:
8227 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
8228
8229 idx += 1
8230 if ctx['num'] == idx:
8231 logger.info("Test: Missing TNCCS-Recommendation type")
8232 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
8233 4 + 1 + 1,
8234 EAP_TYPE_TNC, 0x21)
8235 idx += 1
8236 if ctx['num'] == idx:
8237 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
8238 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>'
8239 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
8240 4 + 1 + 1 + len(resp),
8241 EAP_TYPE_TNC, 0x01) + resp
8242 idx += 1
8243 if ctx['num'] == idx:
8244 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
8245
8246 idx += 1
8247 if ctx['num'] == idx:
8248 logger.info("Test: TNCCS-Recommendation type=none")
8249 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
8250 4 + 1 + 1,
8251 EAP_TYPE_TNC, 0x21)
8252 idx += 1
8253 if ctx['num'] == idx:
8254 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
8255 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>'
8256 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
8257 4 + 1 + 1 + len(resp),
8258 EAP_TYPE_TNC, 0x01) + resp
8259 idx += 1
8260 if ctx['num'] == idx:
8261 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
8262
8263 idx += 1
8264 if ctx['num'] == idx:
8265 logger.info("Test: TNCCS-Recommendation type=isolate")
8266 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
8267 4 + 1 + 1,
8268 EAP_TYPE_TNC, 0x21)
8269 idx += 1
8270 if ctx['num'] == idx:
8271 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
8272 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>'
8273 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
8274 4 + 1 + 1 + len(resp),
8275 EAP_TYPE_TNC, 0x01) + resp
8276 idx += 1
8277 if ctx['num'] == idx:
8278 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
8279
8280 logger.info("No more test responses available - test case completed")
8281 global eap_proto_tnc_test_done
8282 eap_proto_tnc_test_done = True
8283 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
8284
8285 srv = start_radius_server(tnc_handler)
8286
8287 try:
8288 hapd = start_ap(apdev[0])
8289 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
8290
8291 i = 0
8292 while not eap_proto_tnc_test_done:
8293 i += 1
8294 logger.info("Running connection iteration %d" % i)
8295 frag = 1400
8296 if i == 8:
8297 frag = 150
8298 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8299 eap="TNC", identity="tnc", fragment_size=str(frag),
8300 wait_connect=False)
8301 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
8302 if ev is None:
8303 raise Exception("Timeout on EAP start")
8304 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD",
8305 "CTRL-EVENT-EAP-STATUS"], timeout=5)
8306 if ev is None:
8307 raise Exception("Timeout on EAP method start")
8308 time.sleep(0.1)
8309 dev[0].request("REMOVE_NETWORK all")
8310 dev[0].wait_disconnected(timeout=1)
8311 dev[0].dump_monitor()
8312 finally:
8313 stop_radius_server(srv)
8314
8315 def test_eap_canned_success_after_identity(dev, apdev):
8316 """EAP protocol tests for canned EAP-Success after identity"""
8317 check_eap_capa(dev[0], "MD5")
8318 def eap_canned_success_handler(ctx, req):
8319 logger.info("eap_canned_success_handler - RX " + binascii.hexlify(req).decode())
8320 if 'num' not in ctx:
8321 ctx['num'] = 0
8322 ctx['num'] = ctx['num'] + 1
8323 if 'id' not in ctx:
8324 ctx['id'] = 1
8325 ctx['id'] = (ctx['id'] + 1) % 256
8326 idx = 0
8327
8328 idx += 1
8329 if ctx['num'] == idx:
8330 logger.info("Test: EAP-Success")
8331 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4)
8332
8333 idx += 1
8334 if ctx['num'] == idx:
8335 logger.info("Test: EAP-Success")
8336 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4)
8337
8338 return None
8339
8340 srv = start_radius_server(eap_canned_success_handler)
8341
8342 try:
8343 hapd = start_ap(apdev[0])
8344 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
8345
8346 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8347 phase1="allow_canned_success=1",
8348 eap="MD5", identity="user", password="password",
8349 wait_connect=False)
8350 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15)
8351 if ev is None:
8352 raise Exception("Timeout on EAP success")
8353 dev[0].request("REMOVE_NETWORK all")
8354 dev[0].wait_disconnected()
8355
8356 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8357 eap="MD5", identity="user", password="password",
8358 wait_connect=False)
8359 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
8360 if ev is None:
8361 raise Exception("Timeout on EAP start")
8362 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=0.1)
8363 if ev is not None:
8364 raise Exception("Unexpected EAP success")
8365 dev[0].request("REMOVE_NETWORK all")
8366 dev[0].wait_disconnected()
8367 finally:
8368 stop_radius_server(srv)
8369
8370 def test_eap_proto_wsc(dev, apdev):
8371 """EAP-WSC protocol tests"""
8372 global eap_proto_wsc_test_done, eap_proto_wsc_wait_failure
8373 eap_proto_wsc_test_done = False
8374
8375 def wsc_handler(ctx, req):
8376 logger.info("wsc_handler - RX " + binascii.hexlify(req).decode())
8377 if 'num' not in ctx:
8378 ctx['num'] = 0
8379 ctx['num'] += 1
8380 if 'id' not in ctx:
8381 ctx['id'] = 1
8382 ctx['id'] = (ctx['id'] + 1) % 256
8383 idx = 0
8384
8385 global eap_proto_wsc_wait_failure
8386 eap_proto_wsc_wait_failure = False
8387
8388 idx += 1
8389 if ctx['num'] == idx:
8390 logger.info("Test: Missing Flags field")
8391 return struct.pack(">BBHB3BLB", EAP_CODE_REQUEST, ctx['id'],
8392 4 + 1 + 3 + 4 + 1,
8393 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
8394 1)
8395
8396 idx += 1
8397 if ctx['num'] == idx:
8398 logger.info("Test: Message underflow (missing Message Length field)")
8399 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'],
8400 4 + 1 + 3 + 4 + 2,
8401 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
8402 1, 0x02)
8403
8404 idx += 1
8405 if ctx['num'] == idx:
8406 logger.info("Test: Invalid Message Length (> 50000)")
8407 return struct.pack(">BBHB3BLBBH", EAP_CODE_REQUEST, ctx['id'],
8408 4 + 1 + 3 + 4 + 4,
8409 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
8410 1, 0x02, 65535)
8411
8412 idx += 1
8413 if ctx['num'] == idx:
8414 logger.info("Test: Invalid Message Length (< current payload)")
8415 return struct.pack(">BBHB3BLBBHB", EAP_CODE_REQUEST, ctx['id'],
8416 4 + 1 + 3 + 4 + 5,
8417 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
8418 1, 0x02, 0, 0xff)
8419
8420 idx += 1
8421 if ctx['num'] == idx:
8422 logger.info("Test: Unexpected Op-Code 5 in WAIT_START state")
8423 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'],
8424 4 + 1 + 3 + 4 + 2,
8425 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
8426 5, 0x00)
8427
8428 idx += 1
8429 if ctx['num'] == idx:
8430 logger.info("Test: Valid WSC Start to start the sequence")
8431 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'],
8432 4 + 1 + 3 + 4 + 2,
8433 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
8434 1, 0x00)
8435 idx += 1
8436 if ctx['num'] == idx:
8437 logger.info("Test: No Message Length field in a fragmented packet")
8438 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'],
8439 4 + 1 + 3 + 4 + 2,
8440 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
8441 4, 0x01)
8442
8443 idx += 1
8444 if ctx['num'] == idx:
8445 logger.info("Test: Valid WSC Start to start the sequence")
8446 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'],
8447 4 + 1 + 3 + 4 + 2,
8448 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
8449 1, 0x00)
8450 idx += 1
8451 if ctx['num'] == idx:
8452 logger.info("Test: Valid first fragmented packet")
8453 return struct.pack(">BBHB3BLBBHB", EAP_CODE_REQUEST, ctx['id'],
8454 4 + 1 + 3 + 4 + 5,
8455 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
8456 4, 0x03, 10, 1)
8457 idx += 1
8458 if ctx['num'] == idx:
8459 logger.info("Test: Unexpected Op-Code 5 in fragment (expected 4)")
8460 return struct.pack(">BBHB3BLBBB", EAP_CODE_REQUEST, ctx['id'],
8461 4 + 1 + 3 + 4 + 3,
8462 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
8463 5, 0x01, 2)
8464
8465 idx += 1
8466 if ctx['num'] == idx:
8467 logger.info("Test: Valid WSC Start to start the sequence")
8468 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'],
8469 4 + 1 + 3 + 4 + 2,
8470 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
8471 1, 0x00)
8472 idx += 1
8473 if ctx['num'] == idx:
8474 logger.info("Test: Valid first fragmented packet")
8475 return struct.pack(">BBHB3BLBBHB", EAP_CODE_REQUEST, ctx['id'],
8476 4 + 1 + 3 + 4 + 5,
8477 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
8478 4, 0x03, 2, 1)
8479 idx += 1
8480 if ctx['num'] == idx:
8481 logger.info("Test: Fragment overflow")
8482 return struct.pack(">BBHB3BLBBBB", EAP_CODE_REQUEST, ctx['id'],
8483 4 + 1 + 3 + 4 + 4,
8484 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
8485 4, 0x01, 2, 3)
8486
8487 idx += 1
8488 if ctx['num'] == idx:
8489 logger.info("Test: Valid WSC Start to start the sequence")
8490 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'],
8491 4 + 1 + 3 + 4 + 2,
8492 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
8493 1, 0x00)
8494 idx += 1
8495 if ctx['num'] == idx:
8496 logger.info("Test: Unexpected Op-Code 5 in WAIT_FRAG_ACK state")
8497 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'],
8498 4 + 1 + 3 + 4 + 2,
8499 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
8500 5, 0x00)
8501
8502 idx += 1
8503 if ctx['num'] == idx:
8504 logger.info("Test: Valid WSC Start")
8505 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'],
8506 4 + 1 + 3 + 4 + 2,
8507 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
8508 1, 0x00)
8509 idx += 1
8510 if ctx['num'] == idx:
8511 logger.info("No more test responses available - test case completed")
8512 global eap_proto_wsc_test_done
8513 eap_proto_wsc_test_done = True
8514 eap_proto_wsc_wait_failure = True
8515 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
8516
8517 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
8518
8519 srv = start_radius_server(wsc_handler)
8520
8521 try:
8522 hapd = start_ap(apdev[0])
8523 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
8524
8525 i = 0
8526 while not eap_proto_wsc_test_done:
8527 i += 1
8528 logger.info("Running connection iteration %d" % i)
8529 fragment_size = 1398 if i != 9 else 50
8530 dev[0].connect("eap-test", key_mgmt="WPA-EAP", eap="WSC",
8531 fragment_size=str(fragment_size),
8532 identity="WFA-SimpleConfig-Enrollee-1-0",
8533 phase1="pin=12345670",
8534 scan_freq="2412", wait_connect=False)
8535 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5)
8536 if ev is None:
8537 raise Exception("Timeout on EAP method start")
8538 if eap_proto_wsc_wait_failure:
8539 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
8540 if ev is None:
8541 raise Exception("Timeout on EAP failure")
8542 else:
8543 time.sleep(0.1)
8544 dev[0].request("REMOVE_NETWORK all")
8545 dev[0].wait_disconnected(timeout=1)
8546 dev[0].dump_monitor()
8547 finally:
8548 stop_radius_server(srv)
8549
8550 def test_eap_canned_success_before_method(dev, apdev):
8551 """EAP protocol tests for canned EAP-Success before any method"""
8552 params = int_eap_server_params()
8553 hapd = hostapd.add_ap(apdev[0], params)
8554 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
8555 bssid = apdev[0]['bssid']
8556 hapd.request("SET ext_eapol_frame_io 1")
8557
8558 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412",
8559 phase1="allow_canned_success=1",
8560 eap="MD5", identity="user", password="password",
8561 wait_connect=False)
8562
8563 ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
8564 if ev is None:
8565 raise Exception("Timeout on EAPOL-TX from hostapd")
8566
8567 res = dev[0].request("EAPOL_RX " + bssid + " 0200000403020004")
8568 if "OK" not in res:
8569 raise Exception("EAPOL_RX to wpa_supplicant failed")
8570
8571 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=5)
8572 if ev is None:
8573 raise Exception("Timeout on EAP success")
8574 dev[0].request("REMOVE_NETWORK all")
8575 dev[0].wait_disconnected()
8576
8577 def test_eap_canned_failure_before_method(dev, apdev):
8578 """EAP protocol tests for canned EAP-Failure before any method"""
8579 params = int_eap_server_params()
8580 hapd = hostapd.add_ap(apdev[0], params)
8581 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
8582 bssid = apdev[0]['bssid']
8583 hapd.request("SET ext_eapol_frame_io 1")
8584 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412",
8585 phase1="allow_canned_success=1",
8586 eap="MD5", identity="user", password="password",
8587 wait_connect=False)
8588
8589 ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
8590 if ev is None:
8591 raise Exception("Timeout on EAPOL-TX from hostapd")
8592
8593 res = dev[0].request("EAPOL_RX " + bssid + " 0200000404020004")
8594 if "OK" not in res:
8595 raise Exception("EAPOL_RX to wpa_supplicant failed")
8596
8597 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
8598 if ev is None:
8599 raise Exception("Timeout on EAP failure")
8600 dev[0].request("REMOVE_NETWORK all")
8601 dev[0].wait_disconnected()
8602
8603 def test_eap_nak_oom(dev, apdev):
8604 """EAP-Nak OOM"""
8605 check_eap_capa(dev[0], "MD5")
8606 params = hostapd.wpa2_eap_params(ssid="eap-test")
8607 hapd = hostapd.add_ap(apdev[0], params)
8608 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
8609 with alloc_fail(dev[0], 1, "eap_msg_alloc;eap_sm_buildNak"):
8610 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8611 eap="MD5", identity="sake user", password="password",
8612 wait_connect=False)
8613 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
8614 dev[0].request("REMOVE_NETWORK all")
8615 dev[0].wait_disconnected()
8616
8617 def test_eap_nak_expanded(dev, apdev):
8618 """EAP-Nak with expanded method"""
8619 check_eap_capa(dev[0], "MD5")
8620 check_eap_capa(dev[0], "VENDOR-TEST")
8621 params = hostapd.wpa2_eap_params(ssid="eap-test")
8622 hapd = hostapd.add_ap(apdev[0], params)
8623 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
8624 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8625 eap="VENDOR-TEST WSC",
8626 identity="sake user", password="password",
8627 wait_connect=False)
8628 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=10)
8629 if ev is None or "NAK" not in ev:
8630 raise Exception("No NAK event seen")
8631
8632 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
8633 if ev is None:
8634 raise Exception("No EAP-Failure seen")
8635
8636 dev[0].request("REMOVE_NETWORK all")
8637 dev[0].wait_disconnected()
8638
8639 EAP_TLV_RESULT_TLV = 3
8640 EAP_TLV_NAK_TLV = 4
8641 EAP_TLV_ERROR_CODE_TLV = 5
8642 EAP_TLV_CONNECTION_BINDING_TLV = 6
8643 EAP_TLV_VENDOR_SPECIFIC_TLV = 7
8644 EAP_TLV_URI_TLV = 8
8645 EAP_TLV_EAP_PAYLOAD_TLV = 9
8646 EAP_TLV_INTERMEDIATE_RESULT_TLV = 10
8647 EAP_TLV_PAC_TLV = 11
8648 EAP_TLV_CRYPTO_BINDING_TLV = 12
8649 EAP_TLV_CALLING_STATION_ID_TLV = 13
8650 EAP_TLV_CALLED_STATION_ID_TLV = 14
8651 EAP_TLV_NAS_PORT_TYPE_TLV = 15
8652 EAP_TLV_SERVER_IDENTIFIER_TLV = 16
8653 EAP_TLV_IDENTITY_TYPE_TLV = 17
8654 EAP_TLV_SERVER_TRUSTED_ROOT_TLV = 18
8655 EAP_TLV_REQUEST_ACTION_TLV = 19
8656 EAP_TLV_PKCS7_TLV = 20
8657
8658 EAP_TLV_RESULT_SUCCESS = 1
8659 EAP_TLV_RESULT_FAILURE = 2
8660
8661 EAP_TLV_TYPE_MANDATORY = 0x8000
8662 EAP_TLV_TYPE_MASK = 0x3fff
8663
8664 PAC_TYPE_PAC_KEY = 1
8665 PAC_TYPE_PAC_OPAQUE = 2
8666 PAC_TYPE_CRED_LIFETIME = 3
8667 PAC_TYPE_A_ID = 4
8668 PAC_TYPE_I_ID = 5
8669 PAC_TYPE_A_ID_INFO = 7
8670 PAC_TYPE_PAC_ACKNOWLEDGEMENT = 8
8671 PAC_TYPE_PAC_INFO = 9
8672 PAC_TYPE_PAC_TYPE = 10
8673
8674 def eap_fast_start(ctx):
8675 logger.info("Send EAP-FAST/Start")
8676 return struct.pack(">BBHBBHH", EAP_CODE_REQUEST, ctx['id'],
8677 4 + 1 + 1 + 4 + 16,
8678 EAP_TYPE_FAST, 0x21, 4, 16) + 16*b'A'
8679
8680 def test_eap_fast_proto(dev, apdev):
8681 """EAP-FAST Phase protocol testing"""
8682 check_eap_capa(dev[0], "FAST")
8683 global eap_fast_proto_ctx
8684 eap_fast_proto_ctx = None
8685
8686 def eap_handler(ctx, req):
8687 logger.info("eap_handler - RX " + binascii.hexlify(req).decode())
8688 if 'num' not in ctx:
8689 ctx['num'] = 0
8690 ctx['num'] = ctx['num'] + 1
8691 if 'id' not in ctx:
8692 ctx['id'] = 1
8693 ctx['id'] = (ctx['id'] + 1) % 256
8694 idx = 0
8695
8696 global eap_fast_proto_ctx
8697 eap_fast_proto_ctx = ctx
8698 ctx['test_done'] = False
8699
8700 idx += 1
8701 if ctx['num'] == idx:
8702 return eap_fast_start(ctx)
8703 idx += 1
8704 if ctx['num'] == idx:
8705 logger.info("EAP-FAST: TLS processing failed")
8706 data = b'ABCDEFGHIK'
8707 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
8708 4 + 1 + 1 + len(data),
8709 EAP_TYPE_FAST, 0x01) + data
8710 idx += 1
8711 if ctx['num'] == idx:
8712 ctx['test_done'] = True
8713 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
8714
8715 logger.info("Past last test case")
8716 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
8717
8718 srv = start_radius_server(eap_handler)
8719 try:
8720 hapd = start_ap(apdev[0])
8721 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
8722 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8723 eap="FAST", anonymous_identity="FAST",
8724 identity="user", password="password",
8725 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
8726 phase1="fast_provisioning=1",
8727 pac_file="blob://fast_pac_proto",
8728 wait_connect=False)
8729 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5)
8730 if ev is None:
8731 raise Exception("Could not start EAP-FAST")
8732 ok = False
8733 for i in range(100):
8734 if eap_fast_proto_ctx:
8735 if eap_fast_proto_ctx['test_done']:
8736 ok = True
8737 break
8738 time.sleep(0.05)
8739 dev[0].request("REMOVE_NETWORK all")
8740 dev[0].wait_disconnected()
8741 finally:
8742 stop_radius_server(srv)
8743
8744 def run_eap_fast_phase2(dev, test_payload, test_failure=True):
8745 global eap_fast_proto_ctx
8746 eap_fast_proto_ctx = None
8747
8748 def ssl_info_callback(conn, where, ret):
8749 logger.debug("SSL: info where=%d ret=%d" % (where, ret))
8750
8751 def log_conn_state(conn):
8752 try:
8753 state = conn.state_string()
8754 except AttributeError:
8755 state = conn.get_state_string()
8756 if state:
8757 logger.info("State: " + str(state))
8758
8759 def process_clienthello(ctx, payload):
8760 logger.info("Process ClientHello")
8761 ctx['sslctx'] = OpenSSL.SSL.Context(OpenSSL.SSL.TLSv1_METHOD)
8762 ctx['sslctx'].set_info_callback(ssl_info_callback)
8763 ctx['sslctx'].load_tmp_dh("auth_serv/dh.conf")
8764 ctx['sslctx'].set_cipher_list("ADH-AES128-SHA")
8765 ctx['conn'] = OpenSSL.SSL.Connection(ctx['sslctx'], None)
8766 ctx['conn'].set_accept_state()
8767 log_conn_state(ctx['conn'])
8768 ctx['conn'].bio_write(payload)
8769 try:
8770 ctx['conn'].do_handshake()
8771 except OpenSSL.SSL.WantReadError:
8772 pass
8773 log_conn_state(ctx['conn'])
8774 data = ctx['conn'].bio_read(4096)
8775 log_conn_state(ctx['conn'])
8776 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
8777 4 + 1 + 1 + len(data),
8778 EAP_TYPE_FAST, 0x01) + data
8779
8780 def process_clientkeyexchange(ctx, payload, appl_data):
8781 logger.info("Process ClientKeyExchange")
8782 log_conn_state(ctx['conn'])
8783 ctx['conn'].bio_write(payload)
8784 try:
8785 ctx['conn'].do_handshake()
8786 except OpenSSL.SSL.WantReadError:
8787 pass
8788 ctx['conn'].send(appl_data)
8789 log_conn_state(ctx['conn'])
8790 data = ctx['conn'].bio_read(4096)
8791 log_conn_state(ctx['conn'])
8792 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
8793 4 + 1 + 1 + len(data),
8794 EAP_TYPE_FAST, 0x01) + data
8795
8796 def eap_handler(ctx, req):
8797 logger.info("eap_handler - RX " + binascii.hexlify(req).decode())
8798 if 'num' not in ctx:
8799 ctx['num'] = 0
8800 ctx['num'] = ctx['num'] + 1
8801 if 'id' not in ctx:
8802 ctx['id'] = 1
8803 ctx['id'] = (ctx['id'] + 1) % 256
8804 idx = 0
8805
8806 global eap_fast_proto_ctx
8807 eap_fast_proto_ctx = ctx
8808 ctx['test_done'] = False
8809 logger.debug("ctx['num']=%d" % ctx['num'])
8810
8811 idx += 1
8812 if ctx['num'] == idx:
8813 return eap_fast_start(ctx)
8814 idx += 1
8815 if ctx['num'] == idx:
8816 return process_clienthello(ctx, req[6:])
8817 idx += 1
8818 if ctx['num'] == idx:
8819 if not test_failure:
8820 ctx['test_done'] = True
8821 return process_clientkeyexchange(ctx, req[6:], test_payload)
8822 idx += 1
8823 if ctx['num'] == idx:
8824 ctx['test_done'] = True
8825 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
8826
8827 logger.info("Past last test case")
8828 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
8829
8830 srv = start_radius_server(eap_handler)
8831 try:
8832 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8833 eap="FAST", anonymous_identity="FAST",
8834 identity="user", password="password",
8835 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
8836 phase1="fast_provisioning=1",
8837 pac_file="blob://fast_pac_proto",
8838 wait_connect=False)
8839 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5)
8840 if ev is None:
8841 raise Exception("Could not start EAP-FAST")
8842 dev[0].dump_monitor()
8843 ok = False
8844 for i in range(100):
8845 if eap_fast_proto_ctx:
8846 if eap_fast_proto_ctx['test_done']:
8847 ok = True
8848 break
8849 time.sleep(0.05)
8850 time.sleep(0.1)
8851 dev[0].request("REMOVE_NETWORK all")
8852 dev[0].wait_disconnected()
8853 if not ok:
8854 raise Exception("EAP-FAST TLS exchange did not complete")
8855 for i in range(3):
8856 dev[i].dump_monitor()
8857 finally:
8858 stop_radius_server(srv)
8859
8860 def test_eap_fast_proto_phase2(dev, apdev):
8861 """EAP-FAST Phase 2 protocol testing"""
8862 if not openssl_imported:
8863 raise HwsimSkip("OpenSSL python method not available")
8864 check_eap_capa(dev[0], "FAST")
8865 hapd = start_ap(apdev[0])
8866 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
8867
8868 tests = [("Too short Phase 2 TLV frame (len=3)",
8869 "ABC",
8870 False),
8871 ("EAP-FAST: TLV overflow",
8872 struct.pack(">HHB", 0, 2, 0xff),
8873 False),
8874 ("EAP-FAST: Unknown TLV (optional and mandatory)",
8875 struct.pack(">HHB", 0, 1, 0xff) +
8876 struct.pack(">HHB", EAP_TLV_TYPE_MANDATORY, 1, 0xff),
8877 True),
8878 ("EAP-FAST: More than one EAP-Payload TLV in the message",
8879 struct.pack(">HHBHHB",
8880 EAP_TLV_EAP_PAYLOAD_TLV, 1, 0xff,
8881 EAP_TLV_EAP_PAYLOAD_TLV, 1, 0xff),
8882 True),
8883 ("EAP-FAST: Unknown Result 255 and More than one Result TLV in the message",
8884 struct.pack(">HHHHHH",
8885 EAP_TLV_RESULT_TLV, 2, 0xff,
8886 EAP_TLV_RESULT_TLV, 2, 0xff),
8887 True),
8888 ("EAP-FAST: Too short Result TLV",
8889 struct.pack(">HHB", EAP_TLV_RESULT_TLV, 1, 0xff),
8890 True),
8891 ("EAP-FAST: Unknown Intermediate Result 255 and More than one Intermediate-Result TLV in the message",
8892 struct.pack(">HHHHHH",
8893 EAP_TLV_INTERMEDIATE_RESULT_TLV, 2, 0xff,
8894 EAP_TLV_INTERMEDIATE_RESULT_TLV, 2, 0xff),
8895 True),
8896 ("EAP-FAST: Too short Intermediate-Result TLV",
8897 struct.pack(">HHB", EAP_TLV_INTERMEDIATE_RESULT_TLV, 1, 0xff),
8898 True),
8899 ("EAP-FAST: More than one Crypto-Binding TLV in the message",
8900 struct.pack(">HH", EAP_TLV_CRYPTO_BINDING_TLV, 60) + 60*b'A' +
8901 struct.pack(">HH", EAP_TLV_CRYPTO_BINDING_TLV, 60) + 60*b'A',
8902 True),
8903 ("EAP-FAST: Too short Crypto-Binding TLV",
8904 struct.pack(">HHB", EAP_TLV_CRYPTO_BINDING_TLV, 1, 0xff),
8905 True),
8906 ("EAP-FAST: More than one Request-Action TLV in the message",
8907 struct.pack(">HHBBHHBB",
8908 EAP_TLV_REQUEST_ACTION_TLV, 2, 0xff, 0xff,
8909 EAP_TLV_REQUEST_ACTION_TLV, 2, 0xff, 0xff),
8910 True),
8911 ("EAP-FAST: Too short Request-Action TLV",
8912 struct.pack(">HHB", EAP_TLV_REQUEST_ACTION_TLV, 1, 0xff),
8913 True),
8914 ("EAP-FAST: More than one PAC TLV in the message",
8915 struct.pack(">HHBHHB",
8916 EAP_TLV_PAC_TLV, 1, 0xff,
8917 EAP_TLV_PAC_TLV, 1, 0xff),
8918 True),
8919 ("EAP-FAST: Too short EAP Payload TLV (Len=3)",
8920 struct.pack(">HH3B",
8921 EAP_TLV_EAP_PAYLOAD_TLV, 3, 0, 0, 0),
8922 False),
8923 ("EAP-FAST: Too short Phase 2 request (Len=0)",
8924 struct.pack(">HHBBH",
8925 EAP_TLV_EAP_PAYLOAD_TLV, 4,
8926 EAP_CODE_REQUEST, 0, 0),
8927 False),
8928 ("EAP-FAST: EAP packet overflow in EAP Payload TLV",
8929 struct.pack(">HHBBH",
8930 EAP_TLV_EAP_PAYLOAD_TLV, 4,
8931 EAP_CODE_REQUEST, 0, 4 + 1),
8932 False),
8933 ("EAP-FAST: Unexpected code=0 in Phase 2 EAP header",
8934 struct.pack(">HHBBH",
8935 EAP_TLV_EAP_PAYLOAD_TLV, 4,
8936 0, 0, 0),
8937 False),
8938 ("EAP-FAST: PAC TLV without Result TLV acknowledging success",
8939 struct.pack(">HHB", EAP_TLV_PAC_TLV, 1, 0xff),
8940 True),
8941 ("EAP-FAST: PAC TLV does not include all the required fields",
8942 struct.pack(">HHH", EAP_TLV_RESULT_TLV, 2,
8943 EAP_TLV_RESULT_SUCCESS) +
8944 struct.pack(">HHB", EAP_TLV_PAC_TLV, 1, 0xff),
8945 True),
8946 ("EAP-FAST: Invalid PAC-Key length 0, Ignored unknown PAC type 0, and PAC TLV overrun (type=0 len=2 left=1)",
8947 struct.pack(">HHH", EAP_TLV_RESULT_TLV, 2,
8948 EAP_TLV_RESULT_SUCCESS) +
8949 struct.pack(">HHHHHHHHB", EAP_TLV_PAC_TLV, 4 + 4 + 5,
8950 PAC_TYPE_PAC_KEY, 0, 0, 0, 0, 2, 0),
8951 True),
8952 ("EAP-FAST: PAC-Info does not include all the required fields",
8953 struct.pack(">HHH", EAP_TLV_RESULT_TLV, 2,
8954 EAP_TLV_RESULT_SUCCESS) +
8955 struct.pack(">HHHHHHHH", EAP_TLV_PAC_TLV, 4 + 4 + 4 + 32,
8956 PAC_TYPE_PAC_OPAQUE, 0,
8957 PAC_TYPE_PAC_INFO, 0,
8958 PAC_TYPE_PAC_KEY, 32) + 32*b'A',
8959 True),
8960 ("EAP-FAST: Invalid CRED_LIFETIME length, Ignored unknown PAC-Info type 0, and Invalid PAC-Type length 1",
8961 struct.pack(">HHH", EAP_TLV_RESULT_TLV, 2,
8962 EAP_TLV_RESULT_SUCCESS) +
8963 struct.pack(">HHHHHHHHHHHHBHH", EAP_TLV_PAC_TLV, 4 + 4 + 13 + 4 + 32,
8964 PAC_TYPE_PAC_OPAQUE, 0,
8965 PAC_TYPE_PAC_INFO, 13, PAC_TYPE_CRED_LIFETIME, 0,
8966 0, 0, PAC_TYPE_PAC_TYPE, 1, 0,
8967 PAC_TYPE_PAC_KEY, 32) + 32*b'A',
8968 True),
8969 ("EAP-FAST: Unsupported PAC-Type 0",
8970 struct.pack(">HHH", EAP_TLV_RESULT_TLV, 2,
8971 EAP_TLV_RESULT_SUCCESS) +
8972 struct.pack(">HHHHHHHHHHH", EAP_TLV_PAC_TLV, 4 + 4 + 6 + 4 + 32,
8973 PAC_TYPE_PAC_OPAQUE, 0,
8974 PAC_TYPE_PAC_INFO, 6, PAC_TYPE_PAC_TYPE, 2, 0,
8975 PAC_TYPE_PAC_KEY, 32) + 32*b'A',
8976 True),
8977 ("EAP-FAST: PAC-Info overrun (type=0 len=2 left=1)",
8978 struct.pack(">HHH", EAP_TLV_RESULT_TLV, 2,
8979 EAP_TLV_RESULT_SUCCESS) +
8980 struct.pack(">HHHHHHHHBHH", EAP_TLV_PAC_TLV, 4 + 4 + 5 + 4 + 32,
8981 PAC_TYPE_PAC_OPAQUE, 0,
8982 PAC_TYPE_PAC_INFO, 5, 0, 2, 1,
8983 PAC_TYPE_PAC_KEY, 32) + 32*b'A',
8984 True),
8985 ("EAP-FAST: Valid PAC",
8986 struct.pack(">HHH", EAP_TLV_RESULT_TLV, 2,
8987 EAP_TLV_RESULT_SUCCESS) +
8988 struct.pack(">HHHHHHHHBHHBHH", EAP_TLV_PAC_TLV,
8989 4 + 4 + 10 + 4 + 32,
8990 PAC_TYPE_PAC_OPAQUE, 0,
8991 PAC_TYPE_PAC_INFO, 10, PAC_TYPE_A_ID, 1, 0x41,
8992 PAC_TYPE_A_ID_INFO, 1, 0x42,
8993 PAC_TYPE_PAC_KEY, 32) + 32*b'A',
8994 True),
8995 ("EAP-FAST: Invalid version/subtype in Crypto-Binding TLV",
8996 struct.pack(">HH", EAP_TLV_CRYPTO_BINDING_TLV, 60) + 60*b'A',
8997 True)]
8998 for title, payload, failure in tests:
8999 logger.info("Phase 2 test: " + title)
9000 run_eap_fast_phase2(dev, payload, failure)
9001
9002 def test_eap_fast_tlv_nak_oom(dev, apdev):
9003 """EAP-FAST Phase 2 TLV NAK OOM"""
9004 if not openssl_imported:
9005 raise HwsimSkip("OpenSSL python method not available")
9006 check_eap_capa(dev[0], "FAST")
9007 hapd = start_ap(apdev[0])
9008 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
9009
9010 with alloc_fail(dev[0], 1, "eap_fast_tlv_nak"):
9011 run_eap_fast_phase2(dev, struct.pack(">HHB", EAP_TLV_TYPE_MANDATORY,
9012 1, 0xff), False)