]> git.ipfire.org Git - thirdparty/hostap.git/blame - tests/hwsim/test_eap_proto.py
tests: EAP-OTP 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()
12import select
13import struct
14import threading
15import time
16
17import hostapd
d5482411 18from utils import HwsimSkip, alloc_fail, fail_test, wait_fail_trigger
d36ae376 19from test_ap_eap import check_eap_capa, check_hlr_auc_gw_support
b6f17f2f 20from test_erp import check_erp_capa
d81731e6
JM
21
22EAP_CODE_REQUEST = 1
23EAP_CODE_RESPONSE = 2
24EAP_CODE_SUCCESS = 3
25EAP_CODE_FAILURE = 4
b6f17f2f
JM
26EAP_CODE_INITIATE = 5
27EAP_CODE_FINISH = 6
d81731e6
JM
28
29EAP_TYPE_IDENTITY = 1
30EAP_TYPE_NOTIFICATION = 2
31EAP_TYPE_NAK = 3
32EAP_TYPE_MD5 = 4
33EAP_TYPE_OTP = 5
34EAP_TYPE_GTC = 6
35EAP_TYPE_TLS = 13
36EAP_TYPE_LEAP = 17
37EAP_TYPE_SIM = 18
38EAP_TYPE_TTLS = 21
39EAP_TYPE_AKA = 23
40EAP_TYPE_PEAP = 25
41EAP_TYPE_MSCHAPV2 = 26
42EAP_TYPE_TLV = 33
43EAP_TYPE_TNC = 38
44EAP_TYPE_FAST = 43
45EAP_TYPE_PAX = 46
46EAP_TYPE_PSK = 47
47EAP_TYPE_SAKE = 48
48EAP_TYPE_IKEV2 = 49
49EAP_TYPE_AKA_PRIME = 50
50EAP_TYPE_GPSK = 51
51EAP_TYPE_PWD = 52
52EAP_TYPE_EKE = 53
2fd377de 53EAP_TYPE_EXPANDED = 254
d81731e6 54
b6f17f2f
JM
55# Type field in EAP-Initiate and EAP-Finish messages
56EAP_ERP_TYPE_REAUTH_START = 1
57EAP_ERP_TYPE_REAUTH = 2
58
59EAP_ERP_TLV_KEYNAME_NAI = 1
60EAP_ERP_TV_RRK_LIFETIME = 2
61EAP_ERP_TV_RMSK_LIFETIME = 3
62EAP_ERP_TLV_DOMAIN_NAME = 4
63EAP_ERP_TLV_CRYPTOSUITES = 5
64EAP_ERP_TLV_AUTHORIZATION_INDICATION = 6
65EAP_ERP_TLV_CALLED_STATION_ID = 128
66EAP_ERP_TLV_CALLING_STATION_ID = 129
67EAP_ERP_TLV_NAS_IDENTIFIER = 130
68EAP_ERP_TLV_NAS_IP_ADDRESS = 131
69EAP_ERP_TLV_NAS_IPV6_ADDRESS = 132
70
d81731e6
JM
71def run_pyrad_server(srv, t_stop, eap_handler):
72 srv.RunWithStop(t_stop, eap_handler)
73
74def start_radius_server(eap_handler):
75 try:
76 import pyrad.server
77 import pyrad.packet
78 import pyrad.dictionary
79 except ImportError:
81e787b7 80 raise HwsimSkip("No pyrad modules available")
d81731e6
JM
81
82 class TestServer(pyrad.server.Server):
83 def _HandleAuthPacket(self, pkt):
84 pyrad.server.Server._HandleAuthPacket(self, pkt)
37211e15
JM
85 eap = ""
86 for p in pkt[79]:
87 eap += p
d81731e6
JM
88 eap_req = self.eap_handler(self.ctx, eap)
89 reply = self.CreateReplyPacket(pkt)
90 if eap_req:
cb0555f7
JM
91 while True:
92 if len(eap_req) > 253:
93 reply.AddAttribute("EAP-Message", eap_req[0:253])
94 eap_req = eap_req[253:]
95 else:
96 reply.AddAttribute("EAP-Message", eap_req)
97 break
18fc8f40
JM
98 else:
99 logger.info("No EAP request available")
d81731e6
JM
100 reply.code = pyrad.packet.AccessChallenge
101
102 hmac_obj = hmac.new(reply.secret)
103 hmac_obj.update(struct.pack("B", reply.code))
104 hmac_obj.update(struct.pack("B", reply.id))
105
106 # reply attributes
107 reply.AddAttribute("Message-Authenticator",
108 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
109 attrs = reply._PktEncodeAttributes()
110
111 # Length
112 flen = 4 + 16 + len(attrs)
113 hmac_obj.update(struct.pack(">H", flen))
114 hmac_obj.update(pkt.authenticator)
115 hmac_obj.update(attrs)
116 del reply[80]
117 reply.AddAttribute("Message-Authenticator", hmac_obj.digest())
118
119 self.SendReplyPacket(pkt.fd, reply)
120
121 def RunWithStop(self, t_stop, eap_handler):
122 self._poll = select.poll()
123 self._fdmap = {}
124 self._PrepareSockets()
125 self.t_stop = t_stop
126 self.eap_handler = eap_handler
127 self.ctx = {}
128
129 while not t_stop.is_set():
8a848fae 130 for (fd, event) in self._poll.poll(200):
d81731e6
JM
131 if event == select.POLLIN:
132 try:
133 fdo = self._fdmap[fd]
134 self._ProcessInput(fdo)
135 except pyrad.server.ServerPacketError as err:
136 logger.info("pyrad server dropping packet: " + str(err))
137 except pyrad.packet.PacketError as err:
138 logger.info("pyrad server received invalid packet: " + str(err))
139 else:
140 logger.error("Unexpected event in pyrad server main loop")
141
142 srv = TestServer(dict=pyrad.dictionary.Dictionary("dictionary.radius"),
143 authport=18138, acctport=18139)
144 srv.hosts["127.0.0.1"] = pyrad.server.RemoteHost("127.0.0.1",
145 "radius",
146 "localhost")
147 srv.BindToAddress("")
148 t_stop = threading.Event()
149 t = threading.Thread(target=run_pyrad_server, args=(srv, t_stop, eap_handler))
150 t.start()
151
152 return { 'srv': srv, 'stop': t_stop, 'thread': t }
153
154def stop_radius_server(srv):
155 srv['stop'].set()
156 srv['thread'].join()
157
158def start_ap(ifname):
159 params = hostapd.wpa2_eap_params(ssid="eap-test")
160 params['auth_server_port'] = "18138"
161 hapd = hostapd.add_ap(ifname, params)
162 return hapd
163
2eae05f7
JM
164def test_eap_proto(dev, apdev):
165 """EAP protocol tests"""
e7ac04ce 166 check_eap_capa(dev[0], "MD5")
2eae05f7
JM
167 def eap_handler(ctx, req):
168 logger.info("eap_handler - RX " + req.encode("hex"))
169 if 'num' not in ctx:
170 ctx['num'] = 0
171 ctx['num'] = ctx['num'] + 1
172 if 'id' not in ctx:
173 ctx['id'] = 1
174 ctx['id'] = (ctx['id'] + 1) % 256
175 idx = 0
176
177 idx += 1
178 if ctx['num'] == idx:
179 logger.info("Test: MD5 challenge")
180 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
181 4 + 1 + 3,
182 EAP_TYPE_MD5,
183 1, 0xaa, ord('n'))
184 idx += 1
185 if ctx['num'] == idx:
186 logger.info("Test: EAP-Success - id off by 2")
187 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'] + 1, 4)
188
189 idx += 1
190 if ctx['num'] == idx:
191 logger.info("Test: MD5 challenge")
192 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
193 4 + 1 + 3,
194 EAP_TYPE_MD5,
195 1, 0xaa, ord('n'))
196 idx += 1
197 if ctx['num'] == idx:
198 logger.info("Test: EAP-Success - id off by 3")
199 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'] + 2, 4)
200
201 idx += 1
202 if ctx['num'] == idx:
203 logger.info("Test: MD5 challenge")
204 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
205 4 + 1 + 3,
206 EAP_TYPE_MD5,
207 1, 0xaa, ord('n'))
208 idx += 1
209 if ctx['num'] == idx:
210 logger.info("Test: EAP-Notification/Request")
211 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
212 4 + 1 + 1,
213 EAP_TYPE_NOTIFICATION,
214 ord('A'))
215 idx += 1
216 if ctx['num'] == idx:
217 logger.info("Test: EAP-Success")
218 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'] - 1, 4)
219
220 idx += 1
221 if ctx['num'] == idx:
222 logger.info("Test: EAP-Notification/Request")
223 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
224 4 + 1 + 1,
225 EAP_TYPE_NOTIFICATION,
226 ord('B'))
227 idx += 1
228 if ctx['num'] == idx:
229 logger.info("Test: MD5 challenge")
230 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
231 4 + 1 + 3,
232 EAP_TYPE_MD5,
233 1, 0xaa, ord('n'))
234 idx += 1
235 if ctx['num'] == idx:
236 logger.info("Test: EAP-Success")
237 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'] - 1, 4)
238
239 idx += 1
240 if ctx['num'] == idx:
241 logger.info("Test: EAP-Notification/Request")
242 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
243 4 + 1 + 1,
244 EAP_TYPE_NOTIFICATION,
245 ord('C'))
246 idx += 1
247 if ctx['num'] == idx:
248 logger.info("Test: MD5 challenge")
249 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
250 4 + 1 + 3,
251 EAP_TYPE_MD5,
252 1, 0xaa, ord('n'))
253 idx += 1
254 if ctx['num'] == idx:
255 logger.info("Test: EAP-Notification/Request")
256 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
257 4 + 1 + 1,
258 EAP_TYPE_NOTIFICATION,
259 ord('D'))
260 idx += 1
261 if ctx['num'] == idx:
262 logger.info("Test: EAP-Success")
263 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'] - 1, 4)
264
265 idx += 1
266 if ctx['num'] == idx:
267 logger.info("Test: EAP-Notification/Request")
268 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
269 4 + 1 + 1,
270 EAP_TYPE_NOTIFICATION,
271 ord('E'))
272 idx += 1
273 if ctx['num'] == idx:
274 logger.info("Test: EAP-Notification/Request (same id)")
275 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'] - 1,
276 4 + 1 + 1,
277 EAP_TYPE_NOTIFICATION,
278 ord('F'))
279 idx += 1
280 if ctx['num'] == idx:
281 logger.info("Test: Unexpected EAP-Success")
282 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'] - 2, 4)
283
284 return None
285
286 srv = start_radius_server(eap_handler)
2eae05f7
JM
287
288 try:
289 hapd = start_ap(apdev[0]['ifname'])
290
291 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
292 eap="MD5", identity="user", password="password",
293 wait_connect=False)
294 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15)
295 if ev is None:
296 raise Exception("Timeout on EAP start")
297 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15)
298 if ev is None:
299 raise Exception("Timeout on EAP success")
300 dev[0].request("REMOVE_NETWORK all")
301
302 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
303 eap="MD5", identity="user", password="password",
304 wait_connect=False)
305 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15)
306 if ev is None:
307 raise Exception("Timeout on EAP start")
308 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=1)
309 if ev is not None:
310 raise Exception("Unexpected EAP success")
311 dev[0].request("REMOVE_NETWORK all")
312
313 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
314 eap="MD5", identity="user", password="password",
315 wait_connect=False)
316 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15)
317 if ev is None:
318 raise Exception("Timeout on EAP start")
319 ev = dev[0].wait_event(["CTRL-EVENT-EAP-NOTIFICATION"], timeout=10)
320 if ev is None:
321 raise Exception("Timeout on EAP notification")
322 if ev != "<3>CTRL-EVENT-EAP-NOTIFICATION A":
323 raise Exception("Unexpected notification contents: " + ev)
324 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15)
325 if ev is None:
326 raise Exception("Timeout on EAP success")
327 dev[0].request("REMOVE_NETWORK all")
328
329 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
330 eap="MD5", identity="user", password="password",
331 wait_connect=False)
332 ev = dev[0].wait_event(["CTRL-EVENT-EAP-NOTIFICATION"], timeout=10)
333 if ev is None:
334 raise Exception("Timeout on EAP notification")
335 if ev != "<3>CTRL-EVENT-EAP-NOTIFICATION B":
336 raise Exception("Unexpected notification contents: " + ev)
337 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15)
338 if ev is None:
339 raise Exception("Timeout on EAP start")
340 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15)
341 if ev is None:
342 raise Exception("Timeout on EAP success")
343 dev[0].request("REMOVE_NETWORK all")
344
345 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
346 eap="MD5", identity="user", password="password",
347 wait_connect=False)
348 ev = dev[0].wait_event(["CTRL-EVENT-EAP-NOTIFICATION"], timeout=10)
349 if ev is None:
350 raise Exception("Timeout on EAP notification")
351 if ev != "<3>CTRL-EVENT-EAP-NOTIFICATION C":
352 raise Exception("Unexpected notification contents: " + ev)
353 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15)
354 if ev is None:
355 raise Exception("Timeout on EAP start")
356 ev = dev[0].wait_event(["CTRL-EVENT-EAP-NOTIFICATION"], timeout=10)
357 if ev is None:
358 raise Exception("Timeout on EAP notification")
359 if ev != "<3>CTRL-EVENT-EAP-NOTIFICATION D":
360 raise Exception("Unexpected notification contents: " + ev)
361 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15)
362 if ev is None:
363 raise Exception("Timeout on EAP success")
364 dev[0].request("REMOVE_NETWORK all")
365
366 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
367 eap="MD5", identity="user", password="password",
368 wait_connect=False)
369 ev = dev[0].wait_event(["CTRL-EVENT-EAP-NOTIFICATION"], timeout=10)
370 if ev is None:
371 raise Exception("Timeout on EAP notification")
372 if ev != "<3>CTRL-EVENT-EAP-NOTIFICATION E":
373 raise Exception("Unexpected notification contents: " + ev)
374 ev = dev[0].wait_event(["CTRL-EVENT-EAP-NOTIFICATION"], timeout=10)
375 if ev is None:
376 raise Exception("Timeout on EAP notification")
377 if ev != "<3>CTRL-EVENT-EAP-NOTIFICATION F":
378 raise Exception("Unexpected notification contents: " + ev)
379 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=15)
380 if ev is None:
381 raise Exception("Timeout on EAP failure")
382 dev[0].request("REMOVE_NETWORK all")
383 finally:
384 stop_radius_server(srv)
385
d81731e6
JM
386EAP_SAKE_VERSION = 2
387
388EAP_SAKE_SUBTYPE_CHALLENGE = 1
389EAP_SAKE_SUBTYPE_CONFIRM = 2
390EAP_SAKE_SUBTYPE_AUTH_REJECT = 3
391EAP_SAKE_SUBTYPE_IDENTITY = 4
392
393EAP_SAKE_AT_RAND_S = 1
394EAP_SAKE_AT_RAND_P = 2
395EAP_SAKE_AT_MIC_S = 3
396EAP_SAKE_AT_MIC_P = 4
397EAP_SAKE_AT_SERVERID = 5
398EAP_SAKE_AT_PEERID = 6
399EAP_SAKE_AT_SPI_S = 7
400EAP_SAKE_AT_SPI_P = 8
401EAP_SAKE_AT_ANY_ID_REQ = 9
402EAP_SAKE_AT_PERM_ID_REQ = 10
403EAP_SAKE_AT_ENCR_DATA = 128
404EAP_SAKE_AT_IV = 129
405EAP_SAKE_AT_PADDING = 130
406EAP_SAKE_AT_NEXT_TMPID = 131
407EAP_SAKE_AT_MSK_LIFE = 132
408
409def test_eap_proto_sake(dev, apdev):
410 """EAP-SAKE protocol tests"""
c49b383f
JM
411 global eap_proto_sake_test_done
412 eap_proto_sake_test_done = False
413
d81731e6
JM
414 def sake_challenge(ctx):
415 logger.info("Test: Challenge subtype")
416 return struct.pack(">BBHBBBBBBLLLL", EAP_CODE_REQUEST, ctx['id'],
417 4 + 1 + 3 + 18,
418 EAP_TYPE_SAKE,
419 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_CHALLENGE,
420 EAP_SAKE_AT_RAND_S, 18, 0, 0, 0, 0)
421
422 def sake_handler(ctx, req):
423 logger.info("sake_handler - RX " + req.encode("hex"))
424 if 'num' not in ctx:
425 ctx['num'] = 0
c49b383f 426 ctx['num'] += 1
d81731e6
JM
427 if 'id' not in ctx:
428 ctx['id'] = 1
429 ctx['id'] = (ctx['id'] + 1) % 256
c49b383f 430 idx = 0
d81731e6 431
c49b383f
JM
432 idx += 1
433 if ctx['num'] == idx:
d81731e6
JM
434 logger.info("Test: Missing payload")
435 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 4 + 1,
436 EAP_TYPE_SAKE)
437
c49b383f
JM
438 idx += 1
439 if ctx['num'] == idx:
d81731e6
JM
440 logger.info("Test: Identity subtype without any attributes")
441 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
442 4 + 1 + 3,
443 EAP_TYPE_SAKE,
444 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_IDENTITY)
445
c49b383f
JM
446 idx += 1
447 if ctx['num'] == idx:
d81731e6
JM
448 logger.info("Test: Identity subtype")
449 return struct.pack(">BBHBBBBBBH", EAP_CODE_REQUEST, ctx['id'],
450 4 + 1 + 3 + 4,
451 EAP_TYPE_SAKE,
452 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_IDENTITY,
453 EAP_SAKE_AT_ANY_ID_REQ, 4, 0)
c49b383f
JM
454 idx += 1
455 if ctx['num'] == idx:
d81731e6
JM
456 logger.info("Test: Identity subtype (different session id)")
457 return struct.pack(">BBHBBBBBBH", EAP_CODE_REQUEST, ctx['id'],
458 4 + 1 + 3 + 4,
459 EAP_TYPE_SAKE,
460 EAP_SAKE_VERSION, 1, EAP_SAKE_SUBTYPE_IDENTITY,
461 EAP_SAKE_AT_PERM_ID_REQ, 4, 0)
462
c49b383f
JM
463 idx += 1
464 if ctx['num'] == idx:
d81731e6
JM
465 logger.info("Test: Identity subtype with too short attribute")
466 return struct.pack(">BBHBBBBBB", EAP_CODE_REQUEST, ctx['id'],
467 4 + 1 + 3 + 2,
468 EAP_TYPE_SAKE,
469 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_IDENTITY,
470 EAP_SAKE_AT_ANY_ID_REQ, 2)
471
c49b383f
JM
472 idx += 1
473 if ctx['num'] == idx:
d81731e6
JM
474 logger.info("Test: Identity subtype with truncated attribute")
475 return struct.pack(">BBHBBBBBB", EAP_CODE_REQUEST, ctx['id'],
476 4 + 1 + 3 + 2,
477 EAP_TYPE_SAKE,
478 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_IDENTITY,
479 EAP_SAKE_AT_ANY_ID_REQ, 4)
480
288b6f8b
JM
481 idx += 1
482 if ctx['num'] == idx:
483 logger.info("Test: Identity subtype with too short attribute header")
484 payload = struct.pack("B", EAP_SAKE_AT_ANY_ID_REQ)
485 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
486 4 + 1 + 3 + len(payload),
487 EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0,
488 EAP_SAKE_SUBTYPE_IDENTITY) + payload
489
490 idx += 1
491 if ctx['num'] == idx:
492 logger.info("Test: Identity subtype with AT_IV but not AT_ENCR_DATA")
493 payload = struct.pack("BB", EAP_SAKE_AT_IV, 2)
494 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
495 4 + 1 + 3 + len(payload),
496 EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0,
497 EAP_SAKE_SUBTYPE_IDENTITY) + payload
498
499 idx += 1
500 if ctx['num'] == idx:
501 logger.info("Test: Identity subtype with skippable and non-skippable unknown attribute")
502 payload = struct.pack("BBBB", 255, 2, 127, 2)
503 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
504 4 + 1 + 3 + len(payload),
505 EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0,
506 EAP_SAKE_SUBTYPE_IDENTITY) + payload
507
508 idx += 1
509 if ctx['num'] == idx:
510 logger.info("Test: Identity subtype: AT_RAND_P with invalid payload length")
511 payload = struct.pack("BB", EAP_SAKE_AT_RAND_P, 2)
512 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
513 4 + 1 + 3 + len(payload),
514 EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0,
515 EAP_SAKE_SUBTYPE_IDENTITY) + payload
516
517 idx += 1
518 if ctx['num'] == idx:
519 logger.info("Test: Identity subtype: AT_MIC_P with invalid payload length")
520 payload = struct.pack("BB", EAP_SAKE_AT_MIC_P, 2)
521 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
522 4 + 1 + 3 + len(payload),
523 EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0,
524 EAP_SAKE_SUBTYPE_IDENTITY) + payload
525
526 idx += 1
527 if ctx['num'] == idx:
528 logger.info("Test: Identity subtype: AT_PERM_ID_REQ with invalid payload length")
529 payload = struct.pack("BBBBBBBBBBBBBB",
530 EAP_SAKE_AT_SPI_S, 2,
531 EAP_SAKE_AT_SPI_P, 2,
532 EAP_SAKE_AT_ENCR_DATA, 2,
533 EAP_SAKE_AT_NEXT_TMPID, 2,
534 EAP_SAKE_AT_PERM_ID_REQ, 4, 0, 0,
535 EAP_SAKE_AT_PERM_ID_REQ, 2)
536 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
537 4 + 1 + 3 + len(payload),
538 EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0,
539 EAP_SAKE_SUBTYPE_IDENTITY) + payload
540
541 idx += 1
542 if ctx['num'] == idx:
543 logger.info("Test: Identity subtype: AT_PADDING")
544 payload = struct.pack("BBBBBB",
545 EAP_SAKE_AT_PADDING, 3, 0,
546 EAP_SAKE_AT_PADDING, 3, 1)
547 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
548 4 + 1 + 3 + len(payload),
549 EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0,
550 EAP_SAKE_SUBTYPE_IDENTITY) + payload
551
552 idx += 1
553 if ctx['num'] == idx:
554 logger.info("Test: Identity subtype: AT_MSK_LIFE")
555 payload = struct.pack(">BBLBBH",
556 EAP_SAKE_AT_MSK_LIFE, 6, 0,
557 EAP_SAKE_AT_MSK_LIFE, 4, 0)
558 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
559 4 + 1 + 3 + len(payload),
560 EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0,
561 EAP_SAKE_SUBTYPE_IDENTITY) + payload
562
563 idx += 1
564 if ctx['num'] == idx:
565 logger.info("Test: Identity subtype with invalid attribute length")
566 payload = struct.pack("BB", EAP_SAKE_AT_ANY_ID_REQ, 0)
567 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
568 4 + 1 + 3 + len(payload),
569 EAP_TYPE_SAKE, EAP_SAKE_VERSION, 0,
570 EAP_SAKE_SUBTYPE_IDENTITY) + payload
571
c49b383f
JM
572 idx += 1
573 if ctx['num'] == idx:
d81731e6
JM
574 logger.info("Test: Unknown subtype")
575 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
576 4 + 1 + 3,
577 EAP_TYPE_SAKE,
578 EAP_SAKE_VERSION, 0, 123)
579
c49b383f
JM
580 idx += 1
581 if ctx['num'] == idx:
d81731e6
JM
582 logger.info("Test: Challenge subtype without any attributes")
583 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
584 4 + 1 + 3,
585 EAP_TYPE_SAKE,
586 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_CHALLENGE)
587
c49b383f
JM
588 idx += 1
589 if ctx['num'] == idx:
d81731e6
JM
590 logger.info("Test: Challenge subtype with too short AT_RAND_S")
591 return struct.pack(">BBHBBBBBB", EAP_CODE_REQUEST, ctx['id'],
592 4 + 1 + 3 + 2,
593 EAP_TYPE_SAKE,
594 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_CHALLENGE,
595 EAP_SAKE_AT_RAND_S, 2)
596
c49b383f
JM
597 idx += 1
598 if ctx['num'] == idx:
d81731e6 599 return sake_challenge(ctx)
c49b383f
JM
600 idx += 1
601 if ctx['num'] == idx:
d81731e6
JM
602 logger.info("Test: Unexpected Identity subtype")
603 return struct.pack(">BBHBBBBBBH", EAP_CODE_REQUEST, ctx['id'],
604 4 + 1 + 3 + 4,
605 EAP_TYPE_SAKE,
606 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_IDENTITY,
607 EAP_SAKE_AT_ANY_ID_REQ, 4, 0)
608
c49b383f
JM
609 idx += 1
610 if ctx['num'] == idx:
d81731e6 611 return sake_challenge(ctx)
c49b383f
JM
612 idx += 1
613 if ctx['num'] == idx:
d81731e6
JM
614 logger.info("Test: Unexpected Challenge subtype")
615 return struct.pack(">BBHBBBBBBLLLL", EAP_CODE_REQUEST, ctx['id'],
616 4 + 1 + 3 + 18,
617 EAP_TYPE_SAKE,
618 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_CHALLENGE,
619 EAP_SAKE_AT_RAND_S, 18, 0, 0, 0, 0)
620
c49b383f
JM
621 idx += 1
622 if ctx['num'] == idx:
d81731e6 623 return sake_challenge(ctx)
c49b383f
JM
624 idx += 1
625 if ctx['num'] == idx:
d81731e6
JM
626 logger.info("Test: Confirm subtype without any attributes")
627 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
628 4 + 1 + 3,
629 EAP_TYPE_SAKE,
630 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_CONFIRM)
631
c49b383f
JM
632 idx += 1
633 if ctx['num'] == idx:
d81731e6 634 return sake_challenge(ctx)
c49b383f
JM
635 idx += 1
636 if ctx['num'] == idx:
d81731e6
JM
637 logger.info("Test: Confirm subtype with too short AT_MIC_S")
638 return struct.pack(">BBHBBBBBB", EAP_CODE_REQUEST, ctx['id'],
639 4 + 1 + 3 + 2,
640 EAP_TYPE_SAKE,
641 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_CONFIRM,
642 EAP_SAKE_AT_MIC_S, 2)
643
c49b383f
JM
644 idx += 1
645 if ctx['num'] == idx:
d81731e6
JM
646 logger.info("Test: Unexpected Confirm subtype")
647 return struct.pack(">BBHBBBBBBLLLL", EAP_CODE_REQUEST, ctx['id'],
648 4 + 1 + 3 + 18,
649 EAP_TYPE_SAKE,
650 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_CONFIRM,
651 EAP_SAKE_AT_MIC_S, 18, 0, 0, 0, 0)
652
c49b383f
JM
653 idx += 1
654 if ctx['num'] == idx:
d81731e6 655 return sake_challenge(ctx)
c49b383f
JM
656 idx += 1
657 if ctx['num'] == idx:
d81731e6
JM
658 logger.info("Test: Confirm subtype with incorrect AT_MIC_S")
659 return struct.pack(">BBHBBBBBBLLLL", EAP_CODE_REQUEST, ctx['id'],
660 4 + 1 + 3 + 18,
661 EAP_TYPE_SAKE,
662 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_CONFIRM,
663 EAP_SAKE_AT_MIC_S, 18, 0, 0, 0, 0)
664
c49b383f
JM
665 global eap_proto_sake_test_done
666 if eap_proto_sake_test_done:
667 return sake_challenge(ctx)
668
669 logger.info("No more test responses available - test case completed")
670 eap_proto_sake_test_done = True
671 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
d81731e6
JM
672
673 srv = start_radius_server(sake_handler)
d81731e6
JM
674
675 try:
676 hapd = start_ap(apdev[0]['ifname'])
677
c49b383f 678 while not eap_proto_sake_test_done:
d81731e6
JM
679 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
680 eap="SAKE", identity="sake user",
681 password_hex="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
682 wait_connect=False)
683 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15)
684 if ev is None:
685 raise Exception("Timeout on EAP start")
686 time.sleep(0.1)
687 dev[0].request("REMOVE_NETWORK all")
688
689 logger.info("Too short password")
690 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
691 eap="SAKE", identity="sake user",
692 password_hex="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcd",
693 wait_connect=False)
694 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15)
695 if ev is None:
696 raise Exception("Timeout on EAP start")
697 time.sleep(0.1)
698 finally:
699 stop_radius_server(srv)
18fc8f40 700
ab4ea0e9
JM
701def test_eap_proto_sake_errors(dev, apdev):
702 """EAP-SAKE local error cases"""
703 check_eap_capa(dev[0], "SAKE")
704 params = hostapd.wpa2_eap_params(ssid="eap-test")
705 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
706
707 for i in range(1, 3):
708 with alloc_fail(dev[0], i, "eap_sake_init"):
709 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
710 eap="SAKE", identity="sake user",
711 password_hex="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
712 wait_connect=False)
713 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
714 timeout=15)
715 if ev is None:
716 raise Exception("Timeout on EAP start")
717 dev[0].request("REMOVE_NETWORK all")
718 dev[0].wait_disconnected()
719
720 tests = [ ( 1, "eap_msg_alloc;eap_sake_build_msg;eap_sake_process_challenge" ),
721 ( 1, "=eap_sake_process_challenge" ),
722 ( 1, "eap_sake_compute_mic;eap_sake_process_challenge" ),
723 ( 1, "eap_sake_build_msg;eap_sake_process_confirm" ),
724 ( 2, "eap_sake_compute_mic;eap_sake_process_confirm" ),
725 ( 1, "eap_sake_getKey" ),
726 ( 1, "eap_sake_get_emsk" ),
727 ( 1, "eap_sake_get_session_id" ) ]
728 for count, func in tests:
729 with alloc_fail(dev[0], count, func):
730 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
731 eap="SAKE", identity="sake user",
732 password_hex="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
733 erp="1",
734 wait_connect=False)
735 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
736 timeout=15)
737 if ev is None:
738 raise Exception("Timeout on EAP start")
739 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
740 dev[0].request("REMOVE_NETWORK all")
741 dev[0].wait_disconnected()
742
743 with fail_test(dev[0], 1, "os_get_random;eap_sake_process_challenge"):
744 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
745 eap="SAKE", identity="sake user",
746 password_hex="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
747 wait_connect=False)
748 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15)
749 if ev is None:
750 raise Exception("Timeout on EAP start")
751 wait_fail_trigger(dev[0], "GET_FAIL")
752 dev[0].request("REMOVE_NETWORK all")
753 dev[0].wait_disconnected()
754
755def test_eap_proto_sake_errors2(dev, apdev):
756 """EAP-SAKE protocol tests (2)"""
757 def sake_handler(ctx, req):
758 logger.info("sake_handler - RX " + req.encode("hex"))
759 if 'num' not in ctx:
760 ctx['num'] = 0
761 ctx['num'] += 1
762 if 'id' not in ctx:
763 ctx['id'] = 1
764 ctx['id'] = (ctx['id'] + 1) % 256
765 idx = 0
766
767 idx += 1
768 if ctx['num'] == idx:
769 logger.info("Test: Identity subtype")
770 return struct.pack(">BBHBBBBBBH", EAP_CODE_REQUEST, ctx['id'],
771 4 + 1 + 3 + 4,
772 EAP_TYPE_SAKE,
773 EAP_SAKE_VERSION, 0, EAP_SAKE_SUBTYPE_IDENTITY,
774 EAP_SAKE_AT_ANY_ID_REQ, 4, 0)
775
776 srv = start_radius_server(sake_handler)
777
778 try:
779 hapd = start_ap(apdev[0]['ifname'])
780
781 with alloc_fail(dev[0], 1, "eap_msg_alloc;eap_sake_build_msg;eap_sake_process_identity"):
782 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
783 eap="SAKE", identity="sake user",
784 password_hex="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
785 wait_connect=False)
786 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
787 timeout=15)
788 if ev is None:
789 raise Exception("Timeout on EAP start")
790 dev[0].request("REMOVE_NETWORK all")
791 dev[0].wait_disconnected()
792
793 finally:
794 stop_radius_server(srv)
795
18fc8f40
JM
796def test_eap_proto_leap(dev, apdev):
797 """EAP-LEAP protocol tests"""
597516df 798 check_eap_capa(dev[0], "LEAP")
18fc8f40
JM
799 def leap_handler(ctx, req):
800 logger.info("leap_handler - RX " + req.encode("hex"))
801 if 'num' not in ctx:
802 ctx['num'] = 0
803 ctx['num'] = ctx['num'] + 1
804 if 'id' not in ctx:
805 ctx['id'] = 1
806 ctx['id'] = (ctx['id'] + 1) % 256
807
808 if ctx['num'] == 1:
809 logger.info("Test: Missing payload")
810 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
811 4 + 1,
812 EAP_TYPE_LEAP)
813
814 if ctx['num'] == 2:
815 logger.info("Test: Unexpected version")
816 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
817 4 + 1 + 3,
818 EAP_TYPE_LEAP,
819 0, 0, 0)
820
821 if ctx['num'] == 3:
822 logger.info("Test: Invalid challenge length")
823 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
824 4 + 1 + 3,
825 EAP_TYPE_LEAP,
826 1, 0, 0)
827
828 if ctx['num'] == 4:
829 logger.info("Test: Truncated challenge")
830 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
831 4 + 1 + 3,
832 EAP_TYPE_LEAP,
833 1, 0, 8)
834
835 if ctx['num'] == 5:
836 logger.info("Test: Valid challenge")
837 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
838 4 + 1 + 3 + 8,
839 EAP_TYPE_LEAP,
840 1, 0, 8, 0, 0)
841 if ctx['num'] == 6:
842 logger.info("Test: Missing payload in Response")
843 return struct.pack(">BBHB", EAP_CODE_RESPONSE, ctx['id'],
844 4 + 1,
845 EAP_TYPE_LEAP)
846
847 if ctx['num'] == 7:
848 logger.info("Test: Valid challenge")
849 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
850 4 + 1 + 3 + 8,
851 EAP_TYPE_LEAP,
852 1, 0, 8, 0, 0)
853 if ctx['num'] == 8:
854 logger.info("Test: Unexpected version in Response")
855 return struct.pack(">BBHBBBB", EAP_CODE_RESPONSE, ctx['id'],
856 4 + 1 + 3,
857 EAP_TYPE_LEAP,
858 0, 0, 8)
859
860 if ctx['num'] == 9:
861 logger.info("Test: Valid challenge")
862 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
863 4 + 1 + 3 + 8,
864 EAP_TYPE_LEAP,
865 1, 0, 8, 0, 0)
866 if ctx['num'] == 10:
867 logger.info("Test: Invalid challenge length in Response")
868 return struct.pack(">BBHBBBB", EAP_CODE_RESPONSE, ctx['id'],
869 4 + 1 + 3,
870 EAP_TYPE_LEAP,
871 1, 0, 0)
872
873 if ctx['num'] == 11:
874 logger.info("Test: Valid challenge")
875 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
876 4 + 1 + 3 + 8,
877 EAP_TYPE_LEAP,
878 1, 0, 8, 0, 0)
879 if ctx['num'] == 12:
880 logger.info("Test: Truncated challenge in Response")
881 return struct.pack(">BBHBBBB", EAP_CODE_RESPONSE, ctx['id'],
882 4 + 1 + 3,
883 EAP_TYPE_LEAP,
884 1, 0, 24)
885
886 if ctx['num'] == 13:
887 logger.info("Test: Valid challenge")
888 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
889 4 + 1 + 3 + 8,
890 EAP_TYPE_LEAP,
891 1, 0, 8, 0, 0)
892 if ctx['num'] == 14:
893 logger.info("Test: Invalid challange value in Response")
894 return struct.pack(">BBHBBBB6L", EAP_CODE_RESPONSE, ctx['id'],
895 4 + 1 + 3 + 24,
896 EAP_TYPE_LEAP,
897 1, 0, 24,
898 0, 0, 0, 0, 0, 0)
899
900 if ctx['num'] == 15:
901 logger.info("Test: Valid challenge")
902 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
903 4 + 1 + 3 + 8,
904 EAP_TYPE_LEAP,
905 1, 0, 8, 0, 0)
906 if ctx['num'] == 16:
907 logger.info("Test: Valid challange value in Response")
908 return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'],
909 4 + 1 + 3 + 24,
910 EAP_TYPE_LEAP,
911 1, 0, 24,
912 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd,
913 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04,
914 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66)
915
916 if ctx['num'] == 17:
917 logger.info("Test: Valid challenge")
918 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
919 4 + 1 + 3 + 8,
920 EAP_TYPE_LEAP,
921 1, 0, 8, 0, 0)
922 if ctx['num'] == 18:
923 logger.info("Test: Success")
924 return struct.pack(">BBHB", EAP_CODE_SUCCESS, ctx['id'],
925 4 + 1,
926 EAP_TYPE_LEAP)
927 # hostapd will drop the next frame in the sequence
928
929 if ctx['num'] == 19:
930 logger.info("Test: Valid challenge")
931 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
932 4 + 1 + 3 + 8,
933 EAP_TYPE_LEAP,
934 1, 0, 8, 0, 0)
935 if ctx['num'] == 20:
936 logger.info("Test: Failure")
937 return struct.pack(">BBHB", EAP_CODE_FAILURE, ctx['id'],
938 4 + 1,
939 EAP_TYPE_LEAP)
940
941 return None
942
943 srv = start_radius_server(leap_handler)
18fc8f40
JM
944
945 try:
946 hapd = start_ap(apdev[0]['ifname'])
947
948 for i in range(0, 12):
949 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
950 eap="LEAP", identity="user", password="password",
951 wait_connect=False)
952 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15)
953 if ev is None:
954 raise Exception("Timeout on EAP start")
955 time.sleep(0.1)
956 if i == 10:
957 logger.info("Wait for additional roundtrip")
958 time.sleep(1)
959 dev[0].request("REMOVE_NETWORK all")
960 finally:
961 stop_radius_server(srv)
8604a68e 962
e114e999
JM
963def test_eap_proto_leap_errors(dev, apdev):
964 """EAP-LEAP protocol tests (error paths)"""
965 check_eap_capa(dev[0], "LEAP")
966
967 def leap_handler2(ctx, req):
968 logger.info("leap_handler2 - RX " + req.encode("hex"))
969 if 'num' not in ctx:
970 ctx['num'] = 0
971 ctx['num'] = ctx['num'] + 1
972 if 'id' not in ctx:
973 ctx['id'] = 1
974 ctx['id'] = (ctx['id'] + 1) % 256
975 idx = 0
976
977 idx += 1
978 if ctx['num'] == idx:
979 logger.info("Test: Valid challenge")
980 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
981 4 + 1 + 3 + 8,
982 EAP_TYPE_LEAP,
983 1, 0, 8, 0, 0)
984 idx += 1
985 if ctx['num'] == idx:
986 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
987
988 idx += 1
989 if ctx['num'] == idx:
990 logger.info("Test: Valid challenge")
991 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
992 4 + 1 + 3 + 8,
993 EAP_TYPE_LEAP,
994 1, 0, 8, 0, 0)
995
996 idx += 1
997 if ctx['num'] == idx:
998 logger.info("Test: Valid challenge")
999 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
1000 4 + 1 + 3 + 8,
1001 EAP_TYPE_LEAP,
1002 1, 0, 8, 0, 0)
1003 idx += 1
1004 if ctx['num'] == idx:
1005 logger.info("Test: Success")
1006 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4)
1007
1008 idx += 1
1009 if ctx['num'] == idx:
1010 logger.info("Test: Valid challenge")
1011 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
1012 4 + 1 + 3 + 8,
1013 EAP_TYPE_LEAP,
1014 1, 0, 8, 0, 0)
1015 idx += 1
1016 if ctx['num'] == idx:
1017 logger.info("Test: Success")
1018 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4)
1019
1020 idx += 1
1021 if ctx['num'] == idx:
1022 logger.info("Test: Valid challenge")
1023 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
1024 4 + 1 + 3 + 8,
1025 EAP_TYPE_LEAP,
1026 1, 0, 8, 0, 0)
1027 idx += 1
1028 if ctx['num'] == idx:
1029 logger.info("Test: Valid challange value in Response")
1030 return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'],
1031 4 + 1 + 3 + 24,
1032 EAP_TYPE_LEAP,
1033 1, 0, 24,
1034 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd,
1035 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04,
1036 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66)
1037
1038 idx += 1
1039 if ctx['num'] == idx:
1040 logger.info("Test: Valid challenge")
1041 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
1042 4 + 1 + 3 + 8,
1043 EAP_TYPE_LEAP,
1044 1, 0, 8, 0, 0)
1045 idx += 1
1046 if ctx['num'] == idx:
1047 logger.info("Test: Valid challange value in Response")
1048 return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'],
1049 4 + 1 + 3 + 24,
1050 EAP_TYPE_LEAP,
1051 1, 0, 24,
1052 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd,
1053 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04,
1054 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66)
1055
1056 idx += 1
1057 if ctx['num'] == idx:
1058 logger.info("Test: Valid challenge")
1059 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
1060 4 + 1 + 3 + 8,
1061 EAP_TYPE_LEAP,
1062 1, 0, 8, 0, 0)
1063 idx += 1
1064 if ctx['num'] == idx:
1065 logger.info("Test: Valid challange value in Response")
1066 return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'],
1067 4 + 1 + 3 + 24,
1068 EAP_TYPE_LEAP,
1069 1, 0, 24,
1070 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd,
1071 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04,
1072 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66)
1073
1074 idx += 1
1075 if ctx['num'] == idx:
1076 logger.info("Test: Valid challenge")
1077 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
1078 4 + 1 + 3 + 8,
1079 EAP_TYPE_LEAP,
1080 1, 0, 8, 0, 0)
1081 idx += 1
1082 if ctx['num'] == idx:
1083 logger.info("Test: Valid challange value in Response")
1084 return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'],
1085 4 + 1 + 3 + 24,
1086 EAP_TYPE_LEAP,
1087 1, 0, 24,
1088 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd,
1089 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04,
1090 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66)
1091
1092 idx += 1
1093 if ctx['num'] == idx:
1094 logger.info("Test: Valid challenge")
1095 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
1096 4 + 1 + 3 + 8,
1097 EAP_TYPE_LEAP,
1098 1, 0, 8, 0, 0)
1099 idx += 1
1100 if ctx['num'] == idx:
1101 logger.info("Test: Valid challange value in Response")
1102 return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'],
1103 4 + 1 + 3 + 24,
1104 EAP_TYPE_LEAP,
1105 1, 0, 24,
1106 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd,
1107 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04,
1108 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66)
1109
1110 idx += 1
1111 if ctx['num'] == idx:
1112 logger.info("Test: Valid challenge")
1113 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
1114 4 + 1 + 3 + 8,
1115 EAP_TYPE_LEAP,
1116 1, 0, 8, 0, 0)
1117 idx += 1
1118 if ctx['num'] == idx:
1119 logger.info("Test: Valid challange value in Response")
1120 return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'],
1121 4 + 1 + 3 + 24,
1122 EAP_TYPE_LEAP,
1123 1, 0, 24,
1124 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd,
1125 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04,
1126 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66)
1127
1128 idx += 1
1129 if ctx['num'] == idx:
1130 logger.info("Test: Valid challenge")
1131 return struct.pack(">BBHBBBBLL", EAP_CODE_REQUEST, ctx['id'],
1132 4 + 1 + 3 + 8,
1133 EAP_TYPE_LEAP,
1134 1, 0, 8, 0, 0)
1135 idx += 1
1136 if ctx['num'] == idx:
1137 logger.info("Test: Valid challange value in Response")
1138 return struct.pack(">BBHBBBB24B", EAP_CODE_RESPONSE, ctx['id'],
1139 4 + 1 + 3 + 24,
1140 EAP_TYPE_LEAP,
1141 1, 0, 24,
1142 0x48, 0x4e, 0x46, 0xe3, 0x88, 0x49, 0x46, 0xbd,
1143 0x28, 0x48, 0xf8, 0x53, 0x82, 0x50, 0x00, 0x04,
1144 0x93, 0x50, 0x30, 0xd7, 0x25, 0xea, 0x5f, 0x66)
1145
1146 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
1147
1148 srv = start_radius_server(leap_handler2)
1149
1150 try:
1151 hapd = start_ap(apdev[0]['ifname'])
1152
1153 with alloc_fail(dev[0], 1, "eap_leap_init"):
1154 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1155 eap="LEAP", identity="user", password="password",
1156 wait_connect=False)
1157 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
1158 dev[0].request("REMOVE_NETWORK all")
1159 dev[0].wait_disconnected()
1160
1161 with alloc_fail(dev[0], 1, "eap_msg_alloc;eap_leap_process_request"):
1162 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1163 eap="LEAP", identity="user",
1164 password_hex="hash:8846f7eaee8fb117ad06bdd830b7586c",
1165 wait_connect=False)
1166 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
1167 dev[0].request("REMOVE_NETWORK all")
1168 dev[0].wait_disconnected()
1169
1170 with alloc_fail(dev[0], 1, "eap_leap_process_success"):
1171 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1172 eap="LEAP", identity="user", password="password",
1173 wait_connect=False)
1174 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
1175 dev[0].request("REMOVE_NETWORK all")
1176 dev[0].wait_disconnected()
1177
1178 with fail_test(dev[0], 1, "os_get_random;eap_leap_process_success"):
1179 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1180 eap="LEAP", identity="user", password="password",
1181 wait_connect=False)
1182 wait_fail_trigger(dev[0], "GET_FAIL")
1183 dev[0].request("REMOVE_NETWORK all")
1184 dev[0].wait_disconnected()
1185
1186 with fail_test(dev[0], 1, "eap_leap_process_response"):
1187 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1188 eap="LEAP", identity="user",
1189 password_hex="hash:8846f7eaee8fb117ad06bdd830b7586c",
1190 wait_connect=False)
1191 wait_fail_trigger(dev[0], "GET_FAIL")
1192 dev[0].request("REMOVE_NETWORK all")
1193 dev[0].wait_disconnected()
1194
1195 with fail_test(dev[0], 1, "nt_password_hash;eap_leap_process_response"):
1196 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1197 eap="LEAP", identity="user", password="password",
1198 wait_connect=False)
1199 wait_fail_trigger(dev[0], "GET_FAIL")
1200 dev[0].request("REMOVE_NETWORK all")
1201 dev[0].wait_disconnected()
1202
1203 with fail_test(dev[0], 1, "hash_nt_password_hash;eap_leap_process_response"):
1204 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1205 eap="LEAP", identity="user", password="password",
1206 wait_connect=False)
1207 wait_fail_trigger(dev[0], "GET_FAIL")
1208 dev[0].request("REMOVE_NETWORK all")
1209 dev[0].wait_disconnected()
1210
1211 with alloc_fail(dev[0], 1, "eap_leap_getKey"):
1212 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1213 eap="LEAP", identity="user",
1214 password_hex="hash:8846f7eaee8fb117ad06bdd830b7586c",
1215 wait_connect=False)
1216 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
1217 dev[0].request("REMOVE_NETWORK all")
1218 dev[0].wait_disconnected()
1219
1220 with fail_test(dev[0], 1, "eap_leap_getKey"):
1221 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1222 eap="LEAP", identity="user",
1223 password_hex="hash:8846f7eaee8fb117ad06bdd830b7586c",
1224 wait_connect=False)
1225 wait_fail_trigger(dev[0], "GET_FAIL")
1226 dev[0].request("REMOVE_NETWORK all")
1227 dev[0].wait_disconnected()
1228
1229 with fail_test(dev[0], 1, "nt_password_hash;eap_leap_getKey"):
1230 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1231 eap="LEAP", identity="user", password="password",
1232 wait_connect=False)
1233 wait_fail_trigger(dev[0], "GET_FAIL")
1234 dev[0].request("REMOVE_NETWORK all")
1235 dev[0].wait_disconnected()
1236
1237 with fail_test(dev[0], 1, "hash_nt_password_hash;eap_leap_getKey"):
1238 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1239 eap="LEAP", identity="user", password="password",
1240 wait_connect=False)
1241 wait_fail_trigger(dev[0], "GET_FAIL")
1242 dev[0].request("REMOVE_NETWORK all")
1243 dev[0].wait_disconnected()
1244 finally:
1245 stop_radius_server(srv)
1246
8604a68e
JM
1247def test_eap_proto_md5(dev, apdev):
1248 """EAP-MD5 protocol tests"""
e7ac04ce
JM
1249 check_eap_capa(dev[0], "MD5")
1250
8604a68e
JM
1251 def md5_handler(ctx, req):
1252 logger.info("md5_handler - RX " + req.encode("hex"))
1253 if 'num' not in ctx:
1254 ctx['num'] = 0
1255 ctx['num'] = ctx['num'] + 1
1256 if 'id' not in ctx:
1257 ctx['id'] = 1
1258 ctx['id'] = (ctx['id'] + 1) % 256
1259
1260 if ctx['num'] == 1:
1261 logger.info("Test: Missing payload")
1262 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
1263 4 + 1,
1264 EAP_TYPE_MD5)
1265
1266 if ctx['num'] == 2:
1267 logger.info("Test: Zero-length challenge")
1268 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1269 4 + 1 + 1,
1270 EAP_TYPE_MD5,
1271 0)
1272
1273 if ctx['num'] == 3:
1274 logger.info("Test: Truncated challenge")
1275 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1276 4 + 1 + 1,
1277 EAP_TYPE_MD5,
1278 1)
1279
1280 if ctx['num'] == 4:
1281 logger.info("Test: Shortest possible challenge and name")
1282 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
1283 4 + 1 + 3,
1284 EAP_TYPE_MD5,
1285 1, 0xaa, ord('n'))
1286
1287 return None
1288
1289 srv = start_radius_server(md5_handler)
8604a68e
JM
1290
1291 try:
1292 hapd = start_ap(apdev[0]['ifname'])
1293
1294 for i in range(0, 4):
1295 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1296 eap="MD5", identity="user", password="password",
1297 wait_connect=False)
1298 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15)
1299 if ev is None:
1300 raise Exception("Timeout on EAP start")
1301 time.sleep(0.1)
1302 dev[0].request("REMOVE_NETWORK all")
1303 finally:
1304 stop_radius_server(srv)
d5c14b25 1305
d5482411
JM
1306def test_eap_proto_md5_errors(dev, apdev):
1307 """EAP-MD5 local error cases"""
1308 check_eap_capa(dev[0], "MD5")
1309 params = hostapd.wpa2_eap_params(ssid="eap-test")
1310 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1311
1312 with fail_test(dev[0], 1, "chap_md5"):
1313 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1314 eap="MD5", identity="phase1-user", password="password",
1315 wait_connect=False)
1316 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=15)
1317 if ev is None:
1318 raise Exception("Timeout on EAP start")
1319 dev[0].request("REMOVE_NETWORK all")
1320 dev[0].wait_disconnected()
1321
1322 with alloc_fail(dev[0], 1, "eap_msg_alloc;eap_md5_process"):
1323 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1324 eap="MD5", identity="phase1-user", password="password",
1325 wait_connect=False)
1326 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=15)
1327 if ev is None:
1328 raise Exception("Timeout on EAP start")
1329 time.sleep(0.1)
1330 dev[0].request("REMOVE_NETWORK all")
1331
d5c14b25
JM
1332def test_eap_proto_otp(dev, apdev):
1333 """EAP-OTP protocol tests"""
1334 def otp_handler(ctx, req):
1335 logger.info("otp_handler - RX " + req.encode("hex"))
1336 if 'num' not in ctx:
1337 ctx['num'] = 0
1338 ctx['num'] = ctx['num'] + 1
1339 if 'id' not in ctx:
1340 ctx['id'] = 1
1341 ctx['id'] = (ctx['id'] + 1) % 256
1342
1343 if ctx['num'] == 1:
1344 logger.info("Test: Empty payload")
1345 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
1346 4 + 1,
1347 EAP_TYPE_OTP)
1348 if ctx['num'] == 2:
1349 logger.info("Test: Success")
1350 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'],
1351 4)
1352
1353 if ctx['num'] == 3:
1354 logger.info("Test: Challenge included")
1355 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1356 4 + 1 + 1,
1357 EAP_TYPE_OTP,
1358 ord('A'))
1359 if ctx['num'] == 4:
1360 logger.info("Test: Success")
1361 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'],
1362 4)
1363
1364 return None
1365
1366 srv = start_radius_server(otp_handler)
d5c14b25
JM
1367
1368 try:
1369 hapd = start_ap(apdev[0]['ifname'])
1370
1371 for i in range(0, 1):
1372 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1373 eap="OTP", identity="user", password="password",
1374 wait_connect=False)
1375 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
1376 timeout=15)
1377 if ev is None:
1378 raise Exception("Timeout on EAP start")
1379 time.sleep(0.1)
1380 dev[0].request("REMOVE_NETWORK all")
1381
1382 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1383 eap="OTP", identity="user", wait_connect=False)
1384 ev = dev[0].wait_event(["CTRL-REQ-OTP"])
1385 if ev is None:
1386 raise Exception("Request for password timed out")
1387 id = ev.split(':')[0].split('-')[-1]
1388 dev[0].request("CTRL-RSP-OTP-" + id + ":password")
1389 ev = dev[0].wait_event("CTRL-EVENT-EAP-SUCCESS")
1390 if ev is None:
1391 raise Exception("Success not reported")
1392 finally:
1393 stop_radius_server(srv)
2e9f8ee7 1394
2386bb97
JM
1395def test_eap_proto_otp_errors(dev, apdev):
1396 """EAP-OTP local error cases"""
1397 def otp_handler2(ctx, req):
1398 logger.info("otp_handler2 - RX " + req.encode("hex"))
1399 if 'num' not in ctx:
1400 ctx['num'] = 0
1401 ctx['num'] = ctx['num'] + 1
1402 if 'id' not in ctx:
1403 ctx['id'] = 1
1404 ctx['id'] = (ctx['id'] + 1) % 256
1405 idx = 0
1406
1407 idx += 1
1408 if ctx['num'] == idx:
1409 logger.info("Test: Challenge included")
1410 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1411 4 + 1 + 1,
1412 EAP_TYPE_OTP,
1413 ord('A'))
1414
1415 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
1416
1417 srv = start_radius_server(otp_handler2)
1418
1419 try:
1420 hapd = start_ap(apdev[0]['ifname'])
1421
1422 with alloc_fail(dev[0], 1, "eap_msg_alloc;eap_otp_process"):
1423 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1424 eap="OTP", identity="user", password="password",
1425 wait_connect=False)
1426 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
1427 dev[0].request("REMOVE_NETWORK all")
1428 dev[0].wait_disconnected()
1429 finally:
1430 stop_radius_server(srv)
1431
2e9f8ee7
JM
1432EAP_GPSK_OPCODE_GPSK_1 = 1
1433EAP_GPSK_OPCODE_GPSK_2 = 2
1434EAP_GPSK_OPCODE_GPSK_3 = 3
1435EAP_GPSK_OPCODE_GPSK_4 = 4
1436EAP_GPSK_OPCODE_FAIL = 5
1437EAP_GPSK_OPCODE_PROTECTED_FAIL = 6
1438
1439def test_eap_proto_gpsk(dev, apdev):
1440 """EAP-GPSK protocol tests"""
1441 def gpsk_handler(ctx, req):
1442 logger.info("gpsk_handler - RX " + req.encode("hex"))
1443 if 'num' not in ctx:
1444 ctx['num'] = 0
1445 ctx['num'] = ctx['num'] + 1
1446 if 'id' not in ctx:
1447 ctx['id'] = 1
1448 ctx['id'] = (ctx['id'] + 1) % 256
1449
1450 idx = 0
1451
1452 idx += 1
1453 if ctx['num'] == idx:
1454 logger.info("Test: Missing payload")
1455 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
1456 4 + 1,
1457 EAP_TYPE_GPSK)
1458
1459 idx += 1
1460 if ctx['num'] == idx:
1461 logger.info("Test: Unknown opcode")
1462 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1463 4 + 1 + 1,
1464 EAP_TYPE_GPSK,
1465 255)
1466
1467 idx += 1
1468 if ctx['num'] == idx:
1469 logger.info("Test: Unexpected GPSK-3")
1470 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1471 4 + 1 + 1,
1472 EAP_TYPE_GPSK,
1473 EAP_GPSK_OPCODE_GPSK_3)
1474
1475 idx += 1
1476 if ctx['num'] == idx:
1477 logger.info("Test: GPSK-1 Too short GPSK-1")
1478 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1479 4 + 1 + 1,
1480 EAP_TYPE_GPSK,
1481 EAP_GPSK_OPCODE_GPSK_1)
1482
1483 idx += 1
1484 if ctx['num'] == idx:
1485 logger.info("Test: GPSK-1 Truncated ID_Server")
1486 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
1487 4 + 1 + 1 + 2,
1488 EAP_TYPE_GPSK,
1489 EAP_GPSK_OPCODE_GPSK_1, 1)
1490
1491 idx += 1
1492 if ctx['num'] == idx:
1493 logger.info("Test: GPSK-1 Missing RAND_Server")
1494 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
1495 4 + 1 + 1 + 2,
1496 EAP_TYPE_GPSK,
1497 EAP_GPSK_OPCODE_GPSK_1, 0)
1498
1499 idx += 1
1500 if ctx['num'] == idx:
1501 logger.info("Test: GPSK-1 Missing CSuite_List")
1502 return struct.pack(">BBHBBH8L", EAP_CODE_REQUEST, ctx['id'],
1503 4 + 1 + 1 + 2 + 32,
1504 EAP_TYPE_GPSK,
1505 EAP_GPSK_OPCODE_GPSK_1, 0,
1506 0, 0, 0, 0, 0, 0, 0, 0)
1507
1508 idx += 1
1509 if ctx['num'] == idx:
1510 logger.info("Test: GPSK-1 Truncated CSuite_List")
1511 return struct.pack(">BBHBBH8LH", EAP_CODE_REQUEST, ctx['id'],
1512 4 + 1 + 1 + 2 + 32 + 2,
1513 EAP_TYPE_GPSK,
1514 EAP_GPSK_OPCODE_GPSK_1, 0,
1515 0, 0, 0, 0, 0, 0, 0, 0,
1516 1)
1517
1518 idx += 1
1519 if ctx['num'] == idx:
1520 logger.info("Test: GPSK-1 Empty CSuite_List")
1521 return struct.pack(">BBHBBH8LH", EAP_CODE_REQUEST, ctx['id'],
1522 4 + 1 + 1 + 2 + 32 + 2,
1523 EAP_TYPE_GPSK,
1524 EAP_GPSK_OPCODE_GPSK_1, 0,
1525 0, 0, 0, 0, 0, 0, 0, 0,
1526 0)
1527
1528 idx += 1
1529 if ctx['num'] == idx:
1530 logger.info("Test: GPSK-1 Invalid CSuite_List")
1531 return struct.pack(">BBHBBH8LHB", EAP_CODE_REQUEST, ctx['id'],
1532 4 + 1 + 1 + 2 + 32 + 2 + 1,
1533 EAP_TYPE_GPSK,
1534 EAP_GPSK_OPCODE_GPSK_1, 0,
1535 0, 0, 0, 0, 0, 0, 0, 0,
1536 1, 0)
1537
1538 idx += 1
1539 if ctx['num'] == idx:
1540 logger.info("Test: GPSK-1 No supported CSuite")
1541 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
1542 4 + 1 + 1 + 2 + 32 + 2 + 6,
1543 EAP_TYPE_GPSK,
1544 EAP_GPSK_OPCODE_GPSK_1, 0,
1545 0, 0, 0, 0, 0, 0, 0, 0,
1546 6, 0, 0)
1547
1548 idx += 1
1549 if ctx['num'] == idx:
1550 logger.info("Test: GPSK-1 Supported CSuite")
1551 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
1552 4 + 1 + 1 + 2 + 32 + 2 + 6,
1553 EAP_TYPE_GPSK,
1554 EAP_GPSK_OPCODE_GPSK_1, 0,
1555 0, 0, 0, 0, 0, 0, 0, 0,
1556 6, 0, 1)
1557 idx += 1
1558 if ctx['num'] == idx:
1559 logger.info("Test: Unexpected GPSK-1")
1560 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
1561 4 + 1 + 1 + 2 + 32 + 2 + 6,
1562 EAP_TYPE_GPSK,
1563 EAP_GPSK_OPCODE_GPSK_1, 0,
1564 0, 0, 0, 0, 0, 0, 0, 0,
1565 6, 0, 1)
1566
1567 idx += 1
1568 if ctx['num'] == idx:
1569 logger.info("Test: GPSK-1 Supported CSuite but too short key")
1570 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
1571 4 + 1 + 1 + 2 + 32 + 2 + 6,
1572 EAP_TYPE_GPSK,
1573 EAP_GPSK_OPCODE_GPSK_1, 0,
1574 0, 0, 0, 0, 0, 0, 0, 0,
1575 6, 0, 1)
1576
1577 idx += 1
1578 if ctx['num'] == idx:
1579 logger.info("Test: GPSK-1 Supported CSuite")
1580 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
1581 4 + 1 + 1 + 2 + 32 + 2 + 6,
1582 EAP_TYPE_GPSK,
1583 EAP_GPSK_OPCODE_GPSK_1, 0,
1584 0, 0, 0, 0, 0, 0, 0, 0,
1585 6, 0, 1)
1586 idx += 1
1587 if ctx['num'] == idx:
1588 logger.info("Test: Too short GPSK-3")
1589 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1590 4 + 1 + 1,
1591 EAP_TYPE_GPSK,
1592 EAP_GPSK_OPCODE_GPSK_3)
1593
1594 idx += 1
1595 if ctx['num'] == idx:
1596 logger.info("Test: GPSK-1 Supported CSuite")
1597 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
1598 4 + 1 + 1 + 2 + 32 + 2 + 6,
1599 EAP_TYPE_GPSK,
1600 EAP_GPSK_OPCODE_GPSK_1, 0,
1601 0, 0, 0, 0, 0, 0, 0, 0,
1602 6, 0, 1)
1603 idx += 1
1604 if ctx['num'] == idx:
1605 logger.info("Test: GPSK-3 Mismatch in RAND_Peer")
1606 return struct.pack(">BBHBB8L", EAP_CODE_REQUEST, ctx['id'],
1607 4 + 1 + 1 + 32,
1608 EAP_TYPE_GPSK,
1609 EAP_GPSK_OPCODE_GPSK_3,
1610 0, 0, 0, 0, 0, 0, 0, 0)
1611
1612 idx += 1
1613 if ctx['num'] == idx:
1614 logger.info("Test: GPSK-1 Supported CSuite")
1615 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
1616 4 + 1 + 1 + 2 + 32 + 2 + 6,
1617 EAP_TYPE_GPSK,
1618 EAP_GPSK_OPCODE_GPSK_1, 0,
1619 0, 0, 0, 0, 0, 0, 0, 0,
1620 6, 0, 1)
1621 idx += 1
1622 if ctx['num'] == idx:
1623 logger.info("Test: GPSK-3 Missing RAND_Server")
1624 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1625 4 + 1 + 1 + 32,
1626 EAP_TYPE_GPSK,
1627 EAP_GPSK_OPCODE_GPSK_3)
1628 msg += req[14:46]
1629 return msg
1630
1631 idx += 1
1632 if ctx['num'] == idx:
1633 logger.info("Test: GPSK-1 Supported CSuite")
1634 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
1635 4 + 1 + 1 + 2 + 32 + 2 + 6,
1636 EAP_TYPE_GPSK,
1637 EAP_GPSK_OPCODE_GPSK_1, 0,
1638 0, 0, 0, 0, 0, 0, 0, 0,
1639 6, 0, 1)
1640 idx += 1
1641 if ctx['num'] == idx:
1642 logger.info("Test: GPSK-3 Mismatch in RAND_Server")
1643 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1644 4 + 1 + 1 + 32 + 32,
1645 EAP_TYPE_GPSK,
1646 EAP_GPSK_OPCODE_GPSK_3)
1647 msg += req[14:46]
1648 msg += struct.pack(">8L", 1, 1, 1, 1, 1, 1, 1, 1)
1649 return msg
1650
1651 idx += 1
1652 if ctx['num'] == idx:
1653 logger.info("Test: GPSK-1 Supported CSuite")
1654 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
1655 4 + 1 + 1 + 2 + 32 + 2 + 6,
1656 EAP_TYPE_GPSK,
1657 EAP_GPSK_OPCODE_GPSK_1, 0,
1658 0, 0, 0, 0, 0, 0, 0, 0,
1659 6, 0, 1)
1660 idx += 1
1661 if ctx['num'] == idx:
1662 logger.info("Test: GPSK-3 Missing ID_Server")
1663 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1664 4 + 1 + 1 + 32 + 32,
1665 EAP_TYPE_GPSK,
1666 EAP_GPSK_OPCODE_GPSK_3)
1667 msg += req[14:46]
1668 msg += struct.pack(">8L", 0, 0, 0, 0, 0, 0, 0, 0)
1669 return msg
1670
1671 idx += 1
1672 if ctx['num'] == idx:
1673 logger.info("Test: GPSK-1 Supported CSuite")
1674 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
1675 4 + 1 + 1 + 2 + 32 + 2 + 6,
1676 EAP_TYPE_GPSK,
1677 EAP_GPSK_OPCODE_GPSK_1, 0,
1678 0, 0, 0, 0, 0, 0, 0, 0,
1679 6, 0, 1)
1680 idx += 1
1681 if ctx['num'] == idx:
1682 logger.info("Test: GPSK-3 Truncated ID_Server")
1683 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1684 4 + 1 + 1 + 32 + 32 + 2,
1685 EAP_TYPE_GPSK,
1686 EAP_GPSK_OPCODE_GPSK_3)
1687 msg += req[14:46]
1688 msg += struct.pack(">8LH", 0, 0, 0, 0, 0, 0, 0, 0, 1)
1689 return msg
1690
1691 idx += 1
1692 if ctx['num'] == idx:
1693 logger.info("Test: GPSK-1 Supported CSuite")
1694 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
1695 4 + 1 + 1 + 2 + 32 + 2 + 6,
1696 EAP_TYPE_GPSK,
1697 EAP_GPSK_OPCODE_GPSK_1, 0,
1698 0, 0, 0, 0, 0, 0, 0, 0,
1699 6, 0, 1)
1700 idx += 1
1701 if ctx['num'] == idx:
1702 logger.info("Test: GPSK-3 Mismatch in ID_Server")
1703 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1704 4 + 1 + 1 + 32 + 32 + 3,
1705 EAP_TYPE_GPSK,
1706 EAP_GPSK_OPCODE_GPSK_3)
1707 msg += req[14:46]
1708 msg += struct.pack(">8LHB", 0, 0, 0, 0, 0, 0, 0, 0, 1, ord('B'))
1709 return msg
1710
1711 idx += 1
1712 if ctx['num'] == idx:
1713 logger.info("Test: GPSK-1 Supported CSuite")
1714 return struct.pack(">BBHBBHB8LHLH", EAP_CODE_REQUEST, ctx['id'],
1715 4 + 1 + 1 + 3 + 32 + 2 + 6,
1716 EAP_TYPE_GPSK,
1717 EAP_GPSK_OPCODE_GPSK_1, 1, ord('A'),
1718 0, 0, 0, 0, 0, 0, 0, 0,
1719 6, 0, 1)
1720 idx += 1
1721 if ctx['num'] == idx:
1722 logger.info("Test: GPSK-3 Mismatch in ID_Server (same length)")
1723 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1724 4 + 1 + 1 + 32 + 32 + 3,
1725 EAP_TYPE_GPSK,
1726 EAP_GPSK_OPCODE_GPSK_3)
1727 msg += req[15:47]
1728 msg += struct.pack(">8LHB", 0, 0, 0, 0, 0, 0, 0, 0, 1, ord('B'))
1729 return msg
1730
1731 idx += 1
1732 if ctx['num'] == idx:
1733 logger.info("Test: GPSK-1 Supported CSuite")
1734 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
1735 4 + 1 + 1 + 2 + 32 + 2 + 6,
1736 EAP_TYPE_GPSK,
1737 EAP_GPSK_OPCODE_GPSK_1, 0,
1738 0, 0, 0, 0, 0, 0, 0, 0,
1739 6, 0, 1)
1740 idx += 1
1741 if ctx['num'] == idx:
1742 logger.info("Test: GPSK-3 Missing CSuite_Sel")
1743 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1744 4 + 1 + 1 + 32 + 32 + 2,
1745 EAP_TYPE_GPSK,
1746 EAP_GPSK_OPCODE_GPSK_3)
1747 msg += req[14:46]
1748 msg += struct.pack(">8LH", 0, 0, 0, 0, 0, 0, 0, 0, 0)
1749 return msg
1750
1751 idx += 1
1752 if ctx['num'] == idx:
1753 logger.info("Test: GPSK-1 Supported CSuite")
1754 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
1755 4 + 1 + 1 + 2 + 32 + 2 + 6,
1756 EAP_TYPE_GPSK,
1757 EAP_GPSK_OPCODE_GPSK_1, 0,
1758 0, 0, 0, 0, 0, 0, 0, 0,
1759 6, 0, 1)
1760 idx += 1
1761 if ctx['num'] == idx:
1762 logger.info("Test: GPSK-3 Mismatch in CSuite_Sel")
1763 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1764 4 + 1 + 1 + 32 + 32 + 2 + 6,
1765 EAP_TYPE_GPSK,
1766 EAP_GPSK_OPCODE_GPSK_3)
1767 msg += req[14:46]
1768 msg += struct.pack(">8LHLH", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2)
1769 return msg
1770
1771 idx += 1
1772 if ctx['num'] == idx:
1773 logger.info("Test: GPSK-1 Supported CSuite")
1774 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
1775 4 + 1 + 1 + 2 + 32 + 2 + 6,
1776 EAP_TYPE_GPSK,
1777 EAP_GPSK_OPCODE_GPSK_1, 0,
1778 0, 0, 0, 0, 0, 0, 0, 0,
1779 6, 0, 1)
1780 idx += 1
1781 if ctx['num'] == idx:
1782 logger.info("Test: GPSK-3 Missing len(PD_Payload_Block)")
1783 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1784 4 + 1 + 1 + 32 + 32 + 2 + 6,
1785 EAP_TYPE_GPSK,
1786 EAP_GPSK_OPCODE_GPSK_3)
1787 msg += req[14:46]
1788 msg += struct.pack(">8LHLH", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1)
1789 return msg
1790
1791 idx += 1
1792 if ctx['num'] == idx:
1793 logger.info("Test: GPSK-1 Supported CSuite")
1794 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
1795 4 + 1 + 1 + 2 + 32 + 2 + 6,
1796 EAP_TYPE_GPSK,
1797 EAP_GPSK_OPCODE_GPSK_1, 0,
1798 0, 0, 0, 0, 0, 0, 0, 0,
1799 6, 0, 1)
1800 idx += 1
1801 if ctx['num'] == idx:
1802 logger.info("Test: GPSK-3 Truncated PD_Payload_Block")
1803 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1804 4 + 1 + 1 + 32 + 32 + 2 + 6 + 2,
1805 EAP_TYPE_GPSK,
1806 EAP_GPSK_OPCODE_GPSK_3)
1807 msg += req[14:46]
1808 msg += struct.pack(">8LHLHH", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1)
1809 return msg
1810
1811 idx += 1
1812 if ctx['num'] == idx:
1813 logger.info("Test: GPSK-1 Supported CSuite")
1814 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
1815 4 + 1 + 1 + 2 + 32 + 2 + 6,
1816 EAP_TYPE_GPSK,
1817 EAP_GPSK_OPCODE_GPSK_1, 0,
1818 0, 0, 0, 0, 0, 0, 0, 0,
1819 6, 0, 1)
1820 idx += 1
1821 if ctx['num'] == idx:
1822 logger.info("Test: GPSK-3 Missing MAC")
1823 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1824 4 + 1 + 1 + 32 + 32 + 2 + 6 + 3,
1825 EAP_TYPE_GPSK,
1826 EAP_GPSK_OPCODE_GPSK_3)
1827 msg += req[14:46]
1828 msg += struct.pack(">8LHLHHB",
1829 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 123)
1830 return msg
1831
1832 idx += 1
1833 if ctx['num'] == idx:
1834 logger.info("Test: GPSK-1 Supported CSuite")
1835 return struct.pack(">BBHBBH8LHLH", EAP_CODE_REQUEST, ctx['id'],
1836 4 + 1 + 1 + 2 + 32 + 2 + 6,
1837 EAP_TYPE_GPSK,
1838 EAP_GPSK_OPCODE_GPSK_1, 0,
1839 0, 0, 0, 0, 0, 0, 0, 0,
1840 6, 0, 1)
1841 idx += 1
1842 if ctx['num'] == idx:
1843 logger.info("Test: GPSK-3 Incorrect MAC")
1844 msg = struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1845 4 + 1 + 1 + 32 + 32 + 2 + 6 + 3 + 16,
1846 EAP_TYPE_GPSK,
1847 EAP_GPSK_OPCODE_GPSK_3)
1848 msg += req[14:46]
1849 msg += struct.pack(">8LHLHHB4L",
1850 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 123,
1851 0, 0, 0, 0)
1852 return msg
1853
1854 return None
1855
1856 srv = start_radius_server(gpsk_handler)
2e9f8ee7
JM
1857
1858 try:
1859 hapd = start_ap(apdev[0]['ifname'])
1860
1861 for i in range(0, 27):
1862 if i == 12:
1863 pw = "short"
1864 else:
1865 pw = "abcdefghijklmnop0123456789abcdef"
1866 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
1867 eap="GPSK", identity="user", password=pw,
1868 wait_connect=False)
1869 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
1870 timeout=15)
1871 if ev is None:
1872 raise Exception("Timeout on EAP start")
1873 time.sleep(0.05)
1874 dev[0].request("REMOVE_NETWORK all")
1875 finally:
1876 stop_radius_server(srv)
30d62b7a
JM
1877
1878EAP_EKE_ID = 1
1879EAP_EKE_COMMIT = 2
1880EAP_EKE_CONFIRM = 3
1881EAP_EKE_FAILURE = 4
1882
1883def test_eap_proto_eke(dev, apdev):
1884 """EAP-EKE protocol tests"""
1885 def eke_handler(ctx, req):
1886 logger.info("eke_handler - RX " + req.encode("hex"))
1887 if 'num' not in ctx:
1888 ctx['num'] = 0
1889 ctx['num'] = ctx['num'] + 1
1890 if 'id' not in ctx:
1891 ctx['id'] = 1
1892 ctx['id'] = (ctx['id'] + 1) % 256
1893
1894 idx = 0
1895
1896 idx += 1
1897 if ctx['num'] == idx:
1898 logger.info("Test: Missing payload")
1899 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
1900 4 + 1,
1901 EAP_TYPE_EKE)
1902
1903 idx += 1
1904 if ctx['num'] == idx:
1905 logger.info("Test: Unknown exchange")
1906 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1907 4 + 1 + 1,
1908 EAP_TYPE_EKE,
1909 255)
1910
1911 idx += 1
1912 if ctx['num'] == idx:
1913 logger.info("Test: No NumProposals in EAP-EKE-ID/Request")
1914 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
1915 4 + 1 + 1,
1916 EAP_TYPE_EKE,
1917 EAP_EKE_ID)
1918 idx += 1
1919 if ctx['num'] == idx:
1920 logger.info("Test: EAP-Failure")
1921 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
1922
1923 idx += 1
1924 if ctx['num'] == idx:
1925 logger.info("Test: NumProposals=0 in EAP-EKE-ID/Request")
1926 return struct.pack(">BBHBBB", EAP_CODE_REQUEST, ctx['id'],
1927 4 + 1 + 1 + 1,
1928 EAP_TYPE_EKE,
1929 EAP_EKE_ID,
1930 0)
1931 idx += 1
1932 if ctx['num'] == idx:
1933 logger.info("Test: EAP-Failure")
1934 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
1935
1936 idx += 1
1937 if ctx['num'] == idx:
1938 logger.info("Test: Truncated Proposals list in EAP-EKE-ID/Request")
1939 return struct.pack(">BBHBBBB4B", EAP_CODE_REQUEST, ctx['id'],
1940 4 + 1 + 1 + 2 + 4,
1941 EAP_TYPE_EKE,
1942 EAP_EKE_ID,
1943 2, 0, 0, 0, 0, 0)
1944 idx += 1
1945 if ctx['num'] == idx:
1946 logger.info("Test: EAP-Failure")
1947 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
1948
1949 idx += 1
1950 if ctx['num'] == idx:
1951 logger.info("Test: Unsupported proposals in EAP-EKE-ID/Request")
1952 return struct.pack(">BBHBBBB4B4B4B4B", EAP_CODE_REQUEST, ctx['id'],
1953 4 + 1 + 1 + 2 + 4 * 4,
1954 EAP_TYPE_EKE,
1955 EAP_EKE_ID,
1956 4, 0,
1957 0, 0, 0, 0,
1958 3, 0, 0, 0,
1959 3, 1, 0, 0,
1960 3, 1, 1, 0)
1961 idx += 1
1962 if ctx['num'] == idx:
1963 logger.info("Test: EAP-Failure")
1964 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
1965
1966 idx += 1
1967 if ctx['num'] == idx:
1968 logger.info("Test: Missing IDType/Identity in EAP-EKE-ID/Request")
1969 return struct.pack(">BBHBBBB4B4B4B4B4B",
1970 EAP_CODE_REQUEST, ctx['id'],
1971 4 + 1 + 1 + 2 + 5 * 4,
1972 EAP_TYPE_EKE,
1973 EAP_EKE_ID,
1974 5, 0,
1975 0, 0, 0, 0,
1976 3, 0, 0, 0,
1977 3, 1, 0, 0,
1978 3, 1, 1, 0,
1979 3, 1, 1, 1)
1980 idx += 1
1981 if ctx['num'] == idx:
1982 logger.info("Test: EAP-Failure")
1983 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
1984
1985 idx += 1
1986 if ctx['num'] == idx:
1987 logger.info("Test: Valid EAP-EKE-ID/Request")
1988 return struct.pack(">BBHBBBB4BB",
1989 EAP_CODE_REQUEST, ctx['id'],
1990 4 + 1 + 1 + 2 + 4 + 1,
1991 EAP_TYPE_EKE,
1992 EAP_EKE_ID,
1993 1, 0,
1994 3, 1, 1, 1,
1995 255)
1996 idx += 1
1997 if ctx['num'] == idx:
1998 logger.info("Test: Unexpected EAP-EKE-ID/Request")
1999 return struct.pack(">BBHBBBB4BB",
2000 EAP_CODE_REQUEST, ctx['id'],
2001 4 + 1 + 1 + 2 + 4 + 1,
2002 EAP_TYPE_EKE,
2003 EAP_EKE_ID,
2004 1, 0,
2005 3, 1, 1, 1,
2006 255)
2007 idx += 1
2008 if ctx['num'] == idx:
2009 logger.info("Test: EAP-Failure")
2010 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
2011
2012 idx += 1
2013 if ctx['num'] == idx:
2014 logger.info("Test: Valid EAP-EKE-ID/Request")
2015 return struct.pack(">BBHBBBB4BB",
2016 EAP_CODE_REQUEST, ctx['id'],
2017 4 + 1 + 1 + 2 + 4 + 1,
2018 EAP_TYPE_EKE,
2019 EAP_EKE_ID,
2020 1, 0,
2021 3, 1, 1, 1,
2022 255)
2023 idx += 1
2024 if ctx['num'] == idx:
2025 logger.info("Test: Unexpected EAP-EKE-Confirm/Request")
2026 return struct.pack(">BBHBB",
2027 EAP_CODE_REQUEST, ctx['id'],
2028 4 + 1 + 1,
2029 EAP_TYPE_EKE,
2030 EAP_EKE_CONFIRM)
2031 idx += 1
2032 if ctx['num'] == idx:
2033 logger.info("Test: EAP-Failure")
2034 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
2035
2036 idx += 1
2037 if ctx['num'] == idx:
2038 logger.info("Test: Too short EAP-EKE-Failure/Request")
2039 return struct.pack(">BBHBB",
2040 EAP_CODE_REQUEST, ctx['id'],
2041 4 + 1 + 1,
2042 EAP_TYPE_EKE,
2043 EAP_EKE_FAILURE)
2044 idx += 1
2045 if ctx['num'] == idx:
2046 logger.info("Test: EAP-Failure")
2047 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
2048
2049 idx += 1
2050 if ctx['num'] == idx:
2051 logger.info("Test: Unexpected EAP-EKE-Commit/Request")
2052 return struct.pack(">BBHBB",
2053 EAP_CODE_REQUEST, ctx['id'],
2054 4 + 1 + 1,
2055 EAP_TYPE_EKE,
2056 EAP_EKE_COMMIT)
2057 idx += 1
2058 if ctx['num'] == idx:
2059 logger.info("Test: EAP-Failure")
2060 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
2061
2062 idx += 1
2063 if ctx['num'] == idx:
2064 logger.info("Test: Valid EAP-EKE-ID/Request")
2065 return struct.pack(">BBHBBBB4BB",
2066 EAP_CODE_REQUEST, ctx['id'],
2067 4 + 1 + 1 + 2 + 4 + 1,
2068 EAP_TYPE_EKE,
2069 EAP_EKE_ID,
2070 1, 0,
2071 3, 1, 1, 1,
2072 255)
2073 idx += 1
2074 if ctx['num'] == idx:
2075 logger.info("Test: Too short EAP-EKE-Commit/Request")
2076 return struct.pack(">BBHBB",
2077 EAP_CODE_REQUEST, ctx['id'],
2078 4 + 1 + 1,
2079 EAP_TYPE_EKE,
2080 EAP_EKE_COMMIT)
2081 idx += 1
2082 if ctx['num'] == idx:
2083 logger.info("Test: EAP-Failure")
2084 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
2085
2086 idx += 1
2087 if ctx['num'] == idx:
2088 logger.info("Test: Valid EAP-EKE-ID/Request")
2089 return struct.pack(">BBHBBBB4BB",
2090 EAP_CODE_REQUEST, ctx['id'],
2091 4 + 1 + 1 + 2 + 4 + 1,
2092 EAP_TYPE_EKE,
2093 EAP_EKE_ID,
2094 1, 0,
2095 1, 1, 1, 1,
2096 255)
2097 idx += 1
2098 if ctx['num'] == idx:
2099 logger.info("Test: All zeroes DHComponent_S and empty CBvalue in EAP-EKE-Commit/Request")
2100 return struct.pack(">BBHBB4L32L",
2101 EAP_CODE_REQUEST, ctx['id'],
2102 4 + 1 + 1 + 16 + 128,
2103 EAP_TYPE_EKE,
2104 EAP_EKE_COMMIT,
2105 0, 0, 0, 0,
2106 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2107 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
2108 idx += 1
2109 if ctx['num'] == idx:
2110 logger.info("Test: Too short EAP-EKE-Confirm/Request")
2111 return struct.pack(">BBHBB",
2112 EAP_CODE_REQUEST, ctx['id'],
2113 4 + 1 + 1,
2114 EAP_TYPE_EKE,
2115 EAP_EKE_CONFIRM)
2116 idx += 1
2117 if ctx['num'] == idx:
2118 logger.info("Test: EAP-Failure")
2119 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
2120
2121 idx += 1
2122 if ctx['num'] == idx:
2123 logger.info("Test: Valid EAP-EKE-ID/Request")
2124 return struct.pack(">BBHBBBB4BB",
2125 EAP_CODE_REQUEST, ctx['id'],
2126 4 + 1 + 1 + 2 + 4 + 1,
2127 EAP_TYPE_EKE,
2128 EAP_EKE_ID,
2129 1, 0,
2130 1, 1, 1, 1,
2131 255)
2132 idx += 1
2133 if ctx['num'] == idx:
2134 logger.info("Test: All zeroes DHComponent_S and empty CBvalue in EAP-EKE-Commit/Request")
2135 return struct.pack(">BBHBB4L32L",
2136 EAP_CODE_REQUEST, ctx['id'],
2137 4 + 1 + 1 + 16 + 128,
2138 EAP_TYPE_EKE,
2139 EAP_EKE_COMMIT,
2140 0, 0, 0, 0,
2141 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2142 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
2143 idx += 1
2144 if ctx['num'] == idx:
2145 logger.info("Test: Invalid PNonce_PS and Auth_S values in EAP-EKE-Confirm/Request")
2146 return struct.pack(">BBHBB4L8L5L5L",
2147 EAP_CODE_REQUEST, ctx['id'],
2148 4 + 1 + 1 + 16 + 2 * 16 + 20 + 20,
2149 EAP_TYPE_EKE,
2150 EAP_EKE_CONFIRM,
2151 0, 0, 0, 0,
2152 0, 0, 0, 0, 0, 0, 0, 0,
2153 0, 0, 0, 0, 0,
2154 0, 0, 0, 0, 0)
2155 idx += 1
2156 if ctx['num'] == idx:
2157 logger.info("Test: EAP-Failure")
2158 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
2159
2160 return None
2161
2162 srv = start_radius_server(eke_handler)
30d62b7a
JM
2163
2164 try:
2165 hapd = start_ap(apdev[0]['ifname'])
2166
2167 for i in range(0, 14):
2168 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
2169 eap="EKE", identity="user", password="password",
2170 wait_connect=False)
2171 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
2172 timeout=15)
2173 if ev is None:
2174 raise Exception("Timeout on EAP start")
2175 if i in [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 ]:
2176 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"],
2177 timeout=10)
2178 if ev is None:
2179 raise Exception("Timeout on EAP failure")
2180 else:
2181 time.sleep(0.05)
2182 dev[0].request("REMOVE_NETWORK all")
2183 dev[0].dump_monitor()
2184 finally:
2185 stop_radius_server(srv)
09544316 2186
850e054c
JM
2187def eap_eke_test_fail(dev, phase1=None, success=False):
2188 dev.connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
2189 eap="EKE", identity="eke user", password="hello",
2190 phase1=phase1, erp="1", wait_connect=False)
2191 ev = dev.wait_event([ "CTRL-EVENT-EAP-FAILURE",
2192 "CTRL-EVENT-EAP-SUCCESS" ], timeout=5)
2193 if ev is None:
2194 raise Exception("Timeout on EAP failure")
2195 if not success and "CTRL-EVENT-EAP-FAILURE" not in ev:
2196 raise Exception("EAP did not fail during failure test")
2197 dev.request("REMOVE_NETWORK all")
2198 dev.wait_disconnected()
2199
2200def test_eap_proto_eke_errors(dev, apdev):
2201 """EAP-EKE local error cases"""
2202 check_eap_capa(dev[0], "EKE")
2203 params = hostapd.wpa2_eap_params(ssid="eap-test")
2204 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
2205
2206 for i in range(1, 3):
2207 with alloc_fail(dev[0], i, "eap_eke_init"):
2208 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
2209 eap="EKE", identity="eke user", password="hello",
2210 wait_connect=False)
2211 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
2212 timeout=15)
2213 if ev is None:
2214 raise Exception("Timeout on EAP start")
2215 dev[0].request("REMOVE_NETWORK all")
2216 dev[0].wait_disconnected()
2217
2218 tests = [ (1, "eap_eke_dh_init", None),
2219 (1, "eap_eke_prf_hmac_sha1", "dhgroup=3 encr=1 prf=1 mac=1"),
2220 (1, "eap_eke_prf_hmac_sha256", "dhgroup=5 encr=1 prf=2 mac=2"),
2221 (1, "eap_eke_prf", None),
2222 (1, "os_get_random;eap_eke_dhcomp", None),
2223 (1, "aes_128_cbc_encrypt;eap_eke_dhcomp", None),
2224 (1, "aes_128_cbc_decrypt;eap_eke_shared_secret", None),
2225 (1, "eap_eke_prf;eap_eke_shared_secret", None),
2226 (1, "eap_eke_prfplus;eap_eke_derive_ke_ki", None),
2227 (1, "eap_eke_prfplus;eap_eke_derive_ka", None),
2228 (1, "eap_eke_prfplus;eap_eke_derive_msk", None),
2229 (1, "os_get_random;eap_eke_prot", None),
2230 (1, "aes_128_cbc_decrypt;eap_eke_decrypt_prot", None),
2231 (1, "eap_eke_derive_key;eap_eke_process_commit", None),
2232 (1, "eap_eke_dh_init;eap_eke_process_commit", None),
2233 (1, "eap_eke_shared_secret;eap_eke_process_commit", None),
2234 (1, "eap_eke_derive_ke_ki;eap_eke_process_commit", None),
2235 (1, "eap_eke_dhcomp;eap_eke_process_commit", None),
2236 (1, "os_get_random;eap_eke_process_commit", None),
2237 (1, "os_get_random;=eap_eke_process_commit", None),
2238 (1, "eap_eke_prot;eap_eke_process_commit", None),
2239 (1, "eap_eke_decrypt_prot;eap_eke_process_confirm", None),
2240 (1, "eap_eke_derive_ka;eap_eke_process_confirm", None),
2241 (1, "eap_eke_auth;eap_eke_process_confirm", None),
2242 (2, "eap_eke_auth;eap_eke_process_confirm", None),
2243 (1, "eap_eke_prot;eap_eke_process_confirm", None),
2244 (1, "eap_eke_derive_msk;eap_eke_process_confirm", None) ]
2245 for count, func, phase1 in tests:
2246 with fail_test(dev[0], count, func):
2247 eap_eke_test_fail(dev[0], phase1)
2248
2249 tests = [ (1, "=eap_eke_derive_ke_ki", None),
2250 (1, "=eap_eke_derive_ka", None),
2251 (1, "=eap_eke_derive_msk", None),
2252 (1, "eap_eke_build_msg;eap_eke_process_id", None),
2253 (1, "wpabuf_alloc;eap_eke_process_id", None),
2254 (1, "=eap_eke_process_id", None),
491e2d26 2255 (1, "wpabuf_alloc;=eap_eke_process_id", None),
850e054c
JM
2256 (1, "wpabuf_alloc;eap_eke_process_id", None),
2257 (1, "eap_eke_build_msg;eap_eke_process_commit", None),
2258 (1, "wpabuf_resize;eap_eke_process_commit", None),
2259 (1, "eap_eke_build_msg;eap_eke_process_confirm", None) ]
2260 for count, func, phase1 in tests:
2261 with alloc_fail(dev[0], count, func):
2262 eap_eke_test_fail(dev[0], phase1)
2263
2264 tests = [ (1, "eap_eke_getKey", None),
2265 (1, "eap_eke_get_emsk", None),
2266 (1, "eap_eke_get_session_id", None) ]
2267 for count, func, phase1 in tests:
2268 with alloc_fail(dev[0], count, func):
2269 eap_eke_test_fail(dev[0], phase1, success=True)
2270
09544316
JM
2271EAP_PAX_OP_STD_1 = 0x01
2272EAP_PAX_OP_STD_2 = 0x02
2273EAP_PAX_OP_STD_3 = 0x03
2274EAP_PAX_OP_SEC_1 = 0x11
2275EAP_PAX_OP_SEC_2 = 0x12
2276EAP_PAX_OP_SEC_3 = 0x13
2277EAP_PAX_OP_SEC_4 = 0x14
2278EAP_PAX_OP_SEC_5 = 0x15
2279EAP_PAX_OP_ACK = 0x21
2280
2281EAP_PAX_FLAGS_MF = 0x01
2282EAP_PAX_FLAGS_CE = 0x02
2283EAP_PAX_FLAGS_AI = 0x04
2284
2285EAP_PAX_MAC_HMAC_SHA1_128 = 0x01
2286EAP_PAX_HMAC_SHA256_128 = 0x02
2287
2288EAP_PAX_DH_GROUP_NONE = 0x00
2289EAP_PAX_DH_GROUP_2048_MODP = 0x01
2290EAP_PAX_DH_GROUP_3072_MODP = 0x02
2291EAP_PAX_DH_GROUP_NIST_ECC_P_256 = 0x03
2292
2293EAP_PAX_PUBLIC_KEY_NONE = 0x00
2294EAP_PAX_PUBLIC_KEY_RSAES_OAEP = 0x01
2295EAP_PAX_PUBLIC_KEY_RSA_PKCS1_V1_5 = 0x02
2296EAP_PAX_PUBLIC_KEY_EL_GAMAL_NIST_ECC = 0x03
2297
2298EAP_PAX_ADE_VENDOR_SPECIFIC = 0x01
2299EAP_PAX_ADE_CLIENT_CHANNEL_BINDING = 0x02
2300EAP_PAX_ADE_SERVER_CHANNEL_BINDING = 0x03
2301
2302def test_eap_proto_pax(dev, apdev):
2303 """EAP-PAX protocol tests"""
2304 def pax_std_1(ctx):
2305 logger.info("Test: STD-1")
2306 ctx['id'] = 10
2307 return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'],
2308 4 + 1 + 5 + 2 + 32 + 16,
2309 EAP_TYPE_PAX,
2310 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128,
2311 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE,
2312 32, 0, 0, 0, 0, 0, 0, 0, 0,
2313 0x16, 0xc9, 0x08, 0x9d, 0x98, 0xa5, 0x6e, 0x1f,
2314 0xf0, 0xac, 0xcf, 0xc4, 0x66, 0xcd, 0x2d, 0xbf)
2315
2316 def pax_handler(ctx, req):
2317 logger.info("pax_handler - RX " + req.encode("hex"))
2318 if 'num' not in ctx:
2319 ctx['num'] = 0
2320 ctx['num'] = ctx['num'] + 1
2321 if 'id' not in ctx:
2322 ctx['id'] = 1
2323 ctx['id'] = (ctx['id'] + 1) % 256
2324
2325 idx = 0
2326
2327 idx += 1
2328 if ctx['num'] == idx:
2329 logger.info("Test: Missing payload")
2330 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
2331 4 + 1,
2332 EAP_TYPE_PAX)
2333
2334 idx += 1
2335 if ctx['num'] == idx:
2336 logger.info("Test: Minimum length payload")
2337 return struct.pack(">BBHB4L", EAP_CODE_REQUEST, ctx['id'],
2338 4 + 1 + 16,
2339 EAP_TYPE_PAX,
2340 0, 0, 0, 0)
2341
2342 idx += 1
2343 if ctx['num'] == idx:
2344 logger.info("Test: Unsupported MAC ID")
2345 return struct.pack(">BBHBBBBBB4L", EAP_CODE_REQUEST, ctx['id'],
2346 4 + 1 + 5 + 16,
2347 EAP_TYPE_PAX,
2348 EAP_PAX_OP_STD_1, 0, 255, EAP_PAX_DH_GROUP_NONE,
2349 EAP_PAX_PUBLIC_KEY_NONE,
2350 0, 0, 0, 0)
2351
2352 idx += 1
2353 if ctx['num'] == idx:
2354 logger.info("Test: Unsupported DH Group ID")
2355 return struct.pack(">BBHBBBBBB4L", EAP_CODE_REQUEST, ctx['id'],
2356 4 + 1 + 5 + 16,
2357 EAP_TYPE_PAX,
2358 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128,
2359 255, EAP_PAX_PUBLIC_KEY_NONE,
2360 0, 0, 0, 0)
2361
2362 idx += 1
2363 if ctx['num'] == idx:
2364 logger.info("Test: Unsupported Public Key ID")
2365 return struct.pack(">BBHBBBBBB4L", EAP_CODE_REQUEST, ctx['id'],
2366 4 + 1 + 5 + 16,
2367 EAP_TYPE_PAX,
2368 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128,
2369 EAP_PAX_DH_GROUP_NONE, 255,
2370 0, 0, 0, 0)
2371
2372 idx += 1
2373 if ctx['num'] == idx:
2374 logger.info("Test: More fragments")
2375 return struct.pack(">BBHBBBBBB4L", EAP_CODE_REQUEST, ctx['id'],
2376 4 + 1 + 5 + 16,
2377 EAP_TYPE_PAX,
2378 EAP_PAX_OP_STD_1, EAP_PAX_FLAGS_MF,
2379 EAP_PAX_MAC_HMAC_SHA1_128,
2380 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE,
2381 0, 0, 0, 0)
2382
2383 idx += 1
2384 if ctx['num'] == idx:
2385 logger.info("Test: Invalid ICV")
2386 return struct.pack(">BBHBBBBBB4L", EAP_CODE_REQUEST, ctx['id'],
2387 4 + 1 + 5 + 16,
2388 EAP_TYPE_PAX,
2389 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128,
2390 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE,
2391 0, 0, 0, 0)
2392
2393 idx += 1
2394 if ctx['num'] == idx:
2395 logger.info("Test: Invalid ICV in short frame")
2396 return struct.pack(">BBHBBBBBB3L", EAP_CODE_REQUEST, ctx['id'],
2397 4 + 1 + 5 + 12,
2398 EAP_TYPE_PAX,
2399 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128,
2400 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE,
2401 0, 0, 0)
2402
2403 idx += 1
2404 if ctx['num'] == idx:
2405 logger.info("Test: Correct ICV - unsupported op_code")
2406 ctx['id'] = 10
2407 return struct.pack(">BBHBBBBBB16B", EAP_CODE_REQUEST, ctx['id'],
2408 4 + 1 + 5 + 16,
2409 EAP_TYPE_PAX,
2410 255, 0, EAP_PAX_MAC_HMAC_SHA1_128,
2411 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE,
2412 0x90, 0x78, 0x97, 0x38, 0x29, 0x94, 0x32, 0xd4,
2413 0x81, 0x27, 0xe0, 0xf6, 0x3b, 0x0d, 0xb2, 0xb2)
2414
2415 idx += 1
2416 if ctx['num'] == idx:
2417 logger.info("Test: Correct ICV - CE flag in STD-1")
2418 ctx['id'] = 10
2419 return struct.pack(">BBHBBBBBB16B", EAP_CODE_REQUEST, ctx['id'],
2420 4 + 1 + 5 + 16,
2421 EAP_TYPE_PAX,
2422 EAP_PAX_OP_STD_1, EAP_PAX_FLAGS_CE,
2423 EAP_PAX_MAC_HMAC_SHA1_128,
2424 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE,
2425 0x9c, 0x98, 0xb4, 0x0b, 0x94, 0x90, 0xde, 0x88,
2426 0xb7, 0x72, 0x63, 0x44, 0x1d, 0xe3, 0x7c, 0x5c)
2427
2428 idx += 1
2429 if ctx['num'] == idx:
2430 logger.info("Test: Correct ICV - too short STD-1 payload")
2431 ctx['id'] = 10
2432 return struct.pack(">BBHBBBBBB16B", EAP_CODE_REQUEST, ctx['id'],
2433 4 + 1 + 5 + 16,
2434 EAP_TYPE_PAX,
2435 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128,
2436 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE,
2437 0xda, 0xab, 0x2c, 0xe7, 0x84, 0x41, 0xb5, 0x5c,
2438 0xee, 0xcf, 0x62, 0x03, 0xc5, 0x69, 0xcb, 0xf4)
2439
2440 idx += 1
2441 if ctx['num'] == idx:
2442 logger.info("Test: Correct ICV - incorrect A length in STD-1")
2443 ctx['id'] = 10
2444 return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'],
2445 4 + 1 + 5 + 2 + 32 + 16,
2446 EAP_TYPE_PAX,
2447 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128,
2448 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE,
2449 0, 0, 0, 0, 0, 0, 0, 0, 0,
2450 0xc4, 0xb0, 0x81, 0xe4, 0x6c, 0x8c, 0x20, 0x23,
2451 0x60, 0x46, 0x89, 0xea, 0x94, 0x60, 0xf3, 0x2a)
2452
2453 idx += 1
2454 if ctx['num'] == idx:
2455 logger.info("Test: Correct ICV - extra data in STD-1")
2456 ctx['id'] = 10
2457 return struct.pack(">BBHBBBBBBH8LB16B", EAP_CODE_REQUEST, ctx['id'],
2458 4 + 1 + 5 + 2 + 32 + 1 + 16,
2459 EAP_TYPE_PAX,
2460 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128,
2461 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE,
2462 32, 0, 0, 0, 0, 0, 0, 0, 0,
2463 1,
2464 0x61, 0x49, 0x65, 0x37, 0x21, 0xe8, 0xd8, 0xbf,
2465 0xf3, 0x02, 0x01, 0xe5, 0x42, 0x51, 0xd3, 0x34)
2466 idx += 1
2467 if ctx['num'] == idx:
2468 logger.info("Test: Unexpected STD-1")
2469 return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'],
2470 4 + 1 + 5 + 2 + 32 + 16,
2471 EAP_TYPE_PAX,
2472 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128,
2473 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE,
2474 32, 0, 0, 0, 0, 0, 0, 0, 0,
2475 0xe5, 0x1d, 0xbf, 0xb8, 0x70, 0x20, 0x5c, 0xba,
2476 0x41, 0xbb, 0x34, 0xda, 0x1a, 0x08, 0xe6, 0x8d)
2477
2478 idx += 1
2479 if ctx['num'] == idx:
2480 return pax_std_1(ctx)
2481 idx += 1
2482 if ctx['num'] == idx:
2483 logger.info("Test: MAC ID changed during session")
2484 return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'],
2485 4 + 1 + 5 + 2 + 32 + 16,
2486 EAP_TYPE_PAX,
2487 EAP_PAX_OP_STD_1, 0, EAP_PAX_HMAC_SHA256_128,
2488 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE,
2489 32, 0, 0, 0, 0, 0, 0, 0, 0,
2490 0xee, 0x00, 0xbf, 0xb8, 0x70, 0x20, 0x5c, 0xba,
2491 0x41, 0xbb, 0x34, 0xda, 0x1a, 0x08, 0xe6, 0x8d)
2492
2493 idx += 1
2494 if ctx['num'] == idx:
2495 return pax_std_1(ctx)
2496 idx += 1
2497 if ctx['num'] == idx:
2498 logger.info("Test: DH Group ID changed during session")
2499 return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'],
2500 4 + 1 + 5 + 2 + 32 + 16,
2501 EAP_TYPE_PAX,
2502 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128,
2503 EAP_PAX_DH_GROUP_2048_MODP,
2504 EAP_PAX_PUBLIC_KEY_NONE,
2505 32, 0, 0, 0, 0, 0, 0, 0, 0,
2506 0xee, 0x01, 0xbf, 0xb8, 0x70, 0x20, 0x5c, 0xba,
2507 0x41, 0xbb, 0x34, 0xda, 0x1a, 0x08, 0xe6, 0x8d)
2508
2509 idx += 1
2510 if ctx['num'] == idx:
2511 return pax_std_1(ctx)
2512 idx += 1
2513 if ctx['num'] == idx:
2514 logger.info("Test: Public Key ID changed during session")
2515 return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'],
2516 4 + 1 + 5 + 2 + 32 + 16,
2517 EAP_TYPE_PAX,
2518 EAP_PAX_OP_STD_1, 0, EAP_PAX_MAC_HMAC_SHA1_128,
2519 EAP_PAX_DH_GROUP_NONE,
2520 EAP_PAX_PUBLIC_KEY_RSAES_OAEP,
2521 32, 0, 0, 0, 0, 0, 0, 0, 0,
2522 0xee, 0x02, 0xbf, 0xb8, 0x70, 0x20, 0x5c, 0xba,
2523 0x41, 0xbb, 0x34, 0xda, 0x1a, 0x08, 0xe6, 0x8d)
2524
2525 idx += 1
2526 if ctx['num'] == idx:
2527 logger.info("Test: Unexpected STD-3")
2528 ctx['id'] = 10
2529 return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'],
2530 4 + 1 + 5 + 2 + 32 + 16,
2531 EAP_TYPE_PAX,
2532 EAP_PAX_OP_STD_3, 0, EAP_PAX_MAC_HMAC_SHA1_128,
2533 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE,
2534 32, 0, 0, 0, 0, 0, 0, 0, 0,
2535 0x47, 0xbb, 0xc0, 0xf9, 0xb9, 0x69, 0xf5, 0xcb,
2536 0x3a, 0xe8, 0xe7, 0xd6, 0x80, 0x28, 0xf2, 0x59)
2537
2538 idx += 1
2539 if ctx['num'] == idx:
2540 return pax_std_1(ctx)
2541 idx += 1
2542 if ctx['num'] == idx:
2543 # TODO: MAC calculation; for now, this gets dropped due to incorrect
2544 # ICV
2545 logger.info("Test: STD-3 with CE flag")
2546 return struct.pack(">BBHBBBBBBH8L16B", EAP_CODE_REQUEST, ctx['id'],
2547 4 + 1 + 5 + 2 + 32 + 16,
2548 EAP_TYPE_PAX,
2549 EAP_PAX_OP_STD_3, EAP_PAX_FLAGS_CE,
2550 EAP_PAX_MAC_HMAC_SHA1_128,
2551 EAP_PAX_DH_GROUP_NONE, EAP_PAX_PUBLIC_KEY_NONE,
2552 32, 0, 0, 0, 0, 0, 0, 0, 0,
2553 0x8a, 0xc2, 0xf9, 0xf4, 0x8b, 0x75, 0x72, 0xa2,
2554 0x4d, 0xd3, 0x1e, 0x54, 0x77, 0x04, 0x05, 0xe2)
2555
2556 idx += 1
2557 if ctx['num'] & 0x1 == idx & 0x1:
2558 logger.info("Test: Default request")
2559 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
2560 4 + 1,
2561 EAP_TYPE_PAX)
2562 else:
2563 logger.info("Test: Default EAP-Failure")
2564 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
2565
2566 srv = start_radius_server(pax_handler)
09544316
JM
2567
2568 try:
2569 hapd = start_ap(apdev[0]['ifname'])
2570
2571 for i in range(0, 18):
2572 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
2573 eap="PAX", identity="user",
2574 password_hex="0123456789abcdef0123456789abcdef",
2575 wait_connect=False)
2576 logger.info("Waiting for EAP method to start")
2577 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
2578 timeout=15)
2579 if ev is None:
2580 raise Exception("Timeout on EAP start")
2581 time.sleep(0.05)
2582 dev[0].request("REMOVE_NETWORK all")
2583 dev[0].dump_monitor()
2584
2585 logger.info("Too short password")
2586 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
2587 eap="PAX", identity="user",
2588 password_hex="0123456789abcdef0123456789abcd",
2589 wait_connect=False)
2590 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15)
2591 if ev is None:
2592 raise Exception("Timeout on EAP start")
2593 time.sleep(0.1)
2594 dev[0].request("REMOVE_NETWORK all")
2595 dev[0].dump_monitor()
2596
2597 logger.info("No password")
2598 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
2599 eap="PAX", identity="user",
2600 wait_connect=False)
2601 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15)
2602 if ev is None:
2603 raise Exception("Timeout on EAP start")
2604 time.sleep(0.1)
2605 dev[0].request("REMOVE_NETWORK all")
2606 dev[0].dump_monitor()
2607 finally:
2608 stop_radius_server(srv)
e0534ecf
JM
2609
2610def test_eap_proto_psk(dev, apdev):
2611 """EAP-PSK protocol tests"""
2612 def psk_handler(ctx, req):
2613 logger.info("psk_handler - RX " + req.encode("hex"))
2614 if 'num' not in ctx:
2615 ctx['num'] = 0
2616 ctx['num'] = ctx['num'] + 1
2617 if 'id' not in ctx:
2618 ctx['id'] = 1
2619 ctx['id'] = (ctx['id'] + 1) % 256
2620
2621 idx = 0
2622
2623 idx += 1
2624 if ctx['num'] == idx:
2625 logger.info("Test: Missing payload")
2626 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
2627 4 + 1,
2628 EAP_TYPE_PSK)
2629
2630 idx += 1
2631 if ctx['num'] == idx:
2632 logger.info("Test: Non-zero T in first message")
2633 return struct.pack(">BBHBB4L", EAP_CODE_REQUEST, ctx['id'],
2634 4 + 1 + 1 + 16,
2635 EAP_TYPE_PSK, 0xc0, 0, 0, 0, 0)
2636
2637 idx += 1
2638 if ctx['num'] == idx:
2639 logger.info("Test: Valid first message")
2640 return struct.pack(">BBHBB4L", EAP_CODE_REQUEST, ctx['id'],
2641 4 + 1 + 1 + 16,
2642 EAP_TYPE_PSK, 0, 0, 0, 0, 0)
2643 idx += 1
2644 if ctx['num'] == idx:
2645 logger.info("Test: Too short third message")
2646 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
2647 4 + 1,
2648 EAP_TYPE_PSK)
2649
2650 idx += 1
2651 if ctx['num'] == idx:
2652 logger.info("Test: Valid first message")
2653 return struct.pack(">BBHBB4L", EAP_CODE_REQUEST, ctx['id'],
2654 4 + 1 + 1 + 16,
2655 EAP_TYPE_PSK, 0, 0, 0, 0, 0)
2656 idx += 1
2657 if ctx['num'] == idx:
2658 logger.info("Test: Incorrect T in third message")
2659 return struct.pack(">BBHBB4L4L", EAP_CODE_REQUEST, ctx['id'],
2660 4 + 1 + 1 + 16 + 16,
2661 EAP_TYPE_PSK, 0, 0, 0, 0, 0, 0, 0, 0, 0)
2662
2663 idx += 1
2664 if ctx['num'] == idx:
2665 logger.info("Test: Valid first message")
2666 return struct.pack(">BBHBB4L", EAP_CODE_REQUEST, ctx['id'],
2667 4 + 1 + 1 + 16,
2668 EAP_TYPE_PSK, 0, 0, 0, 0, 0)
2669 idx += 1
2670 if ctx['num'] == idx:
2671 logger.info("Test: Missing PCHANNEL in third message")
2672 return struct.pack(">BBHBB4L4L", EAP_CODE_REQUEST, ctx['id'],
2673 4 + 1 + 1 + 16 + 16,
2674 EAP_TYPE_PSK, 0x80, 0, 0, 0, 0, 0, 0, 0, 0)
2675
2676 idx += 1
2677 if ctx['num'] == idx:
2678 logger.info("Test: Valid first message")
2679 return struct.pack(">BBHBB4L", EAP_CODE_REQUEST, ctx['id'],
2680 4 + 1 + 1 + 16,
2681 EAP_TYPE_PSK, 0, 0, 0, 0, 0)
2682 idx += 1
2683 if ctx['num'] == idx:
2684 logger.info("Test: Invalic MAC_S in third message")
2685 return struct.pack(">BBHBB4L4L5LB", EAP_CODE_REQUEST, ctx['id'],
2686 4 + 1 + 1 + 16 + 16 + 21,
2687 EAP_TYPE_PSK, 0x80, 0, 0, 0, 0, 0, 0, 0, 0,
2688 0, 0, 0, 0, 0, 0)
2689
2690 idx += 1
2691 if ctx['num'] == idx:
2692 logger.info("Test: Valid first message")
2693 return struct.pack(">BBHBB4L", EAP_CODE_REQUEST, ctx['id'],
2694 4 + 1 + 1 + 16,
2695 EAP_TYPE_PSK, 0, 0, 0, 0, 0)
2696 idx += 1
2697 if ctx['num'] == idx:
2698 logger.info("Test: EAP-Failure")
2699 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
2700
2701 return None
2702
2703 srv = start_radius_server(psk_handler)
e0534ecf
JM
2704
2705 try:
2706 hapd = start_ap(apdev[0]['ifname'])
2707
2708 for i in range(0, 6):
2709 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
2710 eap="PSK", identity="user",
2711 password_hex="0123456789abcdef0123456789abcdef",
2712 wait_connect=False)
2713 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
2714 timeout=15)
2715 if ev is None:
2716 raise Exception("Timeout on EAP start")
2717 time.sleep(0.1)
2718 dev[0].request("REMOVE_NETWORK all")
2719
2720 logger.info("Test: Invalid PSK length")
2721 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
2722 eap="PSK", identity="user",
2723 password_hex="0123456789abcdef0123456789abcd",
2724 wait_connect=False)
2725 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
2726 timeout=15)
2727 if ev is None:
2728 raise Exception("Timeout on EAP start")
2729 time.sleep(0.1)
2730 dev[0].request("REMOVE_NETWORK all")
2731 finally:
2732 stop_radius_server(srv)
6c080dfa 2733
b4e1e995
JM
2734def test_eap_proto_psk_errors(dev, apdev):
2735 """EAP-PSK local error cases"""
2736 check_eap_capa(dev[0], "PSK")
2737 params = hostapd.wpa2_eap_params(ssid="eap-test")
2738 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
2739
2740 for i in range(1, 6):
2741 with alloc_fail(dev[0], i, "eap_psk_init"):
2742 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
2743 eap="PSK", identity="psk.user@example.com",
2744 password_hex="0123456789abcdef0123456789abcdef",
2745 wait_connect=False)
2746 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
2747 timeout=15)
2748 if ev is None:
2749 raise Exception("Timeout on EAP start")
2750 dev[0].request("REMOVE_NETWORK all")
2751 dev[0].wait_disconnected()
2752
2753 tests = [ (1, "=eap_psk_process_1"),
2754 (2, "=eap_psk_process_1"),
2755 (1, "eap_msg_alloc;eap_psk_process_1"),
2756 (1, "=eap_psk_process_3"),
2757 (2, "=eap_psk_process_3"),
2758 (1, "eap_msg_alloc;eap_psk_process_3"),
2759 (1, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"),
2760 (2, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"),
2761 (3, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"),
2762 (4, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"),
2763 (5, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"),
2764 (6, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"),
2765 (7, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"),
2766 (8, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"),
2767 (9, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"),
2768 (10, "aes_128_encrypt_block;eap_psk_derive_keys;eap_psk_process_3"),
2769 (1, "aes_128_ctr_encrypt;aes_128_eax_decrypt;eap_psk_process_3"),
2770 (1, "aes_128_ctr_encrypt;aes_128_eax_encrypt;eap_psk_process_3"),
2771 (1, "eap_psk_getKey"),
2772 (1, "eap_psk_get_session_id"),
2773 (1, "eap_psk_get_emsk") ]
2774 for count, func in tests:
2775 with alloc_fail(dev[0], count, func):
2776 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
2777 eap="PSK", identity="psk.user@example.com",
2778 password_hex="0123456789abcdef0123456789abcdef",
2779 erp="1", wait_connect=False)
2780 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
2781 timeout=15)
2782 if ev is None:
2783 raise Exception("Timeout on EAP start")
2784 ok = False
2785 for j in range(10):
2786 state = dev[0].request('GET_ALLOC_FAIL')
2787 if state.startswith('0:'):
2788 ok = True
2789 break
2790 time.sleep(0.1)
2791 if not ok:
2792 raise Exception("No allocation failure seen for %d:%s" % (count, func))
2793 dev[0].request("REMOVE_NETWORK all")
2794 dev[0].wait_disconnected()
2795
2796 tests = [ (1, "os_get_random;eap_psk_process_1"),
2797 (1, "omac1_aes_128;eap_psk_process_3"),
2798 (1, "aes_128_eax_decrypt;eap_psk_process_3"),
2799 (2, "aes_128_eax_decrypt;eap_psk_process_3"),
2800 (3, "aes_128_eax_decrypt;eap_psk_process_3"),
2801 (1, "aes_128_eax_encrypt;eap_psk_process_3"),
2802 (2, "aes_128_eax_encrypt;eap_psk_process_3"),
2803 (3, "aes_128_eax_encrypt;eap_psk_process_3") ]
2804 for count, func in tests:
2805 with fail_test(dev[0], count, func):
2806 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
2807 eap="PSK", identity="psk.user@example.com",
2808 password_hex="0123456789abcdef0123456789abcdef",
2809 wait_connect=False)
2810 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
2811 timeout=15)
2812 if ev is None:
2813 raise Exception("Timeout on EAP start")
2814 ok = False
2815 for j in range(10):
2816 state = dev[0].request('GET_FAIL')
2817 if state.startswith('0:'):
2818 ok = True
2819 break
2820 time.sleep(0.1)
2821 if not ok:
2822 raise Exception("No failure seen for %d:%s" % (count, func))
2823 dev[0].request("REMOVE_NETWORK all")
2824 dev[0].wait_disconnected()
2825
6c080dfa
JM
2826EAP_SIM_SUBTYPE_START = 10
2827EAP_SIM_SUBTYPE_CHALLENGE = 11
2828EAP_SIM_SUBTYPE_NOTIFICATION = 12
2829EAP_SIM_SUBTYPE_REAUTHENTICATION = 13
2830EAP_SIM_SUBTYPE_CLIENT_ERROR = 14
2831
2832EAP_AKA_SUBTYPE_CHALLENGE = 1
2833EAP_AKA_SUBTYPE_AUTHENTICATION_REJECT = 2
2834EAP_AKA_SUBTYPE_SYNCHRONIZATION_FAILURE = 4
2835EAP_AKA_SUBTYPE_IDENTITY = 5
2836EAP_AKA_SUBTYPE_NOTIFICATION = 12
2837EAP_AKA_SUBTYPE_REAUTHENTICATION = 13
2838EAP_AKA_SUBTYPE_CLIENT_ERROR = 14
2839
2840EAP_SIM_AT_RAND = 1
2841EAP_SIM_AT_AUTN = 2
2842EAP_SIM_AT_RES = 3
2843EAP_SIM_AT_AUTS = 4
2844EAP_SIM_AT_PADDING = 6
2845EAP_SIM_AT_NONCE_MT = 7
2846EAP_SIM_AT_PERMANENT_ID_REQ = 10
2847EAP_SIM_AT_MAC = 11
2848EAP_SIM_AT_NOTIFICATION = 12
2849EAP_SIM_AT_ANY_ID_REQ = 13
2850EAP_SIM_AT_IDENTITY = 14
2851EAP_SIM_AT_VERSION_LIST = 15
2852EAP_SIM_AT_SELECTED_VERSION = 16
2853EAP_SIM_AT_FULLAUTH_ID_REQ = 17
2854EAP_SIM_AT_COUNTER = 19
2855EAP_SIM_AT_COUNTER_TOO_SMALL = 20
2856EAP_SIM_AT_NONCE_S = 21
2857EAP_SIM_AT_CLIENT_ERROR_CODE = 22
2858EAP_SIM_AT_KDF_INPUT = 23
2859EAP_SIM_AT_KDF = 24
2860EAP_SIM_AT_IV = 129
2861EAP_SIM_AT_ENCR_DATA = 130
2862EAP_SIM_AT_NEXT_PSEUDONYM = 132
2863EAP_SIM_AT_NEXT_REAUTH_ID = 133
2864EAP_SIM_AT_CHECKCODE = 134
2865EAP_SIM_AT_RESULT_IND = 135
2866EAP_SIM_AT_BIDDING = 136
2867
2868def test_eap_proto_aka(dev, apdev):
2869 """EAP-AKA protocol tests"""
2870 def aka_handler(ctx, req):
2871 logger.info("aka_handler - RX " + req.encode("hex"))
2872 if 'num' not in ctx:
2873 ctx['num'] = 0
2874 ctx['num'] = ctx['num'] + 1
2875 if 'id' not in ctx:
2876 ctx['id'] = 1
2877 ctx['id'] = (ctx['id'] + 1) % 256
2878
2879 idx = 0
2880
2881 idx += 1
2882 if ctx['num'] == idx:
2883 logger.info("Test: Missing payload")
2884 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
2885 4 + 1,
2886 EAP_TYPE_AKA)
2887
2888 idx += 1
2889 if ctx['num'] == idx:
2890 logger.info("Test: Unknown subtype")
f0174bff
JM
2891 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
2892 4 + 1 + 3,
2893 EAP_TYPE_AKA, 255, 0)
6c080dfa
JM
2894 idx += 1
2895 if ctx['num'] == idx:
2896 logger.info("Test: EAP-Failure")
2897 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
2898
2899 idx += 1
2900 if ctx['num'] == idx:
2901 logger.info("Test: Client Error")
f0174bff
JM
2902 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
2903 4 + 1 + 3,
2904 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CLIENT_ERROR, 0)
6c080dfa
JM
2905 idx += 1
2906 if ctx['num'] == idx:
2907 logger.info("Test: EAP-Failure")
2908 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
2909
2910 idx += 1
2911 if ctx['num'] == idx:
2912 logger.info("Test: Too short attribute header")
2913 return struct.pack(">BBHBBHB", EAP_CODE_REQUEST, ctx['id'],
2914 4 + 1 + 1 + 3,
2915 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 255)
2916 idx += 1
2917 if ctx['num'] == idx:
2918 logger.info("Test: EAP-Failure")
2919 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
2920
2921 idx += 1
2922 if ctx['num'] == idx:
2923 logger.info("Test: Truncated attribute")
2924 return struct.pack(">BBHBBHBB", EAP_CODE_REQUEST, ctx['id'],
2925 4 + 1 + 1 + 4,
2926 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 255,
2927 255)
2928 idx += 1
2929 if ctx['num'] == idx:
2930 logger.info("Test: EAP-Failure")
2931 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
2932
2933 idx += 1
2934 if ctx['num'] == idx:
2935 logger.info("Test: Too short attribute data")
2936 return struct.pack(">BBHBBHBB", EAP_CODE_REQUEST, ctx['id'],
2937 4 + 1 + 1 + 4,
2938 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0, 255,
2939 0)
2940 idx += 1
2941 if ctx['num'] == idx:
2942 logger.info("Test: EAP-Failure")
2943 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
2944
2945 idx += 1
2946 if ctx['num'] == idx:
2947 logger.info("Test: Skippable/non-skippable unrecognzized attribute")
2948 return struct.pack(">BBHBBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
2949 4 + 1 + 1 + 10,
2950 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
2951 255, 1, 0, 127, 1, 0)
2952 idx += 1
2953 if ctx['num'] == idx:
2954 logger.info("Test: EAP-Failure")
2955 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
2956
2957 idx += 1
2958 if ctx['num'] == idx:
2959 logger.info("Test: Identity request without ID type")
2960 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
2961 4 + 1 + 3,
2962 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0)
2963 idx += 1
2964 if ctx['num'] == idx:
2965 logger.info("Test: Identity request ANY_ID")
2966 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
2967 4 + 1 + 3 + 4,
2968 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
2969 EAP_SIM_AT_ANY_ID_REQ, 1, 0)
2970 idx += 1
2971 if ctx['num'] == idx:
2972 logger.info("Test: Identity request ANY_ID (duplicate)")
2973 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
2974 4 + 1 + 3 + 4,
2975 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
2976 EAP_SIM_AT_ANY_ID_REQ, 1, 0)
2977 idx += 1
2978 if ctx['num'] == idx:
2979 logger.info("Test: EAP-Failure")
2980 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
2981
2982 idx += 1
2983 if ctx['num'] == idx:
2984 logger.info("Test: Identity request ANY_ID")
2985 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
2986 4 + 1 + 3 + 4,
2987 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
2988 EAP_SIM_AT_ANY_ID_REQ, 1, 0)
2989 idx += 1
2990 if ctx['num'] == idx:
2991 logger.info("Test: Identity request FULLAUTH_ID")
2992 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
2993 4 + 1 + 3 + 4,
2994 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
2995 EAP_SIM_AT_FULLAUTH_ID_REQ, 1, 0)
2996 idx += 1
2997 if ctx['num'] == idx:
2998 logger.info("Test: Identity request FULLAUTH_ID (duplicate)")
2999 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3000 4 + 1 + 3 + 4,
3001 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3002 EAP_SIM_AT_FULLAUTH_ID_REQ, 1, 0)
3003 idx += 1
3004 if ctx['num'] == idx:
3005 logger.info("Test: EAP-Failure")
3006 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3007
3008 idx += 1
3009 if ctx['num'] == idx:
3010 logger.info("Test: Identity request ANY_ID")
3011 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3012 4 + 1 + 3 + 4,
3013 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3014 EAP_SIM_AT_ANY_ID_REQ, 1, 0)
3015 idx += 1
3016 if ctx['num'] == idx:
3017 logger.info("Test: Identity request FULLAUTH_ID")
3018 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3019 4 + 1 + 3 + 4,
3020 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3021 EAP_SIM_AT_FULLAUTH_ID_REQ, 1, 0)
3022 idx += 1
3023 if ctx['num'] == idx:
3024 logger.info("Test: Identity request PERMANENT_ID")
3025 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3026 4 + 1 + 3 + 4,
3027 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3028 EAP_SIM_AT_PERMANENT_ID_REQ, 1, 0)
3029 idx += 1
3030 if ctx['num'] == idx:
3031 logger.info("Test: Identity request PERMANENT_ID (duplicate)")
3032 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3033 4 + 1 + 3 + 4,
3034 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3035 EAP_SIM_AT_PERMANENT_ID_REQ, 1, 0)
3036 idx += 1
3037 if ctx['num'] == idx:
3038 logger.info("Test: EAP-Failure")
3039 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3040
3041 idx += 1
3042 if ctx['num'] == idx:
3043 logger.info("Test: Challenge with no attributes")
3044 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
3045 4 + 1 + 3,
3046 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CHALLENGE, 0)
3047 idx += 1
3048 if ctx['num'] == idx:
3049 logger.info("Test: EAP-Failure")
3050 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3051
3052 idx += 1
3053 if ctx['num'] == idx:
3054 logger.info("Test: AKA Challenge with BIDDING")
3055 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3056 4 + 1 + 3 + 4,
3057 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3058 EAP_SIM_AT_BIDDING, 1, 0x8000)
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: Notification with no attributes")
3067 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
3068 4 + 1 + 3,
3069 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0)
3070 idx += 1
3071 if ctx['num'] == idx:
3072 logger.info("Test: EAP-Failure")
3073 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3074
3075 idx += 1
3076 if ctx['num'] == idx:
3077 logger.info("Test: Notification indicating success, but no MAC")
3078 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3079 4 + 1 + 3 + 4,
3080 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0,
3081 EAP_SIM_AT_NOTIFICATION, 1, 32768)
3082 idx += 1
3083 if ctx['num'] == idx:
3084 logger.info("Test: EAP-Failure")
3085 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3086
3087 idx += 1
3088 if ctx['num'] == idx:
3089 logger.info("Test: Notification indicating success, but invalid MAC value")
3090 return struct.pack(">BBHBBHBBHBBH4L", EAP_CODE_REQUEST, ctx['id'],
3091 4 + 1 + 3 + 4 + 20,
3092 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0,
3093 EAP_SIM_AT_NOTIFICATION, 1, 32768,
3094 EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0)
3095 idx += 1
3096 if ctx['num'] == idx:
3097 logger.info("Test: EAP-Failure")
3098 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3099
3100 idx += 1
3101 if ctx['num'] == idx:
3102 logger.info("Test: Notification indicating success with zero-key MAC")
3103 return struct.pack(">BBHBBHBBHBBH16B", EAP_CODE_REQUEST,
3104 ctx['id'] - 2,
3105 4 + 1 + 3 + 4 + 20,
3106 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0,
3107 EAP_SIM_AT_NOTIFICATION, 1, 32768,
3108 EAP_SIM_AT_MAC, 5, 0,
3109 0xbe, 0x2e, 0xbb, 0xa9, 0xfa, 0x2e, 0x82, 0x36,
3110 0x37, 0x8c, 0x32, 0x41, 0xb7, 0xc7, 0x58, 0xa3)
3111 idx += 1
3112 if ctx['num'] == idx:
3113 logger.info("Test: EAP-Success")
3114 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4)
3115
3116 idx += 1
3117 if ctx['num'] == idx:
3118 logger.info("Test: Notification before auth")
3119 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3120 4 + 1 + 3 + 4,
3121 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0,
3122 EAP_SIM_AT_NOTIFICATION, 1, 16384)
3123 idx += 1
3124 if ctx['num'] == idx:
3125 logger.info("Test: EAP-Failure")
3126 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3127
3128 idx += 1
3129 if ctx['num'] == idx:
3130 logger.info("Test: Notification before auth")
3131 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3132 4 + 1 + 3 + 4,
3133 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0,
3134 EAP_SIM_AT_NOTIFICATION, 1, 16385)
3135 idx += 1
3136 if ctx['num'] == idx:
3137 logger.info("Test: EAP-Failure")
3138 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3139
3140 idx += 1
3141 if ctx['num'] == idx:
3142 logger.info("Test: Notification with unrecognized non-failure")
3143 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3144 4 + 1 + 3 + 4,
3145 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0,
3146 EAP_SIM_AT_NOTIFICATION, 1, 0xc000)
3147 idx += 1
3148 if ctx['num'] == idx:
3149 logger.info("Test: Notification before auth (duplicate)")
3150 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3151 4 + 1 + 3 + 4,
3152 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION, 0,
3153 EAP_SIM_AT_NOTIFICATION, 1, 0xc000)
3154 idx += 1
3155 if ctx['num'] == idx:
3156 logger.info("Test: EAP-Failure")
3157 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3158
3159 idx += 1
3160 if ctx['num'] == idx:
3161 logger.info("Test: Re-authentication (unexpected) with no attributes")
3162 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
3163 4 + 1 + 3,
3164 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_REAUTHENTICATION,
3165 0)
3166 idx += 1
3167 if ctx['num'] == idx:
3168 logger.info("Test: EAP-Failure")
3169 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3170
3171 idx += 1
3172 if ctx['num'] == idx:
3173 logger.info("Test: AKA Challenge with Checkcode claiming identity round was used")
3174 return struct.pack(">BBHBBHBBH5L", EAP_CODE_REQUEST, ctx['id'],
3175 4 + 1 + 3 + 24,
3176 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3177 EAP_SIM_AT_CHECKCODE, 6, 0, 0, 0, 0, 0, 0)
3178 idx += 1
3179 if ctx['num'] == idx:
3180 logger.info("Test: EAP-Failure")
3181 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3182
3183 idx += 1
3184 if ctx['num'] == idx:
3185 logger.info("Test: Identity request ANY_ID")
3186 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3187 4 + 1 + 3 + 4,
3188 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3189 EAP_SIM_AT_ANY_ID_REQ, 1, 0)
3190 idx += 1
3191 if ctx['num'] == idx:
3192 logger.info("Test: AKA Challenge with Checkcode claiming no identity round was used")
3193 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3194 4 + 1 + 3 + 4,
3195 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3196 EAP_SIM_AT_CHECKCODE, 1, 0)
3197 idx += 1
3198 if ctx['num'] == idx:
3199 logger.info("Test: EAP-Failure")
3200 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3201
3202 idx += 1
3203 if ctx['num'] == idx:
3204 logger.info("Test: Identity request ANY_ID")
3205 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3206 4 + 1 + 3 + 4,
3207 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3208 EAP_SIM_AT_ANY_ID_REQ, 1, 0)
3209 idx += 1
3210 if ctx['num'] == idx:
3211 logger.info("Test: AKA Challenge with mismatching Checkcode value")
3212 return struct.pack(">BBHBBHBBH5L", EAP_CODE_REQUEST, ctx['id'],
3213 4 + 1 + 3 + 24,
3214 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3215 EAP_SIM_AT_CHECKCODE, 6, 0, 0, 0, 0, 0, 0)
3216 idx += 1
3217 if ctx['num'] == idx:
3218 logger.info("Test: EAP-Failure")
3219 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3220
3221 idx += 1
3222 if ctx['num'] == idx:
3223 logger.info("Test: Re-authentication (unexpected) with Checkcode claimin identity round was used")
3224 return struct.pack(">BBHBBHBBH5L", EAP_CODE_REQUEST, ctx['id'],
3225 4 + 1 + 3 + 24,
3226 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_REAUTHENTICATION,
3227 0,
3228 EAP_SIM_AT_CHECKCODE, 6, 0, 0, 0, 0, 0, 0)
3229 idx += 1
3230 if ctx['num'] == idx:
3231 logger.info("Test: EAP-Failure")
3232 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3233
3234 idx += 1
3235 if ctx['num'] == idx:
3236 logger.info("Test: Invalid AT_RAND length")
3237 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3238 4 + 1 + 3 + 4,
3239 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3240 EAP_SIM_AT_RAND, 1, 0)
3241 idx += 1
3242 if ctx['num'] == idx:
3243 logger.info("Test: EAP-Failure")
3244 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3245
3246 idx += 1
3247 if ctx['num'] == idx:
3248 logger.info("Test: Invalid AT_AUTN length")
3249 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3250 4 + 1 + 3 + 4,
3251 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3252 EAP_SIM_AT_AUTN, 1, 0)
3253 idx += 1
3254 if ctx['num'] == idx:
3255 logger.info("Test: EAP-Failure")
3256 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3257
3258 idx += 1
3259 if ctx['num'] == idx:
3260 logger.info("Test: Unencrypted AT_PADDING")
3261 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3262 4 + 1 + 3 + 4,
3263 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3264 EAP_SIM_AT_PADDING, 1, 0)
3265 idx += 1
3266 if ctx['num'] == idx:
3267 logger.info("Test: EAP-Failure")
3268 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3269
3270 idx += 1
3271 if ctx['num'] == idx:
3272 logger.info("Test: Invalid AT_NONCE_MT length")
3273 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3274 4 + 1 + 3 + 4,
3275 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3276 EAP_SIM_AT_NONCE_MT, 1, 0)
3277 idx += 1
3278 if ctx['num'] == idx:
3279 logger.info("Test: EAP-Failure")
3280 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3281
3282 idx += 1
3283 if ctx['num'] == idx:
3284 logger.info("Test: Invalid AT_MAC length")
3285 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3286 4 + 1 + 3 + 4,
3287 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3288 EAP_SIM_AT_MAC, 1, 0)
3289 idx += 1
3290 if ctx['num'] == idx:
3291 logger.info("Test: EAP-Failure")
3292 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3293
3294 idx += 1
3295 if ctx['num'] == idx:
3296 logger.info("Test: Invalid AT_NOTIFICATION length")
3297 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
3298 4 + 1 + 3 + 8,
3299 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3300 EAP_SIM_AT_NOTIFICATION, 2, 0, 0)
3301 idx += 1
3302 if ctx['num'] == idx:
3303 logger.info("Test: EAP-Failure")
3304 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3305
3306 idx += 1
3307 if ctx['num'] == idx:
3308 logger.info("Test: AT_IDENTITY overflow")
3309 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3310 4 + 1 + 3 + 4,
3311 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3312 EAP_SIM_AT_IDENTITY, 1, 0xffff)
3313 idx += 1
3314 if ctx['num'] == idx:
3315 logger.info("Test: EAP-Failure")
3316 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3317
3318 idx += 1
3319 if ctx['num'] == idx:
3320 logger.info("Test: Unexpected AT_VERSION_LIST")
3321 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3322 4 + 1 + 3 + 4,
3323 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3324 EAP_SIM_AT_VERSION_LIST, 1, 0)
3325 idx += 1
3326 if ctx['num'] == idx:
3327 logger.info("Test: EAP-Failure")
3328 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3329
3330 idx += 1
3331 if ctx['num'] == idx:
3332 logger.info("Test: Invalid AT_SELECTED_VERSION length")
3333 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
3334 4 + 1 + 3 + 8,
3335 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3336 EAP_SIM_AT_SELECTED_VERSION, 2, 0, 0)
3337 idx += 1
3338 if ctx['num'] == idx:
3339 logger.info("Test: EAP-Failure")
3340 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3341
3342 idx += 1
3343 if ctx['num'] == idx:
3344 logger.info("Test: Unencrypted AT_COUNTER")
3345 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3346 4 + 1 + 3 + 4,
3347 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3348 EAP_SIM_AT_COUNTER, 1, 0)
3349 idx += 1
3350 if ctx['num'] == idx:
3351 logger.info("Test: EAP-Failure")
3352 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3353
3354 idx += 1
3355 if ctx['num'] == idx:
3356 logger.info("Test: Unencrypted AT_COUNTER_TOO_SMALL")
3357 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3358 4 + 1 + 3 + 4,
3359 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3360 EAP_SIM_AT_COUNTER_TOO_SMALL, 1, 0)
3361 idx += 1
3362 if ctx['num'] == idx:
3363 logger.info("Test: EAP-Failure")
3364 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3365
3366 idx += 1
3367 if ctx['num'] == idx:
3368 logger.info("Test: Unencrypted AT_NONCE_S")
3369 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3370 4 + 1 + 3 + 4,
3371 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3372 EAP_SIM_AT_NONCE_S, 1, 0)
3373 idx += 1
3374 if ctx['num'] == idx:
3375 logger.info("Test: EAP-Failure")
3376 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3377
3378 idx += 1
3379 if ctx['num'] == idx:
3380 logger.info("Test: Invalid AT_CLIENT_ERROR_CODE length")
3381 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
3382 4 + 1 + 3 + 8,
3383 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3384 EAP_SIM_AT_CLIENT_ERROR_CODE, 2, 0, 0)
3385 idx += 1
3386 if ctx['num'] == idx:
3387 logger.info("Test: EAP-Failure")
3388 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3389
3390 idx += 1
3391 if ctx['num'] == idx:
3392 logger.info("Test: Invalid AT_IV length")
3393 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3394 4 + 1 + 3 + 4,
3395 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3396 EAP_SIM_AT_IV, 1, 0)
3397 idx += 1
3398 if ctx['num'] == idx:
3399 logger.info("Test: EAP-Failure")
3400 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3401
3402 idx += 1
3403 if ctx['num'] == idx:
3404 logger.info("Test: Invalid AT_ENCR_DATA length")
3405 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
3406 4 + 1 + 3 + 8,
3407 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3408 EAP_SIM_AT_ENCR_DATA, 2, 0, 0)
3409 idx += 1
3410 if ctx['num'] == idx:
3411 logger.info("Test: EAP-Failure")
3412 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3413
3414 idx += 1
3415 if ctx['num'] == idx:
3416 logger.info("Test: Unencrypted AT_NEXT_PSEUDONYM")
3417 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3418 4 + 1 + 3 + 4,
3419 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3420 EAP_SIM_AT_NEXT_PSEUDONYM, 1, 0)
3421 idx += 1
3422 if ctx['num'] == idx:
3423 logger.info("Test: EAP-Failure")
3424 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3425
3426 idx += 1
3427 if ctx['num'] == idx:
3428 logger.info("Test: Unencrypted AT_NEXT_REAUTH_ID")
3429 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3430 4 + 1 + 3 + 4,
3431 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3432 EAP_SIM_AT_NEXT_REAUTH_ID, 1, 0)
3433 idx += 1
3434 if ctx['num'] == idx:
3435 logger.info("Test: EAP-Failure")
3436 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3437
3438 idx += 1
3439 if ctx['num'] == idx:
3440 logger.info("Test: Invalid AT_RES length")
3441 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3442 4 + 1 + 3 + 4,
3443 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3444 EAP_SIM_AT_RES, 1, 0)
3445 idx += 1
3446 if ctx['num'] == idx:
3447 logger.info("Test: EAP-Failure")
3448 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3449
3450 idx += 1
3451 if ctx['num'] == idx:
3452 logger.info("Test: Invalid AT_RES length")
3453 return struct.pack(">BBHBBHBBH5L", EAP_CODE_REQUEST, ctx['id'],
3454 4 + 1 + 3 + 24,
3455 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3456 EAP_SIM_AT_RES, 6, 0xffff, 0, 0, 0, 0, 0)
3457 idx += 1
3458 if ctx['num'] == idx:
3459 logger.info("Test: EAP-Failure")
3460 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3461
3462 idx += 1
3463 if ctx['num'] == idx:
3464 logger.info("Test: Invalid AT_AUTS length")
3465 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
3466 4 + 1 + 3 + 8,
3467 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3468 EAP_SIM_AT_AUTS, 2, 0, 0)
3469 idx += 1
3470 if ctx['num'] == idx:
3471 logger.info("Test: EAP-Failure")
3472 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3473
3474 idx += 1
3475 if ctx['num'] == idx:
3476 logger.info("Test: Invalid AT_CHECKCODE length")
3477 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
3478 4 + 1 + 3 + 8,
3479 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3480 EAP_SIM_AT_CHECKCODE, 2, 0, 0)
3481 idx += 1
3482 if ctx['num'] == idx:
3483 logger.info("Test: EAP-Failure")
3484 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3485
3486 idx += 1
3487 if ctx['num'] == idx:
3488 logger.info("Test: Invalid AT_RESULT_IND length")
3489 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
3490 4 + 1 + 3 + 8,
3491 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3492 EAP_SIM_AT_RESULT_IND, 2, 0, 0)
3493 idx += 1
3494 if ctx['num'] == idx:
3495 logger.info("Test: EAP-Failure")
3496 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3497
3498 idx += 1
3499 if ctx['num'] == idx:
3500 logger.info("Test: Unexpected AT_KDF_INPUT")
3501 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
3502 4 + 1 + 3 + 8,
3503 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3504 EAP_SIM_AT_KDF_INPUT, 2, 0, 0)
3505 idx += 1
3506 if ctx['num'] == idx:
3507 logger.info("Test: EAP-Failure")
3508 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3509
3510 idx += 1
3511 if ctx['num'] == idx:
3512 logger.info("Test: Unexpected AT_KDF")
3513 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
3514 4 + 1 + 3 + 8,
3515 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3516 EAP_SIM_AT_KDF, 2, 0, 0)
3517 idx += 1
3518 if ctx['num'] == idx:
3519 logger.info("Test: EAP-Failure")
3520 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3521
3522 idx += 1
3523 if ctx['num'] == idx:
3524 logger.info("Test: Invalid AT_BIDDING length")
3525 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
3526 4 + 1 + 3 + 8,
3527 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY, 0,
3528 EAP_SIM_AT_BIDDING, 2, 0, 0)
3529 idx += 1
3530 if ctx['num'] == idx:
3531 logger.info("Test: EAP-Failure")
3532 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3533
3534 return None
3535
3536 srv = start_radius_server(aka_handler)
6c080dfa
JM
3537
3538 try:
3539 hapd = start_ap(apdev[0]['ifname'])
3540
3541 for i in range(0, 49):
3542 eap = "AKA AKA'" if i == 11 else "AKA"
3543 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
3544 eap=eap, identity="0232010000000000",
3545 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123",
3546 wait_connect=False)
3547 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
3548 timeout=15)
3549 if ev is None:
3550 raise Exception("Timeout on EAP start")
3551 if i in [ 0, 15 ]:
3552 time.sleep(0.1)
3553 else:
3554 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"],
3555 timeout=10)
3556 if ev is None:
3557 raise Exception("Timeout on EAP failure")
3558 dev[0].request("REMOVE_NETWORK all")
f0174bff 3559 dev[0].dump_monitor()
6c080dfa
JM
3560 finally:
3561 stop_radius_server(srv)
3562
3563def test_eap_proto_aka_prime(dev, apdev):
3564 """EAP-AKA' protocol tests"""
3565 def aka_prime_handler(ctx, req):
3566 logger.info("aka_prime_handler - RX " + req.encode("hex"))
3567 if 'num' not in ctx:
3568 ctx['num'] = 0
3569 ctx['num'] = ctx['num'] + 1
3570 if 'id' not in ctx:
3571 ctx['id'] = 1
3572 ctx['id'] = (ctx['id'] + 1) % 256
3573
3574 idx = 0
3575
3576 idx += 1
3577 if ctx['num'] == idx:
3578 logger.info("Test: Missing payload")
3579 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
3580 4 + 1,
3581 EAP_TYPE_AKA_PRIME)
3582
3583 idx += 1
3584 if ctx['num'] == idx:
3585 logger.info("Test: Challenge with no attributes")
3586 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
3587 4 + 1 + 3,
3588 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0)
3589 idx += 1
3590 if ctx['num'] == idx:
3591 logger.info("Test: EAP-Failure")
3592 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3593
3594 idx += 1
3595 if ctx['num'] == idx:
3596 logger.info("Test: Challenge with empty AT_KDF_INPUT")
3597 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3598 4 + 1 + 3 + 4,
3599 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3600 EAP_SIM_AT_KDF_INPUT, 1, 0)
3601 idx += 1
3602 if ctx['num'] == idx:
3603 logger.info("Test: EAP-Failure")
3604 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3605
3606 idx += 1
3607 if ctx['num'] == idx:
3608 logger.info("Test: Challenge with AT_KDF_INPUT")
3609 return struct.pack(">BBHBBHBBHBBBB", EAP_CODE_REQUEST, ctx['id'],
3610 4 + 1 + 3 + 8,
3611 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3612 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
3613 ord('c'), ord('d'))
3614 idx += 1
3615 if ctx['num'] == idx:
3616 logger.info("Test: EAP-Failure")
3617 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3618
3619 idx += 1
3620 if ctx['num'] == idx:
3621 logger.info("Test: Challenge with duplicated KDF")
3622 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH",
3623 EAP_CODE_REQUEST, ctx['id'],
3624 4 + 1 + 3 + 8 + 3 * 4,
3625 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3626 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
3627 ord('c'), ord('d'),
3628 EAP_SIM_AT_KDF, 1, 1,
3629 EAP_SIM_AT_KDF, 1, 2,
3630 EAP_SIM_AT_KDF, 1, 1)
3631 idx += 1
3632 if ctx['num'] == idx:
3633 logger.info("Test: EAP-Failure")
3634 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3635
3636 idx += 1
3637 if ctx['num'] == idx:
3638 logger.info("Test: Challenge with multiple KDF proposals")
3639 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH",
3640 EAP_CODE_REQUEST, ctx['id'],
3641 4 + 1 + 3 + 8 + 3 * 4,
3642 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3643 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
3644 ord('c'), ord('d'),
3645 EAP_SIM_AT_KDF, 1, 255,
3646 EAP_SIM_AT_KDF, 1, 254,
3647 EAP_SIM_AT_KDF, 1, 1)
3648 idx += 1
3649 if ctx['num'] == idx:
3650 logger.info("Test: Challenge with incorrect KDF selected")
3651 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBHBBH",
3652 EAP_CODE_REQUEST, ctx['id'],
3653 4 + 1 + 3 + 8 + 4 * 4,
3654 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3655 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
3656 ord('c'), ord('d'),
3657 EAP_SIM_AT_KDF, 1, 255,
3658 EAP_SIM_AT_KDF, 1, 255,
3659 EAP_SIM_AT_KDF, 1, 254,
3660 EAP_SIM_AT_KDF, 1, 1)
3661 idx += 1
3662 if ctx['num'] == idx:
3663 logger.info("Test: EAP-Failure")
3664 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3665
3666 idx += 1
3667 if ctx['num'] == idx:
3668 logger.info("Test: Challenge with multiple KDF proposals")
3669 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH",
3670 EAP_CODE_REQUEST, ctx['id'],
3671 4 + 1 + 3 + 8 + 3 * 4,
3672 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3673 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
3674 ord('c'), ord('d'),
3675 EAP_SIM_AT_KDF, 1, 255,
3676 EAP_SIM_AT_KDF, 1, 254,
3677 EAP_SIM_AT_KDF, 1, 1)
3678 idx += 1
3679 if ctx['num'] == idx:
3680 logger.info("Test: Challenge with selected KDF not duplicated")
3681 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH",
3682 EAP_CODE_REQUEST, ctx['id'],
3683 4 + 1 + 3 + 8 + 3 * 4,
3684 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3685 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
3686 ord('c'), ord('d'),
3687 EAP_SIM_AT_KDF, 1, 1,
3688 EAP_SIM_AT_KDF, 1, 255,
3689 EAP_SIM_AT_KDF, 1, 254)
3690 idx += 1
3691 if ctx['num'] == idx:
3692 logger.info("Test: EAP-Failure")
3693 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3694
3695 idx += 1
3696 if ctx['num'] == idx:
3697 logger.info("Test: Challenge with multiple KDF proposals")
3698 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH",
3699 EAP_CODE_REQUEST, ctx['id'],
3700 4 + 1 + 3 + 8 + 3 * 4,
3701 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3702 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
3703 ord('c'), ord('d'),
3704 EAP_SIM_AT_KDF, 1, 255,
3705 EAP_SIM_AT_KDF, 1, 254,
3706 EAP_SIM_AT_KDF, 1, 1)
3707 idx += 1
3708 if ctx['num'] == idx:
3709 logger.info("Test: Challenge with selected KDF duplicated (missing MAC, RAND, AUTN)")
3710 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBHBBH",
3711 EAP_CODE_REQUEST, ctx['id'],
3712 4 + 1 + 3 + 8 + 4 * 4,
3713 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3714 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
3715 ord('c'), ord('d'),
3716 EAP_SIM_AT_KDF, 1, 1,
3717 EAP_SIM_AT_KDF, 1, 255,
3718 EAP_SIM_AT_KDF, 1, 254,
3719 EAP_SIM_AT_KDF, 1, 1)
3720 idx += 1
3721 if ctx['num'] == idx:
3722 logger.info("Test: EAP-Failure")
3723 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3724
3725 idx += 1
3726 if ctx['num'] == idx:
3727 logger.info("Test: Challenge with multiple unsupported KDF proposals")
3728 return struct.pack(">BBHBBHBBHBBBBBBHBBH",
3729 EAP_CODE_REQUEST, ctx['id'],
3730 4 + 1 + 3 + 8 + 2 * 4,
3731 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3732 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
3733 ord('c'), ord('d'),
3734 EAP_SIM_AT_KDF, 1, 255,
3735 EAP_SIM_AT_KDF, 1, 254)
3736 idx += 1
3737 if ctx['num'] == idx:
3738 logger.info("Test: EAP-Failure")
3739 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3740
3741 idx += 1
3742 if ctx['num'] == idx:
3743 logger.info("Test: Challenge with multiple KDF proposals")
3744 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBH",
3745 EAP_CODE_REQUEST, ctx['id'],
3746 4 + 1 + 3 + 8 + 3 * 4,
3747 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3748 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
3749 ord('c'), ord('d'),
3750 EAP_SIM_AT_KDF, 1, 255,
3751 EAP_SIM_AT_KDF, 1, 254,
3752 EAP_SIM_AT_KDF, 1, 1)
3753 idx += 1
3754 if ctx['num'] == idx:
3755 logger.info("Test: Challenge with invalid MAC, RAND, AUTN values)")
3756 return struct.pack(">BBHBBHBBHBBBBBBHBBHBBHBBHBBH4LBBH4LBBH4L",
3757 EAP_CODE_REQUEST, ctx['id'],
3758 4 + 1 + 3 + 8 + 4 * 4 + 20 + 20 + 20,
3759 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3760 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
3761 ord('c'), ord('d'),
3762 EAP_SIM_AT_KDF, 1, 1,
3763 EAP_SIM_AT_KDF, 1, 255,
3764 EAP_SIM_AT_KDF, 1, 254,
3765 EAP_SIM_AT_KDF, 1, 1,
3766 EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0,
3767 EAP_SIM_AT_RAND, 5, 0, 0, 0, 0, 0,
3768 EAP_SIM_AT_AUTN, 5, 0, 0, 0, 0, 0)
3769 idx += 1
3770 if ctx['num'] == idx:
3771 logger.info("Test: EAP-Failure")
3772 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3773
3774 idx += 1
3775 if ctx['num'] == idx:
3776 logger.info("Test: Challenge - AMF separation bit not set)")
3777 return struct.pack(">BBHBBHBBHBBBBBBHBBH4LBBH4LBBH4L",
3778 EAP_CODE_REQUEST, ctx['id'],
3779 4 + 1 + 3 + 8 + 4 + 20 + 20 + 20,
3780 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3781 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
3782 ord('c'), ord('d'),
3783 EAP_SIM_AT_KDF, 1, 1,
3784 EAP_SIM_AT_MAC, 5, 0, 1, 2, 3, 4,
3785 EAP_SIM_AT_RAND, 5, 0, 5, 6, 7, 8,
3786 EAP_SIM_AT_AUTN, 5, 0, 9, 10,
3787 0x2fda8ef7, 0xbba518cc)
3788 idx += 1
3789 if ctx['num'] == idx:
3790 logger.info("Test: EAP-Failure")
3791 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3792
3793 idx += 1
3794 if ctx['num'] == idx:
3795 logger.info("Test: Challenge - Invalid MAC")
3796 return struct.pack(">BBHBBHBBHBBBBBBHBBH4LBBH4LBBH4L",
3797 EAP_CODE_REQUEST, ctx['id'],
3798 4 + 1 + 3 + 8 + 4 + 20 + 20 + 20,
3799 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3800 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
3801 ord('c'), ord('d'),
3802 EAP_SIM_AT_KDF, 1, 1,
3803 EAP_SIM_AT_MAC, 5, 0, 1, 2, 3, 4,
3804 EAP_SIM_AT_RAND, 5, 0, 5, 6, 7, 8,
3805 EAP_SIM_AT_AUTN, 5, 0, 0xffffffff, 0xffffffff,
3806 0xd1f90322, 0x40514cb4)
3807 idx += 1
3808 if ctx['num'] == idx:
3809 logger.info("Test: EAP-Failure")
3810 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3811
3812 idx += 1
3813 if ctx['num'] == idx:
3814 logger.info("Test: Challenge - Valid MAC")
3815 return struct.pack(">BBHBBHBBHBBBBBBHBBH4LBBH4LBBH4L",
3816 EAP_CODE_REQUEST, ctx['id'],
3817 4 + 1 + 3 + 8 + 4 + 20 + 20 + 20,
3818 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3819 EAP_SIM_AT_KDF_INPUT, 2, 1, ord('a'), ord('b'),
3820 ord('c'), ord('d'),
3821 EAP_SIM_AT_KDF, 1, 1,
3822 EAP_SIM_AT_MAC, 5, 0,
3823 0xf4a3c1d3, 0x7c901401, 0x34bd8b01, 0x6f7fa32f,
3824 EAP_SIM_AT_RAND, 5, 0, 5, 6, 7, 8,
3825 EAP_SIM_AT_AUTN, 5, 0, 0xffffffff, 0xffffffff,
3826 0xd1f90322, 0x40514cb4)
3827 idx += 1
3828 if ctx['num'] == idx:
3829 logger.info("Test: EAP-Failure")
3830 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3831
3832 idx += 1
3833 if ctx['num'] == idx:
3834 logger.info("Test: Invalid AT_KDF_INPUT length")
3835 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
3836 4 + 1 + 3 + 8,
3837 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_IDENTITY, 0,
3838 EAP_SIM_AT_KDF_INPUT, 2, 0xffff, 0)
3839 idx += 1
3840 if ctx['num'] == idx:
3841 logger.info("Test: EAP-Failure")
3842 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3843
3844 idx += 1
3845 if ctx['num'] == idx:
3846 logger.info("Test: Invalid AT_KDF length")
3847 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
3848 4 + 1 + 3 + 8,
3849 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_IDENTITY, 0,
3850 EAP_SIM_AT_KDF, 2, 0, 0)
3851 idx += 1
3852 if ctx['num'] == idx:
3853 logger.info("Test: EAP-Failure")
3854 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3855
3856 idx += 1
3857 if ctx['num'] == idx:
3858 logger.info("Test: Challenge with large number of KDF proposals")
3859 return struct.pack(">BBHBBHBBHBBHBBHBBHBBHBBHBBHBBHBBHBBHBBHBBH",
3860 EAP_CODE_REQUEST, ctx['id'],
3861 4 + 1 + 3 + 12 * 4,
3862 EAP_TYPE_AKA_PRIME, EAP_AKA_SUBTYPE_CHALLENGE, 0,
3863 EAP_SIM_AT_KDF, 1, 255,
3864 EAP_SIM_AT_KDF, 1, 254,
3865 EAP_SIM_AT_KDF, 1, 253,
3866 EAP_SIM_AT_KDF, 1, 252,
3867 EAP_SIM_AT_KDF, 1, 251,
3868 EAP_SIM_AT_KDF, 1, 250,
3869 EAP_SIM_AT_KDF, 1, 249,
3870 EAP_SIM_AT_KDF, 1, 248,
3871 EAP_SIM_AT_KDF, 1, 247,
3872 EAP_SIM_AT_KDF, 1, 246,
3873 EAP_SIM_AT_KDF, 1, 245,
3874 EAP_SIM_AT_KDF, 1, 244)
3875 idx += 1
3876 if ctx['num'] == idx:
3877 logger.info("Test: EAP-Failure")
3878 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3879
3880 return None
3881
3882 srv = start_radius_server(aka_prime_handler)
6c080dfa
JM
3883
3884 try:
3885 hapd = start_ap(apdev[0]['ifname'])
3886
3887 for i in range(0, 16):
3888 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
3889 eap="AKA'", identity="6555444333222111",
3890 password="5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123",
3891 wait_connect=False)
3892 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
3893 timeout=15)
3894 if ev is None:
3895 raise Exception("Timeout on EAP start")
3896 if i in [ 0 ]:
3897 time.sleep(0.1)
3898 else:
3899 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"],
3900 timeout=10)
3901 if ev is None:
3902 raise Exception("Timeout on EAP failure")
3903 dev[0].request("REMOVE_NETWORK all")
f0174bff 3904 dev[0].dump_monitor()
6c080dfa
JM
3905 finally:
3906 stop_radius_server(srv)
3907
3908def test_eap_proto_sim(dev, apdev):
3909 """EAP-SIM protocol tests"""
3910 def sim_handler(ctx, req):
3911 logger.info("sim_handler - RX " + req.encode("hex"))
3912 if 'num' not in ctx:
3913 ctx['num'] = 0
3914 ctx['num'] = ctx['num'] + 1
3915 if 'id' not in ctx:
3916 ctx['id'] = 1
3917 ctx['id'] = (ctx['id'] + 1) % 256
3918
3919 idx = 0
3920
3921 idx += 1
3922 if ctx['num'] == idx:
3923 logger.info("Test: Missing payload")
3924 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
3925 4 + 1,
3926 EAP_TYPE_SIM)
3927
3928 idx += 1
3929 if ctx['num'] == idx:
3930 logger.info("Test: Unexpected AT_AUTN")
3931 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
3932 4 + 1 + 3 + 8,
3933 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
3934 EAP_SIM_AT_AUTN, 2, 0, 0)
3935 idx += 1
3936 if ctx['num'] == idx:
3937 logger.info("Test: EAP-Failure")
3938 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3939
3940 idx += 1
3941 if ctx['num'] == idx:
3942 logger.info("Test: Too short AT_VERSION_LIST")
3943 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3944 4 + 1 + 3 + 4,
3945 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
3946 EAP_SIM_AT_VERSION_LIST, 1, 0)
3947 idx += 1
3948 if ctx['num'] == idx:
3949 logger.info("Test: EAP-Failure")
3950 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3951
3952 idx += 1
3953 if ctx['num'] == idx:
3954 logger.info("Test: AT_VERSION_LIST overflow")
3955 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
3956 4 + 1 + 3 + 4,
3957 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
3958 EAP_SIM_AT_VERSION_LIST, 1, 0xffff)
3959 idx += 1
3960 if ctx['num'] == idx:
3961 logger.info("Test: EAP-Failure")
3962 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3963
3964 idx += 1
3965 if ctx['num'] == idx:
3966 logger.info("Test: Unexpected AT_AUTS")
3967 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
3968 4 + 1 + 3 + 8,
3969 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
3970 EAP_SIM_AT_AUTS, 2, 0, 0)
3971 idx += 1
3972 if ctx['num'] == idx:
3973 logger.info("Test: EAP-Failure")
3974 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3975
3976 idx += 1
3977 if ctx['num'] == idx:
3978 logger.info("Test: Unexpected AT_CHECKCODE")
3979 return struct.pack(">BBHBBHBBHL", EAP_CODE_REQUEST, ctx['id'],
3980 4 + 1 + 3 + 8,
3981 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
3982 EAP_SIM_AT_CHECKCODE, 2, 0, 0)
3983 idx += 1
3984 if ctx['num'] == idx:
3985 logger.info("Test: EAP-Failure")
3986 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3987
3988 idx += 1
3989 if ctx['num'] == idx:
3990 logger.info("Test: No AT_VERSION_LIST in Start")
3991 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
3992 4 + 1 + 3,
3993 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0)
3994 idx += 1
3995 if ctx['num'] == idx:
3996 logger.info("Test: EAP-Failure")
3997 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
3998
3999 idx += 1
4000 if ctx['num'] == idx:
4001 logger.info("Test: No support version in AT_VERSION_LIST")
4002 return struct.pack(">BBHBBHBBH4B", EAP_CODE_REQUEST, ctx['id'],
4003 4 + 1 + 3 + 8,
4004 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
4005 EAP_SIM_AT_VERSION_LIST, 2, 3, 2, 3, 4, 5)
4006 idx += 1
4007 if ctx['num'] == idx:
4008 logger.info("Test: EAP-Failure")
4009 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4010
4011
4012 idx += 1
4013 if ctx['num'] == idx:
4014 logger.info("Test: Identity request without ID type")
4015 return struct.pack(">BBHBBHBBH2H", EAP_CODE_REQUEST, ctx['id'],
4016 4 + 1 + 3 + 8,
4017 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
4018 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0)
4019 idx += 1
4020 if ctx['num'] == idx:
4021 logger.info("Test: Identity request ANY_ID")
4022 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'],
4023 4 + 1 + 3 + 8 + 4,
4024 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
4025 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0,
4026 EAP_SIM_AT_ANY_ID_REQ, 1, 0)
4027 idx += 1
4028 if ctx['num'] == idx:
4029 logger.info("Test: Identity request ANY_ID (duplicate)")
4030 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'],
4031 4 + 1 + 3 + 8 + 4,
4032 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
4033 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0,
4034 EAP_SIM_AT_ANY_ID_REQ, 1, 0)
4035 idx += 1
4036 if ctx['num'] == idx:
4037 logger.info("Test: EAP-Failure")
4038 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4039
4040 idx += 1
4041 if ctx['num'] == idx:
4042 logger.info("Test: Identity request ANY_ID")
4043 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'],
4044 4 + 1 + 3 + 8 + 4,
4045 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
4046 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0,
4047 EAP_SIM_AT_ANY_ID_REQ, 1, 0)
4048 idx += 1
4049 if ctx['num'] == idx:
4050 logger.info("Test: Identity request FULLAUTH_ID")
4051 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'],
4052 4 + 1 + 3 + 8 + 4,
4053 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
4054 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0,
4055 EAP_SIM_AT_FULLAUTH_ID_REQ, 1, 0)
4056 idx += 1
4057 if ctx['num'] == idx:
4058 logger.info("Test: Identity request FULLAUTH_ID (duplicate)")
4059 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'],
4060 4 + 1 + 3 + 8 + 4,
4061 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
4062 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0,
4063 EAP_SIM_AT_FULLAUTH_ID_REQ, 1, 0)
4064 idx += 1
4065 if ctx['num'] == idx:
4066 logger.info("Test: EAP-Failure")
4067 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4068
4069 idx += 1
4070 if ctx['num'] == idx:
4071 logger.info("Test: Identity request ANY_ID")
4072 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'],
4073 4 + 1 + 3 + 8 + 4,
4074 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
4075 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0,
4076 EAP_SIM_AT_ANY_ID_REQ, 1, 0)
4077 idx += 1
4078 if ctx['num'] == idx:
4079 logger.info("Test: Identity request FULLAUTH_ID")
4080 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'],
4081 4 + 1 + 3 + 8 + 4,
4082 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
4083 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0,
4084 EAP_SIM_AT_FULLAUTH_ID_REQ, 1, 0)
4085 idx += 1
4086 if ctx['num'] == idx:
4087 logger.info("Test: Identity request PERMANENT_ID")
4088 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'],
4089 4 + 1 + 3 + 8 + 4,
4090 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
4091 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0,
4092 EAP_SIM_AT_PERMANENT_ID_REQ, 1, 0)
4093 idx += 1
4094 if ctx['num'] == idx:
4095 logger.info("Test: Identity request PERMANENT_ID (duplicate)")
4096 return struct.pack(">BBHBBHBBH2HBBH", EAP_CODE_REQUEST, ctx['id'],
4097 4 + 1 + 3 + 8 + 4,
4098 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START, 0,
4099 EAP_SIM_AT_VERSION_LIST, 2, 2, 1, 0,
4100 EAP_SIM_AT_PERMANENT_ID_REQ, 1, 0)
4101 idx += 1
4102 if ctx['num'] == idx:
4103 logger.info("Test: EAP-Failure")
4104 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4105
4106 idx += 1
4107 if ctx['num'] == idx:
4108 logger.info("Test: No AT_MAC and AT_RAND in Challenge")
4109 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
4110 4 + 1 + 3,
4111 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CHALLENGE, 0)
4112 idx += 1
4113 if ctx['num'] == idx:
4114 logger.info("Test: EAP-Failure")
4115 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4116
4117 idx += 1
4118 if ctx['num'] == idx:
4119 logger.info("Test: No AT_RAND in Challenge")
4120 return struct.pack(">BBHBBHBBH4L", EAP_CODE_REQUEST, ctx['id'],
4121 4 + 1 + 3 + 20,
4122 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CHALLENGE, 0,
4123 EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0)
4124 idx += 1
4125 if ctx['num'] == idx:
4126 logger.info("Test: EAP-Failure")
4127 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4128
4129 idx += 1
4130 if ctx['num'] == idx:
4131 logger.info("Test: Insufficient number of challenges in Challenge")
4132 return struct.pack(">BBHBBHBBH4LBBH4L", EAP_CODE_REQUEST, ctx['id'],
4133 4 + 1 + 3 + 20 + 20,
4134 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CHALLENGE, 0,
4135 EAP_SIM_AT_RAND, 5, 0, 0, 0, 0, 0,
4136 EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0)
4137 idx += 1
4138 if ctx['num'] == idx:
4139 logger.info("Test: EAP-Failure")
4140 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4141
4142 idx += 1
4143 if ctx['num'] == idx:
4144 logger.info("Test: Too many challenges in Challenge")
4145 return struct.pack(">BBHBBHBBH4L4L4L4LBBH4L", EAP_CODE_REQUEST,
4146 ctx['id'],
4147 4 + 1 + 3 + 4 + 4 * 16 + 20,
4148 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CHALLENGE, 0,
4149 EAP_SIM_AT_RAND, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4150 0, 0, 0, 0, 0, 0, 0, 0,
4151 EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0)
4152 idx += 1
4153 if ctx['num'] == idx:
4154 logger.info("Test: EAP-Failure")
4155 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4156
4157 idx += 1
4158 if ctx['num'] == idx:
4159 logger.info("Test: Same RAND multiple times in Challenge")
4160 return struct.pack(">BBHBBHBBH4L4L4LBBH4L", EAP_CODE_REQUEST,
4161 ctx['id'],
4162 4 + 1 + 3 + 4 + 3 * 16 + 20,
4163 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CHALLENGE, 0,
4164 EAP_SIM_AT_RAND, 13, 0, 0, 0, 0, 0, 0, 0, 0, 1,
4165 0, 0, 0, 0,
4166 EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0)
4167 idx += 1
4168 if ctx['num'] == idx:
4169 logger.info("Test: EAP-Failure")
4170 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4171
4172 idx += 1
4173 if ctx['num'] == idx:
4174 logger.info("Test: Notification with no attributes")
4175 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
4176 4 + 1 + 3,
4177 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0)
4178 idx += 1
4179 if ctx['num'] == idx:
4180 logger.info("Test: EAP-Failure")
4181 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4182
4183 idx += 1
4184 if ctx['num'] == idx:
4185 logger.info("Test: Notification indicating success, but no MAC")
4186 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4187 4 + 1 + 3 + 4,
4188 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0,
4189 EAP_SIM_AT_NOTIFICATION, 1, 32768)
4190 idx += 1
4191 if ctx['num'] == idx:
4192 logger.info("Test: EAP-Failure")
4193 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4194
4195 idx += 1
4196 if ctx['num'] == idx:
4197 logger.info("Test: Notification indicating success, but invalid MAC value")
4198 return struct.pack(">BBHBBHBBHBBH4L", EAP_CODE_REQUEST, ctx['id'],
4199 4 + 1 + 3 + 4 + 20,
4200 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0,
4201 EAP_SIM_AT_NOTIFICATION, 1, 32768,
4202 EAP_SIM_AT_MAC, 5, 0, 0, 0, 0, 0)
4203 idx += 1
4204 if ctx['num'] == idx:
4205 logger.info("Test: EAP-Failure")
4206 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4207
4208 idx += 1
4209 if ctx['num'] == idx:
4210 logger.info("Test: Notification before auth")
4211 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4212 4 + 1 + 3 + 4,
4213 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0,
4214 EAP_SIM_AT_NOTIFICATION, 1, 16384)
4215 idx += 1
4216 if ctx['num'] == idx:
4217 logger.info("Test: EAP-Failure")
4218 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4219
4220 idx += 1
4221 if ctx['num'] == idx:
4222 logger.info("Test: Notification before auth")
4223 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4224 4 + 1 + 3 + 4,
4225 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0,
4226 EAP_SIM_AT_NOTIFICATION, 1, 16385)
4227 idx += 1
4228 if ctx['num'] == idx:
4229 logger.info("Test: EAP-Failure")
4230 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4231
4232 idx += 1
4233 if ctx['num'] == idx:
4234 logger.info("Test: Notification with unrecognized non-failure")
4235 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4236 4 + 1 + 3 + 4,
4237 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0,
4238 EAP_SIM_AT_NOTIFICATION, 1, 0xc000)
4239 idx += 1
4240 if ctx['num'] == idx:
4241 logger.info("Test: Notification before auth (duplicate)")
4242 return struct.pack(">BBHBBHBBH", EAP_CODE_REQUEST, ctx['id'],
4243 4 + 1 + 3 + 4,
4244 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION, 0,
4245 EAP_SIM_AT_NOTIFICATION, 1, 0xc000)
4246 idx += 1
4247 if ctx['num'] == idx:
4248 logger.info("Test: EAP-Failure")
4249 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4250
4251 idx += 1
4252 if ctx['num'] == idx:
4253 logger.info("Test: Re-authentication (unexpected) with no attributes")
4254 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
4255 4 + 1 + 3,
4256 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_REAUTHENTICATION,
4257 0)
4258 idx += 1
4259 if ctx['num'] == idx:
4260 logger.info("Test: EAP-Failure")
4261 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4262
4263 idx += 1
4264 if ctx['num'] == idx:
4265 logger.info("Test: Client Error")
f0174bff
JM
4266 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
4267 4 + 1 + 3,
4268 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CLIENT_ERROR, 0)
6c080dfa
JM
4269 idx += 1
4270 if ctx['num'] == idx:
4271 logger.info("Test: EAP-Failure")
4272 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4273
4274 idx += 1
4275 if ctx['num'] == idx:
4276 logger.info("Test: Unknown subtype")
f0174bff
JM
4277 return struct.pack(">BBHBBH", EAP_CODE_REQUEST, ctx['id'],
4278 4 + 1 + 3,
4279 EAP_TYPE_SIM, 255, 0)
6c080dfa
JM
4280 idx += 1
4281 if ctx['num'] == idx:
4282 logger.info("Test: EAP-Failure")
4283 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4284
4285 return None
4286
4287 srv = start_radius_server(sim_handler)
6c080dfa
JM
4288
4289 try:
4290 hapd = start_ap(apdev[0]['ifname'])
4291
4292 for i in range(0, 25):
4293 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4294 eap="SIM", identity="1232010000000000",
4295 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581",
4296 wait_connect=False)
4297 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
4298 timeout=15)
4299 if ev is None:
4300 raise Exception("Timeout on EAP start")
4301 if i in [ 0 ]:
4302 time.sleep(0.1)
4303 else:
4304 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"],
4305 timeout=10)
4306 if ev is None:
4307 raise Exception("Timeout on EAP failure")
4308 dev[0].request("REMOVE_NETWORK all")
f0174bff 4309 dev[0].dump_monitor()
6c080dfa
JM
4310 finally:
4311 stop_radius_server(srv)
cb0555f7 4312
d36ae376
JM
4313def test_eap_proto_sim_errors(dev, apdev):
4314 """EAP-SIM protocol tests (error paths)"""
4315 check_hlr_auc_gw_support()
4316 params = hostapd.wpa2_eap_params(ssid="eap-test")
4317 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4318
4319 with alloc_fail(dev[0], 1, "eap_sim_init"):
4320 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4321 eap="SIM", identity="1232010000000000",
4322 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581",
4323 wait_connect=False)
4324 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
4325 timeout=15)
4326 if ev is None:
4327 raise Exception("Timeout on EAP start")
4328 dev[0].request("REMOVE_NETWORK all")
4329 dev[0].wait_disconnected()
4330
4331 with fail_test(dev[0], 1, "os_get_random;eap_sim_init"):
4332 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4333 eap="SIM", identity="1232010000000000",
4334 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581",
4335 wait_connect=False)
4336 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
4337 timeout=15)
4338 if ev is None:
4339 raise Exception("Timeout on EAP start")
4340 dev[0].request("REMOVE_NETWORK all")
4341 dev[0].wait_disconnected()
4342
4343 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4344 eap="SIM", identity="1232010000000000",
4345 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581")
4346
4347 with fail_test(dev[0], 1, "aes_128_cbc_encrypt;eap_sim_response_reauth"):
4348 hapd.request("EAPOL_REAUTH " + dev[0].own_addr())
4349 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
4350 if ev is None:
4351 raise Exception("EAP re-authentication did not start")
4352 wait_fail_trigger(dev[0], "GET_FAIL")
4353 dev[0].request("REMOVE_NETWORK all")
4354 dev[0].dump_monitor()
4355
4356 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4357 eap="SIM", identity="1232010000000000",
4358 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581")
4359
4360 with fail_test(dev[0], 1, "os_get_random;eap_sim_msg_add_encr_start"):
4361 hapd.request("EAPOL_REAUTH " + dev[0].own_addr())
4362 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
4363 if ev is None:
4364 raise Exception("EAP re-authentication did not start")
4365 wait_fail_trigger(dev[0], "GET_FAIL")
4366 dev[0].request("REMOVE_NETWORK all")
4367 dev[0].dump_monitor()
4368
4369 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4370 eap="SIM", identity="1232010000000000",
4371 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581")
4372
4373 with fail_test(dev[0], 1, "os_get_random;eap_sim_init_for_reauth"):
4374 hapd.request("EAPOL_REAUTH " + dev[0].own_addr())
4375 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
4376 if ev is None:
4377 raise Exception("EAP re-authentication did not start")
4378 wait_fail_trigger(dev[0], "GET_FAIL")
4379 dev[0].request("REMOVE_NETWORK all")
4380 dev[0].dump_monitor()
4381
4382 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4383 eap="SIM", identity="1232010000000000",
4384 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581")
4385
4386 with alloc_fail(dev[0], 1, "eap_sim_parse_encr;eap_sim_process_reauthentication"):
4387 hapd.request("EAPOL_REAUTH " + dev[0].own_addr())
4388 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
4389 if ev is None:
4390 raise Exception("EAP re-authentication did not start")
4391 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
4392 dev[0].request("REMOVE_NETWORK all")
4393 dev[0].dump_monitor()
4394
4395 tests = [ (1, "eap_sim_verify_mac;eap_sim_process_challenge"),
4396 (1, "eap_sim_parse_encr;eap_sim_process_challenge"),
4397 (1, "eap_sim_msg_init;eap_sim_response_start"),
4398 (1, "wpabuf_alloc;eap_sim_msg_init;eap_sim_response_start"),
4399 (1, "=eap_sim_learn_ids"),
4400 (2, "=eap_sim_learn_ids"),
4401 (2, "eap_sim_learn_ids"),
4402 (3, "eap_sim_learn_ids"),
4403 (1, "eap_sim_process_start"),
4404 (1, "eap_sim_getKey"),
4405 (1, "eap_sim_get_emsk"),
4406 (1, "eap_sim_get_session_id") ]
4407 for count, func in tests:
4408 with alloc_fail(dev[0], count, func):
4409 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4410 eap="SIM", identity="1232010000000000",
4411 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581",
4412 erp="1", wait_connect=False)
4413 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
4414 dev[0].request("REMOVE_NETWORK all")
4415 dev[0].dump_monitor()
4416
4417 tests = [ (1, "aes_128_cbc_decrypt;eap_sim_parse_encr") ]
4418 for count, func in tests:
4419 with fail_test(dev[0], count, func):
4420 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4421 eap="SIM", identity="1232010000000000",
4422 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581",
4423 wait_connect=False)
4424 wait_fail_trigger(dev[0], "GET_FAIL")
4425 dev[0].request("REMOVE_NETWORK all")
4426 dev[0].dump_monitor()
4427
4428def test_eap_proto_aka_errors(dev, apdev):
4429 """EAP-AKA protocol tests (error paths)"""
4430 check_hlr_auc_gw_support()
4431 params = hostapd.wpa2_eap_params(ssid="eap-test")
4432 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4433
4434 with alloc_fail(dev[0], 1, "eap_aka_init"):
4435 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4436 eap="AKA", identity="0232010000000000",
4437 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123",
4438 wait_connect=False)
4439 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
4440 timeout=15)
4441 if ev is None:
4442 raise Exception("Timeout on EAP start")
4443 dev[0].request("REMOVE_NETWORK all")
4444 dev[0].wait_disconnected()
4445
4446 tests = [ (1, "=eap_aka_learn_ids"),
4447 (2, "=eap_aka_learn_ids"),
4448 (1, "eap_sim_parse_encr;eap_aka_process_challenge"),
4449 (1, "eap_aka_getKey"),
4450 (1, "eap_aka_get_emsk"),
4451 (1, "eap_aka_get_session_id") ]
4452 for count, func in tests:
4453 with alloc_fail(dev[0], count, func):
4454 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4455 eap="AKA", identity="0232010000000000",
4456 password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123",
4457 erp="1", wait_connect=False)
4458 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
4459 dev[0].request("REMOVE_NETWORK all")
4460 dev[0].dump_monitor()
4461
4462def test_eap_proto_aka_prime_errors(dev, apdev):
4463 """EAP-AKA' protocol tests (error paths)"""
4464 check_hlr_auc_gw_support()
4465 params = hostapd.wpa2_eap_params(ssid="eap-test")
4466 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4467
4468 with alloc_fail(dev[0], 1, "eap_aka_init"):
4469 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4470 eap="AKA'", identity="6555444333222111",
4471 password="5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123",
4472 wait_connect=False)
4473 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
4474 timeout=15)
4475 if ev is None:
4476 raise Exception("Timeout on EAP start")
4477 dev[0].request("REMOVE_NETWORK all")
4478 dev[0].wait_disconnected()
4479
4480 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4481 eap="AKA'", identity="6555444333222111",
4482 password="5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123")
4483
4484 with fail_test(dev[0], 1, "aes_128_cbc_encrypt;eap_aka_response_reauth"):
4485 hapd.request("EAPOL_REAUTH " + dev[0].own_addr())
4486 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
4487 if ev is None:
4488 raise Exception("EAP re-authentication did not start")
4489 wait_fail_trigger(dev[0], "GET_FAIL")
4490 dev[0].request("REMOVE_NETWORK all")
4491 dev[0].dump_monitor()
4492
4493 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4494 eap="AKA'", identity="6555444333222111",
4495 password="5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123")
4496
4497 with alloc_fail(dev[0], 1, "eap_sim_parse_encr;eap_aka_process_reauthentication"):
4498 hapd.request("EAPOL_REAUTH " + dev[0].own_addr())
4499 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
4500 if ev is None:
4501 raise Exception("EAP re-authentication did not start")
4502 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
4503 dev[0].request("REMOVE_NETWORK all")
4504 dev[0].dump_monitor()
4505
4506 tests = [ (1, "eap_sim_verify_mac_sha256"),
4507 (1, "=eap_aka_process_challenge") ]
4508 for count, func in tests:
4509 with alloc_fail(dev[0], count, func):
4510 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4511 eap="AKA'", identity="6555444333222111",
4512 password="5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123",
4513 erp="1", wait_connect=False)
4514 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
4515 dev[0].request("REMOVE_NETWORK all")
4516 dev[0].dump_monitor()
4517
cb0555f7
JM
4518def test_eap_proto_ikev2(dev, apdev):
4519 """EAP-IKEv2 protocol tests"""
c8e82c94 4520 check_eap_capa(dev[0], "IKEV2")
cb0555f7
JM
4521 def ikev2_handler(ctx, req):
4522 logger.info("ikev2_handler - RX " + req.encode("hex"))
4523 if 'num' not in ctx:
4524 ctx['num'] = 0
4525 ctx['num'] = ctx['num'] + 1
4526 if 'id' not in ctx:
4527 ctx['id'] = 1
4528 ctx['id'] = (ctx['id'] + 1) % 256
4529
4530 idx = 0
4531
4532 idx += 1
4533 if ctx['num'] == idx:
4534 logger.info("Test: Missing payload")
4535 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
4536 4 + 1,
4537 EAP_TYPE_IKEV2)
4538
4539 idx += 1
4540 if ctx['num'] == idx:
4541 logger.info("Test: Truncated Message Length field")
4542 return struct.pack(">BBHBB3B", EAP_CODE_REQUEST, ctx['id'],
4543 4 + 1 + 1 + 3,
4544 EAP_TYPE_IKEV2, 0x80, 0, 0, 0)
4545
4546 idx += 1
4547 if ctx['num'] == idx:
4548 logger.info("Test: Too short Message Length value")
4549 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'],
4550 4 + 1 + 1 + 4 + 1,
4551 EAP_TYPE_IKEV2, 0x80, 0, 1)
4552
4553 idx += 1
4554 if ctx['num'] == idx:
4555 logger.info("Test: Truncated message")
4556 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'],
4557 4 + 1 + 1 + 4,
4558 EAP_TYPE_IKEV2, 0x80, 1)
4559
4560 idx += 1
4561 if ctx['num'] == idx:
4562 logger.info("Test: Truncated message(2)")
4563 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'],
4564 4 + 1 + 1 + 4,
4565 EAP_TYPE_IKEV2, 0x80, 0xffffffff)
4566
4567 idx += 1
4568 if ctx['num'] == idx:
4569 logger.info("Test: Truncated message(3)")
4570 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'],
4571 4 + 1 + 1 + 4,
4572 EAP_TYPE_IKEV2, 0xc0, 0xffffffff)
4573
4574 idx += 1
4575 if ctx['num'] == idx:
4576 logger.info("Test: Truncated message(4)")
4577 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'],
4578 4 + 1 + 1 + 4,
4579 EAP_TYPE_IKEV2, 0xc0, 10000000)
4580
4581 idx += 1
4582 if ctx['num'] == idx:
4583 logger.info("Test: Too long fragments (first fragment)")
4584 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'],
4585 4 + 1 + 1 + 4 + 1,
4586 EAP_TYPE_IKEV2, 0xc0, 2, 1)
4587
4588 idx += 1
4589 if ctx['num'] == idx:
4590 logger.info("Test: Too long fragments (second fragment)")
4591 return struct.pack(">BBHBB2B", EAP_CODE_REQUEST, ctx['id'],
4592 4 + 1 + 1 + 2,
4593 EAP_TYPE_IKEV2, 0x00, 2, 3)
4594
4595 idx += 1
4596 if ctx['num'] == idx:
4597 logger.info("Test: No Message Length field in first fragment")
4598 return struct.pack(">BBHBBB", EAP_CODE_REQUEST, ctx['id'],
4599 4 + 1 + 1 + 1,
4600 EAP_TYPE_IKEV2, 0x40, 1)
4601
4602 idx += 1
4603 if ctx['num'] == idx:
4604 logger.info("Test: ICV before keys")
4605 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
4606 4 + 1 + 1,
4607 EAP_TYPE_IKEV2, 0x20)
4608
4609 idx += 1
4610 if ctx['num'] == idx:
4611 logger.info("Test: Unsupported IKEv2 header version")
4612 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'],
4613 4 + 1 + 1 + 28,
4614 EAP_TYPE_IKEV2, 0x00,
4615 0, 0, 0, 0,
4616 0, 0, 0, 0, 0, 0)
4617
4618 idx += 1
4619 if ctx['num'] == idx:
4620 logger.info("Test: Incorrect IKEv2 header Length")
4621 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'],
4622 4 + 1 + 1 + 28,
4623 EAP_TYPE_IKEV2, 0x00,
4624 0, 0, 0, 0,
4625 0, 0x20, 0, 0, 0, 0)
4626
4627 idx += 1
4628 if ctx['num'] == idx:
4629 logger.info("Test: Unexpected IKEv2 Exchange Type in SA_INIT state")
4630 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'],
4631 4 + 1 + 1 + 28,
4632 EAP_TYPE_IKEV2, 0x00,
4633 0, 0, 0, 0,
4634 0, 0x20, 0, 0, 0, 28)
4635
4636 idx += 1
4637 if ctx['num'] == idx:
4638 logger.info("Test: Unexpected IKEv2 Message ID in SA_INIT state")
4639 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'],
4640 4 + 1 + 1 + 28,
4641 EAP_TYPE_IKEV2, 0x00,
4642 0, 0, 0, 0,
4643 0, 0x20, 34, 0, 1, 28)
4644
4645 idx += 1
4646 if ctx['num'] == idx:
4647 logger.info("Test: Unexpected IKEv2 Flags value")
4648 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'],
4649 4 + 1 + 1 + 28,
4650 EAP_TYPE_IKEV2, 0x00,
4651 0, 0, 0, 0,
4652 0, 0x20, 34, 0, 0, 28)
4653
4654 idx += 1
4655 if ctx['num'] == idx:
4656 logger.info("Test: Unexpected IKEv2 Flags value(2)")
4657 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'],
4658 4 + 1 + 1 + 28,
4659 EAP_TYPE_IKEV2, 0x00,
4660 0, 0, 0, 0,
4661 0, 0x20, 34, 0x20, 0, 28)
4662
4663 idx += 1
4664 if ctx['num'] == idx:
4665 logger.info("Test: No SAi1 in SA_INIT")
4666 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, ctx['id'],
4667 4 + 1 + 1 + 28,
4668 EAP_TYPE_IKEV2, 0x00,
4669 0, 0, 0, 0,
4670 0, 0x20, 34, 0x08, 0, 28)
4671
4672 def build_ike(id, next=0, exch_type=34, flags=0x00, ike=''):
4673 return struct.pack(">BBHBB2L2LBBBBLL", EAP_CODE_REQUEST, id,
4674 4 + 1 + 1 + 28 + len(ike),
4675 EAP_TYPE_IKEV2, flags,
4676 0, 0, 0, 0,
4677 next, 0x20, exch_type, 0x08, 0,
4678 28 + len(ike)) + ike
4679
4680 idx += 1
4681 if ctx['num'] == idx:
4682 logger.info("Test: Unexpected extra data after payloads")
4683 return build_ike(ctx['id'], ike=struct.pack(">B", 1))
4684
4685 idx += 1
4686 if ctx['num'] == idx:
4687 logger.info("Test: Truncated payload header")
4688 return build_ike(ctx['id'], next=128, ike=struct.pack(">B", 1))
4689
4690 idx += 1
4691 if ctx['num'] == idx:
4692 logger.info("Test: Too small payload header length")
4693 ike = struct.pack(">BBH", 0, 0, 3)
4694 return build_ike(ctx['id'], next=128, ike=ike)
4695
4696 idx += 1
4697 if ctx['num'] == idx:
4698 logger.info("Test: Too large payload header length")
4699 ike = struct.pack(">BBH", 0, 0, 5)
4700 return build_ike(ctx['id'], next=128, ike=ike)
4701
4702 idx += 1
4703 if ctx['num'] == idx:
4704 logger.info("Test: Unsupported payload (non-critical and critical)")
4705 ike = struct.pack(">BBHBBH", 129, 0, 4, 0, 0x01, 4)
4706 return build_ike(ctx['id'], next=128, ike=ike)
4707
4708 idx += 1
4709 if ctx['num'] == idx:
4710 logger.info("Test: Certificate and empty SAi1")
4711 ike = struct.pack(">BBHBBH", 33, 0, 4, 0, 0, 4)
4712 return build_ike(ctx['id'], next=37, ike=ike)
4713
4714 idx += 1
4715 if ctx['num'] == idx:
4716 logger.info("Test: Too short proposal")
4717 ike = struct.pack(">BBHBBHBBB", 0, 0, 4 + 7,
4718 0, 0, 7, 0, 0, 0)
4719 return build_ike(ctx['id'], next=33, ike=ike)
4720
4721 idx += 1
4722 if ctx['num'] == idx:
4723 logger.info("Test: Too small proposal length in SAi1")
4724 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8,
4725 0, 0, 7, 0, 0, 0, 0)
4726 return build_ike(ctx['id'], next=33, ike=ike)
4727
4728 idx += 1
4729 if ctx['num'] == idx:
4730 logger.info("Test: Too large proposal length in SAi1")
4731 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8,
4732 0, 0, 9, 0, 0, 0, 0)
4733 return build_ike(ctx['id'], next=33, ike=ike)
4734
4735 idx += 1
4736 if ctx['num'] == idx:
4737 logger.info("Test: Unexpected proposal type in SAi1")
4738 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8,
4739 1, 0, 8, 0, 0, 0, 0)
4740 return build_ike(ctx['id'], next=33, ike=ike)
4741
4742 idx += 1
4743 if ctx['num'] == idx:
4744 logger.info("Test: Unexpected Protocol ID in SAi1")
4745 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8,
4746 0, 0, 8, 0, 0, 0, 0)
4747 return build_ike(ctx['id'], next=33, ike=ike)
4748
4749 idx += 1
4750 if ctx['num'] == idx:
4751 logger.info("Test: Unexpected proposal number in SAi1")
4752 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8,
4753 0, 0, 8, 0, 1, 0, 0)
4754 return build_ike(ctx['id'], next=33, ike=ike)
4755
4756 idx += 1
4757 if ctx['num'] == idx:
4758 logger.info("Test: Not enough room for SPI in SAi1")
4759 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8,
4760 0, 0, 8, 1, 1, 1, 0)
4761 return build_ike(ctx['id'], next=33, ike=ike)
4762
4763 idx += 1
4764 if ctx['num'] == idx:
4765 logger.info("Test: Unexpected SPI in SAi1")
4766 ike = struct.pack(">BBHBBHBBBBB", 0, 0, 4 + 9,
4767 0, 0, 9, 1, 1, 1, 0, 1)
4768 return build_ike(ctx['id'], next=33, ike=ike)
4769
4770 idx += 1
4771 if ctx['num'] == idx:
4772 logger.info("Test: No transforms in SAi1")
4773 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8,
4774 0, 0, 8, 1, 1, 0, 0)
4775 return build_ike(ctx['id'], next=33, ike=ike)
4776
4777 idx += 1
4778 if ctx['num'] == idx:
4779 logger.info("Test: Too short transform in SAi1")
4780 ike = struct.pack(">BBHBBHBBBB", 0, 0, 4 + 8,
4781 0, 0, 8, 1, 1, 0, 1)
4782 return build_ike(ctx['id'], next=33, ike=ike)
4783
4784 idx += 1
4785 if ctx['num'] == idx:
4786 logger.info("Test: Too small transform length in SAi1")
4787 ike = struct.pack(">BBHBBHBBBBBBHBBH", 0, 0, 4 + 8 + 8,
4788 0, 0, 8 + 8, 1, 1, 0, 1,
4789 0, 0, 7, 0, 0, 0)
4790 return build_ike(ctx['id'], next=33, ike=ike)
4791
4792 idx += 1
4793 if ctx['num'] == idx:
4794 logger.info("Test: Too large transform length in SAi1")
4795 ike = struct.pack(">BBHBBHBBBBBBHBBH", 0, 0, 4 + 8 + 8,
4796 0, 0, 8 + 8, 1, 1, 0, 1,
4797 0, 0, 9, 0, 0, 0)
4798 return build_ike(ctx['id'], next=33, ike=ike)
4799
4800 idx += 1
4801 if ctx['num'] == idx:
4802 logger.info("Test: Unexpected Transform type in SAi1")
4803 ike = struct.pack(">BBHBBHBBBBBBHBBH", 0, 0, 4 + 8 + 8,
4804 0, 0, 8 + 8, 1, 1, 0, 1,
4805 1, 0, 8, 0, 0, 0)
4806 return build_ike(ctx['id'], next=33, ike=ike)
4807
4808 idx += 1
4809 if ctx['num'] == idx:
4810 logger.info("Test: No transform attributes in SAi1")
4811 ike = struct.pack(">BBHBBHBBBBBBHBBH", 0, 0, 4 + 8 + 8,
4812 0, 0, 8 + 8, 1, 1, 0, 1,
4813 0, 0, 8, 0, 0, 0)
4814 return build_ike(ctx['id'], next=33, ike=ike)
4815
4816 idx += 1
4817 if ctx['num'] == idx:
4818 logger.info("Test: No transform attr for AES and unexpected data after transforms in SAi1")
4819 tlen1 = 8 + 3
4820 tlen2 = 8 + 4
4821 tlen3 = 8 + 4
4822 tlen = tlen1 + tlen2 + tlen3
4823 ike = struct.pack(">BBHBBHBBBBBBHBBH3BBBHBBHHHBBHBBHHHB",
4824 0, 0, 4 + 8 + tlen + 1,
4825 0, 0, 8 + tlen + 1, 1, 1, 0, 3,
4826 3, 0, tlen1, 1, 0, 12, 1, 2, 3,
4827 3, 0, tlen2, 1, 0, 12, 0, 128,
4828 0, 0, tlen3, 1, 0, 12, 0x8000 | 14, 127,
4829 1)
4830 return build_ike(ctx['id'], next=33, ike=ike)
4831
4832 def build_sa(next=0):
4833 tlen = 5 * 8
4834 return struct.pack(">BBHBBHBBBBBBHBBHBBHBBHBBHBBHBBHBBHBBHBBH",
4835 next, 0, 4 + 8 + tlen,
4836 0, 0, 8 + tlen, 1, 1, 0, 5,
4837 3, 0, 8, 1, 0, 3,
4838 3, 0, 8, 2, 0, 1,
4839 3, 0, 8, 3, 0, 1,
4840 3, 0, 8, 4, 0, 5,
4841 0, 0, 8, 241, 0, 0)
4842
4843 idx += 1
4844 if ctx['num'] == idx:
4845 logger.info("Test: Valid proposal, but no KEi in SAi1")
4846 ike = build_sa()
4847 return build_ike(ctx['id'], next=33, ike=ike)
4848
4849 idx += 1
4850 if ctx['num'] == idx:
4851 logger.info("Test: Empty KEi in SAi1")
4852 ike = build_sa(next=34) + struct.pack(">BBH", 0, 0, 4)
4853 return build_ike(ctx['id'], next=33, ike=ike)
4854
4855 idx += 1
4856 if ctx['num'] == idx:
4857 logger.info("Test: Mismatch in DH Group in SAi1")
4858 ike = build_sa(next=34)
4859 ike += struct.pack(">BBHHH", 0, 0, 4 + 4 + 96, 12345, 0)
4860 ike += 96*'\x00'
4861 return build_ike(ctx['id'], next=33, ike=ike)
4862 idx += 1
4863 if ctx['num'] == idx:
4864 logger.info("Test: EAP-Failure")
4865 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4866
4867 idx += 1
4868 if ctx['num'] == idx:
4869 logger.info("Test: Invalid DH public value length in SAi1")
4870 ike = build_sa(next=34)
4871 ike += struct.pack(">BBHHH", 0, 0, 4 + 4 + 96, 5, 0)
4872 ike += 96*'\x00'
4873 return build_ike(ctx['id'], next=33, ike=ike)
4874
4875 def build_ke(next=0):
4876 ke = struct.pack(">BBHHH", next, 0, 4 + 4 + 192, 5, 0)
4877 ke += 192*'\x00'
4878 return ke
4879
4880 idx += 1
4881 if ctx['num'] == idx:
4882 logger.info("Test: Valid proposal and KEi, but no Ni in SAi1")
4883 ike = build_sa(next=34)
4884 ike += build_ke()
4885 return build_ike(ctx['id'], next=33, ike=ike)
4886
4887 idx += 1
4888 if ctx['num'] == idx:
4889 logger.info("Test: Too short Ni in SAi1")
4890 ike = build_sa(next=34)
4891 ike += build_ke(next=40)
4892 ike += struct.pack(">BBH", 0, 0, 4)
4893 return build_ike(ctx['id'], next=33, ike=ike)
4894
4895 idx += 1
4896 if ctx['num'] == idx:
4897 logger.info("Test: Too long Ni in SAi1")
4898 ike = build_sa(next=34)
4899 ike += build_ke(next=40)
4900 ike += struct.pack(">BBH", 0, 0, 4 + 257) + 257*'\x00'
4901 return build_ike(ctx['id'], next=33, ike=ike)
4902
4903 def build_ni(next=0):
4904 return struct.pack(">BBH", next, 0, 4 + 256) + 256*'\x00'
4905
4906 def build_sai1(id):
4907 ike = build_sa(next=34)
4908 ike += build_ke(next=40)
4909 ike += build_ni()
4910 return build_ike(ctx['id'], next=33, ike=ike)
4911
4912 idx += 1
4913 if ctx['num'] == idx:
4914 logger.info("Test: Valid proposal, KEi, and Ni in SAi1")
4915 return build_sai1(ctx['id'])
4916 idx += 1
4917 if ctx['num'] == idx:
4918 logger.info("Test: EAP-Failure")
4919 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
4920
4921 idx += 1
4922 if ctx['num'] == idx:
4923 logger.info("Test: Valid proposal, KEi, and Ni in SAi1")
4924 return build_sai1(ctx['id'])
4925 idx += 1
4926 if ctx['num'] == idx:
4927 logger.info("Test: No integrity checksum")
4928 ike = ''
4929 return build_ike(ctx['id'], next=37, ike=ike)
4930
4931 idx += 1
4932 if ctx['num'] == idx:
4933 logger.info("Test: Valid proposal, KEi, and Ni in SAi1")
4934 return build_sai1(ctx['id'])
4935 idx += 1
4936 if ctx['num'] == idx:
4937 logger.info("Test: Truncated integrity checksum")
4938 return struct.pack(">BBHBB",
4939 EAP_CODE_REQUEST, ctx['id'],
4940 4 + 1 + 1,
4941 EAP_TYPE_IKEV2, 0x20)
4942
4943 idx += 1
4944 if ctx['num'] == idx:
4945 logger.info("Test: Valid proposal, KEi, and Ni in SAi1")
4946 return build_sai1(ctx['id'])
4947 idx += 1
4948 if ctx['num'] == idx:
4949 logger.info("Test: Invalid integrity checksum")
4950 ike = ''
4951 return build_ike(ctx['id'], next=37, flags=0x20, ike=ike)
4952
4953 return None
4954
4955 srv = start_radius_server(ikev2_handler)
cb0555f7
JM
4956
4957 try:
4958 hapd = start_ap(apdev[0]['ifname'])
4959
4960 for i in range(49):
4961 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
4962 eap="IKEV2", identity="user",
4963 password="password",
4964 wait_connect=False)
4965 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
4966 timeout=15)
4967 if ev is None:
4968 raise Exception("Timeout on EAP start")
4969 if i in [ 40, 45 ]:
4970 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"],
4971 timeout=10)
4972 if ev is None:
4973 raise Exception("Timeout on EAP failure")
4974 else:
4975 time.sleep(0.05)
4976 dev[0].request("REMOVE_NETWORK all")
4977 finally:
4978 stop_radius_server(srv)
37211e15
JM
4979
4980def NtPasswordHash(password):
4981 pw = password.encode('utf_16_le')
4982 return hashlib.new('md4', pw).digest()
4983
4984def HashNtPasswordHash(password_hash):
4985 return hashlib.new('md4', password_hash).digest()
4986
4987def ChallengeHash(peer_challenge, auth_challenge, username):
4988 data = peer_challenge + auth_challenge + username
4989 return hashlib.sha1(data).digest()[0:8]
4990
4991def GenerateAuthenticatorResponse(password, nt_response, peer_challenge,
4992 auth_challenge, username):
4993 magic1 = binascii.unhexlify("4D616769632073657276657220746F20636C69656E74207369676E696E6720636F6E7374616E74")
4994 magic2 = binascii.unhexlify("50616420746F206D616B6520697420646F206D6F7265207468616E206F6E6520697465726174696F6E")
4995
4996 password_hash = NtPasswordHash(password)
4997 password_hash_hash = HashNtPasswordHash(password_hash)
4998 data = password_hash_hash + nt_response + magic1
4999 digest = hashlib.sha1(data).digest()
5000
5001 challenge = ChallengeHash(peer_challenge, auth_challenge, username)
5002
5003 data = digest + challenge + magic2
5004 resp = hashlib.sha1(data).digest()
5005 return resp
5006
4073ef22
JM
5007def test_eap_proto_ikev2_errors(dev, apdev):
5008 """EAP-IKEv2 local error cases"""
5009 check_eap_capa(dev[0], "IKEV2")
5010 params = hostapd.wpa2_eap_params(ssid="eap-test")
5011 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
5012
5013 for i in range(1, 5):
5014 with alloc_fail(dev[0], i, "eap_ikev2_init"):
5015 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5016 eap="IKEV2", identity="ikev2 user",
5017 password="ike password",
5018 wait_connect=False)
5019 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
5020 timeout=15)
5021 if ev is None:
5022 raise Exception("Timeout on EAP start")
5023 dev[0].request("REMOVE_NETWORK all")
5024 dev[0].wait_disconnected()
5025
5026 tests = [ (1, "ikev2_encr_encrypt"),
5027 (1, "ikev2_encr_decrypt"),
5028 (1, "ikev2_derive_auth_data"),
5029 (2, "ikev2_derive_auth_data"),
5030 (1, "=ikev2_decrypt_payload"),
5031 (1, "ikev2_encr_decrypt;ikev2_decrypt_payload"),
5032 (1, "ikev2_encr_encrypt;ikev2_build_encrypted"),
5033 (1, "ikev2_derive_sk_keys"),
5034 (2, "ikev2_derive_sk_keys"),
5035 (3, "ikev2_derive_sk_keys"),
5036 (4, "ikev2_derive_sk_keys"),
5037 (5, "ikev2_derive_sk_keys"),
5038 (6, "ikev2_derive_sk_keys"),
5039 (7, "ikev2_derive_sk_keys"),
5040 (8, "ikev2_derive_sk_keys"),
5041 (1, "eap_ikev2_derive_keymat;eap_ikev2_peer_keymat"),
5042 (1, "eap_msg_alloc;eap_ikev2_build_msg"),
5043 (1, "eap_ikev2_getKey"),
5044 (1, "eap_ikev2_get_emsk"),
5045 (1, "eap_ikev2_get_session_id"),
5046 (1, "=ikev2_derive_keys"),
5047 (2, "=ikev2_derive_keys"),
5048 (1, "wpabuf_alloc;ikev2_process_kei"),
5049 (1, "=ikev2_process_idi"),
5050 (1, "ikev2_derive_auth_data;ikev2_build_auth"),
5051 (1, "wpabuf_alloc;ikev2_build_sa_init"),
5052 (2, "wpabuf_alloc;ikev2_build_sa_init"),
5053 (3, "wpabuf_alloc;ikev2_build_sa_init"),
5054 (4, "wpabuf_alloc;ikev2_build_sa_init"),
5055 (5, "wpabuf_alloc;ikev2_build_sa_init"),
5056 (6, "wpabuf_alloc;ikev2_build_sa_init"),
5057 (1, "wpabuf_alloc;ikev2_build_sa_auth"),
5058 (2, "wpabuf_alloc;ikev2_build_sa_auth"),
5059 (1, "ikev2_build_auth;ikev2_build_sa_auth") ]
5060 for count, func in tests:
5061 with alloc_fail(dev[0], count, func):
5062 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5063 eap="IKEV2", identity="ikev2 user",
5064 password="ike password", erp="1", wait_connect=False)
5065 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
5066 timeout=15)
5067 if ev is None:
5068 raise Exception("Timeout on EAP start")
5069 ok = False
5070 for j in range(10):
5071 state = dev[0].request('GET_ALLOC_FAIL')
5072 if state.startswith('0:'):
5073 ok = True
5074 break
5075 time.sleep(0.1)
5076 if not ok:
5077 raise Exception("No allocation failure seen for %d:%s" % (count, func))
5078 dev[0].request("REMOVE_NETWORK all")
5079 dev[0].wait_disconnected()
5080
5081 tests = [ (1, "wpabuf_alloc;ikev2_build_notify"),
5082 (2, "wpabuf_alloc;ikev2_build_notify"),
5083 (1, "ikev2_build_encrypted;ikev2_build_notify") ]
5084 for count, func in tests:
5085 with alloc_fail(dev[0], count, func):
5086 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5087 eap="IKEV2", identity="ikev2 user",
5088 password="wrong password", erp="1",
5089 wait_connect=False)
5090 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
5091 timeout=15)
5092 if ev is None:
5093 raise Exception("Timeout on EAP start")
5094 ok = False
5095 for j in range(10):
5096 state = dev[0].request('GET_ALLOC_FAIL')
5097 if state.startswith('0:'):
5098 ok = True
5099 break
5100 time.sleep(0.1)
5101 if not ok:
5102 raise Exception("No allocation failure seen for %d:%s" % (count, func))
5103 dev[0].request("REMOVE_NETWORK all")
5104 dev[0].wait_disconnected()
5105
5106 tests = [ (1, "ikev2_integ_hash"),
5107 (1, "ikev2_integ_hash;ikev2_decrypt_payload"),
5108 (1, "os_get_random;ikev2_build_encrypted"),
5109 (1, "ikev2_prf_plus;ikev2_derive_sk_keys"),
5110 (1, "eap_ikev2_derive_keymat;eap_ikev2_peer_keymat"),
5111 (1, "os_get_random;ikev2_build_sa_init"),
5112 (2, "os_get_random;ikev2_build_sa_init"),
5113 (1, "ikev2_integ_hash;eap_ikev2_validate_icv"),
5114 (1, "hmac_sha1_vector;?ikev2_prf_hash;ikev2_derive_keys"),
5115 (1, "hmac_sha1_vector;?ikev2_prf_hash;ikev2_derive_auth_data"),
5116 (2, "hmac_sha1_vector;?ikev2_prf_hash;ikev2_derive_auth_data"),
5117 (3, "hmac_sha1_vector;?ikev2_prf_hash;ikev2_derive_auth_data") ]
5118 for count, func in tests:
5119 with fail_test(dev[0], count, func):
5120 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5121 eap="IKEV2", identity="ikev2 user",
5122 password="ike password", wait_connect=False)
5123 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
5124 timeout=15)
5125 if ev is None:
5126 raise Exception("Timeout on EAP start")
5127 ok = False
5128 for j in range(10):
5129 state = dev[0].request('GET_FAIL')
5130 if state.startswith('0:'):
5131 ok = True
5132 break
5133 time.sleep(0.1)
5134 if not ok:
5135 raise Exception("No failure seen for %d:%s" % (count, func))
5136 dev[0].request("REMOVE_NETWORK all")
5137 dev[0].wait_disconnected()
5138
5139 params = { "ssid": "eap-test2", "wpa": "2", "wpa_key_mgmt": "WPA-EAP",
5140 "rsn_pairwise": "CCMP", "ieee8021x": "1",
5141 "eap_server": "1", "eap_user_file": "auth_serv/eap_user.conf",
5142 "fragment_size": "50" }
5143 hostapd.add_ap(apdev[1]['ifname'], params)
5144
5145 tests = [ (1, "eap_ikev2_build_frag_ack"),
5146 (1, "wpabuf_alloc;eap_ikev2_process_fragment") ]
5147 for count, func in tests:
5148 with alloc_fail(dev[0], count, func):
5149 dev[0].connect("eap-test2", key_mgmt="WPA-EAP", scan_freq="2412",
5150 eap="IKEV2", identity="ikev2 user",
5151 password="ike password", erp="1", wait_connect=False)
5152 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
5153 timeout=15)
5154 if ev is None:
5155 raise Exception("Timeout on EAP start")
5156 ok = False
5157 for j in range(10):
5158 state = dev[0].request('GET_ALLOC_FAIL')
5159 if state.startswith('0:'):
5160 ok = True
5161 break
5162 time.sleep(0.1)
5163 if not ok:
5164 raise Exception("No allocation failure seen for %d:%s" % (count, func))
5165 dev[0].request("REMOVE_NETWORK all")
5166 dev[0].wait_disconnected()
5167
37211e15
JM
5168def test_eap_proto_mschapv2(dev, apdev):
5169 """EAP-MSCHAPv2 protocol tests"""
5170 check_eap_capa(dev[0], "MSCHAPV2")
5171
5172 def mschapv2_handler(ctx, req):
5173 logger.info("mschapv2_handler - RX " + req.encode("hex"))
5174 if 'num' not in ctx:
5175 ctx['num'] = 0
5176 ctx['num'] = ctx['num'] + 1
5177 if 'id' not in ctx:
5178 ctx['id'] = 1
5179 ctx['id'] = (ctx['id'] + 1) % 256
5180 idx = 0
5181
5182 idx += 1
5183 if ctx['num'] == idx:
5184 logger.info("Test: Missing payload")
5185 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
5186 4 + 1,
5187 EAP_TYPE_MSCHAPV2)
5188
5189 idx += 1
5190 if ctx['num'] == idx:
5191 logger.info("Test: Unknown MSCHAPv2 op_code")
5192 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
5193 4 + 1 + 4 + 1,
5194 EAP_TYPE_MSCHAPV2,
5195 0, 0, 5, 0)
5196
5197 idx += 1
5198 if ctx['num'] == idx:
5199 logger.info("Test: Invalid ms_len and unknown MSCHAPv2 op_code")
5200 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
5201 4 + 1 + 4 + 1,
5202 EAP_TYPE_MSCHAPV2,
5203 255, 0, 0, 0)
5204
5205 idx += 1
5206 if ctx['num'] == idx:
5207 logger.info("Test: Success before challenge")
5208 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
5209 4 + 1 + 4 + 1,
5210 EAP_TYPE_MSCHAPV2,
5211 3, 0, 5, 0)
5212
5213 idx += 1
5214 if ctx['num'] == idx:
5215 logger.info("Test: Failure before challenge - required challenge field not present")
5216 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
5217 4 + 1 + 4 + 1,
5218 EAP_TYPE_MSCHAPV2,
5219 4, 0, 5, 0)
5220 idx += 1
5221 if ctx['num'] == idx:
5222 logger.info("Test: Failure")
5223 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5224
5225 idx += 1
5226 if ctx['num'] == idx:
5227 logger.info("Test: Failure before challenge - invalid failure challenge len")
5228 payload = 'C=12'
5229 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
5230 4 + 1 + 4 + len(payload),
5231 EAP_TYPE_MSCHAPV2,
5232 4, 0, 4 + len(payload)) + payload
5233 idx += 1
5234 if ctx['num'] == idx:
5235 logger.info("Test: Failure")
5236 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5237
5238 idx += 1
5239 if ctx['num'] == idx:
5240 logger.info("Test: Failure before challenge - invalid failure challenge len")
5241 payload = 'C=12 V=3'
5242 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
5243 4 + 1 + 4 + len(payload),
5244 EAP_TYPE_MSCHAPV2,
5245 4, 0, 4 + len(payload)) + payload
5246 idx += 1
5247 if ctx['num'] == idx:
5248 logger.info("Test: Failure")
5249 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5250
5251 idx += 1
5252 if ctx['num'] == idx:
5253 logger.info("Test: Failure before challenge - invalid failure challenge")
5254 payload = 'C=00112233445566778899aabbccddeefQ '
5255 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
5256 4 + 1 + 4 + len(payload),
5257 EAP_TYPE_MSCHAPV2,
5258 4, 0, 4 + len(payload)) + payload
5259 idx += 1
5260 if ctx['num'] == idx:
5261 logger.info("Test: Failure")
5262 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5263
5264 idx += 1
5265 if ctx['num'] == idx:
5266 logger.info("Test: Failure before challenge - password expired")
5267 payload = 'E=648 R=1 C=00112233445566778899aabbccddeeff V=3 M=Password expired'
5268 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
5269 4 + 1 + 4 + len(payload),
5270 EAP_TYPE_MSCHAPV2,
5271 4, 0, 4 + len(payload)) + payload
5272 idx += 1
5273 if ctx['num'] == idx:
5274 logger.info("Test: Success after password change")
5275 payload = "S=1122334455667788990011223344556677889900"
5276 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
5277 4 + 1 + 4 + len(payload),
5278 EAP_TYPE_MSCHAPV2,
5279 3, 0, 4 + len(payload)) + payload
5280
5281 idx += 1
5282 if ctx['num'] == idx:
5283 logger.info("Test: Invalid challenge length")
5284 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
5285 4 + 1 + 4 + 1,
5286 EAP_TYPE_MSCHAPV2,
5287 1, 0, 4 + 1, 0)
5288
5289 idx += 1
5290 if ctx['num'] == idx:
5291 logger.info("Test: Too short challenge packet")
5292 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
5293 4 + 1 + 4 + 1,
5294 EAP_TYPE_MSCHAPV2,
5295 1, 0, 4 + 1, 16)
5296
5297 idx += 1
5298 if ctx['num'] == idx:
5299 logger.info("Test: Challenge")
5300 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
5301 4 + 1 + 4 + 1 + 16 + 6,
5302 EAP_TYPE_MSCHAPV2,
5303 1, 0, 4 + 1 + 16 + 6, 16) + 16*'A' + 'foobar'
5304 idx += 1
5305 if ctx['num'] == idx:
5306 logger.info("Test: Failure - password expired")
5307 payload = 'E=648 R=1 C=00112233445566778899aabbccddeeff V=3 M=Password expired'
5308 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
5309 4 + 1 + 4 + len(payload),
5310 EAP_TYPE_MSCHAPV2,
5311 4, 0, 4 + len(payload)) + payload
5312 idx += 1
5313 if ctx['num'] == idx:
5314 logger.info("Test: Success after password change")
5315 if len(req) != 591:
5316 logger.info("Unexpected Change-Password packet length: %s" % len(req))
5317 return None
5318 data = req[9:]
5319 enc_pw = data[0:516]
5320 data = data[516:]
5321 enc_hash = data[0:16]
5322 data = data[16:]
5323 peer_challenge = data[0:16]
5324 data = data[16:]
5325 # Reserved
5326 data = data[8:]
5327 nt_response = data[0:24]
5328 data = data[24:]
5329 flags = data
5330 logger.info("enc_hash: " + enc_hash.encode("hex"))
5331 logger.info("peer_challenge: " + peer_challenge.encode("hex"))
5332 logger.info("nt_response: " + nt_response.encode("hex"))
5333 logger.info("flags: " + flags.encode("hex"))
5334
5335 auth_challenge = binascii.unhexlify("00112233445566778899aabbccddeeff")
5336 logger.info("auth_challenge: " + auth_challenge.encode("hex"))
5337
5338 auth_resp = GenerateAuthenticatorResponse("new-pw", nt_response,
5339 peer_challenge,
5340 auth_challenge, "user")
5341 payload = "S=" + auth_resp.encode('hex').upper()
5342 logger.info("Success message payload: " + payload)
5343 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
5344 4 + 1 + 4 + len(payload),
5345 EAP_TYPE_MSCHAPV2,
5346 3, 0, 4 + len(payload)) + payload
5347 idx += 1
5348 if ctx['num'] == idx:
5349 logger.info("Test: EAP-Success")
5350 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4)
5351
5352 idx += 1
5353 if ctx['num'] == idx:
5354 logger.info("Test: Failure - password expired")
5355 payload = 'E=648 R=1 C=00112233445566778899aabbccddeeff V=3 M=Password expired'
5356 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
5357 4 + 1 + 4 + len(payload),
5358 EAP_TYPE_MSCHAPV2,
5359 4, 0, 4 + len(payload)) + payload
5360 idx += 1
5361 if ctx['num'] == idx:
5362 logger.info("Test: Success after password change")
5363 if len(req) != 591:
5364 logger.info("Unexpected Change-Password packet length: %s" % len(req))
5365 return None
5366 data = req[9:]
5367 enc_pw = data[0:516]
5368 data = data[516:]
5369 enc_hash = data[0:16]
5370 data = data[16:]
5371 peer_challenge = data[0:16]
5372 data = data[16:]
5373 # Reserved
5374 data = data[8:]
5375 nt_response = data[0:24]
5376 data = data[24:]
5377 flags = data
5378 logger.info("enc_hash: " + enc_hash.encode("hex"))
5379 logger.info("peer_challenge: " + peer_challenge.encode("hex"))
5380 logger.info("nt_response: " + nt_response.encode("hex"))
5381 logger.info("flags: " + flags.encode("hex"))
5382
5383 auth_challenge = binascii.unhexlify("00112233445566778899aabbccddeeff")
5384 logger.info("auth_challenge: " + auth_challenge.encode("hex"))
5385
5386 auth_resp = GenerateAuthenticatorResponse("new-pw", nt_response,
5387 peer_challenge,
5388 auth_challenge, "user")
5389 payload = "S=" + auth_resp.encode('hex').upper()
5390 logger.info("Success message payload: " + payload)
5391 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
5392 4 + 1 + 4 + len(payload),
5393 EAP_TYPE_MSCHAPV2,
5394 3, 0, 4 + len(payload)) + payload
5395 idx += 1
5396 if ctx['num'] == idx:
5397 logger.info("Test: EAP-Success")
5398 return struct.pack(">BBH", EAP_CODE_SUCCESS, ctx['id'], 4)
5399
5400 idx += 1
5401 if ctx['num'] == idx:
5402 logger.info("Test: Challenge")
5403 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
5404 4 + 1 + 4 + 1 + 16 + 6,
5405 EAP_TYPE_MSCHAPV2,
5406 1, 0, 4 + 1 + 16 + 6, 16) + 16*'A' + 'foobar'
5407 idx += 1
5408 if ctx['num'] == idx:
5409 logger.info("Test: Failure - authentication failure")
5410 payload = 'E=691 R=1 C=00112233445566778899aabbccddeeff V=3 M=Authentication failed'
5411 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
5412 4 + 1 + 4 + len(payload),
5413 EAP_TYPE_MSCHAPV2,
5414 4, 0, 4 + len(payload)) + payload
5415
5416 idx += 1
5417 if ctx['num'] == idx:
5418 logger.info("Test: Challenge")
5419 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
5420 4 + 1 + 4 + 1 + 16 + 6,
5421 EAP_TYPE_MSCHAPV2,
5422 1, 0, 4 + 1 + 16 + 6, 16) + 16*'A' + 'foobar'
5423 idx += 1
5424 if ctx['num'] == idx:
5425 logger.info("Test: Failure - authentication failure")
5426 payload = 'E=691 R=1 C=00112233445566778899aabbccddeeff V=3 M=Authentication failed (2)'
5427 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
5428 4 + 1 + 4 + len(payload),
5429 EAP_TYPE_MSCHAPV2,
5430 4, 0, 4 + len(payload)) + payload
5431 idx += 1
5432 if ctx['num'] == idx:
5433 logger.info("Test: Failure")
5434 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5435
5436 return None
5437
5438 srv = start_radius_server(mschapv2_handler)
5439
5440 try:
5441 hapd = start_ap(apdev[0]['ifname'])
5442
5443 for i in range(0, 15):
5444 logger.info("RUN: %d" % i)
5445 if i == 12:
5446 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5447 eap="MSCHAPV2", identity="user",
5448 password_hex="hash:8846f7eaee8fb117ad06bdd830b7586c",
5449 wait_connect=False)
5450 elif i == 14:
5451 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5452 eap="MSCHAPV2", identity="user",
5453 phase2="mschapv2_retry=0",
5454 password="password", wait_connect=False)
5455 else:
5456 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5457 eap="MSCHAPV2", identity="user",
5458 password="password", wait_connect=False)
5459 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=15)
5460 if ev is None:
5461 raise Exception("Timeout on EAP start")
5462
5463 if i in [ 8, 11, 12 ]:
5464 ev = dev[0].wait_event(["CTRL-REQ-NEW_PASSWORD"],
5465 timeout=10)
5466 if ev is None:
5467 raise Exception("Timeout on new password request")
5468 id = ev.split(':')[0].split('-')[-1]
5469 dev[0].request("CTRL-RSP-NEW_PASSWORD-" + id + ":new-pw")
5470 if i in [ 11, 12 ]:
5471 ev = dev[0].wait_event(["CTRL-EVENT-PASSWORD-CHANGED"],
5472 timeout=10)
5473 if ev is None:
5474 raise Exception("Timeout on password change")
5475 ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"],
5476 timeout=10)
5477 if ev is None:
5478 raise Exception("Timeout on EAP success")
5479 else:
5480 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"],
5481 timeout=10)
5482 if ev is None:
5483 raise Exception("Timeout on EAP failure")
5484
5485 if i in [ 13 ]:
5486 ev = dev[0].wait_event(["CTRL-REQ-IDENTITY"],
5487 timeout=10)
5488 if ev is None:
5489 raise Exception("Timeout on identity request")
5490 id = ev.split(':')[0].split('-')[-1]
5491 dev[0].request("CTRL-RSP-IDENTITY-" + id + ":user")
5492
5493 ev = dev[0].wait_event(["CTRL-REQ-PASSWORD"],
5494 timeout=10)
5495 if ev is None:
5496 raise Exception("Timeout on password request")
5497 id = ev.split(':')[0].split('-')[-1]
5498 dev[0].request("CTRL-RSP-PASSWORD-" + id + ":password")
5499
5500 # TODO: Does this work correctly?
5501
5502 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"],
5503 timeout=10)
5504 if ev is None:
5505 raise Exception("Timeout on EAP failure")
5506
5507 if i in [ 4, 5, 6, 7, 14 ]:
5508 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"],
5509 timeout=10)
5510 if ev is None:
5511 raise Exception("Timeout on EAP failure")
5512 else:
5513 time.sleep(0.05)
5514 dev[0].request("REMOVE_NETWORK all")
5515 dev[0].wait_disconnected(timeout=1)
5516 finally:
5517 stop_radius_server(srv)
7c0d66cf
JM
5518
5519def test_eap_proto_mschapv2_errors(dev, apdev):
5520 """EAP-MSCHAPv2 protocol tests (error paths)"""
5521 check_eap_capa(dev[0], "MSCHAPV2")
5522
5523 def mschapv2_handler(ctx, req):
5524 logger.info("mschapv2_handler - RX " + req.encode("hex"))
5525 if 'num' not in ctx:
5526 ctx['num'] = 0
5527 ctx['num'] = ctx['num'] + 1
5528 if 'id' not in ctx:
5529 ctx['id'] = 1
5530 ctx['id'] = (ctx['id'] + 1) % 256
5531 idx = 0
5532
5533 idx += 1
5534 if ctx['num'] == idx:
5535 logger.info("Test: Failure before challenge - password expired")
5536 payload = 'E=648 R=1 C=00112233445566778899aabbccddeeff V=3 M=Password expired'
5537 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
5538 4 + 1 + 4 + len(payload),
5539 EAP_TYPE_MSCHAPV2,
5540 4, 0, 4 + len(payload)) + payload
5541 idx += 1
5542 if ctx['num'] == idx:
5543 logger.info("Test: Success after password change")
5544 payload = "S=1122334455667788990011223344556677889900"
5545 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
5546 4 + 1 + 4 + len(payload),
5547 EAP_TYPE_MSCHAPV2,
5548 3, 0, 4 + len(payload)) + payload
5549
5550 idx += 1
5551 if ctx['num'] == idx:
5552 logger.info("Test: Failure before challenge - password expired")
5553 payload = 'E=648 R=1 C=00112233445566778899aabbccddeeff V=3 M=Password expired'
5554 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
5555 4 + 1 + 4 + len(payload),
5556 EAP_TYPE_MSCHAPV2,
5557 4, 0, 4 + len(payload)) + payload
5558 idx += 1
5559 if ctx['num'] == idx:
5560 logger.info("Test: Success after password change")
5561 payload = "S=1122334455667788990011223344556677889900"
5562 return struct.pack(">BBHBBBH", EAP_CODE_REQUEST, ctx['id'],
5563 4 + 1 + 4 + len(payload),
5564 EAP_TYPE_MSCHAPV2,
5565 3, 0, 4 + len(payload)) + payload
5566
5567 return None
5568
5569 srv = start_radius_server(mschapv2_handler)
5570
5571 try:
5572 hapd = start_ap(apdev[0]['ifname'])
5573
5574 with fail_test(dev[0], 1, "eap_mschapv2_change_password"):
5575 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5576 eap="MSCHAPV2", identity="user",
5577 password="password", wait_connect=False)
5578 ev = dev[0].wait_event(["CTRL-REQ-NEW_PASSWORD"], timeout=10)
5579 if ev is None:
5580 raise Exception("Timeout on new password request")
5581 id = ev.split(':')[0].split('-')[-1]
5582 dev[0].request("CTRL-RSP-NEW_PASSWORD-" + id + ":new-pw")
5583 wait_fail_trigger(dev[0], "GET_FAIL")
5584 dev[0].request("REMOVE_NETWORK all")
5585 dev[0].wait_disconnected(timeout=1)
5586
5587 with fail_test(dev[0], 1, "get_master_key;eap_mschapv2_change_password"):
5588 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5589 eap="MSCHAPV2", identity="user",
5590 password="password", wait_connect=False)
5591 ev = dev[0].wait_event(["CTRL-REQ-NEW_PASSWORD"], timeout=10)
5592 if ev is None:
5593 raise Exception("Timeout on new password request")
5594 id = ev.split(':')[0].split('-')[-1]
5595 dev[0].request("CTRL-RSP-NEW_PASSWORD-" + id + ":new-pw")
5596 wait_fail_trigger(dev[0], "GET_FAIL")
5597 dev[0].request("REMOVE_NETWORK all")
5598 dev[0].wait_disconnected(timeout=1)
5599 finally:
5600 stop_radius_server(srv)
8a848fae
JM
5601
5602def test_eap_proto_pwd(dev, apdev):
5603 """EAP-pwd protocol tests"""
5604 check_eap_capa(dev[0], "PWD")
5605
5606 global eap_proto_pwd_test_done, eap_proto_pwd_test_wait
5607 eap_proto_pwd_test_done = False
5608 eap_proto_pwd_test_wait = False
5609
5610 def pwd_handler(ctx, req):
5611 logger.info("pwd_handler - RX " + req.encode("hex"))
5612 if 'num' not in ctx:
5613 ctx['num'] = 0
5614 ctx['num'] = ctx['num'] + 1
5615 if 'id' not in ctx:
5616 ctx['id'] = 1
5617 ctx['id'] = (ctx['id'] + 1) % 256
5618 idx = 0
5619
5620 global eap_proto_pwd_test_wait
5621 eap_proto_pwd_test_wait = False
5622
5623 idx += 1
5624 if ctx['num'] == idx:
5625 logger.info("Test: Missing payload")
5626 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'], 4 + 1,
5627 EAP_TYPE_PWD)
5628
5629 idx += 1
5630 if ctx['num'] == idx:
5631 logger.info("Test: Missing Total-Length field")
5632 payload = struct.pack("B", 0x80)
5633 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
5634 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
5635
5636 idx += 1
5637 if ctx['num'] == idx:
5638 logger.info("Test: Too large Total-Length")
5639 payload = struct.pack(">BH", 0x80, 65535)
5640 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
5641 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
5642
5643 idx += 1
5644 if ctx['num'] == idx:
5645 eap_proto_pwd_test_wait = True
5646 logger.info("Test: First fragment")
5647 payload = struct.pack(">BH", 0xc0, 10)
5648 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
5649 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
5650 idx += 1
5651 if ctx['num'] == idx:
5652 logger.info("Test: Unexpected Total-Length value in the second fragment")
5653 payload = struct.pack(">BH", 0x80, 0)
5654 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
5655 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
5656
5657 idx += 1
5658 if ctx['num'] == idx:
5659 logger.info("Test: First and only fragment")
5660 payload = struct.pack(">BH", 0x80, 0)
5661 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
5662 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
5663
5664 idx += 1
5665 if ctx['num'] == idx:
5666 logger.info("Test: First and only fragment with extra data")
5667 payload = struct.pack(">BHB", 0x80, 0, 0)
5668 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
5669 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
5670
5671 idx += 1
5672 if ctx['num'] == idx:
5673 eap_proto_pwd_test_wait = True
5674 logger.info("Test: First fragment")
5675 payload = struct.pack(">BHB", 0xc0, 2, 1)
5676 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
5677 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
5678 idx += 1
5679 if ctx['num'] == idx:
5680 logger.info("Test: Extra data in the second fragment")
5681 payload = struct.pack(">BBB", 0x0, 2, 3)
5682 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
5683 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
5684
5685 idx += 1
5686 if ctx['num'] == idx:
5687 logger.info("Test: Too short id exchange")
5688 payload = struct.pack(">B", 0x01)
5689 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
5690 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
5691
5692 idx += 1
5693 if ctx['num'] == idx:
5694 logger.info("Test: Unsupported rand func in id exchange")
5695 payload = struct.pack(">BHBBLB", 0x01, 0, 0, 0, 0, 0)
5696 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
5697 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
5698
5699 idx += 1
5700 if ctx['num'] == idx:
5701 logger.info("Test: Unsupported prf in id exchange")
5702 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 0, 0, 0)
5703 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
5704 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
5705
5706 idx += 1
5707 if ctx['num'] == idx:
5708 logger.info("Test: Unsupported password pre-processing technique in id exchange")
5709 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 255)
5710 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
5711 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
5712
5713 idx += 1
5714 if ctx['num'] == idx:
5715 eap_proto_pwd_test_wait = True
5716 logger.info("Test: Valid id exchange")
5717 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0)
5718 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
5719 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
5720 idx += 1
5721 if ctx['num'] == idx:
5722 logger.info("Test: Unexpected id exchange")
5723 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0)
5724 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
5725 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
5726
5727 idx += 1
5728 if ctx['num'] == idx:
5729 logger.info("Test: Unexpected commit exchange")
5730 payload = struct.pack(">B", 0x02)
5731 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
5732 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
5733
5734 idx += 1
5735 if ctx['num'] == idx:
5736 eap_proto_pwd_test_wait = True
5737 logger.info("Test: Valid id exchange")
5738 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0)
5739 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
5740 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
5741 idx += 1
5742 if ctx['num'] == idx:
5743 logger.info("Test: Unexpected Commit payload length")
5744 payload = struct.pack(">B", 0x02)
5745 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
5746 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
5747
5748 idx += 1
5749 if ctx['num'] == idx:
5750 eap_proto_pwd_test_wait = True
5751 logger.info("Test: Valid id exchange")
5752 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0)
5753 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
5754 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
5755 idx += 1
5756 if ctx['num'] == idx:
5757 logger.info("Test: Commit payload with all zeros values --> Shared key at infinity")
5758 payload = struct.pack(">B", 0x02) + 96*'\0'
5759 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
5760 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
5761
5762 idx += 1
5763 if ctx['num'] == idx:
5764 eap_proto_pwd_test_wait = True
5765 logger.info("Test: Valid id exchange")
5766 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0)
5767 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
5768 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
5769 idx += 1
5770 if ctx['num'] == idx:
5771 eap_proto_pwd_test_wait = True
5772 logger.info("Test: Commit payload with valid values")
5773 element = binascii.unhexlify("8dcab2862c5396839a6bac0c689ff03d962863108e7c275bbf1d6eedf634ee832a214db99f0d0a1a6317733eecdd97f0fc4cda19f57e1bb9bb9c8dcf8c60ba6f")
5774 scalar = binascii.unhexlify("450f31e058cf2ac2636a5d6e2b3c70b1fcc301957f0716e77f13aa69f9a2e5bd")
5775 payload = struct.pack(">B", 0x02) + element + scalar
5776 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
5777 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
5778 idx += 1
5779 if ctx['num'] == idx:
5780 logger.info("Test: Unexpected Confirm payload length 0")
5781 payload = struct.pack(">B", 0x03)
5782 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
5783 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
5784
5785 idx += 1
5786 if ctx['num'] == idx:
5787 eap_proto_pwd_test_wait = True
5788 logger.info("Test: Valid id exchange")
5789 payload = struct.pack(">BHBBLB", 0x01, 19, 1, 1, 0, 0)
5790 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
5791 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
5792 idx += 1
5793 if ctx['num'] == idx:
5794 eap_proto_pwd_test_wait = True
5795 logger.info("Test: Commit payload with valid values")
5796 element = binascii.unhexlify("8dcab2862c5396839a6bac0c689ff03d962863108e7c275bbf1d6eedf634ee832a214db99f0d0a1a6317733eecdd97f0fc4cda19f57e1bb9bb9c8dcf8c60ba6f")
5797 scalar = binascii.unhexlify("450f31e058cf2ac2636a5d6e2b3c70b1fcc301957f0716e77f13aa69f9a2e5bd")
5798 payload = struct.pack(">B", 0x02) + element + scalar
5799 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
5800 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
5801 idx += 1
5802 if ctx['num'] == idx:
5803 logger.info("Test: Confirm payload with incorrect value")
5804 payload = struct.pack(">B", 0x03) + 32*'\0'
5805 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
5806 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
5807
5808 idx += 1
5809 if ctx['num'] == idx:
5810 logger.info("Test: Unexpected confirm exchange")
5811 payload = struct.pack(">B", 0x03)
5812 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
5813 4 + 1 + len(payload), EAP_TYPE_PWD) + payload
5814
5815 logger.info("No more test responses available - test case completed")
5816 global eap_proto_pwd_test_done
5817 eap_proto_pwd_test_done = True
5818 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
5819
5820 srv = start_radius_server(pwd_handler)
5821
5822 try:
5823 hapd = start_ap(apdev[0]['ifname'])
5824
5825 i = 0
5826 while not eap_proto_pwd_test_done:
5827 i += 1
5828 logger.info("Running connection iteration %d" % i)
5829 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5830 eap="PWD", identity="pwd user",
5831 password="secret password",
5832 wait_connect=False)
5833 ok = False
5834 for j in range(5):
5835 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STATUS",
5836 "CTRL-EVENT-EAP-PROPOSED-METHOD"],
5837 timeout=5)
5838 if ev is None:
5839 raise Exception("Timeout on EAP start")
5840 if "CTRL-EVENT-EAP-PROPOSED-METHOD" in ev:
5841 ok = True
5842 break
5843 if "CTRL-EVENT-EAP-STATUS" in ev and "status='completion' parameter='failure'" in ev:
5844 ok = True
5845 break
5846 if not ok:
5847 raise Exception("Expected EAP event not seen")
5848 if eap_proto_pwd_test_wait:
5849 for k in range(10):
5850 time.sleep(0.1)
5851 if not eap_proto_pwd_test_wait:
5852 break
5853 dev[0].request("REMOVE_NETWORK all")
5854 dev[0].wait_disconnected(timeout=1)
5855 dev[0].dump_monitor()
5856 finally:
5857 stop_radius_server(srv)
fe5aa8cb
JM
5858
5859def test_eap_proto_pwd_errors(dev, apdev):
5860 """EAP-pwd local error cases"""
5861 check_eap_capa(dev[0], "PWD")
5862 params = hostapd.wpa2_eap_params(ssid="eap-test")
5863 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
5864
5865 for i in range(1, 4):
5866 with alloc_fail(dev[0], i, "eap_pwd_init"):
5867 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5868 eap="PWD", identity="pwd user",
5869 password="secret password",
5870 wait_connect=False)
5871 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
5872 timeout=15)
5873 if ev is None:
5874 raise Exception("Timeout on EAP start")
5875 dev[0].request("REMOVE_NETWORK all")
5876 dev[0].wait_disconnected()
5877
5878 with alloc_fail(dev[0], 1, "eap_pwd_get_session_id"):
5879 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5880 eap="PWD", identity="pwd user",
5881 password="secret password")
5882 dev[0].request("REMOVE_NETWORK all")
5883 dev[0].wait_disconnected()
5884
5885 for i in range(1, 7):
5886 with alloc_fail(dev[0], i, "eap_pwd_perform_id_exchange"):
5887 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5888 eap="PWD", identity="pwd user",
5889 password="secret password",
5890 wait_connect=False)
5891 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
5892 timeout=15)
5893 if ev is None:
5894 raise Exception("Timeout on EAP start")
5895 ok = False
5896 for j in range(10):
5897 state = dev[0].request('GET_ALLOC_FAIL')
5898 if state.startswith('0:'):
5899 ok = True
5900 break
5901 time.sleep(0.1)
5902 if not ok:
5903 raise Exception("No allocation failure seen")
5904 dev[0].request("REMOVE_NETWORK all")
5905 dev[0].wait_disconnected()
5906
5907 with alloc_fail(dev[0], 1, "wpabuf_alloc;eap_pwd_perform_id_exchange"):
5908 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5909 eap="PWD", identity="pwd user",
5910 password="secret password",
5911 wait_connect=False)
5912 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
5913 timeout=15)
5914 if ev is None:
5915 raise Exception("Timeout on EAP start")
5916 dev[0].request("REMOVE_NETWORK all")
5917 dev[0].wait_disconnected()
5918
5919 for i in range(1, 4):
5920 with alloc_fail(dev[0], i, "eap_pwd_perform_commit_exchange"):
5921 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5922 eap="PWD", identity="pwd user",
5923 password="secret password",
5924 wait_connect=False)
5925 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
5926 timeout=15)
5927 if ev is None:
5928 raise Exception("Timeout on EAP start")
5929 ok = False
5930 for j in range(10):
5931 state = dev[0].request('GET_ALLOC_FAIL')
5932 if state.startswith('0:'):
5933 ok = True
5934 break
5935 time.sleep(0.1)
5936 if not ok:
5937 raise Exception("No allocation failure seen")
5938 dev[0].request("REMOVE_NETWORK all")
5939 dev[0].wait_disconnected()
5940
5941 for i in range(1, 12):
5942 with alloc_fail(dev[0], i, "eap_pwd_perform_confirm_exchange"):
5943 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5944 eap="PWD", identity="pwd user",
5945 password="secret password",
5946 wait_connect=False)
5947 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
5948 timeout=15)
5949 if ev is None:
5950 raise Exception("Timeout on EAP start")
5951 ok = False
5952 for j in range(10):
5953 state = dev[0].request('GET_ALLOC_FAIL')
5954 if state.startswith('0:'):
5955 ok = True
5956 break
5957 time.sleep(0.1)
5958 if not ok:
5959 raise Exception("No allocation failure seen")
5960 dev[0].request("REMOVE_NETWORK all")
5961 dev[0].wait_disconnected()
5962
5963 for i in range(1, 4):
5964 with alloc_fail(dev[0], i, "eap_msg_alloc;=eap_pwd_process"):
5965 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5966 eap="PWD", identity="pwd user",
5967 password="secret password",
5968 wait_connect=False)
5969 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
5970 timeout=15)
5971 if ev is None:
5972 raise Exception("Timeout on EAP start")
5973 ok = False
5974 for j in range(10):
5975 state = dev[0].request('GET_ALLOC_FAIL')
5976 if state.startswith('0:'):
5977 ok = True
5978 break
5979 time.sleep(0.1)
5980 if not ok:
5981 raise Exception("No allocation failure seen")
5982 dev[0].request("REMOVE_NETWORK all")
5983 dev[0].wait_disconnected()
5984
5985 # No password configured
5986 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
5987 eap="PWD", identity="pwd user",
5988 wait_connect=False)
5989 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD vendor=0 method=52"],
5990 timeout=15)
5991 if ev is None:
5992 raise Exception("EAP-pwd not started")
5993 dev[0].request("REMOVE_NETWORK all")
5994 dev[0].wait_disconnected()
b6f17f2f
JM
5995
5996def test_eap_proto_erp(dev, apdev):
5997 """ERP protocol tests"""
5998 check_erp_capa(dev[0])
5999
6000 global eap_proto_erp_test_done
6001 eap_proto_erp_test_done = False
6002
6003 def erp_handler(ctx, req):
6004 logger.info("erp_handler - RX " + req.encode("hex"))
6005 if 'num' not in ctx:
6006 ctx['num'] = 0
6007 ctx['num'] += 1
6008 if 'id' not in ctx:
6009 ctx['id'] = 1
6010 ctx['id'] = (ctx['id'] + 1) % 256
6011 idx = 0
6012
6013 idx += 1
6014 if ctx['num'] == idx:
6015 logger.info("Test: Missing type")
6016 return struct.pack(">BBH", EAP_CODE_INITIATE, ctx['id'], 4)
6017
6018 idx += 1
6019 if ctx['num'] == idx:
6020 logger.info("Test: Unexpected type")
6021 return struct.pack(">BBHB", EAP_CODE_INITIATE, ctx['id'], 4 + 1,
6022 255)
6023
6024 idx += 1
6025 if ctx['num'] == idx:
6026 logger.info("Test: Missing Reserved field")
6027 return struct.pack(">BBHB", EAP_CODE_INITIATE, ctx['id'], 4 + 1,
6028 EAP_ERP_TYPE_REAUTH_START)
6029
6030 idx += 1
6031 if ctx['num'] == idx:
6032 logger.info("Test: Zero-length TVs/TLVs")
6033 payload = ""
6034 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'],
6035 4 + 1 + 1 + len(payload),
6036 EAP_ERP_TYPE_REAUTH_START, 0) + payload
6037
6038 idx += 1
6039 if ctx['num'] == idx:
6040 logger.info("Test: Too short TLV")
6041 payload = struct.pack("B", 191)
6042 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'],
6043 4 + 1 + 1 + len(payload),
6044 EAP_ERP_TYPE_REAUTH_START, 0) + payload
6045
6046 idx += 1
6047 if ctx['num'] == idx:
6048 logger.info("Test: Truncated TLV")
6049 payload = struct.pack("BB", 191, 1)
6050 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'],
6051 4 + 1 + 1 + len(payload),
6052 EAP_ERP_TYPE_REAUTH_START, 0) + payload
6053
6054 idx += 1
6055 if ctx['num'] == idx:
6056 logger.info("Test: Ignored unknown TLV and unknown TV/TLV terminating parsing")
6057 payload = struct.pack("BBB", 191, 0, 192)
6058 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'],
6059 4 + 1 + 1 + len(payload),
6060 EAP_ERP_TYPE_REAUTH_START, 0) + payload
6061
6062 idx += 1
6063 if ctx['num'] == idx:
6064 logger.info("Test: More than one keyName-NAI")
6065 payload = struct.pack("BBBB", EAP_ERP_TLV_KEYNAME_NAI, 0,
6066 EAP_ERP_TLV_KEYNAME_NAI, 0)
6067 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'],
6068 4 + 1 + 1 + len(payload),
6069 EAP_ERP_TYPE_REAUTH_START, 0) + payload
6070
6071 idx += 1
6072 if ctx['num'] == idx:
6073 logger.info("Test: Too short TLV keyName-NAI")
6074 payload = struct.pack("B", EAP_ERP_TLV_KEYNAME_NAI)
6075 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'],
6076 4 + 1 + 1 + len(payload),
6077 EAP_ERP_TYPE_REAUTH_START, 0) + payload
6078
6079 idx += 1
6080 if ctx['num'] == idx:
6081 logger.info("Test: Truncated TLV keyName-NAI")
6082 payload = struct.pack("BB", EAP_ERP_TLV_KEYNAME_NAI, 1)
6083 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'],
6084 4 + 1 + 1 + len(payload),
6085 EAP_ERP_TYPE_REAUTH_START, 0) + payload
6086
6087 idx += 1
6088 if ctx['num'] == idx:
6089 logger.info("Test: Valid rRK lifetime TV followed by too short rMSK lifetime TV")
6090 payload = struct.pack(">BLBH", EAP_ERP_TV_RRK_LIFETIME, 0,
6091 EAP_ERP_TV_RMSK_LIFETIME, 0)
6092 return struct.pack(">BBHBB", EAP_CODE_INITIATE, ctx['id'],
6093 4 + 1 + 1 + len(payload),
6094 EAP_ERP_TYPE_REAUTH_START, 0) + payload
6095
6096 idx += 1
6097 if ctx['num'] == idx:
6098 logger.info("Test: Missing type (Finish)")
6099 return struct.pack(">BBH", EAP_CODE_FINISH, ctx['id'], 4)
6100
6101 idx += 1
6102 if ctx['num'] == idx:
6103 logger.info("Test: Unexpected type (Finish)")
6104 return struct.pack(">BBHB", EAP_CODE_FINISH, ctx['id'], 4 + 1,
6105 255)
6106
6107 idx += 1
6108 if ctx['num'] == idx:
6109 logger.info("Test: Missing fields (Finish)")
6110 return struct.pack(">BBHB", EAP_CODE_FINISH, ctx['id'], 4 + 1,
6111 EAP_ERP_TYPE_REAUTH)
6112
6113 idx += 1
6114 if ctx['num'] == idx:
6115 logger.info("Test: Unexpected SEQ (Finish)")
6116 return struct.pack(">BBHBBHB", EAP_CODE_FINISH, ctx['id'],
6117 4 + 1 + 4,
6118 EAP_ERP_TYPE_REAUTH, 0, 0xffff, 0)
6119
6120 logger.info("No more test responses available - test case completed")
6121 global eap_proto_erp_test_done
6122 eap_proto_erp_test_done = True
6123 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6124
6125 srv = start_radius_server(erp_handler)
6126
6127 try:
6128 hapd = start_ap(apdev[0]['ifname'])
6129
6130 i = 0
6131 while not eap_proto_erp_test_done:
6132 i += 1
6133 logger.info("Running connection iteration %d" % i)
6134 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6135 eap="PAX", identity="pax.user@example.com",
6136 password_hex="0123456789abcdef0123456789abcdef",
6137 wait_connect=False)
6138 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
6139 if ev is None:
6140 raise Exception("Timeout on EAP start")
6141 time.sleep(0.1)
6142 dev[0].request("REMOVE_NETWORK all")
6143 dev[0].wait_disconnected(timeout=1)
6144 dev[0].dump_monitor()
6145 finally:
6146 stop_radius_server(srv)
5b7784a8
JM
6147
6148def test_eap_proto_fast_errors(dev, apdev):
6149 """EAP-FAST local error cases"""
6150 check_eap_capa(dev[0], "FAST")
6151 params = hostapd.wpa2_eap_params(ssid="eap-test")
6152 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
6153
6154 for i in range(1, 5):
6155 with alloc_fail(dev[0], i, "eap_fast_init"):
6156 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6157 eap="FAST", anonymous_identity="FAST",
6158 identity="user", password="password",
6159 ca_cert="auth_serv/ca.pem", phase2="auth=GTC",
6160 phase1="fast_provisioning=2",
6161 pac_file="blob://fast_pac_auth",
6162 wait_connect=False)
6163 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
6164 timeout=5)
6165 if ev is None:
6166 raise Exception("Timeout on EAP start")
6167 dev[0].request("REMOVE_NETWORK all")
6168 dev[0].wait_disconnected()
6169
6170 tests = [ (1, "wpabuf_alloc;eap_fast_tlv_eap_payload"),
6171 (1, "eap_fast_derive_key;eap_fast_derive_key_auth"),
6172 (1, "eap_msg_alloc;eap_peer_tls_phase2_nak"),
6173 (1, "wpabuf_alloc;eap_fast_tlv_result"),
6174 (1, "wpabuf_alloc;eap_fast_tlv_pac_ack"),
6175 (1, "=eap_peer_tls_derive_session_id;eap_fast_process_crypto_binding"),
6176 (1, "eap_peer_tls_decrypt;eap_fast_decrypt"),
6177 (1, "eap_fast_getKey"),
6178 (1, "eap_fast_get_session_id"),
6179 (1, "eap_fast_get_emsk") ]
6180 for count, func in tests:
6181 dev[0].request("SET blob fast_pac_auth_errors ")
6182 with alloc_fail(dev[0], count, func):
6183 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6184 eap="FAST", anonymous_identity="FAST",
6185 identity="user", password="password",
6186 ca_cert="auth_serv/ca.pem", phase2="auth=GTC",
6187 phase1="fast_provisioning=2",
6188 pac_file="blob://fast_pac_auth_errors",
6189 erp="1",
6190 wait_connect=False)
6191 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
6192 timeout=15)
6193 if ev is None:
6194 raise Exception("Timeout on EAP start")
6195 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
6196 dev[0].request("REMOVE_NETWORK all")
6197 dev[0].wait_disconnected()
6198
6199 tests = [ (1, "eap_fast_derive_key;eap_fast_derive_key_provisioning"),
6200 (1, "eap_mschapv2_getKey;eap_fast_get_phase2_key"),
6201 (1, "=eap_fast_use_pac_opaque"),
6202 (1, "eap_fast_copy_buf"),
6203 (1, "=eap_fast_add_pac"),
6204 (1, "=eap_fast_init_pac_data"),
6205 (1, "=eap_fast_write_pac"),
6206 (2, "=eap_fast_write_pac") ]
6207 for count, func in tests:
6208 dev[0].request("SET blob fast_pac_errors ")
6209 with alloc_fail(dev[0], count, func):
6210 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6211 eap="FAST", anonymous_identity="FAST",
6212 identity="user", password="password",
6213 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
6214 phase1="fast_provisioning=1",
6215 pac_file="blob://fast_pac_errors",
6216 erp="1",
6217 wait_connect=False)
6218 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
6219 timeout=15)
6220 if ev is None:
6221 raise Exception("Timeout on EAP start")
6222 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
6223 dev[0].request("REMOVE_NETWORK all")
6224 dev[0].wait_disconnected()
6225
6226 tests = [ (1, "eap_fast_get_cmk;eap_fast_process_crypto_binding"),
6227 (1, "eap_fast_derive_eap_msk;eap_fast_process_crypto_binding"),
6228 (1, "eap_fast_derive_eap_emsk;eap_fast_process_crypto_binding") ]
6229 for count, func in tests:
6230 dev[0].request("SET blob fast_pac_auth_errors ")
6231 with fail_test(dev[0], count, func):
6232 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6233 eap="FAST", anonymous_identity="FAST",
6234 identity="user", password="password",
6235 ca_cert="auth_serv/ca.pem", phase2="auth=GTC",
6236 phase1="fast_provisioning=2",
6237 pac_file="blob://fast_pac_auth_errors",
6238 erp="1",
6239 wait_connect=False)
6240 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
6241 timeout=15)
6242 if ev is None:
6243 raise Exception("Timeout on EAP start")
6244 wait_fail_trigger(dev[0], "GET_FAIL")
6245 dev[0].request("REMOVE_NETWORK all")
6246 dev[0].wait_disconnected()
6247
6248 dev[0].request("SET blob fast_pac_errors ")
6249 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6250 eap="FAST", anonymous_identity="FAST",
6251 identity="user", password="password",
6252 ca_cert="auth_serv/ca.pem", phase2="auth=GTC",
6253 phase1="fast_provisioning=1",
6254 pac_file="blob://fast_pac_errors",
6255 wait_connect=False)
6256 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5)
6257 if ev is None:
6258 raise Exception("Timeout on EAP start")
6259 # EAP-FAST: Only EAP-MSCHAPv2 is allowed during unauthenticated
6260 # provisioning; reject phase2 type 6
6261 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
6262 if ev is None:
6263 raise Exception("Timeout on EAP failure")
6264 dev[0].request("REMOVE_NETWORK all")
6265 dev[0].wait_disconnected()
6266
6267 logger.info("Wrong password in Phase 2")
6268 dev[0].request("SET blob fast_pac_errors ")
6269 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6270 eap="FAST", anonymous_identity="FAST",
6271 identity="user", password="wrong password",
6272 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
6273 phase1="fast_provisioning=1",
6274 pac_file="blob://fast_pac_errors",
6275 wait_connect=False)
6276 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5)
6277 if ev is None:
6278 raise Exception("Timeout on EAP start")
6279 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
6280 if ev is None:
6281 raise Exception("Timeout on EAP failure")
6282 dev[0].request("REMOVE_NETWORK all")
6283 dev[0].wait_disconnected()
6284
6285 tests = [ "FOOBAR\n",
6286 "wpa_supplicant EAP-FAST PAC file - version 1\nFOOBAR\n",
6287 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\n",
6288 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nSTART\n",
6289 "wpa_supplicant EAP-FAST PAC file - version 1\nEND\n",
6290 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nPAC-Type=12345\nEND\n"
6291 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nPAC-Key=12\nEND\n",
6292 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nPAC-Key=1\nEND\n",
6293 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nPAC-Key=1q\nEND\n",
6294 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nPAC-Opaque=1\nEND\n",
6295 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nA-ID=1\nEND\n",
6296 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nI-ID=1\nEND\n",
6297 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nA-ID-Info=1\nEND\n" ]
6298 for pac in tests:
6299 blob = binascii.hexlify(pac)
6300 dev[0].request("SET blob fast_pac_errors " + blob)
6301 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6302 eap="FAST", anonymous_identity="FAST",
6303 identity="user", password="password",
6304 ca_cert="auth_serv/ca.pem", phase2="auth=GTC",
6305 phase1="fast_provisioning=2",
6306 pac_file="blob://fast_pac_errors",
6307 wait_connect=False)
6308 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
6309 timeout=5)
6310 if ev is None:
6311 raise Exception("Timeout on EAP start")
6312 dev[0].request("REMOVE_NETWORK all")
6313 dev[0].wait_disconnected()
6314
6315 tests = [ "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nEND\n",
6316 "wpa_supplicant EAP-FAST PAC file - version 1\nSTART\nEND\nSTART\nEND\nSTART\nEND\n" ]
6317 for pac in tests:
6318 blob = binascii.hexlify(pac)
6319 dev[0].request("SET blob fast_pac_errors " + blob)
6320 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6321 eap="FAST", anonymous_identity="FAST",
6322 identity="user", password="password",
6323 ca_cert="auth_serv/ca.pem", phase2="auth=GTC",
6324 phase1="fast_provisioning=2",
6325 pac_file="blob://fast_pac_errors")
6326 dev[0].request("REMOVE_NETWORK all")
6327 dev[0].wait_disconnected()
6328
6329 dev[0].request("SET blob fast_pac_errors ")
a551da6a
JM
6330
6331def test_eap_proto_peap_errors(dev, apdev):
6332 """EAP-PEAP local error cases"""
6333 check_eap_capa(dev[0], "PEAP")
6334 check_eap_capa(dev[0], "MSCHAPV2")
6335 params = hostapd.wpa2_eap_params(ssid="eap-test")
6336 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
6337
6338 for i in range(1, 5):
6339 with alloc_fail(dev[0], i, "eap_peap_init"):
6340 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6341 eap="PEAP", anonymous_identity="peap",
6342 identity="user", password="password",
6343 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
6344 wait_connect=False)
6345 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
6346 timeout=5)
6347 if ev is None:
6348 raise Exception("Timeout on EAP start")
6349 dev[0].request("REMOVE_NETWORK all")
6350 dev[0].wait_disconnected()
6351
6352 tests = [ (1, "eap_mschapv2_getKey;eap_peap_get_isk;eap_peap_derive_cmk"),
6353 (1, "eap_msg_alloc;eap_tlv_build_result"),
6354 (1, "eap_mschapv2_init;eap_peap_phase2_request"),
6355 (1, "eap_peer_tls_decrypt;eap_peap_decrypt"),
6356 (1, "wpabuf_alloc;=eap_peap_decrypt"),
6357 (1, "eap_peer_tls_encrypt;eap_peap_decrypt"),
6358 (1, "eap_peer_tls_process_helper;eap_peap_process"),
6359 (1, "eap_peer_tls_derive_key;eap_peap_process"),
6360 (1, "eap_peer_tls_derive_session_id;eap_peap_process"),
6361 (1, "eap_peap_getKey"),
6362 (1, "eap_peap_get_session_id") ]
6363 for count, func in tests:
6364 with alloc_fail(dev[0], count, func):
6365 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6366 eap="PEAP", anonymous_identity="peap",
6367 identity="user", password="password",
6368 phase1="peapver=0 crypto_binding=2",
6369 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
6370 erp="1", wait_connect=False)
6371 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
6372 timeout=15)
6373 if ev is None:
6374 raise Exception("Timeout on EAP start")
6375 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
6376 dev[0].request("REMOVE_NETWORK all")
6377 dev[0].wait_disconnected()
6378
6379 tests = [ (1, "peap_prfplus;eap_peap_derive_cmk"),
6380 (1, "eap_tlv_add_cryptobinding;eap_tlv_build_result"),
6381 (1, "peap_prfplus;eap_peap_getKey") ]
6382 for count, func in tests:
6383 with fail_test(dev[0], count, func):
6384 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6385 eap="PEAP", anonymous_identity="peap",
6386 identity="user", password="password",
6387 phase1="peapver=0 crypto_binding=2",
6388 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
6389 erp="1", wait_connect=False)
6390 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
6391 timeout=15)
6392 if ev is None:
6393 raise Exception("Timeout on EAP start")
6394 wait_fail_trigger(dev[0], "GET_FAIL")
6395 dev[0].request("REMOVE_NETWORK all")
6396 dev[0].wait_disconnected()
6397
6398 with alloc_fail(dev[0], 1,
6399 "eap_peer_tls_phase2_nak;eap_peap_phase2_request"):
6400 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6401 eap="PEAP", anonymous_identity="peap",
6402 identity="cert user", password="password",
6403 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
6404 wait_connect=False)
6405 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
6406 dev[0].request("REMOVE_NETWORK all")
6407 dev[0].wait_disconnected()
c44e4994
JM
6408
6409def test_eap_proto_ttls_errors(dev, apdev):
6410 """EAP-TTLS local error cases"""
6411 check_eap_capa(dev[0], "TTLS")
6412 check_eap_capa(dev[0], "MSCHAPV2")
6413 params = hostapd.wpa2_eap_params(ssid="eap-test")
6414 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
6415
6416 for i in range(1, 5):
6417 with alloc_fail(dev[0], i, "eap_ttls_init"):
6418 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6419 eap="TTLS", anonymous_identity="ttls",
6420 identity="user", password="password",
6421 ca_cert="auth_serv/ca.pem",
6422 phase2="autheap=MSCHAPV2",
6423 wait_connect=False)
6424 ev = dev[0].wait_event(["EAP: Failed to initialize EAP method"],
6425 timeout=5)
6426 if ev is None:
6427 raise Exception("Timeout on EAP start")
6428 dev[0].request("REMOVE_NETWORK all")
6429 dev[0].wait_disconnected()
6430
6431 tests = [ (1, "eap_peer_tls_derive_key;eap_ttls_v0_derive_key",
6432 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"),
6433 (1, "eap_peer_tls_derive_session_id;eap_ttls_v0_derive_key",
6434 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"),
6435 (1, "wpabuf_alloc;eap_ttls_phase2_request_mschapv2",
6436 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"),
6437 (1, "eap_peer_tls_derive_key;eap_ttls_phase2_request_mschapv2",
6438 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"),
6439 (1, "eap_peer_tls_encrypt;eap_ttls_encrypt_response;eap_ttls_implicit_identity_request",
6440 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"),
6441 (1, "eap_peer_tls_decrypt;eap_ttls_decrypt",
6442 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"),
6443 (1, "eap_ttls_getKey",
6444 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"),
6445 (1, "eap_ttls_get_session_id",
6446 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"),
6447 (1, "eap_ttls_get_emsk",
6448 "DOMAIN\mschapv2 user", "auth=MSCHAPV2"),
6449 (1, "wpabuf_alloc;eap_ttls_phase2_request_mschap",
6450 "mschap user", "auth=MSCHAP"),
6451 (1, "eap_peer_tls_derive_key;eap_ttls_phase2_request_mschap",
6452 "mschap user", "auth=MSCHAP"),
6453 (1, "wpabuf_alloc;eap_ttls_phase2_request_chap",
6454 "chap user", "auth=CHAP"),
6455 (1, "eap_peer_tls_derive_key;eap_ttls_phase2_request_chap",
6456 "chap user", "auth=CHAP"),
6457 (1, "wpabuf_alloc;eap_ttls_phase2_request_pap",
6458 "pap user", "auth=PAP"),
6459 (1, "wpabuf_alloc;eap_ttls_avp_encapsulate",
6460 "user", "autheap=MSCHAPV2"),
6461 (1, "eap_mschapv2_init;eap_ttls_phase2_request_eap_method",
6462 "user", "autheap=MSCHAPV2"),
6463 (1, "eap_sm_buildIdentity;eap_ttls_phase2_request_eap",
6464 "user", "autheap=MSCHAPV2"),
6465 (1, "eap_ttls_avp_encapsulate;eap_ttls_phase2_request_eap",
6466 "user", "autheap=MSCHAPV2"),
6467 (1, "eap_ttls_parse_attr_eap",
6468 "user", "autheap=MSCHAPV2"),
6469 (1, "eap_peer_tls_encrypt;eap_ttls_encrypt_response;eap_ttls_process_decrypted",
6470 "user", "autheap=MSCHAPV2"),
6471 (1, "eap_ttls_fake_identity_request",
6472 "user", "autheap=MSCHAPV2"),
6473 (1, "eap_msg_alloc;eap_tls_process_output",
6474 "user", "autheap=MSCHAPV2"),
6475 (1, "eap_msg_alloc;eap_peer_tls_build_ack",
6476 "user", "autheap=MSCHAPV2"),
6477 (1, "tls_connection_decrypt;eap_peer_tls_decrypt",
6478 "user", "autheap=MSCHAPV2"),
6479 (1, "eap_peer_tls_phase2_nak;eap_ttls_phase2_request_eap_method",
6480 "cert user", "autheap=MSCHAPV2") ]
6481 for count, func, identity, phase2 in tests:
6482 with alloc_fail(dev[0], count, func):
6483 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6484 eap="TTLS", anonymous_identity="ttls",
6485 identity=identity, password="password",
6486 ca_cert="auth_serv/ca.pem", phase2=phase2,
6487 erp="1", wait_connect=False)
6488 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
6489 timeout=15)
6490 if ev is None:
6491 raise Exception("Timeout on EAP start")
6492 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL",
6493 note="Allocation failure not triggered for: %d:%s" % (count, func))
6494 dev[0].request("REMOVE_NETWORK all")
6495 dev[0].wait_disconnected()
6496
6497 tests = [ (1, "os_get_random;eap_ttls_phase2_request_mschapv2"),
6498 (1, "mschapv2_derive_response;eap_ttls_phase2_request_mschapv2") ]
6499 for count, func in tests:
6500 with fail_test(dev[0], count, func):
6501 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6502 eap="TTLS", anonymous_identity="ttls",
6503 identity="DOMAIN\mschapv2 user", password="password",
6504 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
6505 erp="1", wait_connect=False)
6506 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
6507 timeout=15)
6508 if ev is None:
6509 raise Exception("Timeout on EAP start")
6510 wait_fail_trigger(dev[0], "GET_FAIL",
6511 note="Test failure not triggered for: %d:%s" % (count, func))
6512 dev[0].request("REMOVE_NETWORK all")
6513 dev[0].wait_disconnected()
2fd377de
JM
6514
6515def test_eap_proto_expanded(dev, apdev):
6516 """EAP protocol tests with expanded header"""
6517 global eap_proto_expanded_test_done
6518 eap_proto_expanded_test_done = False
6519
6520 def expanded_handler(ctx, req):
6521 logger.info("expanded_handler - RX " + req.encode("hex"))
6522 if 'num' not in ctx:
6523 ctx['num'] = 0
6524 ctx['num'] += 1
6525 if 'id' not in ctx:
6526 ctx['id'] = 1
6527 ctx['id'] = (ctx['id'] + 1) % 256
6528 idx = 0
6529
6530 idx += 1
6531 if ctx['num'] == idx:
6532 logger.info("Test: MD5 challenge in expanded header")
6533 return struct.pack(">BBHB3BLBBB", EAP_CODE_REQUEST, ctx['id'],
6534 4 + 1 + 3 + 4 + 3,
6535 EAP_TYPE_EXPANDED, 0, 0, 0, EAP_TYPE_MD5,
6536 1, 0xaa, ord('n'))
6537 idx += 1
6538 if ctx['num'] == idx:
6539 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6540
6541 idx += 1
6542 if ctx['num'] == idx:
6543 logger.info("Test: Invalid expanded EAP length")
6544 return struct.pack(">BBHB3BH", EAP_CODE_REQUEST, ctx['id'],
6545 4 + 1 + 3 + 2,
6546 EAP_TYPE_EXPANDED, 0, 0, 0, EAP_TYPE_MD5)
6547 idx += 1
6548 if ctx['num'] == idx:
6549 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6550
6551 idx += 1
6552 if ctx['num'] == idx:
6553 logger.info("Test: Invalid expanded frame type")
6554 return struct.pack(">BBHB3BL", EAP_CODE_REQUEST, ctx['id'],
6555 4 + 1 + 3 + 4,
6556 EAP_TYPE_EXPANDED, 0, 0, 1, EAP_TYPE_MD5)
6557 idx += 1
6558 if ctx['num'] == idx:
6559 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6560
6561 idx += 1
6562 if ctx['num'] == idx:
6563 logger.info("Test: MSCHAPv2 Challenge")
6564 return struct.pack(">BBHBBBHB", EAP_CODE_REQUEST, ctx['id'],
6565 4 + 1 + 4 + 1 + 16 + 6,
6566 EAP_TYPE_MSCHAPV2,
6567 1, 0, 4 + 1 + 16 + 6, 16) + 16*'A' + 'foobar'
6568 idx += 1
6569 if ctx['num'] == idx:
6570 logger.info("Test: Invalid expanded frame type")
6571 return struct.pack(">BBHB3BL", EAP_CODE_REQUEST, ctx['id'],
6572 4 + 1 + 3 + 4,
6573 EAP_TYPE_EXPANDED, 0, 0, 1, EAP_TYPE_MSCHAPV2)
6574
6575 logger.info("No more test responses available - test case completed")
6576 global eap_proto_expanded_test_done
6577 eap_proto_expanded_test_done = True
6578 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6579
6580 srv = start_radius_server(expanded_handler)
6581
6582 try:
6583 hapd = start_ap(apdev[0]['ifname'])
6584
6585 i = 0
6586 while not eap_proto_expanded_test_done:
6587 i += 1
6588 logger.info("Running connection iteration %d" % i)
6589 if i == 4:
6590 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6591 eap="MSCHAPV2", identity="user",
6592 password="password",
6593 wait_connect=False)
6594 else:
6595 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6596 eap="MD5", identity="user", password="password",
6597 wait_connect=False)
6598 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
6599 if ev is None:
6600 raise Exception("Timeout on EAP start")
6601 if i in [ 1 ]:
6602 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=5)
6603 if ev is None:
6604 raise Exception("Timeout on EAP method start")
6605 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
6606 if ev is None:
6607 raise Exception("Timeout on EAP failure")
6608 elif i in [ 2, 3 ]:
6609 ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"],
6610 timeout=5)
6611 if ev is None:
6612 raise Exception("Timeout on EAP proposed method")
6613 ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
6614 if ev is None:
6615 raise Exception("Timeout on EAP failure")
6616 else:
6617 time.sleep(0.1)
6618 dev[0].request("REMOVE_NETWORK all")
6619 dev[0].wait_disconnected(timeout=1)
6620 dev[0].dump_monitor()
6621 finally:
6622 stop_radius_server(srv)
0c8eacd1
JM
6623
6624def test_eap_proto_tnc(dev, apdev):
6625 """EAP-TNC protocol tests"""
6626 check_eap_capa(dev[0], "TNC")
6627 global eap_proto_tnc_test_done
6628 eap_proto_tnc_test_done = False
6629
6630 def tnc_handler(ctx, req):
6631 logger.info("tnc_handler - RX " + req.encode("hex"))
6632 if 'num' not in ctx:
6633 ctx['num'] = 0
6634 ctx['num'] += 1
6635 if 'id' not in ctx:
6636 ctx['id'] = 1
6637 ctx['id'] = (ctx['id'] + 1) % 256
6638 idx = 0
6639
6640 idx += 1
6641 if ctx['num'] == idx:
6642 logger.info("Test: TNC start with unsupported version")
6643 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
6644 4 + 1 + 1,
6645 EAP_TYPE_TNC, 0x20)
6646
6647 idx += 1
6648 if ctx['num'] == idx:
6649 logger.info("Test: TNC without Flags field")
6650 return struct.pack(">BBHB", EAP_CODE_REQUEST, ctx['id'],
6651 4 + 1,
6652 EAP_TYPE_TNC)
6653
6654 idx += 1
6655 if ctx['num'] == idx:
6656 logger.info("Test: Message underflow due to missing Message Length")
6657 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
6658 4 + 1 + 1,
6659 EAP_TYPE_TNC, 0xa1)
6660
6661 idx += 1
6662 if ctx['num'] == idx:
6663 logger.info("Test: Invalid Message Length")
6664 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'],
6665 4 + 1 + 1 + 4 + 1,
6666 EAP_TYPE_TNC, 0xa1, 0, 0)
6667
6668 idx += 1
6669 if ctx['num'] == idx:
6670 logger.info("Test: Invalid Message Length")
6671 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'],
6672 4 + 1 + 1 + 4,
6673 EAP_TYPE_TNC, 0xe1, 75001)
6674
6675 idx += 1
6676 if ctx['num'] == idx:
6677 logger.info("Test: Start with Message Length")
6678 return struct.pack(">BBHBBL", EAP_CODE_REQUEST, ctx['id'],
6679 4 + 1 + 1 + 4,
6680 EAP_TYPE_TNC, 0xa1, 1)
6681 idx += 1
6682 if ctx['num'] == idx:
6683 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6684
6685 idx += 1
6686 if ctx['num'] == idx:
6687 logger.info("Test: Server used start flag again")
6688 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
6689 4 + 1 + 1,
6690 EAP_TYPE_TNC, 0x21)
6691 idx += 1
6692 if ctx['num'] == idx:
6693 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
6694 4 + 1 + 1,
6695 EAP_TYPE_TNC, 0x21)
6696
6697 idx += 1
6698 if ctx['num'] == idx:
6699 logger.info("Test: Fragmentation and unexpected payload in ack")
6700 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
6701 4 + 1 + 1,
6702 EAP_TYPE_TNC, 0x21)
6703 idx += 1
6704 if ctx['num'] == idx:
6705 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
6706 4 + 1 + 1,
6707 EAP_TYPE_TNC, 0x01)
6708 idx += 1
6709 if ctx['num'] == idx:
6710 return struct.pack(">BBHBBB", EAP_CODE_REQUEST, ctx['id'],
6711 4 + 1 + 1 + 1,
6712 EAP_TYPE_TNC, 0x01, 0)
6713
6714 idx += 1
6715 if ctx['num'] == idx:
6716 logger.info("Test: Server fragmenting and fragment overflow")
6717 return struct.pack(">BBHBBLB", EAP_CODE_REQUEST, ctx['id'],
6718 4 + 1 + 1 + 4 + 1,
6719 EAP_TYPE_TNC, 0xe1, 2, 1)
6720 idx += 1
6721 if ctx['num'] == idx:
6722 return struct.pack(">BBHBBBB", EAP_CODE_REQUEST, ctx['id'],
6723 4 + 1 + 1 + 2,
6724 EAP_TYPE_TNC, 0x01, 2, 3)
6725
6726 idx += 1
6727 if ctx['num'] == idx:
6728 logger.info("Test: Server fragmenting and no message length in a fragment")
6729 return struct.pack(">BBHBBB", EAP_CODE_REQUEST, ctx['id'],
6730 4 + 1 + 1 + 1,
6731 EAP_TYPE_TNC, 0x61, 2)
6732
6733 idx += 1
6734 if ctx['num'] == idx:
6735 logger.info("Test: TNC start followed by invalid TNCCS-Batch")
6736 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
6737 4 + 1 + 1,
6738 EAP_TYPE_TNC, 0x21)
6739 idx += 1
6740 if ctx['num'] == idx:
6741 logger.info("Received TNCCS-Batch: " + req[6:])
6742 resp = "FOO"
6743 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
6744 4 + 1 + 1 + len(resp),
6745 EAP_TYPE_TNC, 0x01) + resp
6746
6747 idx += 1
6748 if ctx['num'] == idx:
6749 logger.info("Test: TNC start followed by invalid TNCCS-Batch (2)")
6750 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
6751 4 + 1 + 1,
6752 EAP_TYPE_TNC, 0x21)
6753 idx += 1
6754 if ctx['num'] == idx:
6755 logger.info("Received TNCCS-Batch: " + req[6:])
6756 resp = "</TNCCS-Batch><TNCCS-Batch>"
6757 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
6758 4 + 1 + 1 + len(resp),
6759 EAP_TYPE_TNC, 0x01) + resp
6760
6761 idx += 1
6762 if ctx['num'] == idx:
6763 logger.info("Test: TNCCS-Batch missing BatchId attribute")
6764 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
6765 4 + 1 + 1,
6766 EAP_TYPE_TNC, 0x21)
6767 idx += 1
6768 if ctx['num'] == idx:
6769 logger.info("Received TNCCS-Batch: " + req[6:])
6770 resp = "<TNCCS-Batch foo=3></TNCCS-Batch>"
6771 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
6772 4 + 1 + 1 + len(resp),
6773 EAP_TYPE_TNC, 0x01) + resp
6774
6775 idx += 1
6776 if ctx['num'] == idx:
6777 logger.info("Test: Unexpected IF-TNCCS BatchId")
6778 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
6779 4 + 1 + 1,
6780 EAP_TYPE_TNC, 0x21)
6781 idx += 1
6782 if ctx['num'] == idx:
6783 logger.info("Received TNCCS-Batch: " + req[6:])
6784 resp = "<TNCCS-Batch BatchId=123456789></TNCCS-Batch>"
6785 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
6786 4 + 1 + 1 + len(resp),
6787 EAP_TYPE_TNC, 0x01) + resp
6788
6789 idx += 1
6790 if ctx['num'] == idx:
6791 logger.info("Test: Missing IMC-IMV-Message and TNCC-TNCS-Message end tags")
6792 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
6793 4 + 1 + 1,
6794 EAP_TYPE_TNC, 0x21)
6795 idx += 1
6796 if ctx['num'] == idx:
6797 logger.info("Received TNCCS-Batch: " + req[6:])
6798 resp = "<TNCCS-Batch BatchId=2><IMC-IMV-Message><TNCC-TNCS-Message></TNCCS-Batch>"
6799 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
6800 4 + 1 + 1 + len(resp),
6801 EAP_TYPE_TNC, 0x01) + resp
6802 idx += 1
6803 if ctx['num'] == idx:
6804 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6805
6806 idx += 1
6807 if ctx['num'] == idx:
6808 logger.info("Test: Missing IMC-IMV-Message and TNCC-TNCS-Message Type")
6809 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
6810 4 + 1 + 1,
6811 EAP_TYPE_TNC, 0x21)
6812 idx += 1
6813 if ctx['num'] == idx:
6814 logger.info("Received TNCCS-Batch: " + req[6:])
6815 resp = "<TNCCS-Batch BatchId=2><IMC-IMV-Message></IMC-IMV-Message><TNCC-TNCS-Message></TNCC-TNCS-Message></TNCCS-Batch>"
6816 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
6817 4 + 1 + 1 + len(resp),
6818 EAP_TYPE_TNC, 0x01) + resp
6819 idx += 1
6820 if ctx['num'] == idx:
6821 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6822
6823 idx += 1
6824 if ctx['num'] == idx:
6825 logger.info("Test: Missing TNCC-TNCS-Message XML end tag")
6826 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
6827 4 + 1 + 1,
6828 EAP_TYPE_TNC, 0x21)
6829 idx += 1
6830 if ctx['num'] == idx:
6831 logger.info("Received TNCCS-Batch: " + req[6:])
6832 resp = "<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type><XML></TNCC-TNCS-Message></TNCCS-Batch>"
6833 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
6834 4 + 1 + 1 + len(resp),
6835 EAP_TYPE_TNC, 0x01) + resp
6836 idx += 1
6837 if ctx['num'] == idx:
6838 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6839
6840 idx += 1
6841 if ctx['num'] == idx:
6842 logger.info("Test: Missing TNCC-TNCS-Message Base64 start tag")
6843 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
6844 4 + 1 + 1,
6845 EAP_TYPE_TNC, 0x21)
6846 idx += 1
6847 if ctx['num'] == idx:
6848 logger.info("Received TNCCS-Batch: " + req[6:])
6849 resp = "<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type></TNCC-TNCS-Message></TNCCS-Batch>"
6850 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
6851 4 + 1 + 1 + len(resp),
6852 EAP_TYPE_TNC, 0x01) + resp
6853 idx += 1
6854 if ctx['num'] == idx:
6855 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6856
6857 idx += 1
6858 if ctx['num'] == idx:
6859 logger.info("Test: Missing TNCC-TNCS-Message Base64 end tag")
6860 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
6861 4 + 1 + 1,
6862 EAP_TYPE_TNC, 0x21)
6863 idx += 1
6864 if ctx['num'] == idx:
6865 logger.info("Received TNCCS-Batch: " + req[6:])
6866 resp = "<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type><Base64>abc</TNCC-TNCS-Message></TNCCS-Batch>"
6867 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
6868 4 + 1 + 1 + len(resp),
6869 EAP_TYPE_TNC, 0x01) + resp
6870 idx += 1
6871 if ctx['num'] == idx:
6872 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6873
6874 idx += 1
6875 if ctx['num'] == idx:
6876 logger.info("Test: TNCC-TNCS-Message Base64 message")
6877 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
6878 4 + 1 + 1,
6879 EAP_TYPE_TNC, 0x21)
6880 idx += 1
6881 if ctx['num'] == idx:
6882 logger.info("Received TNCCS-Batch: " + req[6:])
6883 resp = "<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type><Base64>aGVsbG8=</Base64></TNCC-TNCS-Message></TNCCS-Batch>"
6884 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
6885 4 + 1 + 1 + len(resp),
6886 EAP_TYPE_TNC, 0x01) + resp
6887 idx += 1
6888 if ctx['num'] == idx:
6889 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6890
6891 idx += 1
6892 if ctx['num'] == idx:
6893 logger.info("Test: Invalid TNCC-TNCS-Message XML message")
6894 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
6895 4 + 1 + 1,
6896 EAP_TYPE_TNC, 0x21)
6897 idx += 1
6898 if ctx['num'] == idx:
6899 logger.info("Received TNCCS-Batch: " + req[6:])
6900 resp = "<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type><XML>hello</XML></TNCC-TNCS-Message></TNCCS-Batch>"
6901 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
6902 4 + 1 + 1 + len(resp),
6903 EAP_TYPE_TNC, 0x01) + resp
6904 idx += 1
6905 if ctx['num'] == idx:
6906 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6907
6908 idx += 1
6909 if ctx['num'] == idx:
6910 logger.info("Test: Missing TNCCS-Recommendation type")
6911 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
6912 4 + 1 + 1,
6913 EAP_TYPE_TNC, 0x21)
6914 idx += 1
6915 if ctx['num'] == idx:
6916 logger.info("Received TNCCS-Batch: " + req[6:])
6917 resp = '<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type><XML><TNCCS-Recommendation foo=1></TNCCS-Recommendation></XML></TNCC-TNCS-Message></TNCCS-Batch>'
6918 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
6919 4 + 1 + 1 + len(resp),
6920 EAP_TYPE_TNC, 0x01) + resp
6921 idx += 1
6922 if ctx['num'] == idx:
6923 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6924
6925 idx += 1
6926 if ctx['num'] == idx:
6927 logger.info("Test: TNCCS-Recommendation type=none")
6928 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
6929 4 + 1 + 1,
6930 EAP_TYPE_TNC, 0x21)
6931 idx += 1
6932 if ctx['num'] == idx:
6933 logger.info("Received TNCCS-Batch: " + req[6:])
6934 resp = '<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type><XML><TNCCS-Recommendation type="none"></TNCCS-Recommendation></XML></TNCC-TNCS-Message></TNCCS-Batch>'
6935 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
6936 4 + 1 + 1 + len(resp),
6937 EAP_TYPE_TNC, 0x01) + resp
6938 idx += 1
6939 if ctx['num'] == idx:
6940 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6941
6942 idx += 1
6943 if ctx['num'] == idx:
6944 logger.info("Test: TNCCS-Recommendation type=isolate")
6945 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
6946 4 + 1 + 1,
6947 EAP_TYPE_TNC, 0x21)
6948 idx += 1
6949 if ctx['num'] == idx:
6950 logger.info("Received TNCCS-Batch: " + req[6:])
6951 resp = '<TNCCS-Batch BatchId=2><TNCC-TNCS-Message><Type>00000001</Type><XML><TNCCS-Recommendation type="isolate"></TNCCS-Recommendation></XML></TNCC-TNCS-Message></TNCCS-Batch>'
6952 return struct.pack(">BBHBB", EAP_CODE_REQUEST, ctx['id'],
6953 4 + 1 + 1 + len(resp),
6954 EAP_TYPE_TNC, 0x01) + resp
6955 idx += 1
6956 if ctx['num'] == idx:
6957 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6958
6959 logger.info("No more test responses available - test case completed")
6960 global eap_proto_tnc_test_done
6961 eap_proto_tnc_test_done = True
6962 return struct.pack(">BBH", EAP_CODE_FAILURE, ctx['id'], 4)
6963
6964 srv = start_radius_server(tnc_handler)
6965
6966 try:
6967 hapd = start_ap(apdev[0]['ifname'])
6968
6969 i = 0
6970 while not eap_proto_tnc_test_done:
6971 i += 1
6972 logger.info("Running connection iteration %d" % i)
6973 frag = 1400
6974 if i == 8:
6975 frag = 150
6976 dev[0].connect("eap-test", key_mgmt="WPA-EAP", scan_freq="2412",
6977 eap="TNC", identity="tnc", fragment_size=str(frag),
6978 wait_connect=False)
6979 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
6980 if ev is None:
6981 raise Exception("Timeout on EAP start")
6982 ev = dev[0].wait_event(["CTRL-EVENT-EAP-METHOD",
6983 "CTRL-EVENT-EAP-STATUS"], timeout=5)
6984 if ev is None:
6985 raise Exception("Timeout on EAP method start")
6986 time.sleep(0.1)
6987 dev[0].request("REMOVE_NETWORK all")
6988 dev[0].wait_disconnected(timeout=1)
6989 dev[0].dump_monitor()
6990 finally:
6991 stop_radius_server(srv)