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