]> git.ipfire.org Git - thirdparty/hostap.git/blob - tests/hwsim/test_eap_proto.py
ea5f1a136d1e5d50fef09eaae01c152f1620d67a
[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 test_eap_proto_mschapv2(dev, apdev):
6444 """EAP-MSCHAPv2 protocol tests"""
6445 check_eap_capa(dev[0], "MSCHAPV2")
6446
6447 def mschapv2_handler(ctx, req):
6448 logger.info("mschapv2_handler - RX " + binascii.hexlify(req).decode())
6449 if 'num' not in ctx:
6450 ctx['num'] = 0
6451 ctx['num'] = ctx['num'] + 1
6452 if 'id' not in ctx:
6453 ctx['id'] = 1
6454 ctx['id'] = (ctx['id'] + 1) % 256
6455 idx = 0
6456
6457 idx += 1
6458 if ctx['num'] == idx:
6459 logger.info("Test: Missing payload")
6460 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6461 4 + 1,
6462 EAP_TYPE_MSCHAPV2)
6463
6464 idx += 1
6465 if ctx['num'] == idx:
6466 logger.info("Test: Unknown MSCHAPv2 op_code")
6467 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
6468 4 + 1 + 4 + 1,
6469 EAP_TYPE_MSCHAPV2,
6470 0, 0, 5, 0)
6471
6472 idx += 1
6473 if ctx['num'] == idx:
6474 logger.info("Test: Invalid ms_len and unknown MSCHAPv2 op_code")
6475 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
6476 4 + 1 + 4 + 1,
6477 EAP_TYPE_MSCHAPV2,
6478 255, 0, 0, 0)
6479
6480 idx += 1
6481 if ctx['num'] == idx:
6482 logger.info("Test: Success before challenge")
6483 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
6484 4 + 1 + 4 + 1,
6485 EAP_TYPE_MSCHAPV2,
6486 3, 0, 5, 0)
6487
6488 idx += 1
6489 if ctx['num'] == idx:
6490 logger.info("Test: Failure before challenge - required challenge field not present")
6491 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
6492 4 + 1 + 4 + 1,
6493 EAP_TYPE_MSCHAPV2,
6494 4, 0, 5, 0)
6495 idx += 1
6496 if ctx['num'] == idx:
6497 logger.info("Test: Failure")
6498 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6499
6500 idx += 1
6501 if ctx['num'] == idx:
6502 logger.info("Test: Failure before challenge - invalid failure challenge len")
6503 payload = b'C=12'
6504 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
6505 4 + 1 + 4 + len(payload),
6506 EAP_TYPE_MSCHAPV2,
6507 4, 0, 4 + len(payload)) + payload
6508 idx += 1
6509 if ctx['num'] == idx:
6510 logger.info("Test: Failure")
6511 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6512
6513 idx += 1
6514 if ctx['num'] == idx:
6515 logger.info("Test: Failure before challenge - invalid failure challenge len")
6516 payload = b'C=12 V=3'
6517 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
6518 4 + 1 + 4 + len(payload),
6519 EAP_TYPE_MSCHAPV2,
6520 4, 0, 4 + len(payload)) + payload
6521 idx += 1
6522 if ctx['num'] == idx:
6523 logger.info("Test: Failure")
6524 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6525
6526 idx += 1
6527 if ctx['num'] == idx:
6528 logger.info("Test: Failure before challenge - invalid failure challenge")
6529 payload = b'C=00112233445566778899aabbccddeefQ '
6530 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
6531 4 + 1 + 4 + len(payload),
6532 EAP_TYPE_MSCHAPV2,
6533 4, 0, 4 + len(payload)) + payload
6534 idx += 1
6535 if ctx['num'] == idx:
6536 logger.info("Test: Failure")
6537 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6538
6539 idx += 1
6540 if ctx['num'] == idx:
6541 logger.info("Test: Failure before challenge - password expired")
6542 payload = b'E=648 R=1 C=00112233445566778899aabbccddeeff V=3 M=Password expired'
6543 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
6544 4 + 1 + 4 + len(payload),
6545 EAP_TYPE_MSCHAPV2,
6546 4, 0, 4 + len(payload)) + payload
6547 idx += 1
6548 if ctx['num'] == idx:
6549 logger.info("Test: Success after password change")
6550 payload = b"S=1122334455667788990011223344556677889900"
6551 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
6552 4 + 1 + 4 + len(payload),
6553 EAP_TYPE_MSCHAPV2,
6554 3, 0, 4 + len(payload)) + payload
6555
6556 idx += 1
6557 if ctx['num'] == idx:
6558 logger.info("Test: Invalid challenge length")
6559 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
6560 4 + 1 + 4 + 1,
6561 EAP_TYPE_MSCHAPV2,
6562 1, 0, 4 + 1, 0)
6563
6564 idx += 1
6565 if ctx['num'] == idx:
6566 logger.info("Test: Too short challenge packet")
6567 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
6568 4 + 1 + 4 + 1,
6569 EAP_TYPE_MSCHAPV2,
6570 1, 0, 4 + 1, 16)
6571
6572 idx += 1
6573 if ctx['num'] == idx:
6574 logger.info("Test: Challenge")
6575 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
6576 4 + 1 + 4 + 1 + 16 + 6,
6577 EAP_TYPE_MSCHAPV2,
6578 1, 0, 4 + 1 + 16 + 6, 16) + 16*b'A' + b'foobar'
6579 idx += 1
6580 if ctx['num'] == idx:
6581 logger.info("Test: Failure - password expired")
6582 payload = b'E=648 R=1 C=00112233445566778899aabbccddeeff V=3 M=Password expired'
6583 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
6584 4 + 1 + 4 + len(payload),
6585 EAP_TYPE_MSCHAPV2,
6586 4, 0, 4 + len(payload)) + payload
6587 idx += 1
6588 if ctx['num'] == idx:
6589 logger.info("Test: Success after password change")
6590 if len(req) != 591:
6591 logger.info("Unexpected Change-Password packet length: %s" % len(req))
6592 return None
6593 data = req[9:]
6594 enc_pw = data[0:516]
6595 data = data[516:]
6596 enc_hash = data[0:16]
6597 data = data[16:]
6598 peer_challenge = data[0:16]
6599 data = data[16:]
6600 # Reserved
6601 data = data[8:]
6602 nt_response = data[0:24]
6603 data = data[24:]
6604 flags = data
6605 logger.info("enc_hash: " + binascii.hexlify(enc_hash).decode())
6606 logger.info("peer_challenge: " + binascii.hexlify(peer_challenge).decode())
6607 logger.info("nt_response: " + binascii.hexlify(nt_response).decode())
6608 logger.info("flags: " + binascii.hexlify(flags).decode())
6609
6610 auth_challenge = binascii.unhexlify("00112233445566778899aabbccddeeff")
6611 logger.info("auth_challenge: " + binascii.hexlify(auth_challenge).decode())
6612
6613 auth_resp = GenerateAuthenticatorResponse("new-pw", nt_response,
6614 peer_challenge,
6615 auth_challenge, "user")
6616 payload = b"S=" + binascii.hexlify(auth_resp).decode().upper().encode()
6617 logger.info("Success message payload: " + payload.decode())
6618 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
6619 4 + 1 + 4 + len(payload),
6620 EAP_TYPE_MSCHAPV2,
6621 3, 0, 4 + len(payload)) + payload
6622 idx += 1
6623 if ctx['num'] == idx:
6624 logger.info("Test: EAP-Success")
6625 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4)
6626
6627 idx += 1
6628 if ctx['num'] == idx:
6629 logger.info("Test: Failure - password expired")
6630 payload = b'E=648 R=1 C=00112233445566778899aabbccddeeff V=3 M=Password expired'
6631 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
6632 4 + 1 + 4 + len(payload),
6633 EAP_TYPE_MSCHAPV2,
6634 4, 0, 4 + len(payload)) + payload
6635 idx += 1
6636 if ctx['num'] == idx:
6637 logger.info("Test: Success after password change")
6638 if len(req) != 591:
6639 logger.info("Unexpected Change-Password packet length: %s" % len(req))
6640 return None
6641 data = req[9:]
6642 enc_pw = data[0:516]
6643 data = data[516:]
6644 enc_hash = data[0:16]
6645 data = data[16:]
6646 peer_challenge = data[0:16]
6647 data = data[16:]
6648 # Reserved
6649 data = data[8:]
6650 nt_response = data[0:24]
6651 data = data[24:]
6652 flags = data
6653 logger.info("enc_hash: " + binascii.hexlify(enc_hash).decode())
6654 logger.info("peer_challenge: " + binascii.hexlify(peer_challenge).decode())
6655 logger.info("nt_response: " + binascii.hexlify(nt_response).decode())
6656 logger.info("flags: " + binascii.hexlify(flags).decode())
6657
6658 auth_challenge = binascii.unhexlify("00112233445566778899aabbccddeeff")
6659 logger.info("auth_challenge: " + binascii.hexlify(auth_challenge).decode())
6660
6661 auth_resp = GenerateAuthenticatorResponse("new-pw", nt_response,
6662 peer_challenge,
6663 auth_challenge, "user")
6664 payload = b"S=" + binascii.hexlify(auth_resp).decode().upper().encode()
6665 logger.info("Success message payload: " + payload.decode())
6666 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
6667 4 + 1 + 4 + len(payload),
6668 EAP_TYPE_MSCHAPV2,
6669 3, 0, 4 + len(payload)) + payload
6670 idx += 1
6671 if ctx['num'] == idx:
6672 logger.info("Test: EAP-Success")
6673 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4)
6674
6675 idx += 1
6676 if ctx['num'] == idx:
6677 logger.info("Test: Challenge")
6678 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
6679 4 + 1 + 4 + 1 + 16 + 6,
6680 EAP_TYPE_MSCHAPV2,
6681 1, 0, 4 + 1 + 16 + 6, 16) + 16*b'A' + b'foobar'
6682 idx += 1
6683 if ctx['num'] == idx:
6684 logger.info("Test: Failure - authentication failure")
6685 payload = b'E=691 R=1 C=00112233445566778899aabbccddeeff V=3 M=Authentication failed'
6686 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
6687 4 + 1 + 4 + len(payload),
6688 EAP_TYPE_MSCHAPV2,
6689 4, 0, 4 + len(payload)) + payload
6690
6691 idx += 1
6692 if ctx['num'] == idx:
6693 logger.info("Test: Challenge")
6694 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
6695 4 + 1 + 4 + 1 + 16 + 6,
6696 EAP_TYPE_MSCHAPV2,
6697 1, 0, 4 + 1 + 16 + 6, 16) + 16*b'A' + b'foobar'
6698 idx += 1
6699 if ctx['num'] == idx:
6700 logger.info("Test: Failure - authentication failure")
6701 payload = b'E=691 R=1 C=00112233445566778899aabbccddeeff V=3 M=Authentication failed (2)'
6702 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
6703 4 + 1 + 4 + len(payload),
6704 EAP_TYPE_MSCHAPV2,
6705 4, 0, 4 + len(payload)) + payload
6706 idx += 1
6707 if ctx['num'] == idx:
6708 logger.info("Test: Failure")
6709 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6710
6711 idx += 1
6712 if ctx['num'] == idx:
6713 logger.info("Test: Challenge - invalid ms_len and workaround disabled")
6714 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
6715 4 + 1 + 4 + 1 + 16 + 6,
6716 EAP_TYPE_MSCHAPV2,
6717 1, 0, 4 + 1 + 16 + 6 + 1, 16) + 16*b'A' + b'foobar'
6718
6719 return None
6720
6721 srv = start_radius_server(mschapv2_handler)
6722
6723 try:
6724 hapd = start_ap(apdev[0])
6725 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
6726
6727 for i in range(0, 16):
6728 logger.info("RUN: %d" % i)
6729 if i == 12:
6730 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6731 eap="MSCHAPV2", identity="user",
6732 password_hex="hash:8846f7eaee8fb117ad06bdd830b7586c",
6733 wait_connect=False)
6734 elif i == 14:
6735 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6736 eap="MSCHAPV2", identity="user",
6737 phase2="mschapv2_retry=0",
6738 password="password", wait_connect=False)
6739 elif i == 15:
6740 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6741 eap="MSCHAPV2", identity="user",
6742 eap_workaround="0",
6743 password="password", wait_connect=False)
6744 else:
6745 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6746 eap="MSCHAPV2", identity="user",
6747 password="password", wait_connect=False)
6748 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15)
6749 if ev is None:
6750 raise Exception("Timeout on EAP start")
6751
6752 if i in [8, 11, 12]:
6753 ev = dev[0].wait_event(["CTRL-REQ-NEW_PASSWORD"],
6754 timeout=10)
6755 if ev is None:
6756 raise Exception("Timeout on new password request")
6757 id = ev.split(':')[0].split('-')[-1]
6758 dev[0].request("CTRL-RSP-NEW_PASSWORD-" + id + ":new-pw")
6759 if i in [11, 12]:
6760 ev = dev[0].wait_event(["CTRL-EVENT-PASSWORD-CHANGED"],
6761 timeout=10)
6762 if ev is None:
6763 raise Exception("Timeout on password change")
6764 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"],
6765 timeout=10)
6766 if ev is None:
6767 raise Exception("Timeout on EAP success")
6768 else:
6769 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"],
6770 timeout=10)
6771 if ev is None:
6772 raise Exception("Timeout on EAP failure")
6773
6774 if i in [13]:
6775 ev = dev[0].wait_event(["CTRL-REQ-IDENTITY"],
6776 timeout=10)
6777 if ev is None:
6778 raise Exception("Timeout on identity request")
6779 id = ev.split(':')[0].split('-')[-1]
6780 dev[0].request("CTRL-RSP-IDENTITY-" + id + ":user")
6781
6782 ev = dev[0].wait_event(["CTRL-REQ-PASSWORD"],
6783 timeout=10)
6784 if ev is None:
6785 raise Exception("Timeout on password request")
6786 id = ev.split(':')[0].split('-')[-1]
6787 dev[0].request("CTRL-RSP-PASSWORD-" + id + ":password")
6788
6789 # TODO: Does this work correctly?
6790
6791 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"],
6792 timeout=10)
6793 if ev is None:
6794 raise Exception("Timeout on EAP failure")
6795
6796 if i in [4, 5, 6, 7, 14]:
6797 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"],
6798 timeout=10)
6799 if ev is None:
6800 raise Exception("Timeout on EAP failure")
6801 else:
6802 time.sleep(0.05)
6803 dev[0].request("REMOVE_NETWORK all")
6804 dev[0].wait_disconnected(timeout=1)
6805 finally:
6806 stop_radius_server(srv)
6807
6808 def test_eap_proto_mschapv2_errors(dev, apdev):
6809 """EAP-MSCHAPv2 protocol tests (error paths)"""
6810 check_eap_capa(dev[0], "MSCHAPV2")
6811
6812 def mschapv2_fail_password_expired(ctx):
6813 logger.info("Test: Failure before challenge - password expired")
6814 payload = b'E=648 R=1 C=00112233445566778899aabbccddeeff V=3 M=Password expired'
6815 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
6816 4 + 1 + 4 + len(payload),
6817 EAP_TYPE_MSCHAPV2,
6818 4, 0, 4 + len(payload)) + payload
6819
6820 def mschapv2_success_after_password_change(ctx, req=None):
6821 logger.info("Test: Success after password change")
6822 if req is None or len(req) != 591:
6823 payload = b"S=1122334455667788990011223344556677889900"
6824 else:
6825 data = req[9:]
6826 enc_pw = data[0:516]
6827 data = data[516:]
6828 enc_hash = data[0:16]
6829 data = data[16:]
6830 peer_challenge = data[0:16]
6831 data = data[16:]
6832 # Reserved
6833 data = data[8:]
6834 nt_response = data[0:24]
6835 data = data[24:]
6836 flags = data
6837 logger.info("enc_hash: " + binascii.hexlify(enc_hash).decode())
6838 logger.info("peer_challenge: " + binascii.hexlify(peer_challenge).decode())
6839 logger.info("nt_response: " + binascii.hexlify(nt_response).decode())
6840 logger.info("flags: " + binascii.hexlify(flags).decode())
6841
6842 auth_challenge = binascii.unhexlify("00112233445566778899aabbccddeeff")
6843 logger.info("auth_challenge: " + binascii.hexlify(auth_challenge).decode())
6844
6845 auth_resp = GenerateAuthenticatorResponse("new-pw", nt_response,
6846 peer_challenge,
6847 auth_challenge, "user")
6848 payload = b"S=" + binascii.hexlify(auth_resp).decode().upper().encode()
6849 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
6850 4 + 1 + 4 + len(payload),
6851 EAP_TYPE_MSCHAPV2,
6852 3, 0, 4 + len(payload)) + payload
6853
6854 def mschapv2_handler(ctx, req):
6855 logger.info("mschapv2_handler - RX " + binascii.hexlify(req).decode())
6856 if 'num' not in ctx:
6857 ctx['num'] = 0
6858 ctx['num'] = ctx['num'] + 1
6859 if 'id' not in ctx:
6860 ctx['id'] = 1
6861 ctx['id'] = (ctx['id'] + 1) % 256
6862 idx = 0
6863
6864 idx += 1
6865 if ctx['num'] == idx:
6866 return mschapv2_fail_password_expired(ctx)
6867 idx += 1
6868 if ctx['num'] == idx:
6869 return mschapv2_success_after_password_change(ctx, req)
6870 idx += 1
6871 if ctx['num'] == idx:
6872 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6873
6874 idx += 1
6875 if ctx['num'] == idx:
6876 return mschapv2_fail_password_expired(ctx)
6877 idx += 1
6878 if ctx['num'] == idx:
6879 return mschapv2_success_after_password_change(ctx, req)
6880 idx += 1
6881 if ctx['num'] == idx:
6882 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6883
6884 idx += 1
6885 if ctx['num'] == idx:
6886 return mschapv2_fail_password_expired(ctx)
6887 idx += 1
6888 if ctx['num'] == idx:
6889 return mschapv2_success_after_password_change(ctx, req)
6890 idx += 1
6891 if ctx['num'] == idx:
6892 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6893
6894 idx += 1
6895 if ctx['num'] == idx:
6896 return mschapv2_fail_password_expired(ctx)
6897 idx += 1
6898 if ctx['num'] == idx:
6899 return mschapv2_success_after_password_change(ctx, req)
6900 idx += 1
6901 if ctx['num'] == idx:
6902 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6903
6904 idx += 1
6905 if ctx['num'] == idx:
6906 return mschapv2_fail_password_expired(ctx)
6907 idx += 1
6908 if ctx['num'] == idx:
6909 return mschapv2_success_after_password_change(ctx, req)
6910 idx += 1
6911 if ctx['num'] == idx:
6912 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6913
6914 idx += 1
6915 if ctx['num'] == idx:
6916 return mschapv2_fail_password_expired(ctx)
6917 idx += 1
6918 if ctx['num'] == idx:
6919 return mschapv2_success_after_password_change(ctx, req)
6920 idx += 1
6921 if ctx['num'] == idx:
6922 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6923
6924 idx += 1
6925 if ctx['num'] == idx:
6926 return mschapv2_fail_password_expired(ctx)
6927 idx += 1
6928 if ctx['num'] == idx:
6929 return mschapv2_success_after_password_change(ctx, req)
6930 idx += 1
6931 if ctx['num'] == idx:
6932 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6933
6934 idx += 1
6935 if ctx['num'] == idx:
6936 return mschapv2_fail_password_expired(ctx)
6937 idx += 1
6938 if ctx['num'] == idx:
6939 return mschapv2_success_after_password_change(ctx, req)
6940 idx += 1
6941 if ctx['num'] == idx:
6942 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6943
6944 idx += 1
6945 if ctx['num'] == idx:
6946 return mschapv2_fail_password_expired(ctx)
6947 idx += 1
6948 if ctx['num'] == idx:
6949 return mschapv2_success_after_password_change(ctx, req)
6950 idx += 1
6951 if ctx['num'] == idx:
6952 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6953
6954 return None
6955
6956 srv = start_radius_server(mschapv2_handler)
6957
6958 try:
6959 hapd = start_ap(apdev[0])
6960 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
6961
6962 tests = ["os_get_random;eap_mschapv2_change_password",
6963 "generate_nt_response;eap_mschapv2_change_password",
6964 "get_master_key;eap_mschapv2_change_password",
6965 "nt_password_hash;eap_mschapv2_change_password",
6966 "old_nt_password_hash_encrypted_with_new_nt_password_hash"]
6967 for func in tests:
6968 with fail_test(dev[0], 1, func):
6969 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6970 eap="MSCHAPV2", identity="user",
6971 password="password", wait_connect=False)
6972 ev = dev[0].wait_event(["CTRL-REQ-NEW_PASSWORD"], timeout=10)
6973 if ev is None:
6974 raise Exception("Timeout on new password request")
6975 id = ev.split(':')[0].split('-')[-1]
6976 dev[0].request("CTRL-RSP-NEW_PASSWORD-" + id + ":new-pw")
6977 time.sleep(0.1)
6978 wait_fail_trigger(dev[0], "GET_FAIL")
6979 dev[0].request("REMOVE_NETWORK all")
6980 dev[0].wait_disconnected(timeout=1)
6981
6982 tests = ["encrypt_pw_block_with_password_hash;eap_mschapv2_change_password",
6983 "nt_password_hash;eap_mschapv2_change_password",
6984 "nt_password_hash;eap_mschapv2_success"]
6985 for func in tests:
6986 with fail_test(dev[0], 1, func):
6987 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6988 eap="MSCHAPV2", identity="user",
6989 password_hex="hash:8846f7eaee8fb117ad06bdd830b7586c",
6990 wait_connect=False)
6991 ev = dev[0].wait_event(["CTRL-REQ-NEW_PASSWORD"], timeout=10)
6992 if ev is None:
6993 raise Exception("Timeout on new password request")
6994 id = ev.split(':')[0].split('-')[-1]
6995 dev[0].request("CTRL-RSP-NEW_PASSWORD-" + id + ":new-pw")
6996 time.sleep(0.1)
6997 wait_fail_trigger(dev[0], "GET_FAIL")
6998 dev[0].request("REMOVE_NETWORK all")
6999 dev[0].wait_disconnected(timeout=1)
7000
7001 tests = ["eap_msg_alloc;eap_mschapv2_change_password"]
7002 for func in tests:
7003 with alloc_fail(dev[0], 1, func):
7004 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7005 eap="MSCHAPV2", identity="user",
7006 password="password", wait_connect=False)
7007 ev = dev[0].wait_event(["CTRL-REQ-NEW_PASSWORD"], timeout=10)
7008 if ev is None:
7009 raise Exception("Timeout on new password request")
7010 id = ev.split(':')[0].split('-')[-1]
7011 dev[0].request("CTRL-RSP-NEW_PASSWORD-" + id + ":new-pw")
7012 time.sleep(0.1)
7013 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
7014 dev[0].request("REMOVE_NETWORK all")
7015 dev[0].wait_disconnected(timeout=1)
7016 finally:
7017 stop_radius_server(srv)
7018
7019 def test_eap_proto_pwd(dev, apdev):
7020 """EAP-pwd protocol tests"""
7021 check_eap_capa(dev[0], "PWD")
7022
7023 global eap_proto_pwd_test_done, eap_proto_pwd_test_wait
7024 eap_proto_pwd_test_done = False
7025 eap_proto_pwd_test_wait = False
7026
7027 def pwd_handler(ctx, req):
7028 logger.info("pwd_handler - RX " + binascii.hexlify(req).decode())
7029 if 'num' not in ctx:
7030 ctx['num'] = 0
7031 ctx['num'] = ctx['num'] + 1
7032 if 'id' not in ctx:
7033 ctx['id'] = 1
7034 ctx['id'] = (ctx['id'] + 1) % 256
7035 idx = 0
7036
7037 global eap_proto_pwd_test_wait
7038 eap_proto_pwd_test_wait = False
7039
7040 idx += 1
7041 if ctx['num'] == idx:
7042 logger.info("Test: Missing payload")
7043 # EAP-pwd: Got a frame but pos is not NULL and len is 0
7044 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 4 + 1,
7045 EAP_TYPE_PWD)
7046
7047 idx += 1
7048 if ctx['num'] == idx:
7049 logger.info("Test: Missing Total-Length field")
7050 # EAP-pwd: Frame too short to contain Total-Length field
7051 payload = struct.pack("B", 0x80)
7052 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7053 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7054
7055 idx += 1
7056 if ctx['num'] == idx:
7057 logger.info("Test: Too large Total-Length")
7058 # EAP-pwd: Incoming fragments whose total length = 65535
7059 payload = struct.pack(">BH", 0x80, 65535)
7060 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7061 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7062
7063 idx += 1
7064 if ctx['num'] == idx:
7065 eap_proto_pwd_test_wait = True
7066 logger.info("Test: First fragment")
7067 # EAP-pwd: Incoming fragments whose total length = 10
7068 # EAP-pwd: ACKing a 0 byte fragment
7069 payload = struct.pack(">BH", 0xc0, 10)
7070 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7071 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7072 idx += 1
7073 if ctx['num'] == idx:
7074 logger.info("Test: Unexpected Total-Length value in the second fragment")
7075 # EAP-pwd: Incoming fragments whose total length = 0
7076 # EAP-pwd: Unexpected new fragment start when previous fragment is still in use
7077 payload = struct.pack(">BH", 0x80, 0)
7078 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7079 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7080
7081 idx += 1
7082 if ctx['num'] == idx:
7083 logger.info("Test: First and only fragment")
7084 # EAP-pwd: Incoming fragments whose total length = 0
7085 # EAP-pwd: processing frame: exch 0, len 0
7086 # EAP-pwd: Ignoring message with unknown opcode 128
7087 payload = struct.pack(">BH", 0x80, 0)
7088 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7089 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7090
7091 idx += 1
7092 if ctx['num'] == idx:
7093 logger.info("Test: First and only fragment with extra data")
7094 # EAP-pwd: Incoming fragments whose total length = 0
7095 # EAP-pwd: processing frame: exch 0, len 1
7096 # EAP-pwd: Ignoring message with unknown opcode 128
7097 payload = struct.pack(">BHB", 0x80, 0, 0)
7098 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7099 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7100
7101 idx += 1
7102 if ctx['num'] == idx:
7103 eap_proto_pwd_test_wait = True
7104 logger.info("Test: First fragment")
7105 # EAP-pwd: Incoming fragments whose total length = 2
7106 # EAP-pwd: ACKing a 1 byte fragment
7107 payload = struct.pack(">BHB", 0xc0, 2, 1)
7108 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7109 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7110 idx += 1
7111 if ctx['num'] == idx:
7112 logger.info("Test: Extra data in the second fragment")
7113 # EAP-pwd: Buffer overflow attack detected (3 vs. 1)!
7114 payload = struct.pack(">BBB", 0x0, 2, 3)
7115 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7116 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7117
7118 idx += 1
7119 if ctx['num'] == idx:
7120 logger.info("Test: Too short id exchange")
7121 # EAP-pwd: processing frame: exch 1, len 0
7122 # EAP-PWD: PWD-ID-Req -> FAILURE
7123 payload = struct.pack(">B", 0x01)
7124 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7125 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7126
7127 idx += 1
7128 if ctx['num'] == idx:
7129 logger.info("Test: Unsupported rand func in id exchange")
7130 # EAP-PWD: Server EAP-pwd-ID proposal: group=0 random=0 prf=0 prep=0
7131 # EAP-PWD: PWD-ID-Req -> FAILURE
7132 payload = struct.pack(">BHBBLB", 0x01, 0, 0, 0, 0, 0)
7133 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7134 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7135
7136 idx += 1
7137 if ctx['num'] == idx:
7138 logger.info("Test: Unsupported prf in id exchange")
7139 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=0 prep=0
7140 # EAP-PWD: PWD-ID-Req -> FAILURE
7141 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 0, 0, 0)
7142 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7143 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7144
7145 idx += 1
7146 if ctx['num'] == idx:
7147 logger.info("Test: Unsupported password pre-processing technique in id exchange")
7148 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=255
7149 # EAP-PWD: Unsupported password pre-processing technique (Prep=255)
7150 # EAP-PWD: PWD-ID-Req -> FAILURE
7151 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 255)
7152 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7153 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7154
7155 idx += 1
7156 if ctx['num'] == idx:
7157 eap_proto_pwd_test_wait = True
7158 logger.info("Test: Valid id exchange")
7159 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=0
7160 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0)
7161 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7162 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7163 idx += 1
7164 if ctx['num'] == idx:
7165 logger.info("Test: Unexpected id exchange")
7166 # EAP-pwd: processing frame: exch 1, len 9
7167 # EAP-PWD: PWD-Commit-Req -> FAILURE
7168 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0)
7169 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7170 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7171
7172 idx += 1
7173 if ctx['num'] == idx:
7174 logger.info("Test: Unexpected commit exchange")
7175 # EAP-pwd: processing frame: exch 2, len 0
7176 # EAP-PWD: PWD-ID-Req -> FAILURE
7177 payload = struct.pack(">B", 0x02)
7178 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7179 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7180
7181 idx += 1
7182 if ctx['num'] == idx:
7183 eap_proto_pwd_test_wait = True
7184 logger.info("Test: Valid id exchange")
7185 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=0
7186 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0)
7187 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7188 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7189 idx += 1
7190 if ctx['num'] == idx:
7191 logger.info("Test: Unexpected Commit payload length (prep=None)")
7192 # EAP-pwd commit request, password prep is NONE
7193 # EAP-pwd: Unexpected Commit payload length 0 (expected 96)
7194 payload = struct.pack(">B", 0x02)
7195 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7196 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7197
7198 idx += 1
7199 if ctx['num'] == idx:
7200 eap_proto_pwd_test_wait = True
7201 logger.info("Test: Valid id exchange")
7202 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=0
7203 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0)
7204 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7205 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7206 idx += 1
7207 if ctx['num'] == idx:
7208 logger.info("Test: Commit payload with all zeros values --> Shared key at infinity")
7209 # EAP-pwd: Invalid coordinate in element
7210 payload = struct.pack(">B", 0x02) + 96*b'\0'
7211 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7212 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7213
7214 idx += 1
7215 if ctx['num'] == idx:
7216 eap_proto_pwd_test_wait = True
7217 logger.info("Test: Valid id exchange")
7218 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=0
7219 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0)
7220 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7221 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7222 idx += 1
7223 if ctx['num'] == idx:
7224 eap_proto_pwd_test_wait = True
7225 logger.info("Test: Commit payload with valid values")
7226 # EAP-pwd commit request, password prep is NONE
7227 element = binascii.unhexlify("8dcab2862c5396839a6bac0c689ff03d962863108e7c275bbf1d6eedf634ee832a214db99f0d0a1a6317733eecdd97f0fc4cda19f57e1bb9bb9c8dcf8c60ba6f")
7228 scalar = binascii.unhexlify("450f31e058cf2ac2636a5d6e2b3c70b1fcc301957f0716e77f13aa69f9a2e5bd")
7229 payload = struct.pack(">B", 0x02) + element + scalar
7230 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7231 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7232 idx += 1
7233 if ctx['num'] == idx:
7234 logger.info("Test: Unexpected Confirm payload length 0")
7235 # EAP-pwd: Unexpected Confirm payload length 0 (expected 32)
7236 payload = struct.pack(">B", 0x03)
7237 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7238 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7239
7240 idx += 1
7241 if ctx['num'] == idx:
7242 eap_proto_pwd_test_wait = True
7243 logger.info("Test: Valid id exchange")
7244 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=0
7245 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0)
7246 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7247 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7248 idx += 1
7249 if ctx['num'] == idx:
7250 eap_proto_pwd_test_wait = True
7251 logger.info("Test: Commit payload with valid values")
7252 # EAP-pwd commit request, password prep is NONE
7253 element = binascii.unhexlify("8dcab2862c5396839a6bac0c689ff03d962863108e7c275bbf1d6eedf634ee832a214db99f0d0a1a6317733eecdd97f0fc4cda19f57e1bb9bb9c8dcf8c60ba6f")
7254 scalar = binascii.unhexlify("450f31e058cf2ac2636a5d6e2b3c70b1fcc301957f0716e77f13aa69f9a2e5bd")
7255 payload = struct.pack(">B", 0x02) + element + scalar
7256 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7257 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7258 idx += 1
7259 if ctx['num'] == idx:
7260 logger.info("Test: Confirm payload with incorrect value")
7261 # EAP-PWD (peer): confirm did not verify
7262 payload = struct.pack(">B", 0x03) + 32*b'\0'
7263 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7264 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7265
7266 idx += 1
7267 if ctx['num'] == idx:
7268 logger.info("Test: Unexpected confirm exchange")
7269 # EAP-pwd: processing frame: exch 3, len 0
7270 # EAP-PWD: PWD-ID-Req -> FAILURE
7271 payload = struct.pack(">B", 0x03)
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 logger.info("Test: Unsupported password pre-processing technique SASLprep in id exchange")
7278 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=2
7279 # EAP-PWD: Unsupported password pre-processing technique (Prep=2)
7280 # EAP-PWD: PWD-ID-Req -> FAILURE
7281 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 2)
7282 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7283 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7284
7285 idx += 1
7286 if ctx['num'] == idx:
7287 eap_proto_pwd_test_wait = True
7288 logger.info("Test: Valid id exchange")
7289 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=1
7290 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 1)
7291 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7292 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7293 idx += 1
7294 if ctx['num'] == idx:
7295 logger.info("Test: Unexpected Commit payload length (prep=MS)")
7296 # EAP-pwd commit request, password prep is MS
7297 # EAP-pwd: Unexpected Commit payload length 0 (expected 96)
7298 payload = struct.pack(">B", 0x02)
7299 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7300 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7301
7302 idx += 1
7303 if ctx['num'] == idx:
7304 eap_proto_pwd_test_wait = True
7305 logger.info("Test: Valid id exchange")
7306 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=3
7307 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 3)
7308 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7309 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7310 idx += 1
7311 if ctx['num'] == idx:
7312 logger.info("Test: Unexpected Commit payload length (prep=ssha1)")
7313 # EAP-pwd commit request, password prep is salted sha1
7314 # EAP-pwd: Invalid Salt-len
7315 payload = struct.pack(">B", 0x02)
7316 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7317 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7318
7319 idx += 1
7320 if ctx['num'] == idx:
7321 eap_proto_pwd_test_wait = True
7322 logger.info("Test: Valid id exchange")
7323 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=3
7324 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 3)
7325 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7326 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7327 idx += 1
7328 if ctx['num'] == idx:
7329 logger.info("Test: Unexpected Commit payload length (prep=ssha1)")
7330 # EAP-pwd commit request, password prep is salted sha1
7331 # EAP-pwd: Invalid Salt-len
7332 payload = struct.pack(">BB", 0x02, 0)
7333 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7334 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7335
7336 idx += 1
7337 if ctx['num'] == idx:
7338 eap_proto_pwd_test_wait = True
7339 logger.info("Test: Valid id exchange")
7340 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=3
7341 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 3)
7342 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7343 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7344 idx += 1
7345 if ctx['num'] == idx:
7346 logger.info("Test: Unexpected Commit payload length (prep=ssha1)")
7347 # EAP-pwd commit request, password prep is salted sha1
7348 # EAP-pwd: Unexpected Commit payload length 1 (expected 98)
7349 payload = struct.pack(">BB", 0x02, 1)
7350 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7351 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7352
7353 idx += 1
7354 if ctx['num'] == idx:
7355 eap_proto_pwd_test_wait = True
7356 logger.info("Test: Valid id exchange")
7357 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=4
7358 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 4)
7359 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7360 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7361 idx += 1
7362 if ctx['num'] == idx:
7363 logger.info("Test: Unexpected Commit payload length (prep=ssha256)")
7364 # EAP-pwd commit request, password prep is salted sha256
7365 # EAP-pwd: Invalid Salt-len
7366 payload = struct.pack(">B", 0x02)
7367 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7368 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7369
7370 idx += 1
7371 if ctx['num'] == idx:
7372 eap_proto_pwd_test_wait = True
7373 logger.info("Test: Valid id exchange")
7374 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=4
7375 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 4)
7376 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7377 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7378 idx += 1
7379 if ctx['num'] == idx:
7380 logger.info("Test: Unexpected Commit payload length (prep=ssha256)")
7381 # EAP-pwd commit request, password prep is salted sha256
7382 # EAP-pwd: Invalid Salt-len
7383 payload = struct.pack(">BB", 0x02, 0)
7384 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7385 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7386
7387 idx += 1
7388 if ctx['num'] == idx:
7389 eap_proto_pwd_test_wait = True
7390 logger.info("Test: Valid id exchange")
7391 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=4
7392 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 4)
7393 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7394 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7395 idx += 1
7396 if ctx['num'] == idx:
7397 logger.info("Test: Unexpected Commit payload length (prep=ssha256)")
7398 # EAP-pwd commit request, password prep is salted sha256
7399 # EAP-pwd: Unexpected Commit payload length 1 (expected 98)
7400 payload = struct.pack(">BB", 0x02, 1)
7401 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7402 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7403
7404 idx += 1
7405 if ctx['num'] == idx:
7406 eap_proto_pwd_test_wait = True
7407 logger.info("Test: Valid id exchange")
7408 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=5
7409 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 5)
7410 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7411 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7412 idx += 1
7413 if ctx['num'] == idx:
7414 logger.info("Test: Unexpected Commit payload length (prep=ssha512)")
7415 # EAP-pwd commit request, password prep is salted sha512
7416 # EAP-pwd: Invalid Salt-len
7417 payload = struct.pack(">B", 0x02)
7418 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7419 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7420
7421 idx += 1
7422 if ctx['num'] == idx:
7423 eap_proto_pwd_test_wait = True
7424 logger.info("Test: Valid id exchange")
7425 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=5
7426 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 5)
7427 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7428 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7429 idx += 1
7430 if ctx['num'] == idx:
7431 logger.info("Test: Unexpected Commit payload length (prep=ssha512)")
7432 # EAP-pwd commit request, password prep is salted sha512
7433 # EAP-pwd: Invalid Salt-len
7434 payload = struct.pack(">BB", 0x02, 0)
7435 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7436 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7437
7438 idx += 1
7439 if ctx['num'] == idx:
7440 eap_proto_pwd_test_wait = True
7441 logger.info("Test: Valid id exchange")
7442 # EAP-PWD: Server EAP-pwd-ID proposal: group=19 random=1 prf=1 prep=5
7443 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 5)
7444 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7445 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7446 idx += 1
7447 if ctx['num'] == idx:
7448 logger.info("Test: Unexpected Commit payload length (prep=ssha512)")
7449 # EAP-pwd commit request, password prep is salted sha512
7450 # EAP-pwd: Unexpected Commit payload length 1 (expected 98)
7451 payload = struct.pack(">BB", 0x02, 1)
7452 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7453 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7454
7455 logger.info("No more test responses available - test case completed")
7456 global eap_proto_pwd_test_done
7457 eap_proto_pwd_test_done = True
7458 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7459
7460 srv = start_radius_server(pwd_handler)
7461
7462 try:
7463 hapd = start_ap(apdev[0])
7464 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
7465
7466 i = 0
7467 while not eap_proto_pwd_test_done:
7468 i += 1
7469 logger.info("Running connection iteration %d" % i)
7470 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7471 eap="PWD", identity="pwd user",
7472 password="secret password",
7473 wait_connect=False)
7474 ok = False
7475 for j in range(5):
7476 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STATUS",
7477 "CTRL-EVENT-EAP-PROPOSED-METHOD"],
7478 timeout=5)
7479 if ev is None:
7480 raise Exception("Timeout on EAP start")
7481 if "CTRL-EVENT-EAP-PROPOSED-METHOD" in ev:
7482 ok = True
7483 break
7484 if "CTRL-EVENT-EAP-STATUS" in ev and "status='completion' parameter='failure'" in ev:
7485 ok = True
7486 break
7487 if not ok:
7488 raise Exception("Expected EAP event not seen")
7489 if eap_proto_pwd_test_wait:
7490 for k in range(20):
7491 time.sleep(0.1)
7492 if not eap_proto_pwd_test_wait:
7493 break
7494 if eap_proto_pwd_test_wait:
7495 raise Exception("eap_proto_pwd_test_wait not cleared")
7496 dev[0].request("REMOVE_NETWORK all")
7497 dev[0].wait_disconnected(timeout=1)
7498 dev[0].dump_monitor()
7499 finally:
7500 stop_radius_server(srv)
7501
7502 def test_eap_proto_pwd_invalid_scalar(dev, apdev):
7503 """EAP-pwd protocol tests - invalid server scalar"""
7504 check_eap_capa(dev[0], "PWD")
7505 run_eap_proto_pwd_invalid_scalar(dev, apdev, 32*b'\0')
7506 run_eap_proto_pwd_invalid_scalar(dev, apdev, 31*b'\0' + b'\x01')
7507 # Group Order
7508 val = binascii.unhexlify("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551")
7509 run_eap_proto_pwd_invalid_scalar(dev, apdev, val)
7510 # Group Order - 1
7511 val = binascii.unhexlify("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632550")
7512 run_eap_proto_pwd_invalid_scalar(dev, apdev, val, valid_scalar=True)
7513
7514 def run_eap_proto_pwd_invalid_scalar(dev, apdev, scalar, valid_scalar=False):
7515 global eap_proto_pwd_invalid_scalar_fail
7516 eap_proto_pwd_invalid_scalar_fail = False
7517
7518 def pwd_handler(ctx, req):
7519 logger.info("pwd_handler - RX " + binascii.hexlify(req).decode())
7520 if 'num' not in ctx:
7521 ctx['num'] = 0
7522 ctx['num'] = ctx['num'] + 1
7523 if 'id' not in ctx:
7524 ctx['id'] = 1
7525 ctx['id'] = (ctx['id'] + 1) % 256
7526 idx = 0
7527
7528 idx += 1
7529 if ctx['num'] == idx:
7530 logger.info("Test: Valid id exchange")
7531 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0)
7532 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7533 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7534 idx += 1
7535 if ctx['num'] == idx:
7536 logger.info("Test: Commit payload with invalid scalar")
7537 payload = struct.pack(">B", 0x02) + binascii.unhexlify("67feb2b46d59e6dd3af3a429ec9c04a949337564615d3a2c19bdf6826eb6f5efa303aed86af3a072ed819d518d620adb2659f0e84c4f8b739629db8c93088cfc") + scalar
7538 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7539 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7540 idx += 1
7541 if ctx['num'] == idx:
7542 logger.info("Confirm message next - should not get here")
7543 global eap_proto_pwd_invalid_scalar_fail
7544 eap_proto_pwd_invalid_scalar_fail = True
7545 payload = struct.pack(">B", 0x03) + 32*b'\0'
7546 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7547 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7548
7549 logger.info("No more test responses available - test case completed")
7550 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7551
7552 srv = start_radius_server(pwd_handler)
7553
7554 try:
7555 hapd = start_ap(apdev[0])
7556 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
7557
7558 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7559 eap="PWD", identity="pwd user",
7560 password="secret password",
7561 wait_connect=False)
7562 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
7563 if ev is None:
7564 raise Exception("EAP failure not reported")
7565 dev[0].request("REMOVE_NETWORK all")
7566 dev[0].wait_disconnected(timeout=1)
7567 dev[0].dump_monitor()
7568 finally:
7569 stop_radius_server(srv)
7570
7571 if valid_scalar and not eap_proto_pwd_invalid_scalar_fail:
7572 raise Exception("Peer did not accept valid EAP-pwd-Commit scalar")
7573 if not valid_scalar and eap_proto_pwd_invalid_scalar_fail:
7574 raise Exception("Peer did not stop after invalid EAP-pwd-Commit scalar")
7575
7576 def test_eap_proto_pwd_invalid_element(dev, apdev):
7577 """EAP-pwd protocol tests - invalid server element"""
7578 check_eap_capa(dev[0], "PWD")
7579 # Invalid x,y coordinates
7580 run_eap_proto_pwd_invalid_element(dev, apdev, 64*b'\x00')
7581 run_eap_proto_pwd_invalid_element(dev, apdev, 32*b'\x00' + 32*b'\x01')
7582 run_eap_proto_pwd_invalid_element(dev, apdev, 32*b'\x01' + 32*b'\x00')
7583 run_eap_proto_pwd_invalid_element(dev, apdev, 32*b'\xff' + 32*b'\x01')
7584 run_eap_proto_pwd_invalid_element(dev, apdev, 32*b'\x01' + 32*b'\xff')
7585 run_eap_proto_pwd_invalid_element(dev, apdev, 64*b'\xff')
7586 # Not on curve
7587 run_eap_proto_pwd_invalid_element(dev, apdev, 64*b'\x01')
7588
7589 def run_eap_proto_pwd_invalid_element(dev, apdev, element):
7590 global eap_proto_pwd_invalid_element_fail
7591 eap_proto_pwd_invalid_element_fail = False
7592
7593 def pwd_handler(ctx, req):
7594 logger.info("pwd_handler - RX " + binascii.hexlify(req).decode())
7595 if 'num' not in ctx:
7596 ctx['num'] = 0
7597 ctx['num'] = ctx['num'] + 1
7598 if 'id' not in ctx:
7599 ctx['id'] = 1
7600 ctx['id'] = (ctx['id'] + 1) % 256
7601 idx = 0
7602
7603 idx += 1
7604 if ctx['num'] == idx:
7605 logger.info("Test: Valid id exchange")
7606 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0)
7607 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7608 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7609 idx += 1
7610 if ctx['num'] == idx:
7611 logger.info("Test: Commit payload with invalid element")
7612 payload = struct.pack(">B", 0x02) + element + 31*b'\0' + b'\x02'
7613 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7614 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7615 idx += 1
7616 if ctx['num'] == idx:
7617 logger.info("Confirm message next - should not get here")
7618 global eap_proto_pwd_invalid_element_fail
7619 eap_proto_pwd_invalid_element_fail = True
7620 payload = struct.pack(">B", 0x03) + 32*b'\0'
7621 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
7622 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
7623
7624 logger.info("No more test responses available - test case completed")
7625 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
7626
7627 srv = start_radius_server(pwd_handler)
7628
7629 try:
7630 hapd = start_ap(apdev[0])
7631 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
7632
7633 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7634 eap="PWD", identity="pwd user",
7635 password="secret password",
7636 wait_connect=False)
7637 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
7638 if ev is None:
7639 raise Exception("EAP failure not reported")
7640 dev[0].request("REMOVE_NETWORK all")
7641 dev[0].wait_disconnected(timeout=1)
7642 dev[0].dump_monitor()
7643 finally:
7644 stop_radius_server(srv)
7645
7646 if eap_proto_pwd_invalid_element_fail:
7647 raise Exception("Peer did not stop after invalid EAP-pwd-Commit element")
7648
7649 def rx_msg(src):
7650 ev = src.wait_event(["EAPOL-TX"], timeout=5)
7651 if ev is None:
7652 raise Exception("No EAPOL-TX")
7653 return ev.split(' ')[2]
7654
7655 def tx_msg(src, dst, msg):
7656 dst.request("EAPOL_RX " + src.own_addr() + " " + msg)
7657
7658 def proxy_msg(src, dst):
7659 msg = rx_msg(src)
7660 tx_msg(src, dst, msg)
7661 return msg
7662
7663 def start_pwd_exchange(dev, ap):
7664 check_eap_capa(dev, "PWD")
7665 params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap")
7666 hapd = hostapd.add_ap(ap, params)
7667 hapd.request("SET ext_eapol_frame_io 1")
7668 dev.request("SET ext_eapol_frame_io 1")
7669 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP",
7670 eap="PWD", identity="pwd user", password="secret password",
7671 wait_connect=False, scan_freq="2412")
7672 proxy_msg(hapd, dev) # EAP-Identity/Request
7673 proxy_msg(dev, hapd) # EAP-Identity/Response
7674 proxy_msg(hapd, dev) # EAP-pwd-ID/Request
7675 proxy_msg(dev, hapd) # EAP-pwd-ID/Response
7676 return hapd
7677
7678 def test_eap_proto_pwd_unexpected_fragment(dev, apdev):
7679 """EAP-pwd protocol tests - unexpected more-fragment frame"""
7680 hapd = start_pwd_exchange(dev[0], apdev[0])
7681
7682 # EAP-pwd-Commit/Request
7683 req = rx_msg(hapd)
7684 if req[18:20] != "02":
7685 raise Exception("Unexpected EAP-pwd-Commit/Request flag")
7686 msg = req[0:18] + "42" + req[20:]
7687 tx_msg(hapd, dev[0], msg)
7688
7689 def test_eap_proto_pwd_reflection_attack(dev, apdev):
7690 """EAP-pwd protocol tests - reflection attack on the server"""
7691 hapd = start_pwd_exchange(dev[0], apdev[0])
7692
7693 # EAP-pwd-Commit/Request
7694 req = proxy_msg(hapd, dev[0])
7695 if len(req) != 212:
7696 raise Exception("Unexpected EAP-pwd-Commit/Response length")
7697
7698 # EAP-pwd-Commit/Response
7699 resp = rx_msg(dev[0])
7700 # Reflect same Element/Scalar back to the server
7701 msg = resp[0:20] + req[20:]
7702 tx_msg(dev[0], hapd, msg)
7703
7704 # EAP-pwd-Commit/Response or EAP-Failure
7705 req = rx_msg(hapd)
7706 if req[8:10] != "04":
7707 # reflect EAP-pwd-Confirm/Request
7708 msg = req[0:8] + "02" + req[10:]
7709 tx_msg(dev[0], hapd, msg)
7710 req = rx_msg(hapd)
7711 if req[8:10] == "03":
7712 raise Exception("EAP-Success after reflected Element/Scalar")
7713 raise Exception("No EAP-Failure to reject invalid EAP-pwd-Commit/Response")
7714
7715 def test_eap_proto_pwd_invalid_scalar_peer(dev, apdev):
7716 """EAP-pwd protocol tests - invalid peer scalar"""
7717 run_eap_proto_pwd_invalid_scalar_peer(dev, apdev, 32*"00")
7718 run_eap_proto_pwd_invalid_scalar_peer(dev, apdev, 31*"00" + "01")
7719 # Group Order
7720 run_eap_proto_pwd_invalid_scalar_peer(dev, apdev,
7721 "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551")
7722 # Group Order - 1
7723 run_eap_proto_pwd_invalid_scalar_peer(dev, apdev,
7724 "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632550",
7725 valid_scalar=True)
7726
7727 def run_eap_proto_pwd_invalid_scalar_peer(dev, apdev, scalar,
7728 valid_scalar=False):
7729 hapd = start_pwd_exchange(dev[0], apdev[0])
7730 proxy_msg(hapd, dev[0]) # EAP-pwd-Commit/Request
7731
7732 # EAP-pwd-Commit/Response
7733 resp = rx_msg(dev[0])
7734 # Replace scalar with an invalid value
7735 msg = resp[0:20] + resp[20:148] + scalar
7736 tx_msg(dev[0], hapd, msg)
7737
7738 # EAP-pwd-Commit/Response or EAP-Failure
7739 req = rx_msg(hapd)
7740 if valid_scalar and req[8:10] == "04":
7741 raise Exception("Unexpected EAP-Failure with valid scalar")
7742 if not valid_scalar and req[8:10] != "04":
7743 raise Exception("No EAP-Failure to reject invalid scalar")
7744 dev[0].request("REMOVE_NETWORK all")
7745 dev[0].wait_disconnected(timeout=1)
7746 hapd.disable()
7747
7748 def test_eap_proto_pwd_invalid_element_peer(dev, apdev):
7749 """EAP-pwd protocol tests - invalid peer element"""
7750 # Invalid x,y coordinates
7751 run_eap_proto_pwd_invalid_element_peer(dev, apdev, 64*'00')
7752 run_eap_proto_pwd_invalid_element_peer(dev, apdev, 32*'00' + 32*'01')
7753 run_eap_proto_pwd_invalid_element_peer(dev, apdev, 32*'01' + 32*'00')
7754 run_eap_proto_pwd_invalid_element_peer(dev, apdev, 32*'ff' + 32*'01')
7755 run_eap_proto_pwd_invalid_element_peer(dev, apdev, 32*'01' + 32*'ff')
7756 run_eap_proto_pwd_invalid_element_peer(dev, apdev, 64*'ff')
7757 # Not on curve
7758 run_eap_proto_pwd_invalid_element_peer(dev, apdev, 64*'01')
7759
7760 def run_eap_proto_pwd_invalid_element_peer(dev, apdev, element):
7761 hapd = start_pwd_exchange(dev[0], apdev[0])
7762 proxy_msg(hapd, dev[0]) # EAP-pwd-Commit/Request
7763
7764 # EAP-pwd-Commit/Response
7765 resp = rx_msg(dev[0])
7766 # Replace element with an invalid value
7767 msg = resp[0:20] + element + resp[148:]
7768 tx_msg(dev[0], hapd, msg)
7769
7770 # EAP-pwd-Commit/Response or EAP-Failure
7771 req = rx_msg(hapd)
7772 if req[8:10] != "04":
7773 raise Exception("No EAP-Failure to reject invalid element")
7774 dev[0].request("REMOVE_NETWORK all")
7775 dev[0].wait_disconnected(timeout=1)
7776 hapd.disable()
7777
7778 def test_eap_proto_pwd_errors(dev, apdev):
7779 """EAP-pwd local error cases"""
7780 check_eap_capa(dev[0], "PWD")
7781 params = hostapd.wpa2_eap_params(ssid="eap-test")
7782 hapd = hostapd.add_ap(apdev[0], params)
7783 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
7784
7785 for i in range(1, 4):
7786 with alloc_fail(dev[0], i, "eap_pwd_init"):
7787 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7788 eap="PWD", identity="pwd user",
7789 password="secret password",
7790 wait_connect=False)
7791 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
7792 timeout=15)
7793 if ev is None:
7794 raise Exception("Timeout on EAP start")
7795 dev[0].request("REMOVE_NETWORK all")
7796 dev[0].wait_disconnected()
7797
7798 with alloc_fail(dev[0], 1, "eap_pwd_get_session_id"):
7799 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7800 eap="PWD", identity="pwd user",
7801 fragment_size="0",
7802 password="secret password")
7803 dev[0].request("REMOVE_NETWORK all")
7804 dev[0].wait_disconnected()
7805
7806 funcs = ["eap_pwd_getkey", "eap_pwd_get_emsk",
7807 "=wpabuf_alloc;eap_pwd_perform_commit_exchange",
7808 "=wpabuf_alloc;eap_pwd_perform_confirm_exchange"]
7809 for func in funcs:
7810 with alloc_fail(dev[0], 1, func):
7811 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7812 eap="PWD", identity="pwd user@domain",
7813 password="secret password", erp="1",
7814 wait_connect=False)
7815 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
7816 dev[0].request("REMOVE_NETWORK all")
7817 dev[0].wait_disconnected()
7818
7819 for i in range(1, 5):
7820 with alloc_fail(dev[0], i, "eap_pwd_perform_id_exchange"):
7821 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7822 eap="PWD", identity="pwd user",
7823 password="secret password",
7824 wait_connect=False)
7825 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
7826 timeout=15)
7827 if ev is None:
7828 raise Exception("Timeout on EAP start")
7829 ok = False
7830 for j in range(10):
7831 state = dev[0].request('GET_ALLOC_FAIL')
7832 if state.startswith('0:'):
7833 ok = True
7834 break
7835 time.sleep(0.1)
7836 if not ok:
7837 raise Exception("No allocation failure seen")
7838 dev[0].request("REMOVE_NETWORK all")
7839 dev[0].wait_disconnected()
7840
7841 with alloc_fail(dev[0], 1, "wpabuf_alloc;eap_pwd_perform_id_exchange"):
7842 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7843 eap="PWD", identity="pwd user",
7844 password="secret password",
7845 wait_connect=False)
7846 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
7847 timeout=15)
7848 if ev is None:
7849 raise Exception("Timeout on EAP start")
7850 dev[0].request("REMOVE_NETWORK all")
7851 dev[0].wait_disconnected()
7852
7853 for i in range(1, 9):
7854 with alloc_fail(dev[0], i, "eap_pwd_perform_commit_exchange"):
7855 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7856 eap="PWD", identity="pwd user",
7857 password="secret password",
7858 wait_connect=False)
7859 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
7860 timeout=15)
7861 if ev is None:
7862 raise Exception("Timeout on EAP start")
7863 ok = False
7864 for j in range(10):
7865 state = dev[0].request('GET_ALLOC_FAIL')
7866 if state.startswith('0:'):
7867 ok = True
7868 break
7869 time.sleep(0.1)
7870 if not ok:
7871 raise Exception("No allocation failure seen")
7872 dev[0].request("REMOVE_NETWORK all")
7873 dev[0].wait_disconnected()
7874
7875 for i in range(1, 12):
7876 with alloc_fail(dev[0], i, "eap_pwd_perform_confirm_exchange"):
7877 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7878 eap="PWD", identity="pwd user",
7879 password="secret password",
7880 wait_connect=False)
7881 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
7882 timeout=15)
7883 if ev is None:
7884 raise Exception("Timeout on EAP start")
7885 ok = False
7886 for j in range(10):
7887 state = dev[0].request('GET_ALLOC_FAIL')
7888 if state.startswith('0:'):
7889 ok = True
7890 break
7891 time.sleep(0.1)
7892 if not ok:
7893 raise Exception("No allocation failure seen")
7894 dev[0].request("REMOVE_NETWORK all")
7895 dev[0].wait_disconnected()
7896
7897 for i in range(1, 5):
7898 with alloc_fail(dev[0], i, "eap_msg_alloc;=eap_pwd_process"):
7899 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7900 eap="PWD", identity="pwd user",
7901 password="secret password", fragment_size="50",
7902 wait_connect=False)
7903 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
7904 timeout=15)
7905 if ev is None:
7906 raise Exception("Timeout on EAP start")
7907 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
7908 dev[0].request("REMOVE_NETWORK all")
7909 dev[0].wait_disconnected()
7910
7911 # No password configured
7912 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7913 eap="PWD", identity="pwd user",
7914 wait_connect=False)
7915 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD vendor=0 method=52"],
7916 timeout=15)
7917 if ev is None:
7918 raise Exception("EAP-pwd not started")
7919 dev[0].request("REMOVE_NETWORK all")
7920 dev[0].wait_disconnected()
7921
7922 funcs = [(1, "hash_nt_password_hash;eap_pwd_perform_commit_exchange"),
7923 (1, "=crypto_bignum_init;eap_pwd_perform_commit_exchange"),
7924 (1, "=crypto_ec_point_init;eap_pwd_perform_commit_exchange"),
7925 (2, "=crypto_ec_point_init;eap_pwd_perform_commit_exchange"),
7926 (1, "=crypto_ec_point_mul;eap_pwd_perform_commit_exchange"),
7927 (2, "=crypto_ec_point_mul;eap_pwd_perform_commit_exchange"),
7928 (3, "=crypto_ec_point_mul;eap_pwd_perform_commit_exchange"),
7929 (1, "=crypto_ec_point_add;eap_pwd_perform_commit_exchange"),
7930 (1, "=crypto_ec_point_invert;eap_pwd_perform_commit_exchange"),
7931 (1, "=crypto_ec_point_to_bin;eap_pwd_perform_commit_exchange"),
7932 (1, "crypto_hash_finish;eap_pwd_kdf"),
7933 (1, "crypto_ec_point_from_bin;eap_pwd_get_element"),
7934 (3, "crypto_bignum_init;compute_password_element"),
7935 (4, "crypto_bignum_init;compute_password_element"),
7936 (1, "crypto_bignum_init_set;compute_password_element"),
7937 (2, "crypto_bignum_init_set;compute_password_element"),
7938 (3, "crypto_bignum_init_set;compute_password_element"),
7939 (1, "crypto_bignum_to_bin;compute_password_element"),
7940 (1, "crypto_ec_point_compute_y_sqr;compute_password_element"),
7941 (1, "crypto_ec_point_solve_y_coord;compute_password_element"),
7942 (1, "crypto_bignum_rand;compute_password_element"),
7943 (1, "crypto_bignum_sub;compute_password_element")]
7944 for count, func in funcs:
7945 with fail_test(dev[0], count, func):
7946 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7947 eap="PWD", identity="pwd-hash",
7948 password_hex="hash:e3718ece8ab74792cbbfffd316d2d19a",
7949 wait_connect=False)
7950 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
7951 if ev is None:
7952 raise Exception("No EAP-Failure reported")
7953 dev[0].request("REMOVE_NETWORK all")
7954 dev[0].wait_disconnected()
7955
7956 params = {"ssid": "eap-test2", "wpa": "2", "wpa_key_mgmt": "WPA-EAP",
7957 "rsn_pairwise": "CCMP", "ieee8021x": "1",
7958 "eap_server": "1", "eap_user_file": "auth_serv/eap_user.conf",
7959 "pwd_group": "19", "fragment_size": "40"}
7960 hapd2 = hostapd.add_ap(apdev[1], params)
7961 dev[0].scan_for_bss(hapd2.own_addr(), freq=2412)
7962
7963 with alloc_fail(dev[0], 1, "wpabuf_alloc;=eap_pwd_process"):
7964 dev[0].connect("eap-test2", key_mgmt="WPA-EAP", scan_freq="2412",
7965 eap="PWD", identity="pwd user",
7966 password="secret password",
7967 wait_connect=False)
7968 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
7969 dev[0].request("REMOVE_NETWORK all")
7970 dev[0].wait_disconnected()
7971
7972 for i in range(1, 5):
7973 with fail_test(dev[0], i,
7974 "=crypto_ec_point_to_bin;eap_pwd_perform_confirm_exchange"):
7975 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
7976 eap="PWD", identity="pwd-hash",
7977 password_hex="hash:e3718ece8ab74792cbbfffd316d2d19a",
7978 wait_connect=False)
7979 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
7980 if ev is None:
7981 raise Exception("No EAP-Failure reported")
7982 dev[0].request("REMOVE_NETWORK all")
7983 dev[0].wait_disconnected()
7984 dev[0].dump_monitor()
7985
7986 def run_eap_pwd_connect(dev, hash=True, fragment=2000):
7987 if hash:
7988 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP",
7989 fragment_size=str(fragment),
7990 eap="PWD", identity="pwd-hash",
7991 password_hex="hash:e3718ece8ab74792cbbfffd316d2d19a",
7992 scan_freq="2412", wait_connect=False)
7993 else:
7994 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP",
7995 fragment_size=str(fragment),
7996 eap="PWD", identity="pwd-hash-sha1",
7997 password="secret password",
7998 scan_freq="2412", wait_connect=False)
7999 ev = dev.wait_event(["CTRL-EVENT-EAP-SUCCESS", "CTRL-EVENT-EAP-FAILURE",
8000 "CTRL-EVENT-DISCONNECTED"],
8001 timeout=1)
8002 dev.request("REMOVE_NETWORK all")
8003 if not ev or "CTRL-EVENT-DISCONNECTED" not in ev:
8004 dev.wait_disconnected()
8005 dev.dump_monitor()
8006
8007 def test_eap_proto_pwd_errors_server(dev, apdev):
8008 """EAP-pwd local error cases on server"""
8009 check_eap_capa(dev[0], "PWD")
8010 params = int_eap_server_params()
8011 params['erp_domain'] = 'example.com'
8012 params['eap_server_erp'] = '1'
8013 hapd = hostapd.add_ap(apdev[0], params)
8014 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
8015
8016 tests = [(1, "eap_pwd_init"),
8017 (2, "eap_pwd_init"),
8018 (3, "eap_pwd_init"),
8019 (1, "eap_pwd_build_id_req"),
8020 (1, "eap_pwd_build_commit_req"),
8021 (1, "eap_pwd_build_confirm_req"),
8022 (1, "eap_pwd_h_init;eap_pwd_build_confirm_req"),
8023 (1, "wpabuf_alloc;eap_pwd_build_confirm_req"),
8024 (1, "eap_msg_alloc;eap_pwd_build_req"),
8025 (1, "eap_pwd_process_id_resp"),
8026 (1, "get_eap_pwd_group;eap_pwd_process_id_resp"),
8027 (1, "eap_pwd_process_confirm_resp"),
8028 (1, "eap_pwd_h_init;eap_pwd_process_confirm_resp"),
8029 (1, "compute_keys;eap_pwd_process_confirm_resp"),
8030 (1, "eap_pwd_getkey"),
8031 (1, "eap_pwd_get_emsk"),
8032 (1, "eap_pwd_get_session_id")]
8033 for count, func in tests:
8034 with alloc_fail(hapd, count, func):
8035 run_eap_pwd_connect(dev[0], hash=True)
8036
8037 tests = [(1, "eap_msg_alloc;eap_pwd_build_req"),
8038 (2, "eap_msg_alloc;eap_pwd_build_req"),
8039 (1, "wpabuf_alloc;eap_pwd_process")]
8040 for count, func in tests:
8041 with alloc_fail(hapd, count, func):
8042 run_eap_pwd_connect(dev[0], hash=True, fragment=13)
8043
8044 tests = [(4, "eap_pwd_init")]
8045 for count, func in tests:
8046 with alloc_fail(hapd, count, func):
8047 run_eap_pwd_connect(dev[0], hash=False)
8048
8049 tests = [(1, "eap_pwd_build_id_req"),
8050 (1, "eap_pwd_build_commit_req"),
8051 (1, "crypto_ec_point_mul;eap_pwd_build_commit_req"),
8052 (1, "crypto_ec_point_invert;eap_pwd_build_commit_req"),
8053 (1, "crypto_ec_point_to_bin;eap_pwd_build_commit_req"),
8054 (1, "crypto_ec_point_to_bin;eap_pwd_build_confirm_req"),
8055 (2, "=crypto_ec_point_to_bin;eap_pwd_build_confirm_req"),
8056 (1, "hash_nt_password_hash;eap_pwd_process_id_resp"),
8057 (1, "compute_password_element;eap_pwd_process_id_resp"),
8058 (1, "crypto_bignum_init;eap_pwd_process_commit_resp"),
8059 (1, "crypto_ec_point_mul;eap_pwd_process_commit_resp"),
8060 (2, "crypto_ec_point_mul;eap_pwd_process_commit_resp"),
8061 (1, "crypto_ec_point_add;eap_pwd_process_commit_resp"),
8062 (1, "crypto_ec_point_to_bin;eap_pwd_process_confirm_resp"),
8063 (2, "=crypto_ec_point_to_bin;eap_pwd_process_confirm_resp")]
8064 for count, func in tests:
8065 with fail_test(hapd, count, func):
8066 run_eap_pwd_connect(dev[0], hash=True)
8067
8068 def start_pwd_assoc(dev, hapd):
8069 dev.connect("test-wpa2-eap", key_mgmt="WPA-EAP",
8070 eap="PWD", identity="pwd user", password="secret password",
8071 wait_connect=False, scan_freq="2412")
8072 proxy_msg(hapd, dev) # EAP-Identity/Request
8073 proxy_msg(dev, hapd) # EAP-Identity/Response
8074 proxy_msg(hapd, dev) # EAP-pwd-Identity/Request
8075
8076 def stop_pwd_assoc(dev, hapd):
8077 dev.request("REMOVE_NETWORK all")
8078 dev.wait_disconnected()
8079 dev.dump_monitor()
8080 hapd.dump_monitor()
8081
8082 def test_eap_proto_pwd_server(dev, apdev):
8083 """EAP-pwd protocol testing for the server"""
8084 check_eap_capa(dev[0], "PWD")
8085 params = int_eap_server_params()
8086 hapd = hostapd.add_ap(apdev[0], params)
8087 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
8088 hapd.request("SET ext_eapol_frame_io 1")
8089 dev[0].request("SET ext_eapol_frame_io 1")
8090
8091 start_pwd_assoc(dev[0], hapd)
8092 resp = rx_msg(dev[0])
8093 # Replace exch field with unexpected value
8094 # --> EAP-pwd: Unexpected opcode=4 in state=0
8095 msg = resp[0:18] + "04" + resp[20:]
8096 tx_msg(dev[0], hapd, msg)
8097
8098 # Too short EAP-pwd header (no flags/exch field)
8099 # --> EAP-pwd: Invalid frame
8100 msg = resp[0:4] + "0005" + resp[8:12] + "0005" + "34"
8101 tx_msg(dev[0], hapd, msg)
8102
8103 # Too short EAP-pwd header (L=1 but only one octet of total length field)
8104 # --> EAP-pwd: Frame too short to contain Total-Length field
8105 msg = resp[0:4] + "0007" + resp[8:12] + "0007" + "34" + "81ff"
8106 tx_msg(dev[0], hapd, msg)
8107 # server continues exchange, so start from scratch for the next step
8108 rx_msg(hapd)
8109 stop_pwd_assoc(dev[0], hapd)
8110
8111 start_pwd_assoc(dev[0], hapd)
8112 resp = rx_msg(dev[0])
8113 # Too large total length
8114 msg = resp[0:4] + "0008" + resp[8:12] + "0008" + "34" + "c1ffff"
8115 tx_msg(dev[0], hapd, msg)
8116 # server continues exchange, so start from scratch for the next step
8117 rx_msg(hapd)
8118 stop_pwd_assoc(dev[0], hapd)
8119
8120 start_pwd_assoc(dev[0], hapd)
8121 resp = rx_msg(dev[0])
8122 # First fragment
8123 msg = resp[0:4] + "0009" + resp[8:12] + "0009" + "34" + "c100ff" + "aa"
8124 tx_msg(dev[0], hapd, msg)
8125 # Ack
8126 req = rx_msg(hapd)
8127 # Unexpected first fragment
8128 # --> EAP-pwd: Unexpected new fragment start when previous fragment is still in use
8129 msg = resp[0:4] + "0009" + resp[8:10] + req[10:12] + "0009" + "34" + "c100ee" + "bb"
8130 tx_msg(dev[0], hapd, msg)
8131 # server continues exchange, so start from scratch for the next step
8132 rx_msg(hapd)
8133 stop_pwd_assoc(dev[0], hapd)
8134
8135 start_pwd_assoc(dev[0], hapd)
8136 resp = rx_msg(dev[0])
8137 # Too much data in first fragment
8138 # --> EAP-pwd: Buffer overflow attack detected! (0+2 > 1)
8139 msg = resp[0:4] + "000a" + resp[8:12] + "000a" + "34" + "c10001" + "aabb"
8140 tx_msg(dev[0], hapd, msg)
8141 # EAP-Failure
8142 rx_msg(hapd)
8143 stop_pwd_assoc(dev[0], hapd)
8144
8145 start_pwd_assoc(dev[0], hapd)
8146 resp = rx_msg(dev[0])
8147 # Change parameters
8148 # --> EAP-pwd: peer changed parameters
8149 msg = resp[0:20] + "ff" + resp[22:]
8150 tx_msg(dev[0], hapd, msg)
8151 # EAP-Failure
8152 rx_msg(hapd)
8153 stop_pwd_assoc(dev[0], hapd)
8154
8155 start_pwd_assoc(dev[0], hapd)
8156 resp = rx_msg(dev[0])
8157 # Too short ID response
8158 # --> EAP-pwd: Invalid ID response
8159 msg = resp[0:4] + "000a" + resp[8:12] + "000a" + "34" + "01ffeeddcc"
8160 tx_msg(dev[0], hapd, msg)
8161 # server continues exchange, so start from scratch for the next step
8162 rx_msg(hapd)
8163 stop_pwd_assoc(dev[0], hapd)
8164
8165 start_pwd_assoc(dev[0], hapd)
8166 # EAP-pwd-Identity/Response
8167 resp = rx_msg(dev[0])
8168 tx_msg(dev[0], hapd, resp)
8169 # EAP-pwd-Commit/Request
8170 req = rx_msg(hapd)
8171 # Unexpected EAP-pwd-Identity/Response
8172 # --> EAP-pwd: Unexpected opcode=1 in state=1
8173 msg = resp[0:10] + req[10:12] + resp[12:]
8174 tx_msg(dev[0], hapd, msg)
8175 # server continues exchange, so start from scratch for the next step
8176 rx_msg(hapd)
8177 stop_pwd_assoc(dev[0], hapd)
8178
8179 start_pwd_assoc(dev[0], hapd)
8180 proxy_msg(dev[0], hapd) # EAP-pwd-Identity/Response
8181 proxy_msg(hapd, dev[0]) # EAP-pwd-Commit/Request
8182 # EAP-pwd-Commit/Response
8183 resp = rx_msg(dev[0])
8184 # Too short Commit response
8185 # --> EAP-pwd: Unexpected Commit payload length 4 (expected 96)
8186 msg = resp[0:4] + "000a" + resp[8:12] + "000a" + "34" + "02ffeeddcc"
8187 tx_msg(dev[0], hapd, msg)
8188 # EAP-Failure
8189 rx_msg(hapd)
8190 stop_pwd_assoc(dev[0], hapd)
8191
8192 start_pwd_assoc(dev[0], hapd)
8193 proxy_msg(dev[0], hapd) # EAP-pwd-Identity/Response
8194 proxy_msg(hapd, dev[0]) # EAP-pwd-Commit/Request
8195 proxy_msg(dev[0], hapd) # EAP-pwd-Commit/Response
8196 proxy_msg(hapd, dev[0]) # EAP-pwd-Confirm/Request
8197 # EAP-pwd-Confirm/Response
8198 resp = rx_msg(dev[0])
8199 # Too short Confirm response
8200 # --> EAP-pwd: Unexpected Confirm payload length 4 (expected 32)
8201 msg = resp[0:4] + "000a" + resp[8:12] + "000a" + "34" + "03ffeeddcc"
8202 tx_msg(dev[0], hapd, msg)
8203 # EAP-Failure
8204 rx_msg(hapd)
8205 stop_pwd_assoc(dev[0], hapd)
8206
8207 start_pwd_assoc(dev[0], hapd)
8208 resp = rx_msg(dev[0])
8209 # Set M=1
8210 # --> EAP-pwd: No buffer for reassembly
8211 msg = resp[0:18] + "41" + resp[20:]
8212 tx_msg(dev[0], hapd, msg)
8213 # EAP-Failure
8214 rx_msg(hapd)
8215 stop_pwd_assoc(dev[0], hapd)
8216
8217 def test_eap_proto_erp(dev, apdev):
8218 """ERP protocol tests"""
8219 check_erp_capa(dev[0])
8220
8221 global eap_proto_erp_test_done
8222 eap_proto_erp_test_done = False
8223
8224 def erp_handler(ctx, req):
8225 logger.info("erp_handler - RX " + binascii.hexlify(req).decode())
8226 if 'num' not in ctx:
8227 ctx['num'] = 0
8228 ctx['num'] += 1
8229 if 'id' not in ctx:
8230 ctx['id'] = 1
8231 ctx['id'] = (ctx['id'] + 1) % 256
8232 idx = 0
8233
8234 idx += 1
8235 if ctx['num'] == idx:
8236 logger.info("Test: Missing type")
8237 return struct.pack(">BBH", EAP_CODE_INITIATE, ctx['id'], 4)
8238
8239 idx += 1
8240 if ctx['num'] == idx:
8241 logger.info("Test: Unexpected type")
8242 return struct.pack(">BBHB", EAP_CODE_INITIATE, ctx['id'], 4 + 1,
8243 255)
8244
8245 idx += 1
8246 if ctx['num'] == idx:
8247 logger.info("Test: Missing Reserved field")
8248 return struct.pack(">BBHB", EAP_CODE_INITIATE, ctx['id'], 4 + 1,
8249 EAP_ERP_TYPE_REAUTH_START)
8250
8251 idx += 1
8252 if ctx['num'] == idx:
8253 logger.info("Test: Zero-length TVs/TLVs")
8254 payload = b""
8255 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'],
8256 4 + 1 + 1 + len(payload),
8257 EAP_ERP_TYPE_REAUTH_START, 0) + payload
8258
8259 idx += 1
8260 if ctx['num'] == idx:
8261 logger.info("Test: Too short TLV")
8262 payload = struct.pack("B", 191)
8263 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'],
8264 4 + 1 + 1 + len(payload),
8265 EAP_ERP_TYPE_REAUTH_START, 0) + payload
8266
8267 idx += 1
8268 if ctx['num'] == idx:
8269 logger.info("Test: Truncated TLV")
8270 payload = struct.pack("BB", 191, 1)
8271 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'],
8272 4 + 1 + 1 + len(payload),
8273 EAP_ERP_TYPE_REAUTH_START, 0) + payload
8274
8275 idx += 1
8276 if ctx['num'] == idx:
8277 logger.info("Test: Ignored unknown TLV and unknown TV/TLV terminating parsing")
8278 payload = struct.pack("BBB", 191, 0, 192)
8279 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'],
8280 4 + 1 + 1 + len(payload),
8281 EAP_ERP_TYPE_REAUTH_START, 0) + payload
8282
8283 idx += 1
8284 if ctx['num'] == idx:
8285 logger.info("Test: More than one keyName-NAI")
8286 payload = struct.pack("BBBB", EAP_ERP_TLV_KEYNAME_NAI, 0,
8287 EAP_ERP_TLV_KEYNAME_NAI, 0)
8288 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'],
8289 4 + 1 + 1 + len(payload),
8290 EAP_ERP_TYPE_REAUTH_START, 0) + payload
8291
8292 idx += 1
8293 if ctx['num'] == idx:
8294 logger.info("Test: Too short TLV keyName-NAI")
8295 payload = struct.pack("B", EAP_ERP_TLV_KEYNAME_NAI)
8296 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'],
8297 4 + 1 + 1 + len(payload),
8298 EAP_ERP_TYPE_REAUTH_START, 0) + payload
8299
8300 idx += 1
8301 if ctx['num'] == idx:
8302 logger.info("Test: Truncated TLV keyName-NAI")
8303 payload = struct.pack("BB", EAP_ERP_TLV_KEYNAME_NAI, 1)
8304 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'],
8305 4 + 1 + 1 + len(payload),
8306 EAP_ERP_TYPE_REAUTH_START, 0) + payload
8307
8308 idx += 1
8309 if ctx['num'] == idx:
8310 logger.info("Test: Valid rRK lifetime TV followed by too short rMSK lifetime TV")
8311 payload = struct.pack(">BLBH", EAP_ERP_TV_RRK_LIFETIME, 0,
8312 EAP_ERP_TV_RMSK_LIFETIME, 0)
8313 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'],
8314 4 + 1 + 1 + len(payload),
8315 EAP_ERP_TYPE_REAUTH_START, 0) + payload
8316
8317 idx += 1
8318 if ctx['num'] == idx:
8319 logger.info("Test: Missing type (Finish)")
8320 return struct.pack(">BBH", EAP_CODE_FINISH, ctx['id'], 4)
8321
8322 idx += 1
8323 if ctx['num'] == idx:
8324 logger.info("Test: Unexpected type (Finish)")
8325 return struct.pack(">BBHB", EAP_CODE_FINISH, ctx['id'], 4 + 1,
8326 255)
8327
8328 idx += 1
8329 if ctx['num'] == idx:
8330 logger.info("Test: Missing fields (Finish)")
8331 return struct.pack(">BBHB", EAP_CODE_FINISH, ctx['id'], 4 + 1,
8332 EAP_ERP_TYPE_REAUTH)
8333
8334 idx += 1
8335 if ctx['num'] == idx:
8336 logger.info("Test: Unexpected SEQ (Finish)")
8337 return struct.pack(">BBHBBHB", EAP_CODE_FINISH, ctx['id'],
8338 4 + 1 + 4,
8339 EAP_ERP_TYPE_REAUTH, 0, 0xffff, 0)
8340
8341 logger.info("No more test responses available - test case completed")
8342 global eap_proto_erp_test_done
8343 eap_proto_erp_test_done = True
8344 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
8345
8346 srv = start_radius_server(erp_handler)
8347
8348 try:
8349 hapd = start_ap(apdev[0])
8350 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
8351
8352 i = 0
8353 while not eap_proto_erp_test_done:
8354 i += 1
8355 logger.info("Running connection iteration %d" % i)
8356 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8357 eap="PAX", identity="pax.user@example.com",
8358 password_hex="0123456789abcdef0123456789abcdef",
8359 wait_connect=False)
8360 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
8361 if ev is None:
8362 raise Exception("Timeout on EAP start")
8363 time.sleep(0.1)
8364 dev[0].request("REMOVE_NETWORK all")
8365 dev[0].wait_disconnected(timeout=1)
8366 dev[0].dump_monitor()
8367 finally:
8368 stop_radius_server(srv)
8369
8370 def test_eap_proto_fast_errors(dev, apdev):
8371 """EAP-FAST local error cases"""
8372 check_eap_capa(dev[0], "FAST")
8373 params = hostapd.wpa2_eap_params(ssid="eap-test")
8374 hapd = hostapd.add_ap(apdev[0], params)
8375 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
8376
8377 for i in range(1, 5):
8378 with alloc_fail(dev[0], i, "eap_fast_init"):
8379 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8380 eap="FAST", anonymous_identity="FAST",
8381 identity="user", password="password",
8382 ca_cert="auth_serv/ca.pem", phase2="auth=GTC",
8383 phase1="fast_provisioning=2",
8384 pac_file="blob://fast_pac_auth",
8385 wait_connect=False)
8386 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
8387 timeout=5)
8388 if ev is None:
8389 raise Exception("Timeout on EAP start")
8390 dev[0].request("REMOVE_NETWORK all")
8391 dev[0].wait_disconnected()
8392
8393 tests = [(1, "wpabuf_alloc;eap_fast_tlv_eap_payload"),
8394 (1, "eap_fast_derive_key;eap_fast_derive_key_auth"),
8395 (1, "eap_msg_alloc;eap_peer_tls_phase2_nak"),
8396 (1, "wpabuf_alloc;eap_fast_tlv_result"),
8397 (1, "wpabuf_alloc;eap_fast_tlv_pac_ack"),
8398 (1, "=eap_peer_tls_derive_session_id;eap_fast_process_crypto_binding"),
8399 (1, "eap_peer_tls_decrypt;eap_fast_decrypt"),
8400 (1, "eap_fast_getKey"),
8401 (1, "eap_fast_get_session_id"),
8402 (1, "eap_fast_get_emsk")]
8403 for count, func in tests:
8404 dev[0].request("SET blob fast_pac_auth_errors ")
8405 with alloc_fail(dev[0], count, func):
8406 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8407 eap="FAST", anonymous_identity="FAST",
8408 identity="user@example.com", password="password",
8409 ca_cert="auth_serv/ca.pem", phase2="auth=GTC",
8410 phase1="fast_provisioning=2",
8411 pac_file="blob://fast_pac_auth_errors",
8412 erp="1",
8413 wait_connect=False)
8414 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
8415 timeout=15)
8416 if ev is None:
8417 raise Exception("Timeout on EAP start")
8418 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
8419 dev[0].request("REMOVE_NETWORK all")
8420 dev[0].wait_disconnected()
8421
8422 tests = [(1, "eap_fast_derive_key;eap_fast_derive_key_provisioning"),
8423 (1, "eap_mschapv2_getKey;eap_fast_get_phase2_key"),
8424 (1, "=eap_fast_use_pac_opaque"),
8425 (1, "eap_fast_copy_buf"),
8426 (1, "=eap_fast_add_pac"),
8427 (1, "=eap_fast_init_pac_data"),
8428 (1, "=eap_fast_write_pac"),
8429 (2, "=eap_fast_write_pac")]
8430 for count, func in tests:
8431 dev[0].request("SET blob fast_pac_errors ")
8432 with alloc_fail(dev[0], count, func):
8433 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8434 eap="FAST", anonymous_identity="FAST",
8435 identity="user", password="password",
8436 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
8437 phase1="fast_provisioning=1",
8438 pac_file="blob://fast_pac_errors",
8439 erp="1",
8440 wait_connect=False)
8441 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
8442 timeout=15)
8443 if ev is None:
8444 raise Exception("Timeout on EAP start")
8445 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
8446 dev[0].request("REMOVE_NETWORK all")
8447 dev[0].wait_disconnected()
8448
8449 tests = [(1, "eap_fast_get_cmk;eap_fast_process_crypto_binding"),
8450 (1, "eap_fast_derive_eap_msk;eap_fast_process_crypto_binding"),
8451 (1, "eap_fast_derive_eap_emsk;eap_fast_process_crypto_binding")]
8452 for count, func in tests:
8453 dev[0].request("SET blob fast_pac_auth_errors ")
8454 with fail_test(dev[0], count, func):
8455 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8456 eap="FAST", anonymous_identity="FAST",
8457 identity="user", password="password",
8458 ca_cert="auth_serv/ca.pem", phase2="auth=GTC",
8459 phase1="fast_provisioning=2",
8460 pac_file="blob://fast_pac_auth_errors",
8461 erp="1",
8462 wait_connect=False)
8463 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
8464 timeout=15)
8465 if ev is None:
8466 raise Exception("Timeout on EAP start")
8467 wait_fail_trigger(dev[0], "GET_FAIL")
8468 dev[0].request("REMOVE_NETWORK all")
8469 dev[0].wait_disconnected()
8470
8471 dev[0].request("SET blob fast_pac_errors ")
8472 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8473 eap="FAST", anonymous_identity="FAST",
8474 identity="user", password="password",
8475 ca_cert="auth_serv/ca.pem", phase2="auth=GTC",
8476 phase1="fast_provisioning=1",
8477 pac_file="blob://fast_pac_errors",
8478 wait_connect=False)
8479 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5)
8480 if ev is None:
8481 raise Exception("Timeout on EAP start")
8482 # EAP-FAST: Only EAP-MSCHAPv2 is allowed during unauthenticated
8483 # provisioning; reject phase2 type 6
8484 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
8485 if ev is None:
8486 raise Exception("Timeout on EAP failure")
8487 dev[0].request("REMOVE_NETWORK all")
8488 dev[0].wait_disconnected()
8489
8490 logger.info("Wrong password in Phase 2")
8491 dev[0].request("SET blob fast_pac_errors ")
8492 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8493 eap="FAST", anonymous_identity="FAST",
8494 identity="user", password="wrong password",
8495 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
8496 phase1="fast_provisioning=1",
8497 pac_file="blob://fast_pac_errors",
8498 wait_connect=False)
8499 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5)
8500 if ev is None:
8501 raise Exception("Timeout on EAP start")
8502 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
8503 if ev is None:
8504 raise Exception("Timeout on EAP failure")
8505 dev[0].request("REMOVE_NETWORK all")
8506 dev[0].wait_disconnected()
8507
8508 tests = ["FOOBAR\n",
8509 "wpa_supplicant EAP-FAST PAC file - version 1\nFOOBAR\n",
8510 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\n",
8511 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nSTART\n",
8512 "wpa_supplicant EAP-FAST PAC file - version 1\nEND\n",
8513 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nPAC-Type=12345\nEND\n"
8514 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nPAC-Key=12\nEND\n",
8515 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nPAC-Key=1\nEND\n",
8516 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nPAC-Key=1q\nEND\n",
8517 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nPAC-Opaque=1\nEND\n",
8518 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nA-ID=1\nEND\n",
8519 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nI-ID=1\nEND\n",
8520 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nA-ID-Info=1\nEND\n"]
8521 for pac in tests:
8522 blob = binascii.hexlify(pac.encode()).decode()
8523 dev[0].request("SET blob fast_pac_errors " + blob)
8524 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8525 eap="FAST", anonymous_identity="FAST",
8526 identity="user", password="password",
8527 ca_cert="auth_serv/ca.pem", phase2="auth=GTC",
8528 phase1="fast_provisioning=2",
8529 pac_file="blob://fast_pac_errors",
8530 wait_connect=False)
8531 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
8532 timeout=5)
8533 if ev is None:
8534 raise Exception("Timeout on EAP start")
8535 dev[0].request("REMOVE_NETWORK all")
8536 dev[0].wait_disconnected()
8537
8538 tests = ["wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nEND\n",
8539 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nEND\nSTART\nEND\nSTART\nEND\n"]
8540 for pac in tests:
8541 blob = binascii.hexlify(pac.encode()).decode()
8542 dev[0].request("SET blob fast_pac_errors " + blob)
8543 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8544 eap="FAST", anonymous_identity="FAST",
8545 identity="user", password="password",
8546 ca_cert="auth_serv/ca.pem", phase2="auth=GTC",
8547 phase1="fast_provisioning=2",
8548 pac_file="blob://fast_pac_errors")
8549 dev[0].request("REMOVE_NETWORK all")
8550 dev[0].wait_disconnected()
8551
8552 dev[0].request("SET blob fast_pac_errors ")
8553
8554 def test_eap_proto_peap_errors_server(dev, apdev):
8555 """EAP-PEAP local error cases on server"""
8556 params = int_eap_server_params()
8557 hapd = hostapd.add_ap(apdev[0], params)
8558 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
8559
8560 tests = [(1, "get_asymetric_start_key;eap_mschapv2_getKey"),
8561 (1, "generate_authenticator_response_pwhash;eap_mschapv2_process_response"),
8562 (1, "hash_nt_password_hash;eap_mschapv2_process_response"),
8563 (1, "get_master_key;eap_mschapv2_process_response")]
8564 for count, func in tests:
8565 with fail_test(hapd, count, func):
8566 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP",
8567 scan_freq="2412",
8568 eap="PEAP", anonymous_identity="peap",
8569 identity="user", password="password",
8570 phase1="peapver=0 crypto_binding=2",
8571 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
8572 erp="1", wait_connect=False)
8573 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
8574 if ev is None:
8575 raise Exception("EAP-Failure not reported")
8576 dev[0].request("REMOVE_NETWORK all")
8577 dev[0].wait_disconnected()
8578
8579 def test_eap_proto_peap_errors(dev, apdev):
8580 """EAP-PEAP local error cases"""
8581 check_eap_capa(dev[0], "PEAP")
8582 check_eap_capa(dev[0], "MSCHAPV2")
8583 params = hostapd.wpa2_eap_params(ssid="eap-test")
8584 hapd = hostapd.add_ap(apdev[0], params)
8585 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
8586
8587 for i in range(1, 5):
8588 with alloc_fail(dev[0], i, "eap_peap_init"):
8589 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8590 eap="PEAP", anonymous_identity="peap",
8591 identity="user", password="password",
8592 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
8593 wait_connect=False)
8594 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
8595 timeout=5)
8596 if ev is None:
8597 raise Exception("Timeout on EAP start")
8598 dev[0].request("REMOVE_NETWORK all")
8599 dev[0].wait_disconnected()
8600
8601 tests = [(1, "eap_mschapv2_getKey;eap_peap_get_isk;eap_peap_derive_cmk"),
8602 (1, "eap_msg_alloc;eap_tlv_build_result"),
8603 (1, "eap_mschapv2_init;eap_peap_phase2_request"),
8604 (1, "eap_peer_tls_decrypt;eap_peap_decrypt"),
8605 (1, "wpabuf_alloc;=eap_peap_decrypt"),
8606 (1, "eap_peer_tls_encrypt;eap_peap_decrypt"),
8607 (1, "eap_peer_tls_process_helper;eap_peap_process"),
8608 (1, "eap_peer_tls_derive_key;eap_peap_process"),
8609 (1, "eap_peer_tls_derive_session_id;eap_peap_process"),
8610 (1, "eap_peap_getKey"),
8611 (1, "eap_peap_get_session_id")]
8612 for count, func in tests:
8613 with alloc_fail(dev[0], count, func):
8614 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8615 eap="PEAP", anonymous_identity="peap",
8616 identity="user", password="password",
8617 phase1="peapver=0 crypto_binding=2",
8618 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
8619 erp="1", wait_connect=False)
8620 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
8621 timeout=15)
8622 if ev is None:
8623 raise Exception("Timeout on EAP start")
8624 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
8625 dev[0].request("REMOVE_NETWORK all")
8626 dev[0].wait_disconnected()
8627
8628 tests = [(1, "peap_prfplus;eap_peap_derive_cmk"),
8629 (1, "eap_tlv_add_cryptobinding;eap_tlv_build_result"),
8630 (1, "peap_prfplus;eap_peap_getKey"),
8631 (1, "get_asymetric_start_key;eap_mschapv2_getKey")]
8632 for count, func in tests:
8633 with fail_test(dev[0], count, func):
8634 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8635 eap="PEAP", anonymous_identity="peap",
8636 identity="user", password="password",
8637 phase1="peapver=0 crypto_binding=2",
8638 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
8639 erp="1", wait_connect=False)
8640 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
8641 timeout=15)
8642 if ev is None:
8643 raise Exception("Timeout on EAP start")
8644 wait_fail_trigger(dev[0], "GET_FAIL")
8645 dev[0].request("REMOVE_NETWORK all")
8646 dev[0].wait_disconnected()
8647
8648 with alloc_fail(dev[0], 1,
8649 "eap_peer_tls_phase2_nak;eap_peap_phase2_request"):
8650 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8651 eap="PEAP", anonymous_identity="peap",
8652 identity="cert user", password="password",
8653 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
8654 wait_connect=False)
8655 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
8656 dev[0].request("REMOVE_NETWORK all")
8657 dev[0].wait_disconnected()
8658
8659 def test_eap_proto_ttls_errors(dev, apdev):
8660 """EAP-TTLS local error cases"""
8661 check_eap_capa(dev[0], "TTLS")
8662 check_eap_capa(dev[0], "MSCHAPV2")
8663 params = hostapd.wpa2_eap_params(ssid="eap-test")
8664 hapd = hostapd.add_ap(apdev[0], params)
8665 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
8666
8667 for i in range(1, 5):
8668 with alloc_fail(dev[0], i, "eap_ttls_init"):
8669 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8670 eap="TTLS", anonymous_identity="ttls",
8671 identity="user", password="password",
8672 ca_cert="auth_serv/ca.pem",
8673 phase2="autheap=MSCHAPV2",
8674 wait_connect=False)
8675 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
8676 timeout=5)
8677 if ev is None:
8678 raise Exception("Timeout on EAP start")
8679 dev[0].request("REMOVE_NETWORK all")
8680 dev[0].wait_disconnected()
8681
8682 tests = [(1, "eap_peer_tls_derive_key;eap_ttls_v0_derive_key",
8683 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"),
8684 (1, "eap_peer_tls_derive_session_id;eap_ttls_v0_derive_key",
8685 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"),
8686 (1, "wpabuf_alloc;eap_ttls_phase2_request_mschapv2",
8687 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"),
8688 (1, "eap_peer_tls_derive_key;eap_ttls_phase2_request_mschapv2",
8689 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"),
8690 (1, "eap_peer_tls_encrypt;eap_ttls_encrypt_response;eap_ttls_implicit_identity_request",
8691 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"),
8692 (1, "eap_peer_tls_decrypt;eap_ttls_decrypt",
8693 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"),
8694 (1, "eap_ttls_getKey",
8695 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"),
8696 (1, "eap_ttls_get_session_id",
8697 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"),
8698 (1, "eap_ttls_get_emsk",
8699 "mschapv2 user@domain", "auth=MSCHAPV2"),
8700 (1, "wpabuf_alloc;eap_ttls_phase2_request_mschap",
8701 "mschap user", "auth=MSCHAP"),
8702 (1, "eap_peer_tls_derive_key;eap_ttls_phase2_request_mschap",
8703 "mschap user", "auth=MSCHAP"),
8704 (1, "wpabuf_alloc;eap_ttls_phase2_request_chap",
8705 "chap user", "auth=CHAP"),
8706 (1, "eap_peer_tls_derive_key;eap_ttls_phase2_request_chap",
8707 "chap user", "auth=CHAP"),
8708 (1, "wpabuf_alloc;eap_ttls_phase2_request_pap",
8709 "pap user", "auth=PAP"),
8710 (1, "wpabuf_alloc;eap_ttls_avp_encapsulate",
8711 "user", "autheap=MSCHAPV2"),
8712 (1, "eap_mschapv2_init;eap_ttls_phase2_request_eap_method",
8713 "user", "autheap=MSCHAPV2"),
8714 (1, "eap_sm_buildIdentity;eap_ttls_phase2_request_eap",
8715 "user", "autheap=MSCHAPV2"),
8716 (1, "eap_ttls_avp_encapsulate;eap_ttls_phase2_request_eap",
8717 "user", "autheap=MSCHAPV2"),
8718 (1, "eap_ttls_parse_attr_eap",
8719 "user", "autheap=MSCHAPV2"),
8720 (1, "eap_peer_tls_encrypt;eap_ttls_encrypt_response;eap_ttls_process_decrypted",
8721 "user", "autheap=MSCHAPV2"),
8722 (1, "eap_ttls_fake_identity_request",
8723 "user", "autheap=MSCHAPV2"),
8724 (1, "eap_msg_alloc;eap_tls_process_output",
8725 "user", "autheap=MSCHAPV2"),
8726 (1, "eap_msg_alloc;eap_peer_tls_build_ack",
8727 "user", "autheap=MSCHAPV2"),
8728 (1, "tls_connection_decrypt;eap_peer_tls_decrypt",
8729 "user", "autheap=MSCHAPV2"),
8730 (1, "eap_peer_tls_phase2_nak;eap_ttls_phase2_request_eap_method",
8731 "cert user", "autheap=MSCHAPV2")]
8732 for count, func, identity, phase2 in tests:
8733 with alloc_fail(dev[0], count, func):
8734 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8735 eap="TTLS", anonymous_identity="ttls",
8736 identity=identity, password="password",
8737 ca_cert="auth_serv/ca.pem", phase2=phase2,
8738 erp="1", wait_connect=False)
8739 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
8740 timeout=15)
8741 if ev is None:
8742 raise Exception("Timeout on EAP start")
8743 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL",
8744 note="Allocation failure not triggered for: %d:%s" % (count, func))
8745 dev[0].request("REMOVE_NETWORK all")
8746 dev[0].wait_disconnected()
8747
8748 tests = [(1, "os_get_random;eap_ttls_phase2_request_mschapv2"),
8749 (1, "mschapv2_derive_response;eap_ttls_phase2_request_mschapv2")]
8750 for count, func in tests:
8751 with fail_test(dev[0], count, func):
8752 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8753 eap="TTLS", anonymous_identity="ttls",
8754 identity="DOMAIN\mschapv2 user", password="password",
8755 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
8756 erp="1", wait_connect=False)
8757 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
8758 timeout=15)
8759 if ev is None:
8760 raise Exception("Timeout on EAP start")
8761 wait_fail_trigger(dev[0], "GET_FAIL",
8762 note="Test failure not triggered for: %d:%s" % (count, func))
8763 dev[0].request("REMOVE_NETWORK all")
8764 dev[0].wait_disconnected()
8765
8766 tests = [(1, "nt_challenge_response;eap_ttls_phase2_request_mschap")]
8767 for count, func in tests:
8768 with fail_test(dev[0], count, func):
8769 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8770 eap="TTLS", anonymous_identity="ttls",
8771 identity="mschap user", password="password",
8772 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAP",
8773 erp="1", wait_connect=False)
8774 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
8775 timeout=15)
8776 if ev is None:
8777 raise Exception("Timeout on EAP start")
8778 wait_fail_trigger(dev[0], "GET_FAIL",
8779 note="Test failure not triggered for: %d:%s" % (count, func))
8780 dev[0].request("REMOVE_NETWORK all")
8781 dev[0].wait_disconnected()
8782
8783 def test_eap_proto_expanded(dev, apdev):
8784 """EAP protocol tests with expanded header"""
8785 global eap_proto_expanded_test_done
8786 eap_proto_expanded_test_done = False
8787
8788 def expanded_handler(ctx, req):
8789 logger.info("expanded_handler - RX " + binascii.hexlify(req).decode())
8790 if 'num' not in ctx:
8791 ctx['num'] = 0
8792 ctx['num'] += 1
8793 if 'id' not in ctx:
8794 ctx['id'] = 1
8795 ctx['id'] = (ctx['id'] + 1) % 256
8796 idx = 0
8797
8798 idx += 1
8799 if ctx['num'] == idx:
8800 logger.info("Test: MD5 challenge in expanded header")
8801 return struct.pack(">BBHB3BLBBB", EAP_CODE_REQUEST, ctx['id'],
8802 4 + 1 + 3 + 4 + 3,
8803 EAP_TYPE_EXPANDED, 0, 0, 0, EAP_TYPE_MD5,
8804 1, 0xaa, ord('n'))
8805 idx += 1
8806 if ctx['num'] == idx:
8807 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
8808
8809 idx += 1
8810 if ctx['num'] == idx:
8811 logger.info("Test: Invalid expanded EAP length")
8812 return struct.pack(">BBHB3BH", EAP_CODE_REQUEST, ctx['id'],
8813 4 + 1 + 3 + 2,
8814 EAP_TYPE_EXPANDED, 0, 0, 0, EAP_TYPE_MD5)
8815 idx += 1
8816 if ctx['num'] == idx:
8817 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
8818
8819 idx += 1
8820 if ctx['num'] == idx:
8821 logger.info("Test: Invalid expanded frame type")
8822 return struct.pack(">BBHB3BL", EAP_CODE_REQUEST, ctx['id'],
8823 4 + 1 + 3 + 4,
8824 EAP_TYPE_EXPANDED, 0, 0, 1, EAP_TYPE_MD5)
8825 idx += 1
8826 if ctx['num'] == idx:
8827 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
8828
8829 idx += 1
8830 if ctx['num'] == idx:
8831 logger.info("Test: MSCHAPv2 Challenge")
8832 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
8833 4 + 1 + 4 + 1 + 16 + 6,
8834 EAP_TYPE_MSCHAPV2,
8835 1, 0, 4 + 1 + 16 + 6, 16) + 16*b'A' + b'foobar'
8836 idx += 1
8837 if ctx['num'] == idx:
8838 logger.info("Test: Invalid expanded frame type")
8839 return struct.pack(">BBHB3BL", EAP_CODE_REQUEST, ctx['id'],
8840 4 + 1 + 3 + 4,
8841 EAP_TYPE_EXPANDED, 0, 0, 1, EAP_TYPE_MSCHAPV2)
8842
8843 logger.info("No more test responses available - test case completed")
8844 global eap_proto_expanded_test_done
8845 eap_proto_expanded_test_done = True
8846 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
8847
8848 srv = start_radius_server(expanded_handler)
8849
8850 try:
8851 hapd = start_ap(apdev[0])
8852 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
8853
8854 i = 0
8855 while not eap_proto_expanded_test_done:
8856 i += 1
8857 logger.info("Running connection iteration %d" % i)
8858 if i == 4:
8859 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8860 eap="MSCHAPV2", identity="user",
8861 password="password",
8862 wait_connect=False)
8863 else:
8864 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
8865 eap="MD5", identity="user", password="password",
8866 wait_connect=False)
8867 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
8868 if ev is None:
8869 raise Exception("Timeout on EAP start")
8870 if i in [1]:
8871 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5)
8872 if ev is None:
8873 raise Exception("Timeout on EAP method start")
8874 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
8875 if ev is None:
8876 raise Exception("Timeout on EAP failure")
8877 elif i in [2, 3]:
8878 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
8879 timeout=5)
8880 if ev is None:
8881 raise Exception("Timeout on EAP proposed method")
8882 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
8883 if ev is None:
8884 raise Exception("Timeout on EAP failure")
8885 else:
8886 time.sleep(0.1)
8887 dev[0].request("REMOVE_NETWORK all")
8888 dev[0].wait_disconnected(timeout=1)
8889 dev[0].dump_monitor()
8890 finally:
8891 stop_radius_server(srv)
8892
8893 def test_eap_proto_tls(dev, apdev):
8894 """EAP-TLS protocol tests"""
8895 check_eap_capa(dev[0], "TLS")
8896 global eap_proto_tls_test_done, eap_proto_tls_test_wait
8897 eap_proto_tls_test_done = False
8898 eap_proto_tls_test_wait = False
8899
8900 def tls_handler(ctx, req):
8901 logger.info("tls_handler - RX " + binascii.hexlify(req).decode())
8902 if 'num' not in ctx:
8903 ctx['num'] = 0
8904 ctx['num'] += 1
8905 if 'id' not in ctx:
8906 ctx['id'] = 1
8907 ctx['id'] = (ctx['id'] + 1) % 256
8908 idx = 0
8909
8910 global eap_proto_tls_test_wait
8911
8912 idx += 1
8913 if ctx['num'] == idx:
8914 logger.info("Test: Too much payload in TLS/Start: TLS Message Length (0 bytes) smaller than this fragment (1 bytes)")
8915 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'],
8916 4 + 1 + 1 + 4 + 1,
8917 EAP_TYPE_TLS, 0xa0, 0, 1)
8918
8919 idx += 1
8920 if ctx['num'] == idx:
8921 logger.info("Test: Fragmented TLS/Start")
8922 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'],
8923 4 + 1 + 1 + 4 + 1,
8924 EAP_TYPE_TLS, 0xe0, 2, 1)
8925 idx += 1
8926 if ctx['num'] == idx:
8927 logger.info("Test: Too long fragment of TLS/Start: Invalid reassembly state: tls_in_left=2 tls_in_len=0 in_len=0")
8928 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
8929 4 + 1 + 1 + 2,
8930 EAP_TYPE_TLS, 0x00, 2, 3)
8931 idx += 1
8932 if ctx['num'] == idx:
8933 logger.info("Test: EAP-Failure")
8934 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
8935
8936 idx += 1
8937 if ctx['num'] == idx:
8938 logger.info("Test: TLS/Start")
8939 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
8940 4 + 1 + 1,
8941 EAP_TYPE_TLS, 0x20)
8942 idx += 1
8943 if ctx['num'] == idx:
8944 logger.info("Test: Fragmented TLS message")
8945 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'],
8946 4 + 1 + 1 + 4 + 1,
8947 EAP_TYPE_TLS, 0xc0, 2, 1)
8948 idx += 1
8949 if ctx['num'] == idx:
8950 logger.info("Test: Invalid TLS message: no Flags octet included + workaround")
8951 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
8952 4 + 1,
8953 EAP_TYPE_TLS)
8954 idx += 1
8955 if ctx['num'] == idx:
8956 logger.info("Test: Too long fragment of TLS message: more data than TLS message length indicated")
8957 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
8958 4 + 1 + 1 + 2,
8959 EAP_TYPE_TLS, 0x00, 2, 3)
8960 idx += 1
8961 if ctx['num'] == idx:
8962 logger.info("Test: EAP-Failure")
8963 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
8964
8965 idx += 1
8966 if ctx['num'] == idx:
8967 logger.info("Test: Fragmented TLS/Start and truncated Message Length field")
8968 return struct.pack(">BBHBB3B", EAP_CODE_REQUEST, ctx['id'],
8969 4 + 1 + 1 + 3,
8970 EAP_TYPE_TLS, 0xe0, 1, 2, 3)
8971
8972 idx += 1
8973 if ctx['num'] == idx:
8974 logger.info("Test: TLS/Start")
8975 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
8976 4 + 1 + 1,
8977 EAP_TYPE_TLS, 0x20)
8978 idx += 1
8979 if ctx['num'] == idx:
8980 logger.info("Test: Fragmented TLS message")
8981 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'],
8982 4 + 1 + 1 + 4 + 1,
8983 EAP_TYPE_TLS, 0xc0, 2, 1)
8984 idx += 1
8985 if ctx['num'] == idx:
8986 logger.info("Test: Invalid TLS message: no Flags octet included + workaround disabled")
8987 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
8988 4 + 1,
8989 EAP_TYPE_TLS)
8990
8991 idx += 1
8992 if ctx['num'] == idx:
8993 logger.info("Test: TLS/Start")
8994 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
8995 4 + 1 + 1,
8996 EAP_TYPE_TLS, 0x20)
8997 idx += 1
8998 if ctx['num'] == idx:
8999 logger.info("Test: Fragmented TLS message (long; first)")
9000 payload = 1450*b'A'
9001 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'],
9002 4 + 1 + 1 + 4 + len(payload),
9003 EAP_TYPE_TLS, 0xc0, 65536) + payload
9004 # "Too long TLS fragment (size over 64 kB)" on the last one
9005 for i in range(44):
9006 idx += 1
9007 if ctx['num'] == idx:
9008 logger.info("Test: Fragmented TLS message (long; cont %d)" % i)
9009 eap_proto_tls_test_wait = True
9010 payload = 1470*b'A'
9011 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9012 4 + 1 + 1 + len(payload),
9013 EAP_TYPE_TLS, 0x40) + payload
9014 eap_proto_tls_test_wait = False
9015 idx += 1
9016 if ctx['num'] == idx:
9017 logger.info("Test: EAP-Failure")
9018 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9019
9020 idx += 1
9021 if ctx['num'] == idx:
9022 logger.info("Test: TLS/Start")
9023 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9024 4 + 1 + 1,
9025 EAP_TYPE_TLS, 0x20)
9026 idx += 1
9027 if ctx['num'] == idx:
9028 logger.info("Test: Non-ACK to more-fragment message")
9029 return struct.pack(">BBHBBB", EAP_CODE_REQUEST, ctx['id'],
9030 4 + 1 + 1 + 1,
9031 EAP_TYPE_TLS, 0x00, 255)
9032 idx += 1
9033 if ctx['num'] == idx:
9034 logger.info("Test: EAP-Failure")
9035 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9036
9037 logger.info("No more test responses available - test case completed")
9038 global eap_proto_tls_test_done
9039 eap_proto_tls_test_done = True
9040 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9041
9042 srv = start_radius_server(tls_handler)
9043
9044 try:
9045 hapd = start_ap(apdev[0])
9046 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
9047
9048 i = 0
9049 while not eap_proto_tls_test_done:
9050 i += 1
9051 logger.info("Running connection iteration %d" % i)
9052 workaround = "0" if i == 6 else "1"
9053 fragment_size = "100" if i == 8 else "1400"
9054 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
9055 eap="TLS", identity="tls user",
9056 ca_cert="auth_serv/ca.pem",
9057 client_cert="auth_serv/user.pem",
9058 private_key="auth_serv/user.key",
9059 eap_workaround=workaround,
9060 fragment_size=fragment_size,
9061 wait_connect=False)
9062 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
9063 if ev is None:
9064 raise Exception("Timeout on EAP start")
9065 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD",
9066 "CTRL-EVENT-EAP-STATUS"], timeout=5)
9067 if ev is None:
9068 raise Exception("Timeout on EAP method start")
9069 time.sleep(0.1)
9070 start = os.times()[4]
9071 while eap_proto_tls_test_wait:
9072 now = os.times()[4]
9073 if now - start > 10:
9074 break
9075 time.sleep(0.1)
9076 dev[0].request("REMOVE_NETWORK all")
9077 dev[0].wait_disconnected(timeout=1)
9078 dev[0].dump_monitor()
9079 finally:
9080 stop_radius_server(srv)
9081
9082 def test_eap_proto_tnc(dev, apdev):
9083 """EAP-TNC protocol tests"""
9084 check_eap_capa(dev[0], "TNC")
9085 global eap_proto_tnc_test_done
9086 eap_proto_tnc_test_done = False
9087
9088 def tnc_handler(ctx, req):
9089 logger.info("tnc_handler - RX " + binascii.hexlify(req).decode())
9090 if 'num' not in ctx:
9091 ctx['num'] = 0
9092 ctx['num'] += 1
9093 if 'id' not in ctx:
9094 ctx['id'] = 1
9095 ctx['id'] = (ctx['id'] + 1) % 256
9096 idx = 0
9097
9098 idx += 1
9099 if ctx['num'] == idx:
9100 logger.info("Test: TNC start with unsupported version")
9101 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9102 4 + 1 + 1,
9103 EAP_TYPE_TNC, 0x20)
9104
9105 idx += 1
9106 if ctx['num'] == idx:
9107 logger.info("Test: TNC without Flags field")
9108 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
9109 4 + 1,
9110 EAP_TYPE_TNC)
9111
9112 idx += 1
9113 if ctx['num'] == idx:
9114 logger.info("Test: Message underflow due to missing Message Length")
9115 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9116 4 + 1 + 1,
9117 EAP_TYPE_TNC, 0xa1)
9118
9119 idx += 1
9120 if ctx['num'] == idx:
9121 logger.info("Test: Invalid Message Length")
9122 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'],
9123 4 + 1 + 1 + 4 + 1,
9124 EAP_TYPE_TNC, 0xa1, 0, 0)
9125
9126 idx += 1
9127 if ctx['num'] == idx:
9128 logger.info("Test: Invalid Message Length")
9129 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'],
9130 4 + 1 + 1 + 4,
9131 EAP_TYPE_TNC, 0xe1, 75001)
9132
9133 idx += 1
9134 if ctx['num'] == idx:
9135 logger.info("Test: Start with Message Length")
9136 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'],
9137 4 + 1 + 1 + 4,
9138 EAP_TYPE_TNC, 0xa1, 1)
9139 idx += 1
9140 if ctx['num'] == idx:
9141 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9142
9143 idx += 1
9144 if ctx['num'] == idx:
9145 logger.info("Test: Server used start flag again")
9146 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9147 4 + 1 + 1,
9148 EAP_TYPE_TNC, 0x21)
9149 idx += 1
9150 if ctx['num'] == idx:
9151 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9152 4 + 1 + 1,
9153 EAP_TYPE_TNC, 0x21)
9154
9155 idx += 1
9156 if ctx['num'] == idx:
9157 logger.info("Test: Fragmentation and unexpected payload in ack")
9158 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9159 4 + 1 + 1,
9160 EAP_TYPE_TNC, 0x21)
9161 idx += 1
9162 if ctx['num'] == idx:
9163 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9164 4 + 1 + 1,
9165 EAP_TYPE_TNC, 0x01)
9166 idx += 1
9167 if ctx['num'] == idx:
9168 return struct.pack(">BBHBBB", EAP_CODE_REQUEST, ctx['id'],
9169 4 + 1 + 1 + 1,
9170 EAP_TYPE_TNC, 0x01, 0)
9171
9172 idx += 1
9173 if ctx['num'] == idx:
9174 logger.info("Test: Server fragmenting and fragment overflow")
9175 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'],
9176 4 + 1 + 1 + 4 + 1,
9177 EAP_TYPE_TNC, 0xe1, 2, 1)
9178 idx += 1
9179 if ctx['num'] == idx:
9180 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
9181 4 + 1 + 1 + 2,
9182 EAP_TYPE_TNC, 0x01, 2, 3)
9183
9184 idx += 1
9185 if ctx['num'] == idx:
9186 logger.info("Test: Server fragmenting and no message length in a fragment")
9187 return struct.pack(">BBHBBB", EAP_CODE_REQUEST, ctx['id'],
9188 4 + 1 + 1 + 1,
9189 EAP_TYPE_TNC, 0x61, 2)
9190
9191 idx += 1
9192 if ctx['num'] == idx:
9193 logger.info("Test: TNC start followed by invalid TNCCS-Batch")
9194 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9195 4 + 1 + 1,
9196 EAP_TYPE_TNC, 0x21)
9197 idx += 1
9198 if ctx['num'] == idx:
9199 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
9200 resp = b"FOO"
9201 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9202 4 + 1 + 1 + len(resp),
9203 EAP_TYPE_TNC, 0x01) + resp
9204
9205 idx += 1
9206 if ctx['num'] == idx:
9207 logger.info("Test: TNC start followed by invalid TNCCS-Batch (2)")
9208 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9209 4 + 1 + 1,
9210 EAP_TYPE_TNC, 0x21)
9211 idx += 1
9212 if ctx['num'] == idx:
9213 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
9214 resp = b"</TNCCS-Batch><TNCCS-Batch>"
9215 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9216 4 + 1 + 1 + len(resp),
9217 EAP_TYPE_TNC, 0x01) + resp
9218
9219 idx += 1
9220 if ctx['num'] == idx:
9221 logger.info("Test: TNCCS-Batch missing BatchId attribute")
9222 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9223 4 + 1 + 1,
9224 EAP_TYPE_TNC, 0x21)
9225 idx += 1
9226 if ctx['num'] == idx:
9227 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
9228 resp = b"<TNCCS-Batch foo=3></TNCCS-Batch>"
9229 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9230 4 + 1 + 1 + len(resp),
9231 EAP_TYPE_TNC, 0x01) + resp
9232
9233 idx += 1
9234 if ctx['num'] == idx:
9235 logger.info("Test: Unexpected IF-TNCCS BatchId")
9236 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9237 4 + 1 + 1,
9238 EAP_TYPE_TNC, 0x21)
9239 idx += 1
9240 if ctx['num'] == idx:
9241 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
9242 resp = b"<TNCCS-Batch BatchId=123456789></TNCCS-Batch>"
9243 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9244 4 + 1 + 1 + len(resp),
9245 EAP_TYPE_TNC, 0x01) + resp
9246
9247 idx += 1
9248 if ctx['num'] == idx:
9249 logger.info("Test: Missing IMC-IMV-Message and TNCC-TNCS-Message end tags")
9250 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9251 4 + 1 + 1,
9252 EAP_TYPE_TNC, 0x21)
9253 idx += 1
9254 if ctx['num'] == idx:
9255 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
9256 resp = b"<TNCCS-Batch BatchId=2><IMC-IMV-Message><TNCC-TNCS-Message></TNCCS-Batch>"
9257 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9258 4 + 1 + 1 + len(resp),
9259 EAP_TYPE_TNC, 0x01) + resp
9260 idx += 1
9261 if ctx['num'] == idx:
9262 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9263
9264 idx += 1
9265 if ctx['num'] == idx:
9266 logger.info("Test: Missing IMC-IMV-Message and TNCC-TNCS-Message Type")
9267 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9268 4 + 1 + 1,
9269 EAP_TYPE_TNC, 0x21)
9270 idx += 1
9271 if ctx['num'] == idx:
9272 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
9273 resp = b"<TNCCS-Batch BatchId=2><IMC-IMV-Message></IMC-IMV-Message><TNCC-TNCS-Message></TNCC-TNCS-Message></TNCCS-Batch>"
9274 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9275 4 + 1 + 1 + len(resp),
9276 EAP_TYPE_TNC, 0x01) + resp
9277 idx += 1
9278 if ctx['num'] == idx:
9279 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9280
9281 idx += 1
9282 if ctx['num'] == idx:
9283 logger.info("Test: Missing TNCC-TNCS-Message XML end tag")
9284 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9285 4 + 1 + 1,
9286 EAP_TYPE_TNC, 0x21)
9287 idx += 1
9288 if ctx['num'] == idx:
9289 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
9290 resp = b"<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type><XML></TNCC-TNCS-Message></TNCCS-Batch>"
9291 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9292 4 + 1 + 1 + len(resp),
9293 EAP_TYPE_TNC, 0x01) + resp
9294 idx += 1
9295 if ctx['num'] == idx:
9296 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9297
9298 idx += 1
9299 if ctx['num'] == idx:
9300 logger.info("Test: Missing TNCC-TNCS-Message Base64 start tag")
9301 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9302 4 + 1 + 1,
9303 EAP_TYPE_TNC, 0x21)
9304 idx += 1
9305 if ctx['num'] == idx:
9306 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
9307 resp = b"<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type></TNCC-TNCS-Message></TNCCS-Batch>"
9308 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9309 4 + 1 + 1 + len(resp),
9310 EAP_TYPE_TNC, 0x01) + resp
9311 idx += 1
9312 if ctx['num'] == idx:
9313 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9314
9315 idx += 1
9316 if ctx['num'] == idx:
9317 logger.info("Test: Missing TNCC-TNCS-Message Base64 end tag")
9318 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9319 4 + 1 + 1,
9320 EAP_TYPE_TNC, 0x21)
9321 idx += 1
9322 if ctx['num'] == idx:
9323 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
9324 resp = b"<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type><Base64>abc</TNCC-TNCS-Message></TNCCS-Batch>"
9325 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9326 4 + 1 + 1 + len(resp),
9327 EAP_TYPE_TNC, 0x01) + resp
9328 idx += 1
9329 if ctx['num'] == idx:
9330 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9331
9332 idx += 1
9333 if ctx['num'] == idx:
9334 logger.info("Test: TNCC-TNCS-Message Base64 message")
9335 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9336 4 + 1 + 1,
9337 EAP_TYPE_TNC, 0x21)
9338 idx += 1
9339 if ctx['num'] == idx:
9340 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
9341 resp = b"<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type><Base64>aGVsbG8=</Base64></TNCC-TNCS-Message></TNCCS-Batch>"
9342 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9343 4 + 1 + 1 + len(resp),
9344 EAP_TYPE_TNC, 0x01) + resp
9345 idx += 1
9346 if ctx['num'] == idx:
9347 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9348
9349 idx += 1
9350 if ctx['num'] == idx:
9351 logger.info("Test: Invalid TNCC-TNCS-Message XML message")
9352 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9353 4 + 1 + 1,
9354 EAP_TYPE_TNC, 0x21)
9355 idx += 1
9356 if ctx['num'] == idx:
9357 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
9358 resp = b"<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type><XML>hello</XML></TNCC-TNCS-Message></TNCCS-Batch>"
9359 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9360 4 + 1 + 1 + len(resp),
9361 EAP_TYPE_TNC, 0x01) + resp
9362 idx += 1
9363 if ctx['num'] == idx:
9364 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9365
9366 idx += 1
9367 if ctx['num'] == idx:
9368 logger.info("Test: Missing TNCCS-Recommendation type")
9369 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9370 4 + 1 + 1,
9371 EAP_TYPE_TNC, 0x21)
9372 idx += 1
9373 if ctx['num'] == idx:
9374 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
9375 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>'
9376 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9377 4 + 1 + 1 + len(resp),
9378 EAP_TYPE_TNC, 0x01) + resp
9379 idx += 1
9380 if ctx['num'] == idx:
9381 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9382
9383 idx += 1
9384 if ctx['num'] == idx:
9385 logger.info("Test: TNCCS-Recommendation type=none")
9386 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9387 4 + 1 + 1,
9388 EAP_TYPE_TNC, 0x21)
9389 idx += 1
9390 if ctx['num'] == idx:
9391 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
9392 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>'
9393 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9394 4 + 1 + 1 + len(resp),
9395 EAP_TYPE_TNC, 0x01) + resp
9396 idx += 1
9397 if ctx['num'] == idx:
9398 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9399
9400 idx += 1
9401 if ctx['num'] == idx:
9402 logger.info("Test: TNCCS-Recommendation type=isolate")
9403 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9404 4 + 1 + 1,
9405 EAP_TYPE_TNC, 0x21)
9406 idx += 1
9407 if ctx['num'] == idx:
9408 logger.info("Received TNCCS-Batch: " + binascii.hexlify(req[6:]).decode())
9409 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>'
9410 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9411 4 + 1 + 1 + len(resp),
9412 EAP_TYPE_TNC, 0x01) + resp
9413 idx += 1
9414 if ctx['num'] == idx:
9415 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9416
9417 logger.info("No more test responses available - test case completed")
9418 global eap_proto_tnc_test_done
9419 eap_proto_tnc_test_done = True
9420 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9421
9422 srv = start_radius_server(tnc_handler)
9423
9424 try:
9425 hapd = start_ap(apdev[0])
9426 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
9427
9428 i = 0
9429 while not eap_proto_tnc_test_done:
9430 i += 1
9431 logger.info("Running connection iteration %d" % i)
9432 frag = 1400
9433 if i == 8:
9434 frag = 150
9435 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
9436 eap="TNC", identity="tnc", fragment_size=str(frag),
9437 wait_connect=False)
9438 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
9439 if ev is None:
9440 raise Exception("Timeout on EAP start")
9441 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD",
9442 "CTRL-EVENT-EAP-STATUS"], timeout=5)
9443 if ev is None:
9444 raise Exception("Timeout on EAP method start")
9445 time.sleep(0.1)
9446 dev[0].request("REMOVE_NETWORK all")
9447 dev[0].wait_disconnected(timeout=1)
9448 dev[0].dump_monitor()
9449 finally:
9450 stop_radius_server(srv)
9451
9452 def test_eap_canned_success_after_identity(dev, apdev):
9453 """EAP protocol tests for canned EAP-Success after identity"""
9454 check_eap_capa(dev[0], "MD5")
9455 def eap_canned_success_handler(ctx, req):
9456 logger.info("eap_canned_success_handler - RX " + binascii.hexlify(req).decode())
9457 if 'num' not in ctx:
9458 ctx['num'] = 0
9459 ctx['num'] = ctx['num'] + 1
9460 if 'id' not in ctx:
9461 ctx['id'] = 1
9462 ctx['id'] = (ctx['id'] + 1) % 256
9463 idx = 0
9464
9465 idx += 1
9466 if ctx['num'] == idx:
9467 logger.info("Test: EAP-Success")
9468 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4)
9469
9470 idx += 1
9471 if ctx['num'] == idx:
9472 logger.info("Test: EAP-Success")
9473 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4)
9474
9475 return None
9476
9477 srv = start_radius_server(eap_canned_success_handler)
9478
9479 try:
9480 hapd = start_ap(apdev[0])
9481 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
9482
9483 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
9484 phase1="allow_canned_success=1",
9485 eap="MD5", identity="user", password="password",
9486 wait_connect=False)
9487 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15)
9488 if ev is None:
9489 raise Exception("Timeout on EAP success")
9490 dev[0].request("REMOVE_NETWORK all")
9491 dev[0].wait_disconnected()
9492
9493 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
9494 eap="MD5", identity="user", password="password",
9495 wait_connect=False)
9496 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
9497 if ev is None:
9498 raise Exception("Timeout on EAP start")
9499 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=0.1)
9500 if ev is not None:
9501 raise Exception("Unexpected EAP success")
9502 dev[0].request("REMOVE_NETWORK all")
9503 dev[0].wait_disconnected()
9504 finally:
9505 stop_radius_server(srv)
9506
9507 def test_eap_proto_wsc(dev, apdev):
9508 """EAP-WSC protocol tests"""
9509 global eap_proto_wsc_test_done, eap_proto_wsc_wait_failure
9510 eap_proto_wsc_test_done = False
9511
9512 def wsc_handler(ctx, req):
9513 logger.info("wsc_handler - RX " + binascii.hexlify(req).decode())
9514 if 'num' not in ctx:
9515 ctx['num'] = 0
9516 ctx['num'] += 1
9517 if 'id' not in ctx:
9518 ctx['id'] = 1
9519 ctx['id'] = (ctx['id'] + 1) % 256
9520 idx = 0
9521
9522 global eap_proto_wsc_wait_failure
9523 eap_proto_wsc_wait_failure = False
9524
9525 idx += 1
9526 if ctx['num'] == idx:
9527 logger.info("Test: Missing Flags field")
9528 return struct.pack(">BBHB3BLB", EAP_CODE_REQUEST, ctx['id'],
9529 4 + 1 + 3 + 4 + 1,
9530 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
9531 1)
9532
9533 idx += 1
9534 if ctx['num'] == idx:
9535 logger.info("Test: Message underflow (missing Message Length field)")
9536 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'],
9537 4 + 1 + 3 + 4 + 2,
9538 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
9539 1, 0x02)
9540
9541 idx += 1
9542 if ctx['num'] == idx:
9543 logger.info("Test: Invalid Message Length (> 50000)")
9544 return struct.pack(">BBHB3BLBBH", EAP_CODE_REQUEST, ctx['id'],
9545 4 + 1 + 3 + 4 + 4,
9546 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
9547 1, 0x02, 65535)
9548
9549 idx += 1
9550 if ctx['num'] == idx:
9551 logger.info("Test: Invalid Message Length (< current payload)")
9552 return struct.pack(">BBHB3BLBBHB", EAP_CODE_REQUEST, ctx['id'],
9553 4 + 1 + 3 + 4 + 5,
9554 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
9555 1, 0x02, 0, 0xff)
9556
9557 idx += 1
9558 if ctx['num'] == idx:
9559 logger.info("Test: Unexpected Op-Code 5 in WAIT_START state")
9560 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'],
9561 4 + 1 + 3 + 4 + 2,
9562 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
9563 5, 0x00)
9564
9565 idx += 1
9566 if ctx['num'] == idx:
9567 logger.info("Test: Valid WSC Start to start the sequence")
9568 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'],
9569 4 + 1 + 3 + 4 + 2,
9570 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
9571 1, 0x00)
9572 idx += 1
9573 if ctx['num'] == idx:
9574 logger.info("Test: No Message Length field in a fragmented packet")
9575 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'],
9576 4 + 1 + 3 + 4 + 2,
9577 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
9578 4, 0x01)
9579
9580 idx += 1
9581 if ctx['num'] == idx:
9582 logger.info("Test: Valid WSC Start to start the sequence")
9583 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'],
9584 4 + 1 + 3 + 4 + 2,
9585 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
9586 1, 0x00)
9587 idx += 1
9588 if ctx['num'] == idx:
9589 logger.info("Test: Valid first fragmented packet")
9590 return struct.pack(">BBHB3BLBBHB", EAP_CODE_REQUEST, ctx['id'],
9591 4 + 1 + 3 + 4 + 5,
9592 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
9593 4, 0x03, 10, 1)
9594 idx += 1
9595 if ctx['num'] == idx:
9596 logger.info("Test: Unexpected Op-Code 5 in fragment (expected 4)")
9597 return struct.pack(">BBHB3BLBBB", EAP_CODE_REQUEST, ctx['id'],
9598 4 + 1 + 3 + 4 + 3,
9599 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
9600 5, 0x01, 2)
9601
9602 idx += 1
9603 if ctx['num'] == idx:
9604 logger.info("Test: Valid WSC Start to start the sequence")
9605 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'],
9606 4 + 1 + 3 + 4 + 2,
9607 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
9608 1, 0x00)
9609 idx += 1
9610 if ctx['num'] == idx:
9611 logger.info("Test: Valid first fragmented packet")
9612 return struct.pack(">BBHB3BLBBHB", EAP_CODE_REQUEST, ctx['id'],
9613 4 + 1 + 3 + 4 + 5,
9614 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
9615 4, 0x03, 2, 1)
9616 idx += 1
9617 if ctx['num'] == idx:
9618 logger.info("Test: Fragment overflow")
9619 return struct.pack(">BBHB3BLBBBB", EAP_CODE_REQUEST, ctx['id'],
9620 4 + 1 + 3 + 4 + 4,
9621 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
9622 4, 0x01, 2, 3)
9623
9624 idx += 1
9625 if ctx['num'] == idx:
9626 logger.info("Test: Valid WSC Start to start the sequence")
9627 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'],
9628 4 + 1 + 3 + 4 + 2,
9629 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
9630 1, 0x00)
9631 idx += 1
9632 if ctx['num'] == idx:
9633 logger.info("Test: Unexpected Op-Code 5 in WAIT_FRAG_ACK state")
9634 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'],
9635 4 + 1 + 3 + 4 + 2,
9636 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
9637 5, 0x00)
9638
9639 idx += 1
9640 if ctx['num'] == idx:
9641 logger.info("Test: Valid WSC Start")
9642 return struct.pack(">BBHB3BLBB", EAP_CODE_REQUEST, ctx['id'],
9643 4 + 1 + 3 + 4 + 2,
9644 EAP_TYPE_EXPANDED, 0x00, 0x37, 0x2a, 1,
9645 1, 0x00)
9646 idx += 1
9647 if ctx['num'] == idx:
9648 logger.info("No more test responses available - test case completed")
9649 global eap_proto_wsc_test_done
9650 eap_proto_wsc_test_done = True
9651 eap_proto_wsc_wait_failure = True
9652 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9653
9654 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9655
9656 srv = start_radius_server(wsc_handler)
9657
9658 try:
9659 hapd = start_ap(apdev[0])
9660 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
9661
9662 i = 0
9663 while not eap_proto_wsc_test_done:
9664 i += 1
9665 logger.info("Running connection iteration %d" % i)
9666 fragment_size = 1398 if i != 9 else 50
9667 dev[0].connect("eap-test", key_mgmt="WPA-EAP", eap="WSC",
9668 fragment_size=str(fragment_size),
9669 identity="WFA-SimpleConfig-Enrollee-1-0",
9670 phase1="pin=12345670",
9671 scan_freq="2412", wait_connect=False)
9672 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5)
9673 if ev is None:
9674 raise Exception("Timeout on EAP method start")
9675 if eap_proto_wsc_wait_failure:
9676 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
9677 if ev is None:
9678 raise Exception("Timeout on EAP failure")
9679 else:
9680 time.sleep(0.1)
9681 dev[0].request("REMOVE_NETWORK all")
9682 dev[0].wait_disconnected(timeout=1)
9683 dev[0].dump_monitor()
9684 finally:
9685 stop_radius_server(srv)
9686
9687 def test_eap_canned_success_before_method(dev, apdev):
9688 """EAP protocol tests for canned EAP-Success before any method"""
9689 params = int_eap_server_params()
9690 hapd = hostapd.add_ap(apdev[0], params)
9691 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
9692 bssid = apdev[0]['bssid']
9693 hapd.request("SET ext_eapol_frame_io 1")
9694
9695 dev[0].connect("test-wpa2-eap", 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
9700 ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
9701 if ev is None:
9702 raise Exception("Timeout on EAPOL-TX from hostapd")
9703
9704 res = dev[0].request("EAPOL_RX " + bssid + " 0200000403020004")
9705 if "OK" not in res:
9706 raise Exception("EAPOL_RX to wpa_supplicant failed")
9707
9708 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=5)
9709 if ev is None:
9710 raise Exception("Timeout on EAP success")
9711 dev[0].request("REMOVE_NETWORK all")
9712 dev[0].wait_disconnected()
9713
9714 def test_eap_canned_failure_before_method(dev, apdev):
9715 """EAP protocol tests for canned EAP-Failure before any method"""
9716 params = int_eap_server_params()
9717 hapd = hostapd.add_ap(apdev[0], params)
9718 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
9719 bssid = apdev[0]['bssid']
9720 hapd.request("SET ext_eapol_frame_io 1")
9721 dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412",
9722 phase1="allow_canned_success=1",
9723 eap="MD5", identity="user", password="password",
9724 wait_connect=False)
9725
9726 ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
9727 if ev is None:
9728 raise Exception("Timeout on EAPOL-TX from hostapd")
9729
9730 res = dev[0].request("EAPOL_RX " + bssid + " 0200000404020004")
9731 if "OK" not in res:
9732 raise Exception("EAPOL_RX to wpa_supplicant failed")
9733
9734 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
9735 if ev is None:
9736 raise Exception("Timeout on EAP failure")
9737 dev[0].request("REMOVE_NETWORK all")
9738 dev[0].wait_disconnected()
9739
9740 def test_eap_nak_oom(dev, apdev):
9741 """EAP-Nak OOM"""
9742 check_eap_capa(dev[0], "MD5")
9743 params = hostapd.wpa2_eap_params(ssid="eap-test")
9744 hapd = hostapd.add_ap(apdev[0], params)
9745 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
9746 with alloc_fail(dev[0], 1, "eap_msg_alloc;eap_sm_buildNak"):
9747 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
9748 eap="MD5", identity="sake user", password="password",
9749 wait_connect=False)
9750 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
9751 dev[0].request("REMOVE_NETWORK all")
9752 dev[0].wait_disconnected()
9753
9754 def test_eap_nak_expanded(dev, apdev):
9755 """EAP-Nak with expanded method"""
9756 check_eap_capa(dev[0], "MD5")
9757 check_eap_capa(dev[0], "VENDOR-TEST")
9758 params = hostapd.wpa2_eap_params(ssid="eap-test")
9759 hapd = hostapd.add_ap(apdev[0], params)
9760 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
9761 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
9762 eap="VENDOR-TEST WSC",
9763 identity="sake user", password="password",
9764 wait_connect=False)
9765 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=10)
9766 if ev is None or "NAK" not in ev:
9767 raise Exception("No NAK event seen")
9768
9769 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
9770 if ev is None:
9771 raise Exception("No EAP-Failure seen")
9772
9773 dev[0].request("REMOVE_NETWORK all")
9774 dev[0].wait_disconnected()
9775
9776 EAP_TLV_RESULT_TLV = 3
9777 EAP_TLV_NAK_TLV = 4
9778 EAP_TLV_ERROR_CODE_TLV = 5
9779 EAP_TLV_CONNECTION_BINDING_TLV = 6
9780 EAP_TLV_VENDOR_SPECIFIC_TLV = 7
9781 EAP_TLV_URI_TLV = 8
9782 EAP_TLV_EAP_PAYLOAD_TLV = 9
9783 EAP_TLV_INTERMEDIATE_RESULT_TLV = 10
9784 EAP_TLV_PAC_TLV = 11
9785 EAP_TLV_CRYPTO_BINDING_TLV = 12
9786 EAP_TLV_CALLING_STATION_ID_TLV = 13
9787 EAP_TLV_CALLED_STATION_ID_TLV = 14
9788 EAP_TLV_NAS_PORT_TYPE_TLV = 15
9789 EAP_TLV_SERVER_IDENTIFIER_TLV = 16
9790 EAP_TLV_IDENTITY_TYPE_TLV = 17
9791 EAP_TLV_SERVER_TRUSTED_ROOT_TLV = 18
9792 EAP_TLV_REQUEST_ACTION_TLV = 19
9793 EAP_TLV_PKCS7_TLV = 20
9794
9795 EAP_TLV_RESULT_SUCCESS = 1
9796 EAP_TLV_RESULT_FAILURE = 2
9797
9798 EAP_TLV_TYPE_MANDATORY = 0x8000
9799 EAP_TLV_TYPE_MASK = 0x3fff
9800
9801 PAC_TYPE_PAC_KEY = 1
9802 PAC_TYPE_PAC_OPAQUE = 2
9803 PAC_TYPE_CRED_LIFETIME = 3
9804 PAC_TYPE_A_ID = 4
9805 PAC_TYPE_I_ID = 5
9806 PAC_TYPE_A_ID_INFO = 7
9807 PAC_TYPE_PAC_ACKNOWLEDGEMENT = 8
9808 PAC_TYPE_PAC_INFO = 9
9809 PAC_TYPE_PAC_TYPE = 10
9810
9811 def eap_fast_start(ctx):
9812 logger.info("Send EAP-FAST/Start")
9813 return struct.pack(">BBHBBHH", EAP_CODE_REQUEST, ctx['id'],
9814 4 + 1 + 1 + 4 + 16,
9815 EAP_TYPE_FAST, 0x21, 4, 16) + 16*b'A'
9816
9817 def test_eap_fast_proto(dev, apdev):
9818 """EAP-FAST Phase protocol testing"""
9819 check_eap_capa(dev[0], "FAST")
9820 global eap_fast_proto_ctx
9821 eap_fast_proto_ctx = None
9822
9823 def eap_handler(ctx, req):
9824 logger.info("eap_handler - RX " + binascii.hexlify(req).decode())
9825 if 'num' not in ctx:
9826 ctx['num'] = 0
9827 ctx['num'] = ctx['num'] + 1
9828 if 'id' not in ctx:
9829 ctx['id'] = 1
9830 ctx['id'] = (ctx['id'] + 1) % 256
9831 idx = 0
9832
9833 global eap_fast_proto_ctx
9834 eap_fast_proto_ctx = ctx
9835 ctx['test_done'] = False
9836
9837 idx += 1
9838 if ctx['num'] == idx:
9839 return eap_fast_start(ctx)
9840 idx += 1
9841 if ctx['num'] == idx:
9842 logger.info("EAP-FAST: TLS processing failed")
9843 data = b'ABCDEFGHIK'
9844 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9845 4 + 1 + 1 + len(data),
9846 EAP_TYPE_FAST, 0x01) + data
9847 idx += 1
9848 if ctx['num'] == idx:
9849 ctx['test_done'] = True
9850 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9851
9852 logger.info("Past last test case")
9853 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9854
9855 srv = start_radius_server(eap_handler)
9856 try:
9857 hapd = start_ap(apdev[0])
9858 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
9859 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
9860 eap="FAST", anonymous_identity="FAST",
9861 identity="user", password="password",
9862 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
9863 phase1="fast_provisioning=1",
9864 pac_file="blob://fast_pac_proto",
9865 wait_connect=False)
9866 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5)
9867 if ev is None:
9868 raise Exception("Could not start EAP-FAST")
9869 ok = False
9870 for i in range(100):
9871 if eap_fast_proto_ctx:
9872 if eap_fast_proto_ctx['test_done']:
9873 ok = True
9874 break
9875 time.sleep(0.05)
9876 dev[0].request("REMOVE_NETWORK all")
9877 dev[0].wait_disconnected()
9878 finally:
9879 stop_radius_server(srv)
9880
9881 def run_eap_fast_phase2(dev, test_payload, test_failure=True):
9882 global eap_fast_proto_ctx
9883 eap_fast_proto_ctx = None
9884
9885 def ssl_info_callback(conn, where, ret):
9886 logger.debug("SSL: info where=%d ret=%d" % (where, ret))
9887
9888 def log_conn_state(conn):
9889 try:
9890 state = conn.state_string()
9891 except AttributeError:
9892 state = conn.get_state_string()
9893 if state:
9894 logger.info("State: " + str(state))
9895
9896 def process_clienthello(ctx, payload):
9897 logger.info("Process ClientHello")
9898 ctx['sslctx'] = OpenSSL.SSL.Context(OpenSSL.SSL.TLSv1_METHOD)
9899 ctx['sslctx'].set_info_callback(ssl_info_callback)
9900 ctx['sslctx'].load_tmp_dh("auth_serv/dh.conf")
9901 ctx['sslctx'].set_cipher_list("ADH-AES128-SHA")
9902 ctx['conn'] = OpenSSL.SSL.Connection(ctx['sslctx'], None)
9903 ctx['conn'].set_accept_state()
9904 log_conn_state(ctx['conn'])
9905 ctx['conn'].bio_write(payload)
9906 try:
9907 ctx['conn'].do_handshake()
9908 except OpenSSL.SSL.WantReadError:
9909 pass
9910 log_conn_state(ctx['conn'])
9911 data = ctx['conn'].bio_read(4096)
9912 log_conn_state(ctx['conn'])
9913 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9914 4 + 1 + 1 + len(data),
9915 EAP_TYPE_FAST, 0x01) + data
9916
9917 def process_clientkeyexchange(ctx, payload, appl_data):
9918 logger.info("Process ClientKeyExchange")
9919 log_conn_state(ctx['conn'])
9920 ctx['conn'].bio_write(payload)
9921 try:
9922 ctx['conn'].do_handshake()
9923 except OpenSSL.SSL.WantReadError:
9924 pass
9925 ctx['conn'].send(appl_data)
9926 log_conn_state(ctx['conn'])
9927 data = ctx['conn'].bio_read(4096)
9928 log_conn_state(ctx['conn'])
9929 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
9930 4 + 1 + 1 + len(data),
9931 EAP_TYPE_FAST, 0x01) + data
9932
9933 def eap_handler(ctx, req):
9934 logger.info("eap_handler - RX " + binascii.hexlify(req).decode())
9935 if 'num' not in ctx:
9936 ctx['num'] = 0
9937 ctx['num'] = ctx['num'] + 1
9938 if 'id' not in ctx:
9939 ctx['id'] = 1
9940 ctx['id'] = (ctx['id'] + 1) % 256
9941 idx = 0
9942
9943 global eap_fast_proto_ctx
9944 eap_fast_proto_ctx = ctx
9945 ctx['test_done'] = False
9946 logger.debug("ctx['num']=%d" % ctx['num'])
9947
9948 idx += 1
9949 if ctx['num'] == idx:
9950 return eap_fast_start(ctx)
9951 idx += 1
9952 if ctx['num'] == idx:
9953 return process_clienthello(ctx, req[6:])
9954 idx += 1
9955 if ctx['num'] == idx:
9956 if not test_failure:
9957 ctx['test_done'] = True
9958 return process_clientkeyexchange(ctx, req[6:], test_payload)
9959 idx += 1
9960 if ctx['num'] == idx:
9961 ctx['test_done'] = True
9962 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9963
9964 logger.info("Past last test case")
9965 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
9966
9967 srv = start_radius_server(eap_handler)
9968 try:
9969 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
9970 eap="FAST", anonymous_identity="FAST",
9971 identity="user", password="password",
9972 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
9973 phase1="fast_provisioning=1",
9974 pac_file="blob://fast_pac_proto",
9975 wait_connect=False)
9976 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5)
9977 if ev is None:
9978 raise Exception("Could not start EAP-FAST")
9979 dev[0].dump_monitor()
9980 ok = False
9981 for i in range(100):
9982 if eap_fast_proto_ctx:
9983 if eap_fast_proto_ctx['test_done']:
9984 ok = True
9985 break
9986 time.sleep(0.05)
9987 time.sleep(0.1)
9988 dev[0].request("REMOVE_NETWORK all")
9989 dev[0].wait_disconnected()
9990 if not ok:
9991 raise Exception("EAP-FAST TLS exchange did not complete")
9992 for i in range(3):
9993 dev[i].dump_monitor()
9994 finally:
9995 stop_radius_server(srv)
9996
9997 def test_eap_fast_proto_phase2(dev, apdev):
9998 """EAP-FAST Phase 2 protocol testing"""
9999 if not openssl_imported:
10000 raise HwsimSkip("OpenSSL python method not available")
10001 check_eap_capa(dev[0], "FAST")
10002 hapd = start_ap(apdev[0])
10003 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
10004
10005 tests = [("Too short Phase 2 TLV frame (len=3)",
10006 "ABC",
10007 False),
10008 ("EAP-FAST: TLV overflow",
10009 struct.pack(">HHB", 0, 2, 0xff),
10010 False),
10011 ("EAP-FAST: Unknown TLV (optional and mandatory)",
10012 struct.pack(">HHB", 0, 1, 0xff) +
10013 struct.pack(">HHB", EAP_TLV_TYPE_MANDATORY, 1, 0xff),
10014 True),
10015 ("EAP-FAST: More than one EAP-Payload TLV in the message",
10016 struct.pack(">HHBHHB",
10017 EAP_TLV_EAP_PAYLOAD_TLV, 1, 0xff,
10018 EAP_TLV_EAP_PAYLOAD_TLV, 1, 0xff),
10019 True),
10020 ("EAP-FAST: Unknown Result 255 and More than one Result TLV in the message",
10021 struct.pack(">HHHHHH",
10022 EAP_TLV_RESULT_TLV, 2, 0xff,
10023 EAP_TLV_RESULT_TLV, 2, 0xff),
10024 True),
10025 ("EAP-FAST: Too short Result TLV",
10026 struct.pack(">HHB", EAP_TLV_RESULT_TLV, 1, 0xff),
10027 True),
10028 ("EAP-FAST: Unknown Intermediate Result 255 and More than one Intermediate-Result TLV in the message",
10029 struct.pack(">HHHHHH",
10030 EAP_TLV_INTERMEDIATE_RESULT_TLV, 2, 0xff,
10031 EAP_TLV_INTERMEDIATE_RESULT_TLV, 2, 0xff),
10032 True),
10033 ("EAP-FAST: Too short Intermediate-Result TLV",
10034 struct.pack(">HHB", EAP_TLV_INTERMEDIATE_RESULT_TLV, 1, 0xff),
10035 True),
10036 ("EAP-FAST: More than one Crypto-Binding TLV in the message",
10037 struct.pack(">HH", EAP_TLV_CRYPTO_BINDING_TLV, 60) + 60*b'A' +
10038 struct.pack(">HH", EAP_TLV_CRYPTO_BINDING_TLV, 60) + 60*b'A',
10039 True),
10040 ("EAP-FAST: Too short Crypto-Binding TLV",
10041 struct.pack(">HHB", EAP_TLV_CRYPTO_BINDING_TLV, 1, 0xff),
10042 True),
10043 ("EAP-FAST: More than one Request-Action TLV in the message",
10044 struct.pack(">HHBBHHBB",
10045 EAP_TLV_REQUEST_ACTION_TLV, 2, 0xff, 0xff,
10046 EAP_TLV_REQUEST_ACTION_TLV, 2, 0xff, 0xff),
10047 True),
10048 ("EAP-FAST: Too short Request-Action TLV",
10049 struct.pack(">HHB", EAP_TLV_REQUEST_ACTION_TLV, 1, 0xff),
10050 True),
10051 ("EAP-FAST: More than one PAC TLV in the message",
10052 struct.pack(">HHBHHB",
10053 EAP_TLV_PAC_TLV, 1, 0xff,
10054 EAP_TLV_PAC_TLV, 1, 0xff),
10055 True),
10056 ("EAP-FAST: Too short EAP Payload TLV (Len=3)",
10057 struct.pack(">HH3B",
10058 EAP_TLV_EAP_PAYLOAD_TLV, 3, 0, 0, 0),
10059 False),
10060 ("EAP-FAST: Too short Phase 2 request (Len=0)",
10061 struct.pack(">HHBBH",
10062 EAP_TLV_EAP_PAYLOAD_TLV, 4,
10063 EAP_CODE_REQUEST, 0, 0),
10064 False),
10065 ("EAP-FAST: EAP packet overflow in EAP Payload TLV",
10066 struct.pack(">HHBBH",
10067 EAP_TLV_EAP_PAYLOAD_TLV, 4,
10068 EAP_CODE_REQUEST, 0, 4 + 1),
10069 False),
10070 ("EAP-FAST: Unexpected code=0 in Phase 2 EAP header",
10071 struct.pack(">HHBBH",
10072 EAP_TLV_EAP_PAYLOAD_TLV, 4,
10073 0, 0, 0),
10074 False),
10075 ("EAP-FAST: PAC TLV without Result TLV acknowledging success",
10076 struct.pack(">HHB", EAP_TLV_PAC_TLV, 1, 0xff),
10077 True),
10078 ("EAP-FAST: PAC TLV does not include all the required fields",
10079 struct.pack(">HHH", EAP_TLV_RESULT_TLV, 2,
10080 EAP_TLV_RESULT_SUCCESS) +
10081 struct.pack(">HHB", EAP_TLV_PAC_TLV, 1, 0xff),
10082 True),
10083 ("EAP-FAST: Invalid PAC-Key length 0, Ignored unknown PAC type 0, and PAC TLV overrun (type=0 len=2 left=1)",
10084 struct.pack(">HHH", EAP_TLV_RESULT_TLV, 2,
10085 EAP_TLV_RESULT_SUCCESS) +
10086 struct.pack(">HHHHHHHHB", EAP_TLV_PAC_TLV, 4 + 4 + 5,
10087 PAC_TYPE_PAC_KEY, 0, 0, 0, 0, 2, 0),
10088 True),
10089 ("EAP-FAST: PAC-Info does not include all the required fields",
10090 struct.pack(">HHH", EAP_TLV_RESULT_TLV, 2,
10091 EAP_TLV_RESULT_SUCCESS) +
10092 struct.pack(">HHHHHHHH", EAP_TLV_PAC_TLV, 4 + 4 + 4 + 32,
10093 PAC_TYPE_PAC_OPAQUE, 0,
10094 PAC_TYPE_PAC_INFO, 0,
10095 PAC_TYPE_PAC_KEY, 32) + 32*b'A',
10096 True),
10097 ("EAP-FAST: Invalid CRED_LIFETIME length, Ignored unknown PAC-Info type 0, and Invalid PAC-Type length 1",
10098 struct.pack(">HHH", EAP_TLV_RESULT_TLV, 2,
10099 EAP_TLV_RESULT_SUCCESS) +
10100 struct.pack(">HHHHHHHHHHHHBHH", EAP_TLV_PAC_TLV, 4 + 4 + 13 + 4 + 32,
10101 PAC_TYPE_PAC_OPAQUE, 0,
10102 PAC_TYPE_PAC_INFO, 13, PAC_TYPE_CRED_LIFETIME, 0,
10103 0, 0, PAC_TYPE_PAC_TYPE, 1, 0,
10104 PAC_TYPE_PAC_KEY, 32) + 32*b'A',
10105 True),
10106 ("EAP-FAST: Unsupported PAC-Type 0",
10107 struct.pack(">HHH", EAP_TLV_RESULT_TLV, 2,
10108 EAP_TLV_RESULT_SUCCESS) +
10109 struct.pack(">HHHHHHHHHHH", EAP_TLV_PAC_TLV, 4 + 4 + 6 + 4 + 32,
10110 PAC_TYPE_PAC_OPAQUE, 0,
10111 PAC_TYPE_PAC_INFO, 6, PAC_TYPE_PAC_TYPE, 2, 0,
10112 PAC_TYPE_PAC_KEY, 32) + 32*b'A',
10113 True),
10114 ("EAP-FAST: PAC-Info overrun (type=0 len=2 left=1)",
10115 struct.pack(">HHH", EAP_TLV_RESULT_TLV, 2,
10116 EAP_TLV_RESULT_SUCCESS) +
10117 struct.pack(">HHHHHHHHBHH", EAP_TLV_PAC_TLV, 4 + 4 + 5 + 4 + 32,
10118 PAC_TYPE_PAC_OPAQUE, 0,
10119 PAC_TYPE_PAC_INFO, 5, 0, 2, 1,
10120 PAC_TYPE_PAC_KEY, 32) + 32*b'A',
10121 True),
10122 ("EAP-FAST: Valid PAC",
10123 struct.pack(">HHH", EAP_TLV_RESULT_TLV, 2,
10124 EAP_TLV_RESULT_SUCCESS) +
10125 struct.pack(">HHHHHHHHBHHBHH", EAP_TLV_PAC_TLV,
10126 4 + 4 + 10 + 4 + 32,
10127 PAC_TYPE_PAC_OPAQUE, 0,
10128 PAC_TYPE_PAC_INFO, 10, PAC_TYPE_A_ID, 1, 0x41,
10129 PAC_TYPE_A_ID_INFO, 1, 0x42,
10130 PAC_TYPE_PAC_KEY, 32) + 32*b'A',
10131 True),
10132 ("EAP-FAST: Invalid version/subtype in Crypto-Binding TLV",
10133 struct.pack(">HH", EAP_TLV_CRYPTO_BINDING_TLV, 60) + 60*b'A',
10134 True)]
10135 for title, payload, failure in tests:
10136 logger.info("Phase 2 test: " + title)
10137 run_eap_fast_phase2(dev, payload, failure)
10138
10139 def test_eap_fast_tlv_nak_oom(dev, apdev):
10140 """EAP-FAST Phase 2 TLV NAK OOM"""
10141 if not openssl_imported:
10142 raise HwsimSkip("OpenSSL python method not available")
10143 check_eap_capa(dev[0], "FAST")
10144 hapd = start_ap(apdev[0])
10145 dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
10146
10147 with alloc_fail(dev[0], 1, "eap_fast_tlv_nak"):
10148 run_eap_fast_phase2(dev, struct.pack(">HHB", EAP_TLV_TYPE_MANDATORY,
10149 1, 0xff), False)