]> git.ipfire.org Git - thirdparty/hostap.git/blob - tests/hwsim/test_eap_proto.py
tests: EAP-IKEV2 server local errors and protocol testing
[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 dev[0].dump_monitor()
797
798 tests = [(1, "eap_msg_alloc;eap_sake_build_msg;eap_sake_process_challenge"),
799 (1, "=eap_sake_process_challenge"),
800 (1, "eap_sake_compute_mic;eap_sake_process_challenge"),
801 (1, "eap_sake_build_msg;eap_sake_process_confirm"),
802 (1, "eap_sake_compute_mic;eap_sake_process_confirm"),
803 (2, "eap_sake_compute_mic;=eap_sake_process_confirm"),
804 (1, "eap_sake_getKey"),
805 (1, "eap_sake_get_emsk"),
806 (1, "eap_sake_get_session_id")]
807 for count, func in tests:
808 with alloc_fail(dev[0], count, func):
809 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
810 eap="SAKE", identity="sake user@domain",
811 password_hex="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
812 erp="1",
813 wait_connect=False)
814 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
815 timeout=15)
816 if ev is None:
817 raise Exception("Timeout on EAP start")
818 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
819 dev[0].request("REMOVE_NETWORK all")
820 dev[0].wait_disconnected()
821 dev[0].dump_monitor()
822
823 tests = [(1, "os_get_random;eap_sake_process_challenge"),
824 (1, "eap_sake_derive_keys;eap_sake_process_challenge")]
825 for count, func in tests:
826 with fail_test(dev[0], count, func):
827 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
828 eap="SAKE", identity="sake user",
829 password_hex="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
830 wait_connect=False)
831 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15)
832 if ev is None:
833 raise Exception("Timeout on EAP start")
834 wait_fail_trigger(dev[0], "GET_FAIL")
835 dev[0].request("REMOVE_NETWORK all")
836 dev[0].wait_disconnected()
837 dev[0].dump_monitor()
838
839 def test_eap_proto_sake_errors2(dev, apdev):
840 """EAP-SAKE protocol tests (2)"""
841 def sake_handler(ctx, req):
842 logger.info("sake_handler - RX " + binascii.hexlify(req).decode())
843 if 'num' not in ctx:
844 ctx['num'] = 0
845 ctx['num'] += 1
846 if 'id' not in ctx:
847 ctx['id'] = 1
848 ctx['id'] = (ctx['id'] + 1) % 256
849 idx = 0
850
851 idx += 1
852 if ctx['num'] == idx:
853 logger.info("Test: Identity subtype")
854 return struct.pack(">BBHBBBBBBH", EAP_CODE_REQUEST, ctx['id'],
855 4 + 1 + 3 + 4,
856 EAP_TYPE_SAKE,
857 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_IDENTITY,
858 EAP_SAKE_AT_ANY_ID_REQ, 4, 0)
859
860 srv = start_radius_server(sake_handler)
861
862 try:
863 hapd = start_ap(apdev[0])
864 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
865
866 with alloc_fail(dev[0], 1, "eap_msg_alloc;eap_sake_build_msg;eap_sake_process_identity"):
867 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
868 eap="SAKE", identity="sake user",
869 password_hex="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
870 wait_connect=False)
871 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
872 timeout=15)
873 if ev is None:
874 raise Exception("Timeout on EAP start")
875 dev[0].request("REMOVE_NETWORK all")
876 dev[0].wait_disconnected()
877
878 finally:
879 stop_radius_server(srv)
880
881 def run_eap_sake_connect(dev):
882 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412",
883 eap="SAKE", identity="sake user",
884 password_hex="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
885 wait_connect=False)
886 ev = dev.wait_event(["CTRL-EVENT-EAP-SUCCESS", "CTRL-EVENT-EAP-FAILURE",
887 "CTRL-EVENT-DISCONNECTED"],
888 timeout=1)
889 dev.request("REMOVE_NETWORK all")
890 if not ev or "CTRL-EVENT-DISCONNECTED" not in ev:
891 dev.wait_disconnected()
892 dev.dump_monitor()
893
894 def test_eap_proto_sake_errors_server(dev, apdev):
895 """EAP-SAKE local error cases on server"""
896 check_eap_capa(dev[0], "SAKE")
897 params = int_eap_server_params()
898 params['erp_domain'] = 'example.com'
899 params['eap_server_erp'] = '1'
900 hapd = hostapd.add_ap(apdev[0], params)
901 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
902
903 tests = [(1, "eap_sake_init"),
904 (1, "eap_sake_build_msg;eap_sake_build_challenge"),
905 (1, "eap_sake_build_msg;eap_sake_build_confirm"),
906 (1, "eap_sake_compute_mic;eap_sake_build_confirm"),
907 (1, "eap_sake_process_challenge"),
908 (1, "eap_sake_getKey"),
909 (1, "eap_sake_get_emsk"),
910 (1, "eap_sake_get_session_id")]
911 for count, func in tests:
912 with alloc_fail(hapd, count, func):
913 run_eap_sake_connect(dev[0])
914
915 tests = [(1, "eap_sake_init"),
916 (1, "eap_sake_build_challenge"),
917 (1, "eap_sake_build_confirm"),
918 (1, "eap_sake_derive_keys;eap_sake_process_challenge"),
919 (1, "eap_sake_compute_mic;eap_sake_process_challenge"),
920 (1, "eap_sake_compute_mic;eap_sake_process_confirm"),
921 (1, "eap_sake_compute_mic;eap_sake_build_confirm"),
922 (1, "eap_sake_process_confirm")]
923 for count, func in tests:
924 with fail_test(hapd, count, func):
925 run_eap_sake_connect(dev[0])
926
927 def start_sake_assoc(dev, hapd):
928 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412",
929 eap="SAKE", identity="sake user",
930 password_hex="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
931 wait_connect=False)
932 proxy_msg(hapd, dev) # EAP-Identity/Request
933 proxy_msg(dev, hapd) # EAP-Identity/Response
934 proxy_msg(hapd, dev) # SAKE/Challenge/Request
935
936 def stop_sake_assoc(dev, hapd):
937 dev.request("REMOVE_NETWORK all")
938 dev.wait_disconnected()
939 dev.dump_monitor()
940 hapd.dump_monitor()
941
942 def test_eap_proto_sake_server(dev, apdev):
943 """EAP-SAKE protocol testing for the server"""
944 check_eap_capa(dev[0], "SAKE")
945 params = int_eap_server_params()
946 params['erp_domain'] = 'example.com'
947 params['eap_server_erp'] = '1'
948 hapd = hostapd.add_ap(apdev[0], params)
949 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
950 hapd.request("SET ext_eapol_frame_io 1")
951 dev[0].request("SET ext_eapol_frame_io 1")
952
953 # Successful exchange to verify proxying mechanism
954 start_sake_assoc(dev[0], hapd)
955 proxy_msg(dev[0], hapd) # SAKE/Challenge/Response
956 proxy_msg(hapd, dev[0]) # SAKE/Confirm/Request
957 proxy_msg(dev[0], hapd) # SAKE/Confirm/Response
958 proxy_msg(hapd, dev[0]) # EAP-Success
959 proxy_msg(hapd, dev[0]) # EAPOL-Key msg 1/4
960 proxy_msg(dev[0], hapd) # EAPOL-Key msg 2/4
961 proxy_msg(hapd, dev[0]) # EAPOL-Key msg 3/4
962 proxy_msg(dev[0], hapd) # EAPOL-Key msg 4/4
963 dev[0].wait_connected()
964 stop_sake_assoc(dev[0], hapd)
965
966 start_sake_assoc(dev[0], hapd)
967 resp = rx_msg(dev[0])
968 # Too short EAP-SAKE header
969 # --> EAP-SAKE: Invalid frame
970 msg = resp[0:4] + "0007" + resp[8:12] + "0007" + "300200"
971 tx_msg(dev[0], hapd, msg)
972 # Unknown version
973 # --> EAP-SAKE: Unknown version 1
974 msg = resp[0:4] + "0008" + resp[8:12] + "0008" + "30010000"
975 tx_msg(dev[0], hapd, msg)
976 # Unknown session
977 # --> EAP-SAKE: Session ID mismatch
978 sess, = struct.unpack('B', binascii.unhexlify(resp[20:22]))
979 sess = binascii.hexlify(struct.pack('B', sess + 1)).decode()
980 msg = resp[0:4] + "0008" + resp[8:12] + "0008" + "3002" + sess + "00"
981 tx_msg(dev[0], hapd, msg)
982 # Unknown subtype
983 # --> EAP-SAKE: Unexpected subtype=5 in state=1
984 msg = resp[0:22] + "05" + resp[24:]
985 tx_msg(dev[0], hapd, msg)
986 # Empty challenge
987 # --> EAP-SAKE: Response/Challenge did not include AT_RAND_P or AT_MIC_P
988 msg = resp[0:4] + "0008" + resp[8:12] + "0008" + resp[16:24]
989 tx_msg(dev[0], hapd, msg)
990 rx_msg(hapd)
991 stop_sake_assoc(dev[0], hapd)
992
993 start_sake_assoc(dev[0], hapd)
994 resp = rx_msg(dev[0])
995 # Invalid attribute in challenge
996 # --> EAP-SAKE: Too short attribute
997 msg = resp[0:4] + "0009" + resp[8:12] + "0009" + resp[16:26]
998 tx_msg(dev[0], hapd, msg)
999 rx_msg(hapd)
1000 stop_sake_assoc(dev[0], hapd)
1001
1002 start_sake_assoc(dev[0], hapd)
1003 proxy_msg(dev[0], hapd) # SAKE/Challenge/Response
1004 proxy_msg(hapd, dev[0]) # SAKE/Confirm/Request
1005 resp = rx_msg(dev[0])
1006 # Empty confirm
1007 # --> EAP-SAKE: Response/Confirm did not include AT_MIC_P
1008 msg = resp[0:4] + "0008" + resp[8:12] + "0008" + resp[16:26]
1009 tx_msg(dev[0], hapd, msg)
1010 rx_msg(hapd)
1011 stop_sake_assoc(dev[0], hapd)
1012
1013 start_sake_assoc(dev[0], hapd)
1014 proxy_msg(dev[0], hapd) # SAKE/Challenge/Response
1015 proxy_msg(hapd, dev[0]) # SAKE/Confirm/Request
1016 resp = rx_msg(dev[0])
1017 # Invalid attribute in confirm
1018 # --> EAP-SAKE: Too short attribute
1019 msg = resp[0:4] + "0009" + resp[8:12] + "0009" + resp[16:26]
1020 tx_msg(dev[0], hapd, msg)
1021 rx_msg(hapd)
1022 stop_sake_assoc(dev[0], hapd)
1023
1024 start_sake_assoc(dev[0], hapd)
1025 proxy_msg(dev[0], hapd) # SAKE/Challenge/Response
1026 proxy_msg(hapd, dev[0]) # SAKE/Confirm/Request
1027 resp = rx_msg(dev[0])
1028 # Corrupted AT_MIC_P value
1029 # --> EAP-SAKE: Incorrect AT_MIC_P
1030 msg = resp[0:30] + "000000000000" + resp[42:]
1031 tx_msg(dev[0], hapd, msg)
1032 rx_msg(hapd)
1033 stop_sake_assoc(dev[0], hapd)
1034
1035 def test_eap_proto_leap(dev, apdev):
1036 """EAP-LEAP protocol tests"""
1037 check_eap_capa(dev[0], "LEAP")
1038 def leap_handler(ctx, req):
1039 logger.info("leap_handler - RX " + binascii.hexlify(req).decode())
1040 if 'num' not in ctx:
1041 ctx['num'] = 0
1042 ctx['num'] = ctx['num'] + 1
1043 if 'id' not in ctx:
1044 ctx['id'] = 1
1045 ctx['id'] = (ctx['id'] + 1) % 256
1046
1047 if ctx['num'] == 1:
1048 logger.info("Test: Missing payload")
1049 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
1050 4 + 1,
1051 EAP_TYPE_LEAP)
1052
1053 if ctx['num'] == 2:
1054 logger.info("Test: Unexpected version")
1055 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
1056 4 + 1 + 3,
1057 EAP_TYPE_LEAP,
1058 0, 0, 0)
1059
1060 if ctx['num'] == 3:
1061 logger.info("Test: Invalid challenge length")
1062 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
1063 4 + 1 + 3,
1064 EAP_TYPE_LEAP,
1065 1, 0, 0)
1066
1067 if ctx['num'] == 4:
1068 logger.info("Test: Truncated challenge")
1069 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
1070 4 + 1 + 3,
1071 EAP_TYPE_LEAP,
1072 1, 0, 8)
1073
1074 if ctx['num'] == 5:
1075 logger.info("Test: Valid challenge")
1076 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
1077 4 + 1 + 3 + 8,
1078 EAP_TYPE_LEAP,
1079 1, 0, 8, 0, 0)
1080 if ctx['num'] == 6:
1081 logger.info("Test: Missing payload in Response")
1082 return struct.pack(">BBHB", EAP_CODE_RESPONSE, ctx['id'],
1083 4 + 1,
1084 EAP_TYPE_LEAP)
1085
1086 if ctx['num'] == 7:
1087 logger.info("Test: Valid challenge")
1088 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
1089 4 + 1 + 3 + 8,
1090 EAP_TYPE_LEAP,
1091 1, 0, 8, 0, 0)
1092 if ctx['num'] == 8:
1093 logger.info("Test: Unexpected version in Response")
1094 return struct.pack(">BBHBBBB", EAP_CODE_RESPONSE, ctx['id'],
1095 4 + 1 + 3,
1096 EAP_TYPE_LEAP,
1097 0, 0, 8)
1098
1099 if ctx['num'] == 9:
1100 logger.info("Test: Valid challenge")
1101 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
1102 4 + 1 + 3 + 8,
1103 EAP_TYPE_LEAP,
1104 1, 0, 8, 0, 0)
1105 if ctx['num'] == 10:
1106 logger.info("Test: Invalid challenge length in Response")
1107 return struct.pack(">BBHBBBB", EAP_CODE_RESPONSE, ctx['id'],
1108 4 + 1 + 3,
1109 EAP_TYPE_LEAP,
1110 1, 0, 0)
1111
1112 if ctx['num'] == 11:
1113 logger.info("Test: Valid challenge")
1114 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
1115 4 + 1 + 3 + 8,
1116 EAP_TYPE_LEAP,
1117 1, 0, 8, 0, 0)
1118 if ctx['num'] == 12:
1119 logger.info("Test: Truncated challenge in Response")
1120 return struct.pack(">BBHBBBB", EAP_CODE_RESPONSE, ctx['id'],
1121 4 + 1 + 3,
1122 EAP_TYPE_LEAP,
1123 1, 0, 24)
1124
1125 if ctx['num'] == 13:
1126 logger.info("Test: Valid challenge")
1127 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
1128 4 + 1 + 3 + 8,
1129 EAP_TYPE_LEAP,
1130 1, 0, 8, 0, 0)
1131 if ctx['num'] == 14:
1132 logger.info("Test: Invalid challange value in Response")
1133 return struct.pack(">BBHBBBB6L", EAP_CODE_RESPONSE, ctx['id'],
1134 4 + 1 + 3 + 24,
1135 EAP_TYPE_LEAP,
1136 1, 0, 24,
1137 0, 0, 0, 0, 0, 0)
1138
1139 if ctx['num'] == 15:
1140 logger.info("Test: Valid challenge")
1141 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
1142 4 + 1 + 3 + 8,
1143 EAP_TYPE_LEAP,
1144 1, 0, 8, 0, 0)
1145 if ctx['num'] == 16:
1146 logger.info("Test: Valid challange value in Response")
1147 return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'],
1148 4 + 1 + 3 + 24,
1149 EAP_TYPE_LEAP,
1150 1, 0, 24,
1151 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd,
1152 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04,
1153 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66)
1154
1155 if ctx['num'] == 17:
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 if ctx['num'] == 18:
1162 logger.info("Test: Success")
1163 return struct.pack(">BBHB", EAP_CODE_SUCCESS, ctx['id'],
1164 4 + 1,
1165 EAP_TYPE_LEAP)
1166 # hostapd will drop the next frame in the sequence
1167
1168 if ctx['num'] == 19:
1169 logger.info("Test: Valid challenge")
1170 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
1171 4 + 1 + 3 + 8,
1172 EAP_TYPE_LEAP,
1173 1, 0, 8, 0, 0)
1174 if ctx['num'] == 20:
1175 logger.info("Test: Failure")
1176 return struct.pack(">BBHB", EAP_CODE_FAILURE, ctx['id'],
1177 4 + 1,
1178 EAP_TYPE_LEAP)
1179
1180 return None
1181
1182 srv = start_radius_server(leap_handler)
1183
1184 try:
1185 hapd = start_ap(apdev[0])
1186 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
1187
1188 for i in range(0, 12):
1189 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1190 eap="LEAP", identity="user", password="password",
1191 wait_connect=False)
1192 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15)
1193 if ev is None:
1194 raise Exception("Timeout on EAP start")
1195 time.sleep(0.1)
1196 if i == 10:
1197 logger.info("Wait for additional roundtrip")
1198 time.sleep(1)
1199 dev[0].request("REMOVE_NETWORK all")
1200 finally:
1201 stop_radius_server(srv)
1202
1203 def test_eap_proto_leap_errors(dev, apdev):
1204 """EAP-LEAP protocol tests (error paths)"""
1205 check_eap_capa(dev[0], "LEAP")
1206
1207 def leap_handler2(ctx, req):
1208 logger.info("leap_handler2 - RX " + binascii.hexlify(req).decode())
1209 if 'num' not in ctx:
1210 ctx['num'] = 0
1211 ctx['num'] = ctx['num'] + 1
1212 if 'id' not in ctx:
1213 ctx['id'] = 1
1214 ctx['id'] = (ctx['id'] + 1) % 256
1215 idx = 0
1216
1217 idx += 1
1218 if ctx['num'] == idx:
1219 logger.info("Test: Valid challenge")
1220 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
1221 4 + 1 + 3 + 8,
1222 EAP_TYPE_LEAP,
1223 1, 0, 8, 0, 0)
1224 idx += 1
1225 if ctx['num'] == idx:
1226 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
1227
1228 idx += 1
1229 if ctx['num'] == idx:
1230 logger.info("Test: Valid challenge")
1231 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
1232 4 + 1 + 3 + 8,
1233 EAP_TYPE_LEAP,
1234 1, 0, 8, 0, 0)
1235
1236 idx += 1
1237 if ctx['num'] == idx:
1238 logger.info("Test: Valid challenge")
1239 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
1240 4 + 1 + 3 + 8,
1241 EAP_TYPE_LEAP,
1242 1, 0, 8, 0, 0)
1243 idx += 1
1244 if ctx['num'] == idx:
1245 logger.info("Test: Success")
1246 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4)
1247
1248 idx += 1
1249 if ctx['num'] == idx:
1250 logger.info("Test: Valid challenge")
1251 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
1252 4 + 1 + 3 + 8,
1253 EAP_TYPE_LEAP,
1254 1, 0, 8, 0, 0)
1255 idx += 1
1256 if ctx['num'] == idx:
1257 logger.info("Test: Success")
1258 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4)
1259
1260 idx += 1
1261 if ctx['num'] == idx:
1262 logger.info("Test: Valid challenge")
1263 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
1264 4 + 1 + 3 + 8,
1265 EAP_TYPE_LEAP,
1266 1, 0, 8, 0, 0)
1267 idx += 1
1268 if ctx['num'] == idx:
1269 logger.info("Test: Valid challange value in Response")
1270 return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'],
1271 4 + 1 + 3 + 24,
1272 EAP_TYPE_LEAP,
1273 1, 0, 24,
1274 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd,
1275 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04,
1276 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66)
1277
1278 idx += 1
1279 if ctx['num'] == idx:
1280 logger.info("Test: Valid challenge")
1281 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
1282 4 + 1 + 3 + 8,
1283 EAP_TYPE_LEAP,
1284 1, 0, 8, 0, 0)
1285 idx += 1
1286 if ctx['num'] == idx:
1287 logger.info("Test: Valid challange value in Response")
1288 return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'],
1289 4 + 1 + 3 + 24,
1290 EAP_TYPE_LEAP,
1291 1, 0, 24,
1292 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd,
1293 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04,
1294 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66)
1295
1296 idx += 1
1297 if ctx['num'] == idx:
1298 logger.info("Test: Valid challenge")
1299 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
1300 4 + 1 + 3 + 8,
1301 EAP_TYPE_LEAP,
1302 1, 0, 8, 0, 0)
1303 idx += 1
1304 if ctx['num'] == idx:
1305 logger.info("Test: Valid challange value in Response")
1306 return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'],
1307 4 + 1 + 3 + 24,
1308 EAP_TYPE_LEAP,
1309 1, 0, 24,
1310 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd,
1311 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04,
1312 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66)
1313
1314 idx += 1
1315 if ctx['num'] == idx:
1316 logger.info("Test: Valid challenge")
1317 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
1318 4 + 1 + 3 + 8,
1319 EAP_TYPE_LEAP,
1320 1, 0, 8, 0, 0)
1321 idx += 1
1322 if ctx['num'] == idx:
1323 logger.info("Test: Valid challange value in Response")
1324 return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'],
1325 4 + 1 + 3 + 24,
1326 EAP_TYPE_LEAP,
1327 1, 0, 24,
1328 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd,
1329 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04,
1330 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66)
1331
1332 idx += 1
1333 if ctx['num'] == idx:
1334 logger.info("Test: Valid challenge")
1335 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
1336 4 + 1 + 3 + 8,
1337 EAP_TYPE_LEAP,
1338 1, 0, 8, 0, 0)
1339 idx += 1
1340 if ctx['num'] == idx:
1341 logger.info("Test: Valid challange value in Response")
1342 return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'],
1343 4 + 1 + 3 + 24,
1344 EAP_TYPE_LEAP,
1345 1, 0, 24,
1346 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd,
1347 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04,
1348 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66)
1349
1350 idx += 1
1351 if ctx['num'] == idx:
1352 logger.info("Test: Valid challenge")
1353 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
1354 4 + 1 + 3 + 8,
1355 EAP_TYPE_LEAP,
1356 1, 0, 8, 0, 0)
1357 idx += 1
1358 if ctx['num'] == idx:
1359 logger.info("Test: Valid challange value in Response")
1360 return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'],
1361 4 + 1 + 3 + 24,
1362 EAP_TYPE_LEAP,
1363 1, 0, 24,
1364 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd,
1365 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04,
1366 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66)
1367
1368 idx += 1
1369 if ctx['num'] == idx:
1370 logger.info("Test: Valid challenge")
1371 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
1372 4 + 1 + 3 + 8,
1373 EAP_TYPE_LEAP,
1374 1, 0, 8, 0, 0)
1375 idx += 1
1376 if ctx['num'] == idx:
1377 logger.info("Test: Valid challange value in Response")
1378 return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'],
1379 4 + 1 + 3 + 24,
1380 EAP_TYPE_LEAP,
1381 1, 0, 24,
1382 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd,
1383 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04,
1384 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66)
1385
1386 idx += 1
1387 if ctx['num'] == idx:
1388 logger.info("Test: Valid challenge")
1389 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
1390 4 + 1 + 3 + 8,
1391 EAP_TYPE_LEAP,
1392 1, 0, 8, 0, 0)
1393
1394 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
1395
1396 srv = start_radius_server(leap_handler2)
1397
1398 try:
1399 hapd = start_ap(apdev[0])
1400 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
1401
1402 with alloc_fail(dev[0], 1, "eap_leap_init"):
1403 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1404 eap="LEAP", identity="user", password="password",
1405 wait_connect=False)
1406 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
1407 dev[0].request("REMOVE_NETWORK all")
1408 dev[0].wait_disconnected()
1409
1410 with alloc_fail(dev[0], 1, "eap_msg_alloc;eap_leap_process_request"):
1411 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1412 eap="LEAP", identity="user",
1413 password_hex="hash:8846f7eaee8fb117ad06bdd830b7586c",
1414 wait_connect=False)
1415 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
1416 dev[0].request("REMOVE_NETWORK all")
1417 dev[0].wait_disconnected()
1418
1419 with alloc_fail(dev[0], 1, "eap_leap_process_success"):
1420 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1421 eap="LEAP", identity="user", password="password",
1422 wait_connect=False)
1423 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
1424 dev[0].request("REMOVE_NETWORK all")
1425 dev[0].wait_disconnected()
1426
1427 with fail_test(dev[0], 1, "os_get_random;eap_leap_process_success"):
1428 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1429 eap="LEAP", identity="user", password="password",
1430 wait_connect=False)
1431 wait_fail_trigger(dev[0], "GET_FAIL")
1432 dev[0].request("REMOVE_NETWORK all")
1433 dev[0].wait_disconnected()
1434
1435 with fail_test(dev[0], 1, "eap_leap_process_response"):
1436 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1437 eap="LEAP", identity="user",
1438 password_hex="hash:8846f7eaee8fb117ad06bdd830b7586c",
1439 wait_connect=False)
1440 wait_fail_trigger(dev[0], "GET_FAIL")
1441 dev[0].request("REMOVE_NETWORK all")
1442 dev[0].wait_disconnected()
1443
1444 with fail_test(dev[0], 1, "nt_password_hash;eap_leap_process_response"):
1445 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1446 eap="LEAP", identity="user", password="password",
1447 wait_connect=False)
1448 wait_fail_trigger(dev[0], "GET_FAIL")
1449 dev[0].request("REMOVE_NETWORK all")
1450 dev[0].wait_disconnected()
1451
1452 with fail_test(dev[0], 1, "hash_nt_password_hash;eap_leap_process_response"):
1453 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1454 eap="LEAP", identity="user", password="password",
1455 wait_connect=False)
1456 wait_fail_trigger(dev[0], "GET_FAIL")
1457 dev[0].request("REMOVE_NETWORK all")
1458 dev[0].wait_disconnected()
1459
1460 with alloc_fail(dev[0], 1, "eap_leap_getKey"):
1461 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1462 eap="LEAP", identity="user",
1463 password_hex="hash:8846f7eaee8fb117ad06bdd830b7586c",
1464 wait_connect=False)
1465 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
1466 dev[0].request("REMOVE_NETWORK all")
1467 dev[0].wait_disconnected()
1468
1469 with fail_test(dev[0], 1, "eap_leap_getKey"):
1470 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1471 eap="LEAP", identity="user",
1472 password_hex="hash:8846f7eaee8fb117ad06bdd830b7586c",
1473 wait_connect=False)
1474 wait_fail_trigger(dev[0], "GET_FAIL")
1475 dev[0].request("REMOVE_NETWORK all")
1476 dev[0].wait_disconnected()
1477
1478 with fail_test(dev[0], 1, "nt_password_hash;eap_leap_getKey"):
1479 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1480 eap="LEAP", identity="user", password="password",
1481 wait_connect=False)
1482 wait_fail_trigger(dev[0], "GET_FAIL")
1483 dev[0].request("REMOVE_NETWORK all")
1484 dev[0].wait_disconnected()
1485
1486 with fail_test(dev[0], 1, "hash_nt_password_hash;eap_leap_getKey"):
1487 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1488 eap="LEAP", identity="user", password="password",
1489 wait_connect=False)
1490 wait_fail_trigger(dev[0], "GET_FAIL")
1491 dev[0].request("REMOVE_NETWORK all")
1492 dev[0].wait_disconnected()
1493
1494 with fail_test(dev[0], 1,
1495 "nt_challenge_response;eap_leap_process_request"):
1496 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1497 eap="LEAP", identity="user", password="password",
1498 wait_connect=False)
1499 wait_fail_trigger(dev[0], "GET_FAIL")
1500 dev[0].request("REMOVE_NETWORK all")
1501 dev[0].wait_disconnected()
1502 finally:
1503 stop_radius_server(srv)
1504
1505 def test_eap_proto_md5(dev, apdev):
1506 """EAP-MD5 protocol tests"""
1507 check_eap_capa(dev[0], "MD5")
1508
1509 def md5_handler(ctx, req):
1510 logger.info("md5_handler - RX " + binascii.hexlify(req).decode())
1511 if 'num' not in ctx:
1512 ctx['num'] = 0
1513 ctx['num'] = ctx['num'] + 1
1514 if 'id' not in ctx:
1515 ctx['id'] = 1
1516 ctx['id'] = (ctx['id'] + 1) % 256
1517
1518 if ctx['num'] == 1:
1519 logger.info("Test: Missing payload")
1520 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
1521 4 + 1,
1522 EAP_TYPE_MD5)
1523
1524 if ctx['num'] == 2:
1525 logger.info("Test: Zero-length challenge")
1526 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1527 4 + 1 + 1,
1528 EAP_TYPE_MD5,
1529 0)
1530
1531 if ctx['num'] == 3:
1532 logger.info("Test: Truncated challenge")
1533 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1534 4 + 1 + 1,
1535 EAP_TYPE_MD5,
1536 1)
1537
1538 if ctx['num'] == 4:
1539 logger.info("Test: Shortest possible challenge and name")
1540 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
1541 4 + 1 + 3,
1542 EAP_TYPE_MD5,
1543 1, 0xaa, ord('n'))
1544
1545 return None
1546
1547 srv = start_radius_server(md5_handler)
1548
1549 try:
1550 hapd = start_ap(apdev[0])
1551 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
1552
1553 for i in range(0, 4):
1554 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1555 eap="MD5", identity="user", password="password",
1556 wait_connect=False)
1557 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15)
1558 if ev is None:
1559 raise Exception("Timeout on EAP start")
1560 time.sleep(0.1)
1561 dev[0].request("REMOVE_NETWORK all")
1562 finally:
1563 stop_radius_server(srv)
1564
1565 def test_eap_proto_md5_errors(dev, apdev):
1566 """EAP-MD5 local error cases"""
1567 check_eap_capa(dev[0], "MD5")
1568 params = hostapd.wpa2_eap_params(ssid="eap-test")
1569 hapd = hostapd.add_ap(apdev[0], params)
1570 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
1571
1572 with fail_test(dev[0], 1, "chap_md5"):
1573 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1574 eap="MD5", identity="phase1-user", password="password",
1575 wait_connect=False)
1576 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=15)
1577 if ev is None:
1578 raise Exception("Timeout on EAP start")
1579 dev[0].request("REMOVE_NETWORK all")
1580 dev[0].wait_disconnected()
1581
1582 with alloc_fail(dev[0], 1, "eap_msg_alloc;eap_md5_process"):
1583 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1584 eap="MD5", identity="phase1-user", password="password",
1585 wait_connect=False)
1586 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=15)
1587 if ev is None:
1588 raise Exception("Timeout on EAP start")
1589 time.sleep(0.1)
1590 dev[0].request("REMOVE_NETWORK all")
1591
1592 def run_eap_md5_connect(dev):
1593 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412",
1594 eap="MD5", identity="phase1-user", password="password",
1595 wait_connect=False)
1596 ev = dev.wait_event(["CTRL-EVENT-EAP-SUCCESS", "CTRL-EVENT-EAP-FAILURE",
1597 "CTRL-EVENT-DISCONNECTED"],
1598 timeout=1)
1599 dev.request("REMOVE_NETWORK all")
1600 if not ev or "CTRL-EVENT-DISCONNECTED" not in ev:
1601 dev.wait_disconnected()
1602 dev.dump_monitor()
1603
1604 def test_eap_proto_md5_errors_server(dev, apdev):
1605 """EAP-MD5 local error cases on server"""
1606 check_eap_capa(dev[0], "MD5")
1607 params = int_eap_server_params()
1608 params['erp_domain'] = 'example.com'
1609 params['eap_server_erp'] = '1'
1610 hapd = hostapd.add_ap(apdev[0], params)
1611 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
1612
1613 tests = [(1, "eap_md5_init")]
1614 for count, func in tests:
1615 with alloc_fail(hapd, count, func):
1616 run_eap_md5_connect(dev[0])
1617
1618 tests = [(1, "os_get_random;eap_md5_buildReq"),
1619 (1, "chap_md5;eap_md5_process")]
1620 for count, func in tests:
1621 with fail_test(hapd, count, func):
1622 run_eap_md5_connect(dev[0])
1623
1624 def start_md5_assoc(dev, hapd):
1625 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412",
1626 eap="MD5", identity="phase1-user", password="password",
1627 wait_connect=False)
1628 proxy_msg(hapd, dev) # EAP-Identity/Request
1629 proxy_msg(dev, hapd) # EAP-Identity/Response
1630 proxy_msg(hapd, dev) # MSCHAPV2/Request
1631 proxy_msg(dev, hapd) # NAK
1632 proxy_msg(hapd, dev) # MD5 Request
1633
1634 def stop_md5_assoc(dev, hapd):
1635 dev.request("REMOVE_NETWORK all")
1636 dev.wait_disconnected()
1637 dev.dump_monitor()
1638 hapd.dump_monitor()
1639
1640 def test_eap_proto_md5_server(dev, apdev):
1641 """EAP-MD5 protocol testing for the server"""
1642 check_eap_capa(dev[0], "MD5")
1643 params = int_eap_server_params()
1644 params['erp_domain'] = 'example.com'
1645 params['eap_server_erp'] = '1'
1646 hapd = hostapd.add_ap(apdev[0], params)
1647 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
1648 hapd.request("SET ext_eapol_frame_io 1")
1649 dev[0].request("SET ext_eapol_frame_io 1")
1650
1651 # Successful exchange to verify proxying mechanism
1652 start_md5_assoc(dev[0], hapd)
1653 proxy_msg(dev[0], hapd) # MD5 Response
1654 proxy_msg(hapd, dev[0]) # EAP-Success
1655 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=5)
1656 if ev is None:
1657 raise Exception("No EAP-Success reported")
1658 stop_md5_assoc(dev[0], hapd)
1659
1660 start_md5_assoc(dev[0], hapd)
1661 resp = rx_msg(dev[0])
1662 # Too short EAP-MD5 header (no length field)
1663 hapd.note("EAP-MD5: Invalid frame")
1664 msg = resp[0:4] + "0005" + resp[8:12] + "0005" + "04"
1665 tx_msg(dev[0], hapd, msg)
1666 # Too short EAP-MD5 header (no length field)
1667 hapd.note("EAP-MD5: Invalid response (response_len=0 payload_len=1")
1668 msg = resp[0:4] + "0006" + resp[8:12] + "0006" + "0400"
1669 tx_msg(dev[0], hapd, msg)
1670 stop_md5_assoc(dev[0], hapd)
1671
1672 def test_eap_proto_otp(dev, apdev):
1673 """EAP-OTP protocol tests"""
1674 def otp_handler(ctx, req):
1675 logger.info("otp_handler - RX " + binascii.hexlify(req).decode())
1676 if 'num' not in ctx:
1677 ctx['num'] = 0
1678 ctx['num'] = ctx['num'] + 1
1679 if 'id' not in ctx:
1680 ctx['id'] = 1
1681 ctx['id'] = (ctx['id'] + 1) % 256
1682
1683 if ctx['num'] == 1:
1684 logger.info("Test: Empty payload")
1685 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
1686 4 + 1,
1687 EAP_TYPE_OTP)
1688 if ctx['num'] == 2:
1689 logger.info("Test: Success")
1690 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'],
1691 4)
1692
1693 if ctx['num'] == 3:
1694 logger.info("Test: Challenge included")
1695 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1696 4 + 1 + 1,
1697 EAP_TYPE_OTP,
1698 ord('A'))
1699 if ctx['num'] == 4:
1700 logger.info("Test: Success")
1701 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'],
1702 4)
1703
1704 return None
1705
1706 srv = start_radius_server(otp_handler)
1707
1708 try:
1709 hapd = start_ap(apdev[0])
1710 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
1711
1712 for i in range(0, 1):
1713 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1714 eap="OTP", identity="user", password="password",
1715 wait_connect=False)
1716 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
1717 timeout=15)
1718 if ev is None:
1719 raise Exception("Timeout on EAP start")
1720 time.sleep(0.1)
1721 dev[0].request("REMOVE_NETWORK all")
1722
1723 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1724 eap="OTP", identity="user", wait_connect=False)
1725 ev = dev[0].wait_event(["CTRL-REQ-OTP"])
1726 if ev is None:
1727 raise Exception("Request for password timed out")
1728 id = ev.split(':')[0].split('-')[-1]
1729 dev[0].request("CTRL-RSP-OTP-" + id + ":password")
1730 ev = dev[0].wait_event("CTRL-EVENT-EAP-SUCCESS")
1731 if ev is None:
1732 raise Exception("Success not reported")
1733 finally:
1734 stop_radius_server(srv)
1735
1736 def test_eap_proto_otp_errors(dev, apdev):
1737 """EAP-OTP local error cases"""
1738 def otp_handler2(ctx, req):
1739 logger.info("otp_handler2 - RX " + binascii.hexlify(req).decode())
1740 if 'num' not in ctx:
1741 ctx['num'] = 0
1742 ctx['num'] = ctx['num'] + 1
1743 if 'id' not in ctx:
1744 ctx['id'] = 1
1745 ctx['id'] = (ctx['id'] + 1) % 256
1746 idx = 0
1747
1748 idx += 1
1749 if ctx['num'] == idx:
1750 logger.info("Test: Challenge included")
1751 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1752 4 + 1 + 1,
1753 EAP_TYPE_OTP,
1754 ord('A'))
1755
1756 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
1757
1758 srv = start_radius_server(otp_handler2)
1759
1760 try:
1761 hapd = start_ap(apdev[0])
1762 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
1763
1764 with alloc_fail(dev[0], 1, "eap_msg_alloc;eap_otp_process"):
1765 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1766 eap="OTP", identity="user", password="password",
1767 wait_connect=False)
1768 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
1769 dev[0].request("REMOVE_NETWORK all")
1770 dev[0].wait_disconnected()
1771 finally:
1772 stop_radius_server(srv)
1773
1774 EAP_GPSK_OPCODE_GPSK_1 = 1
1775 EAP_GPSK_OPCODE_GPSK_2 = 2
1776 EAP_GPSK_OPCODE_GPSK_3 = 3
1777 EAP_GPSK_OPCODE_GPSK_4 = 4
1778 EAP_GPSK_OPCODE_FAIL = 5
1779 EAP_GPSK_OPCODE_PROTECTED_FAIL = 6
1780
1781 def test_eap_proto_gpsk(dev, apdev):
1782 """EAP-GPSK protocol tests"""
1783 def gpsk_handler(ctx, req):
1784 logger.info("gpsk_handler - RX " + binascii.hexlify(req).decode())
1785 if 'num' not in ctx:
1786 ctx['num'] = 0
1787 ctx['num'] = ctx['num'] + 1
1788 if 'id' not in ctx:
1789 ctx['id'] = 1
1790 ctx['id'] = (ctx['id'] + 1) % 256
1791
1792 idx = 0
1793
1794 idx += 1
1795 if ctx['num'] == idx:
1796 logger.info("Test: Missing payload")
1797 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
1798 4 + 1,
1799 EAP_TYPE_GPSK)
1800
1801 idx += 1
1802 if ctx['num'] == idx:
1803 logger.info("Test: Unknown opcode")
1804 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1805 4 + 1 + 1,
1806 EAP_TYPE_GPSK,
1807 255)
1808
1809 idx += 1
1810 if ctx['num'] == idx:
1811 logger.info("Test: Unexpected GPSK-3")
1812 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1813 4 + 1 + 1,
1814 EAP_TYPE_GPSK,
1815 EAP_GPSK_OPCODE_GPSK_3)
1816
1817 idx += 1
1818 if ctx['num'] == idx:
1819 logger.info("Test: GPSK-1 Too short GPSK-1")
1820 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1821 4 + 1 + 1,
1822 EAP_TYPE_GPSK,
1823 EAP_GPSK_OPCODE_GPSK_1)
1824
1825 idx += 1
1826 if ctx['num'] == idx:
1827 logger.info("Test: GPSK-1 Truncated ID_Server")
1828 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
1829 4 + 1 + 1 + 2,
1830 EAP_TYPE_GPSK,
1831 EAP_GPSK_OPCODE_GPSK_1, 1)
1832
1833 idx += 1
1834 if ctx['num'] == idx:
1835 logger.info("Test: GPSK-1 Missing RAND_Server")
1836 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
1837 4 + 1 + 1 + 2,
1838 EAP_TYPE_GPSK,
1839 EAP_GPSK_OPCODE_GPSK_1, 0)
1840
1841 idx += 1
1842 if ctx['num'] == idx:
1843 logger.info("Test: GPSK-1 Missing CSuite_List")
1844 return struct.pack(">BBHBBH8L", EAP_CODE_REQUEST, ctx['id'],
1845 4 + 1 + 1 + 2 + 32,
1846 EAP_TYPE_GPSK,
1847 EAP_GPSK_OPCODE_GPSK_1, 0,
1848 0, 0, 0, 0, 0, 0, 0, 0)
1849
1850 idx += 1
1851 if ctx['num'] == idx:
1852 logger.info("Test: GPSK-1 Truncated CSuite_List")
1853 return struct.pack(">BBHBBH8LH", EAP_CODE_REQUEST, ctx['id'],
1854 4 + 1 + 1 + 2 + 32 + 2,
1855 EAP_TYPE_GPSK,
1856 EAP_GPSK_OPCODE_GPSK_1, 0,
1857 0, 0, 0, 0, 0, 0, 0, 0,
1858 1)
1859
1860 idx += 1
1861 if ctx['num'] == idx:
1862 logger.info("Test: GPSK-1 Empty CSuite_List")
1863 return struct.pack(">BBHBBH8LH", EAP_CODE_REQUEST, ctx['id'],
1864 4 + 1 + 1 + 2 + 32 + 2,
1865 EAP_TYPE_GPSK,
1866 EAP_GPSK_OPCODE_GPSK_1, 0,
1867 0, 0, 0, 0, 0, 0, 0, 0,
1868 0)
1869
1870 idx += 1
1871 if ctx['num'] == idx:
1872 logger.info("Test: GPSK-1 Invalid CSuite_List")
1873 return struct.pack(">BBHBBH8LHB", EAP_CODE_REQUEST, ctx['id'],
1874 4 + 1 + 1 + 2 + 32 + 2 + 1,
1875 EAP_TYPE_GPSK,
1876 EAP_GPSK_OPCODE_GPSK_1, 0,
1877 0, 0, 0, 0, 0, 0, 0, 0,
1878 1, 0)
1879
1880 idx += 1
1881 if ctx['num'] == idx:
1882 logger.info("Test: GPSK-1 No supported CSuite")
1883 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
1884 4 + 1 + 1 + 2 + 32 + 2 + 6,
1885 EAP_TYPE_GPSK,
1886 EAP_GPSK_OPCODE_GPSK_1, 0,
1887 0, 0, 0, 0, 0, 0, 0, 0,
1888 6, 0, 0)
1889
1890 idx += 1
1891 if ctx['num'] == idx:
1892 logger.info("Test: GPSK-1 Supported CSuite")
1893 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
1894 4 + 1 + 1 + 2 + 32 + 2 + 6,
1895 EAP_TYPE_GPSK,
1896 EAP_GPSK_OPCODE_GPSK_1, 0,
1897 0, 0, 0, 0, 0, 0, 0, 0,
1898 6, 0, 1)
1899 idx += 1
1900 if ctx['num'] == idx:
1901 logger.info("Test: Unexpected GPSK-1")
1902 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
1903 4 + 1 + 1 + 2 + 32 + 2 + 6,
1904 EAP_TYPE_GPSK,
1905 EAP_GPSK_OPCODE_GPSK_1, 0,
1906 0, 0, 0, 0, 0, 0, 0, 0,
1907 6, 0, 1)
1908
1909 idx += 1
1910 if ctx['num'] == idx:
1911 logger.info("Test: GPSK-1 Supported CSuite but too short key")
1912 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
1913 4 + 1 + 1 + 2 + 32 + 2 + 6,
1914 EAP_TYPE_GPSK,
1915 EAP_GPSK_OPCODE_GPSK_1, 0,
1916 0, 0, 0, 0, 0, 0, 0, 0,
1917 6, 0, 1)
1918
1919 idx += 1
1920 if ctx['num'] == idx:
1921 logger.info("Test: GPSK-1 Supported CSuite")
1922 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
1923 4 + 1 + 1 + 2 + 32 + 2 + 6,
1924 EAP_TYPE_GPSK,
1925 EAP_GPSK_OPCODE_GPSK_1, 0,
1926 0, 0, 0, 0, 0, 0, 0, 0,
1927 6, 0, 1)
1928 idx += 1
1929 if ctx['num'] == idx:
1930 logger.info("Test: Too short GPSK-3")
1931 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1932 4 + 1 + 1,
1933 EAP_TYPE_GPSK,
1934 EAP_GPSK_OPCODE_GPSK_3)
1935
1936 idx += 1
1937 if ctx['num'] == idx:
1938 logger.info("Test: GPSK-1 Supported CSuite")
1939 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
1940 4 + 1 + 1 + 2 + 32 + 2 + 6,
1941 EAP_TYPE_GPSK,
1942 EAP_GPSK_OPCODE_GPSK_1, 0,
1943 0, 0, 0, 0, 0, 0, 0, 0,
1944 6, 0, 1)
1945 idx += 1
1946 if ctx['num'] == idx:
1947 logger.info("Test: GPSK-3 Mismatch in RAND_Peer")
1948 return struct.pack(">BBHBB8L", EAP_CODE_REQUEST, ctx['id'],
1949 4 + 1 + 1 + 32,
1950 EAP_TYPE_GPSK,
1951 EAP_GPSK_OPCODE_GPSK_3,
1952 0, 0, 0, 0, 0, 0, 0, 0)
1953
1954 idx += 1
1955 if ctx['num'] == idx:
1956 logger.info("Test: GPSK-1 Supported CSuite")
1957 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
1958 4 + 1 + 1 + 2 + 32 + 2 + 6,
1959 EAP_TYPE_GPSK,
1960 EAP_GPSK_OPCODE_GPSK_1, 0,
1961 0, 0, 0, 0, 0, 0, 0, 0,
1962 6, 0, 1)
1963 idx += 1
1964 if ctx['num'] == idx:
1965 logger.info("Test: GPSK-3 Missing RAND_Server")
1966 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1967 4 + 1 + 1 + 32,
1968 EAP_TYPE_GPSK,
1969 EAP_GPSK_OPCODE_GPSK_3)
1970 msg += req[14:46]
1971 return msg
1972
1973 idx += 1
1974 if ctx['num'] == idx:
1975 logger.info("Test: GPSK-1 Supported CSuite")
1976 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
1977 4 + 1 + 1 + 2 + 32 + 2 + 6,
1978 EAP_TYPE_GPSK,
1979 EAP_GPSK_OPCODE_GPSK_1, 0,
1980 0, 0, 0, 0, 0, 0, 0, 0,
1981 6, 0, 1)
1982 idx += 1
1983 if ctx['num'] == idx:
1984 logger.info("Test: GPSK-3 Mismatch in RAND_Server")
1985 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1986 4 + 1 + 1 + 32 + 32,
1987 EAP_TYPE_GPSK,
1988 EAP_GPSK_OPCODE_GPSK_3)
1989 msg += req[14:46]
1990 msg += struct.pack(">8L", 1, 1, 1, 1, 1, 1, 1, 1)
1991 return msg
1992
1993 idx += 1
1994 if ctx['num'] == idx:
1995 logger.info("Test: GPSK-1 Supported CSuite")
1996 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
1997 4 + 1 + 1 + 2 + 32 + 2 + 6,
1998 EAP_TYPE_GPSK,
1999 EAP_GPSK_OPCODE_GPSK_1, 0,
2000 0, 0, 0, 0, 0, 0, 0, 0,
2001 6, 0, 1)
2002 idx += 1
2003 if ctx['num'] == idx:
2004 logger.info("Test: GPSK-3 Missing ID_Server")
2005 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
2006 4 + 1 + 1 + 32 + 32,
2007 EAP_TYPE_GPSK,
2008 EAP_GPSK_OPCODE_GPSK_3)
2009 msg += req[14:46]
2010 msg += struct.pack(">8L", 0, 0, 0, 0, 0, 0, 0, 0)
2011 return msg
2012
2013 idx += 1
2014 if ctx['num'] == idx:
2015 logger.info("Test: GPSK-1 Supported CSuite")
2016 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
2017 4 + 1 + 1 + 2 + 32 + 2 + 6,
2018 EAP_TYPE_GPSK,
2019 EAP_GPSK_OPCODE_GPSK_1, 0,
2020 0, 0, 0, 0, 0, 0, 0, 0,
2021 6, 0, 1)
2022 idx += 1
2023 if ctx['num'] == idx:
2024 logger.info("Test: GPSK-3 Truncated ID_Server")
2025 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
2026 4 + 1 + 1 + 32 + 32 + 2,
2027 EAP_TYPE_GPSK,
2028 EAP_GPSK_OPCODE_GPSK_3)
2029 msg += req[14:46]
2030 msg += struct.pack(">8LH", 0, 0, 0, 0, 0, 0, 0, 0, 1)
2031 return msg
2032
2033 idx += 1
2034 if ctx['num'] == idx:
2035 logger.info("Test: GPSK-1 Supported CSuite")
2036 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
2037 4 + 1 + 1 + 2 + 32 + 2 + 6,
2038 EAP_TYPE_GPSK,
2039 EAP_GPSK_OPCODE_GPSK_1, 0,
2040 0, 0, 0, 0, 0, 0, 0, 0,
2041 6, 0, 1)
2042 idx += 1
2043 if ctx['num'] == idx:
2044 logger.info("Test: GPSK-3 Mismatch in ID_Server")
2045 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
2046 4 + 1 + 1 + 32 + 32 + 3,
2047 EAP_TYPE_GPSK,
2048 EAP_GPSK_OPCODE_GPSK_3)
2049 msg += req[14:46]
2050 msg += struct.pack(">8LHB", 0, 0, 0, 0, 0, 0, 0, 0, 1, ord('B'))
2051 return msg
2052
2053 idx += 1
2054 if ctx['num'] == idx:
2055 logger.info("Test: GPSK-1 Supported CSuite")
2056 return struct.pack(">BBHBBHB8LHLH", EAP_CODE_REQUEST, ctx['id'],
2057 4 + 1 + 1 + 3 + 32 + 2 + 6,
2058 EAP_TYPE_GPSK,
2059 EAP_GPSK_OPCODE_GPSK_1, 1, ord('A'),
2060 0, 0, 0, 0, 0, 0, 0, 0,
2061 6, 0, 1)
2062 idx += 1
2063 if ctx['num'] == idx:
2064 logger.info("Test: GPSK-3 Mismatch in ID_Server (same length)")
2065 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
2066 4 + 1 + 1 + 32 + 32 + 3,
2067 EAP_TYPE_GPSK,
2068 EAP_GPSK_OPCODE_GPSK_3)
2069 msg += req[15:47]
2070 msg += struct.pack(">8LHB", 0, 0, 0, 0, 0, 0, 0, 0, 1, ord('B'))
2071 return msg
2072
2073 idx += 1
2074 if ctx['num'] == idx:
2075 logger.info("Test: GPSK-1 Supported CSuite")
2076 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
2077 4 + 1 + 1 + 2 + 32 + 2 + 6,
2078 EAP_TYPE_GPSK,
2079 EAP_GPSK_OPCODE_GPSK_1, 0,
2080 0, 0, 0, 0, 0, 0, 0, 0,
2081 6, 0, 1)
2082 idx += 1
2083 if ctx['num'] == idx:
2084 logger.info("Test: GPSK-3 Missing CSuite_Sel")
2085 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
2086 4 + 1 + 1 + 32 + 32 + 2,
2087 EAP_TYPE_GPSK,
2088 EAP_GPSK_OPCODE_GPSK_3)
2089 msg += req[14:46]
2090 msg += struct.pack(">8LH", 0, 0, 0, 0, 0, 0, 0, 0, 0)
2091 return msg
2092
2093 idx += 1
2094 if ctx['num'] == idx:
2095 logger.info("Test: GPSK-1 Supported CSuite")
2096 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
2097 4 + 1 + 1 + 2 + 32 + 2 + 6,
2098 EAP_TYPE_GPSK,
2099 EAP_GPSK_OPCODE_GPSK_1, 0,
2100 0, 0, 0, 0, 0, 0, 0, 0,
2101 6, 0, 1)
2102 idx += 1
2103 if ctx['num'] == idx:
2104 logger.info("Test: GPSK-3 Mismatch in CSuite_Sel")
2105 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
2106 4 + 1 + 1 + 32 + 32 + 2 + 6,
2107 EAP_TYPE_GPSK,
2108 EAP_GPSK_OPCODE_GPSK_3)
2109 msg += req[14:46]
2110 msg += struct.pack(">8LHLH", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2)
2111 return msg
2112
2113 idx += 1
2114 if ctx['num'] == idx:
2115 logger.info("Test: GPSK-1 Supported CSuite")
2116 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
2117 4 + 1 + 1 + 2 + 32 + 2 + 6,
2118 EAP_TYPE_GPSK,
2119 EAP_GPSK_OPCODE_GPSK_1, 0,
2120 0, 0, 0, 0, 0, 0, 0, 0,
2121 6, 0, 1)
2122 idx += 1
2123 if ctx['num'] == idx:
2124 logger.info("Test: GPSK-3 Missing len(PD_Payload_Block)")
2125 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
2126 4 + 1 + 1 + 32 + 32 + 2 + 6,
2127 EAP_TYPE_GPSK,
2128 EAP_GPSK_OPCODE_GPSK_3)
2129 msg += req[14:46]
2130 msg += struct.pack(">8LHLH", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1)
2131 return msg
2132
2133 idx += 1
2134 if ctx['num'] == idx:
2135 logger.info("Test: GPSK-1 Supported CSuite")
2136 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
2137 4 + 1 + 1 + 2 + 32 + 2 + 6,
2138 EAP_TYPE_GPSK,
2139 EAP_GPSK_OPCODE_GPSK_1, 0,
2140 0, 0, 0, 0, 0, 0, 0, 0,
2141 6, 0, 1)
2142 idx += 1
2143 if ctx['num'] == idx:
2144 logger.info("Test: GPSK-3 Truncated PD_Payload_Block")
2145 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
2146 4 + 1 + 1 + 32 + 32 + 2 + 6 + 2,
2147 EAP_TYPE_GPSK,
2148 EAP_GPSK_OPCODE_GPSK_3)
2149 msg += req[14:46]
2150 msg += struct.pack(">8LHLHH", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1)
2151 return msg
2152
2153 idx += 1
2154 if ctx['num'] == idx:
2155 logger.info("Test: GPSK-1 Supported CSuite")
2156 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
2157 4 + 1 + 1 + 2 + 32 + 2 + 6,
2158 EAP_TYPE_GPSK,
2159 EAP_GPSK_OPCODE_GPSK_1, 0,
2160 0, 0, 0, 0, 0, 0, 0, 0,
2161 6, 0, 1)
2162 idx += 1
2163 if ctx['num'] == idx:
2164 logger.info("Test: GPSK-3 Missing MAC")
2165 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
2166 4 + 1 + 1 + 32 + 32 + 2 + 6 + 3,
2167 EAP_TYPE_GPSK,
2168 EAP_GPSK_OPCODE_GPSK_3)
2169 msg += req[14:46]
2170 msg += struct.pack(">8LHLHHB",
2171 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 123)
2172 return msg
2173
2174 idx += 1
2175 if ctx['num'] == idx:
2176 logger.info("Test: GPSK-1 Supported CSuite")
2177 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
2178 4 + 1 + 1 + 2 + 32 + 2 + 6,
2179 EAP_TYPE_GPSK,
2180 EAP_GPSK_OPCODE_GPSK_1, 0,
2181 0, 0, 0, 0, 0, 0, 0, 0,
2182 6, 0, 1)
2183 idx += 1
2184 if ctx['num'] == idx:
2185 logger.info("Test: GPSK-3 Incorrect MAC")
2186 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
2187 4 + 1 + 1 + 32 + 32 + 2 + 6 + 3 + 16,
2188 EAP_TYPE_GPSK,
2189 EAP_GPSK_OPCODE_GPSK_3)
2190 msg += req[14:46]
2191 msg += struct.pack(">8LHLHHB4L",
2192 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 123,
2193 0, 0, 0, 0)
2194 return msg
2195
2196 return None
2197
2198 srv = start_radius_server(gpsk_handler)
2199
2200 try:
2201 hapd = start_ap(apdev[0])
2202 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
2203
2204 for i in range(0, 27):
2205 if i == 12:
2206 pw = "short"
2207 else:
2208 pw = "abcdefghijklmnop0123456789abcdef"
2209 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
2210 eap="GPSK", identity="user", password=pw,
2211 wait_connect=False)
2212 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
2213 timeout=15)
2214 if ev is None:
2215 raise Exception("Timeout on EAP start")
2216 time.sleep(0.05)
2217 dev[0].request("REMOVE_NETWORK all")
2218 finally:
2219 stop_radius_server(srv)
2220
2221 def run_eap_gpsk_connect(dev):
2222 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412",
2223 eap="GPSK", identity="gpsk user",
2224 password="abcdefghijklmnop0123456789abcdef",
2225 wait_connect=False)
2226 ev = dev.wait_event(["CTRL-EVENT-EAP-SUCCESS", "CTRL-EVENT-EAP-FAILURE",
2227 "CTRL-EVENT-DISCONNECTED"],
2228 timeout=1)
2229 dev.request("REMOVE_NETWORK all")
2230 if not ev or "CTRL-EVENT-DISCONNECTED" not in ev:
2231 dev.wait_disconnected()
2232 dev.dump_monitor()
2233
2234 def test_eap_proto_gpsk_errors_server(dev, apdev):
2235 """EAP-GPSK local error cases on server"""
2236 check_eap_capa(dev[0], "GPSK")
2237 params = int_eap_server_params()
2238 params['erp_domain'] = 'example.com'
2239 params['eap_server_erp'] = '1'
2240 hapd = hostapd.add_ap(apdev[0], params)
2241 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
2242
2243 tests = [(1, "eap_gpsk_init"),
2244 (1, "eap_msg_alloc;eap_gpsk_build_gpsk_1"),
2245 (1, "eap_msg_alloc;eap_gpsk_build_gpsk_3"),
2246 (1, "eap_gpsk_process_gpsk_2"),
2247 (1, "eap_gpsk_derive_keys;eap_gpsk_process_gpsk_2"),
2248 (1, "eap_gpsk_derive_session_id;eap_gpsk_process_gpsk_2"),
2249 (1, "eap_gpsk_getKey"),
2250 (1, "eap_gpsk_get_emsk"),
2251 (1, "eap_gpsk_get_session_id")]
2252 for count, func in tests:
2253 with alloc_fail(hapd, count, func):
2254 run_eap_gpsk_connect(dev[0])
2255
2256 tests = [(1, "os_get_random;eap_gpsk_build_gpsk_1"),
2257 (1, "eap_gpsk_compute_mic;eap_gpsk_build_gpsk_3"),
2258 (1, "eap_gpsk_derive_keys;eap_gpsk_process_gpsk_2"),
2259 (1, "eap_gpsk_derive_session_id;eap_gpsk_process_gpsk_2"),
2260 (1, "eap_gpsk_compute_mic;eap_gpsk_process_gpsk_2"),
2261 (1, "eap_gpsk_compute_mic;eap_gpsk_process_gpsk_4")]
2262 for count, func in tests:
2263 with fail_test(hapd, count, func):
2264 run_eap_gpsk_connect(dev[0])
2265
2266 def start_gpsk_assoc(dev, hapd):
2267 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412",
2268 eap="GPSK", identity="gpsk user",
2269 password="abcdefghijklmnop0123456789abcdef",
2270 wait_connect=False)
2271 proxy_msg(hapd, dev) # EAP-Identity/Request
2272 proxy_msg(dev, hapd) # EAP-Identity/Response
2273 proxy_msg(hapd, dev) # GPSK-1
2274
2275 def stop_gpsk_assoc(dev, hapd):
2276 dev.request("REMOVE_NETWORK all")
2277 dev.wait_disconnected()
2278 dev.dump_monitor()
2279 hapd.dump_monitor()
2280
2281 def test_eap_proto_gpsk_server(dev, apdev):
2282 """EAP-GPSK protocol testing for the server"""
2283 check_eap_capa(dev[0], "GPSK")
2284 params = int_eap_server_params()
2285 params['erp_domain'] = 'example.com'
2286 params['eap_server_erp'] = '1'
2287 hapd = hostapd.add_ap(apdev[0], params)
2288 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
2289 hapd.request("SET ext_eapol_frame_io 1")
2290 dev[0].request("SET ext_eapol_frame_io 1")
2291
2292 # Successful exchange to verify proxying mechanism
2293 start_gpsk_assoc(dev[0], hapd)
2294 proxy_msg(dev[0], hapd) # GPSK-2
2295 proxy_msg(hapd, dev[0]) # GPSK-3
2296 proxy_msg(dev[0], hapd) # GPSK-4
2297 proxy_msg(hapd, dev[0]) # EAP-Success
2298 proxy_msg(hapd, dev[0]) # EAPOL-Key msg 1/4
2299 proxy_msg(dev[0], hapd) # EAPOL-Key msg 2/4
2300 proxy_msg(hapd, dev[0]) # EAPOL-Key msg 3/4
2301 proxy_msg(dev[0], hapd) # EAPOL-Key msg 4/4
2302 dev[0].wait_connected()
2303 stop_gpsk_assoc(dev[0], hapd)
2304
2305 start_gpsk_assoc(dev[0], hapd)
2306 resp = rx_msg(dev[0])
2307 # Too short EAP-GPSK header (no OP-Code)
2308 # --> EAP-GPSK: Invalid frame
2309 msg = resp[0:4] + "0005" + resp[8:12] + "0005" + "33"
2310 tx_msg(dev[0], hapd, msg)
2311 # Unknown OP-Code
2312 # --> EAP-GPSK: Unexpected opcode=7 in state=0
2313 msg = resp[0:4] + "0006" + resp[8:12] + "0006" + "3307"
2314 tx_msg(dev[0], hapd, msg)
2315 # Too short GPSK-2
2316 # --> EAP-GPSK: Too short message for ID_Peer length
2317 msg = resp[0:4] + "0006" + resp[8:12] + "0006" + "3302"
2318 tx_msg(dev[0], hapd, msg)
2319 rx_msg(hapd)
2320 stop_gpsk_assoc(dev[0], hapd)
2321
2322 start_gpsk_assoc(dev[0], hapd)
2323 resp = rx_msg(dev[0])
2324 # Too short GPSK-2
2325 # --> EAP-GPSK: Too short message for ID_Peer
2326 msg = resp[0:4] + "0008" + resp[8:12] + "0008" + "33020001"
2327 tx_msg(dev[0], hapd, msg)
2328 rx_msg(hapd)
2329 stop_gpsk_assoc(dev[0], hapd)
2330
2331 start_gpsk_assoc(dev[0], hapd)
2332 resp = rx_msg(dev[0])
2333 # Too short GPSK-2
2334 # --> EAP-GPSK: Too short message for ID_Server length
2335 msg = resp[0:4] + "0008" + resp[8:12] + "0008" + "33020000"
2336 tx_msg(dev[0], hapd, msg)
2337 rx_msg(hapd)
2338 stop_gpsk_assoc(dev[0], hapd)
2339
2340 start_gpsk_assoc(dev[0], hapd)
2341 resp = rx_msg(dev[0])
2342 # Too short GPSK-2
2343 # --> EAP-GPSK: Too short message for ID_Server
2344 msg = resp[0:4] + "000a" + resp[8:12] + "000a" + "330200000001"
2345 tx_msg(dev[0], hapd, msg)
2346 rx_msg(hapd)
2347 stop_gpsk_assoc(dev[0], hapd)
2348
2349 start_gpsk_assoc(dev[0], hapd)
2350 resp = rx_msg(dev[0])
2351 # ID_Server mismatch
2352 # --> EAP-GPSK: ID_Server in GPSK-1 and GPSK-2 did not match
2353 msg = resp[0:4] + "000a" + resp[8:12] + "000a" + "330200000000"
2354 tx_msg(dev[0], hapd, msg)
2355 rx_msg(hapd)
2356 stop_gpsk_assoc(dev[0], hapd)
2357
2358 start_gpsk_assoc(dev[0], hapd)
2359 resp = rx_msg(dev[0])
2360 # Too short GPSK-2
2361 # --> EAP-GPSK: Too short message for RAND_Peer
2362 msg = resp[0:4] + "0011" + resp[8:12] + "0011" + "330200000007" + binascii.hexlify(b"hostapd").decode()
2363 tx_msg(dev[0], hapd, msg)
2364 rx_msg(hapd)
2365 stop_gpsk_assoc(dev[0], hapd)
2366
2367 start_gpsk_assoc(dev[0], hapd)
2368 resp = rx_msg(dev[0])
2369 # Too short GPSK-2
2370 # --> EAP-GPSK: Too short message for RAND_Server
2371 msg = resp[0:4] + "0031" + resp[8:12] + "0031" + "330200000007" + binascii.hexlify(b"hostapd").decode() + 32*"00"
2372 tx_msg(dev[0], hapd, msg)
2373 rx_msg(hapd)
2374 stop_gpsk_assoc(dev[0], hapd)
2375
2376 start_gpsk_assoc(dev[0], hapd)
2377 resp = rx_msg(dev[0])
2378 # RAND_Server mismatch
2379 # --> EAP-GPSK: RAND_Server in GPSK-1 and GPSK-2 did not match
2380 msg = resp[0:4] + "0051" + resp[8:12] + "0051" + "330200000007" + binascii.hexlify(b"hostapd").decode() + 32*"00" + 32*"00"
2381 tx_msg(dev[0], hapd, msg)
2382 rx_msg(hapd)
2383 stop_gpsk_assoc(dev[0], hapd)
2384
2385 start_gpsk_assoc(dev[0], hapd)
2386 resp = rx_msg(dev[0])
2387 # Too short GPSK-2
2388 # --> EAP-GPSK: Too short message for CSuite_List length
2389 msg = resp[0:4] + "005a" + resp[8:12] + "005a" + resp[16:188]
2390 tx_msg(dev[0], hapd, msg)
2391 rx_msg(hapd)
2392 stop_gpsk_assoc(dev[0], hapd)
2393
2394 start_gpsk_assoc(dev[0], hapd)
2395 resp = rx_msg(dev[0])
2396 # Too short GPSK-2
2397 # --> EAP-GPSK: Too short message for CSuite_List
2398 msg = resp[0:4] + "005c" + resp[8:12] + "005c" + resp[16:192]
2399 tx_msg(dev[0], hapd, msg)
2400 rx_msg(hapd)
2401 stop_gpsk_assoc(dev[0], hapd)
2402
2403 start_gpsk_assoc(dev[0], hapd)
2404 resp = rx_msg(dev[0])
2405 # Too short GPSK-2
2406 # --> EAP-GPSK: CSuite_List in GPSK-1 and GPSK-2 did not match
2407 msg = resp[0:4] + "005c" + resp[8:12] + "005c" + resp[16:188] + "0000"
2408 tx_msg(dev[0], hapd, msg)
2409 rx_msg(hapd)
2410 stop_gpsk_assoc(dev[0], hapd)
2411
2412 start_gpsk_assoc(dev[0], hapd)
2413 resp = rx_msg(dev[0])
2414 # Too short GPSK-2
2415 # --> EAP-GPSK: Too short message for CSuite_Sel
2416 msg = resp[0:4] + "0068" + resp[8:12] + "0068" + resp[16:216]
2417 tx_msg(dev[0], hapd, msg)
2418 rx_msg(hapd)
2419 stop_gpsk_assoc(dev[0], hapd)
2420
2421 start_gpsk_assoc(dev[0], hapd)
2422 resp = rx_msg(dev[0])
2423 # Unsupported CSuite_Sel
2424 # --> EAP-GPSK: Peer selected unsupported ciphersuite 0:255
2425 msg = resp[0:4] + "006e" + resp[8:12] + "006e" + resp[16:226] + "ff"
2426 tx_msg(dev[0], hapd, msg)
2427 rx_msg(hapd)
2428 stop_gpsk_assoc(dev[0], hapd)
2429
2430 start_gpsk_assoc(dev[0], hapd)
2431 resp = rx_msg(dev[0])
2432 # Too short GPSK-2
2433 # --> EAP-GPSK: Too short message for PD_Payload_1 length
2434 msg = resp[0:4] + "006e" + resp[8:12] + "006e" + resp[16:228]
2435 tx_msg(dev[0], hapd, msg)
2436 rx_msg(hapd)
2437 stop_gpsk_assoc(dev[0], hapd)
2438
2439 start_gpsk_assoc(dev[0], hapd)
2440 resp = rx_msg(dev[0])
2441 # Too short GPSK-2
2442 # --> EAP-GPSK: Too short message for PD_Payload_1
2443 msg = resp[0:4] + "0070" + resp[8:12] + "0070" + resp[16:230] + "ff"
2444 tx_msg(dev[0], hapd, msg)
2445 rx_msg(hapd)
2446 stop_gpsk_assoc(dev[0], hapd)
2447
2448 start_gpsk_assoc(dev[0], hapd)
2449 resp = rx_msg(dev[0])
2450 # Too short GPSK-2
2451 # --> EAP-GPSK: Message too short for MIC (left=0 miclen=16)
2452 msg = resp[0:4] + "0070" + resp[8:12] + "0070" + resp[16:232]
2453 tx_msg(dev[0], hapd, msg)
2454 rx_msg(hapd)
2455 stop_gpsk_assoc(dev[0], hapd)
2456
2457 start_gpsk_assoc(dev[0], hapd)
2458 resp = rx_msg(dev[0])
2459 # Extra data in the end of GPSK-2
2460 # --> EAP-GPSK: Ignored 1 bytes of extra data in the end of GPSK-2
2461 msg = resp[0:4] + "0081" + resp[8:12] + "0081" + resp[16:264] + "00"
2462 tx_msg(dev[0], hapd, msg)
2463 proxy_msg(hapd, dev[0]) # GPSK-3
2464 resp = rx_msg(dev[0])
2465 # Too short GPSK-4
2466 # --> EAP-GPSK: Too short message for PD_Payload_1 length
2467 msg = resp[0:4] + "0006" + resp[8:12] + "0006" + "3304"
2468 tx_msg(dev[0], hapd, msg)
2469 rx_msg(hapd) # EAP-Failure
2470 stop_gpsk_assoc(dev[0], hapd)
2471
2472 start_gpsk_assoc(dev[0], hapd)
2473 proxy_msg(dev[0], hapd) # GPSK-2
2474 proxy_msg(hapd, dev[0]) # GPSK-3
2475 resp = rx_msg(dev[0])
2476 # Too short GPSK-4
2477 # --> EAP-GPSK: Too short message for PD_Payload_1
2478 msg = resp[0:4] + "0008" + resp[8:12] + "0008" + "33040001"
2479 tx_msg(dev[0], hapd, msg)
2480 rx_msg(hapd) # EAP-Failure
2481 stop_gpsk_assoc(dev[0], hapd)
2482
2483 start_gpsk_assoc(dev[0], hapd)
2484 proxy_msg(dev[0], hapd) # GPSK-2
2485 proxy_msg(hapd, dev[0]) # GPSK-3
2486 resp = rx_msg(dev[0])
2487 # Too short GPSK-4
2488 # --> EAP-GPSK: Message too short for MIC (left=0 miclen=16)
2489 msg = resp[0:4] + "0008" + resp[8:12] + "0008" + "33040000"
2490 tx_msg(dev[0], hapd, msg)
2491 rx_msg(hapd) # EAP-Failure
2492 stop_gpsk_assoc(dev[0], hapd)
2493
2494 start_gpsk_assoc(dev[0], hapd)
2495 proxy_msg(dev[0], hapd) # GPSK-2
2496 proxy_msg(hapd, dev[0]) # GPSK-3
2497 resp = rx_msg(dev[0])
2498 # Incorrect MIC in GPSK-4
2499 # --> EAP-GPSK: Incorrect MIC in GPSK-4
2500 msg = resp[0:4] + "0018" + resp[8:12] + "0018" + "33040000" + 16*"00"
2501 tx_msg(dev[0], hapd, msg)
2502 rx_msg(hapd) # EAP-Failure
2503 stop_gpsk_assoc(dev[0], hapd)
2504
2505 start_gpsk_assoc(dev[0], hapd)
2506 proxy_msg(dev[0], hapd) # GPSK-2
2507 proxy_msg(hapd, dev[0]) # GPSK-3
2508 resp = rx_msg(dev[0])
2509 # Incorrect MIC in GPSK-4
2510 # --> EAP-GPSK: Ignored 1 bytes of extra data in the end of GPSK-4
2511 msg = resp[0:4] + "0019" + resp[8:12] + "0019" + resp[16:] + "00"
2512 tx_msg(dev[0], hapd, msg)
2513 rx_msg(hapd) # EAP-Success
2514 stop_gpsk_assoc(dev[0], hapd)
2515
2516 EAP_EKE_ID = 1
2517 EAP_EKE_COMMIT = 2
2518 EAP_EKE_CONFIRM = 3
2519 EAP_EKE_FAILURE = 4
2520
2521 def test_eap_proto_eke(dev, apdev):
2522 """EAP-EKE protocol tests"""
2523 def eke_handler(ctx, req):
2524 logger.info("eke_handler - RX " + binascii.hexlify(req).decode())
2525 if 'num' not in ctx:
2526 ctx['num'] = 0
2527 ctx['num'] = ctx['num'] + 1
2528 if 'id' not in ctx:
2529 ctx['id'] = 1
2530 ctx['id'] = (ctx['id'] + 1) % 256
2531
2532 idx = 0
2533
2534 idx += 1
2535 if ctx['num'] == idx:
2536 logger.info("Test: Missing payload")
2537 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
2538 4 + 1,
2539 EAP_TYPE_EKE)
2540
2541 idx += 1
2542 if ctx['num'] == idx:
2543 logger.info("Test: Unknown exchange")
2544 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
2545 4 + 1 + 1,
2546 EAP_TYPE_EKE,
2547 255)
2548
2549 idx += 1
2550 if ctx['num'] == idx:
2551 logger.info("Test: No NumProposals in EAP-EKE-ID/Request")
2552 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
2553 4 + 1 + 1,
2554 EAP_TYPE_EKE,
2555 EAP_EKE_ID)
2556 idx += 1
2557 if ctx['num'] == idx:
2558 logger.info("Test: EAP-Failure")
2559 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
2560
2561 idx += 1
2562 if ctx['num'] == idx:
2563 logger.info("Test: NumProposals=0 in EAP-EKE-ID/Request")
2564 return struct.pack(">BBHBBB", EAP_CODE_REQUEST, ctx['id'],
2565 4 + 1 + 1 + 1,
2566 EAP_TYPE_EKE,
2567 EAP_EKE_ID,
2568 0)
2569 idx += 1
2570 if ctx['num'] == idx:
2571 logger.info("Test: EAP-Failure")
2572 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
2573
2574 idx += 1
2575 if ctx['num'] == idx:
2576 logger.info("Test: Truncated Proposals list in EAP-EKE-ID/Request")
2577 return struct.pack(">BBHBBBB4B", EAP_CODE_REQUEST, ctx['id'],
2578 4 + 1 + 1 + 2 + 4,
2579 EAP_TYPE_EKE,
2580 EAP_EKE_ID,
2581 2, 0, 0, 0, 0, 0)
2582 idx += 1
2583 if ctx['num'] == idx:
2584 logger.info("Test: EAP-Failure")
2585 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
2586
2587 idx += 1
2588 if ctx['num'] == idx:
2589 logger.info("Test: Unsupported proposals in EAP-EKE-ID/Request")
2590 return struct.pack(">BBHBBBB4B4B4B4B", EAP_CODE_REQUEST, ctx['id'],
2591 4 + 1 + 1 + 2 + 4 * 4,
2592 EAP_TYPE_EKE,
2593 EAP_EKE_ID,
2594 4, 0,
2595 0, 0, 0, 0,
2596 3, 0, 0, 0,
2597 3, 1, 0, 0,
2598 3, 1, 1, 0)
2599 idx += 1
2600 if ctx['num'] == idx:
2601 logger.info("Test: EAP-Failure")
2602 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
2603
2604 idx += 1
2605 if ctx['num'] == idx:
2606 logger.info("Test: Missing IDType/Identity in EAP-EKE-ID/Request")
2607 return struct.pack(">BBHBBBB4B4B4B4B4B",
2608 EAP_CODE_REQUEST, ctx['id'],
2609 4 + 1 + 1 + 2 + 5 * 4,
2610 EAP_TYPE_EKE,
2611 EAP_EKE_ID,
2612 5, 0,
2613 0, 0, 0, 0,
2614 3, 0, 0, 0,
2615 3, 1, 0, 0,
2616 3, 1, 1, 0,
2617 3, 1, 1, 1)
2618 idx += 1
2619 if ctx['num'] == idx:
2620 logger.info("Test: EAP-Failure")
2621 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
2622
2623 idx += 1
2624 if ctx['num'] == idx:
2625 logger.info("Test: Valid EAP-EKE-ID/Request")
2626 return struct.pack(">BBHBBBB4BB",
2627 EAP_CODE_REQUEST, ctx['id'],
2628 4 + 1 + 1 + 2 + 4 + 1,
2629 EAP_TYPE_EKE,
2630 EAP_EKE_ID,
2631 1, 0,
2632 3, 1, 1, 1,
2633 255)
2634 idx += 1
2635 if ctx['num'] == idx:
2636 logger.info("Test: Unexpected EAP-EKE-ID/Request")
2637 return struct.pack(">BBHBBBB4BB",
2638 EAP_CODE_REQUEST, ctx['id'],
2639 4 + 1 + 1 + 2 + 4 + 1,
2640 EAP_TYPE_EKE,
2641 EAP_EKE_ID,
2642 1, 0,
2643 3, 1, 1, 1,
2644 255)
2645 idx += 1
2646 if ctx['num'] == idx:
2647 logger.info("Test: EAP-Failure")
2648 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
2649
2650 idx += 1
2651 if ctx['num'] == idx:
2652 logger.info("Test: Valid EAP-EKE-ID/Request")
2653 return struct.pack(">BBHBBBB4BB",
2654 EAP_CODE_REQUEST, ctx['id'],
2655 4 + 1 + 1 + 2 + 4 + 1,
2656 EAP_TYPE_EKE,
2657 EAP_EKE_ID,
2658 1, 0,
2659 3, 1, 1, 1,
2660 255)
2661 idx += 1
2662 if ctx['num'] == idx:
2663 logger.info("Test: Unexpected EAP-EKE-Confirm/Request")
2664 return struct.pack(">BBHBB",
2665 EAP_CODE_REQUEST, ctx['id'],
2666 4 + 1 + 1,
2667 EAP_TYPE_EKE,
2668 EAP_EKE_CONFIRM)
2669 idx += 1
2670 if ctx['num'] == idx:
2671 logger.info("Test: EAP-Failure")
2672 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
2673
2674 idx += 1
2675 if ctx['num'] == idx:
2676 logger.info("Test: Too short EAP-EKE-Failure/Request")
2677 return struct.pack(">BBHBB",
2678 EAP_CODE_REQUEST, ctx['id'],
2679 4 + 1 + 1,
2680 EAP_TYPE_EKE,
2681 EAP_EKE_FAILURE)
2682 idx += 1
2683 if ctx['num'] == idx:
2684 logger.info("Test: EAP-Failure")
2685 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
2686
2687 idx += 1
2688 if ctx['num'] == idx:
2689 logger.info("Test: Unexpected EAP-EKE-Commit/Request")
2690 return struct.pack(">BBHBB",
2691 EAP_CODE_REQUEST, ctx['id'],
2692 4 + 1 + 1,
2693 EAP_TYPE_EKE,
2694 EAP_EKE_COMMIT)
2695 idx += 1
2696 if ctx['num'] == idx:
2697 logger.info("Test: EAP-Failure")
2698 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
2699
2700 idx += 1
2701 if ctx['num'] == idx:
2702 logger.info("Test: Valid EAP-EKE-ID/Request")
2703 return struct.pack(">BBHBBBB4BB",
2704 EAP_CODE_REQUEST, ctx['id'],
2705 4 + 1 + 1 + 2 + 4 + 1,
2706 EAP_TYPE_EKE,
2707 EAP_EKE_ID,
2708 1, 0,
2709 3, 1, 1, 1,
2710 255)
2711 idx += 1
2712 if ctx['num'] == idx:
2713 logger.info("Test: Too short EAP-EKE-Commit/Request")
2714 return struct.pack(">BBHBB",
2715 EAP_CODE_REQUEST, ctx['id'],
2716 4 + 1 + 1,
2717 EAP_TYPE_EKE,
2718 EAP_EKE_COMMIT)
2719 idx += 1
2720 if ctx['num'] == idx:
2721 logger.info("Test: EAP-Failure")
2722 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
2723
2724 idx += 1
2725 if ctx['num'] == idx:
2726 logger.info("Test: Valid EAP-EKE-ID/Request")
2727 return struct.pack(">BBHBBBB4BB",
2728 EAP_CODE_REQUEST, ctx['id'],
2729 4 + 1 + 1 + 2 + 4 + 1,
2730 EAP_TYPE_EKE,
2731 EAP_EKE_ID,
2732 1, 0,
2733 1, 1, 1, 1,
2734 255)
2735 idx += 1
2736 if ctx['num'] == idx:
2737 logger.info("Test: All zeroes DHComponent_S and empty CBvalue in EAP-EKE-Commit/Request")
2738 return struct.pack(">BBHBB4L32L",
2739 EAP_CODE_REQUEST, ctx['id'],
2740 4 + 1 + 1 + 16 + 128,
2741 EAP_TYPE_EKE,
2742 EAP_EKE_COMMIT,
2743 0, 0, 0, 0,
2744 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2745 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
2746 idx += 1
2747 if ctx['num'] == idx:
2748 logger.info("Test: Too short EAP-EKE-Confirm/Request")
2749 return struct.pack(">BBHBB",
2750 EAP_CODE_REQUEST, ctx['id'],
2751 4 + 1 + 1,
2752 EAP_TYPE_EKE,
2753 EAP_EKE_CONFIRM)
2754 idx += 1
2755 if ctx['num'] == idx:
2756 logger.info("Test: EAP-Failure")
2757 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
2758
2759 idx += 1
2760 if ctx['num'] == idx:
2761 logger.info("Test: Valid EAP-EKE-ID/Request")
2762 return struct.pack(">BBHBBBB4BB",
2763 EAP_CODE_REQUEST, ctx['id'],
2764 4 + 1 + 1 + 2 + 4 + 1,
2765 EAP_TYPE_EKE,
2766 EAP_EKE_ID,
2767 1, 0,
2768 1, 1, 1, 1,
2769 255)
2770 idx += 1
2771 if ctx['num'] == idx:
2772 logger.info("Test: All zeroes DHComponent_S and empty CBvalue in EAP-EKE-Commit/Request")
2773 return struct.pack(">BBHBB4L32L",
2774 EAP_CODE_REQUEST, ctx['id'],
2775 4 + 1 + 1 + 16 + 128,
2776 EAP_TYPE_EKE,
2777 EAP_EKE_COMMIT,
2778 0, 0, 0, 0,
2779 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2780 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
2781 idx += 1
2782 if ctx['num'] == idx:
2783 logger.info("Test: Invalid PNonce_PS and Auth_S values in EAP-EKE-Confirm/Request")
2784 return struct.pack(">BBHBB4L8L5L5L",
2785 EAP_CODE_REQUEST, ctx['id'],
2786 4 + 1 + 1 + 16 + 2 * 16 + 20 + 20,
2787 EAP_TYPE_EKE,
2788 EAP_EKE_CONFIRM,
2789 0, 0, 0, 0,
2790 0, 0, 0, 0, 0, 0, 0, 0,
2791 0, 0, 0, 0, 0,
2792 0, 0, 0, 0, 0)
2793 idx += 1
2794 if ctx['num'] == idx:
2795 logger.info("Test: EAP-Failure")
2796 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
2797
2798 return None
2799
2800 srv = start_radius_server(eke_handler)
2801
2802 try:
2803 hapd = start_ap(apdev[0])
2804 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
2805
2806 for i in range(0, 14):
2807 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
2808 eap="EKE", identity="user", password="password",
2809 wait_connect=False)
2810 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
2811 timeout=15)
2812 if ev is None:
2813 raise Exception("Timeout on EAP start")
2814 if i in [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]:
2815 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"],
2816 timeout=10)
2817 if ev is None:
2818 raise Exception("Timeout on EAP failure")
2819 else:
2820 time.sleep(0.05)
2821 dev[0].request("REMOVE_NETWORK all")
2822 dev[0].dump_monitor()
2823 finally:
2824 stop_radius_server(srv)
2825
2826 def eap_eke_test_fail(dev, phase1=None, success=False):
2827 dev.connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
2828 eap="EKE", identity="eke user@domain", password="hello",
2829 phase1=phase1, erp="1", wait_connect=False)
2830 ev = dev.wait_event(["CTRL-EVENT-EAP-FAILURE",
2831 "CTRL-EVENT-EAP-SUCCESS"], timeout=5)
2832 if ev is None:
2833 raise Exception("Timeout on EAP failure")
2834 if not success and "CTRL-EVENT-EAP-FAILURE" not in ev:
2835 raise Exception("EAP did not fail during failure test")
2836 dev.request("REMOVE_NETWORK all")
2837 dev.wait_disconnected()
2838
2839 def test_eap_proto_eke_errors(dev, apdev):
2840 """EAP-EKE local error cases"""
2841 check_eap_capa(dev[0], "EKE")
2842 params = hostapd.wpa2_eap_params(ssid="eap-test")
2843 hapd = hostapd.add_ap(apdev[0], params)
2844 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
2845
2846 for i in range(1, 3):
2847 with alloc_fail(dev[0], i, "eap_eke_init"):
2848 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
2849 eap="EKE", identity="eke user", password="hello",
2850 wait_connect=False)
2851 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
2852 timeout=15)
2853 if ev is None:
2854 raise Exception("Timeout on EAP start")
2855 dev[0].request("REMOVE_NETWORK all")
2856 dev[0].wait_disconnected()
2857
2858 tests = [(1, "eap_eke_dh_init", None),
2859 (1, "eap_eke_prf_hmac_sha1", "dhgroup=3 encr=1 prf=1 mac=1"),
2860 (1, "eap_eke_prf_hmac_sha256", "dhgroup=5 encr=1 prf=2 mac=2"),
2861 (1, "eap_eke_prf", None),
2862 (1, "os_get_random;eap_eke_dhcomp", None),
2863 (1, "aes_128_cbc_encrypt;eap_eke_dhcomp", None),
2864 (1, "aes_128_cbc_decrypt;eap_eke_shared_secret", None),
2865 (1, "eap_eke_prf;eap_eke_shared_secret", None),
2866 (1, "eap_eke_prfplus;eap_eke_derive_ke_ki", None),
2867 (1, "eap_eke_prfplus;eap_eke_derive_ka", None),
2868 (1, "eap_eke_prfplus;eap_eke_derive_msk", None),
2869 (1, "os_get_random;eap_eke_prot", None),
2870 (1, "aes_128_cbc_decrypt;eap_eke_decrypt_prot", None),
2871 (1, "eap_eke_derive_key;eap_eke_process_commit", None),
2872 (1, "eap_eke_dh_init;eap_eke_process_commit", None),
2873 (1, "eap_eke_shared_secret;eap_eke_process_commit", None),
2874 (1, "eap_eke_derive_ke_ki;eap_eke_process_commit", None),
2875 (1, "eap_eke_dhcomp;eap_eke_process_commit", None),
2876 (1, "os_get_random;eap_eke_process_commit", None),
2877 (1, "os_get_random;=eap_eke_process_commit", None),
2878 (1, "eap_eke_prot;eap_eke_process_commit", None),
2879 (1, "eap_eke_decrypt_prot;eap_eke_process_confirm", None),
2880 (1, "eap_eke_derive_ka;eap_eke_process_confirm", None),
2881 (1, "eap_eke_auth;eap_eke_process_confirm", None),
2882 (2, "eap_eke_auth;eap_eke_process_confirm", None),
2883 (1, "eap_eke_prot;eap_eke_process_confirm", None),
2884 (1, "eap_eke_derive_msk;eap_eke_process_confirm", None)]
2885 for count, func, phase1 in tests:
2886 with fail_test(dev[0], count, func):
2887 eap_eke_test_fail(dev[0], phase1)
2888
2889 tests = [(1, "=eap_eke_derive_ke_ki", None),
2890 (1, "=eap_eke_derive_ka", None),
2891 (1, "=eap_eke_derive_msk", None),
2892 (1, "eap_eke_build_msg;eap_eke_process_id", None),
2893 (1, "wpabuf_alloc;eap_eke_process_id", None),
2894 (1, "=eap_eke_process_id", None),
2895 (1, "wpabuf_alloc;=eap_eke_process_id", None),
2896 (1, "wpabuf_alloc;eap_eke_process_id", None),
2897 (1, "eap_eke_build_msg;eap_eke_process_commit", None),
2898 (1, "wpabuf_resize;eap_eke_process_commit", None),
2899 (1, "eap_eke_build_msg;eap_eke_process_confirm", None)]
2900 for count, func, phase1 in tests:
2901 with alloc_fail(dev[0], count, func):
2902 eap_eke_test_fail(dev[0], phase1)
2903
2904 tests = [(1, "eap_eke_getKey", None),
2905 (1, "eap_eke_get_emsk", None),
2906 (1, "eap_eke_get_session_id", None)]
2907 for count, func, phase1 in tests:
2908 with alloc_fail(dev[0], count, func):
2909 eap_eke_test_fail(dev[0], phase1, success=True)
2910
2911 EAP_PAX_OP_STD_1 = 0x01
2912 EAP_PAX_OP_STD_2 = 0x02
2913 EAP_PAX_OP_STD_3 = 0x03
2914 EAP_PAX_OP_SEC_1 = 0x11
2915 EAP_PAX_OP_SEC_2 = 0x12
2916 EAP_PAX_OP_SEC_3 = 0x13
2917 EAP_PAX_OP_SEC_4 = 0x14
2918 EAP_PAX_OP_SEC_5 = 0x15
2919 EAP_PAX_OP_ACK = 0x21
2920
2921 EAP_PAX_FLAGS_MF = 0x01
2922 EAP_PAX_FLAGS_CE = 0x02
2923 EAP_PAX_FLAGS_AI = 0x04
2924
2925 EAP_PAX_MAC_HMAC_SHA1_128 = 0x01
2926 EAP_PAX_HMAC_SHA256_128 = 0x02
2927
2928 EAP_PAX_DH_GROUP_NONE = 0x00
2929 EAP_PAX_DH_GROUP_2048_MODP = 0x01
2930 EAP_PAX_DH_GROUP_3072_MODP = 0x02
2931 EAP_PAX_DH_GROUP_NIST_ECC_P_256 = 0x03
2932
2933 EAP_PAX_PUBLIC_KEY_NONE = 0x00
2934 EAP_PAX_PUBLIC_KEY_RSAES_OAEP = 0x01
2935 EAP_PAX_PUBLIC_KEY_RSA_PKCS1_V1_5 = 0x02
2936 EAP_PAX_PUBLIC_KEY_EL_GAMAL_NIST_ECC = 0x03
2937
2938 EAP_PAX_ADE_VENDOR_SPECIFIC = 0x01
2939 EAP_PAX_ADE_CLIENT_CHANNEL_BINDING = 0x02
2940 EAP_PAX_ADE_SERVER_CHANNEL_BINDING = 0x03
2941
2942 def test_eap_proto_pax(dev, apdev):
2943 """EAP-PAX protocol tests"""
2944 def pax_std_1(ctx):
2945 logger.info("Test: STD-1")
2946 ctx['id'] = 10
2947 return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'],
2948 4 + 1 + 5 + 2 + 32 + 16,
2949 EAP_TYPE_PAX,
2950 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128,
2951 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE,
2952 32, 0, 0, 0, 0, 0, 0, 0, 0,
2953 0x16, 0xc9, 0x08, 0x9d, 0x98, 0xa5, 0x6e, 0x1f,
2954 0xf0, 0xac, 0xcf, 0xc4, 0x66, 0xcd, 0x2d, 0xbf)
2955
2956 def pax_handler(ctx, req):
2957 logger.info("pax_handler - RX " + binascii.hexlify(req).decode())
2958 if 'num' not in ctx:
2959 ctx['num'] = 0
2960 ctx['num'] = ctx['num'] + 1
2961 if 'id' not in ctx:
2962 ctx['id'] = 1
2963 ctx['id'] = (ctx['id'] + 1) % 256
2964
2965 idx = 0
2966
2967 idx += 1
2968 if ctx['num'] == idx:
2969 logger.info("Test: Missing payload")
2970 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
2971 4 + 1,
2972 EAP_TYPE_PAX)
2973
2974 idx += 1
2975 if ctx['num'] == idx:
2976 logger.info("Test: Minimum length payload")
2977 return struct.pack(">BBHB4L", EAP_CODE_REQUEST, ctx['id'],
2978 4 + 1 + 16,
2979 EAP_TYPE_PAX,
2980 0, 0, 0, 0)
2981
2982 idx += 1
2983 if ctx['num'] == idx:
2984 logger.info("Test: Unsupported MAC ID")
2985 return struct.pack(">BBHBBBBBB4L", EAP_CODE_REQUEST, ctx['id'],
2986 4 + 1 + 5 + 16,
2987 EAP_TYPE_PAX,
2988 EAP_PAX_OP_STD_1, 0, 255, EAP_PAX_DH_GROUP_NONE,
2989 EAP_PAX_PUBLIC_KEY_NONE,
2990 0, 0, 0, 0)
2991
2992 idx += 1
2993 if ctx['num'] == idx:
2994 logger.info("Test: Unsupported DH Group ID")
2995 return struct.pack(">BBHBBBBBB4L", EAP_CODE_REQUEST, ctx['id'],
2996 4 + 1 + 5 + 16,
2997 EAP_TYPE_PAX,
2998 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128,
2999 255, EAP_PAX_PUBLIC_KEY_NONE,
3000 0, 0, 0, 0)
3001
3002 idx += 1
3003 if ctx['num'] == idx:
3004 logger.info("Test: Unsupported Public Key ID")
3005 return struct.pack(">BBHBBBBBB4L", EAP_CODE_REQUEST, ctx['id'],
3006 4 + 1 + 5 + 16,
3007 EAP_TYPE_PAX,
3008 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128,
3009 EAP_PAX_DH_GROUP_NONE, 255,
3010 0, 0, 0, 0)
3011
3012 idx += 1
3013 if ctx['num'] == idx:
3014 logger.info("Test: More fragments")
3015 return struct.pack(">BBHBBBBBB4L", EAP_CODE_REQUEST, ctx['id'],
3016 4 + 1 + 5 + 16,
3017 EAP_TYPE_PAX,
3018 EAP_PAX_OP_STD_1, EAP_PAX_FLAGS_MF,
3019 EAP_PAX_MAC_HMAC_SHA1_128,
3020 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE,
3021 0, 0, 0, 0)
3022
3023 idx += 1
3024 if ctx['num'] == idx:
3025 logger.info("Test: Invalid ICV")
3026 return struct.pack(">BBHBBBBBB4L", EAP_CODE_REQUEST, ctx['id'],
3027 4 + 1 + 5 + 16,
3028 EAP_TYPE_PAX,
3029 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128,
3030 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE,
3031 0, 0, 0, 0)
3032
3033 idx += 1
3034 if ctx['num'] == idx:
3035 logger.info("Test: Invalid ICV in short frame")
3036 return struct.pack(">BBHBBBBBB3L", EAP_CODE_REQUEST, ctx['id'],
3037 4 + 1 + 5 + 12,
3038 EAP_TYPE_PAX,
3039 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128,
3040 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE,
3041 0, 0, 0)
3042
3043 idx += 1
3044 if ctx['num'] == idx:
3045 logger.info("Test: Correct ICV - unsupported op_code")
3046 ctx['id'] = 10
3047 return struct.pack(">BBHBBBBBB16B", EAP_CODE_REQUEST, ctx['id'],
3048 4 + 1 + 5 + 16,
3049 EAP_TYPE_PAX,
3050 255, 0, EAP_PAX_MAC_HMAC_SHA1_128,
3051 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE,
3052 0x90, 0x78, 0x97, 0x38, 0x29, 0x94, 0x32, 0xd4,
3053 0x81, 0x27, 0xe0, 0xf6, 0x3b, 0x0d, 0xb2, 0xb2)
3054
3055 idx += 1
3056 if ctx['num'] == idx:
3057 logger.info("Test: Correct ICV - CE flag in STD-1")
3058 ctx['id'] = 10
3059 return struct.pack(">BBHBBBBBB16B", EAP_CODE_REQUEST, ctx['id'],
3060 4 + 1 + 5 + 16,
3061 EAP_TYPE_PAX,
3062 EAP_PAX_OP_STD_1, EAP_PAX_FLAGS_CE,
3063 EAP_PAX_MAC_HMAC_SHA1_128,
3064 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE,
3065 0x9c, 0x98, 0xb4, 0x0b, 0x94, 0x90, 0xde, 0x88,
3066 0xb7, 0x72, 0x63, 0x44, 0x1d, 0xe3, 0x7c, 0x5c)
3067
3068 idx += 1
3069 if ctx['num'] == idx:
3070 logger.info("Test: Correct ICV - too short STD-1 payload")
3071 ctx['id'] = 10
3072 return struct.pack(">BBHBBBBBB16B", EAP_CODE_REQUEST, ctx['id'],
3073 4 + 1 + 5 + 16,
3074 EAP_TYPE_PAX,
3075 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128,
3076 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE,
3077 0xda, 0xab, 0x2c, 0xe7, 0x84, 0x41, 0xb5, 0x5c,
3078 0xee, 0xcf, 0x62, 0x03, 0xc5, 0x69, 0xcb, 0xf4)
3079
3080 idx += 1
3081 if ctx['num'] == idx:
3082 logger.info("Test: Correct ICV - incorrect A length in STD-1")
3083 ctx['id'] = 10
3084 return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'],
3085 4 + 1 + 5 + 2 + 32 + 16,
3086 EAP_TYPE_PAX,
3087 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128,
3088 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE,
3089 0, 0, 0, 0, 0, 0, 0, 0, 0,
3090 0xc4, 0xb0, 0x81, 0xe4, 0x6c, 0x8c, 0x20, 0x23,
3091 0x60, 0x46, 0x89, 0xea, 0x94, 0x60, 0xf3, 0x2a)
3092
3093 idx += 1
3094 if ctx['num'] == idx:
3095 logger.info("Test: Correct ICV - extra data in STD-1")
3096 ctx['id'] = 10
3097 return struct.pack(">BBHBBBBBBH8LB16B", EAP_CODE_REQUEST, ctx['id'],
3098 4 + 1 + 5 + 2 + 32 + 1 + 16,
3099 EAP_TYPE_PAX,
3100 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128,
3101 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE,
3102 32, 0, 0, 0, 0, 0, 0, 0, 0,
3103 1,
3104 0x61, 0x49, 0x65, 0x37, 0x21, 0xe8, 0xd8, 0xbf,
3105 0xf3, 0x02, 0x01, 0xe5, 0x42, 0x51, 0xd3, 0x34)
3106 idx += 1
3107 if ctx['num'] == idx:
3108 logger.info("Test: Unexpected STD-1")
3109 return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'],
3110 4 + 1 + 5 + 2 + 32 + 16,
3111 EAP_TYPE_PAX,
3112 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128,
3113 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE,
3114 32, 0, 0, 0, 0, 0, 0, 0, 0,
3115 0xe5, 0x1d, 0xbf, 0xb8, 0x70, 0x20, 0x5c, 0xba,
3116 0x41, 0xbb, 0x34, 0xda, 0x1a, 0x08, 0xe6, 0x8d)
3117
3118 idx += 1
3119 if ctx['num'] == idx:
3120 return pax_std_1(ctx)
3121 idx += 1
3122 if ctx['num'] == idx:
3123 logger.info("Test: MAC ID changed during session")
3124 return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'],
3125 4 + 1 + 5 + 2 + 32 + 16,
3126 EAP_TYPE_PAX,
3127 EAP_PAX_OP_STD_1, 0, EAP_PAX_HMAC_SHA256_128,
3128 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE,
3129 32, 0, 0, 0, 0, 0, 0, 0, 0,
3130 0xee, 0x00, 0xbf, 0xb8, 0x70, 0x20, 0x5c, 0xba,
3131 0x41, 0xbb, 0x34, 0xda, 0x1a, 0x08, 0xe6, 0x8d)
3132
3133 idx += 1
3134 if ctx['num'] == idx:
3135 return pax_std_1(ctx)
3136 idx += 1
3137 if ctx['num'] == idx:
3138 logger.info("Test: DH Group ID changed during session")
3139 return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'],
3140 4 + 1 + 5 + 2 + 32 + 16,
3141 EAP_TYPE_PAX,
3142 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128,
3143 EAP_PAX_DH_GROUP_2048_MODP,
3144 EAP_PAX_PUBLIC_KEY_NONE,
3145 32, 0, 0, 0, 0, 0, 0, 0, 0,
3146 0xee, 0x01, 0xbf, 0xb8, 0x70, 0x20, 0x5c, 0xba,
3147 0x41, 0xbb, 0x34, 0xda, 0x1a, 0x08, 0xe6, 0x8d)
3148
3149 idx += 1
3150 if ctx['num'] == idx:
3151 return pax_std_1(ctx)
3152 idx += 1
3153 if ctx['num'] == idx:
3154 logger.info("Test: Public Key ID changed during session")
3155 return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'],
3156 4 + 1 + 5 + 2 + 32 + 16,
3157 EAP_TYPE_PAX,
3158 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128,
3159 EAP_PAX_DH_GROUP_NONE,
3160 EAP_PAX_PUBLIC_KEY_RSAES_OAEP,
3161 32, 0, 0, 0, 0, 0, 0, 0, 0,
3162 0xee, 0x02, 0xbf, 0xb8, 0x70, 0x20, 0x5c, 0xba,
3163 0x41, 0xbb, 0x34, 0xda, 0x1a, 0x08, 0xe6, 0x8d)
3164
3165 idx += 1
3166 if ctx['num'] == idx:
3167 logger.info("Test: Unexpected STD-3")
3168 ctx['id'] = 10
3169 return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'],
3170 4 + 1 + 5 + 2 + 32 + 16,
3171 EAP_TYPE_PAX,
3172 EAP_PAX_OP_STD_3, 0, EAP_PAX_MAC_HMAC_SHA1_128,
3173 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE,
3174 32, 0, 0, 0, 0, 0, 0, 0, 0,
3175 0x47, 0xbb, 0xc0, 0xf9, 0xb9, 0x69, 0xf5, 0xcb,
3176 0x3a, 0xe8, 0xe7, 0xd6, 0x80, 0x28, 0xf2, 0x59)
3177
3178 idx += 1
3179 if ctx['num'] == idx:
3180 return pax_std_1(ctx)
3181 idx += 1
3182 if ctx['num'] == idx:
3183 # TODO: MAC calculation; for now, this gets dropped due to incorrect
3184 # ICV
3185 logger.info("Test: STD-3 with CE flag")
3186 return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'],
3187 4 + 1 + 5 + 2 + 32 + 16,
3188 EAP_TYPE_PAX,
3189 EAP_PAX_OP_STD_3, EAP_PAX_FLAGS_CE,
3190 EAP_PAX_MAC_HMAC_SHA1_128,
3191 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE,
3192 32, 0, 0, 0, 0, 0, 0, 0, 0,
3193 0x8a, 0xc2, 0xf9, 0xf4, 0x8b, 0x75, 0x72, 0xa2,
3194 0x4d, 0xd3, 0x1e, 0x54, 0x77, 0x04, 0x05, 0xe2)
3195
3196 idx += 1
3197 if ctx['num'] & 0x1 == idx & 0x1:
3198 logger.info("Test: Default request")
3199 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
3200 4 + 1,
3201 EAP_TYPE_PAX)
3202 else:
3203 logger.info("Test: Default EAP-Failure")
3204 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3205
3206 srv = start_radius_server(pax_handler)
3207
3208 try:
3209 hapd = start_ap(apdev[0])
3210 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
3211
3212 for i in range(0, 18):
3213 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
3214 eap="PAX", identity="user",
3215 password_hex="0123456789abcdef0123456789abcdef",
3216 wait_connect=False)
3217 logger.info("Waiting for EAP method to start")
3218 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
3219 timeout=15)
3220 if ev is None:
3221 raise Exception("Timeout on EAP start")
3222 time.sleep(0.05)
3223 dev[0].request("REMOVE_NETWORK all")
3224 dev[0].dump_monitor()
3225
3226 logger.info("Too short password")
3227 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
3228 eap="PAX", identity="user",
3229 password_hex="0123456789abcdef0123456789abcd",
3230 wait_connect=False)
3231 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15)
3232 if ev is None:
3233 raise Exception("Timeout on EAP start")
3234 time.sleep(0.1)
3235 dev[0].request("REMOVE_NETWORK all")
3236 dev[0].dump_monitor()
3237
3238 logger.info("No password")
3239 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
3240 eap="PAX", identity="user",
3241 wait_connect=False)
3242 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15)
3243 if ev is None:
3244 raise Exception("Timeout on EAP start")
3245 time.sleep(0.1)
3246 dev[0].request("REMOVE_NETWORK all")
3247 dev[0].dump_monitor()
3248 finally:
3249 stop_radius_server(srv)
3250
3251 def test_eap_proto_pax_errors(dev, apdev):
3252 """EAP-PAX local error cases"""
3253 check_eap_capa(dev[0], "PAX")
3254 params = hostapd.wpa2_eap_params(ssid="eap-test")
3255 hapd = hostapd.add_ap(apdev[0], params)
3256 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
3257
3258 for i in range(1, 3):
3259 with alloc_fail(dev[0], i, "eap_pax_init"):
3260 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
3261 eap="PAX", identity="pax.user@example.com",
3262 password_hex="0123456789abcdef0123456789abcdef",
3263 wait_connect=False)
3264 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
3265 timeout=15)
3266 if ev is None:
3267 raise Exception("Timeout on EAP start")
3268 dev[0].request("REMOVE_NETWORK all")
3269 dev[0].wait_disconnected()
3270
3271 tests = ["eap_msg_alloc;eap_pax_alloc_resp;eap_pax_process_std_1",
3272 "eap_msg_alloc;eap_pax_alloc_resp;eap_pax_process_std_3",
3273 "eap_pax_getKey",
3274 "eap_pax_get_emsk",
3275 "eap_pax_get_session_id"]
3276 for func in tests:
3277 with alloc_fail(dev[0], 1, func):
3278 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
3279 eap="PAX", identity="pax.user@example.com",
3280 password_hex="0123456789abcdef0123456789abcdef",
3281 erp="1", wait_connect=False)
3282 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
3283 dev[0].request("REMOVE_NETWORK all")
3284 dev[0].wait_disconnected()
3285
3286 tests = [(1, "os_get_random;eap_pax_process_std_1"),
3287 (1, "eap_pax_initial_key_derivation"),
3288 (1, "eap_pax_mac;eap_pax_process_std_3"),
3289 (2, "eap_pax_mac;eap_pax_process_std_3"),
3290 (1, "eap_pax_kdf;eap_pax_getKey"),
3291 (1, "eap_pax_kdf;eap_pax_get_emsk")]
3292 for count, func in tests:
3293 with fail_test(dev[0], count, func):
3294 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
3295 eap="PAX", identity="pax.user@example.com",
3296 password_hex="0123456789abcdef0123456789abcdef",
3297 erp="1", wait_connect=False)
3298 wait_fail_trigger(dev[0], "GET_FAIL")
3299 dev[0].request("REMOVE_NETWORK all")
3300 dev[0].wait_disconnected()
3301
3302 def run_eap_pax_connect(dev):
3303 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412",
3304 eap="PAX", identity="pax.user@example.com",
3305 password_hex="0123456789abcdef0123456789abcdef",
3306 wait_connect=False)
3307 ev = dev.wait_event(["CTRL-EVENT-EAP-SUCCESS", "CTRL-EVENT-EAP-FAILURE",
3308 "CTRL-EVENT-DISCONNECTED"],
3309 timeout=1)
3310 dev.request("REMOVE_NETWORK all")
3311 if not ev or "CTRL-EVENT-DISCONNECTED" not in ev:
3312 dev.wait_disconnected()
3313 dev.dump_monitor()
3314
3315 def test_eap_proto_pax_errors_server(dev, apdev):
3316 """EAP-PAX local error cases on server"""
3317 check_eap_capa(dev[0], "PAX")
3318 params = int_eap_server_params()
3319 params['erp_domain'] = 'example.com'
3320 params['eap_server_erp'] = '1'
3321 hapd = hostapd.add_ap(apdev[0], params)
3322 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
3323
3324 tests = [(1, "eap_pax_init"),
3325 (1, "eap_msg_alloc;eap_pax_build_std_1"),
3326 (1, "eap_msg_alloc;eap_pax_build_std_3"),
3327 (1, "=eap_pax_process_std_2"),
3328 (1, "eap_pax_getKey"),
3329 (1, "eap_pax_get_emsk"),
3330 (1, "eap_pax_get_session_id")]
3331 for count, func in tests:
3332 with alloc_fail(hapd, count, func):
3333 run_eap_pax_connect(dev[0])
3334
3335 tests = [(1, "os_get_random;eap_pax_build_std_1"),
3336 (1, "eap_pax_mac;eap_pax_build_std_1"),
3337 (1, "eap_pax_mac;eap_pax_build_std_3"),
3338 (2, "eap_pax_mac;=eap_pax_build_std_3"),
3339 (1, "eap_pax_initial_key_derivation;eap_pax_process_std_2"),
3340 (1, "eap_pax_mac;eap_pax_process_std_2"),
3341 (2, "eap_pax_mac;=eap_pax_process_std_2"),
3342 (1, "eap_pax_mac;eap_pax_check")]
3343 for count, func in tests:
3344 with fail_test(hapd, count, func):
3345 run_eap_pax_connect(dev[0])
3346
3347 def start_pax_assoc(dev, hapd):
3348 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412",
3349 eap="PAX", identity="pax.user@example.com",
3350 password_hex="0123456789abcdef0123456789abcdef",
3351 wait_connect=False)
3352 proxy_msg(hapd, dev) # EAP-Identity/Request
3353 proxy_msg(dev, hapd) # EAP-Identity/Response
3354 proxy_msg(hapd, dev) # PAX_STD-1
3355
3356 def stop_pax_assoc(dev, hapd):
3357 dev.request("REMOVE_NETWORK all")
3358 dev.wait_disconnected()
3359 dev.dump_monitor()
3360 hapd.dump_monitor()
3361
3362 def test_eap_proto_pax_server(dev, apdev):
3363 """EAP-PAX protocol testing for the server"""
3364 check_eap_capa(dev[0], "PAX")
3365 params = int_eap_server_params()
3366 params['erp_domain'] = 'example.com'
3367 params['eap_server_erp'] = '1'
3368 hapd = hostapd.add_ap(apdev[0], params)
3369 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
3370 hapd.request("SET ext_eapol_frame_io 1")
3371 dev[0].request("SET ext_eapol_frame_io 1")
3372
3373 # Successful exchange to verify proxying mechanism
3374 start_pax_assoc(dev[0], hapd)
3375 proxy_msg(dev[0], hapd) # PAX_STD-2
3376 proxy_msg(hapd, dev[0]) # PAX_STD-3
3377 proxy_msg(dev[0], hapd) # PAX-ACK
3378 proxy_msg(hapd, dev[0]) # EAP-Success
3379 proxy_msg(hapd, dev[0]) # EAPOL-Key msg 1/4
3380 proxy_msg(dev[0], hapd) # EAPOL-Key msg 2/4
3381 proxy_msg(hapd, dev[0]) # EAPOL-Key msg 3/4
3382 proxy_msg(dev[0], hapd) # EAPOL-Key msg 4/4
3383 dev[0].wait_connected()
3384 stop_pax_assoc(dev[0], hapd)
3385
3386 start_pax_assoc(dev[0], hapd)
3387 resp = rx_msg(dev[0])
3388 # Too short EAP-PAX header (no OP-Code)
3389 hapd.note("EAP-PAX: Invalid frame")
3390 msg = resp[0:4] + "0005" + resp[8:12] + "0005" + "2e"
3391 tx_msg(dev[0], hapd, msg)
3392 # Too short EAP-PAX message (no payload)
3393 hapd.note("EAP-PAX: Invalid frame")
3394 msg = resp[0:4] + "000a" + resp[8:12] + "000a" + "2e1100000000"
3395 tx_msg(dev[0], hapd, msg)
3396 # Unexpected PAX_SEC-2
3397 hapd.note("EAP-PAX: Expected PAX_STD-2 - ignore op 17")
3398 msg = resp[0:4] + "001a" + resp[8:12] + "001a" + "2e1100000000" + 16*"00"
3399 tx_msg(dev[0], hapd, msg)
3400 # Unexpected MAC ID
3401 hapd.note("EAP-PAX: Expected MAC ID 0x1, received 0xff")
3402 msg = resp[0:4] + "001a" + resp[8:12] + "001a" + "2e0200ff0000" + 16*"00"
3403 tx_msg(dev[0], hapd, msg)
3404 # Unexpected DH Group ID
3405 hapd.note("EAP-PAX: Expected DH Group ID 0x0, received 0xff")
3406 msg = resp[0:4] + "001a" + resp[8:12] + "001a" + "2e020001ff00" + 16*"00"
3407 tx_msg(dev[0], hapd, msg)
3408 # Unexpected Public Key ID
3409 hapd.note("EAP-PAX: Expected Public Key ID 0x0, received 0xff")
3410 msg = resp[0:4] + "001a" + resp[8:12] + "001a" + "2e02000100ff" + 16*"00"
3411 tx_msg(dev[0], hapd, msg)
3412 # Unsupported Flags - MF
3413 hapd.note("EAP-PAX: fragmentation not supported")
3414 msg = resp[0:4] + "001a" + resp[8:12] + "001a" + "2e0201010000" + 16*"00"
3415 tx_msg(dev[0], hapd, msg)
3416 # Unsupported Flags - CE
3417 hapd.note("EAP-PAX: Unexpected CE flag")
3418 msg = resp[0:4] + "001a" + resp[8:12] + "001a" + "2e0202010000" + 16*"00"
3419 tx_msg(dev[0], hapd, msg)
3420 # Too short Payload in PAX_STD-2
3421 hapd.note("EAP-PAX: Too short PAX_STD-2 (B)")
3422 msg = resp[0:4] + "001a" + resp[8:12] + "001a" + "2e0200010000" + 16*"00"
3423 tx_msg(dev[0], hapd, msg)
3424 rx_msg(hapd)
3425 stop_pax_assoc(dev[0], hapd)
3426
3427 start_pax_assoc(dev[0], hapd)
3428 resp = rx_msg(dev[0])
3429 # Too short Payload in PAX_STD-2
3430 hapd.note("EAP-PAX: Too short PAX_STD-2 (CID)")
3431 msg = resp[0:4] + "002c" + resp[8:12] + "002c" + "2e0200010000" + "0020" + 32*"00"
3432 tx_msg(dev[0], hapd, msg)
3433 rx_msg(hapd)
3434 stop_pax_assoc(dev[0], hapd)
3435
3436 start_pax_assoc(dev[0], hapd)
3437 resp = rx_msg(dev[0])
3438 # Too short Payload in PAX_STD-2
3439 hapd.note("EAP-PAX: Too short PAX_STD-2 (CID)")
3440 msg = resp[0:4] + "002e" + resp[8:12] + "002e" + "2e0200010000" + "0020" + 32*"00" + "ffff"
3441 tx_msg(dev[0], hapd, msg)
3442 rx_msg(hapd)
3443 stop_pax_assoc(dev[0], hapd)
3444
3445 start_pax_assoc(dev[0], hapd)
3446 resp = rx_msg(dev[0])
3447 # Too long CID in PAX_STD-2
3448 hapd.note("EAP-PAX: Too long CID")
3449 msg = resp[0:4] + "062e" + resp[8:12] + "062e" + "2e0200010000" + "0020" + 32*"00" + "0600" + 1536*"00"
3450 tx_msg(dev[0], hapd, msg)
3451 rx_msg(hapd)
3452 stop_pax_assoc(dev[0], hapd)
3453
3454 start_pax_assoc(dev[0], hapd)
3455 resp = rx_msg(dev[0])
3456 # Too short Payload in PAX_STD-2
3457 hapd.note("EAP-PAX: Too short PAX_STD-2 (MAC_CK)")
3458 msg = resp[0:4] + "003c" + resp[8:12] + "003c" + "2e0200010000" + "0020" + 32*"00" + 16*"00"
3459 tx_msg(dev[0], hapd, msg)
3460 rx_msg(hapd)
3461 stop_pax_assoc(dev[0], hapd)
3462
3463 start_pax_assoc(dev[0], hapd)
3464 resp = rx_msg(dev[0])
3465 # Unknown CID for PAX
3466 hapd.note("EAP-PAX: EAP-PAX not enabled for CID")
3467 msg = resp[0:4] + "0041" + resp[8:12] + "0041" + "2e0200010000" + "0020" + 32*"00" + "0001" + "00" + "0010" + 16*"00"
3468 tx_msg(dev[0], hapd, msg)
3469 rx_msg(hapd)
3470 stop_pax_assoc(dev[0], hapd)
3471
3472 start_pax_assoc(dev[0], hapd)
3473 resp = rx_msg(dev[0])
3474 # Too short ICV
3475 hapd.note("EAP-PAX: Too short ICV (15) in PAX_STD-2")
3476 msg = resp[0:4] + "0063" + resp[8:12] + "0063" + resp[16:206]
3477 tx_msg(dev[0], hapd, msg)
3478 rx_msg(hapd)
3479 stop_pax_assoc(dev[0], hapd)
3480
3481 start_pax_assoc(dev[0], hapd)
3482 proxy_msg(dev[0], hapd) # PAX_STD-2
3483 proxy_msg(hapd, dev[0]) # PAX_STD-3
3484 resp = rx_msg(dev[0])
3485 # Unexpected PAX_STD-2
3486 hapd.note("EAP-PAX: Expected PAX-ACK - ignore op 1")
3487 msg = resp[0:4] + "001a" + resp[8:12] + "001a" + "2e0100000000" + 16*"00"
3488 tx_msg(dev[0], hapd, msg)
3489 stop_pax_assoc(dev[0], hapd)
3490
3491 def test_eap_proto_psk(dev, apdev):
3492 """EAP-PSK protocol tests"""
3493 def psk_handler(ctx, req):
3494 logger.info("psk_handler - RX " + binascii.hexlify(req).decode())
3495 if 'num' not in ctx:
3496 ctx['num'] = 0
3497 ctx['num'] = ctx['num'] + 1
3498 if 'id' not in ctx:
3499 ctx['id'] = 1
3500 ctx['id'] = (ctx['id'] + 1) % 256
3501
3502 idx = 0
3503
3504 idx += 1
3505 if ctx['num'] == idx:
3506 logger.info("Test: Missing payload")
3507 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
3508 4 + 1,
3509 EAP_TYPE_PSK)
3510
3511 idx += 1
3512 if ctx['num'] == idx:
3513 logger.info("Test: Non-zero T in first message")
3514 return struct.pack(">BBHBB4L", EAP_CODE_REQUEST, ctx['id'],
3515 4 + 1 + 1 + 16,
3516 EAP_TYPE_PSK, 0xc0, 0, 0, 0, 0)
3517
3518 idx += 1
3519 if ctx['num'] == idx:
3520 logger.info("Test: Valid first message")
3521 return struct.pack(">BBHBB4L", EAP_CODE_REQUEST, ctx['id'],
3522 4 + 1 + 1 + 16,
3523 EAP_TYPE_PSK, 0, 0, 0, 0, 0)
3524 idx += 1
3525 if ctx['num'] == idx:
3526 logger.info("Test: Too short third message")
3527 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
3528 4 + 1,
3529 EAP_TYPE_PSK)
3530
3531 idx += 1
3532 if ctx['num'] == idx:
3533 logger.info("Test: Valid first message")
3534 return struct.pack(">BBHBB4L", EAP_CODE_REQUEST, ctx['id'],
3535 4 + 1 + 1 + 16,
3536 EAP_TYPE_PSK, 0, 0, 0, 0, 0)
3537 idx += 1
3538 if ctx['num'] == idx:
3539 logger.info("Test: Incorrect T in third message")
3540 return struct.pack(">BBHBB4L4L", EAP_CODE_REQUEST, ctx['id'],
3541 4 + 1 + 1 + 16 + 16,
3542 EAP_TYPE_PSK, 0, 0, 0, 0, 0, 0, 0, 0, 0)
3543
3544 idx += 1
3545 if ctx['num'] == idx:
3546 logger.info("Test: Valid first message")
3547 return struct.pack(">BBHBB4L", EAP_CODE_REQUEST, ctx['id'],
3548 4 + 1 + 1 + 16,
3549 EAP_TYPE_PSK, 0, 0, 0, 0, 0)
3550 idx += 1
3551 if ctx['num'] == idx:
3552 logger.info("Test: Missing PCHANNEL in third message")
3553 return struct.pack(">BBHBB4L4L", EAP_CODE_REQUEST, ctx['id'],
3554 4 + 1 + 1 + 16 + 16,
3555 EAP_TYPE_PSK, 0x80, 0, 0, 0, 0, 0, 0, 0, 0)
3556
3557 idx += 1
3558 if ctx['num'] == idx:
3559 logger.info("Test: Valid first message")
3560 return struct.pack(">BBHBB4L", EAP_CODE_REQUEST, ctx['id'],
3561 4 + 1 + 1 + 16,
3562 EAP_TYPE_PSK, 0, 0, 0, 0, 0)
3563 idx += 1
3564 if ctx['num'] == idx:
3565 logger.info("Test: Invalic MAC_S in third message")
3566 return struct.pack(">BBHBB4L4L5LB", EAP_CODE_REQUEST, ctx['id'],
3567 4 + 1 + 1 + 16 + 16 + 21,
3568 EAP_TYPE_PSK, 0x80, 0, 0, 0, 0, 0, 0, 0, 0,
3569 0, 0, 0, 0, 0, 0)
3570
3571 idx += 1
3572 if ctx['num'] == idx:
3573 logger.info("Test: Valid first message")
3574 return struct.pack(">BBHBB4L", EAP_CODE_REQUEST, ctx['id'],
3575 4 + 1 + 1 + 16,
3576 EAP_TYPE_PSK, 0, 0, 0, 0, 0)
3577 idx += 1
3578 if ctx['num'] == idx:
3579 logger.info("Test: EAP-Failure")
3580 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3581
3582 return None
3583
3584 srv = start_radius_server(psk_handler)
3585
3586 try:
3587 hapd = start_ap(apdev[0])
3588 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
3589
3590 for i in range(0, 6):
3591 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
3592 eap="PSK", identity="user",
3593 password_hex="0123456789abcdef0123456789abcdef",
3594 wait_connect=False)
3595 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
3596 timeout=15)
3597 if ev is None:
3598 raise Exception("Timeout on EAP start")
3599 time.sleep(0.1)
3600 dev[0].request("REMOVE_NETWORK all")
3601
3602 logger.info("Test: Invalid PSK length")
3603 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
3604 eap="PSK", identity="user",
3605 password_hex="0123456789abcdef0123456789abcd",
3606 wait_connect=False)
3607 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
3608 timeout=15)
3609 if ev is None:
3610 raise Exception("Timeout on EAP start")
3611 time.sleep(0.1)
3612 dev[0].request("REMOVE_NETWORK all")
3613 finally:
3614 stop_radius_server(srv)
3615
3616 def test_eap_proto_psk_errors(dev, apdev):
3617 """EAP-PSK local error cases"""
3618 check_eap_capa(dev[0], "PSK")
3619 params = hostapd.wpa2_eap_params(ssid="eap-test")
3620 hapd = hostapd.add_ap(apdev[0], params)
3621 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
3622
3623 for i in range(1, 3):
3624 with alloc_fail(dev[0], i, "eap_psk_init"):
3625 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
3626 eap="PSK", identity="psk.user@example.com",
3627 password_hex="0123456789abcdef0123456789abcdef",
3628 wait_connect=False)
3629 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
3630 timeout=15)
3631 if ev is None:
3632 raise Exception("Timeout on EAP start")
3633 dev[0].request("REMOVE_NETWORK all")
3634 dev[0].wait_disconnected()
3635
3636 for i in range(1, 4):
3637 with fail_test(dev[0], i, "eap_psk_key_setup;eap_psk_init"):
3638 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
3639 eap="PSK", identity="psk.user@example.com",
3640 password_hex="0123456789abcdef0123456789abcdef",
3641 wait_connect=False)
3642 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
3643 timeout=15)
3644 if ev is None:
3645 raise Exception("Timeout on EAP start")
3646 dev[0].request("REMOVE_NETWORK all")
3647 dev[0].wait_disconnected()
3648
3649 tests = [(1, "=eap_psk_process_1"),
3650 (2, "=eap_psk_process_1"),
3651 (1, "eap_msg_alloc;eap_psk_process_1"),
3652 (1, "=eap_psk_process_3"),
3653 (2, "=eap_psk_process_3"),
3654 (1, "eap_msg_alloc;eap_psk_process_3"),
3655 (1, "eap_psk_getKey"),
3656 (1, "eap_psk_get_session_id"),
3657 (1, "eap_psk_get_emsk")]
3658 for count, func in tests:
3659 with alloc_fail(dev[0], count, func):
3660 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
3661 eap="PSK", identity="psk.user@example.com",
3662 password_hex="0123456789abcdef0123456789abcdef",
3663 erp="1", wait_connect=False)
3664 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
3665 timeout=15)
3666 if ev is None:
3667 raise Exception("Timeout on EAP start")
3668 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL",
3669 note="No allocation failure seen for %d:%s" % (count, func))
3670 dev[0].request("REMOVE_NETWORK all")
3671 dev[0].wait_disconnected()
3672
3673 tests = [(1, "os_get_random;eap_psk_process_1"),
3674 (1, "omac1_aes_128;eap_psk_process_3"),
3675 (1, "=omac1_aes_vector;omac1_aes_128;aes_128_eax_encrypt"),
3676 (2, "=omac1_aes_vector;omac1_aes_128;aes_128_eax_encrypt"),
3677 (3, "=omac1_aes_vector;omac1_aes_128;aes_128_eax_encrypt"),
3678 (1, "=omac1_aes_vector;omac1_aes_128;aes_128_eax_decrypt"),
3679 (2, "=omac1_aes_vector;omac1_aes_128;aes_128_eax_decrypt"),
3680 (3, "=omac1_aes_vector;omac1_aes_128;aes_128_eax_decrypt"),
3681 (1, "aes_128_eax_decrypt;eap_psk_process_3"),
3682 (2, "aes_128_eax_decrypt;eap_psk_process_3"),
3683 (3, "aes_128_eax_decrypt;eap_psk_process_3"),
3684 (1, "aes_128_eax_encrypt;eap_psk_process_3"),
3685 (2, "aes_128_eax_encrypt;eap_psk_process_3"),
3686 (3, "aes_128_eax_encrypt;eap_psk_process_3"),
3687 (1, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"),
3688 (2, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"),
3689 (3, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"),
3690 (4, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"),
3691 (5, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"),
3692 (6, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"),
3693 (7, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"),
3694 (8, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"),
3695 (9, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"),
3696 (10, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"),
3697 (1, "aes_ctr_encrypt;aes_128_eax_decrypt;eap_psk_process_3"),
3698 (1, "aes_ctr_encrypt;aes_128_eax_encrypt;eap_psk_process_3")]
3699 for count, func in tests:
3700 with fail_test(dev[0], count, func):
3701 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
3702 eap="PSK", identity="psk.user@example.com",
3703 password_hex="0123456789abcdef0123456789abcdef",
3704 wait_connect=False)
3705 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
3706 timeout=15)
3707 if ev is None:
3708 raise Exception("Timeout on EAP start")
3709 wait_fail_trigger(dev[0], "GET_FAIL",
3710 note="No failure seen for %d:%s" % (count, func))
3711 dev[0].request("REMOVE_NETWORK all")
3712 dev[0].wait_disconnected()
3713 dev[0].dump_monitor()
3714
3715 def run_eap_psk_connect(dev):
3716 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412",
3717 eap="PSK", identity="psk.user@example.com",
3718 password_hex="0123456789abcdef0123456789abcdef",
3719 wait_connect=False)
3720 ev = dev.wait_event(["CTRL-EVENT-EAP-SUCCESS", "CTRL-EVENT-EAP-FAILURE",
3721 "CTRL-EVENT-DISCONNECTED"],
3722 timeout=1)
3723 dev.request("REMOVE_NETWORK all")
3724 if not ev or "CTRL-EVENT-DISCONNECTED" not in ev:
3725 dev.wait_disconnected()
3726 dev.dump_monitor()
3727
3728 def test_eap_proto_psk_errors_server(dev, apdev):
3729 """EAP-PSK local error cases on server"""
3730 check_eap_capa(dev[0], "PSK")
3731 params = int_eap_server_params()
3732 params['erp_domain'] = 'example.com'
3733 params['eap_server_erp'] = '1'
3734 hapd = hostapd.add_ap(apdev[0], params)
3735 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
3736
3737 tests = [(1, "eap_psk_init"),
3738 (1, "eap_msg_alloc;eap_psk_build_1"),
3739 (1, "eap_msg_alloc;eap_psk_build_3"),
3740 (1, "=eap_psk_build_3"),
3741 (1, "=eap_psk_process_2"),
3742 (2, "=eap_psk_process_2"),
3743 (1, "=eap_psk_process_4"),
3744 (1, "aes_128_eax_decrypt;eap_psk_process_4"),
3745 (1, "eap_psk_getKey"),
3746 (1, "eap_psk_get_emsk"),
3747 (1, "eap_psk_get_session_id")]
3748 for count, func in tests:
3749 with alloc_fail(hapd, count, func):
3750 run_eap_psk_connect(dev[0])
3751
3752 tests = [(1, "os_get_random;eap_psk_build_1"),
3753 (1, "omac1_aes_128;eap_psk_build_3"),
3754 (1, "eap_psk_derive_keys;eap_psk_build_3"),
3755 (1, "aes_128_eax_encrypt;eap_psk_build_3"),
3756 (1, "eap_psk_key_setup;eap_psk_process_2"),
3757 (1, "omac1_aes_128;eap_psk_process_2"),
3758 (1, "aes_128_eax_decrypt;eap_psk_process_4")]
3759 for count, func in tests:
3760 with fail_test(hapd, count, func):
3761 run_eap_psk_connect(dev[0])
3762
3763 def start_psk_assoc(dev, hapd):
3764 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412",
3765 eap="PSK", identity="psk.user@example.com",
3766 password_hex="0123456789abcdef0123456789abcdef",
3767 wait_connect=False)
3768 proxy_msg(hapd, dev) # EAP-Identity/Request
3769 proxy_msg(dev, hapd) # EAP-Identity/Response
3770 proxy_msg(hapd, dev) # PSK-1
3771
3772 def stop_psk_assoc(dev, hapd):
3773 dev.request("REMOVE_NETWORK all")
3774 dev.wait_disconnected()
3775 dev.dump_monitor()
3776 hapd.dump_monitor()
3777
3778 def test_eap_proto_psk_server(dev, apdev):
3779 """EAP-PSK protocol testing for the server"""
3780 check_eap_capa(dev[0], "PSK")
3781 params = int_eap_server_params()
3782 params['erp_domain'] = 'example.com'
3783 params['eap_server_erp'] = '1'
3784 hapd = hostapd.add_ap(apdev[0], params)
3785 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
3786 hapd.request("SET ext_eapol_frame_io 1")
3787 dev[0].request("SET ext_eapol_frame_io 1")
3788
3789 # Successful exchange to verify proxying mechanism
3790 start_psk_assoc(dev[0], hapd)
3791 proxy_msg(dev[0], hapd) # PSK-2
3792 proxy_msg(hapd, dev[0]) # PSK-3
3793 proxy_msg(dev[0], hapd) # PSK-4
3794 proxy_msg(hapd, dev[0]) # EAP-Success
3795 proxy_msg(hapd, dev[0]) # EAPOL-Key msg 1/4
3796 proxy_msg(dev[0], hapd) # EAPOL-Key msg 2/4
3797 proxy_msg(hapd, dev[0]) # EAPOL-Key msg 3/4
3798 proxy_msg(dev[0], hapd) # EAPOL-Key msg 4/4
3799 dev[0].wait_connected()
3800 stop_psk_assoc(dev[0], hapd)
3801
3802 start_psk_assoc(dev[0], hapd)
3803 resp = rx_msg(dev[0])
3804 # Too short EAP-PSK header (no Flags)
3805 hapd.note("EAP-PSK: Invalid frame")
3806 msg = resp[0:4] + "0005" + resp[8:12] + "0005" + "2f"
3807 tx_msg(dev[0], hapd, msg)
3808 # Unexpected PSK-1
3809 hapd.note("EAP-PSK: Expected PSK-2 - ignore T=0")
3810 msg = resp[0:4] + "0006" + resp[8:12] + "0006" + "2f00"
3811 tx_msg(dev[0], hapd, msg)
3812 # Too short PSK-2
3813 hapd.note("EAP-PSK: Too short frame")
3814 msg = resp[0:4] + "0006" + resp[8:12] + "0006" + "2f40"
3815 tx_msg(dev[0], hapd, msg)
3816 # PSK-2 with unknown ID_P
3817 hapd.note("EAP-PSK: EAP-PSK not enabled for ID_P")
3818 msg = resp[0:4] + "004a" + resp[8:12] + "004a" + "2f40" + 3*16*"00" + 20*"00"
3819 tx_msg(dev[0], hapd, msg)
3820 rx_msg(hapd) # EAP-Failure
3821 stop_psk_assoc(dev[0], hapd)
3822
3823 start_psk_assoc(dev[0], hapd)
3824 proxy_msg(dev[0], hapd) # PSK-2
3825 proxy_msg(hapd, dev[0]) # PSK-3
3826 resp = rx_msg(dev[0])
3827 # Unexpected PSK-2
3828 hapd.note("EAP-PSK: Expected PSK-4 - ignore T=1")
3829 msg = resp[0:4] + "0016" + resp[8:12] + "0016" + "2f40" + 16*"00"
3830 tx_msg(dev[0], hapd, msg)
3831 # Too short PSK-4 (no PCHANNEL)
3832 hapd.note("EAP-PSK: Too short PCHANNEL data in PSK-4 (len=0, expected 21)")
3833 msg = resp[0:4] + "0016" + resp[8:12] + "0016" + "2fc0" + 16*"00"
3834 tx_msg(dev[0], hapd, msg)
3835 rx_msg(hapd) # PSK-3 retry
3836 stop_psk_assoc(dev[0], hapd)
3837
3838 start_psk_assoc(dev[0], hapd)
3839 proxy_msg(dev[0], hapd) # PSK-2
3840 proxy_msg(hapd, dev[0]) # PSK-3
3841 resp = rx_msg(dev[0])
3842 # PCHANNEL Nonce did not increase
3843 hapd.note("EAP-PSK: Nonce did not increase")
3844 msg = resp[0:4] + "002b" + resp[8:12] + "002b" + "2fc0" + 16*"00" + 21*"00"
3845 tx_msg(dev[0], hapd, msg)
3846 rx_msg(hapd) # PSK-3 retry
3847 stop_psk_assoc(dev[0], hapd)
3848
3849 start_psk_assoc(dev[0], hapd)
3850 proxy_msg(dev[0], hapd) # PSK-2
3851 proxy_msg(hapd, dev[0]) # PSK-3
3852 resp = rx_msg(dev[0])
3853 # Invalid PCHANNEL encryption
3854 hapd.note("EAP-PSK: PCHANNEL decryption failed")
3855 msg = resp[0:4] + "002b" + resp[8:12] + "002b" + "2fc0" + 16*"00" + 21*"11"
3856 tx_msg(dev[0], hapd, msg)
3857 rx_msg(hapd) # PSK-3 retry
3858 stop_psk_assoc(dev[0], hapd)
3859
3860 EAP_SIM_SUBTYPE_START = 10
3861 EAP_SIM_SUBTYPE_CHALLENGE = 11
3862 EAP_SIM_SUBTYPE_NOTIFICATION = 12
3863 EAP_SIM_SUBTYPE_REAUTHENTICATION = 13
3864 EAP_SIM_SUBTYPE_CLIENT_ERROR = 14
3865
3866 EAP_AKA_SUBTYPE_CHALLENGE = 1
3867 EAP_AKA_SUBTYPE_AUTHENTICATION_REJECT = 2
3868 EAP_AKA_SUBTYPE_SYNCHRONIZATION_FAILURE = 4
3869 EAP_AKA_SUBTYPE_IDENTITY = 5
3870 EAP_AKA_SUBTYPE_NOTIFICATION = 12
3871 EAP_AKA_SUBTYPE_REAUTHENTICATION = 13
3872 EAP_AKA_SUBTYPE_CLIENT_ERROR = 14
3873
3874 EAP_SIM_AT_RAND = 1
3875 EAP_SIM_AT_AUTN = 2
3876 EAP_SIM_AT_RES = 3
3877 EAP_SIM_AT_AUTS = 4
3878 EAP_SIM_AT_PADDING = 6
3879 EAP_SIM_AT_NONCE_MT = 7
3880 EAP_SIM_AT_PERMANENT_ID_REQ = 10
3881 EAP_SIM_AT_MAC = 11
3882 EAP_SIM_AT_NOTIFICATION = 12
3883 EAP_SIM_AT_ANY_ID_REQ = 13
3884 EAP_SIM_AT_IDENTITY = 14
3885 EAP_SIM_AT_VERSION_LIST = 15
3886 EAP_SIM_AT_SELECTED_VERSION = 16
3887 EAP_SIM_AT_FULLAUTH_ID_REQ = 17
3888 EAP_SIM_AT_COUNTER = 19
3889 EAP_SIM_AT_COUNTER_TOO_SMALL = 20
3890 EAP_SIM_AT_NONCE_S = 21
3891 EAP_SIM_AT_CLIENT_ERROR_CODE = 22
3892 EAP_SIM_AT_KDF_INPUT = 23
3893 EAP_SIM_AT_KDF = 24
3894 EAP_SIM_AT_IV = 129
3895 EAP_SIM_AT_ENCR_DATA = 130
3896 EAP_SIM_AT_NEXT_PSEUDONYM = 132
3897 EAP_SIM_AT_NEXT_REAUTH_ID = 133
3898 EAP_SIM_AT_CHECKCODE = 134
3899 EAP_SIM_AT_RESULT_IND = 135
3900 EAP_SIM_AT_BIDDING = 136
3901
3902 def test_eap_proto_aka(dev, apdev):
3903 """EAP-AKA protocol tests"""
3904 def aka_handler(ctx, req):
3905 logger.info("aka_handler - RX " + binascii.hexlify(req).decode())
3906 if 'num' not in ctx:
3907 ctx['num'] = 0
3908 ctx['num'] = ctx['num'] + 1
3909 if 'id' not in ctx:
3910 ctx['id'] = 1
3911 ctx['id'] = (ctx['id'] + 1) % 256
3912
3913 idx = 0
3914
3915 idx += 1
3916 if ctx['num'] == idx:
3917 logger.info("Test: Missing payload")
3918 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
3919 4 + 1,
3920 EAP_TYPE_AKA)
3921
3922 idx += 1
3923 if ctx['num'] == idx:
3924 logger.info("Test: Unknown subtype")
3925 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
3926 4 + 1 + 3,
3927 EAP_TYPE_AKA, 255, 0)
3928 idx += 1
3929 if ctx['num'] == idx:
3930 logger.info("Test: EAP-Failure")
3931 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3932
3933 idx += 1
3934 if ctx['num'] == idx:
3935 logger.info("Test: Client Error")
3936 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
3937 4 + 1 + 3,
3938 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CLIENT_ERROR, 0)
3939 idx += 1
3940 if ctx['num'] == idx:
3941 logger.info("Test: EAP-Failure")
3942 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3943
3944 idx += 1
3945 if ctx['num'] == idx:
3946 logger.info("Test: Too short attribute header")
3947 return struct.pack(">BBHBBHB", EAP_CODE_REQUEST, ctx['id'],
3948 4 + 1 + 1 + 3,
3949 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 255)
3950 idx += 1
3951 if ctx['num'] == idx:
3952 logger.info("Test: EAP-Failure")
3953 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3954
3955 idx += 1
3956 if ctx['num'] == idx:
3957 logger.info("Test: Truncated attribute")
3958 return struct.pack(">BBHBBHBB", EAP_CODE_REQUEST, ctx['id'],
3959 4 + 1 + 1 + 4,
3960 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 255,
3961 255)
3962 idx += 1
3963 if ctx['num'] == idx:
3964 logger.info("Test: EAP-Failure")
3965 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3966
3967 idx += 1
3968 if ctx['num'] == idx:
3969 logger.info("Test: Too short attribute data")
3970 return struct.pack(">BBHBBHBB", EAP_CODE_REQUEST, ctx['id'],
3971 4 + 1 + 1 + 4,
3972 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 255,
3973 0)
3974 idx += 1
3975 if ctx['num'] == idx:
3976 logger.info("Test: EAP-Failure")
3977 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3978
3979 idx += 1
3980 if ctx['num'] == idx:
3981 logger.info("Test: Skippable/non-skippable unrecognzized attribute")
3982 return struct.pack(">BBHBBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3983 4 + 1 + 1 + 10,
3984 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3985 255, 1, 0, 127, 1, 0)
3986 idx += 1
3987 if ctx['num'] == idx:
3988 logger.info("Test: EAP-Failure")
3989 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3990
3991 idx += 1
3992 if ctx['num'] == idx:
3993 logger.info("Test: Identity request without ID type")
3994 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
3995 4 + 1 + 3,
3996 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0)
3997 idx += 1
3998 if ctx['num'] == idx:
3999 logger.info("Test: Identity request ANY_ID")
4000 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4001 4 + 1 + 3 + 4,
4002 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
4003 EAP_SIM_AT_ANY_ID_REQ, 1, 0)
4004 idx += 1
4005 if ctx['num'] == idx:
4006 logger.info("Test: Identity request ANY_ID (duplicate)")
4007 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4008 4 + 1 + 3 + 4,
4009 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
4010 EAP_SIM_AT_ANY_ID_REQ, 1, 0)
4011 idx += 1
4012 if ctx['num'] == idx:
4013 logger.info("Test: EAP-Failure")
4014 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4015
4016 idx += 1
4017 if ctx['num'] == idx:
4018 logger.info("Test: Identity request ANY_ID")
4019 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4020 4 + 1 + 3 + 4,
4021 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
4022 EAP_SIM_AT_ANY_ID_REQ, 1, 0)
4023 idx += 1
4024 if ctx['num'] == idx:
4025 logger.info("Test: Identity request FULLAUTH_ID")
4026 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4027 4 + 1 + 3 + 4,
4028 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
4029 EAP_SIM_AT_FULLAUTH_ID_REQ, 1, 0)
4030 idx += 1
4031 if ctx['num'] == idx:
4032 logger.info("Test: Identity request FULLAUTH_ID (duplicate)")
4033 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4034 4 + 1 + 3 + 4,
4035 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
4036 EAP_SIM_AT_FULLAUTH_ID_REQ, 1, 0)
4037 idx += 1
4038 if ctx['num'] == idx:
4039 logger.info("Test: EAP-Failure")
4040 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4041
4042 idx += 1
4043 if ctx['num'] == idx:
4044 logger.info("Test: Identity request ANY_ID")
4045 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4046 4 + 1 + 3 + 4,
4047 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
4048 EAP_SIM_AT_ANY_ID_REQ, 1, 0)
4049 idx += 1
4050 if ctx['num'] == idx:
4051 logger.info("Test: Identity request FULLAUTH_ID")
4052 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4053 4 + 1 + 3 + 4,
4054 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
4055 EAP_SIM_AT_FULLAUTH_ID_REQ, 1, 0)
4056 idx += 1
4057 if ctx['num'] == idx:
4058 logger.info("Test: Identity request PERMANENT_ID")
4059 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4060 4 + 1 + 3 + 4,
4061 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
4062 EAP_SIM_AT_PERMANENT_ID_REQ, 1, 0)
4063 idx += 1
4064 if ctx['num'] == idx:
4065 logger.info("Test: Identity request PERMANENT_ID (duplicate)")
4066 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4067 4 + 1 + 3 + 4,
4068 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
4069 EAP_SIM_AT_PERMANENT_ID_REQ, 1, 0)
4070 idx += 1
4071 if ctx['num'] == idx:
4072 logger.info("Test: EAP-Failure")
4073 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4074
4075 idx += 1
4076 if ctx['num'] == idx:
4077 logger.info("Test: Challenge with no attributes")
4078 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
4079 4 + 1 + 3,
4080 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CHALLENGE, 0)
4081 idx += 1
4082 if ctx['num'] == idx:
4083 logger.info("Test: EAP-Failure")
4084 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4085
4086 idx += 1
4087 if ctx['num'] == idx:
4088 logger.info("Test: AKA Challenge with BIDDING")
4089 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4090 4 + 1 + 3 + 4,
4091 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CHALLENGE, 0,
4092 EAP_SIM_AT_BIDDING, 1, 0x8000)
4093 idx += 1
4094 if ctx['num'] == idx:
4095 logger.info("Test: EAP-Failure")
4096 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4097
4098 idx += 1
4099 if ctx['num'] == idx:
4100 logger.info("Test: Notification with no attributes")
4101 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
4102 4 + 1 + 3,
4103 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0)
4104 idx += 1
4105 if ctx['num'] == idx:
4106 logger.info("Test: EAP-Failure")
4107 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4108
4109 idx += 1
4110 if ctx['num'] == idx:
4111 logger.info("Test: Notification indicating success, but no MAC")
4112 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4113 4 + 1 + 3 + 4,
4114 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0,
4115 EAP_SIM_AT_NOTIFICATION, 1, 32768)
4116 idx += 1
4117 if ctx['num'] == idx:
4118 logger.info("Test: EAP-Failure")
4119 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4120
4121 idx += 1
4122 if ctx['num'] == idx:
4123 logger.info("Test: Notification indicating success, but invalid MAC value")
4124 return struct.pack(">BBHBBHBBHBBH4L", EAP_CODE_REQUEST, ctx['id'],
4125 4 + 1 + 3 + 4 + 20,
4126 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0,
4127 EAP_SIM_AT_NOTIFICATION, 1, 32768,
4128 EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0)
4129 idx += 1
4130 if ctx['num'] == idx:
4131 logger.info("Test: EAP-Failure")
4132 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4133
4134 idx += 1
4135 if ctx['num'] == idx:
4136 logger.info("Test: Notification indicating success with zero-key MAC")
4137 return struct.pack(">BBHBBHBBHBBH16B", EAP_CODE_REQUEST,
4138 ctx['id'] - 2,
4139 4 + 1 + 3 + 4 + 20,
4140 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0,
4141 EAP_SIM_AT_NOTIFICATION, 1, 32768,
4142 EAP_SIM_AT_MAC, 5, 0,
4143 0xbe, 0x2e, 0xbb, 0xa9, 0xfa, 0x2e, 0x82, 0x36,
4144 0x37, 0x8c, 0x32, 0x41, 0xb7, 0xc7, 0x58, 0xa3)
4145 idx += 1
4146 if ctx['num'] == idx:
4147 logger.info("Test: EAP-Success")
4148 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4)
4149
4150 idx += 1
4151 if ctx['num'] == idx:
4152 logger.info("Test: Notification before auth")
4153 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4154 4 + 1 + 3 + 4,
4155 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0,
4156 EAP_SIM_AT_NOTIFICATION, 1, 16384)
4157 idx += 1
4158 if ctx['num'] == idx:
4159 logger.info("Test: EAP-Failure")
4160 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4161
4162 idx += 1
4163 if ctx['num'] == idx:
4164 logger.info("Test: Notification before auth")
4165 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4166 4 + 1 + 3 + 4,
4167 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0,
4168 EAP_SIM_AT_NOTIFICATION, 1, 16385)
4169 idx += 1
4170 if ctx['num'] == idx:
4171 logger.info("Test: EAP-Failure")
4172 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4173
4174 idx += 1
4175 if ctx['num'] == idx:
4176 logger.info("Test: Notification with unrecognized non-failure")
4177 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4178 4 + 1 + 3 + 4,
4179 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0,
4180 EAP_SIM_AT_NOTIFICATION, 1, 0xc000)
4181 idx += 1
4182 if ctx['num'] == idx:
4183 logger.info("Test: Notification before auth (duplicate)")
4184 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4185 4 + 1 + 3 + 4,
4186 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0,
4187 EAP_SIM_AT_NOTIFICATION, 1, 0xc000)
4188 idx += 1
4189 if ctx['num'] == idx:
4190 logger.info("Test: EAP-Failure")
4191 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4192
4193 idx += 1
4194 if ctx['num'] == idx:
4195 logger.info("Test: Re-authentication (unexpected) with no attributes")
4196 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
4197 4 + 1 + 3,
4198 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_REAUTHENTICATION,
4199 0)
4200 idx += 1
4201 if ctx['num'] == idx:
4202 logger.info("Test: EAP-Failure")
4203 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4204
4205 idx += 1
4206 if ctx['num'] == idx:
4207 logger.info("Test: AKA Challenge with Checkcode claiming identity round was used")
4208 return struct.pack(">BBHBBHBBH5L", EAP_CODE_REQUEST, ctx['id'],
4209 4 + 1 + 3 + 24,
4210 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CHALLENGE, 0,
4211 EAP_SIM_AT_CHECKCODE, 6, 0, 0, 0, 0, 0, 0)
4212 idx += 1
4213 if ctx['num'] == idx:
4214 logger.info("Test: EAP-Failure")
4215 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4216
4217 idx += 1
4218 if ctx['num'] == idx:
4219 logger.info("Test: Identity request ANY_ID")
4220 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4221 4 + 1 + 3 + 4,
4222 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
4223 EAP_SIM_AT_ANY_ID_REQ, 1, 0)
4224 idx += 1
4225 if ctx['num'] == idx:
4226 logger.info("Test: AKA Challenge with Checkcode claiming no identity round was used")
4227 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4228 4 + 1 + 3 + 4,
4229 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CHALLENGE, 0,
4230 EAP_SIM_AT_CHECKCODE, 1, 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: Identity request ANY_ID")
4239 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4240 4 + 1 + 3 + 4,
4241 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
4242 EAP_SIM_AT_ANY_ID_REQ, 1, 0)
4243 idx += 1
4244 if ctx['num'] == idx:
4245 logger.info("Test: AKA Challenge with mismatching Checkcode value")
4246 return struct.pack(">BBHBBHBBH5L", EAP_CODE_REQUEST, ctx['id'],
4247 4 + 1 + 3 + 24,
4248 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CHALLENGE, 0,
4249 EAP_SIM_AT_CHECKCODE, 6, 0, 0, 0, 0, 0, 0)
4250 idx += 1
4251 if ctx['num'] == idx:
4252 logger.info("Test: EAP-Failure")
4253 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4254
4255 idx += 1
4256 if ctx['num'] == idx:
4257 logger.info("Test: Re-authentication (unexpected) with Checkcode claimin identity round was used")
4258 return struct.pack(">BBHBBHBBH5L", EAP_CODE_REQUEST, ctx['id'],
4259 4 + 1 + 3 + 24,
4260 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_REAUTHENTICATION,
4261 0,
4262 EAP_SIM_AT_CHECKCODE, 6, 0, 0, 0, 0, 0, 0)
4263 idx += 1
4264 if ctx['num'] == idx:
4265 logger.info("Test: EAP-Failure")
4266 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4267
4268 idx += 1
4269 if ctx['num'] == idx:
4270 logger.info("Test: Invalid AT_RAND length")
4271 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4272 4 + 1 + 3 + 4,
4273 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
4274 EAP_SIM_AT_RAND, 1, 0)
4275 idx += 1
4276 if ctx['num'] == idx:
4277 logger.info("Test: EAP-Failure")
4278 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4279
4280 idx += 1
4281 if ctx['num'] == idx:
4282 logger.info("Test: Invalid AT_AUTN length")
4283 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4284 4 + 1 + 3 + 4,
4285 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
4286 EAP_SIM_AT_AUTN, 1, 0)
4287 idx += 1
4288 if ctx['num'] == idx:
4289 logger.info("Test: EAP-Failure")
4290 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4291
4292 idx += 1
4293 if ctx['num'] == idx:
4294 logger.info("Test: Unencrypted AT_PADDING")
4295 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4296 4 + 1 + 3 + 4,
4297 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
4298 EAP_SIM_AT_PADDING, 1, 0)
4299 idx += 1
4300 if ctx['num'] == idx:
4301 logger.info("Test: EAP-Failure")
4302 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4303
4304 idx += 1
4305 if ctx['num'] == idx:
4306 logger.info("Test: Invalid AT_NONCE_MT length")
4307 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4308 4 + 1 + 3 + 4,
4309 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
4310 EAP_SIM_AT_NONCE_MT, 1, 0)
4311 idx += 1
4312 if ctx['num'] == idx:
4313 logger.info("Test: EAP-Failure")
4314 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4315
4316 idx += 1
4317 if ctx['num'] == idx:
4318 logger.info("Test: Invalid AT_MAC length")
4319 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4320 4 + 1 + 3 + 4,
4321 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
4322 EAP_SIM_AT_MAC, 1, 0)
4323 idx += 1
4324 if ctx['num'] == idx:
4325 logger.info("Test: EAP-Failure")
4326 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4327
4328 idx += 1
4329 if ctx['num'] == idx:
4330 logger.info("Test: Invalid AT_NOTIFICATION length")
4331 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
4332 4 + 1 + 3 + 8,
4333 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
4334 EAP_SIM_AT_NOTIFICATION, 2, 0, 0)
4335 idx += 1
4336 if ctx['num'] == idx:
4337 logger.info("Test: EAP-Failure")
4338 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4339
4340 idx += 1
4341 if ctx['num'] == idx:
4342 logger.info("Test: AT_IDENTITY overflow")
4343 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4344 4 + 1 + 3 + 4,
4345 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
4346 EAP_SIM_AT_IDENTITY, 1, 0xffff)
4347 idx += 1
4348 if ctx['num'] == idx:
4349 logger.info("Test: EAP-Failure")
4350 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4351
4352 idx += 1
4353 if ctx['num'] == idx:
4354 logger.info("Test: Unexpected AT_VERSION_LIST")
4355 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4356 4 + 1 + 3 + 4,
4357 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
4358 EAP_SIM_AT_VERSION_LIST, 1, 0)
4359 idx += 1
4360 if ctx['num'] == idx:
4361 logger.info("Test: EAP-Failure")
4362 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4363
4364 idx += 1
4365 if ctx['num'] == idx:
4366 logger.info("Test: Invalid AT_SELECTED_VERSION length")
4367 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
4368 4 + 1 + 3 + 8,
4369 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
4370 EAP_SIM_AT_SELECTED_VERSION, 2, 0, 0)
4371 idx += 1
4372 if ctx['num'] == idx:
4373 logger.info("Test: EAP-Failure")
4374 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4375
4376 idx += 1
4377 if ctx['num'] == idx:
4378 logger.info("Test: Unencrypted AT_COUNTER")
4379 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4380 4 + 1 + 3 + 4,
4381 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
4382 EAP_SIM_AT_COUNTER, 1, 0)
4383 idx += 1
4384 if ctx['num'] == idx:
4385 logger.info("Test: EAP-Failure")
4386 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4387
4388 idx += 1
4389 if ctx['num'] == idx:
4390 logger.info("Test: Unencrypted AT_COUNTER_TOO_SMALL")
4391 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4392 4 + 1 + 3 + 4,
4393 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
4394 EAP_SIM_AT_COUNTER_TOO_SMALL, 1, 0)
4395 idx += 1
4396 if ctx['num'] == idx:
4397 logger.info("Test: EAP-Failure")
4398 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4399
4400 idx += 1
4401 if ctx['num'] == idx:
4402 logger.info("Test: Unencrypted AT_NONCE_S")
4403 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4404 4 + 1 + 3 + 4,
4405 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
4406 EAP_SIM_AT_NONCE_S, 1, 0)
4407 idx += 1
4408 if ctx['num'] == idx:
4409 logger.info("Test: EAP-Failure")
4410 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4411
4412 idx += 1
4413 if ctx['num'] == idx:
4414 logger.info("Test: Invalid AT_CLIENT_ERROR_CODE length")
4415 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
4416 4 + 1 + 3 + 8,
4417 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
4418 EAP_SIM_AT_CLIENT_ERROR_CODE, 2, 0, 0)
4419 idx += 1
4420 if ctx['num'] == idx:
4421 logger.info("Test: EAP-Failure")
4422 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4423
4424 idx += 1
4425 if ctx['num'] == idx:
4426 logger.info("Test: Invalid AT_IV length")
4427 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4428 4 + 1 + 3 + 4,
4429 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
4430 EAP_SIM_AT_IV, 1, 0)
4431 idx += 1
4432 if ctx['num'] == idx:
4433 logger.info("Test: EAP-Failure")
4434 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4435
4436 idx += 1
4437 if ctx['num'] == idx:
4438 logger.info("Test: Invalid AT_ENCR_DATA length")
4439 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
4440 4 + 1 + 3 + 8,
4441 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
4442 EAP_SIM_AT_ENCR_DATA, 2, 0, 0)
4443 idx += 1
4444 if ctx['num'] == idx:
4445 logger.info("Test: EAP-Failure")
4446 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4447
4448 idx += 1
4449 if ctx['num'] == idx:
4450 logger.info("Test: Unencrypted AT_NEXT_PSEUDONYM")
4451 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4452 4 + 1 + 3 + 4,
4453 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
4454 EAP_SIM_AT_NEXT_PSEUDONYM, 1, 0)
4455 idx += 1
4456 if ctx['num'] == idx:
4457 logger.info("Test: EAP-Failure")
4458 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4459
4460 idx += 1
4461 if ctx['num'] == idx:
4462 logger.info("Test: Unencrypted AT_NEXT_REAUTH_ID")
4463 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4464 4 + 1 + 3 + 4,
4465 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
4466 EAP_SIM_AT_NEXT_REAUTH_ID, 1, 0)
4467 idx += 1
4468 if ctx['num'] == idx:
4469 logger.info("Test: EAP-Failure")
4470 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4471
4472 idx += 1
4473 if ctx['num'] == idx:
4474 logger.info("Test: Invalid AT_RES length")
4475 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4476 4 + 1 + 3 + 4,
4477 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
4478 EAP_SIM_AT_RES, 1, 0)
4479 idx += 1
4480 if ctx['num'] == idx:
4481 logger.info("Test: EAP-Failure")
4482 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4483
4484 idx += 1
4485 if ctx['num'] == idx:
4486 logger.info("Test: Invalid AT_RES length")
4487 return struct.pack(">BBHBBHBBH5L", EAP_CODE_REQUEST, ctx['id'],
4488 4 + 1 + 3 + 24,
4489 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
4490 EAP_SIM_AT_RES, 6, 0xffff, 0, 0, 0, 0, 0)
4491 idx += 1
4492 if ctx['num'] == idx:
4493 logger.info("Test: EAP-Failure")
4494 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4495
4496 idx += 1
4497 if ctx['num'] == idx:
4498 logger.info("Test: Invalid AT_AUTS length")
4499 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
4500 4 + 1 + 3 + 8,
4501 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
4502 EAP_SIM_AT_AUTS, 2, 0, 0)
4503 idx += 1
4504 if ctx['num'] == idx:
4505 logger.info("Test: EAP-Failure")
4506 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4507
4508 idx += 1
4509 if ctx['num'] == idx:
4510 logger.info("Test: Invalid AT_CHECKCODE length")
4511 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
4512 4 + 1 + 3 + 8,
4513 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
4514 EAP_SIM_AT_CHECKCODE, 2, 0, 0)
4515 idx += 1
4516 if ctx['num'] == idx:
4517 logger.info("Test: EAP-Failure")
4518 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4519
4520 idx += 1
4521 if ctx['num'] == idx:
4522 logger.info("Test: Invalid AT_RESULT_IND length")
4523 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
4524 4 + 1 + 3 + 8,
4525 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
4526 EAP_SIM_AT_RESULT_IND, 2, 0, 0)
4527 idx += 1
4528 if ctx['num'] == idx:
4529 logger.info("Test: EAP-Failure")
4530 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4531
4532 idx += 1
4533 if ctx['num'] == idx:
4534 logger.info("Test: Unexpected AT_KDF_INPUT")
4535 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
4536 4 + 1 + 3 + 8,
4537 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
4538 EAP_SIM_AT_KDF_INPUT, 2, 0, 0)
4539 idx += 1
4540 if ctx['num'] == idx:
4541 logger.info("Test: EAP-Failure")
4542 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4543
4544 idx += 1
4545 if ctx['num'] == idx:
4546 logger.info("Test: Unexpected AT_KDF")
4547 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
4548 4 + 1 + 3 + 8,
4549 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
4550 EAP_SIM_AT_KDF, 2, 0, 0)
4551 idx += 1
4552 if ctx['num'] == idx:
4553 logger.info("Test: EAP-Failure")
4554 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4555
4556 idx += 1
4557 if ctx['num'] == idx:
4558 logger.info("Test: Invalid AT_BIDDING length")
4559 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
4560 4 + 1 + 3 + 8,
4561 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
4562 EAP_SIM_AT_BIDDING, 2, 0, 0)
4563 idx += 1
4564 if ctx['num'] == idx:
4565 logger.info("Test: EAP-Failure")
4566 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4567
4568 return None
4569
4570 srv = start_radius_server(aka_handler)
4571
4572 try:
4573 hapd = start_ap(apdev[0])
4574 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
4575
4576 for i in range(0, 49):
4577 eap = "AKA AKA'" if i == 11 else "AKA"
4578 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4579 eap=eap, identity="0232010000000000",
4580 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123",
4581 wait_connect=False)
4582 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
4583 timeout=15)
4584 if ev is None:
4585 raise Exception("Timeout on EAP start")
4586 if i in [0, 15]:
4587 time.sleep(0.1)
4588 else:
4589 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"],
4590 timeout=10)
4591 if ev is None:
4592 raise Exception("Timeout on EAP failure")
4593 dev[0].request("REMOVE_NETWORK all")
4594 dev[0].dump_monitor()
4595 finally:
4596 stop_radius_server(srv)
4597
4598 def test_eap_proto_aka_prime(dev, apdev):
4599 """EAP-AKA' protocol tests"""
4600 def aka_prime_handler(ctx, req):
4601 logger.info("aka_prime_handler - RX " + binascii.hexlify(req).decode())
4602 if 'num' not in ctx:
4603 ctx['num'] = 0
4604 ctx['num'] = ctx['num'] + 1
4605 if 'id' not in ctx:
4606 ctx['id'] = 1
4607 ctx['id'] = (ctx['id'] + 1) % 256
4608
4609 idx = 0
4610
4611 idx += 1
4612 if ctx['num'] == idx:
4613 logger.info("Test: Missing payload")
4614 dev[0].note("Missing payload")
4615 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
4616 4 + 1,
4617 EAP_TYPE_AKA_PRIME)
4618
4619 idx += 1
4620 if ctx['num'] == idx:
4621 logger.info("Test: Challenge with no attributes")
4622 dev[0].note("Challenge with no attributes")
4623 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
4624 4 + 1 + 3,
4625 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0)
4626 idx += 1
4627 if ctx['num'] == idx:
4628 logger.info("Test: EAP-Failure")
4629 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4630
4631 idx += 1
4632 if ctx['num'] == idx:
4633 logger.info("Test: Challenge with empty AT_KDF_INPUT")
4634 dev[0].note("Challenge with empty AT_KDF_INPUT")
4635 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4636 4 + 1 + 3 + 4,
4637 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
4638 EAP_SIM_AT_KDF_INPUT, 1, 0)
4639 idx += 1
4640 if ctx['num'] == idx:
4641 logger.info("Test: EAP-Failure")
4642 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4643
4644 idx += 1
4645 if ctx['num'] == idx:
4646 logger.info("Test: Challenge with AT_KDF_INPUT")
4647 dev[0].note("Test: Challenge with AT_KDF_INPUT")
4648 return struct.pack(">BBHBBHBBHBBBB", EAP_CODE_REQUEST, ctx['id'],
4649 4 + 1 + 3 + 8,
4650 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
4651 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
4652 ord('c'), ord('d'))
4653 idx += 1
4654 if ctx['num'] == idx:
4655 logger.info("Test: EAP-Failure")
4656 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4657
4658 idx += 1
4659 if ctx['num'] == idx:
4660 logger.info("Test: Challenge with duplicated KDF")
4661 dev[0].note("Challenge with duplicated KDF")
4662 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH",
4663 EAP_CODE_REQUEST, ctx['id'],
4664 4 + 1 + 3 + 8 + 3 * 4,
4665 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
4666 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
4667 ord('c'), ord('d'),
4668 EAP_SIM_AT_KDF, 1, 1,
4669 EAP_SIM_AT_KDF, 1, 2,
4670 EAP_SIM_AT_KDF, 1, 1)
4671 idx += 1
4672 if ctx['num'] == idx:
4673 logger.info("Test: EAP-Failure")
4674 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4675
4676 idx += 1
4677 if ctx['num'] == idx:
4678 logger.info("Test: Challenge with multiple KDF proposals")
4679 dev[0].note("Challenge with multiple KDF proposals (preparation)")
4680 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH",
4681 EAP_CODE_REQUEST, ctx['id'],
4682 4 + 1 + 3 + 8 + 3 * 4,
4683 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
4684 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
4685 ord('c'), ord('d'),
4686 EAP_SIM_AT_KDF, 1, 255,
4687 EAP_SIM_AT_KDF, 1, 254,
4688 EAP_SIM_AT_KDF, 1, 1)
4689 idx += 1
4690 if ctx['num'] == idx:
4691 logger.info("Test: Challenge with incorrect KDF selected")
4692 dev[0].note("Challenge with incorrect KDF selected")
4693 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBHBBH",
4694 EAP_CODE_REQUEST, ctx['id'],
4695 4 + 1 + 3 + 8 + 4 * 4,
4696 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
4697 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
4698 ord('c'), ord('d'),
4699 EAP_SIM_AT_KDF, 1, 255,
4700 EAP_SIM_AT_KDF, 1, 255,
4701 EAP_SIM_AT_KDF, 1, 254,
4702 EAP_SIM_AT_KDF, 1, 1)
4703 idx += 1
4704 if ctx['num'] == idx:
4705 logger.info("Test: EAP-Failure")
4706 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4707
4708 idx += 1
4709 if ctx['num'] == idx:
4710 logger.info("Test: Challenge with multiple KDF proposals")
4711 dev[0].note("Challenge with multiple KDF proposals (preparation)")
4712 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH",
4713 EAP_CODE_REQUEST, ctx['id'],
4714 4 + 1 + 3 + 8 + 3 * 4,
4715 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
4716 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
4717 ord('c'), ord('d'),
4718 EAP_SIM_AT_KDF, 1, 255,
4719 EAP_SIM_AT_KDF, 1, 254,
4720 EAP_SIM_AT_KDF, 1, 1)
4721 idx += 1
4722 if ctx['num'] == idx:
4723 logger.info("Test: Challenge with selected KDF not duplicated")
4724 dev[0].note("Challenge with selected KDF not duplicated")
4725 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH",
4726 EAP_CODE_REQUEST, ctx['id'],
4727 4 + 1 + 3 + 8 + 3 * 4,
4728 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
4729 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
4730 ord('c'), ord('d'),
4731 EAP_SIM_AT_KDF, 1, 1,
4732 EAP_SIM_AT_KDF, 1, 255,
4733 EAP_SIM_AT_KDF, 1, 254)
4734 idx += 1
4735 if ctx['num'] == idx:
4736 logger.info("Test: EAP-Failure")
4737 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4738
4739 idx += 1
4740 if ctx['num'] == idx:
4741 logger.info("Test: Challenge with multiple KDF proposals")
4742 dev[0].note("Challenge with multiple KDF proposals (preparation)")
4743 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH",
4744 EAP_CODE_REQUEST, ctx['id'],
4745 4 + 1 + 3 + 8 + 3 * 4,
4746 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
4747 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
4748 ord('c'), ord('d'),
4749 EAP_SIM_AT_KDF, 1, 255,
4750 EAP_SIM_AT_KDF, 1, 254,
4751 EAP_SIM_AT_KDF, 1, 1)
4752 idx += 1
4753 if ctx['num'] == idx:
4754 logger.info("Test: Challenge with selected KDF duplicated (missing MAC, RAND, AUTN)")
4755 dev[0].note("Challenge with selected KDF duplicated (missing MAC, RAND, AUTN)")
4756 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBHBBH",
4757 EAP_CODE_REQUEST, ctx['id'],
4758 4 + 1 + 3 + 8 + 4 * 4,
4759 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
4760 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
4761 ord('c'), ord('d'),
4762 EAP_SIM_AT_KDF, 1, 1,
4763 EAP_SIM_AT_KDF, 1, 255,
4764 EAP_SIM_AT_KDF, 1, 254,
4765 EAP_SIM_AT_KDF, 1, 1)
4766 idx += 1
4767 if ctx['num'] == idx:
4768 logger.info("Test: EAP-Failure")
4769 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4770
4771 idx += 1
4772 if ctx['num'] == idx:
4773 logger.info("Test: Challenge with multiple unsupported KDF proposals")
4774 dev[0].note("Challenge with multiple unsupported KDF proposals")
4775 return struct.pack(">BBHBBHBBHBBBBBBHBBH",
4776 EAP_CODE_REQUEST, ctx['id'],
4777 4 + 1 + 3 + 8 + 2 * 4,
4778 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
4779 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
4780 ord('c'), ord('d'),
4781 EAP_SIM_AT_KDF, 1, 255,
4782 EAP_SIM_AT_KDF, 1, 254)
4783 idx += 1
4784 if ctx['num'] == idx:
4785 logger.info("Test: EAP-Failure")
4786 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4787
4788 idx += 1
4789 if ctx['num'] == idx:
4790 logger.info("Test: Challenge with multiple KDF proposals")
4791 dev[0].note("Challenge with multiple KDF proposals (preparation)")
4792 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH",
4793 EAP_CODE_REQUEST, ctx['id'],
4794 4 + 1 + 3 + 8 + 3 * 4,
4795 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
4796 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
4797 ord('c'), ord('d'),
4798 EAP_SIM_AT_KDF, 1, 255,
4799 EAP_SIM_AT_KDF, 1, 254,
4800 EAP_SIM_AT_KDF, 1, 1)
4801 idx += 1
4802 if ctx['num'] == idx:
4803 logger.info("Test: Challenge with invalid MAC, RAND, AUTN values)")
4804 dev[0].note("Challenge with invalid MAC, RAND, AUTN values)")
4805 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBHBBHBBH4LBBH4LBBH4L",
4806 EAP_CODE_REQUEST, ctx['id'],
4807 4 + 1 + 3 + 8 + 4 * 4 + 20 + 20 + 20,
4808 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
4809 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
4810 ord('c'), ord('d'),
4811 EAP_SIM_AT_KDF, 1, 1,
4812 EAP_SIM_AT_KDF, 1, 255,
4813 EAP_SIM_AT_KDF, 1, 254,
4814 EAP_SIM_AT_KDF, 1, 1,
4815 EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0,
4816 EAP_SIM_AT_RAND, 5, 0, 0, 0, 0, 0,
4817 EAP_SIM_AT_AUTN, 5, 0, 0, 0, 0, 0)
4818 idx += 1
4819 if ctx['num'] == idx:
4820 logger.info("Test: EAP-Failure")
4821 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4822
4823 idx += 1
4824 if ctx['num'] == idx:
4825 logger.info("Test: Challenge - AMF separation bit not set)")
4826 dev[0].note("Challenge - AMF separation bit not set)")
4827 return struct.pack(">BBHBBHBBHBBBBBBHBBH4LBBH4LBBH4L",
4828 EAP_CODE_REQUEST, ctx['id'],
4829 4 + 1 + 3 + 8 + 4 + 20 + 20 + 20,
4830 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
4831 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
4832 ord('c'), ord('d'),
4833 EAP_SIM_AT_KDF, 1, 1,
4834 EAP_SIM_AT_MAC, 5, 0, 1, 2, 3, 4,
4835 EAP_SIM_AT_RAND, 5, 0, 5, 6, 7, 8,
4836 EAP_SIM_AT_AUTN, 5, 0, 9, 10,
4837 0x2fda8ef7, 0xbba518cc)
4838 idx += 1
4839 if ctx['num'] == idx:
4840 logger.info("Test: EAP-Failure")
4841 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4842
4843 idx += 1
4844 if ctx['num'] == idx:
4845 logger.info("Test: Challenge - Invalid MAC")
4846 dev[0].note("Challenge - Invalid MAC")
4847 return struct.pack(">BBHBBHBBHBBBBBBHBBH4LBBH4LBBH4L",
4848 EAP_CODE_REQUEST, ctx['id'],
4849 4 + 1 + 3 + 8 + 4 + 20 + 20 + 20,
4850 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
4851 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
4852 ord('c'), ord('d'),
4853 EAP_SIM_AT_KDF, 1, 1,
4854 EAP_SIM_AT_MAC, 5, 0, 1, 2, 3, 4,
4855 EAP_SIM_AT_RAND, 5, 0, 5, 6, 7, 8,
4856 EAP_SIM_AT_AUTN, 5, 0, 0xffffffff, 0xffffffff,
4857 0xd1f90322, 0x40514cb4)
4858 idx += 1
4859 if ctx['num'] == idx:
4860 logger.info("Test: EAP-Failure")
4861 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4862
4863 idx += 1
4864 if ctx['num'] == idx:
4865 logger.info("Test: Challenge - Valid MAC")
4866 dev[0].note("Challenge - Valid MAC")
4867 return struct.pack(">BBHBBHBBHBBBBBBHBBH4LBBH4LBBH4L",
4868 EAP_CODE_REQUEST, ctx['id'],
4869 4 + 1 + 3 + 8 + 4 + 20 + 20 + 20,
4870 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
4871 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
4872 ord('c'), ord('d'),
4873 EAP_SIM_AT_KDF, 1, 1,
4874 EAP_SIM_AT_MAC, 5, 0,
4875 0xf4a3c1d3, 0x7c901401, 0x34bd8b01, 0x6f7fa32f,
4876 EAP_SIM_AT_RAND, 5, 0, 5, 6, 7, 8,
4877 EAP_SIM_AT_AUTN, 5, 0, 0xffffffff, 0xffffffff,
4878 0xd1f90322, 0x40514cb4)
4879 idx += 1
4880 if ctx['num'] == idx:
4881 logger.info("Test: EAP-Failure")
4882 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4883
4884 idx += 1
4885 if ctx['num'] == idx:
4886 logger.info("Test: Invalid AT_KDF_INPUT length")
4887 dev[0].note("Invalid AT_KDF_INPUT length")
4888 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
4889 4 + 1 + 3 + 8,
4890 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_IDENTITY, 0,
4891 EAP_SIM_AT_KDF_INPUT, 2, 0xffff, 0)
4892 idx += 1
4893 if ctx['num'] == idx:
4894 logger.info("Test: EAP-Failure")
4895 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4896
4897 idx += 1
4898 if ctx['num'] == idx:
4899 logger.info("Test: Invalid AT_KDF length")
4900 dev[0].note("Invalid AT_KDF length")
4901 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
4902 4 + 1 + 3 + 8,
4903 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_IDENTITY, 0,
4904 EAP_SIM_AT_KDF, 2, 0, 0)
4905 idx += 1
4906 if ctx['num'] == idx:
4907 logger.info("Test: EAP-Failure")
4908 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4909
4910 idx += 1
4911 if ctx['num'] == idx:
4912 logger.info("Test: Challenge with large number of KDF proposals")
4913 dev[0].note("Challenge with large number of KDF proposals")
4914 return struct.pack(">BBHBBHBBHBBHBBHBBHBBHBBHBBHBBHBBHBBHBBHBBH",
4915 EAP_CODE_REQUEST, ctx['id'],
4916 4 + 1 + 3 + 12 * 4,
4917 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
4918 EAP_SIM_AT_KDF, 1, 255,
4919 EAP_SIM_AT_KDF, 1, 254,
4920 EAP_SIM_AT_KDF, 1, 253,
4921 EAP_SIM_AT_KDF, 1, 252,
4922 EAP_SIM_AT_KDF, 1, 251,
4923 EAP_SIM_AT_KDF, 1, 250,
4924 EAP_SIM_AT_KDF, 1, 249,
4925 EAP_SIM_AT_KDF, 1, 248,
4926 EAP_SIM_AT_KDF, 1, 247,
4927 EAP_SIM_AT_KDF, 1, 246,
4928 EAP_SIM_AT_KDF, 1, 245,
4929 EAP_SIM_AT_KDF, 1, 244)
4930 idx += 1
4931 if ctx['num'] == idx:
4932 logger.info("Test: EAP-Failure")
4933 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4934
4935 idx += 1
4936 if ctx['num'] == idx:
4937 logger.info("Test: Challenge with multiple KDF proposals")
4938 dev[0].note("Challenge with multiple KDF proposals (preparation)")
4939 return struct.pack(">BBHBBHBBHBBBBBBHBBH",
4940 EAP_CODE_REQUEST, ctx['id'],
4941 4 + 1 + 3 + 8 + 2 * 4,
4942 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
4943 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
4944 ord('c'), ord('d'),
4945 EAP_SIM_AT_KDF, 1, 2,
4946 EAP_SIM_AT_KDF, 1, 1)
4947 idx += 1
4948 if ctx['num'] == idx:
4949 logger.info("Test: Challenge with an extra KDF appended")
4950 dev[0].note("Challenge with an extra KDF appended")
4951 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBHBBH",
4952 EAP_CODE_REQUEST, ctx['id'],
4953 4 + 1 + 3 + 8 + 4 * 4,
4954 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
4955 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
4956 ord('c'), ord('d'),
4957 EAP_SIM_AT_KDF, 1, 1,
4958 EAP_SIM_AT_KDF, 1, 2,
4959 EAP_SIM_AT_KDF, 1, 1,
4960 EAP_SIM_AT_KDF, 1, 0)
4961 idx += 1
4962 if ctx['num'] == idx:
4963 logger.info("Test: EAP-Failure")
4964 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4965
4966 idx += 1
4967 if ctx['num'] == idx:
4968 logger.info("Test: Challenge with multiple KDF proposals")
4969 dev[0].note("Challenge with multiple KDF proposals (preparation)")
4970 return struct.pack(">BBHBBHBBHBBBBBBHBBH",
4971 EAP_CODE_REQUEST, ctx['id'],
4972 4 + 1 + 3 + 8 + 2 * 4,
4973 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
4974 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
4975 ord('c'), ord('d'),
4976 EAP_SIM_AT_KDF, 1, 2,
4977 EAP_SIM_AT_KDF, 1, 1)
4978 idx += 1
4979 if ctx['num'] == idx:
4980 logger.info("Test: Challenge with a modified KDF")
4981 dev[0].note("Challenge with a modified KDF")
4982 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH",
4983 EAP_CODE_REQUEST, ctx['id'],
4984 4 + 1 + 3 + 8 + 3 * 4,
4985 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
4986 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
4987 ord('c'), ord('d'),
4988 EAP_SIM_AT_KDF, 1, 1,
4989 EAP_SIM_AT_KDF, 1, 0,
4990 EAP_SIM_AT_KDF, 1, 1)
4991 idx += 1
4992 if ctx['num'] == idx:
4993 logger.info("Test: EAP-Failure")
4994 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4995
4996 return None
4997
4998 srv = start_radius_server(aka_prime_handler)
4999
5000 try:
5001 hapd = start_ap(apdev[0])
5002 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
5003
5004 for i in range(0, 18):
5005 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5006 eap="AKA'", identity="6555444333222111",
5007 password="5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123",
5008 wait_connect=False)
5009 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
5010 timeout=15)
5011 if ev is None:
5012 raise Exception("Timeout on EAP start")
5013 if i in [0]:
5014 time.sleep(0.1)
5015 else:
5016 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"],
5017 timeout=10)
5018 if ev is None:
5019 raise Exception("Timeout on EAP failure")
5020 dev[0].request("REMOVE_NETWORK all")
5021 dev[0].dump_monitor()
5022 finally:
5023 stop_radius_server(srv)
5024
5025 def test_eap_proto_sim(dev, apdev):
5026 """EAP-SIM protocol tests"""
5027 def sim_handler(ctx, req):
5028 logger.info("sim_handler - RX " + binascii.hexlify(req).decode())
5029 if 'num' not in ctx:
5030 ctx['num'] = 0
5031 ctx['num'] = ctx['num'] + 1
5032 if 'id' not in ctx:
5033 ctx['id'] = 1
5034 ctx['id'] = (ctx['id'] + 1) % 256
5035
5036 idx = 0
5037
5038 idx += 1
5039 if ctx['num'] == idx:
5040 logger.info("Test: Missing payload")
5041 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
5042 4 + 1,
5043 EAP_TYPE_SIM)
5044
5045 idx += 1
5046 if ctx['num'] == idx:
5047 logger.info("Test: Unexpected AT_AUTN")
5048 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
5049 4 + 1 + 3 + 8,
5050 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
5051 EAP_SIM_AT_AUTN, 2, 0, 0)
5052 idx += 1
5053 if ctx['num'] == idx:
5054 logger.info("Test: EAP-Failure")
5055 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5056
5057 idx += 1
5058 if ctx['num'] == idx:
5059 logger.info("Test: Too short AT_VERSION_LIST")
5060 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
5061 4 + 1 + 3 + 4,
5062 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
5063 EAP_SIM_AT_VERSION_LIST, 1, 0)
5064 idx += 1
5065 if ctx['num'] == idx:
5066 logger.info("Test: EAP-Failure")
5067 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5068
5069 idx += 1
5070 if ctx['num'] == idx:
5071 logger.info("Test: AT_VERSION_LIST overflow")
5072 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
5073 4 + 1 + 3 + 4,
5074 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
5075 EAP_SIM_AT_VERSION_LIST, 1, 0xffff)
5076 idx += 1
5077 if ctx['num'] == idx:
5078 logger.info("Test: EAP-Failure")
5079 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5080
5081 idx += 1
5082 if ctx['num'] == idx:
5083 logger.info("Test: Unexpected AT_AUTS")
5084 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
5085 4 + 1 + 3 + 8,
5086 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
5087 EAP_SIM_AT_AUTS, 2, 0, 0)
5088 idx += 1
5089 if ctx['num'] == idx:
5090 logger.info("Test: EAP-Failure")
5091 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5092
5093 idx += 1
5094 if ctx['num'] == idx:
5095 logger.info("Test: Unexpected AT_CHECKCODE")
5096 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
5097 4 + 1 + 3 + 8,
5098 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
5099 EAP_SIM_AT_CHECKCODE, 2, 0, 0)
5100 idx += 1
5101 if ctx['num'] == idx:
5102 logger.info("Test: EAP-Failure")
5103 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5104
5105 idx += 1
5106 if ctx['num'] == idx:
5107 logger.info("Test: No AT_VERSION_LIST in Start")
5108 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
5109 4 + 1 + 3,
5110 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0)
5111 idx += 1
5112 if ctx['num'] == idx:
5113 logger.info("Test: EAP-Failure")
5114 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5115
5116 idx += 1
5117 if ctx['num'] == idx:
5118 logger.info("Test: No support version in AT_VERSION_LIST")
5119 return struct.pack(">BBHBBHBBH4B", EAP_CODE_REQUEST, ctx['id'],
5120 4 + 1 + 3 + 8,
5121 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
5122 EAP_SIM_AT_VERSION_LIST, 2, 3, 2, 3, 4, 5)
5123 idx += 1
5124 if ctx['num'] == idx:
5125 logger.info("Test: EAP-Failure")
5126 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5127
5128
5129 idx += 1
5130 if ctx['num'] == idx:
5131 logger.info("Test: Identity request without ID type")
5132 return struct.pack(">BBHBBHBBH2H", EAP_CODE_REQUEST, ctx['id'],
5133 4 + 1 + 3 + 8,
5134 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
5135 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0)
5136 idx += 1
5137 if ctx['num'] == idx:
5138 logger.info("Test: Identity request ANY_ID")
5139 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'],
5140 4 + 1 + 3 + 8 + 4,
5141 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
5142 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0,
5143 EAP_SIM_AT_ANY_ID_REQ, 1, 0)
5144 idx += 1
5145 if ctx['num'] == idx:
5146 logger.info("Test: Identity request ANY_ID (duplicate)")
5147 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'],
5148 4 + 1 + 3 + 8 + 4,
5149 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
5150 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0,
5151 EAP_SIM_AT_ANY_ID_REQ, 1, 0)
5152 idx += 1
5153 if ctx['num'] == idx:
5154 logger.info("Test: EAP-Failure")
5155 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5156
5157 idx += 1
5158 if ctx['num'] == idx:
5159 logger.info("Test: Identity request ANY_ID")
5160 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'],
5161 4 + 1 + 3 + 8 + 4,
5162 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
5163 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0,
5164 EAP_SIM_AT_ANY_ID_REQ, 1, 0)
5165 idx += 1
5166 if ctx['num'] == idx:
5167 logger.info("Test: Identity request FULLAUTH_ID")
5168 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'],
5169 4 + 1 + 3 + 8 + 4,
5170 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
5171 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0,
5172 EAP_SIM_AT_FULLAUTH_ID_REQ, 1, 0)
5173 idx += 1
5174 if ctx['num'] == idx:
5175 logger.info("Test: Identity request FULLAUTH_ID (duplicate)")
5176 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'],
5177 4 + 1 + 3 + 8 + 4,
5178 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
5179 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0,
5180 EAP_SIM_AT_FULLAUTH_ID_REQ, 1, 0)
5181 idx += 1
5182 if ctx['num'] == idx:
5183 logger.info("Test: EAP-Failure")
5184 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5185
5186 idx += 1
5187 if ctx['num'] == idx:
5188 logger.info("Test: Identity request ANY_ID")
5189 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'],
5190 4 + 1 + 3 + 8 + 4,
5191 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
5192 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0,
5193 EAP_SIM_AT_ANY_ID_REQ, 1, 0)
5194 idx += 1
5195 if ctx['num'] == idx:
5196 logger.info("Test: Identity request FULLAUTH_ID")
5197 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'],
5198 4 + 1 + 3 + 8 + 4,
5199 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
5200 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0,
5201 EAP_SIM_AT_FULLAUTH_ID_REQ, 1, 0)
5202 idx += 1
5203 if ctx['num'] == idx:
5204 logger.info("Test: Identity request PERMANENT_ID")
5205 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'],
5206 4 + 1 + 3 + 8 + 4,
5207 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
5208 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0,
5209 EAP_SIM_AT_PERMANENT_ID_REQ, 1, 0)
5210 idx += 1
5211 if ctx['num'] == idx:
5212 logger.info("Test: Identity request PERMANENT_ID (duplicate)")
5213 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'],
5214 4 + 1 + 3 + 8 + 4,
5215 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
5216 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0,
5217 EAP_SIM_AT_PERMANENT_ID_REQ, 1, 0)
5218 idx += 1
5219 if ctx['num'] == idx:
5220 logger.info("Test: EAP-Failure")
5221 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5222
5223 idx += 1
5224 if ctx['num'] == idx:
5225 logger.info("Test: No AT_MAC and AT_RAND in Challenge")
5226 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
5227 4 + 1 + 3,
5228 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CHALLENGE, 0)
5229 idx += 1
5230 if ctx['num'] == idx:
5231 logger.info("Test: EAP-Failure")
5232 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5233
5234 idx += 1
5235 if ctx['num'] == idx:
5236 logger.info("Test: No AT_RAND in Challenge")
5237 return struct.pack(">BBHBBHBBH4L", EAP_CODE_REQUEST, ctx['id'],
5238 4 + 1 + 3 + 20,
5239 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CHALLENGE, 0,
5240 EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0)
5241 idx += 1
5242 if ctx['num'] == idx:
5243 logger.info("Test: EAP-Failure")
5244 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5245
5246 idx += 1
5247 if ctx['num'] == idx:
5248 logger.info("Test: Insufficient number of challenges in Challenge")
5249 return struct.pack(">BBHBBHBBH4LBBH4L", EAP_CODE_REQUEST, ctx['id'],
5250 4 + 1 + 3 + 20 + 20,
5251 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CHALLENGE, 0,
5252 EAP_SIM_AT_RAND, 5, 0, 0, 0, 0, 0,
5253 EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0)
5254 idx += 1
5255 if ctx['num'] == idx:
5256 logger.info("Test: EAP-Failure")
5257 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5258
5259 idx += 1
5260 if ctx['num'] == idx:
5261 logger.info("Test: Too many challenges in Challenge")
5262 return struct.pack(">BBHBBHBBH4L4L4L4LBBH4L", EAP_CODE_REQUEST,
5263 ctx['id'],
5264 4 + 1 + 3 + 4 + 4 * 16 + 20,
5265 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CHALLENGE, 0,
5266 EAP_SIM_AT_RAND, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5267 0, 0, 0, 0, 0, 0, 0, 0,
5268 EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0)
5269 idx += 1
5270 if ctx['num'] == idx:
5271 logger.info("Test: EAP-Failure")
5272 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5273
5274 idx += 1
5275 if ctx['num'] == idx:
5276 logger.info("Test: Same RAND multiple times in Challenge")
5277 return struct.pack(">BBHBBHBBH4L4L4LBBH4L", EAP_CODE_REQUEST,
5278 ctx['id'],
5279 4 + 1 + 3 + 4 + 3 * 16 + 20,
5280 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CHALLENGE, 0,
5281 EAP_SIM_AT_RAND, 13, 0, 0, 0, 0, 0, 0, 0, 0, 1,
5282 0, 0, 0, 0,
5283 EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0)
5284 idx += 1
5285 if ctx['num'] == idx:
5286 logger.info("Test: EAP-Failure")
5287 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5288
5289 idx += 1
5290 if ctx['num'] == idx:
5291 logger.info("Test: Notification with no attributes")
5292 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
5293 4 + 1 + 3,
5294 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0)
5295 idx += 1
5296 if ctx['num'] == idx:
5297 logger.info("Test: EAP-Failure")
5298 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5299
5300 idx += 1
5301 if ctx['num'] == idx:
5302 logger.info("Test: Notification indicating success, but no MAC")
5303 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
5304 4 + 1 + 3 + 4,
5305 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0,
5306 EAP_SIM_AT_NOTIFICATION, 1, 32768)
5307 idx += 1
5308 if ctx['num'] == idx:
5309 logger.info("Test: EAP-Failure")
5310 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5311
5312 idx += 1
5313 if ctx['num'] == idx:
5314 logger.info("Test: Notification indicating success, but invalid MAC value")
5315 return struct.pack(">BBHBBHBBHBBH4L", EAP_CODE_REQUEST, ctx['id'],
5316 4 + 1 + 3 + 4 + 20,
5317 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0,
5318 EAP_SIM_AT_NOTIFICATION, 1, 32768,
5319 EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0)
5320 idx += 1
5321 if ctx['num'] == idx:
5322 logger.info("Test: EAP-Failure")
5323 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5324
5325 idx += 1
5326 if ctx['num'] == idx:
5327 logger.info("Test: Notification before auth")
5328 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
5329 4 + 1 + 3 + 4,
5330 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0,
5331 EAP_SIM_AT_NOTIFICATION, 1, 16384)
5332 idx += 1
5333 if ctx['num'] == idx:
5334 logger.info("Test: EAP-Failure")
5335 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5336
5337 idx += 1
5338 if ctx['num'] == idx:
5339 logger.info("Test: Notification before auth")
5340 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
5341 4 + 1 + 3 + 4,
5342 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0,
5343 EAP_SIM_AT_NOTIFICATION, 1, 16385)
5344 idx += 1
5345 if ctx['num'] == idx:
5346 logger.info("Test: EAP-Failure")
5347 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5348
5349 idx += 1
5350 if ctx['num'] == idx:
5351 logger.info("Test: Notification with unrecognized non-failure")
5352 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
5353 4 + 1 + 3 + 4,
5354 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0,
5355 EAP_SIM_AT_NOTIFICATION, 1, 0xc000)
5356 idx += 1
5357 if ctx['num'] == idx:
5358 logger.info("Test: Notification before auth (duplicate)")
5359 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
5360 4 + 1 + 3 + 4,
5361 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0,
5362 EAP_SIM_AT_NOTIFICATION, 1, 0xc000)
5363 idx += 1
5364 if ctx['num'] == idx:
5365 logger.info("Test: EAP-Failure")
5366 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5367
5368 idx += 1
5369 if ctx['num'] == idx:
5370 logger.info("Test: Re-authentication (unexpected) with no attributes")
5371 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
5372 4 + 1 + 3,
5373 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_REAUTHENTICATION,
5374 0)
5375 idx += 1
5376 if ctx['num'] == idx:
5377 logger.info("Test: EAP-Failure")
5378 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5379
5380 idx += 1
5381 if ctx['num'] == idx:
5382 logger.info("Test: Client Error")
5383 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
5384 4 + 1 + 3,
5385 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CLIENT_ERROR, 0)
5386 idx += 1
5387 if ctx['num'] == idx:
5388 logger.info("Test: EAP-Failure")
5389 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5390
5391 idx += 1
5392 if ctx['num'] == idx:
5393 logger.info("Test: Unknown subtype")
5394 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
5395 4 + 1 + 3,
5396 EAP_TYPE_SIM, 255, 0)
5397 idx += 1
5398 if ctx['num'] == idx:
5399 logger.info("Test: EAP-Failure")
5400 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5401
5402 return None
5403
5404 srv = start_radius_server(sim_handler)
5405
5406 try:
5407 hapd = start_ap(apdev[0])
5408 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
5409
5410 for i in range(0, 25):
5411 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5412 eap="SIM", identity="1232010000000000",
5413 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581",
5414 wait_connect=False)
5415 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
5416 timeout=15)
5417 if ev is None:
5418 raise Exception("Timeout on EAP start")
5419 if i in [0]:
5420 time.sleep(0.1)
5421 else:
5422 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"],
5423 timeout=10)
5424 if ev is None:
5425 raise Exception("Timeout on EAP failure")
5426 dev[0].request("REMOVE_NETWORK all")
5427 dev[0].dump_monitor()
5428 finally:
5429 stop_radius_server(srv)
5430
5431 def test_eap_proto_sim_errors(dev, apdev):
5432 """EAP-SIM protocol tests (error paths)"""
5433 check_hlr_auc_gw_support()
5434 params = hostapd.wpa2_eap_params(ssid="eap-test")
5435 hapd = hostapd.add_ap(apdev[0], params)
5436 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
5437
5438 with alloc_fail(dev[0], 1, "eap_sim_init"):
5439 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5440 eap="SIM", identity="1232010000000000",
5441 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581",
5442 wait_connect=False)
5443 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
5444 timeout=15)
5445 if ev is None:
5446 raise Exception("Timeout on EAP start")
5447 dev[0].request("REMOVE_NETWORK all")
5448 dev[0].wait_disconnected()
5449
5450 with fail_test(dev[0], 1, "os_get_random;eap_sim_init"):
5451 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5452 eap="SIM", identity="1232010000000000",
5453 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581",
5454 wait_connect=False)
5455 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
5456 timeout=15)
5457 if ev is None:
5458 raise Exception("Timeout on EAP start")
5459 dev[0].request("REMOVE_NETWORK all")
5460 dev[0].wait_disconnected()
5461
5462 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5463 eap="SIM", identity="1232010000000000",
5464 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581")
5465
5466 with fail_test(dev[0], 1, "aes_128_cbc_encrypt;eap_sim_response_reauth"):
5467 hapd.request("EAPOL_REAUTH " + dev[0].own_addr())
5468 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
5469 if ev is None:
5470 raise Exception("EAP re-authentication did not start")
5471 wait_fail_trigger(dev[0], "GET_FAIL")
5472 dev[0].request("REMOVE_NETWORK all")
5473 dev[0].dump_monitor()
5474
5475 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5476 eap="SIM", identity="1232010000000000",
5477 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581")
5478
5479 with fail_test(dev[0], 1, "os_get_random;eap_sim_msg_add_encr_start"):
5480 hapd.request("EAPOL_REAUTH " + dev[0].own_addr())
5481 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
5482 if ev is None:
5483 raise Exception("EAP re-authentication did not start")
5484 wait_fail_trigger(dev[0], "GET_FAIL")
5485 dev[0].request("REMOVE_NETWORK all")
5486 dev[0].dump_monitor()
5487
5488 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5489 eap="SIM", identity="1232010000000000",
5490 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581")
5491
5492 with fail_test(dev[0], 1, "os_get_random;eap_sim_init_for_reauth"):
5493 hapd.request("EAPOL_REAUTH " + dev[0].own_addr())
5494 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
5495 if ev is None:
5496 raise Exception("EAP re-authentication did not start")
5497 wait_fail_trigger(dev[0], "GET_FAIL")
5498 dev[0].request("REMOVE_NETWORK all")
5499 dev[0].dump_monitor()
5500
5501 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5502 eap="SIM", identity="1232010000000000",
5503 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581")
5504
5505 with alloc_fail(dev[0], 1, "eap_sim_parse_encr;eap_sim_process_reauthentication"):
5506 hapd.request("EAPOL_REAUTH " + dev[0].own_addr())
5507 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
5508 if ev is None:
5509 raise Exception("EAP re-authentication did not start")
5510 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
5511 dev[0].request("REMOVE_NETWORK all")
5512 dev[0].dump_monitor()
5513
5514 tests = [(1, "eap_sim_verify_mac;eap_sim_process_challenge"),
5515 (1, "eap_sim_parse_encr;eap_sim_process_challenge"),
5516 (1, "eap_sim_msg_init;eap_sim_response_start"),
5517 (1, "wpabuf_alloc;eap_sim_msg_init;eap_sim_response_start"),
5518 (1, "=eap_sim_learn_ids"),
5519 (2, "=eap_sim_learn_ids"),
5520 (2, "eap_sim_learn_ids"),
5521 (3, "eap_sim_learn_ids"),
5522 (1, "eap_sim_process_start"),
5523 (1, "eap_sim_getKey"),
5524 (1, "eap_sim_get_emsk"),
5525 (1, "eap_sim_get_session_id")]
5526 for count, func in tests:
5527 with alloc_fail(dev[0], count, func):
5528 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5529 eap="SIM", identity="1232010000000000@domain",
5530 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581",
5531 erp="1", wait_connect=False)
5532 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
5533 dev[0].request("REMOVE_NETWORK all")
5534 dev[0].dump_monitor()
5535
5536 tests = [(1, "aes_128_cbc_decrypt;eap_sim_parse_encr")]
5537 for count, func in tests:
5538 with fail_test(dev[0], count, func):
5539 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5540 eap="SIM", identity="1232010000000000",
5541 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581",
5542 wait_connect=False)
5543 wait_fail_trigger(dev[0], "GET_FAIL")
5544 dev[0].request("REMOVE_NETWORK all")
5545 dev[0].dump_monitor()
5546
5547 params = int_eap_server_params()
5548 params['eap_sim_db'] = "unix:/tmp/hlr_auc_gw.sock"
5549 params['eap_sim_aka_result_ind'] = "1"
5550 hapd2 = hostapd.add_ap(apdev[1], params)
5551 dev[0].scan_for_bss(hapd2.own_addr(), freq=2412)
5552
5553 with alloc_fail(dev[0], 1,
5554 "eap_sim_msg_init;eap_sim_response_notification"):
5555 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP",
5556 scan_freq="2412",
5557 eap="SIM", identity="1232010000000000",
5558 phase1="result_ind=1",
5559 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581",
5560 wait_connect=False)
5561 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
5562 dev[0].request("REMOVE_NETWORK all")
5563 dev[0].dump_monitor()
5564
5565 tests = ["eap_sim_msg_add_encr_start;eap_sim_response_notification",
5566 "aes_128_cbc_encrypt;eap_sim_response_notification"]
5567 for func in tests:
5568 with fail_test(dev[0], 1, func):
5569 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP",
5570 scan_freq="2412",
5571 eap="SIM", identity="1232010000000000",
5572 phase1="result_ind=1",
5573 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581")
5574 dev[0].request("REAUTHENTICATE")
5575 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5)
5576 if ev is None:
5577 raise Exception("EAP method not started on reauthentication")
5578 time.sleep(0.1)
5579 wait_fail_trigger(dev[0], "GET_FAIL")
5580 dev[0].request("REMOVE_NETWORK all")
5581 dev[0].dump_monitor()
5582
5583 tests = ["eap_sim_parse_encr;eap_sim_process_notification_reauth"]
5584 for func in tests:
5585 with alloc_fail(dev[0], 1, func):
5586 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP",
5587 scan_freq="2412",
5588 eap="SIM", identity="1232010000000000",
5589 phase1="result_ind=1",
5590 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581")
5591 dev[0].request("REAUTHENTICATE")
5592 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5)
5593 if ev is None:
5594 raise Exception("EAP method not started on reauthentication")
5595 time.sleep(0.1)
5596 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
5597 dev[0].request("REMOVE_NETWORK all")
5598 dev[0].dump_monitor()
5599
5600 def test_eap_proto_aka_errors(dev, apdev):
5601 """EAP-AKA protocol tests (error paths)"""
5602 check_hlr_auc_gw_support()
5603 params = hostapd.wpa2_eap_params(ssid="eap-test")
5604 hapd = hostapd.add_ap(apdev[0], params)
5605 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
5606
5607 with alloc_fail(dev[0], 1, "eap_aka_init"):
5608 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5609 eap="AKA", identity="0232010000000000",
5610 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123",
5611 wait_connect=False)
5612 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
5613 timeout=15)
5614 if ev is None:
5615 raise Exception("Timeout on EAP start")
5616 dev[0].request("REMOVE_NETWORK all")
5617 dev[0].wait_disconnected()
5618
5619 tests = [(1, "=eap_aka_learn_ids"),
5620 (2, "=eap_aka_learn_ids"),
5621 (1, "eap_sim_parse_encr;eap_aka_process_challenge"),
5622 (1, "wpabuf_dup;eap_aka_add_id_msg"),
5623 (1, "wpabuf_resize;eap_aka_add_id_msg"),
5624 (1, "eap_aka_getKey"),
5625 (1, "eap_aka_get_emsk"),
5626 (1, "eap_aka_get_session_id")]
5627 for count, func in tests:
5628 with alloc_fail(dev[0], count, func):
5629 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5630 eap="AKA", identity="0232010000000000@domain",
5631 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123",
5632 erp="1", wait_connect=False)
5633 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
5634 dev[0].request("REMOVE_NETWORK all")
5635 dev[0].dump_monitor()
5636
5637 params = int_eap_server_params()
5638 params['eap_sim_db'] = "unix:/tmp/hlr_auc_gw.sock"
5639 params['eap_sim_aka_result_ind'] = "1"
5640 hapd2 = hostapd.add_ap(apdev[1], params)
5641 dev[0].scan_for_bss(hapd2.own_addr(), freq=2412)
5642
5643 with alloc_fail(dev[0], 1,
5644 "eap_sim_msg_init;eap_aka_response_notification"):
5645 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412",
5646 eap="AKA", identity="0232010000000000",
5647 phase1="result_ind=1",
5648 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123",
5649 wait_connect=False)
5650 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
5651 dev[0].request("REMOVE_NETWORK all")
5652 dev[0].dump_monitor()
5653
5654 tests = [(1, "aes_128_encrypt_block;milenage_f1;milenage_check", None),
5655 (2, "aes_128_encrypt_block;milenage_f1;milenage_check", None),
5656 (1, "milenage_f2345;milenage_check", None),
5657 (7, "aes_128_encrypt_block;milenage_f2345;milenage_check",
5658 "ff0000000123"),
5659 (1, "aes_128_encrypt_block;milenage_f1;milenage_check",
5660 "fff000000123")]
5661 for count, func, seq in tests:
5662 if not seq:
5663 seq = "000000000123"
5664 with fail_test(dev[0], count, func):
5665 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP",
5666 scan_freq="2412",
5667 eap="AKA", identity="0232010000000000",
5668 phase1="result_ind=1",
5669 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:" + seq,
5670 wait_connect=False)
5671 wait_fail_trigger(dev[0], "GET_FAIL")
5672 dev[0].request("REMOVE_NETWORK all")
5673 dev[0].wait_disconnected()
5674 dev[0].dump_monitor()
5675
5676 tests = ["eap_sim_msg_add_encr_start;eap_aka_response_notification",
5677 "aes_128_cbc_encrypt;eap_aka_response_notification"]
5678 for func in tests:
5679 with fail_test(dev[0], 1, func):
5680 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP",
5681 scan_freq="2412",
5682 eap="AKA", identity="0232010000000000",
5683 phase1="result_ind=1",
5684 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123")
5685 dev[0].request("REAUTHENTICATE")
5686 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5)
5687 if ev is None:
5688 raise Exception("EAP method not started on reauthentication")
5689 time.sleep(0.1)
5690 wait_fail_trigger(dev[0], "GET_FAIL")
5691 dev[0].request("REMOVE_NETWORK all")
5692 dev[0].dump_monitor()
5693
5694 tests = ["eap_sim_parse_encr;eap_aka_process_notification_reauth"]
5695 for func in tests:
5696 with alloc_fail(dev[0], 1, func):
5697 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP",
5698 scan_freq="2412",
5699 eap="AKA", identity="0232010000000000",
5700 phase1="result_ind=1",
5701 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123")
5702 dev[0].request("REAUTHENTICATE")
5703 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5)
5704 if ev is None:
5705 raise Exception("EAP method not started on reauthentication")
5706 time.sleep(0.1)
5707 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
5708 dev[0].request("REMOVE_NETWORK all")
5709 dev[0].dump_monitor()
5710
5711 def test_eap_proto_aka_prime_errors(dev, apdev):
5712 """EAP-AKA' protocol tests (error paths)"""
5713 check_hlr_auc_gw_support()
5714 params = hostapd.wpa2_eap_params(ssid="eap-test")
5715 hapd = hostapd.add_ap(apdev[0], params)
5716 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
5717
5718 with alloc_fail(dev[0], 1, "eap_aka_init"):
5719 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5720 eap="AKA'", identity="6555444333222111",
5721 password="5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123",
5722 wait_connect=False)
5723 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
5724 timeout=15)
5725 if ev is None:
5726 raise Exception("Timeout on EAP start")
5727 dev[0].request("REMOVE_NETWORK all")
5728 dev[0].wait_disconnected()
5729
5730 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5731 eap="AKA'", identity="6555444333222111",
5732 password="5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123")
5733
5734 with fail_test(dev[0], 1, "aes_128_cbc_encrypt;eap_aka_response_reauth"):
5735 hapd.request("EAPOL_REAUTH " + dev[0].own_addr())
5736 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
5737 if ev is None:
5738 raise Exception("EAP re-authentication did not start")
5739 wait_fail_trigger(dev[0], "GET_FAIL")
5740 dev[0].request("REMOVE_NETWORK all")
5741 dev[0].dump_monitor()
5742
5743 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5744 eap="AKA'", identity="6555444333222111",
5745 password="5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123")
5746
5747 with alloc_fail(dev[0], 1, "eap_sim_parse_encr;eap_aka_process_reauthentication"):
5748 hapd.request("EAPOL_REAUTH " + dev[0].own_addr())
5749 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
5750 if ev is None:
5751 raise Exception("EAP re-authentication did not start")
5752 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
5753 dev[0].request("REMOVE_NETWORK all")
5754 dev[0].dump_monitor()
5755
5756 tests = [(1, "eap_sim_verify_mac_sha256"),
5757 (1, "=eap_aka_process_challenge")]
5758 for count, func in tests:
5759 with alloc_fail(dev[0], count, func):
5760 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5761 eap="AKA'", identity="6555444333222111",
5762 password="5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123",
5763 erp="1", wait_connect=False)
5764 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
5765 dev[0].request("REMOVE_NETWORK all")
5766 dev[0].dump_monitor()
5767
5768 def test_eap_proto_ikev2(dev, apdev):
5769 """EAP-IKEv2 protocol tests"""
5770 check_eap_capa(dev[0], "IKEV2")
5771
5772 global eap_proto_ikev2_test_done
5773 eap_proto_ikev2_test_done = False
5774
5775 def ikev2_handler(ctx, req):
5776 logger.info("ikev2_handler - RX " + binascii.hexlify(req).decode())
5777 if 'num' not in ctx:
5778 ctx['num'] = 0
5779 ctx['num'] = ctx['num'] + 1
5780 if 'id' not in ctx:
5781 ctx['id'] = 1
5782 ctx['id'] = (ctx['id'] + 1) % 256
5783
5784 idx = 0
5785
5786 idx += 1
5787 if ctx['num'] == idx:
5788 logger.info("Test: Missing payload")
5789 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
5790 4 + 1,
5791 EAP_TYPE_IKEV2)
5792
5793 idx += 1
5794 if ctx['num'] == idx:
5795 logger.info("Test: Truncated Message Length field")
5796 return struct.pack(">BBHBB3B", EAP_CODE_REQUEST, ctx['id'],
5797 4 + 1 + 1 + 3,
5798 EAP_TYPE_IKEV2, 0x80, 0, 0, 0)
5799
5800 idx += 1
5801 if ctx['num'] == idx:
5802 logger.info("Test: Too short Message Length value")
5803 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'],
5804 4 + 1 + 1 + 4 + 1,
5805 EAP_TYPE_IKEV2, 0x80, 0, 1)
5806
5807 idx += 1
5808 if ctx['num'] == idx:
5809 logger.info("Test: Truncated message")
5810 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'],
5811 4 + 1 + 1 + 4,
5812 EAP_TYPE_IKEV2, 0x80, 1)
5813
5814 idx += 1
5815 if ctx['num'] == idx:
5816 logger.info("Test: Truncated message(2)")
5817 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'],
5818 4 + 1 + 1 + 4,
5819 EAP_TYPE_IKEV2, 0x80, 0xffffffff)
5820
5821 idx += 1
5822 if ctx['num'] == idx:
5823 logger.info("Test: Truncated message(3)")
5824 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'],
5825 4 + 1 + 1 + 4,
5826 EAP_TYPE_IKEV2, 0xc0, 0xffffffff)
5827
5828 idx += 1
5829 if ctx['num'] == idx:
5830 logger.info("Test: Truncated message(4)")
5831 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'],
5832 4 + 1 + 1 + 4,
5833 EAP_TYPE_IKEV2, 0xc0, 10000000)
5834
5835 idx += 1
5836 if ctx['num'] == idx:
5837 logger.info("Test: Too long fragments (first fragment)")
5838 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'],
5839 4 + 1 + 1 + 4 + 1,
5840 EAP_TYPE_IKEV2, 0xc0, 2, 1)
5841
5842 idx += 1
5843 if ctx['num'] == idx:
5844 logger.info("Test: Too long fragments (second fragment)")
5845 return struct.pack(">BBHBB2B", EAP_CODE_REQUEST, ctx['id'],
5846 4 + 1 + 1 + 2,
5847 EAP_TYPE_IKEV2, 0x00, 2, 3)
5848
5849 idx += 1
5850 if ctx['num'] == idx:
5851 logger.info("Test: No Message Length field in first fragment")
5852 return struct.pack(">BBHBBB", EAP_CODE_REQUEST, ctx['id'],
5853 4 + 1 + 1 + 1,
5854 EAP_TYPE_IKEV2, 0x40, 1)
5855
5856 idx += 1
5857 if ctx['num'] == idx:
5858 logger.info("Test: ICV before keys")
5859 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
5860 4 + 1 + 1,
5861 EAP_TYPE_IKEV2, 0x20)
5862
5863 idx += 1
5864 if ctx['num'] == idx:
5865 logger.info("Test: Unsupported IKEv2 header version")
5866 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'],
5867 4 + 1 + 1 + 28,
5868 EAP_TYPE_IKEV2, 0x00,
5869 0, 0, 0, 0,
5870 0, 0, 0, 0, 0, 0)
5871
5872 idx += 1
5873 if ctx['num'] == idx:
5874 logger.info("Test: Incorrect IKEv2 header Length")
5875 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'],
5876 4 + 1 + 1 + 28,
5877 EAP_TYPE_IKEV2, 0x00,
5878 0, 0, 0, 0,
5879 0, 0x20, 0, 0, 0, 0)
5880
5881 idx += 1
5882 if ctx['num'] == idx:
5883 logger.info("Test: Unexpected IKEv2 Exchange Type in SA_INIT state")
5884 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'],
5885 4 + 1 + 1 + 28,
5886 EAP_TYPE_IKEV2, 0x00,
5887 0, 0, 0, 0,
5888 0, 0x20, 0, 0, 0, 28)
5889
5890 idx += 1
5891 if ctx['num'] == idx:
5892 logger.info("Test: Unexpected IKEv2 Message ID in SA_INIT state")
5893 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'],
5894 4 + 1 + 1 + 28,
5895 EAP_TYPE_IKEV2, 0x00,
5896 0, 0, 0, 0,
5897 0, 0x20, 34, 0, 1, 28)
5898
5899 idx += 1
5900 if ctx['num'] == idx:
5901 logger.info("Test: Unexpected IKEv2 Flags value")
5902 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'],
5903 4 + 1 + 1 + 28,
5904 EAP_TYPE_IKEV2, 0x00,
5905 0, 0, 0, 0,
5906 0, 0x20, 34, 0, 0, 28)
5907
5908 idx += 1
5909 if ctx['num'] == idx:
5910 logger.info("Test: Unexpected IKEv2 Flags value(2)")
5911 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'],
5912 4 + 1 + 1 + 28,
5913 EAP_TYPE_IKEV2, 0x00,
5914 0, 0, 0, 0,
5915 0, 0x20, 34, 0x20, 0, 28)
5916
5917 idx += 1
5918 if ctx['num'] == idx:
5919 logger.info("Test: No SAi1 in SA_INIT")
5920 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'],
5921 4 + 1 + 1 + 28,
5922 EAP_TYPE_IKEV2, 0x00,
5923 0, 0, 0, 0,
5924 0, 0x20, 34, 0x08, 0, 28)
5925
5926 def build_ike(id, next=0, exch_type=34, flags=0x00, ike=b''):
5927 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, id,
5928 4 + 1 + 1 + 28 + len(ike),
5929 EAP_TYPE_IKEV2, flags,
5930 0, 0, 0, 0,
5931 next, 0x20, exch_type, 0x08, 0,
5932 28 + len(ike)) + ike
5933
5934 idx += 1
5935 if ctx['num'] == idx:
5936 logger.info("Test: Unexpected extra data after payloads")
5937 return build_ike(ctx['id'], ike=struct.pack(">B", 1))
5938
5939 idx += 1
5940 if ctx['num'] == idx:
5941 logger.info("Test: Truncated payload header")
5942 return build_ike(ctx['id'], next=128, ike=struct.pack(">B", 1))
5943
5944 idx += 1
5945 if ctx['num'] == idx:
5946 logger.info("Test: Too small payload header length")
5947 ike = struct.pack(">BBH", 0, 0, 3)
5948 return build_ike(ctx['id'], next=128, ike=ike)
5949
5950 idx += 1
5951 if ctx['num'] == idx:
5952 logger.info("Test: Too large payload header length")
5953 ike = struct.pack(">BBH", 0, 0, 5)
5954 return build_ike(ctx['id'], next=128, ike=ike)
5955
5956 idx += 1
5957 if ctx['num'] == idx:
5958 logger.info("Test: Unsupported payload (non-critical and critical)")
5959 ike = struct.pack(">BBHBBH", 129, 0, 4, 0, 0x01, 4)
5960 return build_ike(ctx['id'], next=128, ike=ike)
5961
5962 idx += 1
5963 if ctx['num'] == idx:
5964 logger.info("Test: Certificate and empty SAi1")
5965 ike = struct.pack(">BBHBBH", 33, 0, 4, 0, 0, 4)
5966 return build_ike(ctx['id'], next=37, ike=ike)
5967
5968 idx += 1
5969 if ctx['num'] == idx:
5970 logger.info("Test: Too short proposal")
5971 ike = struct.pack(">BBHBBHBBB", 0, 0, 4 + 7,
5972 0, 0, 7, 0, 0, 0)
5973 return build_ike(ctx['id'], next=33, ike=ike)
5974
5975 idx += 1
5976 if ctx['num'] == idx:
5977 logger.info("Test: Too small proposal length in SAi1")
5978 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8,
5979 0, 0, 7, 0, 0, 0, 0)
5980 return build_ike(ctx['id'], next=33, ike=ike)
5981
5982 idx += 1
5983 if ctx['num'] == idx:
5984 logger.info("Test: Too large proposal length in SAi1")
5985 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8,
5986 0, 0, 9, 0, 0, 0, 0)
5987 return build_ike(ctx['id'], next=33, ike=ike)
5988
5989 idx += 1
5990 if ctx['num'] == idx:
5991 logger.info("Test: Unexpected proposal type in SAi1")
5992 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8,
5993 1, 0, 8, 0, 0, 0, 0)
5994 return build_ike(ctx['id'], next=33, ike=ike)
5995
5996 idx += 1
5997 if ctx['num'] == idx:
5998 logger.info("Test: Unexpected Protocol ID in SAi1")
5999 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8,
6000 0, 0, 8, 0, 0, 0, 0)
6001 return build_ike(ctx['id'], next=33, ike=ike)
6002
6003 idx += 1
6004 if ctx['num'] == idx:
6005 logger.info("Test: Unexpected proposal number in SAi1")
6006 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8,
6007 0, 0, 8, 0, 1, 0, 0)
6008 return build_ike(ctx['id'], next=33, ike=ike)
6009
6010 idx += 1
6011 if ctx['num'] == idx:
6012 logger.info("Test: Not enough room for SPI in SAi1")
6013 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8,
6014 0, 0, 8, 1, 1, 1, 0)
6015 return build_ike(ctx['id'], next=33, ike=ike)
6016
6017 idx += 1
6018 if ctx['num'] == idx:
6019 logger.info("Test: Unexpected SPI in SAi1")
6020 ike = struct.pack(">BBHBBHBBBBB", 0, 0, 4 + 9,
6021 0, 0, 9, 1, 1, 1, 0, 1)
6022 return build_ike(ctx['id'], next=33, ike=ike)
6023
6024 idx += 1
6025 if ctx['num'] == idx:
6026 logger.info("Test: No transforms in SAi1")
6027 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8,
6028 0, 0, 8, 1, 1, 0, 0)
6029 return build_ike(ctx['id'], next=33, ike=ike)
6030
6031 idx += 1
6032 if ctx['num'] == idx:
6033 logger.info("Test: Too short transform in SAi1")
6034 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8,
6035 0, 0, 8, 1, 1, 0, 1)
6036 return build_ike(ctx['id'], next=33, ike=ike)
6037
6038 idx += 1
6039 if ctx['num'] == idx:
6040 logger.info("Test: Too small transform length in SAi1")
6041 ike = struct.pack(">BBHBBHBBBBBBHBBH", 0, 0, 4 + 8 + 8,
6042 0, 0, 8 + 8, 1, 1, 0, 1,
6043 0, 0, 7, 0, 0, 0)
6044 return build_ike(ctx['id'], next=33, ike=ike)
6045
6046 idx += 1
6047 if ctx['num'] == idx:
6048 logger.info("Test: Too large transform length in SAi1")
6049 ike = struct.pack(">BBHBBHBBBBBBHBBH", 0, 0, 4 + 8 + 8,
6050 0, 0, 8 + 8, 1, 1, 0, 1,
6051 0, 0, 9, 0, 0, 0)
6052 return build_ike(ctx['id'], next=33, ike=ike)
6053
6054 idx += 1
6055 if ctx['num'] == idx:
6056 logger.info("Test: Unexpected Transform type in SAi1")
6057 ike = struct.pack(">BBHBBHBBBBBBHBBH", 0, 0, 4 + 8 + 8,
6058 0, 0, 8 + 8, 1, 1, 0, 1,
6059 1, 0, 8, 0, 0, 0)
6060 return build_ike(ctx['id'], next=33, ike=ike)
6061
6062 idx += 1
6063 if ctx['num'] == idx:
6064 logger.info("Test: No transform attributes in SAi1")
6065 ike = struct.pack(">BBHBBHBBBBBBHBBH", 0, 0, 4 + 8 + 8,
6066 0, 0, 8 + 8, 1, 1, 0, 1,
6067 0, 0, 8, 0, 0, 0)
6068 return build_ike(ctx['id'], next=33, ike=ike)
6069
6070 idx += 1
6071 if ctx['num'] == idx:
6072 logger.info("Test: No transform attr for AES and unexpected data after transforms in SAi1")
6073 tlen1 = 8 + 3
6074 tlen2 = 8 + 4
6075 tlen3 = 8 + 4
6076 tlen = tlen1 + tlen2 + tlen3
6077 ike = struct.pack(">BBHBBHBBBBBBHBBH3BBBHBBHHHBBHBBHHHB",
6078 0, 0, 4 + 8 + tlen + 1,
6079 0, 0, 8 + tlen + 1, 1, 1, 0, 3,
6080 3, 0, tlen1, 1, 0, 12, 1, 2, 3,
6081 3, 0, tlen2, 1, 0, 12, 0, 128,
6082 0, 0, tlen3, 1, 0, 12, 0x8000 | 14, 127,
6083 1)
6084 return build_ike(ctx['id'], next=33, ike=ike)
6085
6086 def build_sa(next=0):
6087 tlen = 5 * 8
6088 return struct.pack(">BBHBBHBBBBBBHBBHBBHBBHBBHBBHBBHBBHBBHBBH",
6089 next, 0, 4 + 8 + tlen,
6090 0, 0, 8 + tlen, 1, 1, 0, 5,
6091 3, 0, 8, 1, 0, 3,
6092 3, 0, 8, 2, 0, 1,
6093 3, 0, 8, 3, 0, 1,
6094 3, 0, 8, 4, 0, 5,
6095 0, 0, 8, 241, 0, 0)
6096
6097 idx += 1
6098 if ctx['num'] == idx:
6099 logger.info("Test: Valid proposal, but no KEi in SAi1")
6100 ike = build_sa()
6101 return build_ike(ctx['id'], next=33, ike=ike)
6102
6103 idx += 1
6104 if ctx['num'] == idx:
6105 logger.info("Test: Empty KEi in SAi1")
6106 ike = build_sa(next=34) + struct.pack(">BBH", 0, 0, 4)
6107 return build_ike(ctx['id'], next=33, ike=ike)
6108
6109 idx += 1
6110 if ctx['num'] == idx:
6111 logger.info("Test: Mismatch in DH Group in SAi1")
6112 ike = build_sa(next=34)
6113 ike += struct.pack(">BBHHH", 0, 0, 4 + 4 + 96, 12345, 0)
6114 ike += 96*b'\x00'
6115 return build_ike(ctx['id'], next=33, ike=ike)
6116 idx += 1
6117 if ctx['num'] == idx:
6118 logger.info("Test: EAP-Failure")
6119 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6120
6121 idx += 1
6122 if ctx['num'] == idx:
6123 logger.info("Test: Invalid DH public value length in SAi1")
6124 ike = build_sa(next=34)
6125 ike += struct.pack(">BBHHH", 0, 0, 4 + 4 + 96, 5, 0)
6126 ike += 96*b'\x00'
6127 return build_ike(ctx['id'], next=33, ike=ike)
6128
6129 def build_ke(next=0):
6130 ke = struct.pack(">BBHHH", next, 0, 4 + 4 + 192, 5, 0)
6131 ke += 191*b'\x00'+b'\x02'
6132 return ke
6133
6134 idx += 1
6135 if ctx['num'] == idx:
6136 logger.info("Test: Valid proposal and KEi, but no Ni in SAi1")
6137 ike = build_sa(next=34)
6138 ike += build_ke()
6139 return build_ike(ctx['id'], next=33, ike=ike)
6140
6141 idx += 1
6142 if ctx['num'] == idx:
6143 logger.info("Test: Too short Ni in SAi1")
6144 ike = build_sa(next=34)
6145 ike += build_ke(next=40)
6146 ike += struct.pack(">BBH", 0, 0, 4)
6147 return build_ike(ctx['id'], next=33, ike=ike)
6148
6149 idx += 1
6150 if ctx['num'] == idx:
6151 logger.info("Test: Too long Ni in SAi1")
6152 ike = build_sa(next=34)
6153 ike += build_ke(next=40)
6154 ike += struct.pack(">BBH", 0, 0, 4 + 257) + 257*b'\x00'
6155 return build_ike(ctx['id'], next=33, ike=ike)
6156
6157 def build_ni(next=0):
6158 return struct.pack(">BBH", next, 0, 4 + 256) + 256*b'\x00'
6159
6160 def build_sai1(id):
6161 ike = build_sa(next=34)
6162 ike += build_ke(next=40)
6163 ike += build_ni()
6164 return build_ike(ctx['id'], next=33, ike=ike)
6165
6166 idx += 1
6167 if ctx['num'] == idx:
6168 logger.info("Test: Valid proposal, KEi, and Ni in SAi1")
6169 return build_sai1(ctx['id'])
6170 idx += 1
6171 if ctx['num'] == idx:
6172 logger.info("Test: EAP-Failure")
6173 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6174
6175 idx += 1
6176 if ctx['num'] == idx:
6177 logger.info("Test: Valid proposal, KEi, and Ni in SAi1")
6178 return build_sai1(ctx['id'])
6179 idx += 1
6180 if ctx['num'] == idx:
6181 logger.info("Test: No integrity checksum")
6182 ike = b''
6183 return build_ike(ctx['id'], next=37, ike=ike)
6184
6185 idx += 1
6186 if ctx['num'] == idx:
6187 logger.info("Test: Valid proposal, KEi, and Ni in SAi1")
6188 return build_sai1(ctx['id'])
6189 idx += 1
6190 if ctx['num'] == idx:
6191 logger.info("Test: Truncated integrity checksum")
6192 return struct.pack(">BBHBB",
6193 EAP_CODE_REQUEST, ctx['id'],
6194 4 + 1 + 1,
6195 EAP_TYPE_IKEV2, 0x20)
6196
6197 idx += 1
6198 if ctx['num'] == idx:
6199 logger.info("Test: Valid proposal, KEi, and Ni in SAi1")
6200 return build_sai1(ctx['id'])
6201 idx += 1
6202 if ctx['num'] == idx:
6203 logger.info("Test: Invalid integrity checksum")
6204 ike = b''
6205 return build_ike(ctx['id'], next=37, flags=0x20, ike=ike)
6206
6207 idx += 1
6208 if ctx['num'] == idx:
6209 logger.info("No more test responses available - test case completed")
6210 global eap_proto_ikev2_test_done
6211 eap_proto_ikev2_test_done = True
6212 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6213 4 + 1,
6214 EAP_TYPE_IKEV2)
6215 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6216
6217 srv = start_radius_server(ikev2_handler)
6218
6219 try:
6220 hapd = start_ap(apdev[0])
6221 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
6222
6223 i = 0
6224 while not eap_proto_ikev2_test_done:
6225 i += 1
6226 logger.info("Running connection iteration %d" % i)
6227 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6228 eap="IKEV2", identity="user",
6229 password="password",
6230 wait_connect=False)
6231 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=15)
6232 if ev is None:
6233 raise Exception("Timeout on EAP start")
6234 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
6235 timeout=15)
6236 if ev is None:
6237 raise Exception("Timeout on EAP method start")
6238 if i in [41, 46]:
6239 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"],
6240 timeout=10)
6241 if ev is None:
6242 raise Exception("Timeout on EAP failure")
6243 else:
6244 time.sleep(0.05)
6245 dev[0].request("REMOVE_NETWORK all")
6246 dev[0].wait_disconnected()
6247 dev[0].dump_monitor()
6248 dev[1].dump_monitor()
6249 dev[2].dump_monitor()
6250 finally:
6251 stop_radius_server(srv)
6252
6253 def NtPasswordHash(password):
6254 pw = password.encode('utf_16_le')
6255 return hashlib.new('md4', pw).digest()
6256
6257 def HashNtPasswordHash(password_hash):
6258 return hashlib.new('md4', password_hash).digest()
6259
6260 def ChallengeHash(peer_challenge, auth_challenge, username):
6261 data = peer_challenge + auth_challenge + username
6262 return hashlib.sha1(data).digest()[0:8]
6263
6264 def GenerateAuthenticatorResponse(password, nt_response, peer_challenge,
6265 auth_challenge, username):
6266 magic1 = binascii.unhexlify("4D616769632073657276657220746F20636C69656E74207369676E696E6720636F6E7374616E74")
6267 magic2 = binascii.unhexlify("50616420746F206D616B6520697420646F206D6F7265207468616E206F6E6520697465726174696F6E")
6268
6269 password_hash = NtPasswordHash(password)
6270 password_hash_hash = HashNtPasswordHash(password_hash)
6271 data = password_hash_hash + nt_response + magic1
6272 digest = hashlib.sha1(data).digest()
6273
6274 challenge = ChallengeHash(peer_challenge, auth_challenge, username.encode())
6275
6276 data = digest + challenge + magic2
6277 resp = hashlib.sha1(data).digest()
6278 return resp
6279
6280 def test_eap_proto_ikev2_errors(dev, apdev):
6281 """EAP-IKEv2 local error cases"""
6282 check_eap_capa(dev[0], "IKEV2")
6283 params = hostapd.wpa2_eap_params(ssid="eap-test")
6284 hapd = hostapd.add_ap(apdev[0], params)
6285 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
6286
6287 for i in range(1, 5):
6288 with alloc_fail(dev[0], i, "eap_ikev2_init"):
6289 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6290 eap="IKEV2", identity="ikev2 user",
6291 password="ike password",
6292 wait_connect=False)
6293 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
6294 timeout=15)
6295 if ev is None:
6296 raise Exception("Timeout on EAP start")
6297 dev[0].request("REMOVE_NETWORK all")
6298 dev[0].wait_disconnected()
6299
6300 tests = [(1, "ikev2_encr_encrypt"),
6301 (1, "ikev2_encr_decrypt"),
6302 (1, "ikev2_derive_auth_data"),
6303 (2, "ikev2_derive_auth_data"),
6304 (1, "=ikev2_decrypt_payload"),
6305 (1, "ikev2_encr_decrypt;ikev2_decrypt_payload"),
6306 (1, "ikev2_encr_encrypt;ikev2_build_encrypted"),
6307 (1, "ikev2_derive_sk_keys"),
6308 (2, "ikev2_derive_sk_keys"),
6309 (3, "ikev2_derive_sk_keys"),
6310 (4, "ikev2_derive_sk_keys"),
6311 (5, "ikev2_derive_sk_keys"),
6312 (6, "ikev2_derive_sk_keys"),
6313 (7, "ikev2_derive_sk_keys"),
6314 (8, "ikev2_derive_sk_keys"),
6315 (1, "eap_ikev2_derive_keymat;eap_ikev2_peer_keymat"),
6316 (1, "eap_msg_alloc;eap_ikev2_build_msg"),
6317 (1, "eap_ikev2_getKey"),
6318 (1, "eap_ikev2_get_emsk"),
6319 (1, "eap_ikev2_get_session_id"),
6320 (1, "=ikev2_derive_keys"),
6321 (2, "=ikev2_derive_keys"),
6322 (1, "wpabuf_alloc;ikev2_process_kei"),
6323 (1, "=ikev2_process_idi"),
6324 (1, "ikev2_derive_auth_data;ikev2_build_auth"),
6325 (1, "wpabuf_alloc;ikev2_build_sa_init"),
6326 (2, "wpabuf_alloc;ikev2_build_sa_init"),
6327 (3, "wpabuf_alloc;ikev2_build_sa_init"),
6328 (4, "wpabuf_alloc;ikev2_build_sa_init"),
6329 (5, "wpabuf_alloc;ikev2_build_sa_init"),
6330 (6, "wpabuf_alloc;ikev2_build_sa_init"),
6331 (1, "wpabuf_alloc;ikev2_build_sa_auth"),
6332 (2, "wpabuf_alloc;ikev2_build_sa_auth"),
6333 (1, "ikev2_build_auth;ikev2_build_sa_auth")]
6334 for count, func in tests:
6335 with alloc_fail(dev[0], count, func):
6336 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6337 eap="IKEV2", identity="ikev2 user@domain",
6338 password="ike password", erp="1", wait_connect=False)
6339 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
6340 timeout=15)
6341 if ev is None:
6342 raise Exception("Timeout on EAP start")
6343 ok = False
6344 for j in range(10):
6345 state = dev[0].request('GET_ALLOC_FAIL')
6346 if state.startswith('0:'):
6347 ok = True
6348 break
6349 time.sleep(0.1)
6350 if not ok:
6351 raise Exception("No allocation failure seen for %d:%s" % (count, func))
6352 dev[0].request("REMOVE_NETWORK all")
6353 dev[0].wait_disconnected()
6354
6355 tests = [(1, "wpabuf_alloc;ikev2_build_notify"),
6356 (2, "wpabuf_alloc;ikev2_build_notify"),
6357 (1, "ikev2_build_encrypted;ikev2_build_notify")]
6358 for count, func in tests:
6359 with alloc_fail(dev[0], count, func):
6360 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6361 eap="IKEV2", identity="ikev2 user",
6362 password="wrong password", erp="1",
6363 wait_connect=False)
6364 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
6365 timeout=15)
6366 if ev is None:
6367 raise Exception("Timeout on EAP start")
6368 ok = False
6369 for j in range(10):
6370 state = dev[0].request('GET_ALLOC_FAIL')
6371 if state.startswith('0:'):
6372 ok = True
6373 break
6374 time.sleep(0.1)
6375 if not ok:
6376 raise Exception("No allocation failure seen for %d:%s" % (count, func))
6377 dev[0].request("REMOVE_NETWORK all")
6378 dev[0].wait_disconnected()
6379
6380 tests = [(1, "ikev2_integ_hash"),
6381 (1, "ikev2_integ_hash;ikev2_decrypt_payload"),
6382 (1, "os_get_random;ikev2_build_encrypted"),
6383 (1, "ikev2_prf_plus;ikev2_derive_sk_keys"),
6384 (1, "eap_ikev2_derive_keymat;eap_ikev2_peer_keymat"),
6385 (1, "os_get_random;ikev2_build_sa_init"),
6386 (2, "os_get_random;ikev2_build_sa_init"),
6387 (1, "ikev2_integ_hash;eap_ikev2_validate_icv"),
6388 (1, "hmac_sha1_vector;?ikev2_prf_hash;ikev2_derive_keys"),
6389 (1, "hmac_sha1_vector;?ikev2_prf_hash;ikev2_derive_auth_data"),
6390 (2, "hmac_sha1_vector;?ikev2_prf_hash;ikev2_derive_auth_data"),
6391 (3, "hmac_sha1_vector;?ikev2_prf_hash;ikev2_derive_auth_data")]
6392 for count, func in tests:
6393 with fail_test(dev[0], count, func):
6394 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6395 eap="IKEV2", identity="ikev2 user",
6396 password="ike password", wait_connect=False)
6397 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
6398 timeout=15)
6399 if ev is None:
6400 raise Exception("Timeout on EAP start")
6401 ok = False
6402 for j in range(10):
6403 state = dev[0].request('GET_FAIL')
6404 if state.startswith('0:'):
6405 ok = True
6406 break
6407 time.sleep(0.1)
6408 if not ok:
6409 raise Exception("No failure seen for %d:%s" % (count, func))
6410 dev[0].request("REMOVE_NETWORK all")
6411 dev[0].wait_disconnected()
6412
6413 params = {"ssid": "eap-test2", "wpa": "2", "wpa_key_mgmt": "WPA-EAP",
6414 "rsn_pairwise": "CCMP", "ieee8021x": "1",
6415 "eap_server": "1", "eap_user_file": "auth_serv/eap_user.conf",
6416 "fragment_size": "50"}
6417 hapd2 = hostapd.add_ap(apdev[1], params)
6418 dev[0].scan_for_bss(hapd2.own_addr(), freq=2412)
6419
6420 tests = [(1, "eap_ikev2_build_frag_ack"),
6421 (1, "wpabuf_alloc;eap_ikev2_process_fragment")]
6422 for count, func in tests:
6423 with alloc_fail(dev[0], count, func):
6424 dev[0].connect("eap-test2", key_mgmt="WPA-EAP", scan_freq="2412",
6425 eap="IKEV2", identity="ikev2 user",
6426 password="ike password", erp="1", wait_connect=False)
6427 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
6428 timeout=15)
6429 if ev is None:
6430 raise Exception("Timeout on EAP start")
6431 ok = False
6432 for j in range(10):
6433 state = dev[0].request('GET_ALLOC_FAIL')
6434 if state.startswith('0:'):
6435 ok = True
6436 break
6437 time.sleep(0.1)
6438 if not ok:
6439 raise Exception("No allocation failure seen for %d:%s" % (count, func))
6440 dev[0].request("REMOVE_NETWORK all")
6441 dev[0].wait_disconnected()
6442
6443 def run_eap_ikev2_connect(dev):
6444 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412",
6445 eap="IKEV2", identity="ikev2 user",
6446 password="ike password",
6447 fragment_size="30", wait_connect=False)
6448 ev = dev.wait_event(["CTRL-EVENT-EAP-SUCCESS", "CTRL-EVENT-EAP-FAILURE",
6449 "CTRL-EVENT-DISCONNECTED"],
6450 timeout=1)
6451 dev.request("REMOVE_NETWORK all")
6452 if not ev or "CTRL-EVENT-DISCONNECTED" not in ev:
6453 dev.wait_disconnected()
6454 dev.dump_monitor()
6455
6456 def test_eap_proto_ikev2_errors_server(dev, apdev):
6457 """EAP-IKEV2 local error cases on server"""
6458 check_eap_capa(dev[0], "IKEV2")
6459 params = int_eap_server_params()
6460 params['erp_domain'] = 'example.com'
6461 params['eap_server_erp'] = '1'
6462 hapd = hostapd.add_ap(apdev[0], params)
6463 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
6464
6465 tests = [(1, "eap_ikev2_init"),
6466 (2, "=eap_ikev2_init"),
6467 (3, "=eap_ikev2_init"),
6468 (1, "eap_msg_alloc;eap_ikev2_build_msg"),
6469 (1, "ikev2_initiator_build;eap_ikev2_buildReq"),
6470 (1, "eap_ikev2_process_fragment"),
6471 (1, "wpabuf_alloc_copy;ikev2_process_ker"),
6472 (1, "ikev2_process_idr"),
6473 (1, "ikev2_derive_auth_data;ikev2_process_auth_secret"),
6474 (1, "ikev2_decrypt_payload;ikev2_process_sa_auth"),
6475 (1, "ikev2_process_sa_auth_decrypted;ikev2_process_sa_auth"),
6476 (1, "dh_init;ikev2_build_kei"),
6477 (1, "ikev2_build_auth"),
6478 (1, "wpabuf_alloc;ikev2_build_sa_init"),
6479 (1, "ikev2_build_sa_auth"),
6480 (1, "=ikev2_build_sa_auth"),
6481 (2, "=ikev2_derive_auth_data"),
6482 (1, "wpabuf_alloc;ikev2_build_sa_auth"),
6483 (2, "wpabuf_alloc;=ikev2_build_sa_auth"),
6484 (1, "ikev2_decrypt_payload;ikev2_process_sa_init_encr"),
6485 (1, "dh_derive_shared;ikev2_derive_keys"),
6486 (1, "=ikev2_derive_keys"),
6487 (2, "=ikev2_derive_keys"),
6488 (1, "eap_ikev2_getKey"),
6489 (1, "eap_ikev2_get_emsk"),
6490 (1, "eap_ikev2_get_session_id")]
6491 for count, func in tests:
6492 with alloc_fail(hapd, count, func):
6493 run_eap_ikev2_connect(dev[0])
6494
6495 tests = [(1, "eap_ikev2_validate_icv;eap_ikev2_process_icv"),
6496 (1, "eap_ikev2_server_keymat"),
6497 (1, "ikev2_build_auth"),
6498 (1, "os_get_random;ikev2_build_sa_init"),
6499 (2, "os_get_random;ikev2_build_sa_init"),
6500 (1, "ikev2_derive_keys"),
6501 (2, "ikev2_derive_keys"),
6502 (3, "ikev2_derive_keys"),
6503 (4, "ikev2_derive_keys"),
6504 (5, "ikev2_derive_keys"),
6505 (6, "ikev2_derive_keys"),
6506 (7, "ikev2_derive_keys"),
6507 (8, "ikev2_derive_keys"),
6508 (1, "ikev2_decrypt_payload;ikev2_process_sa_auth"),
6509 (1, "eap_ikev2_process_icv;eap_ikev2_process")]
6510 for count, func in tests:
6511 with fail_test(hapd, count, func):
6512 run_eap_ikev2_connect(dev[0])
6513
6514 def start_ikev2_assoc(dev, hapd):
6515 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412",
6516 eap="IKEV2", identity="ikev2 user",
6517 password="ike password", wait_connect=False)
6518 proxy_msg(hapd, dev) # EAP-Identity/Request
6519 proxy_msg(dev, hapd) # EAP-Identity/Response
6520 proxy_msg(hapd, dev) # IKEV2 1
6521
6522 def stop_ikev2_assoc(dev, hapd):
6523 dev.request("REMOVE_NETWORK all")
6524 dev.wait_disconnected()
6525 dev.dump_monitor()
6526 hapd.dump_monitor()
6527
6528 def test_eap_proto_ikev2_server(dev, apdev):
6529 """EAP-IKEV2 protocol testing for the server"""
6530 check_eap_capa(dev[0], "IKEV2")
6531 params = int_eap_server_params()
6532 params['erp_domain'] = 'example.com'
6533 params['eap_server_erp'] = '1'
6534 hapd = hostapd.add_ap(apdev[0], params)
6535 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
6536 hapd.request("SET ext_eapol_frame_io 1")
6537 dev[0].request("SET ext_eapol_frame_io 1")
6538
6539 # Successful exchange to verify proxying mechanism
6540 start_ikev2_assoc(dev[0], hapd)
6541 proxy_msg(dev[0], hapd) # IKEV2 2
6542 proxy_msg(hapd, dev[0]) # IKEV2 3
6543 proxy_msg(dev[0], hapd) # IKEV2 4
6544 proxy_msg(hapd, dev[0]) # EAP-Success
6545 proxy_msg(hapd, dev[0]) # EAPOL-Key msg 1/4
6546 proxy_msg(dev[0], hapd) # EAPOL-Key msg 2/4
6547 proxy_msg(hapd, dev[0]) # EAPOL-Key msg 3/4
6548 proxy_msg(dev[0], hapd) # EAPOL-Key msg 4/4
6549 dev[0].wait_connected()
6550 stop_ikev2_assoc(dev[0], hapd)
6551
6552 start_ikev2_assoc(dev[0], hapd)
6553 resp = rx_msg(dev[0])
6554 # Too short EAP-IKEV2 header
6555 hapd.note("IKEV2: Too short frame to include HDR")
6556 msg = resp[0:4] + "0005" + resp[8:12] + "0005" + "31"
6557 tx_msg(dev[0], hapd, msg)
6558 rx_msg(hapd)
6559 stop_ikev2_assoc(dev[0], hapd)
6560
6561 start_ikev2_assoc(dev[0], hapd)
6562 resp = rx_msg(dev[0])
6563 # Too short EAP-IKEV2 header - missing Message Length field
6564 hapd.note("EAP-IKEV2: Message underflow")
6565 msg = resp[0:4] + "0006" + resp[8:12] + "0006" + "3180"
6566 tx_msg(dev[0], hapd, msg)
6567 rx_msg(hapd)
6568 stop_ikev2_assoc(dev[0], hapd)
6569
6570 start_ikev2_assoc(dev[0], hapd)
6571 resp = rx_msg(dev[0])
6572 # Too short EAP-IKEV2 header - too small Message Length
6573 hapd.note("EAP-IKEV2: Invalid Message Length (0; 1 remaining in this msg)")
6574 msg = resp[0:4] + "000b" + resp[8:12] + "000b" + "318000000000ff"
6575 tx_msg(dev[0], hapd, msg)
6576 rx_msg(hapd)
6577 stop_ikev2_assoc(dev[0], hapd)
6578
6579 start_ikev2_assoc(dev[0], hapd)
6580 resp = rx_msg(dev[0])
6581 # Too short EAP-IKEV2 header - too large Message Length
6582 hapd.note("EAP-IKEV2: Ignore too long message")
6583 msg = resp[0:4] + "000b" + resp[8:12] + "000b" + "31c0bbccddeeff"
6584 tx_msg(dev[0], hapd, msg)
6585 rx_msg(hapd)
6586 stop_ikev2_assoc(dev[0], hapd)
6587
6588 start_ikev2_assoc(dev[0], hapd)
6589 resp = rx_msg(dev[0])
6590 # No Message Length in first fragment
6591 hapd.note("EAP-IKEV2: No Message Length field in a fragmented packet")
6592 msg = resp[0:4] + "0007" + resp[8:12] + "0007" + "3140ff"
6593 tx_msg(dev[0], hapd, msg)
6594 rx_msg(hapd)
6595 stop_ikev2_assoc(dev[0], hapd)
6596
6597 start_ikev2_assoc(dev[0], hapd)
6598 resp = rx_msg(dev[0])
6599 # First fragment (valid)
6600 hapd.note("EAP-IKEV2: Received 1 bytes in first fragment, waiting for 255 bytes more")
6601 msg = resp[0:4] + "000b" + resp[8:12] + "000b" + "31c000000100ff"
6602 tx_msg(dev[0], hapd, msg)
6603 req = rx_msg(hapd)
6604 id, = struct.unpack('B', binascii.unhexlify(req)[5:6])
6605 hapd.note("EAP-IKEV2: Received 1 bytes in first fragment, waiting for 254 bytes more")
6606 payload = struct.pack('BBB', 49, 0x40, 0)
6607 msg = struct.pack('>BBHBBH', 1, 0, 4 + len(payload), 2, id, 4 + len(payload)) + payload
6608 tx_msg(dev[0], hapd, binascii.hexlify(msg).decode())
6609 req = rx_msg(hapd)
6610 id, = struct.unpack('B', binascii.unhexlify(req)[5:6])
6611 hapd.note("EAP-IKEV2: Fragment overflow")
6612 payload = struct.pack('BB', 49, 0x40) + 255*b'\x00'
6613 msg = struct.pack('>BBHBBH', 1, 0, 4 + len(payload), 2, id, 4 + len(payload)) + payload
6614 tx_msg(dev[0], hapd, binascii.hexlify(msg).decode())
6615 rx_msg(hapd)
6616 stop_ikev2_assoc(dev[0], hapd)
6617
6618 start_ikev2_assoc(dev[0], hapd)
6619 proxy_msg(dev[0], hapd) # IKEV2 2
6620 req = proxy_msg(hapd, dev[0]) # IKEV2 3
6621 id, = struct.unpack('B', binascii.unhexlify(req)[5:6])
6622 # Missing ICV
6623 hapd.note("EAP-IKEV2: The message should have included integrity checksum")
6624 payload = struct.pack('BB', 49, 0) + b'\x00'
6625 msg = struct.pack('>BBHBBH', 1, 0, 4 + len(payload), 2, id, 4 + len(payload)) + payload
6626 tx_msg(dev[0], hapd, binascii.hexlify(msg).decode())
6627 rx_msg(hapd)
6628 stop_ikev2_assoc(dev[0], hapd)
6629
6630 tests = [("Unsupported HDR version 0x0 (expected 0x20)",
6631 struct.pack('BB', 49, 0) + 16*b'\x00' +
6632 struct.pack('>BBBBLL', 0, 0, 0, 0, 0, 0)),
6633 ("IKEV2: Invalid length (HDR: 0 != RX: 28)",
6634 struct.pack('BB', 49, 0) + 16*b'\x00' +
6635 struct.pack('>BBBBLL', 0, 0x20, 0, 0, 0, 0)),
6636 ("IKEV2: Unexpected Exchange Type 0 in SA_INIT state",
6637 struct.pack('BB', 49, 0) + 16*b'\x00' +
6638 struct.pack('>BBBBLL', 0, 0x20, 0, 0, 0, 28)),
6639 ("IKEV2: Unexpected Flags value 0x0",
6640 struct.pack('BB', 49, 0) + 16*b'\x00' +
6641 struct.pack('>BBBBLL', 0, 0x20, 34, 0, 0, 28)),
6642 ("IKEV2: SAr1 not received",
6643 struct.pack('BB', 49, 0) + 16*b'\x00' +
6644 struct.pack('>BBBBLL', 0, 0x20, 34, 0x20, 0, 28))]
6645 for txt, payload in tests:
6646 start_ikev2_assoc(dev[0], hapd)
6647 resp = rx_msg(dev[0])
6648 id, = struct.unpack('B', binascii.unhexlify(resp)[5:6])
6649 hapd.note(txt)
6650 msg = struct.pack('>BBHBBH', 1, 0, 4 + len(payload), 2, id, 4 + len(payload)) + payload
6651 tx_msg(dev[0], hapd, binascii.hexlify(msg).decode())
6652 rx_msg(hapd)
6653 stop_ikev2_assoc(dev[0], hapd)
6654
6655 def test_eap_proto_mschapv2(dev, apdev):
6656 """EAP-MSCHAPv2 protocol tests"""
6657 check_eap_capa(dev[0], "MSCHAPV2")
6658
6659 def mschapv2_handler(ctx, req):
6660 logger.info("mschapv2_handler - RX " + binascii.hexlify(req).decode())
6661 if 'num' not in ctx:
6662 ctx['num'] = 0
6663 ctx['num'] = ctx['num'] + 1
6664 if 'id' not in ctx:
6665 ctx['id'] = 1
6666 ctx['id'] = (ctx['id'] + 1) % 256
6667 idx = 0
6668
6669 idx += 1
6670 if ctx['num'] == idx:
6671 logger.info("Test: Missing payload")
6672 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6673 4 + 1,
6674 EAP_TYPE_MSCHAPV2)
6675
6676 idx += 1
6677 if ctx['num'] == idx:
6678 logger.info("Test: Unknown MSCHAPv2 op_code")
6679 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
6680 4 + 1 + 4 + 1,
6681 EAP_TYPE_MSCHAPV2,
6682 0, 0, 5, 0)
6683
6684 idx += 1
6685 if ctx['num'] == idx:
6686 logger.info("Test: Invalid ms_len and unknown MSCHAPv2 op_code")
6687 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
6688 4 + 1 + 4 + 1,
6689 EAP_TYPE_MSCHAPV2,
6690 255, 0, 0, 0)
6691
6692 idx += 1
6693 if ctx['num'] == idx:
6694 logger.info("Test: Success before challenge")
6695 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
6696 4 + 1 + 4 + 1,
6697 EAP_TYPE_MSCHAPV2,
6698 3, 0, 5, 0)
6699
6700 idx += 1
6701 if ctx['num'] == idx:
6702 logger.info("Test: Failure before challenge - required challenge field not present")
6703 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
6704 4 + 1 + 4 + 1,
6705 EAP_TYPE_MSCHAPV2,
6706 4, 0, 5, 0)
6707 idx += 1
6708 if ctx['num'] == idx:
6709 logger.info("Test: Failure")
6710 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6711
6712 idx += 1
6713 if ctx['num'] == idx:
6714 logger.info("Test: Failure before challenge - invalid failure challenge len")
6715 payload = b'C=12'
6716 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
6717 4 + 1 + 4 + len(payload),
6718 EAP_TYPE_MSCHAPV2,
6719 4, 0, 4 + len(payload)) + payload
6720 idx += 1
6721 if ctx['num'] == idx:
6722 logger.info("Test: Failure")
6723 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6724
6725 idx += 1
6726 if ctx['num'] == idx:
6727 logger.info("Test: Failure before challenge - invalid failure challenge len")
6728 payload = b'C=12 V=3'
6729 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
6730 4 + 1 + 4 + len(payload),
6731 EAP_TYPE_MSCHAPV2,
6732 4, 0, 4 + len(payload)) + payload
6733 idx += 1
6734 if ctx['num'] == idx:
6735 logger.info("Test: Failure")
6736 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6737
6738 idx += 1
6739 if ctx['num'] == idx:
6740 logger.info("Test: Failure before challenge - invalid failure challenge")
6741 payload = b'C=00112233445566778899aabbccddeefQ '
6742 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
6743 4 + 1 + 4 + len(payload),
6744 EAP_TYPE_MSCHAPV2,
6745 4, 0, 4 + len(payload)) + payload
6746 idx += 1
6747 if ctx['num'] == idx:
6748 logger.info("Test: Failure")
6749 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6750
6751 idx += 1
6752 if ctx['num'] == idx:
6753 logger.info("Test: Failure before challenge - password expired")
6754 payload = b'E=648 R=1 C=00112233445566778899aabbccddeeff V=3 M=Password expired'
6755 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
6756 4 + 1 + 4 + len(payload),
6757 EAP_TYPE_MSCHAPV2,
6758 4, 0, 4 + len(payload)) + payload
6759 idx += 1
6760 if ctx['num'] == idx:
6761 logger.info("Test: Success after password change")
6762 payload = b"S=1122334455667788990011223344556677889900"
6763 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
6764 4 + 1 + 4 + len(payload),
6765 EAP_TYPE_MSCHAPV2,
6766 3, 0, 4 + len(payload)) + payload
6767
6768 idx += 1
6769 if ctx['num'] == idx:
6770 logger.info("Test: Invalid challenge length")
6771 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
6772 4 + 1 + 4 + 1,
6773 EAP_TYPE_MSCHAPV2,
6774 1, 0, 4 + 1, 0)
6775
6776 idx += 1
6777 if ctx['num'] == idx:
6778 logger.info("Test: Too short challenge packet")
6779 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
6780 4 + 1 + 4 + 1,
6781 EAP_TYPE_MSCHAPV2,
6782 1, 0, 4 + 1, 16)
6783
6784 idx += 1
6785 if ctx['num'] == idx:
6786 logger.info("Test: Challenge")
6787 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
6788 4 + 1 + 4 + 1 + 16 + 6,
6789 EAP_TYPE_MSCHAPV2,
6790 1, 0, 4 + 1 + 16 + 6, 16) + 16*b'A' + b'foobar'
6791 idx += 1
6792 if ctx['num'] == idx:
6793 logger.info("Test: Failure - password expired")
6794 payload = b'E=648 R=1 C=00112233445566778899aabbccddeeff V=3 M=Password expired'
6795 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
6796 4 + 1 + 4 + len(payload),
6797 EAP_TYPE_MSCHAPV2,
6798 4, 0, 4 + len(payload)) + payload
6799 idx += 1
6800 if ctx['num'] == idx:
6801 logger.info("Test: Success after password change")
6802 if len(req) != 591:
6803 logger.info("Unexpected Change-Password packet length: %s" % len(req))
6804 return None
6805 data = req[9:]
6806 enc_pw = data[0:516]
6807 data = data[516:]
6808 enc_hash = data[0:16]
6809 data = data[16:]
6810 peer_challenge = data[0:16]
6811 data = data[16:]
6812 # Reserved
6813 data = data[8:]
6814 nt_response = data[0:24]
6815 data = data[24:]
6816 flags = data
6817 logger.info("enc_hash: " + binascii.hexlify(enc_hash).decode())
6818 logger.info("peer_challenge: " + binascii.hexlify(peer_challenge).decode())
6819 logger.info("nt_response: " + binascii.hexlify(nt_response).decode())
6820 logger.info("flags: " + binascii.hexlify(flags).decode())
6821
6822 auth_challenge = binascii.unhexlify("00112233445566778899aabbccddeeff")
6823 logger.info("auth_challenge: " + binascii.hexlify(auth_challenge).decode())
6824
6825 auth_resp = GenerateAuthenticatorResponse("new-pw", nt_response,
6826 peer_challenge,
6827 auth_challenge, "user")
6828 payload = b"S=" + binascii.hexlify(auth_resp).decode().upper().encode()
6829 logger.info("Success message payload: " + payload.decode())
6830 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
6831 4 + 1 + 4 + len(payload),
6832 EAP_TYPE_MSCHAPV2,
6833 3, 0, 4 + len(payload)) + payload
6834 idx += 1
6835 if ctx['num'] == idx:
6836 logger.info("Test: EAP-Success")
6837 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4)
6838
6839 idx += 1
6840 if ctx['num'] == idx:
6841 logger.info("Test: Failure - password expired")
6842 payload = b'E=648 R=1 C=00112233445566778899aabbccddeeff V=3 M=Password expired'
6843 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
6844 4 + 1 + 4 + len(payload),
6845 EAP_TYPE_MSCHAPV2,
6846 4, 0, 4 + len(payload)) + payload
6847 idx += 1
6848 if ctx['num'] == idx:
6849 logger.info("Test: Success after password change")
6850 if len(req) != 591:
6851 logger.info("Unexpected Change-Password packet length: %s" % len(req))
6852 return None
6853 data = req[9:]
6854 enc_pw = data[0:516]
6855 data = data[516:]
6856 enc_hash = data[0:16]
6857 data = data[16:]
6858 peer_challenge = data[0:16]
6859 data = data[16:]
6860 # Reserved
6861 data = data[8:]
6862 nt_response = data[0:24]
6863 data = data[24:]
6864 flags = data
6865 logger.info("enc_hash: " + binascii.hexlify(enc_hash).decode())
6866 logger.info("peer_challenge: " + binascii.hexlify(peer_challenge).decode())
6867 logger.info("nt_response: " + binascii.hexlify(nt_response).decode())
6868 logger.info("flags: " + binascii.hexlify(flags).decode())
6869
6870 auth_challenge = binascii.unhexlify("00112233445566778899aabbccddeeff")
6871 logger.info("auth_challenge: " + binascii.hexlify(auth_challenge).decode())
6872
6873 auth_resp = GenerateAuthenticatorResponse("new-pw", nt_response,
6874 peer_challenge,
6875 auth_challenge, "user")
6876 payload = b"S=" + binascii.hexlify(auth_resp).decode().upper().encode()
6877 logger.info("Success message payload: " + payload.decode())
6878 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
6879 4 + 1 + 4 + len(payload),
6880 EAP_TYPE_MSCHAPV2,
6881 3, 0, 4 + len(payload)) + payload
6882 idx += 1
6883 if ctx['num'] == idx:
6884 logger.info("Test: EAP-Success")
6885 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4)
6886
6887 idx += 1
6888 if ctx['num'] == idx:
6889 logger.info("Test: Challenge")
6890 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
6891 4 + 1 + 4 + 1 + 16 + 6,
6892 EAP_TYPE_MSCHAPV2,
6893 1, 0, 4 + 1 + 16 + 6, 16) + 16*b'A' + b'foobar'
6894 idx += 1
6895 if ctx['num'] == idx:
6896 logger.info("Test: Failure - authentication failure")
6897 payload = b'E=691 R=1 C=00112233445566778899aabbccddeeff V=3 M=Authentication failed'
6898 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
6899 4 + 1 + 4 + len(payload),
6900 EAP_TYPE_MSCHAPV2,
6901 4, 0, 4 + len(payload)) + payload
6902
6903 idx += 1
6904 if ctx['num'] == idx:
6905 logger.info("Test: Challenge")
6906 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
6907 4 + 1 + 4 + 1 + 16 + 6,
6908 EAP_TYPE_MSCHAPV2,
6909 1, 0, 4 + 1 + 16 + 6, 16) + 16*b'A' + b'foobar'
6910 idx += 1
6911 if ctx['num'] == idx:
6912 logger.info("Test: Failure - authentication failure")
6913 payload = b'E=691 R=1 C=00112233445566778899aabbccddeeff V=3 M=Authentication failed (2)'
6914 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
6915 4 + 1 + 4 + len(payload),
6916 EAP_TYPE_MSCHAPV2,
6917 4, 0, 4 + len(payload)) + payload
6918 idx += 1
6919 if ctx['num'] == idx:
6920 logger.info("Test: Failure")
6921 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6922
6923 idx += 1
6924 if ctx['num'] == idx:
6925 logger.info("Test: Challenge - invalid ms_len and workaround disabled")
6926 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
6927 4 + 1 + 4 + 1 + 16 + 6,
6928 EAP_TYPE_MSCHAPV2,
6929 1, 0, 4 + 1 + 16 + 6 + 1, 16) + 16*b'A' + b'foobar'
6930
6931 return None
6932
6933 srv = start_radius_server(mschapv2_handler)
6934
6935 try:
6936 hapd = start_ap(apdev[0])
6937 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
6938
6939 for i in range(0, 16):
6940 logger.info("RUN: %d" % i)
6941 if i == 12:
6942 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6943 eap="MSCHAPV2", identity="user",
6944 password_hex="hash:8846f7eaee8fb117ad06bdd830b7586c",
6945 wait_connect=False)
6946 elif i == 14:
6947 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6948 eap="MSCHAPV2", identity="user",
6949 phase2="mschapv2_retry=0",
6950 password="password", wait_connect=False)
6951 elif i == 15:
6952 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6953 eap="MSCHAPV2", identity="user",
6954 eap_workaround="0",
6955 password="password", wait_connect=False)
6956 else:
6957 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6958 eap="MSCHAPV2", identity="user",
6959 password="password", wait_connect=False)
6960 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15)
6961 if ev is None:
6962 raise Exception("Timeout on EAP start")
6963
6964 if i in [8, 11, 12]:
6965 ev = dev[0].wait_event(["CTRL-REQ-NEW_PASSWORD"],
6966 timeout=10)
6967 if ev is None:
6968 raise Exception("Timeout on new password request")
6969 id = ev.split(':')[0].split('-')[-1]
6970 dev[0].request("CTRL-RSP-NEW_PASSWORD-" + id + ":new-pw")
6971 if i in [11, 12]:
6972 ev = dev[0].wait_event(["CTRL-EVENT-PASSWORD-CHANGED"],
6973 timeout=10)
6974 if ev is None:
6975 raise Exception("Timeout on password change")
6976 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"],
6977 timeout=10)
6978 if ev is None:
6979 raise Exception("Timeout on EAP success")
6980 else:
6981 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"],
6982 timeout=10)
6983 if ev is None:
6984 raise Exception("Timeout on EAP failure")
6985
6986 if i in [13]:
6987 ev = dev[0].wait_event(["CTRL-REQ-IDENTITY"],
6988 timeout=10)
6989 if ev is None:
6990 raise Exception("Timeout on identity request")
6991 id = ev.split(':')[0].split('-')[-1]
6992 dev[0].request("CTRL-RSP-IDENTITY-" + id + ":user")
6993
6994 ev = dev[0].wait_event(["CTRL-REQ-PASSWORD"],
6995 timeout=10)
6996 if ev is None:
6997 raise Exception("Timeout on password request")
6998 id = ev.split(':')[0].split('-')[-1]
6999 dev[0].request("CTRL-RSP-PASSWORD-" + id + ":password")
7000
7001 # TODO: Does this work correctly?
7002
7003 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"],
7004 timeout=10)
7005 if ev is None:
7006 raise Exception("Timeout on EAP failure")
7007
7008 if i in [4, 5, 6, 7, 14]:
7009 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"],
7010 timeout=10)
7011 if ev is None:
7012 raise Exception("Timeout on EAP failure")
7013 else:
7014 time.sleep(0.05)
7015 dev[0].request("REMOVE_NETWORK all")
7016 dev[0].wait_disconnected(timeout=1)
7017 finally:
7018 stop_radius_server(srv)
7019
7020 def test_eap_proto_mschapv2_errors(dev, apdev):
7021 """EAP-MSCHAPv2 protocol tests (error paths)"""
7022 check_eap_capa(dev[0], "MSCHAPV2")
7023
7024 def mschapv2_fail_password_expired(ctx):
7025 logger.info("Test: Failure before challenge - password expired")
7026 payload = b'E=648 R=1 C=00112233445566778899aabbccddeeff V=3 M=Password expired'
7027 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
7028 4 + 1 + 4 + len(payload),
7029 EAP_TYPE_MSCHAPV2,
7030 4, 0, 4 + len(payload)) + payload
7031
7032 def mschapv2_success_after_password_change(ctx, req=None):
7033 logger.info("Test: Success after password change")
7034 if req is None or len(req) != 591:
7035 payload = b"S=1122334455667788990011223344556677889900"
7036 else:
7037 data = req[9:]
7038 enc_pw = data[0:516]
7039 data = data[516:]
7040 enc_hash = data[0:16]
7041 data = data[16:]
7042 peer_challenge = data[0:16]
7043 data = data[16:]
7044 # Reserved
7045 data = data[8:]
7046 nt_response = data[0:24]
7047 data = data[24:]
7048 flags = data
7049 logger.info("enc_hash: " + binascii.hexlify(enc_hash).decode())
7050 logger.info("peer_challenge: " + binascii.hexlify(peer_challenge).decode())
7051 logger.info("nt_response: " + binascii.hexlify(nt_response).decode())
7052 logger.info("flags: " + binascii.hexlify(flags).decode())
7053
7054 auth_challenge = binascii.unhexlify("00112233445566778899aabbccddeeff")
7055 logger.info("auth_challenge: " + binascii.hexlify(auth_challenge).decode())
7056
7057 auth_resp = GenerateAuthenticatorResponse("new-pw", nt_response,
7058 peer_challenge,
7059 auth_challenge, "user")
7060 payload = b"S=" + binascii.hexlify(auth_resp).decode().upper().encode()
7061 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
7062 4 + 1 + 4 + len(payload),
7063 EAP_TYPE_MSCHAPV2,
7064 3, 0, 4 + len(payload)) + payload
7065
7066 def mschapv2_handler(ctx, req):
7067 logger.info("mschapv2_handler - RX " + binascii.hexlify(req).decode())
7068 if 'num' not in ctx:
7069 ctx['num'] = 0
7070 ctx['num'] = ctx['num'] + 1
7071 if 'id' not in ctx:
7072 ctx['id'] = 1
7073 ctx['id'] = (ctx['id'] + 1) % 256
7074 idx = 0
7075
7076 idx += 1
7077 if ctx['num'] == idx:
7078 return mschapv2_fail_password_expired(ctx)
7079 idx += 1
7080 if ctx['num'] == idx:
7081 return mschapv2_success_after_password_change(ctx, req)
7082 idx += 1
7083 if ctx['num'] == idx:
7084 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7085
7086 idx += 1
7087 if ctx['num'] == idx:
7088 return mschapv2_fail_password_expired(ctx)
7089 idx += 1
7090 if ctx['num'] == idx:
7091 return mschapv2_success_after_password_change(ctx, req)
7092 idx += 1
7093 if ctx['num'] == idx:
7094 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7095
7096 idx += 1
7097 if ctx['num'] == idx:
7098 return mschapv2_fail_password_expired(ctx)
7099 idx += 1
7100 if ctx['num'] == idx:
7101 return mschapv2_success_after_password_change(ctx, req)
7102 idx += 1
7103 if ctx['num'] == idx:
7104 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7105
7106 idx += 1
7107 if ctx['num'] == idx:
7108 return mschapv2_fail_password_expired(ctx)
7109 idx += 1
7110 if ctx['num'] == idx:
7111 return mschapv2_success_after_password_change(ctx, req)
7112 idx += 1
7113 if ctx['num'] == idx:
7114 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7115
7116 idx += 1
7117 if ctx['num'] == idx:
7118 return mschapv2_fail_password_expired(ctx)
7119 idx += 1
7120 if ctx['num'] == idx:
7121 return mschapv2_success_after_password_change(ctx, req)
7122 idx += 1
7123 if ctx['num'] == idx:
7124 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7125
7126 idx += 1
7127 if ctx['num'] == idx:
7128 return mschapv2_fail_password_expired(ctx)
7129 idx += 1
7130 if ctx['num'] == idx:
7131 return mschapv2_success_after_password_change(ctx, req)
7132 idx += 1
7133 if ctx['num'] == idx:
7134 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7135
7136 idx += 1
7137 if ctx['num'] == idx:
7138 return mschapv2_fail_password_expired(ctx)
7139 idx += 1
7140 if ctx['num'] == idx:
7141 return mschapv2_success_after_password_change(ctx, req)
7142 idx += 1
7143 if ctx['num'] == idx:
7144 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7145
7146 idx += 1
7147 if ctx['num'] == idx:
7148 return mschapv2_fail_password_expired(ctx)
7149 idx += 1
7150 if ctx['num'] == idx:
7151 return mschapv2_success_after_password_change(ctx, req)
7152 idx += 1
7153 if ctx['num'] == idx:
7154 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7155
7156 idx += 1
7157 if ctx['num'] == idx:
7158 return mschapv2_fail_password_expired(ctx)
7159 idx += 1
7160 if ctx['num'] == idx:
7161 return mschapv2_success_after_password_change(ctx, req)
7162 idx += 1
7163 if ctx['num'] == idx:
7164 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7165
7166 return None
7167
7168 srv = start_radius_server(mschapv2_handler)
7169
7170 try:
7171 hapd = start_ap(apdev[0])
7172 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
7173
7174 tests = ["os_get_random;eap_mschapv2_change_password",
7175 "generate_nt_response;eap_mschapv2_change_password",
7176 "get_master_key;eap_mschapv2_change_password",
7177 "nt_password_hash;eap_mschapv2_change_password",
7178 "old_nt_password_hash_encrypted_with_new_nt_password_hash"]
7179 for func in tests:
7180 with fail_test(dev[0], 1, func):
7181 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7182 eap="MSCHAPV2", identity="user",
7183 password="password", wait_connect=False)
7184 ev = dev[0].wait_event(["CTRL-REQ-NEW_PASSWORD"], timeout=10)
7185 if ev is None:
7186 raise Exception("Timeout on new password request")
7187 id = ev.split(':')[0].split('-')[-1]
7188 dev[0].request("CTRL-RSP-NEW_PASSWORD-" + id + ":new-pw")
7189 time.sleep(0.1)
7190 wait_fail_trigger(dev[0], "GET_FAIL")
7191 dev[0].request("REMOVE_NETWORK all")
7192 dev[0].wait_disconnected(timeout=1)
7193
7194 tests = ["encrypt_pw_block_with_password_hash;eap_mschapv2_change_password",
7195 "nt_password_hash;eap_mschapv2_change_password",
7196 "nt_password_hash;eap_mschapv2_success"]
7197 for func in tests:
7198 with fail_test(dev[0], 1, func):
7199 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7200 eap="MSCHAPV2", identity="user",
7201 password_hex="hash:8846f7eaee8fb117ad06bdd830b7586c",
7202 wait_connect=False)
7203 ev = dev[0].wait_event(["CTRL-REQ-NEW_PASSWORD"], timeout=10)
7204 if ev is None:
7205 raise Exception("Timeout on new password request")
7206 id = ev.split(':')[0].split('-')[-1]
7207 dev[0].request("CTRL-RSP-NEW_PASSWORD-" + id + ":new-pw")
7208 time.sleep(0.1)
7209 wait_fail_trigger(dev[0], "GET_FAIL")
7210 dev[0].request("REMOVE_NETWORK all")
7211 dev[0].wait_disconnected(timeout=1)
7212
7213 tests = ["eap_msg_alloc;eap_mschapv2_change_password"]
7214 for func in tests:
7215 with alloc_fail(dev[0], 1, func):
7216 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7217 eap="MSCHAPV2", identity="user",
7218 password="password", wait_connect=False)
7219 ev = dev[0].wait_event(["CTRL-REQ-NEW_PASSWORD"], timeout=10)
7220 if ev is None:
7221 raise Exception("Timeout on new password request")
7222 id = ev.split(':')[0].split('-')[-1]
7223 dev[0].request("CTRL-RSP-NEW_PASSWORD-" + id + ":new-pw")
7224 time.sleep(0.1)
7225 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
7226 dev[0].request("REMOVE_NETWORK all")
7227 dev[0].wait_disconnected(timeout=1)
7228 finally:
7229 stop_radius_server(srv)
7230
7231 def test_eap_proto_pwd(dev, apdev):
7232 """EAP-pwd protocol tests"""
7233 check_eap_capa(dev[0], "PWD")
7234
7235 global eap_proto_pwd_test_done, eap_proto_pwd_test_wait
7236 eap_proto_pwd_test_done = False
7237 eap_proto_pwd_test_wait = False
7238
7239 def pwd_handler(ctx, req):
7240 logger.info("pwd_handler - RX " + binascii.hexlify(req).decode())
7241 if 'num' not in ctx:
7242 ctx['num'] = 0
7243 ctx['num'] = ctx['num'] + 1
7244 if 'id' not in ctx:
7245 ctx['id'] = 1
7246 ctx['id'] = (ctx['id'] + 1) % 256
7247 idx = 0
7248
7249 global eap_proto_pwd_test_wait
7250 eap_proto_pwd_test_wait = False
7251
7252 idx += 1
7253 if ctx['num'] == idx:
7254 logger.info("Test: Missing payload")
7255 # EAP-pwd: Got a frame but pos is not NULL and len is 0
7256 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 4 + 1,
7257 EAP_TYPE_PWD)
7258
7259 idx += 1
7260 if ctx['num'] == idx:
7261 logger.info("Test: Missing Total-Length field")
7262 # EAP-pwd: Frame too short to contain Total-Length field
7263 payload = struct.pack("B", 0x80)
7264 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7265 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7266
7267 idx += 1
7268 if ctx['num'] == idx:
7269 logger.info("Test: Too large Total-Length")
7270 # EAP-pwd: Incoming fragments whose total length = 65535
7271 payload = struct.pack(">BH", 0x80, 65535)
7272 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7273 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7274
7275 idx += 1
7276 if ctx['num'] == idx:
7277 eap_proto_pwd_test_wait = True
7278 logger.info("Test: First fragment")
7279 # EAP-pwd: Incoming fragments whose total length = 10
7280 # EAP-pwd: ACKing a 0 byte fragment
7281 payload = struct.pack(">BH", 0xc0, 10)
7282 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7283 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7284 idx += 1
7285 if ctx['num'] == idx:
7286 logger.info("Test: Unexpected Total-Length value in the second fragment")
7287 # EAP-pwd: Incoming fragments whose total length = 0
7288 # EAP-pwd: Unexpected new fragment start when previous fragment is still in use
7289 payload = struct.pack(">BH", 0x80, 0)
7290 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7291 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7292
7293 idx += 1
7294 if ctx['num'] == idx:
7295 logger.info("Test: First and only fragment")
7296 # EAP-pwd: Incoming fragments whose total length = 0
7297 # EAP-pwd: processing frame: exch 0, len 0
7298 # EAP-pwd: Ignoring message with unknown opcode 128
7299 payload = struct.pack(">BH", 0x80, 0)
7300 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7301 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7302
7303 idx += 1
7304 if ctx['num'] == idx:
7305 logger.info("Test: First and only fragment with extra data")
7306 # EAP-pwd: Incoming fragments whose total length = 0
7307 # EAP-pwd: processing frame: exch 0, len 1
7308 # EAP-pwd: Ignoring message with unknown opcode 128
7309 payload = struct.pack(">BHB", 0x80, 0, 0)
7310 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7311 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7312
7313 idx += 1
7314 if ctx['num'] == idx:
7315 eap_proto_pwd_test_wait = True
7316 logger.info("Test: First fragment")
7317 # EAP-pwd: Incoming fragments whose total length = 2
7318 # EAP-pwd: ACKing a 1 byte fragment
7319 payload = struct.pack(">BHB", 0xc0, 2, 1)
7320 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7321 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7322 idx += 1
7323 if ctx['num'] == idx:
7324 logger.info("Test: Extra data in the second fragment")
7325 # EAP-pwd: Buffer overflow attack detected (3 vs. 1)!
7326 payload = struct.pack(">BBB", 0x0, 2, 3)
7327 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7328 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7329
7330 idx += 1
7331 if ctx['num'] == idx:
7332 logger.info("Test: Too short id exchange")
7333 # EAP-pwd: processing frame: exch 1, len 0
7334 # EAP-PWD: PWD-ID-Req -> FAILURE
7335 payload = struct.pack(">B", 0x01)
7336 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7337 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7338
7339 idx += 1
7340 if ctx['num'] == idx:
7341 logger.info("Test: Unsupported rand func in id exchange")
7342 # EAP-PWD: Server EAP-pwd-ID proposal: group=0 random=0 prf=0 prep=0
7343 # EAP-PWD: PWD-ID-Req -> FAILURE
7344 payload = struct.pack(">BHBBLB", 0x01, 0, 0, 0, 0, 0)
7345 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7346 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7347
7348 idx += 1
7349 if ctx['num'] == idx:
7350 logger.info("Test: Unsupported prf in id exchange")
7351 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=0 prep=0
7352 # EAP-PWD: PWD-ID-Req -> FAILURE
7353 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 0, 0, 0)
7354 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7355 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7356
7357 idx += 1
7358 if ctx['num'] == idx:
7359 logger.info("Test: Unsupported password pre-processing technique in id exchange")
7360 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=255
7361 # EAP-PWD: Unsupported password pre-processing technique (Prep=255)
7362 # EAP-PWD: PWD-ID-Req -> FAILURE
7363 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 255)
7364 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7365 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7366
7367 idx += 1
7368 if ctx['num'] == idx:
7369 eap_proto_pwd_test_wait = True
7370 logger.info("Test: Valid id exchange")
7371 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=0
7372 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0)
7373 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7374 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7375 idx += 1
7376 if ctx['num'] == idx:
7377 logger.info("Test: Unexpected id exchange")
7378 # EAP-pwd: processing frame: exch 1, len 9
7379 # EAP-PWD: PWD-Commit-Req -> FAILURE
7380 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0)
7381 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7382 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7383
7384 idx += 1
7385 if ctx['num'] == idx:
7386 logger.info("Test: Unexpected commit exchange")
7387 # EAP-pwd: processing frame: exch 2, len 0
7388 # EAP-PWD: PWD-ID-Req -> FAILURE
7389 payload = struct.pack(">B", 0x02)
7390 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7391 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7392
7393 idx += 1
7394 if ctx['num'] == idx:
7395 eap_proto_pwd_test_wait = True
7396 logger.info("Test: Valid id exchange")
7397 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=0
7398 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0)
7399 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7400 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7401 idx += 1
7402 if ctx['num'] == idx:
7403 logger.info("Test: Unexpected Commit payload length (prep=None)")
7404 # EAP-pwd commit request, password prep is NONE
7405 # EAP-pwd: Unexpected Commit payload length 0 (expected 96)
7406 payload = struct.pack(">B", 0x02)
7407 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7408 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7409
7410 idx += 1
7411 if ctx['num'] == idx:
7412 eap_proto_pwd_test_wait = True
7413 logger.info("Test: Valid id exchange")
7414 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=0
7415 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0)
7416 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7417 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7418 idx += 1
7419 if ctx['num'] == idx:
7420 logger.info("Test: Commit payload with all zeros values --> Shared key at infinity")
7421 # EAP-pwd: Invalid coordinate in element
7422 payload = struct.pack(">B", 0x02) + 96*b'\0'
7423 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7424 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7425
7426 idx += 1
7427 if ctx['num'] == idx:
7428 eap_proto_pwd_test_wait = True
7429 logger.info("Test: Valid id exchange")
7430 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=0
7431 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0)
7432 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7433 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7434 idx += 1
7435 if ctx['num'] == idx:
7436 eap_proto_pwd_test_wait = True
7437 logger.info("Test: Commit payload with valid values")
7438 # EAP-pwd commit request, password prep is NONE
7439 element = binascii.unhexlify("8dcab2862c5396839a6bac0c689ff03d962863108e7c275bbf1d6eedf634ee832a214db99f0d0a1a6317733eecdd97f0fc4cda19f57e1bb9bb9c8dcf8c60ba6f")
7440 scalar = binascii.unhexlify("450f31e058cf2ac2636a5d6e2b3c70b1fcc301957f0716e77f13aa69f9a2e5bd")
7441 payload = struct.pack(">B", 0x02) + element + scalar
7442 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7443 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7444 idx += 1
7445 if ctx['num'] == idx:
7446 logger.info("Test: Unexpected Confirm payload length 0")
7447 # EAP-pwd: Unexpected Confirm payload length 0 (expected 32)
7448 payload = struct.pack(">B", 0x03)
7449 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7450 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7451
7452 idx += 1
7453 if ctx['num'] == idx:
7454 eap_proto_pwd_test_wait = True
7455 logger.info("Test: Valid id exchange")
7456 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=0
7457 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0)
7458 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7459 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7460 idx += 1
7461 if ctx['num'] == idx:
7462 eap_proto_pwd_test_wait = True
7463 logger.info("Test: Commit payload with valid values")
7464 # EAP-pwd commit request, password prep is NONE
7465 element = binascii.unhexlify("8dcab2862c5396839a6bac0c689ff03d962863108e7c275bbf1d6eedf634ee832a214db99f0d0a1a6317733eecdd97f0fc4cda19f57e1bb9bb9c8dcf8c60ba6f")
7466 scalar = binascii.unhexlify("450f31e058cf2ac2636a5d6e2b3c70b1fcc301957f0716e77f13aa69f9a2e5bd")
7467 payload = struct.pack(">B", 0x02) + element + scalar
7468 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7469 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7470 idx += 1
7471 if ctx['num'] == idx:
7472 logger.info("Test: Confirm payload with incorrect value")
7473 # EAP-PWD (peer): confirm did not verify
7474 payload = struct.pack(">B", 0x03) + 32*b'\0'
7475 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7476 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7477
7478 idx += 1
7479 if ctx['num'] == idx:
7480 logger.info("Test: Unexpected confirm exchange")
7481 # EAP-pwd: processing frame: exch 3, len 0
7482 # EAP-PWD: PWD-ID-Req -> FAILURE
7483 payload = struct.pack(">B", 0x03)
7484 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7485 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7486
7487 idx += 1
7488 if ctx['num'] == idx:
7489 logger.info("Test: Unsupported password pre-processing technique SASLprep in id exchange")
7490 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=2
7491 # EAP-PWD: Unsupported password pre-processing technique (Prep=2)
7492 # EAP-PWD: PWD-ID-Req -> FAILURE
7493 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 2)
7494 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7495 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7496
7497 idx += 1
7498 if ctx['num'] == idx:
7499 eap_proto_pwd_test_wait = True
7500 logger.info("Test: Valid id exchange")
7501 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=1
7502 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 1)
7503 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7504 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7505 idx += 1
7506 if ctx['num'] == idx:
7507 logger.info("Test: Unexpected Commit payload length (prep=MS)")
7508 # EAP-pwd commit request, password prep is MS
7509 # EAP-pwd: Unexpected Commit payload length 0 (expected 96)
7510 payload = struct.pack(">B", 0x02)
7511 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7512 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7513
7514 idx += 1
7515 if ctx['num'] == idx:
7516 eap_proto_pwd_test_wait = True
7517 logger.info("Test: Valid id exchange")
7518 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=3
7519 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 3)
7520 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7521 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7522 idx += 1
7523 if ctx['num'] == idx:
7524 logger.info("Test: Unexpected Commit payload length (prep=ssha1)")
7525 # EAP-pwd commit request, password prep is salted sha1
7526 # EAP-pwd: Invalid Salt-len
7527 payload = struct.pack(">B", 0x02)
7528 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7529 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7530
7531 idx += 1
7532 if ctx['num'] == idx:
7533 eap_proto_pwd_test_wait = True
7534 logger.info("Test: Valid id exchange")
7535 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=3
7536 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 3)
7537 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7538 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7539 idx += 1
7540 if ctx['num'] == idx:
7541 logger.info("Test: Unexpected Commit payload length (prep=ssha1)")
7542 # EAP-pwd commit request, password prep is salted sha1
7543 # EAP-pwd: Invalid Salt-len
7544 payload = struct.pack(">BB", 0x02, 0)
7545 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7546 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7547
7548 idx += 1
7549 if ctx['num'] == idx:
7550 eap_proto_pwd_test_wait = True
7551 logger.info("Test: Valid id exchange")
7552 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=3
7553 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 3)
7554 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7555 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7556 idx += 1
7557 if ctx['num'] == idx:
7558 logger.info("Test: Unexpected Commit payload length (prep=ssha1)")
7559 # EAP-pwd commit request, password prep is salted sha1
7560 # EAP-pwd: Unexpected Commit payload length 1 (expected 98)
7561 payload = struct.pack(">BB", 0x02, 1)
7562 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7563 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7564
7565 idx += 1
7566 if ctx['num'] == idx:
7567 eap_proto_pwd_test_wait = True
7568 logger.info("Test: Valid id exchange")
7569 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=4
7570 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 4)
7571 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7572 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7573 idx += 1
7574 if ctx['num'] == idx:
7575 logger.info("Test: Unexpected Commit payload length (prep=ssha256)")
7576 # EAP-pwd commit request, password prep is salted sha256
7577 # EAP-pwd: Invalid Salt-len
7578 payload = struct.pack(">B", 0x02)
7579 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7580 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7581
7582 idx += 1
7583 if ctx['num'] == idx:
7584 eap_proto_pwd_test_wait = True
7585 logger.info("Test: Valid id exchange")
7586 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=4
7587 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 4)
7588 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7589 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7590 idx += 1
7591 if ctx['num'] == idx:
7592 logger.info("Test: Unexpected Commit payload length (prep=ssha256)")
7593 # EAP-pwd commit request, password prep is salted sha256
7594 # EAP-pwd: Invalid Salt-len
7595 payload = struct.pack(">BB", 0x02, 0)
7596 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7597 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7598
7599 idx += 1
7600 if ctx['num'] == idx:
7601 eap_proto_pwd_test_wait = True
7602 logger.info("Test: Valid id exchange")
7603 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=4
7604 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 4)
7605 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7606 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7607 idx += 1
7608 if ctx['num'] == idx:
7609 logger.info("Test: Unexpected Commit payload length (prep=ssha256)")
7610 # EAP-pwd commit request, password prep is salted sha256
7611 # EAP-pwd: Unexpected Commit payload length 1 (expected 98)
7612 payload = struct.pack(">BB", 0x02, 1)
7613 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7614 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7615
7616 idx += 1
7617 if ctx['num'] == idx:
7618 eap_proto_pwd_test_wait = True
7619 logger.info("Test: Valid id exchange")
7620 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=5
7621 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 5)
7622 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7623 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7624 idx += 1
7625 if ctx['num'] == idx:
7626 logger.info("Test: Unexpected Commit payload length (prep=ssha512)")
7627 # EAP-pwd commit request, password prep is salted sha512
7628 # EAP-pwd: Invalid Salt-len
7629 payload = struct.pack(">B", 0x02)
7630 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7631 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7632
7633 idx += 1
7634 if ctx['num'] == idx:
7635 eap_proto_pwd_test_wait = True
7636 logger.info("Test: Valid id exchange")
7637 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=5
7638 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 5)
7639 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7640 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7641 idx += 1
7642 if ctx['num'] == idx:
7643 logger.info("Test: Unexpected Commit payload length (prep=ssha512)")
7644 # EAP-pwd commit request, password prep is salted sha512
7645 # EAP-pwd: Invalid Salt-len
7646 payload = struct.pack(">BB", 0x02, 0)
7647 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7648 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7649
7650 idx += 1
7651 if ctx['num'] == idx:
7652 eap_proto_pwd_test_wait = True
7653 logger.info("Test: Valid id exchange")
7654 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=5
7655 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 5)
7656 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7657 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7658 idx += 1
7659 if ctx['num'] == idx:
7660 logger.info("Test: Unexpected Commit payload length (prep=ssha512)")
7661 # EAP-pwd commit request, password prep is salted sha512
7662 # EAP-pwd: Unexpected Commit payload length 1 (expected 98)
7663 payload = struct.pack(">BB", 0x02, 1)
7664 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7665 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7666
7667 logger.info("No more test responses available - test case completed")
7668 global eap_proto_pwd_test_done
7669 eap_proto_pwd_test_done = True
7670 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7671
7672 srv = start_radius_server(pwd_handler)
7673
7674 try:
7675 hapd = start_ap(apdev[0])
7676 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
7677
7678 i = 0
7679 while not eap_proto_pwd_test_done:
7680 i += 1
7681 logger.info("Running connection iteration %d" % i)
7682 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7683 eap="PWD", identity="pwd user",
7684 password="secret password",
7685 wait_connect=False)
7686 ok = False
7687 for j in range(5):
7688 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STATUS",
7689 "CTRL-EVENT-EAP-PROPOSED-METHOD"],
7690 timeout=5)
7691 if ev is None:
7692 raise Exception("Timeout on EAP start")
7693 if "CTRL-EVENT-EAP-PROPOSED-METHOD" in ev:
7694 ok = True
7695 break
7696 if "CTRL-EVENT-EAP-STATUS" in ev and "status='completion' parameter='failure'" in ev:
7697 ok = True
7698 break
7699 if not ok:
7700 raise Exception("Expected EAP event not seen")
7701 if eap_proto_pwd_test_wait:
7702 for k in range(20):
7703 time.sleep(0.1)
7704 if not eap_proto_pwd_test_wait:
7705 break
7706 if eap_proto_pwd_test_wait:
7707 raise Exception("eap_proto_pwd_test_wait not cleared")
7708 dev[0].request("REMOVE_NETWORK all")
7709 dev[0].wait_disconnected(timeout=1)
7710 dev[0].dump_monitor()
7711 finally:
7712 stop_radius_server(srv)
7713
7714 def test_eap_proto_pwd_invalid_scalar(dev, apdev):
7715 """EAP-pwd protocol tests - invalid server scalar"""
7716 check_eap_capa(dev[0], "PWD")
7717 run_eap_proto_pwd_invalid_scalar(dev, apdev, 32*b'\0')
7718 run_eap_proto_pwd_invalid_scalar(dev, apdev, 31*b'\0' + b'\x01')
7719 # Group Order
7720 val = binascii.unhexlify("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551")
7721 run_eap_proto_pwd_invalid_scalar(dev, apdev, val)
7722 # Group Order - 1
7723 val = binascii.unhexlify("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632550")
7724 run_eap_proto_pwd_invalid_scalar(dev, apdev, val, valid_scalar=True)
7725
7726 def run_eap_proto_pwd_invalid_scalar(dev, apdev, scalar, valid_scalar=False):
7727 global eap_proto_pwd_invalid_scalar_fail
7728 eap_proto_pwd_invalid_scalar_fail = False
7729
7730 def pwd_handler(ctx, req):
7731 logger.info("pwd_handler - RX " + binascii.hexlify(req).decode())
7732 if 'num' not in ctx:
7733 ctx['num'] = 0
7734 ctx['num'] = ctx['num'] + 1
7735 if 'id' not in ctx:
7736 ctx['id'] = 1
7737 ctx['id'] = (ctx['id'] + 1) % 256
7738 idx = 0
7739
7740 idx += 1
7741 if ctx['num'] == idx:
7742 logger.info("Test: Valid id exchange")
7743 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0)
7744 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7745 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7746 idx += 1
7747 if ctx['num'] == idx:
7748 logger.info("Test: Commit payload with invalid scalar")
7749 payload = struct.pack(">B", 0x02) + binascii.unhexlify("67feb2b46d59e6dd3af3a429ec9c04a949337564615d3a2c19bdf6826eb6f5efa303aed86af3a072ed819d518d620adb2659f0e84c4f8b739629db8c93088cfc") + scalar
7750 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7751 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7752 idx += 1
7753 if ctx['num'] == idx:
7754 logger.info("Confirm message next - should not get here")
7755 global eap_proto_pwd_invalid_scalar_fail
7756 eap_proto_pwd_invalid_scalar_fail = True
7757 payload = struct.pack(">B", 0x03) + 32*b'\0'
7758 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7759 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7760
7761 logger.info("No more test responses available - test case completed")
7762 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7763
7764 srv = start_radius_server(pwd_handler)
7765
7766 try:
7767 hapd = start_ap(apdev[0])
7768 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
7769
7770 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7771 eap="PWD", identity="pwd user",
7772 password="secret password",
7773 wait_connect=False)
7774 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
7775 if ev is None:
7776 raise Exception("EAP failure not reported")
7777 dev[0].request("REMOVE_NETWORK all")
7778 dev[0].wait_disconnected(timeout=1)
7779 dev[0].dump_monitor()
7780 finally:
7781 stop_radius_server(srv)
7782
7783 if valid_scalar and not eap_proto_pwd_invalid_scalar_fail:
7784 raise Exception("Peer did not accept valid EAP-pwd-Commit scalar")
7785 if not valid_scalar and eap_proto_pwd_invalid_scalar_fail:
7786 raise Exception("Peer did not stop after invalid EAP-pwd-Commit scalar")
7787
7788 def test_eap_proto_pwd_invalid_element(dev, apdev):
7789 """EAP-pwd protocol tests - invalid server element"""
7790 check_eap_capa(dev[0], "PWD")
7791 # Invalid x,y coordinates
7792 run_eap_proto_pwd_invalid_element(dev, apdev, 64*b'\x00')
7793 run_eap_proto_pwd_invalid_element(dev, apdev, 32*b'\x00' + 32*b'\x01')
7794 run_eap_proto_pwd_invalid_element(dev, apdev, 32*b'\x01' + 32*b'\x00')
7795 run_eap_proto_pwd_invalid_element(dev, apdev, 32*b'\xff' + 32*b'\x01')
7796 run_eap_proto_pwd_invalid_element(dev, apdev, 32*b'\x01' + 32*b'\xff')
7797 run_eap_proto_pwd_invalid_element(dev, apdev, 64*b'\xff')
7798 # Not on curve
7799 run_eap_proto_pwd_invalid_element(dev, apdev, 64*b'\x01')
7800
7801 def run_eap_proto_pwd_invalid_element(dev, apdev, element):
7802 global eap_proto_pwd_invalid_element_fail
7803 eap_proto_pwd_invalid_element_fail = False
7804
7805 def pwd_handler(ctx, req):
7806 logger.info("pwd_handler - RX " + binascii.hexlify(req).decode())
7807 if 'num' not in ctx:
7808 ctx['num'] = 0
7809 ctx['num'] = ctx['num'] + 1
7810 if 'id' not in ctx:
7811 ctx['id'] = 1
7812 ctx['id'] = (ctx['id'] + 1) % 256
7813 idx = 0
7814
7815 idx += 1
7816 if ctx['num'] == idx:
7817 logger.info("Test: Valid id exchange")
7818 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0)
7819 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7820 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7821 idx += 1
7822 if ctx['num'] == idx:
7823 logger.info("Test: Commit payload with invalid element")
7824 payload = struct.pack(">B", 0x02) + element + 31*b'\0' + b'\x02'
7825 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7826 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7827 idx += 1
7828 if ctx['num'] == idx:
7829 logger.info("Confirm message next - should not get here")
7830 global eap_proto_pwd_invalid_element_fail
7831 eap_proto_pwd_invalid_element_fail = True
7832 payload = struct.pack(">B", 0x03) + 32*b'\0'
7833 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7834 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7835
7836 logger.info("No more test responses available - test case completed")
7837 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7838
7839 srv = start_radius_server(pwd_handler)
7840
7841 try:
7842 hapd = start_ap(apdev[0])
7843 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
7844
7845 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7846 eap="PWD", identity="pwd user",
7847 password="secret password",
7848 wait_connect=False)
7849 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
7850 if ev is None:
7851 raise Exception("EAP failure not reported")
7852 dev[0].request("REMOVE_NETWORK all")
7853 dev[0].wait_disconnected(timeout=1)
7854 dev[0].dump_monitor()
7855 finally:
7856 stop_radius_server(srv)
7857
7858 if eap_proto_pwd_invalid_element_fail:
7859 raise Exception("Peer did not stop after invalid EAP-pwd-Commit element")
7860
7861 def rx_msg(src):
7862 ev = src.wait_event(["EAPOL-TX"], timeout=5)
7863 if ev is None:
7864 raise Exception("No EAPOL-TX")
7865 return ev.split(' ')[2]
7866
7867 def tx_msg(src, dst, msg):
7868 dst.request("EAPOL_RX " + src.own_addr() + " " + msg)
7869
7870 def proxy_msg(src, dst):
7871 msg = rx_msg(src)
7872 tx_msg(src, dst, msg)
7873 return msg
7874
7875 def start_pwd_exchange(dev, ap):
7876 check_eap_capa(dev, "PWD")
7877 params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap")
7878 hapd = hostapd.add_ap(ap, params)
7879 hapd.request("SET ext_eapol_frame_io 1")
7880 dev.request("SET ext_eapol_frame_io 1")
7881 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP",
7882 eap="PWD", identity="pwd user", password="secret password",
7883 wait_connect=False, scan_freq="2412")
7884 proxy_msg(hapd, dev) # EAP-Identity/Request
7885 proxy_msg(dev, hapd) # EAP-Identity/Response
7886 proxy_msg(hapd, dev) # EAP-pwd-ID/Request
7887 proxy_msg(dev, hapd) # EAP-pwd-ID/Response
7888 return hapd
7889
7890 def test_eap_proto_pwd_unexpected_fragment(dev, apdev):
7891 """EAP-pwd protocol tests - unexpected more-fragment frame"""
7892 hapd = start_pwd_exchange(dev[0], apdev[0])
7893
7894 # EAP-pwd-Commit/Request
7895 req = rx_msg(hapd)
7896 if req[18:20] != "02":
7897 raise Exception("Unexpected EAP-pwd-Commit/Request flag")
7898 msg = req[0:18] + "42" + req[20:]
7899 tx_msg(hapd, dev[0], msg)
7900
7901 def test_eap_proto_pwd_reflection_attack(dev, apdev):
7902 """EAP-pwd protocol tests - reflection attack on the server"""
7903 hapd = start_pwd_exchange(dev[0], apdev[0])
7904
7905 # EAP-pwd-Commit/Request
7906 req = proxy_msg(hapd, dev[0])
7907 if len(req) != 212:
7908 raise Exception("Unexpected EAP-pwd-Commit/Response length")
7909
7910 # EAP-pwd-Commit/Response
7911 resp = rx_msg(dev[0])
7912 # Reflect same Element/Scalar back to the server
7913 msg = resp[0:20] + req[20:]
7914 tx_msg(dev[0], hapd, msg)
7915
7916 # EAP-pwd-Commit/Response or EAP-Failure
7917 req = rx_msg(hapd)
7918 if req[8:10] != "04":
7919 # reflect EAP-pwd-Confirm/Request
7920 msg = req[0:8] + "02" + req[10:]
7921 tx_msg(dev[0], hapd, msg)
7922 req = rx_msg(hapd)
7923 if req[8:10] == "03":
7924 raise Exception("EAP-Success after reflected Element/Scalar")
7925 raise Exception("No EAP-Failure to reject invalid EAP-pwd-Commit/Response")
7926
7927 def test_eap_proto_pwd_invalid_scalar_peer(dev, apdev):
7928 """EAP-pwd protocol tests - invalid peer scalar"""
7929 run_eap_proto_pwd_invalid_scalar_peer(dev, apdev, 32*"00")
7930 run_eap_proto_pwd_invalid_scalar_peer(dev, apdev, 31*"00" + "01")
7931 # Group Order
7932 run_eap_proto_pwd_invalid_scalar_peer(dev, apdev,
7933 "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551")
7934 # Group Order - 1
7935 run_eap_proto_pwd_invalid_scalar_peer(dev, apdev,
7936 "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632550",
7937 valid_scalar=True)
7938
7939 def run_eap_proto_pwd_invalid_scalar_peer(dev, apdev, scalar,
7940 valid_scalar=False):
7941 hapd = start_pwd_exchange(dev[0], apdev[0])
7942 proxy_msg(hapd, dev[0]) # EAP-pwd-Commit/Request
7943
7944 # EAP-pwd-Commit/Response
7945 resp = rx_msg(dev[0])
7946 # Replace scalar with an invalid value
7947 msg = resp[0:20] + resp[20:148] + scalar
7948 tx_msg(dev[0], hapd, msg)
7949
7950 # EAP-pwd-Commit/Response or EAP-Failure
7951 req = rx_msg(hapd)
7952 if valid_scalar and req[8:10] == "04":
7953 raise Exception("Unexpected EAP-Failure with valid scalar")
7954 if not valid_scalar and req[8:10] != "04":
7955 raise Exception("No EAP-Failure to reject invalid scalar")
7956 dev[0].request("REMOVE_NETWORK all")
7957 dev[0].wait_disconnected(timeout=1)
7958 hapd.disable()
7959
7960 def test_eap_proto_pwd_invalid_element_peer(dev, apdev):
7961 """EAP-pwd protocol tests - invalid peer element"""
7962 # Invalid x,y coordinates
7963 run_eap_proto_pwd_invalid_element_peer(dev, apdev, 64*'00')
7964 run_eap_proto_pwd_invalid_element_peer(dev, apdev, 32*'00' + 32*'01')
7965 run_eap_proto_pwd_invalid_element_peer(dev, apdev, 32*'01' + 32*'00')
7966 run_eap_proto_pwd_invalid_element_peer(dev, apdev, 32*'ff' + 32*'01')
7967 run_eap_proto_pwd_invalid_element_peer(dev, apdev, 32*'01' + 32*'ff')
7968 run_eap_proto_pwd_invalid_element_peer(dev, apdev, 64*'ff')
7969 # Not on curve
7970 run_eap_proto_pwd_invalid_element_peer(dev, apdev, 64*'01')
7971
7972 def run_eap_proto_pwd_invalid_element_peer(dev, apdev, element):
7973 hapd = start_pwd_exchange(dev[0], apdev[0])
7974 proxy_msg(hapd, dev[0]) # EAP-pwd-Commit/Request
7975
7976 # EAP-pwd-Commit/Response
7977 resp = rx_msg(dev[0])
7978 # Replace element with an invalid value
7979 msg = resp[0:20] + element + resp[148:]
7980 tx_msg(dev[0], hapd, msg)
7981
7982 # EAP-pwd-Commit/Response or EAP-Failure
7983 req = rx_msg(hapd)
7984 if req[8:10] != "04":
7985 raise Exception("No EAP-Failure to reject invalid element")
7986 dev[0].request("REMOVE_NETWORK all")
7987 dev[0].wait_disconnected(timeout=1)
7988 hapd.disable()
7989
7990 def test_eap_proto_pwd_errors(dev, apdev):
7991 """EAP-pwd local error cases"""
7992 check_eap_capa(dev[0], "PWD")
7993 params = hostapd.wpa2_eap_params(ssid="eap-test")
7994 hapd = hostapd.add_ap(apdev[0], params)
7995 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
7996
7997 for i in range(1, 4):
7998 with alloc_fail(dev[0], i, "eap_pwd_init"):
7999 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8000 eap="PWD", identity="pwd user",
8001 password="secret password",
8002 wait_connect=False)
8003 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
8004 timeout=15)
8005 if ev is None:
8006 raise Exception("Timeout on EAP start")
8007 dev[0].request("REMOVE_NETWORK all")
8008 dev[0].wait_disconnected()
8009
8010 with alloc_fail(dev[0], 1, "eap_pwd_get_session_id"):
8011 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8012 eap="PWD", identity="pwd user",
8013 fragment_size="0",
8014 password="secret password")
8015 dev[0].request("REMOVE_NETWORK all")
8016 dev[0].wait_disconnected()
8017
8018 funcs = ["eap_pwd_getkey", "eap_pwd_get_emsk",
8019 "=wpabuf_alloc;eap_pwd_perform_commit_exchange",
8020 "=wpabuf_alloc;eap_pwd_perform_confirm_exchange"]
8021 for func in funcs:
8022 with alloc_fail(dev[0], 1, func):
8023 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8024 eap="PWD", identity="pwd user@domain",
8025 password="secret password", erp="1",
8026 wait_connect=False)
8027 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
8028 dev[0].request("REMOVE_NETWORK all")
8029 dev[0].wait_disconnected()
8030
8031 for i in range(1, 5):
8032 with alloc_fail(dev[0], i, "eap_pwd_perform_id_exchange"):
8033 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8034 eap="PWD", identity="pwd user",
8035 password="secret password",
8036 wait_connect=False)
8037 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
8038 timeout=15)
8039 if ev is None:
8040 raise Exception("Timeout on EAP start")
8041 ok = False
8042 for j in range(10):
8043 state = dev[0].request('GET_ALLOC_FAIL')
8044 if state.startswith('0:'):
8045 ok = True
8046 break
8047 time.sleep(0.1)
8048 if not ok:
8049 raise Exception("No allocation failure seen")
8050 dev[0].request("REMOVE_NETWORK all")
8051 dev[0].wait_disconnected()
8052
8053 with alloc_fail(dev[0], 1, "wpabuf_alloc;eap_pwd_perform_id_exchange"):
8054 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8055 eap="PWD", identity="pwd user",
8056 password="secret password",
8057 wait_connect=False)
8058 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
8059 timeout=15)
8060 if ev is None:
8061 raise Exception("Timeout on EAP start")
8062 dev[0].request("REMOVE_NETWORK all")
8063 dev[0].wait_disconnected()
8064
8065 for i in range(1, 9):
8066 with alloc_fail(dev[0], i, "eap_pwd_perform_commit_exchange"):
8067 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8068 eap="PWD", identity="pwd user",
8069 password="secret password",
8070 wait_connect=False)
8071 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
8072 timeout=15)
8073 if ev is None:
8074 raise Exception("Timeout on EAP start")
8075 ok = False
8076 for j in range(10):
8077 state = dev[0].request('GET_ALLOC_FAIL')
8078 if state.startswith('0:'):
8079 ok = True
8080 break
8081 time.sleep(0.1)
8082 if not ok:
8083 raise Exception("No allocation failure seen")
8084 dev[0].request("REMOVE_NETWORK all")
8085 dev[0].wait_disconnected()
8086
8087 for i in range(1, 12):
8088 with alloc_fail(dev[0], i, "eap_pwd_perform_confirm_exchange"):
8089 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8090 eap="PWD", identity="pwd user",
8091 password="secret password",
8092 wait_connect=False)
8093 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
8094 timeout=15)
8095 if ev is None:
8096 raise Exception("Timeout on EAP start")
8097 ok = False
8098 for j in range(10):
8099 state = dev[0].request('GET_ALLOC_FAIL')
8100 if state.startswith('0:'):
8101 ok = True
8102 break
8103 time.sleep(0.1)
8104 if not ok:
8105 raise Exception("No allocation failure seen")
8106 dev[0].request("REMOVE_NETWORK all")
8107 dev[0].wait_disconnected()
8108
8109 for i in range(1, 5):
8110 with alloc_fail(dev[0], i, "eap_msg_alloc;=eap_pwd_process"):
8111 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8112 eap="PWD", identity="pwd user",
8113 password="secret password", fragment_size="50",
8114 wait_connect=False)
8115 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
8116 timeout=15)
8117 if ev is None:
8118 raise Exception("Timeout on EAP start")
8119 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
8120 dev[0].request("REMOVE_NETWORK all")
8121 dev[0].wait_disconnected()
8122
8123 # No password configured
8124 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8125 eap="PWD", identity="pwd user",
8126 wait_connect=False)
8127 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD vendor=0 method=52"],
8128 timeout=15)
8129 if ev is None:
8130 raise Exception("EAP-pwd not started")
8131 dev[0].request("REMOVE_NETWORK all")
8132 dev[0].wait_disconnected()
8133
8134 funcs = [(1, "hash_nt_password_hash;eap_pwd_perform_commit_exchange"),
8135 (1, "=crypto_bignum_init;eap_pwd_perform_commit_exchange"),
8136 (1, "=crypto_ec_point_init;eap_pwd_perform_commit_exchange"),
8137 (2, "=crypto_ec_point_init;eap_pwd_perform_commit_exchange"),
8138 (1, "=crypto_ec_point_mul;eap_pwd_perform_commit_exchange"),
8139 (2, "=crypto_ec_point_mul;eap_pwd_perform_commit_exchange"),
8140 (3, "=crypto_ec_point_mul;eap_pwd_perform_commit_exchange"),
8141 (1, "=crypto_ec_point_add;eap_pwd_perform_commit_exchange"),
8142 (1, "=crypto_ec_point_invert;eap_pwd_perform_commit_exchange"),
8143 (1, "=crypto_ec_point_to_bin;eap_pwd_perform_commit_exchange"),
8144 (1, "crypto_hash_finish;eap_pwd_kdf"),
8145 (1, "crypto_ec_point_from_bin;eap_pwd_get_element"),
8146 (3, "crypto_bignum_init;compute_password_element"),
8147 (4, "crypto_bignum_init;compute_password_element"),
8148 (1, "crypto_bignum_init_set;compute_password_element"),
8149 (2, "crypto_bignum_init_set;compute_password_element"),
8150 (3, "crypto_bignum_init_set;compute_password_element"),
8151 (1, "crypto_bignum_to_bin;compute_password_element"),
8152 (1, "crypto_ec_point_compute_y_sqr;compute_password_element"),
8153 (1, "crypto_ec_point_solve_y_coord;compute_password_element"),
8154 (1, "crypto_bignum_rand;compute_password_element"),
8155 (1, "crypto_bignum_sub;compute_password_element")]
8156 for count, func in funcs:
8157 with fail_test(dev[0], count, func):
8158 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8159 eap="PWD", identity="pwd-hash",
8160 password_hex="hash:e3718ece8ab74792cbbfffd316d2d19a",
8161 wait_connect=False)
8162 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
8163 if ev is None:
8164 raise Exception("No EAP-Failure reported")
8165 dev[0].request("REMOVE_NETWORK all")
8166 dev[0].wait_disconnected()
8167
8168 params = {"ssid": "eap-test2", "wpa": "2", "wpa_key_mgmt": "WPA-EAP",
8169 "rsn_pairwise": "CCMP", "ieee8021x": "1",
8170 "eap_server": "1", "eap_user_file": "auth_serv/eap_user.conf",
8171 "pwd_group": "19", "fragment_size": "40"}
8172 hapd2 = hostapd.add_ap(apdev[1], params)
8173 dev[0].scan_for_bss(hapd2.own_addr(), freq=2412)
8174
8175 with alloc_fail(dev[0], 1, "wpabuf_alloc;=eap_pwd_process"):
8176 dev[0].connect("eap-test2", key_mgmt="WPA-EAP", scan_freq="2412",
8177 eap="PWD", identity="pwd user",
8178 password="secret password",
8179 wait_connect=False)
8180 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
8181 dev[0].request("REMOVE_NETWORK all")
8182 dev[0].wait_disconnected()
8183
8184 for i in range(1, 5):
8185 with fail_test(dev[0], i,
8186 "=crypto_ec_point_to_bin;eap_pwd_perform_confirm_exchange"):
8187 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8188 eap="PWD", identity="pwd-hash",
8189 password_hex="hash:e3718ece8ab74792cbbfffd316d2d19a",
8190 wait_connect=False)
8191 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
8192 if ev is None:
8193 raise Exception("No EAP-Failure reported")
8194 dev[0].request("REMOVE_NETWORK all")
8195 dev[0].wait_disconnected()
8196 dev[0].dump_monitor()
8197
8198 def run_eap_pwd_connect(dev, hash=True, fragment=2000):
8199 if hash:
8200 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP",
8201 fragment_size=str(fragment),
8202 eap="PWD", identity="pwd-hash",
8203 password_hex="hash:e3718ece8ab74792cbbfffd316d2d19a",
8204 scan_freq="2412", wait_connect=False)
8205 else:
8206 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP",
8207 fragment_size=str(fragment),
8208 eap="PWD", identity="pwd-hash-sha1",
8209 password="secret password",
8210 scan_freq="2412", wait_connect=False)
8211 ev = dev.wait_event(["CTRL-EVENT-EAP-SUCCESS", "CTRL-EVENT-EAP-FAILURE",
8212 "CTRL-EVENT-DISCONNECTED"],
8213 timeout=1)
8214 dev.request("REMOVE_NETWORK all")
8215 if not ev or "CTRL-EVENT-DISCONNECTED" not in ev:
8216 dev.wait_disconnected()
8217 dev.dump_monitor()
8218
8219 def test_eap_proto_pwd_errors_server(dev, apdev):
8220 """EAP-pwd local error cases on server"""
8221 check_eap_capa(dev[0], "PWD")
8222 params = int_eap_server_params()
8223 params['erp_domain'] = 'example.com'
8224 params['eap_server_erp'] = '1'
8225 hapd = hostapd.add_ap(apdev[0], params)
8226 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
8227
8228 tests = [(1, "eap_pwd_init"),
8229 (2, "eap_pwd_init"),
8230 (3, "eap_pwd_init"),
8231 (1, "eap_pwd_build_id_req"),
8232 (1, "eap_pwd_build_commit_req"),
8233 (1, "eap_pwd_build_confirm_req"),
8234 (1, "eap_pwd_h_init;eap_pwd_build_confirm_req"),
8235 (1, "wpabuf_alloc;eap_pwd_build_confirm_req"),
8236 (1, "eap_msg_alloc;eap_pwd_build_req"),
8237 (1, "eap_pwd_process_id_resp"),
8238 (1, "get_eap_pwd_group;eap_pwd_process_id_resp"),
8239 (1, "eap_pwd_process_confirm_resp"),
8240 (1, "eap_pwd_h_init;eap_pwd_process_confirm_resp"),
8241 (1, "compute_keys;eap_pwd_process_confirm_resp"),
8242 (1, "eap_pwd_getkey"),
8243 (1, "eap_pwd_get_emsk"),
8244 (1, "eap_pwd_get_session_id")]
8245 for count, func in tests:
8246 with alloc_fail(hapd, count, func):
8247 run_eap_pwd_connect(dev[0], hash=True)
8248
8249 tests = [(1, "eap_msg_alloc;eap_pwd_build_req"),
8250 (2, "eap_msg_alloc;eap_pwd_build_req"),
8251 (1, "wpabuf_alloc;eap_pwd_process")]
8252 for count, func in tests:
8253 with alloc_fail(hapd, count, func):
8254 run_eap_pwd_connect(dev[0], hash=True, fragment=13)
8255
8256 tests = [(4, "eap_pwd_init")]
8257 for count, func in tests:
8258 with alloc_fail(hapd, count, func):
8259 run_eap_pwd_connect(dev[0], hash=False)
8260
8261 tests = [(1, "eap_pwd_build_id_req"),
8262 (1, "eap_pwd_build_commit_req"),
8263 (1, "crypto_ec_point_mul;eap_pwd_build_commit_req"),
8264 (1, "crypto_ec_point_invert;eap_pwd_build_commit_req"),
8265 (1, "crypto_ec_point_to_bin;eap_pwd_build_commit_req"),
8266 (1, "crypto_ec_point_to_bin;eap_pwd_build_confirm_req"),
8267 (2, "=crypto_ec_point_to_bin;eap_pwd_build_confirm_req"),
8268 (1, "hash_nt_password_hash;eap_pwd_process_id_resp"),
8269 (1, "compute_password_element;eap_pwd_process_id_resp"),
8270 (1, "crypto_bignum_init;eap_pwd_process_commit_resp"),
8271 (1, "crypto_ec_point_mul;eap_pwd_process_commit_resp"),
8272 (2, "crypto_ec_point_mul;eap_pwd_process_commit_resp"),
8273 (1, "crypto_ec_point_add;eap_pwd_process_commit_resp"),
8274 (1, "crypto_ec_point_to_bin;eap_pwd_process_confirm_resp"),
8275 (2, "=crypto_ec_point_to_bin;eap_pwd_process_confirm_resp")]
8276 for count, func in tests:
8277 with fail_test(hapd, count, func):
8278 run_eap_pwd_connect(dev[0], hash=True)
8279
8280 def start_pwd_assoc(dev, hapd):
8281 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP",
8282 eap="PWD", identity="pwd user", password="secret password",
8283 wait_connect=False, scan_freq="2412")
8284 proxy_msg(hapd, dev) # EAP-Identity/Request
8285 proxy_msg(dev, hapd) # EAP-Identity/Response
8286 proxy_msg(hapd, dev) # EAP-pwd-Identity/Request
8287
8288 def stop_pwd_assoc(dev, hapd):
8289 dev.request("REMOVE_NETWORK all")
8290 dev.wait_disconnected()
8291 dev.dump_monitor()
8292 hapd.dump_monitor()
8293
8294 def test_eap_proto_pwd_server(dev, apdev):
8295 """EAP-pwd protocol testing for the server"""
8296 check_eap_capa(dev[0], "PWD")
8297 params = int_eap_server_params()
8298 hapd = hostapd.add_ap(apdev[0], params)
8299 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
8300 hapd.request("SET ext_eapol_frame_io 1")
8301 dev[0].request("SET ext_eapol_frame_io 1")
8302
8303 start_pwd_assoc(dev[0], hapd)
8304 resp = rx_msg(dev[0])
8305 # Replace exch field with unexpected value
8306 # --> EAP-pwd: Unexpected opcode=4 in state=0
8307 msg = resp[0:18] + "04" + resp[20:]
8308 tx_msg(dev[0], hapd, msg)
8309
8310 # Too short EAP-pwd header (no flags/exch field)
8311 # --> EAP-pwd: Invalid frame
8312 msg = resp[0:4] + "0005" + resp[8:12] + "0005" + "34"
8313 tx_msg(dev[0], hapd, msg)
8314
8315 # Too short EAP-pwd header (L=1 but only one octet of total length field)
8316 # --> EAP-pwd: Frame too short to contain Total-Length field
8317 msg = resp[0:4] + "0007" + resp[8:12] + "0007" + "34" + "81ff"
8318 tx_msg(dev[0], hapd, msg)
8319 # server continues exchange, so start from scratch for the next step
8320 rx_msg(hapd)
8321 stop_pwd_assoc(dev[0], hapd)
8322
8323 start_pwd_assoc(dev[0], hapd)
8324 resp = rx_msg(dev[0])
8325 # Too large total length
8326 msg = resp[0:4] + "0008" + resp[8:12] + "0008" + "34" + "c1ffff"
8327 tx_msg(dev[0], hapd, msg)
8328 # server continues exchange, so start from scratch for the next step
8329 rx_msg(hapd)
8330 stop_pwd_assoc(dev[0], hapd)
8331
8332 start_pwd_assoc(dev[0], hapd)
8333 resp = rx_msg(dev[0])
8334 # First fragment
8335 msg = resp[0:4] + "0009" + resp[8:12] + "0009" + "34" + "c100ff" + "aa"
8336 tx_msg(dev[0], hapd, msg)
8337 # Ack
8338 req = rx_msg(hapd)
8339 # Unexpected first fragment
8340 # --> EAP-pwd: Unexpected new fragment start when previous fragment is still in use
8341 msg = resp[0:4] + "0009" + resp[8:10] + req[10:12] + "0009" + "34" + "c100ee" + "bb"
8342 tx_msg(dev[0], hapd, msg)
8343 # server continues exchange, so start from scratch for the next step
8344 rx_msg(hapd)
8345 stop_pwd_assoc(dev[0], hapd)
8346
8347 start_pwd_assoc(dev[0], hapd)
8348 resp = rx_msg(dev[0])
8349 # Too much data in first fragment
8350 # --> EAP-pwd: Buffer overflow attack detected! (0+2 > 1)
8351 msg = resp[0:4] + "000a" + resp[8:12] + "000a" + "34" + "c10001" + "aabb"
8352 tx_msg(dev[0], hapd, msg)
8353 # EAP-Failure
8354 rx_msg(hapd)
8355 stop_pwd_assoc(dev[0], hapd)
8356
8357 start_pwd_assoc(dev[0], hapd)
8358 resp = rx_msg(dev[0])
8359 # Change parameters
8360 # --> EAP-pwd: peer changed parameters
8361 msg = resp[0:20] + "ff" + resp[22:]
8362 tx_msg(dev[0], hapd, msg)
8363 # EAP-Failure
8364 rx_msg(hapd)
8365 stop_pwd_assoc(dev[0], hapd)
8366
8367 start_pwd_assoc(dev[0], hapd)
8368 resp = rx_msg(dev[0])
8369 # Too short ID response
8370 # --> EAP-pwd: Invalid ID response
8371 msg = resp[0:4] + "000a" + resp[8:12] + "000a" + "34" + "01ffeeddcc"
8372 tx_msg(dev[0], hapd, msg)
8373 # server continues exchange, so start from scratch for the next step
8374 rx_msg(hapd)
8375 stop_pwd_assoc(dev[0], hapd)
8376
8377 start_pwd_assoc(dev[0], hapd)
8378 # EAP-pwd-Identity/Response
8379 resp = rx_msg(dev[0])
8380 tx_msg(dev[0], hapd, resp)
8381 # EAP-pwd-Commit/Request
8382 req = rx_msg(hapd)
8383 # Unexpected EAP-pwd-Identity/Response
8384 # --> EAP-pwd: Unexpected opcode=1 in state=1
8385 msg = resp[0:10] + req[10:12] + resp[12:]
8386 tx_msg(dev[0], hapd, msg)
8387 # server continues exchange, so start from scratch for the next step
8388 rx_msg(hapd)
8389 stop_pwd_assoc(dev[0], hapd)
8390
8391 start_pwd_assoc(dev[0], hapd)
8392 proxy_msg(dev[0], hapd) # EAP-pwd-Identity/Response
8393 proxy_msg(hapd, dev[0]) # EAP-pwd-Commit/Request
8394 # EAP-pwd-Commit/Response
8395 resp = rx_msg(dev[0])
8396 # Too short Commit response
8397 # --> EAP-pwd: Unexpected Commit payload length 4 (expected 96)
8398 msg = resp[0:4] + "000a" + resp[8:12] + "000a" + "34" + "02ffeeddcc"
8399 tx_msg(dev[0], hapd, msg)
8400 # EAP-Failure
8401 rx_msg(hapd)
8402 stop_pwd_assoc(dev[0], hapd)
8403
8404 start_pwd_assoc(dev[0], hapd)
8405 proxy_msg(dev[0], hapd) # EAP-pwd-Identity/Response
8406 proxy_msg(hapd, dev[0]) # EAP-pwd-Commit/Request
8407 proxy_msg(dev[0], hapd) # EAP-pwd-Commit/Response
8408 proxy_msg(hapd, dev[0]) # EAP-pwd-Confirm/Request
8409 # EAP-pwd-Confirm/Response
8410 resp = rx_msg(dev[0])
8411 # Too short Confirm response
8412 # --> EAP-pwd: Unexpected Confirm payload length 4 (expected 32)
8413 msg = resp[0:4] + "000a" + resp[8:12] + "000a" + "34" + "03ffeeddcc"
8414 tx_msg(dev[0], hapd, msg)
8415 # EAP-Failure
8416 rx_msg(hapd)
8417 stop_pwd_assoc(dev[0], hapd)
8418
8419 start_pwd_assoc(dev[0], hapd)
8420 resp = rx_msg(dev[0])
8421 # Set M=1
8422 # --> EAP-pwd: No buffer for reassembly
8423 msg = resp[0:18] + "41" + resp[20:]
8424 tx_msg(dev[0], hapd, msg)
8425 # EAP-Failure
8426 rx_msg(hapd)
8427 stop_pwd_assoc(dev[0], hapd)
8428
8429 def test_eap_proto_erp(dev, apdev):
8430 """ERP protocol tests"""
8431 check_erp_capa(dev[0])
8432
8433 global eap_proto_erp_test_done
8434 eap_proto_erp_test_done = False
8435
8436 def erp_handler(ctx, req):
8437 logger.info("erp_handler - RX " + binascii.hexlify(req).decode())
8438 if 'num' not in ctx:
8439 ctx['num'] = 0
8440 ctx['num'] += 1
8441 if 'id' not in ctx:
8442 ctx['id'] = 1
8443 ctx['id'] = (ctx['id'] + 1) % 256
8444 idx = 0
8445
8446 idx += 1
8447 if ctx['num'] == idx:
8448 logger.info("Test: Missing type")
8449 return struct.pack(">BBH", EAP_CODE_INITIATE, ctx['id'], 4)
8450
8451 idx += 1
8452 if ctx['num'] == idx:
8453 logger.info("Test: Unexpected type")
8454 return struct.pack(">BBHB", EAP_CODE_INITIATE, ctx['id'], 4 + 1,
8455 255)
8456
8457 idx += 1
8458 if ctx['num'] == idx:
8459 logger.info("Test: Missing Reserved field")
8460 return struct.pack(">BBHB", EAP_CODE_INITIATE, ctx['id'], 4 + 1,
8461 EAP_ERP_TYPE_REAUTH_START)
8462
8463 idx += 1
8464 if ctx['num'] == idx:
8465 logger.info("Test: Zero-length TVs/TLVs")
8466 payload = b""
8467 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'],
8468 4 + 1 + 1 + len(payload),
8469 EAP_ERP_TYPE_REAUTH_START, 0) + payload
8470
8471 idx += 1
8472 if ctx['num'] == idx:
8473 logger.info("Test: Too short TLV")
8474 payload = struct.pack("B", 191)
8475 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'],
8476 4 + 1 + 1 + len(payload),
8477 EAP_ERP_TYPE_REAUTH_START, 0) + payload
8478
8479 idx += 1
8480 if ctx['num'] == idx:
8481 logger.info("Test: Truncated TLV")
8482 payload = struct.pack("BB", 191, 1)
8483 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'],
8484 4 + 1 + 1 + len(payload),
8485 EAP_ERP_TYPE_REAUTH_START, 0) + payload
8486
8487 idx += 1
8488 if ctx['num'] == idx:
8489 logger.info("Test: Ignored unknown TLV and unknown TV/TLV terminating parsing")
8490 payload = struct.pack("BBB", 191, 0, 192)
8491 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'],
8492 4 + 1 + 1 + len(payload),
8493 EAP_ERP_TYPE_REAUTH_START, 0) + payload
8494
8495 idx += 1
8496 if ctx['num'] == idx:
8497 logger.info("Test: More than one keyName-NAI")
8498 payload = struct.pack("BBBB", EAP_ERP_TLV_KEYNAME_NAI, 0,
8499 EAP_ERP_TLV_KEYNAME_NAI, 0)
8500 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'],
8501 4 + 1 + 1 + len(payload),
8502 EAP_ERP_TYPE_REAUTH_START, 0) + payload
8503
8504 idx += 1
8505 if ctx['num'] == idx:
8506 logger.info("Test: Too short TLV keyName-NAI")
8507 payload = struct.pack("B", EAP_ERP_TLV_KEYNAME_NAI)
8508 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'],
8509 4 + 1 + 1 + len(payload),
8510 EAP_ERP_TYPE_REAUTH_START, 0) + payload
8511
8512 idx += 1
8513 if ctx['num'] == idx:
8514 logger.info("Test: Truncated TLV keyName-NAI")
8515 payload = struct.pack("BB", EAP_ERP_TLV_KEYNAME_NAI, 1)
8516 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'],
8517 4 + 1 + 1 + len(payload),
8518 EAP_ERP_TYPE_REAUTH_START, 0) + payload
8519
8520 idx += 1
8521 if ctx['num'] == idx:
8522 logger.info("Test: Valid rRK lifetime TV followed by too short rMSK lifetime TV")
8523 payload = struct.pack(">BLBH", EAP_ERP_TV_RRK_LIFETIME, 0,
8524 EAP_ERP_TV_RMSK_LIFETIME, 0)
8525 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'],
8526 4 + 1 + 1 + len(payload),
8527 EAP_ERP_TYPE_REAUTH_START, 0) + payload
8528
8529 idx += 1
8530 if ctx['num'] == idx:
8531 logger.info("Test: Missing type (Finish)")
8532 return struct.pack(">BBH", EAP_CODE_FINISH, ctx['id'], 4)
8533
8534 idx += 1
8535 if ctx['num'] == idx:
8536 logger.info("Test: Unexpected type (Finish)")
8537 return struct.pack(">BBHB", EAP_CODE_FINISH, ctx['id'], 4 + 1,
8538 255)
8539
8540 idx += 1
8541 if ctx['num'] == idx:
8542 logger.info("Test: Missing fields (Finish)")
8543 return struct.pack(">BBHB", EAP_CODE_FINISH, ctx['id'], 4 + 1,
8544 EAP_ERP_TYPE_REAUTH)
8545
8546 idx += 1
8547 if ctx['num'] == idx:
8548 logger.info("Test: Unexpected SEQ (Finish)")
8549 return struct.pack(">BBHBBHB", EAP_CODE_FINISH, ctx['id'],
8550 4 + 1 + 4,
8551 EAP_ERP_TYPE_REAUTH, 0, 0xffff, 0)
8552
8553 logger.info("No more test responses available - test case completed")
8554 global eap_proto_erp_test_done
8555 eap_proto_erp_test_done = True
8556 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
8557
8558 srv = start_radius_server(erp_handler)
8559
8560 try:
8561 hapd = start_ap(apdev[0])
8562 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
8563
8564 i = 0
8565 while not eap_proto_erp_test_done:
8566 i += 1
8567 logger.info("Running connection iteration %d" % i)
8568 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8569 eap="PAX", identity="pax.user@example.com",
8570 password_hex="0123456789abcdef0123456789abcdef",
8571 wait_connect=False)
8572 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
8573 if ev is None:
8574 raise Exception("Timeout on EAP start")
8575 time.sleep(0.1)
8576 dev[0].request("REMOVE_NETWORK all")
8577 dev[0].wait_disconnected(timeout=1)
8578 dev[0].dump_monitor()
8579 finally:
8580 stop_radius_server(srv)
8581
8582 def test_eap_proto_fast_errors(dev, apdev):
8583 """EAP-FAST local error cases"""
8584 check_eap_capa(dev[0], "FAST")
8585 params = hostapd.wpa2_eap_params(ssid="eap-test")
8586 hapd = hostapd.add_ap(apdev[0], params)
8587 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
8588
8589 for i in range(1, 5):
8590 with alloc_fail(dev[0], i, "eap_fast_init"):
8591 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8592 eap="FAST", anonymous_identity="FAST",
8593 identity="user", password="password",
8594 ca_cert="auth_serv/ca.pem", phase2="auth=GTC",
8595 phase1="fast_provisioning=2",
8596 pac_file="blob://fast_pac_auth",
8597 wait_connect=False)
8598 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
8599 timeout=5)
8600 if ev is None:
8601 raise Exception("Timeout on EAP start")
8602 dev[0].request("REMOVE_NETWORK all")
8603 dev[0].wait_disconnected()
8604
8605 tests = [(1, "wpabuf_alloc;eap_fast_tlv_eap_payload"),
8606 (1, "eap_fast_derive_key;eap_fast_derive_key_auth"),
8607 (1, "eap_msg_alloc;eap_peer_tls_phase2_nak"),
8608 (1, "wpabuf_alloc;eap_fast_tlv_result"),
8609 (1, "wpabuf_alloc;eap_fast_tlv_pac_ack"),
8610 (1, "=eap_peer_tls_derive_session_id;eap_fast_process_crypto_binding"),
8611 (1, "eap_peer_tls_decrypt;eap_fast_decrypt"),
8612 (1, "eap_fast_getKey"),
8613 (1, "eap_fast_get_session_id"),
8614 (1, "eap_fast_get_emsk")]
8615 for count, func in tests:
8616 dev[0].request("SET blob fast_pac_auth_errors ")
8617 with alloc_fail(dev[0], count, func):
8618 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8619 eap="FAST", anonymous_identity="FAST",
8620 identity="user@example.com", password="password",
8621 ca_cert="auth_serv/ca.pem", phase2="auth=GTC",
8622 phase1="fast_provisioning=2",
8623 pac_file="blob://fast_pac_auth_errors",
8624 erp="1",
8625 wait_connect=False)
8626 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
8627 timeout=15)
8628 if ev is None:
8629 raise Exception("Timeout on EAP start")
8630 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
8631 dev[0].request("REMOVE_NETWORK all")
8632 dev[0].wait_disconnected()
8633
8634 tests = [(1, "eap_fast_derive_key;eap_fast_derive_key_provisioning"),
8635 (1, "eap_mschapv2_getKey;eap_fast_get_phase2_key"),
8636 (1, "=eap_fast_use_pac_opaque"),
8637 (1, "eap_fast_copy_buf"),
8638 (1, "=eap_fast_add_pac"),
8639 (1, "=eap_fast_init_pac_data"),
8640 (1, "=eap_fast_write_pac"),
8641 (2, "=eap_fast_write_pac")]
8642 for count, func in tests:
8643 dev[0].request("SET blob fast_pac_errors ")
8644 with alloc_fail(dev[0], count, func):
8645 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8646 eap="FAST", anonymous_identity="FAST",
8647 identity="user", password="password",
8648 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
8649 phase1="fast_provisioning=1",
8650 pac_file="blob://fast_pac_errors",
8651 erp="1",
8652 wait_connect=False)
8653 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
8654 timeout=15)
8655 if ev is None:
8656 raise Exception("Timeout on EAP start")
8657 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
8658 dev[0].request("REMOVE_NETWORK all")
8659 dev[0].wait_disconnected()
8660
8661 tests = [(1, "eap_fast_get_cmk;eap_fast_process_crypto_binding"),
8662 (1, "eap_fast_derive_eap_msk;eap_fast_process_crypto_binding"),
8663 (1, "eap_fast_derive_eap_emsk;eap_fast_process_crypto_binding")]
8664 for count, func in tests:
8665 dev[0].request("SET blob fast_pac_auth_errors ")
8666 with fail_test(dev[0], count, func):
8667 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8668 eap="FAST", anonymous_identity="FAST",
8669 identity="user", password="password",
8670 ca_cert="auth_serv/ca.pem", phase2="auth=GTC",
8671 phase1="fast_provisioning=2",
8672 pac_file="blob://fast_pac_auth_errors",
8673 erp="1",
8674 wait_connect=False)
8675 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
8676 timeout=15)
8677 if ev is None:
8678 raise Exception("Timeout on EAP start")
8679 wait_fail_trigger(dev[0], "GET_FAIL")
8680 dev[0].request("REMOVE_NETWORK all")
8681 dev[0].wait_disconnected()
8682
8683 dev[0].request("SET blob fast_pac_errors ")
8684 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8685 eap="FAST", anonymous_identity="FAST",
8686 identity="user", password="password",
8687 ca_cert="auth_serv/ca.pem", phase2="auth=GTC",
8688 phase1="fast_provisioning=1",
8689 pac_file="blob://fast_pac_errors",
8690 wait_connect=False)
8691 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5)
8692 if ev is None:
8693 raise Exception("Timeout on EAP start")
8694 # EAP-FAST: Only EAP-MSCHAPv2 is allowed during unauthenticated
8695 # provisioning; reject phase2 type 6
8696 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
8697 if ev is None:
8698 raise Exception("Timeout on EAP failure")
8699 dev[0].request("REMOVE_NETWORK all")
8700 dev[0].wait_disconnected()
8701
8702 logger.info("Wrong password in Phase 2")
8703 dev[0].request("SET blob fast_pac_errors ")
8704 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8705 eap="FAST", anonymous_identity="FAST",
8706 identity="user", password="wrong password",
8707 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
8708 phase1="fast_provisioning=1",
8709 pac_file="blob://fast_pac_errors",
8710 wait_connect=False)
8711 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5)
8712 if ev is None:
8713 raise Exception("Timeout on EAP start")
8714 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
8715 if ev is None:
8716 raise Exception("Timeout on EAP failure")
8717 dev[0].request("REMOVE_NETWORK all")
8718 dev[0].wait_disconnected()
8719
8720 tests = ["FOOBAR\n",
8721 "wpa_supplicant EAP-FAST PAC file - version 1\nFOOBAR\n",
8722 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\n",
8723 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nSTART\n",
8724 "wpa_supplicant EAP-FAST PAC file - version 1\nEND\n",
8725 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nPAC-Type=12345\nEND\n"
8726 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nPAC-Key=12\nEND\n",
8727 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nPAC-Key=1\nEND\n",
8728 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nPAC-Key=1q\nEND\n",
8729 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nPAC-Opaque=1\nEND\n",
8730 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nA-ID=1\nEND\n",
8731 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nI-ID=1\nEND\n",
8732 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nA-ID-Info=1\nEND\n"]
8733 for pac in tests:
8734 blob = binascii.hexlify(pac.encode()).decode()
8735 dev[0].request("SET blob fast_pac_errors " + blob)
8736 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8737 eap="FAST", anonymous_identity="FAST",
8738 identity="user", password="password",
8739 ca_cert="auth_serv/ca.pem", phase2="auth=GTC",
8740 phase1="fast_provisioning=2",
8741 pac_file="blob://fast_pac_errors",
8742 wait_connect=False)
8743 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
8744 timeout=5)
8745 if ev is None:
8746 raise Exception("Timeout on EAP start")
8747 dev[0].request("REMOVE_NETWORK all")
8748 dev[0].wait_disconnected()
8749
8750 tests = ["wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nEND\n",
8751 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nEND\nSTART\nEND\nSTART\nEND\n"]
8752 for pac in tests:
8753 blob = binascii.hexlify(pac.encode()).decode()
8754 dev[0].request("SET blob fast_pac_errors " + blob)
8755 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8756 eap="FAST", anonymous_identity="FAST",
8757 identity="user", password="password",
8758 ca_cert="auth_serv/ca.pem", phase2="auth=GTC",
8759 phase1="fast_provisioning=2",
8760 pac_file="blob://fast_pac_errors")
8761 dev[0].request("REMOVE_NETWORK all")
8762 dev[0].wait_disconnected()
8763
8764 dev[0].request("SET blob fast_pac_errors ")
8765
8766 def test_eap_proto_peap_errors_server(dev, apdev):
8767 """EAP-PEAP local error cases on server"""
8768 params = int_eap_server_params()
8769 hapd = hostapd.add_ap(apdev[0], params)
8770 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
8771
8772 tests = [(1, "get_asymetric_start_key;eap_mschapv2_getKey"),
8773 (1, "generate_authenticator_response_pwhash;eap_mschapv2_process_response"),
8774 (1, "hash_nt_password_hash;eap_mschapv2_process_response"),
8775 (1, "get_master_key;eap_mschapv2_process_response")]
8776 for count, func in tests:
8777 with fail_test(hapd, count, func):
8778 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP",
8779 scan_freq="2412",
8780 eap="PEAP", anonymous_identity="peap",
8781 identity="user", password="password",
8782 phase1="peapver=0 crypto_binding=2",
8783 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
8784 erp="1", wait_connect=False)
8785 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
8786 if ev is None:
8787 raise Exception("EAP-Failure not reported")
8788 dev[0].request("REMOVE_NETWORK all")
8789 dev[0].wait_disconnected()
8790
8791 def test_eap_proto_peap_errors(dev, apdev):
8792 """EAP-PEAP local error cases"""
8793 check_eap_capa(dev[0], "PEAP")
8794 check_eap_capa(dev[0], "MSCHAPV2")
8795 params = hostapd.wpa2_eap_params(ssid="eap-test")
8796 hapd = hostapd.add_ap(apdev[0], params)
8797 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
8798
8799 for i in range(1, 5):
8800 with alloc_fail(dev[0], i, "eap_peap_init"):
8801 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8802 eap="PEAP", anonymous_identity="peap",
8803 identity="user", password="password",
8804 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
8805 wait_connect=False)
8806 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
8807 timeout=5)
8808 if ev is None:
8809 raise Exception("Timeout on EAP start")
8810 dev[0].request("REMOVE_NETWORK all")
8811 dev[0].wait_disconnected()
8812
8813 tests = [(1, "eap_mschapv2_getKey;eap_peap_get_isk;eap_peap_derive_cmk"),
8814 (1, "eap_msg_alloc;eap_tlv_build_result"),
8815 (1, "eap_mschapv2_init;eap_peap_phase2_request"),
8816 (1, "eap_peer_tls_decrypt;eap_peap_decrypt"),
8817 (1, "wpabuf_alloc;=eap_peap_decrypt"),
8818 (1, "eap_peer_tls_encrypt;eap_peap_decrypt"),
8819 (1, "eap_peer_tls_process_helper;eap_peap_process"),
8820 (1, "eap_peer_tls_derive_key;eap_peap_process"),
8821 (1, "eap_peer_tls_derive_session_id;eap_peap_process"),
8822 (1, "eap_peap_getKey"),
8823 (1, "eap_peap_get_session_id")]
8824 for count, func in tests:
8825 with alloc_fail(dev[0], count, func):
8826 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8827 eap="PEAP", anonymous_identity="peap",
8828 identity="user", password="password",
8829 phase1="peapver=0 crypto_binding=2",
8830 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
8831 erp="1", wait_connect=False)
8832 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
8833 timeout=15)
8834 if ev is None:
8835 raise Exception("Timeout on EAP start")
8836 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
8837 dev[0].request("REMOVE_NETWORK all")
8838 dev[0].wait_disconnected()
8839
8840 tests = [(1, "peap_prfplus;eap_peap_derive_cmk"),
8841 (1, "eap_tlv_add_cryptobinding;eap_tlv_build_result"),
8842 (1, "peap_prfplus;eap_peap_getKey"),
8843 (1, "get_asymetric_start_key;eap_mschapv2_getKey")]
8844 for count, func in tests:
8845 with fail_test(dev[0], count, func):
8846 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8847 eap="PEAP", anonymous_identity="peap",
8848 identity="user", password="password",
8849 phase1="peapver=0 crypto_binding=2",
8850 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
8851 erp="1", wait_connect=False)
8852 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
8853 timeout=15)
8854 if ev is None:
8855 raise Exception("Timeout on EAP start")
8856 wait_fail_trigger(dev[0], "GET_FAIL")
8857 dev[0].request("REMOVE_NETWORK all")
8858 dev[0].wait_disconnected()
8859
8860 with alloc_fail(dev[0], 1,
8861 "eap_peer_tls_phase2_nak;eap_peap_phase2_request"):
8862 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8863 eap="PEAP", anonymous_identity="peap",
8864 identity="cert user", password="password",
8865 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
8866 wait_connect=False)
8867 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
8868 dev[0].request("REMOVE_NETWORK all")
8869 dev[0].wait_disconnected()
8870
8871 def test_eap_proto_ttls_errors(dev, apdev):
8872 """EAP-TTLS local error cases"""
8873 check_eap_capa(dev[0], "TTLS")
8874 check_eap_capa(dev[0], "MSCHAPV2")
8875 params = hostapd.wpa2_eap_params(ssid="eap-test")
8876 hapd = hostapd.add_ap(apdev[0], params)
8877 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
8878
8879 for i in range(1, 5):
8880 with alloc_fail(dev[0], i, "eap_ttls_init"):
8881 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8882 eap="TTLS", anonymous_identity="ttls",
8883 identity="user", password="password",
8884 ca_cert="auth_serv/ca.pem",
8885 phase2="autheap=MSCHAPV2",
8886 wait_connect=False)
8887 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
8888 timeout=5)
8889 if ev is None:
8890 raise Exception("Timeout on EAP start")
8891 dev[0].request("REMOVE_NETWORK all")
8892 dev[0].wait_disconnected()
8893
8894 tests = [(1, "eap_peer_tls_derive_key;eap_ttls_v0_derive_key",
8895 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"),
8896 (1, "eap_peer_tls_derive_session_id;eap_ttls_v0_derive_key",
8897 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"),
8898 (1, "wpabuf_alloc;eap_ttls_phase2_request_mschapv2",
8899 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"),
8900 (1, "eap_peer_tls_derive_key;eap_ttls_phase2_request_mschapv2",
8901 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"),
8902 (1, "eap_peer_tls_encrypt;eap_ttls_encrypt_response;eap_ttls_implicit_identity_request",
8903 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"),
8904 (1, "eap_peer_tls_decrypt;eap_ttls_decrypt",
8905 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"),
8906 (1, "eap_ttls_getKey",
8907 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"),
8908 (1, "eap_ttls_get_session_id",
8909 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"),
8910 (1, "eap_ttls_get_emsk",
8911 "mschapv2 user@domain", "auth=MSCHAPV2"),
8912 (1, "wpabuf_alloc;eap_ttls_phase2_request_mschap",
8913 "mschap user", "auth=MSCHAP"),
8914 (1, "eap_peer_tls_derive_key;eap_ttls_phase2_request_mschap",
8915 "mschap user", "auth=MSCHAP"),
8916 (1, "wpabuf_alloc;eap_ttls_phase2_request_chap",
8917 "chap user", "auth=CHAP"),
8918 (1, "eap_peer_tls_derive_key;eap_ttls_phase2_request_chap",
8919 "chap user", "auth=CHAP"),
8920 (1, "wpabuf_alloc;eap_ttls_phase2_request_pap",
8921 "pap user", "auth=PAP"),
8922 (1, "wpabuf_alloc;eap_ttls_avp_encapsulate",
8923 "user", "autheap=MSCHAPV2"),
8924 (1, "eap_mschapv2_init;eap_ttls_phase2_request_eap_method",
8925 "user", "autheap=MSCHAPV2"),
8926 (1, "eap_sm_buildIdentity;eap_ttls_phase2_request_eap",
8927 "user", "autheap=MSCHAPV2"),
8928 (1, "eap_ttls_avp_encapsulate;eap_ttls_phase2_request_eap",
8929 "user", "autheap=MSCHAPV2"),
8930 (1, "eap_ttls_parse_attr_eap",
8931 "user", "autheap=MSCHAPV2"),
8932 (1, "eap_peer_tls_encrypt;eap_ttls_encrypt_response;eap_ttls_process_decrypted",
8933 "user", "autheap=MSCHAPV2"),
8934 (1, "eap_ttls_fake_identity_request",
8935 "user", "autheap=MSCHAPV2"),
8936 (1, "eap_msg_alloc;eap_tls_process_output",
8937 "user", "autheap=MSCHAPV2"),
8938 (1, "eap_msg_alloc;eap_peer_tls_build_ack",
8939 "user", "autheap=MSCHAPV2"),
8940 (1, "tls_connection_decrypt;eap_peer_tls_decrypt",
8941 "user", "autheap=MSCHAPV2"),
8942 (1, "eap_peer_tls_phase2_nak;eap_ttls_phase2_request_eap_method",
8943 "cert user", "autheap=MSCHAPV2")]
8944 for count, func, identity, phase2 in tests:
8945 with alloc_fail(dev[0], count, func):
8946 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8947 eap="TTLS", anonymous_identity="ttls",
8948 identity=identity, password="password",
8949 ca_cert="auth_serv/ca.pem", phase2=phase2,
8950 erp="1", wait_connect=False)
8951 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
8952 timeout=15)
8953 if ev is None:
8954 raise Exception("Timeout on EAP start")
8955 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL",
8956 note="Allocation failure not triggered for: %d:%s" % (count, func))
8957 dev[0].request("REMOVE_NETWORK all")
8958 dev[0].wait_disconnected()
8959
8960 tests = [(1, "os_get_random;eap_ttls_phase2_request_mschapv2"),
8961 (1, "mschapv2_derive_response;eap_ttls_phase2_request_mschapv2")]
8962 for count, func in tests:
8963 with fail_test(dev[0], count, func):
8964 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8965 eap="TTLS", anonymous_identity="ttls",
8966 identity="DOMAIN\mschapv2 user", password="password",
8967 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
8968 erp="1", wait_connect=False)
8969 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
8970 timeout=15)
8971 if ev is None:
8972 raise Exception("Timeout on EAP start")
8973 wait_fail_trigger(dev[0], "GET_FAIL",
8974 note="Test failure not triggered for: %d:%s" % (count, func))
8975 dev[0].request("REMOVE_NETWORK all")
8976 dev[0].wait_disconnected()
8977
8978 tests = [(1, "nt_challenge_response;eap_ttls_phase2_request_mschap")]
8979 for count, func in tests:
8980 with fail_test(dev[0], count, func):
8981 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8982 eap="TTLS", anonymous_identity="ttls",
8983 identity="mschap user", password="password",
8984 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAP",
8985 erp="1", wait_connect=False)
8986 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
8987 timeout=15)
8988 if ev is None:
8989 raise Exception("Timeout on EAP start")
8990 wait_fail_trigger(dev[0], "GET_FAIL",
8991 note="Test failure not triggered for: %d:%s" % (count, func))
8992 dev[0].request("REMOVE_NETWORK all")
8993 dev[0].wait_disconnected()
8994
8995 def test_eap_proto_expanded(dev, apdev):
8996 """EAP protocol tests with expanded header"""
8997 global eap_proto_expanded_test_done
8998 eap_proto_expanded_test_done = False
8999
9000 def expanded_handler(ctx, req):
9001 logger.info("expanded_handler - RX " + binascii.hexlify(req).decode())
9002 if 'num' not in ctx:
9003 ctx['num'] = 0
9004 ctx['num'] += 1
9005 if 'id' not in ctx:
9006 ctx['id'] = 1
9007 ctx['id'] = (ctx['id'] + 1) % 256
9008 idx = 0
9009
9010 idx += 1
9011 if ctx['num'] == idx:
9012 logger.info("Test: MD5 challenge in expanded header")
9013 return struct.pack(">BBHB3BLBBB", EAP_CODE_REQUEST, ctx['id'],
9014 4 + 1 + 3 + 4 + 3,
9015 EAP_TYPE_EXPANDED, 0, 0, 0, EAP_TYPE_MD5,
9016 1, 0xaa, ord('n'))
9017 idx += 1
9018 if ctx['num'] == idx:
9019 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9020
9021 idx += 1
9022 if ctx['num'] == idx:
9023 logger.info("Test: Invalid expanded EAP length")
9024 return struct.pack(">BBHB3BH", EAP_CODE_REQUEST, ctx['id'],
9025 4 + 1 + 3 + 2,
9026 EAP_TYPE_EXPANDED, 0, 0, 0, EAP_TYPE_MD5)
9027 idx += 1
9028 if ctx['num'] == idx:
9029 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9030
9031 idx += 1
9032 if ctx['num'] == idx:
9033 logger.info("Test: Invalid expanded frame type")
9034 return struct.pack(">BBHB3BL", EAP_CODE_REQUEST, ctx['id'],
9035 4 + 1 + 3 + 4,
9036 EAP_TYPE_EXPANDED, 0, 0, 1, EAP_TYPE_MD5)
9037 idx += 1
9038 if ctx['num'] == idx:
9039 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9040
9041 idx += 1
9042 if ctx['num'] == idx:
9043 logger.info("Test: MSCHAPv2 Challenge")
9044 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
9045 4 + 1 + 4 + 1 + 16 + 6,
9046 EAP_TYPE_MSCHAPV2,
9047 1, 0, 4 + 1 + 16 + 6, 16) + 16*b'A' + b'foobar'
9048 idx += 1
9049 if ctx['num'] == idx:
9050 logger.info("Test: Invalid expanded frame type")
9051 return struct.pack(">BBHB3BL", EAP_CODE_REQUEST, ctx['id'],
9052 4 + 1 + 3 + 4,
9053 EAP_TYPE_EXPANDED, 0, 0, 1, EAP_TYPE_MSCHAPV2)
9054
9055 logger.info("No more test responses available - test case completed")
9056 global eap_proto_expanded_test_done
9057 eap_proto_expanded_test_done = True
9058 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9059
9060 srv = start_radius_server(expanded_handler)
9061
9062 try:
9063 hapd = start_ap(apdev[0])
9064 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
9065
9066 i = 0
9067 while not eap_proto_expanded_test_done:
9068 i += 1
9069 logger.info("Running connection iteration %d" % i)
9070 if i == 4:
9071 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
9072 eap="MSCHAPV2", identity="user",
9073 password="password",
9074 wait_connect=False)
9075 else:
9076 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
9077 eap="MD5", identity="user", password="password",
9078 wait_connect=False)
9079 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
9080 if ev is None:
9081 raise Exception("Timeout on EAP start")
9082 if i in [1]:
9083 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5)
9084 if ev is None:
9085 raise Exception("Timeout on EAP method start")
9086 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
9087 if ev is None:
9088 raise Exception("Timeout on EAP failure")
9089 elif i in [2, 3]:
9090 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
9091 timeout=5)
9092 if ev is None:
9093 raise Exception("Timeout on EAP proposed method")
9094 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
9095 if ev is None:
9096 raise Exception("Timeout on EAP failure")
9097 else:
9098 time.sleep(0.1)
9099 dev[0].request("REMOVE_NETWORK all")
9100 dev[0].wait_disconnected(timeout=1)
9101 dev[0].dump_monitor()
9102 finally:
9103 stop_radius_server(srv)
9104
9105 def test_eap_proto_tls(dev, apdev):
9106 """EAP-TLS protocol tests"""
9107 check_eap_capa(dev[0], "TLS")
9108 global eap_proto_tls_test_done, eap_proto_tls_test_wait
9109 eap_proto_tls_test_done = False
9110 eap_proto_tls_test_wait = False
9111
9112 def tls_handler(ctx, req):
9113 logger.info("tls_handler - RX " + binascii.hexlify(req).decode())
9114 if 'num' not in ctx:
9115 ctx['num'] = 0
9116 ctx['num'] += 1
9117 if 'id' not in ctx:
9118 ctx['id'] = 1
9119 ctx['id'] = (ctx['id'] + 1) % 256
9120 idx = 0
9121
9122 global eap_proto_tls_test_wait
9123
9124 idx += 1
9125 if ctx['num'] == idx:
9126 logger.info("Test: Too much payload in TLS/Start: TLS Message Length (0 bytes) smaller than this fragment (1 bytes)")
9127 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'],
9128 4 + 1 + 1 + 4 + 1,
9129 EAP_TYPE_TLS, 0xa0, 0, 1)
9130
9131 idx += 1
9132 if ctx['num'] == idx:
9133 logger.info("Test: Fragmented TLS/Start")
9134 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'],
9135 4 + 1 + 1 + 4 + 1,
9136 EAP_TYPE_TLS, 0xe0, 2, 1)
9137 idx += 1
9138 if ctx['num'] == idx:
9139 logger.info("Test: Too long fragment of TLS/Start: Invalid reassembly state: tls_in_left=2 tls_in_len=0 in_len=0")
9140 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
9141 4 + 1 + 1 + 2,
9142 EAP_TYPE_TLS, 0x00, 2, 3)
9143 idx += 1
9144 if ctx['num'] == idx:
9145 logger.info("Test: EAP-Failure")
9146 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9147
9148 idx += 1
9149 if ctx['num'] == idx:
9150 logger.info("Test: TLS/Start")
9151 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9152 4 + 1 + 1,
9153 EAP_TYPE_TLS, 0x20)
9154 idx += 1
9155 if ctx['num'] == idx:
9156 logger.info("Test: Fragmented TLS message")
9157 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'],
9158 4 + 1 + 1 + 4 + 1,
9159 EAP_TYPE_TLS, 0xc0, 2, 1)
9160 idx += 1
9161 if ctx['num'] == idx:
9162 logger.info("Test: Invalid TLS message: no Flags octet included + workaround")
9163 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
9164 4 + 1,
9165 EAP_TYPE_TLS)
9166 idx += 1
9167 if ctx['num'] == idx:
9168 logger.info("Test: Too long fragment of TLS message: more data than TLS message length indicated")
9169 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
9170 4 + 1 + 1 + 2,
9171 EAP_TYPE_TLS, 0x00, 2, 3)
9172 idx += 1
9173 if ctx['num'] == idx:
9174 logger.info("Test: EAP-Failure")
9175 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9176
9177 idx += 1
9178 if ctx['num'] == idx:
9179 logger.info("Test: Fragmented TLS/Start and truncated Message Length field")
9180 return struct.pack(">BBHBB3B", EAP_CODE_REQUEST, ctx['id'],
9181 4 + 1 + 1 + 3,
9182 EAP_TYPE_TLS, 0xe0, 1, 2, 3)
9183
9184 idx += 1
9185 if ctx['num'] == idx:
9186 logger.info("Test: TLS/Start")
9187 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9188 4 + 1 + 1,
9189 EAP_TYPE_TLS, 0x20)
9190 idx += 1
9191 if ctx['num'] == idx:
9192 logger.info("Test: Fragmented TLS message")
9193 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'],
9194 4 + 1 + 1 + 4 + 1,
9195 EAP_TYPE_TLS, 0xc0, 2, 1)
9196 idx += 1
9197 if ctx['num'] == idx:
9198 logger.info("Test: Invalid TLS message: no Flags octet included + workaround disabled")
9199 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
9200 4 + 1,
9201 EAP_TYPE_TLS)
9202
9203 idx += 1
9204 if ctx['num'] == idx:
9205 logger.info("Test: TLS/Start")
9206 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9207 4 + 1 + 1,
9208 EAP_TYPE_TLS, 0x20)
9209 idx += 1
9210 if ctx['num'] == idx:
9211 logger.info("Test: Fragmented TLS message (long; first)")
9212 payload = 1450*b'A'
9213 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'],
9214 4 + 1 + 1 + 4 + len(payload),
9215 EAP_TYPE_TLS, 0xc0, 65536) + payload
9216 # "Too long TLS fragment (size over 64 kB)" on the last one
9217 for i in range(44):
9218 idx += 1
9219 if ctx['num'] == idx:
9220 logger.info("Test: Fragmented TLS message (long; cont %d)" % i)
9221 eap_proto_tls_test_wait = True
9222 payload = 1470*b'A'
9223 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9224 4 + 1 + 1 + len(payload),
9225 EAP_TYPE_TLS, 0x40) + payload
9226 eap_proto_tls_test_wait = False
9227 idx += 1
9228 if ctx['num'] == idx:
9229 logger.info("Test: EAP-Failure")
9230 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9231
9232 idx += 1
9233 if ctx['num'] == idx:
9234 logger.info("Test: TLS/Start")
9235 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9236 4 + 1 + 1,
9237 EAP_TYPE_TLS, 0x20)
9238 idx += 1
9239 if ctx['num'] == idx:
9240 logger.info("Test: Non-ACK to more-fragment message")
9241 return struct.pack(">BBHBBB", EAP_CODE_REQUEST, ctx['id'],
9242 4 + 1 + 1 + 1,
9243 EAP_TYPE_TLS, 0x00, 255)
9244 idx += 1
9245 if ctx['num'] == idx:
9246 logger.info("Test: EAP-Failure")
9247 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9248
9249 logger.info("No more test responses available - test case completed")
9250 global eap_proto_tls_test_done
9251 eap_proto_tls_test_done = True
9252 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9253
9254 srv = start_radius_server(tls_handler)
9255
9256 try:
9257 hapd = start_ap(apdev[0])
9258 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
9259
9260 i = 0
9261 while not eap_proto_tls_test_done:
9262 i += 1
9263 logger.info("Running connection iteration %d" % i)
9264 workaround = "0" if i == 6 else "1"
9265 fragment_size = "100" if i == 8 else "1400"
9266 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
9267 eap="TLS", identity="tls user",
9268 ca_cert="auth_serv/ca.pem",
9269 client_cert="auth_serv/user.pem",
9270 private_key="auth_serv/user.key",
9271 eap_workaround=workaround,
9272 fragment_size=fragment_size,
9273 wait_connect=False)
9274 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
9275 if ev is None:
9276 raise Exception("Timeout on EAP start")
9277 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD",
9278 "CTRL-EVENT-EAP-STATUS"], timeout=5)
9279 if ev is None:
9280 raise Exception("Timeout on EAP method start")
9281 time.sleep(0.1)
9282 start = os.times()[4]
9283 while eap_proto_tls_test_wait:
9284 now = os.times()[4]
9285 if now - start > 10:
9286 break
9287 time.sleep(0.1)
9288 dev[0].request("REMOVE_NETWORK all")
9289 dev[0].wait_disconnected(timeout=1)
9290 dev[0].dump_monitor()
9291 finally:
9292 stop_radius_server(srv)
9293
9294 def test_eap_proto_tnc(dev, apdev):
9295 """EAP-TNC protocol tests"""
9296 check_eap_capa(dev[0], "TNC")
9297 global eap_proto_tnc_test_done
9298 eap_proto_tnc_test_done = False
9299
9300 def tnc_handler(ctx, req):
9301 logger.info("tnc_handler - RX " + binascii.hexlify(req).decode())
9302 if 'num' not in ctx:
9303 ctx['num'] = 0
9304 ctx['num'] += 1
9305 if 'id' not in ctx:
9306 ctx['id'] = 1
9307 ctx['id'] = (ctx['id'] + 1) % 256
9308 idx = 0
9309
9310 idx += 1
9311 if ctx['num'] == idx:
9312 logger.info("Test: TNC start with unsupported version")
9313 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9314 4 + 1 + 1,
9315 EAP_TYPE_TNC, 0x20)
9316
9317 idx += 1
9318 if ctx['num'] == idx:
9319 logger.info("Test: TNC without Flags field")
9320 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
9321 4 + 1,
9322 EAP_TYPE_TNC)
9323
9324 idx += 1
9325 if ctx['num'] == idx:
9326 logger.info("Test: Message underflow due to missing Message Length")
9327 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9328 4 + 1 + 1,
9329 EAP_TYPE_TNC, 0xa1)
9330
9331 idx += 1
9332 if ctx['num'] == idx:
9333 logger.info("Test: Invalid Message Length")
9334 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'],
9335 4 + 1 + 1 + 4 + 1,
9336 EAP_TYPE_TNC, 0xa1, 0, 0)
9337
9338 idx += 1
9339 if ctx['num'] == idx:
9340 logger.info("Test: Invalid Message Length")
9341 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'],
9342 4 + 1 + 1 + 4,
9343 EAP_TYPE_TNC, 0xe1, 75001)
9344
9345 idx += 1
9346 if ctx['num'] == idx:
9347 logger.info("Test: Start with Message Length")
9348 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'],
9349 4 + 1 + 1 + 4,
9350 EAP_TYPE_TNC, 0xa1, 1)
9351 idx += 1
9352 if ctx['num'] == idx:
9353 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9354
9355 idx += 1
9356 if ctx['num'] == idx:
9357 logger.info("Test: Server used start flag again")
9358 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9359 4 + 1 + 1,
9360 EAP_TYPE_TNC, 0x21)
9361 idx += 1
9362 if ctx['num'] == idx:
9363 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9364 4 + 1 + 1,
9365 EAP_TYPE_TNC, 0x21)
9366
9367 idx += 1
9368 if ctx['num'] == idx:
9369 logger.info("Test: Fragmentation and unexpected payload in ack")
9370 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9371 4 + 1 + 1,
9372 EAP_TYPE_TNC, 0x21)
9373 idx += 1
9374 if ctx['num'] == idx:
9375 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9376 4 + 1 + 1,
9377 EAP_TYPE_TNC, 0x01)
9378 idx += 1
9379 if ctx['num'] == idx:
9380 return struct.pack(">BBHBBB", EAP_CODE_REQUEST, ctx['id'],
9381 4 + 1 + 1 + 1,
9382 EAP_TYPE_TNC, 0x01, 0)
9383
9384 idx += 1
9385 if ctx['num'] == idx:
9386 logger.info("Test: Server fragmenting and fragment overflow")
9387 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'],
9388 4 + 1 + 1 + 4 + 1,
9389 EAP_TYPE_TNC, 0xe1, 2, 1)
9390 idx += 1
9391 if ctx['num'] == idx:
9392 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
9393 4 + 1 + 1 + 2,
9394 EAP_TYPE_TNC, 0x01, 2, 3)
9395
9396 idx += 1
9397 if ctx['num'] == idx:
9398 logger.info("Test: Server fragmenting and no message length in a fragment")
9399 return struct.pack(">BBHBBB", EAP_CODE_REQUEST, ctx['id'],
9400 4 + 1 + 1 + 1,
9401 EAP_TYPE_TNC, 0x61, 2)
9402
9403 idx += 1
9404 if ctx['num'] == idx:
9405 logger.info("Test: TNC start followed by invalid TNCCS-Batch")
9406 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9407 4 + 1 + 1,
9408 EAP_TYPE_TNC, 0x21)
9409 idx += 1
9410 if ctx['num'] == idx:
9411 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
9412 resp = b"FOO"
9413 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9414 4 + 1 + 1 + len(resp),
9415 EAP_TYPE_TNC, 0x01) + resp
9416
9417 idx += 1
9418 if ctx['num'] == idx:
9419 logger.info("Test: TNC start followed by invalid TNCCS-Batch (2)")
9420 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9421 4 + 1 + 1,
9422 EAP_TYPE_TNC, 0x21)
9423 idx += 1
9424 if ctx['num'] == idx:
9425 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
9426 resp = b"</TNCCS-Batch><TNCCS-Batch>"
9427 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9428 4 + 1 + 1 + len(resp),
9429 EAP_TYPE_TNC, 0x01) + resp
9430
9431 idx += 1
9432 if ctx['num'] == idx:
9433 logger.info("Test: TNCCS-Batch missing BatchId attribute")
9434 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9435 4 + 1 + 1,
9436 EAP_TYPE_TNC, 0x21)
9437 idx += 1
9438 if ctx['num'] == idx:
9439 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
9440 resp = b"<TNCCS-Batch foo=3></TNCCS-Batch>"
9441 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9442 4 + 1 + 1 + len(resp),
9443 EAP_TYPE_TNC, 0x01) + resp
9444
9445 idx += 1
9446 if ctx['num'] == idx:
9447 logger.info("Test: Unexpected IF-TNCCS BatchId")
9448 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9449 4 + 1 + 1,
9450 EAP_TYPE_TNC, 0x21)
9451 idx += 1
9452 if ctx['num'] == idx:
9453 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
9454 resp = b"<TNCCS-Batch BatchId=123456789></TNCCS-Batch>"
9455 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9456 4 + 1 + 1 + len(resp),
9457 EAP_TYPE_TNC, 0x01) + resp
9458
9459 idx += 1
9460 if ctx['num'] == idx:
9461 logger.info("Test: Missing IMC-IMV-Message and TNCC-TNCS-Message end tags")
9462 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9463 4 + 1 + 1,
9464 EAP_TYPE_TNC, 0x21)
9465 idx += 1
9466 if ctx['num'] == idx:
9467 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
9468 resp = b"<TNCCS-Batch BatchId=2><IMC-IMV-Message><TNCC-TNCS-Message></TNCCS-Batch>"
9469 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9470 4 + 1 + 1 + len(resp),
9471 EAP_TYPE_TNC, 0x01) + resp
9472 idx += 1
9473 if ctx['num'] == idx:
9474 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9475
9476 idx += 1
9477 if ctx['num'] == idx:
9478 logger.info("Test: Missing IMC-IMV-Message and TNCC-TNCS-Message Type")
9479 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9480 4 + 1 + 1,
9481 EAP_TYPE_TNC, 0x21)
9482 idx += 1
9483 if ctx['num'] == idx:
9484 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
9485 resp = b"<TNCCS-Batch BatchId=2><IMC-IMV-Message></IMC-IMV-Message><TNCC-TNCS-Message></TNCC-TNCS-Message></TNCCS-Batch>"
9486 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9487 4 + 1 + 1 + len(resp),
9488 EAP_TYPE_TNC, 0x01) + resp
9489 idx += 1
9490 if ctx['num'] == idx:
9491 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9492
9493 idx += 1
9494 if ctx['num'] == idx:
9495 logger.info("Test: Missing TNCC-TNCS-Message XML end tag")
9496 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9497 4 + 1 + 1,
9498 EAP_TYPE_TNC, 0x21)
9499 idx += 1
9500 if ctx['num'] == idx:
9501 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
9502 resp = b"<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type><XML></TNCC-TNCS-Message></TNCCS-Batch>"
9503 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9504 4 + 1 + 1 + len(resp),
9505 EAP_TYPE_TNC, 0x01) + resp
9506 idx += 1
9507 if ctx['num'] == idx:
9508 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9509
9510 idx += 1
9511 if ctx['num'] == idx:
9512 logger.info("Test: Missing TNCC-TNCS-Message Base64 start tag")
9513 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9514 4 + 1 + 1,
9515 EAP_TYPE_TNC, 0x21)
9516 idx += 1
9517 if ctx['num'] == idx:
9518 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
9519 resp = b"<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type></TNCC-TNCS-Message></TNCCS-Batch>"
9520 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9521 4 + 1 + 1 + len(resp),
9522 EAP_TYPE_TNC, 0x01) + resp
9523 idx += 1
9524 if ctx['num'] == idx:
9525 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9526
9527 idx += 1
9528 if ctx['num'] == idx:
9529 logger.info("Test: Missing TNCC-TNCS-Message Base64 end tag")
9530 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9531 4 + 1 + 1,
9532 EAP_TYPE_TNC, 0x21)
9533 idx += 1
9534 if ctx['num'] == idx:
9535 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
9536 resp = b"<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type><Base64>abc</TNCC-TNCS-Message></TNCCS-Batch>"
9537 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9538 4 + 1 + 1 + len(resp),
9539 EAP_TYPE_TNC, 0x01) + resp
9540 idx += 1
9541 if ctx['num'] == idx:
9542 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9543
9544 idx += 1
9545 if ctx['num'] == idx:
9546 logger.info("Test: TNCC-TNCS-Message Base64 message")
9547 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9548 4 + 1 + 1,
9549 EAP_TYPE_TNC, 0x21)
9550 idx += 1
9551 if ctx['num'] == idx:
9552 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
9553 resp = b"<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type><Base64>aGVsbG8=</Base64></TNCC-TNCS-Message></TNCCS-Batch>"
9554 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9555 4 + 1 + 1 + len(resp),
9556 EAP_TYPE_TNC, 0x01) + resp
9557 idx += 1
9558 if ctx['num'] == idx:
9559 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9560
9561 idx += 1
9562 if ctx['num'] == idx:
9563 logger.info("Test: Invalid TNCC-TNCS-Message XML message")
9564 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9565 4 + 1 + 1,
9566 EAP_TYPE_TNC, 0x21)
9567 idx += 1
9568 if ctx['num'] == idx:
9569 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
9570 resp = b"<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type><XML>hello</XML></TNCC-TNCS-Message></TNCCS-Batch>"
9571 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9572 4 + 1 + 1 + len(resp),
9573 EAP_TYPE_TNC, 0x01) + resp
9574 idx += 1
9575 if ctx['num'] == idx:
9576 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9577
9578 idx += 1
9579 if ctx['num'] == idx:
9580 logger.info("Test: Missing TNCCS-Recommendation type")
9581 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9582 4 + 1 + 1,
9583 EAP_TYPE_TNC, 0x21)
9584 idx += 1
9585 if ctx['num'] == idx:
9586 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
9587 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>'
9588 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9589 4 + 1 + 1 + len(resp),
9590 EAP_TYPE_TNC, 0x01) + resp
9591 idx += 1
9592 if ctx['num'] == idx:
9593 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9594
9595 idx += 1
9596 if ctx['num'] == idx:
9597 logger.info("Test: TNCCS-Recommendation type=none")
9598 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9599 4 + 1 + 1,
9600 EAP_TYPE_TNC, 0x21)
9601 idx += 1
9602 if ctx['num'] == idx:
9603 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
9604 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>'
9605 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9606 4 + 1 + 1 + len(resp),
9607 EAP_TYPE_TNC, 0x01) + resp
9608 idx += 1
9609 if ctx['num'] == idx:
9610 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9611
9612 idx += 1
9613 if ctx['num'] == idx:
9614 logger.info("Test: TNCCS-Recommendation type=isolate")
9615 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9616 4 + 1 + 1,
9617 EAP_TYPE_TNC, 0x21)
9618 idx += 1
9619 if ctx['num'] == idx:
9620 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
9621 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>'
9622 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9623 4 + 1 + 1 + len(resp),
9624 EAP_TYPE_TNC, 0x01) + resp
9625 idx += 1
9626 if ctx['num'] == idx:
9627 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9628
9629 logger.info("No more test responses available - test case completed")
9630 global eap_proto_tnc_test_done
9631 eap_proto_tnc_test_done = True
9632 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9633
9634 srv = start_radius_server(tnc_handler)
9635
9636 try:
9637 hapd = start_ap(apdev[0])
9638 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
9639
9640 i = 0
9641 while not eap_proto_tnc_test_done:
9642 i += 1
9643 logger.info("Running connection iteration %d" % i)
9644 frag = 1400
9645 if i == 8:
9646 frag = 150
9647 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
9648 eap="TNC", identity="tnc", fragment_size=str(frag),
9649 wait_connect=False)
9650 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
9651 if ev is None:
9652 raise Exception("Timeout on EAP start")
9653 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD",
9654 "CTRL-EVENT-EAP-STATUS"], timeout=5)
9655 if ev is None:
9656 raise Exception("Timeout on EAP method start")
9657 time.sleep(0.1)
9658 dev[0].request("REMOVE_NETWORK all")
9659 dev[0].wait_disconnected(timeout=1)
9660 dev[0].dump_monitor()
9661 finally:
9662 stop_radius_server(srv)
9663
9664 def test_eap_canned_success_after_identity(dev, apdev):
9665 """EAP protocol tests for canned EAP-Success after identity"""
9666 check_eap_capa(dev[0], "MD5")
9667 def eap_canned_success_handler(ctx, req):
9668 logger.info("eap_canned_success_handler - RX " + binascii.hexlify(req).decode())
9669 if 'num' not in ctx:
9670 ctx['num'] = 0
9671 ctx['num'] = ctx['num'] + 1
9672 if 'id' not in ctx:
9673 ctx['id'] = 1
9674 ctx['id'] = (ctx['id'] + 1) % 256
9675 idx = 0
9676
9677 idx += 1
9678 if ctx['num'] == idx:
9679 logger.info("Test: EAP-Success")
9680 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4)
9681
9682 idx += 1
9683 if ctx['num'] == idx:
9684 logger.info("Test: EAP-Success")
9685 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4)
9686
9687 return None
9688
9689 srv = start_radius_server(eap_canned_success_handler)
9690
9691 try:
9692 hapd = start_ap(apdev[0])
9693 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
9694
9695 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
9696 phase1="allow_canned_success=1",
9697 eap="MD5", identity="user", password="password",
9698 wait_connect=False)
9699 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15)
9700 if ev is None:
9701 raise Exception("Timeout on EAP success")
9702 dev[0].request("REMOVE_NETWORK all")
9703 dev[0].wait_disconnected()
9704
9705 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
9706 eap="MD5", identity="user", password="password",
9707 wait_connect=False)
9708 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
9709 if ev is None:
9710 raise Exception("Timeout on EAP start")
9711 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=0.1)
9712 if ev is not None:
9713 raise Exception("Unexpected EAP success")
9714 dev[0].request("REMOVE_NETWORK all")
9715 dev[0].wait_disconnected()
9716 finally:
9717 stop_radius_server(srv)
9718
9719 def test_eap_proto_wsc(dev, apdev):
9720 """EAP-WSC protocol tests"""
9721 global eap_proto_wsc_test_done, eap_proto_wsc_wait_failure
9722 eap_proto_wsc_test_done = False
9723
9724 def wsc_handler(ctx, req):
9725 logger.info("wsc_handler - RX " + binascii.hexlify(req).decode())
9726 if 'num' not in ctx:
9727 ctx['num'] = 0
9728 ctx['num'] += 1
9729 if 'id' not in ctx:
9730 ctx['id'] = 1
9731 ctx['id'] = (ctx['id'] + 1) % 256
9732 idx = 0
9733
9734 global eap_proto_wsc_wait_failure
9735 eap_proto_wsc_wait_failure = False
9736
9737 idx += 1
9738 if ctx['num'] == idx:
9739 logger.info("Test: Missing Flags field")
9740 return struct.pack(">BBHB3BLB", EAP_CODE_REQUEST, ctx['id'],
9741 4 + 1 + 3 + 4 + 1,
9742 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
9743 1)
9744
9745 idx += 1
9746 if ctx['num'] == idx:
9747 logger.info("Test: Message underflow (missing Message Length field)")
9748 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'],
9749 4 + 1 + 3 + 4 + 2,
9750 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
9751 1, 0x02)
9752
9753 idx += 1
9754 if ctx['num'] == idx:
9755 logger.info("Test: Invalid Message Length (> 50000)")
9756 return struct.pack(">BBHB3BLBBH", EAP_CODE_REQUEST, ctx['id'],
9757 4 + 1 + 3 + 4 + 4,
9758 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
9759 1, 0x02, 65535)
9760
9761 idx += 1
9762 if ctx['num'] == idx:
9763 logger.info("Test: Invalid Message Length (< current payload)")
9764 return struct.pack(">BBHB3BLBBHB", EAP_CODE_REQUEST, ctx['id'],
9765 4 + 1 + 3 + 4 + 5,
9766 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
9767 1, 0x02, 0, 0xff)
9768
9769 idx += 1
9770 if ctx['num'] == idx:
9771 logger.info("Test: Unexpected Op-Code 5 in WAIT_START state")
9772 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'],
9773 4 + 1 + 3 + 4 + 2,
9774 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
9775 5, 0x00)
9776
9777 idx += 1
9778 if ctx['num'] == idx:
9779 logger.info("Test: Valid WSC Start to start the sequence")
9780 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'],
9781 4 + 1 + 3 + 4 + 2,
9782 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
9783 1, 0x00)
9784 idx += 1
9785 if ctx['num'] == idx:
9786 logger.info("Test: No Message Length field in a fragmented packet")
9787 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'],
9788 4 + 1 + 3 + 4 + 2,
9789 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
9790 4, 0x01)
9791
9792 idx += 1
9793 if ctx['num'] == idx:
9794 logger.info("Test: Valid WSC Start to start the sequence")
9795 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'],
9796 4 + 1 + 3 + 4 + 2,
9797 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
9798 1, 0x00)
9799 idx += 1
9800 if ctx['num'] == idx:
9801 logger.info("Test: Valid first fragmented packet")
9802 return struct.pack(">BBHB3BLBBHB", EAP_CODE_REQUEST, ctx['id'],
9803 4 + 1 + 3 + 4 + 5,
9804 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
9805 4, 0x03, 10, 1)
9806 idx += 1
9807 if ctx['num'] == idx:
9808 logger.info("Test: Unexpected Op-Code 5 in fragment (expected 4)")
9809 return struct.pack(">BBHB3BLBBB", EAP_CODE_REQUEST, ctx['id'],
9810 4 + 1 + 3 + 4 + 3,
9811 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
9812 5, 0x01, 2)
9813
9814 idx += 1
9815 if ctx['num'] == idx:
9816 logger.info("Test: Valid WSC Start to start the sequence")
9817 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'],
9818 4 + 1 + 3 + 4 + 2,
9819 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
9820 1, 0x00)
9821 idx += 1
9822 if ctx['num'] == idx:
9823 logger.info("Test: Valid first fragmented packet")
9824 return struct.pack(">BBHB3BLBBHB", EAP_CODE_REQUEST, ctx['id'],
9825 4 + 1 + 3 + 4 + 5,
9826 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
9827 4, 0x03, 2, 1)
9828 idx += 1
9829 if ctx['num'] == idx:
9830 logger.info("Test: Fragment overflow")
9831 return struct.pack(">BBHB3BLBBBB", EAP_CODE_REQUEST, ctx['id'],
9832 4 + 1 + 3 + 4 + 4,
9833 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
9834 4, 0x01, 2, 3)
9835
9836 idx += 1
9837 if ctx['num'] == idx:
9838 logger.info("Test: Valid WSC Start to start the sequence")
9839 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'],
9840 4 + 1 + 3 + 4 + 2,
9841 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
9842 1, 0x00)
9843 idx += 1
9844 if ctx['num'] == idx:
9845 logger.info("Test: Unexpected Op-Code 5 in WAIT_FRAG_ACK state")
9846 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'],
9847 4 + 1 + 3 + 4 + 2,
9848 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
9849 5, 0x00)
9850
9851 idx += 1
9852 if ctx['num'] == idx:
9853 logger.info("Test: Valid WSC Start")
9854 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'],
9855 4 + 1 + 3 + 4 + 2,
9856 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
9857 1, 0x00)
9858 idx += 1
9859 if ctx['num'] == idx:
9860 logger.info("No more test responses available - test case completed")
9861 global eap_proto_wsc_test_done
9862 eap_proto_wsc_test_done = True
9863 eap_proto_wsc_wait_failure = True
9864 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9865
9866 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9867
9868 srv = start_radius_server(wsc_handler)
9869
9870 try:
9871 hapd = start_ap(apdev[0])
9872 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
9873
9874 i = 0
9875 while not eap_proto_wsc_test_done:
9876 i += 1
9877 logger.info("Running connection iteration %d" % i)
9878 fragment_size = 1398 if i != 9 else 50
9879 dev[0].connect("eap-test", key_mgmt="WPA-EAP", eap="WSC",
9880 fragment_size=str(fragment_size),
9881 identity="WFA-SimpleConfig-Enrollee-1-0",
9882 phase1="pin=12345670",
9883 scan_freq="2412", wait_connect=False)
9884 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5)
9885 if ev is None:
9886 raise Exception("Timeout on EAP method start")
9887 if eap_proto_wsc_wait_failure:
9888 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
9889 if ev is None:
9890 raise Exception("Timeout on EAP failure")
9891 else:
9892 time.sleep(0.1)
9893 dev[0].request("REMOVE_NETWORK all")
9894 dev[0].wait_disconnected(timeout=1)
9895 dev[0].dump_monitor()
9896 finally:
9897 stop_radius_server(srv)
9898
9899 def test_eap_canned_success_before_method(dev, apdev):
9900 """EAP protocol tests for canned EAP-Success before any method"""
9901 params = int_eap_server_params()
9902 hapd = hostapd.add_ap(apdev[0], params)
9903 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
9904 bssid = apdev[0]['bssid']
9905 hapd.request("SET ext_eapol_frame_io 1")
9906
9907 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412",
9908 phase1="allow_canned_success=1",
9909 eap="MD5", identity="user", password="password",
9910 wait_connect=False)
9911
9912 ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
9913 if ev is None:
9914 raise Exception("Timeout on EAPOL-TX from hostapd")
9915
9916 res = dev[0].request("EAPOL_RX " + bssid + " 0200000403020004")
9917 if "OK" not in res:
9918 raise Exception("EAPOL_RX to wpa_supplicant failed")
9919
9920 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=5)
9921 if ev is None:
9922 raise Exception("Timeout on EAP success")
9923 dev[0].request("REMOVE_NETWORK all")
9924 dev[0].wait_disconnected()
9925
9926 def test_eap_canned_failure_before_method(dev, apdev):
9927 """EAP protocol tests for canned EAP-Failure before any method"""
9928 params = int_eap_server_params()
9929 hapd = hostapd.add_ap(apdev[0], params)
9930 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
9931 bssid = apdev[0]['bssid']
9932 hapd.request("SET ext_eapol_frame_io 1")
9933 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412",
9934 phase1="allow_canned_success=1",
9935 eap="MD5", identity="user", password="password",
9936 wait_connect=False)
9937
9938 ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
9939 if ev is None:
9940 raise Exception("Timeout on EAPOL-TX from hostapd")
9941
9942 res = dev[0].request("EAPOL_RX " + bssid + " 0200000404020004")
9943 if "OK" not in res:
9944 raise Exception("EAPOL_RX to wpa_supplicant failed")
9945
9946 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
9947 if ev is None:
9948 raise Exception("Timeout on EAP failure")
9949 dev[0].request("REMOVE_NETWORK all")
9950 dev[0].wait_disconnected()
9951
9952 def test_eap_nak_oom(dev, apdev):
9953 """EAP-Nak OOM"""
9954 check_eap_capa(dev[0], "MD5")
9955 params = hostapd.wpa2_eap_params(ssid="eap-test")
9956 hapd = hostapd.add_ap(apdev[0], params)
9957 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
9958 with alloc_fail(dev[0], 1, "eap_msg_alloc;eap_sm_buildNak"):
9959 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
9960 eap="MD5", identity="sake user", password="password",
9961 wait_connect=False)
9962 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
9963 dev[0].request("REMOVE_NETWORK all")
9964 dev[0].wait_disconnected()
9965
9966 def test_eap_nak_expanded(dev, apdev):
9967 """EAP-Nak with expanded method"""
9968 check_eap_capa(dev[0], "MD5")
9969 check_eap_capa(dev[0], "VENDOR-TEST")
9970 params = hostapd.wpa2_eap_params(ssid="eap-test")
9971 hapd = hostapd.add_ap(apdev[0], params)
9972 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
9973 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
9974 eap="VENDOR-TEST WSC",
9975 identity="sake user", password="password",
9976 wait_connect=False)
9977 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=10)
9978 if ev is None or "NAK" not in ev:
9979 raise Exception("No NAK event seen")
9980
9981 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
9982 if ev is None:
9983 raise Exception("No EAP-Failure seen")
9984
9985 dev[0].request("REMOVE_NETWORK all")
9986 dev[0].wait_disconnected()
9987
9988 EAP_TLV_RESULT_TLV = 3
9989 EAP_TLV_NAK_TLV = 4
9990 EAP_TLV_ERROR_CODE_TLV = 5
9991 EAP_TLV_CONNECTION_BINDING_TLV = 6
9992 EAP_TLV_VENDOR_SPECIFIC_TLV = 7
9993 EAP_TLV_URI_TLV = 8
9994 EAP_TLV_EAP_PAYLOAD_TLV = 9
9995 EAP_TLV_INTERMEDIATE_RESULT_TLV = 10
9996 EAP_TLV_PAC_TLV = 11
9997 EAP_TLV_CRYPTO_BINDING_TLV = 12
9998 EAP_TLV_CALLING_STATION_ID_TLV = 13
9999 EAP_TLV_CALLED_STATION_ID_TLV = 14
10000 EAP_TLV_NAS_PORT_TYPE_TLV = 15
10001 EAP_TLV_SERVER_IDENTIFIER_TLV = 16
10002 EAP_TLV_IDENTITY_TYPE_TLV = 17
10003 EAP_TLV_SERVER_TRUSTED_ROOT_TLV = 18
10004 EAP_TLV_REQUEST_ACTION_TLV = 19
10005 EAP_TLV_PKCS7_TLV = 20
10006
10007 EAP_TLV_RESULT_SUCCESS = 1
10008 EAP_TLV_RESULT_FAILURE = 2
10009
10010 EAP_TLV_TYPE_MANDATORY = 0x8000
10011 EAP_TLV_TYPE_MASK = 0x3fff
10012
10013 PAC_TYPE_PAC_KEY = 1
10014 PAC_TYPE_PAC_OPAQUE = 2
10015 PAC_TYPE_CRED_LIFETIME = 3
10016 PAC_TYPE_A_ID = 4
10017 PAC_TYPE_I_ID = 5
10018 PAC_TYPE_A_ID_INFO = 7
10019 PAC_TYPE_PAC_ACKNOWLEDGEMENT = 8
10020 PAC_TYPE_PAC_INFO = 9
10021 PAC_TYPE_PAC_TYPE = 10
10022
10023 def eap_fast_start(ctx):
10024 logger.info("Send EAP-FAST/Start")
10025 return struct.pack(">BBHBBHH", EAP_CODE_REQUEST, ctx['id'],
10026 4 + 1 + 1 + 4 + 16,
10027 EAP_TYPE_FAST, 0x21, 4, 16) + 16*b'A'
10028
10029 def test_eap_fast_proto(dev, apdev):
10030 """EAP-FAST Phase protocol testing"""
10031 check_eap_capa(dev[0], "FAST")
10032 global eap_fast_proto_ctx
10033 eap_fast_proto_ctx = None
10034
10035 def eap_handler(ctx, req):
10036 logger.info("eap_handler - RX " + binascii.hexlify(req).decode())
10037 if 'num' not in ctx:
10038 ctx['num'] = 0
10039 ctx['num'] = ctx['num'] + 1
10040 if 'id' not in ctx:
10041 ctx['id'] = 1
10042 ctx['id'] = (ctx['id'] + 1) % 256
10043 idx = 0
10044
10045 global eap_fast_proto_ctx
10046 eap_fast_proto_ctx = ctx
10047 ctx['test_done'] = False
10048
10049 idx += 1
10050 if ctx['num'] == idx:
10051 return eap_fast_start(ctx)
10052 idx += 1
10053 if ctx['num'] == idx:
10054 logger.info("EAP-FAST: TLS processing failed")
10055 data = b'ABCDEFGHIK'
10056 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
10057 4 + 1 + 1 + len(data),
10058 EAP_TYPE_FAST, 0x01) + data
10059 idx += 1
10060 if ctx['num'] == idx:
10061 ctx['test_done'] = True
10062 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
10063
10064 logger.info("Past last test case")
10065 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
10066
10067 srv = start_radius_server(eap_handler)
10068 try:
10069 hapd = start_ap(apdev[0])
10070 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
10071 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
10072 eap="FAST", anonymous_identity="FAST",
10073 identity="user", password="password",
10074 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
10075 phase1="fast_provisioning=1",
10076 pac_file="blob://fast_pac_proto",
10077 wait_connect=False)
10078 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5)
10079 if ev is None:
10080 raise Exception("Could not start EAP-FAST")
10081 ok = False
10082 for i in range(100):
10083 if eap_fast_proto_ctx:
10084 if eap_fast_proto_ctx['test_done']:
10085 ok = True
10086 break
10087 time.sleep(0.05)
10088 dev[0].request("REMOVE_NETWORK all")
10089 dev[0].wait_disconnected()
10090 finally:
10091 stop_radius_server(srv)
10092
10093 def run_eap_fast_phase2(dev, test_payload, test_failure=True):
10094 global eap_fast_proto_ctx
10095 eap_fast_proto_ctx = None
10096
10097 def ssl_info_callback(conn, where, ret):
10098 logger.debug("SSL: info where=%d ret=%d" % (where, ret))
10099
10100 def log_conn_state(conn):
10101 try:
10102 state = conn.state_string()
10103 except AttributeError:
10104 state = conn.get_state_string()
10105 if state:
10106 logger.info("State: " + str(state))
10107
10108 def process_clienthello(ctx, payload):
10109 logger.info("Process ClientHello")
10110 ctx['sslctx'] = OpenSSL.SSL.Context(OpenSSL.SSL.TLSv1_METHOD)
10111 ctx['sslctx'].set_info_callback(ssl_info_callback)
10112 ctx['sslctx'].load_tmp_dh("auth_serv/dh.conf")
10113 ctx['sslctx'].set_cipher_list("ADH-AES128-SHA")
10114 ctx['conn'] = OpenSSL.SSL.Connection(ctx['sslctx'], None)
10115 ctx['conn'].set_accept_state()
10116 log_conn_state(ctx['conn'])
10117 ctx['conn'].bio_write(payload)
10118 try:
10119 ctx['conn'].do_handshake()
10120 except OpenSSL.SSL.WantReadError:
10121 pass
10122 log_conn_state(ctx['conn'])
10123 data = ctx['conn'].bio_read(4096)
10124 log_conn_state(ctx['conn'])
10125 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
10126 4 + 1 + 1 + len(data),
10127 EAP_TYPE_FAST, 0x01) + data
10128
10129 def process_clientkeyexchange(ctx, payload, appl_data):
10130 logger.info("Process ClientKeyExchange")
10131 log_conn_state(ctx['conn'])
10132 ctx['conn'].bio_write(payload)
10133 try:
10134 ctx['conn'].do_handshake()
10135 except OpenSSL.SSL.WantReadError:
10136 pass
10137 ctx['conn'].send(appl_data)
10138 log_conn_state(ctx['conn'])
10139 data = ctx['conn'].bio_read(4096)
10140 log_conn_state(ctx['conn'])
10141 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
10142 4 + 1 + 1 + len(data),
10143 EAP_TYPE_FAST, 0x01) + data
10144
10145 def eap_handler(ctx, req):
10146 logger.info("eap_handler - RX " + binascii.hexlify(req).decode())
10147 if 'num' not in ctx:
10148 ctx['num'] = 0
10149 ctx['num'] = ctx['num'] + 1
10150 if 'id' not in ctx:
10151 ctx['id'] = 1
10152 ctx['id'] = (ctx['id'] + 1) % 256
10153 idx = 0
10154
10155 global eap_fast_proto_ctx
10156 eap_fast_proto_ctx = ctx
10157 ctx['test_done'] = False
10158 logger.debug("ctx['num']=%d" % ctx['num'])
10159
10160 idx += 1
10161 if ctx['num'] == idx:
10162 return eap_fast_start(ctx)
10163 idx += 1
10164 if ctx['num'] == idx:
10165 return process_clienthello(ctx, req[6:])
10166 idx += 1
10167 if ctx['num'] == idx:
10168 if not test_failure:
10169 ctx['test_done'] = True
10170 return process_clientkeyexchange(ctx, req[6:], test_payload)
10171 idx += 1
10172 if ctx['num'] == idx:
10173 ctx['test_done'] = True
10174 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
10175
10176 logger.info("Past last test case")
10177 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
10178
10179 srv = start_radius_server(eap_handler)
10180 try:
10181 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
10182 eap="FAST", anonymous_identity="FAST",
10183 identity="user", password="password",
10184 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
10185 phase1="fast_provisioning=1",
10186 pac_file="blob://fast_pac_proto",
10187 wait_connect=False)
10188 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5)
10189 if ev is None:
10190 raise Exception("Could not start EAP-FAST")
10191 dev[0].dump_monitor()
10192 ok = False
10193 for i in range(100):
10194 if eap_fast_proto_ctx:
10195 if eap_fast_proto_ctx['test_done']:
10196 ok = True
10197 break
10198 time.sleep(0.05)
10199 time.sleep(0.1)
10200 dev[0].request("REMOVE_NETWORK all")
10201 dev[0].wait_disconnected()
10202 if not ok:
10203 raise Exception("EAP-FAST TLS exchange did not complete")
10204 for i in range(3):
10205 dev[i].dump_monitor()
10206 finally:
10207 stop_radius_server(srv)
10208
10209 def test_eap_fast_proto_phase2(dev, apdev):
10210 """EAP-FAST Phase 2 protocol testing"""
10211 if not openssl_imported:
10212 raise HwsimSkip("OpenSSL python method not available")
10213 check_eap_capa(dev[0], "FAST")
10214 hapd = start_ap(apdev[0])
10215 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
10216
10217 tests = [("Too short Phase 2 TLV frame (len=3)",
10218 "ABC",
10219 False),
10220 ("EAP-FAST: TLV overflow",
10221 struct.pack(">HHB", 0, 2, 0xff),
10222 False),
10223 ("EAP-FAST: Unknown TLV (optional and mandatory)",
10224 struct.pack(">HHB", 0, 1, 0xff) +
10225 struct.pack(">HHB", EAP_TLV_TYPE_MANDATORY, 1, 0xff),
10226 True),
10227 ("EAP-FAST: More than one EAP-Payload TLV in the message",
10228 struct.pack(">HHBHHB",
10229 EAP_TLV_EAP_PAYLOAD_TLV, 1, 0xff,
10230 EAP_TLV_EAP_PAYLOAD_TLV, 1, 0xff),
10231 True),
10232 ("EAP-FAST: Unknown Result 255 and More than one Result TLV in the message",
10233 struct.pack(">HHHHHH",
10234 EAP_TLV_RESULT_TLV, 2, 0xff,
10235 EAP_TLV_RESULT_TLV, 2, 0xff),
10236 True),
10237 ("EAP-FAST: Too short Result TLV",
10238 struct.pack(">HHB", EAP_TLV_RESULT_TLV, 1, 0xff),
10239 True),
10240 ("EAP-FAST: Unknown Intermediate Result 255 and More than one Intermediate-Result TLV in the message",
10241 struct.pack(">HHHHHH",
10242 EAP_TLV_INTERMEDIATE_RESULT_TLV, 2, 0xff,
10243 EAP_TLV_INTERMEDIATE_RESULT_TLV, 2, 0xff),
10244 True),
10245 ("EAP-FAST: Too short Intermediate-Result TLV",
10246 struct.pack(">HHB", EAP_TLV_INTERMEDIATE_RESULT_TLV, 1, 0xff),
10247 True),
10248 ("EAP-FAST: More than one Crypto-Binding TLV in the message",
10249 struct.pack(">HH", EAP_TLV_CRYPTO_BINDING_TLV, 60) + 60*b'A' +
10250 struct.pack(">HH", EAP_TLV_CRYPTO_BINDING_TLV, 60) + 60*b'A',
10251 True),
10252 ("EAP-FAST: Too short Crypto-Binding TLV",
10253 struct.pack(">HHB", EAP_TLV_CRYPTO_BINDING_TLV, 1, 0xff),
10254 True),
10255 ("EAP-FAST: More than one Request-Action TLV in the message",
10256 struct.pack(">HHBBHHBB",
10257 EAP_TLV_REQUEST_ACTION_TLV, 2, 0xff, 0xff,
10258 EAP_TLV_REQUEST_ACTION_TLV, 2, 0xff, 0xff),
10259 True),
10260 ("EAP-FAST: Too short Request-Action TLV",
10261 struct.pack(">HHB", EAP_TLV_REQUEST_ACTION_TLV, 1, 0xff),
10262 True),
10263 ("EAP-FAST: More than one PAC TLV in the message",
10264 struct.pack(">HHBHHB",
10265 EAP_TLV_PAC_TLV, 1, 0xff,
10266 EAP_TLV_PAC_TLV, 1, 0xff),
10267 True),
10268 ("EAP-FAST: Too short EAP Payload TLV (Len=3)",
10269 struct.pack(">HH3B",
10270 EAP_TLV_EAP_PAYLOAD_TLV, 3, 0, 0, 0),
10271 False),
10272 ("EAP-FAST: Too short Phase 2 request (Len=0)",
10273 struct.pack(">HHBBH",
10274 EAP_TLV_EAP_PAYLOAD_TLV, 4,
10275 EAP_CODE_REQUEST, 0, 0),
10276 False),
10277 ("EAP-FAST: EAP packet overflow in EAP Payload TLV",
10278 struct.pack(">HHBBH",
10279 EAP_TLV_EAP_PAYLOAD_TLV, 4,
10280 EAP_CODE_REQUEST, 0, 4 + 1),
10281 False),
10282 ("EAP-FAST: Unexpected code=0 in Phase 2 EAP header",
10283 struct.pack(">HHBBH",
10284 EAP_TLV_EAP_PAYLOAD_TLV, 4,
10285 0, 0, 0),
10286 False),
10287 ("EAP-FAST: PAC TLV without Result TLV acknowledging success",
10288 struct.pack(">HHB", EAP_TLV_PAC_TLV, 1, 0xff),
10289 True),
10290 ("EAP-FAST: PAC TLV does not include all the required fields",
10291 struct.pack(">HHH", EAP_TLV_RESULT_TLV, 2,
10292 EAP_TLV_RESULT_SUCCESS) +
10293 struct.pack(">HHB", EAP_TLV_PAC_TLV, 1, 0xff),
10294 True),
10295 ("EAP-FAST: Invalid PAC-Key length 0, Ignored unknown PAC type 0, and PAC TLV overrun (type=0 len=2 left=1)",
10296 struct.pack(">HHH", EAP_TLV_RESULT_TLV, 2,
10297 EAP_TLV_RESULT_SUCCESS) +
10298 struct.pack(">HHHHHHHHB", EAP_TLV_PAC_TLV, 4 + 4 + 5,
10299 PAC_TYPE_PAC_KEY, 0, 0, 0, 0, 2, 0),
10300 True),
10301 ("EAP-FAST: PAC-Info does not include all the required fields",
10302 struct.pack(">HHH", EAP_TLV_RESULT_TLV, 2,
10303 EAP_TLV_RESULT_SUCCESS) +
10304 struct.pack(">HHHHHHHH", EAP_TLV_PAC_TLV, 4 + 4 + 4 + 32,
10305 PAC_TYPE_PAC_OPAQUE, 0,
10306 PAC_TYPE_PAC_INFO, 0,
10307 PAC_TYPE_PAC_KEY, 32) + 32*b'A',
10308 True),
10309 ("EAP-FAST: Invalid CRED_LIFETIME length, Ignored unknown PAC-Info type 0, and Invalid PAC-Type length 1",
10310 struct.pack(">HHH", EAP_TLV_RESULT_TLV, 2,
10311 EAP_TLV_RESULT_SUCCESS) +
10312 struct.pack(">HHHHHHHHHHHHBHH", EAP_TLV_PAC_TLV, 4 + 4 + 13 + 4 + 32,
10313 PAC_TYPE_PAC_OPAQUE, 0,
10314 PAC_TYPE_PAC_INFO, 13, PAC_TYPE_CRED_LIFETIME, 0,
10315 0, 0, PAC_TYPE_PAC_TYPE, 1, 0,
10316 PAC_TYPE_PAC_KEY, 32) + 32*b'A',
10317 True),
10318 ("EAP-FAST: Unsupported PAC-Type 0",
10319 struct.pack(">HHH", EAP_TLV_RESULT_TLV, 2,
10320 EAP_TLV_RESULT_SUCCESS) +
10321 struct.pack(">HHHHHHHHHHH", EAP_TLV_PAC_TLV, 4 + 4 + 6 + 4 + 32,
10322 PAC_TYPE_PAC_OPAQUE, 0,
10323 PAC_TYPE_PAC_INFO, 6, PAC_TYPE_PAC_TYPE, 2, 0,
10324 PAC_TYPE_PAC_KEY, 32) + 32*b'A',
10325 True),
10326 ("EAP-FAST: PAC-Info overrun (type=0 len=2 left=1)",
10327 struct.pack(">HHH", EAP_TLV_RESULT_TLV, 2,
10328 EAP_TLV_RESULT_SUCCESS) +
10329 struct.pack(">HHHHHHHHBHH", EAP_TLV_PAC_TLV, 4 + 4 + 5 + 4 + 32,
10330 PAC_TYPE_PAC_OPAQUE, 0,
10331 PAC_TYPE_PAC_INFO, 5, 0, 2, 1,
10332 PAC_TYPE_PAC_KEY, 32) + 32*b'A',
10333 True),
10334 ("EAP-FAST: Valid PAC",
10335 struct.pack(">HHH", EAP_TLV_RESULT_TLV, 2,
10336 EAP_TLV_RESULT_SUCCESS) +
10337 struct.pack(">HHHHHHHHBHHBHH", EAP_TLV_PAC_TLV,
10338 4 + 4 + 10 + 4 + 32,
10339 PAC_TYPE_PAC_OPAQUE, 0,
10340 PAC_TYPE_PAC_INFO, 10, PAC_TYPE_A_ID, 1, 0x41,
10341 PAC_TYPE_A_ID_INFO, 1, 0x42,
10342 PAC_TYPE_PAC_KEY, 32) + 32*b'A',
10343 True),
10344 ("EAP-FAST: Invalid version/subtype in Crypto-Binding TLV",
10345 struct.pack(">HH", EAP_TLV_CRYPTO_BINDING_TLV, 60) + 60*b'A',
10346 True)]
10347 for title, payload, failure in tests:
10348 logger.info("Phase 2 test: " + title)
10349 run_eap_fast_phase2(dev, payload, failure)
10350
10351 def test_eap_fast_tlv_nak_oom(dev, apdev):
10352 """EAP-FAST Phase 2 TLV NAK OOM"""
10353 if not openssl_imported:
10354 raise HwsimSkip("OpenSSL python method not available")
10355 check_eap_capa(dev[0], "FAST")
10356 hapd = start_ap(apdev[0])
10357 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
10358
10359 with alloc_fail(dev[0], 1, "eap_fast_tlv_nak"):
10360 run_eap_fast_phase2(dev, struct.pack(">HHB", EAP_TLV_TYPE_MANDATORY,
10361 1, 0xff), False)