test_fils.py 62 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618
  1. # Test cases for FILS
  2. # Copyright (c) 2015-2017, Qualcomm Atheros, Inc.
  3. #
  4. # This software may be distributed under the terms of the BSD license.
  5. # See README for more details.
  6. import binascii
  7. import hashlib
  8. import logging
  9. logger = logging.getLogger()
  10. import os
  11. import socket
  12. import struct
  13. import time
  14. import hostapd
  15. from wpasupplicant import WpaSupplicant
  16. import hwsim_utils
  17. from utils import HwsimSkip, alloc_fail
  18. from test_erp import check_erp_capa, start_erp_as
  19. from test_ap_hs20 import ip_checksum
  20. def check_fils_capa(dev):
  21. capa = dev.get_capability("fils")
  22. if capa is None or "FILS" not in capa:
  23. raise HwsimSkip("FILS not supported")
  24. def check_fils_sk_pfs_capa(dev):
  25. capa = dev.get_capability("fils")
  26. if capa is None or "FILS-SK-PFS" not in capa:
  27. raise HwsimSkip("FILS-SK-PFS not supported")
  28. def test_fils_sk_full_auth(dev, apdev, params):
  29. """FILS SK full authentication"""
  30. check_fils_capa(dev[0])
  31. check_erp_capa(dev[0])
  32. start_erp_as(apdev[1], msk_dump=os.path.join(params['logdir'], "msk.lst"))
  33. bssid = apdev[0]['bssid']
  34. params = hostapd.wpa2_eap_params(ssid="fils")
  35. params['wpa_key_mgmt'] = "FILS-SHA256"
  36. params['auth_server_port'] = "18128"
  37. params['erp_send_reauth_start'] = '1'
  38. params['erp_domain'] = 'example.com'
  39. params['fils_realm'] = 'example.com'
  40. params['wpa_group_rekey'] = '1'
  41. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  42. dev[0].scan_for_bss(bssid, freq=2412)
  43. bss = dev[0].get_bss(bssid)
  44. logger.debug("BSS: " + str(bss))
  45. if "[FILS]" not in bss['flags']:
  46. raise Exception("[FILS] flag not indicated")
  47. if "[WPA2-FILS-SHA256-CCMP]" not in bss['flags']:
  48. raise Exception("[WPA2-FILS-SHA256-CCMP] flag not indicated")
  49. res = dev[0].request("SCAN_RESULTS")
  50. logger.debug("SCAN_RESULTS: " + res)
  51. if "[FILS]" not in res:
  52. raise Exception("[FILS] flag not indicated")
  53. if "[WPA2-FILS-SHA256-CCMP]" not in res:
  54. raise Exception("[WPA2-FILS-SHA256-CCMP] flag not indicated")
  55. dev[0].request("ERP_FLUSH")
  56. dev[0].connect("fils", key_mgmt="FILS-SHA256",
  57. eap="PSK", identity="psk.user@example.com",
  58. password_hex="0123456789abcdef0123456789abcdef",
  59. erp="1", scan_freq="2412")
  60. hwsim_utils.test_connectivity(dev[0], hapd)
  61. ev = dev[0].wait_event(["WPA: Group rekeying completed"], timeout=2)
  62. if ev is None:
  63. raise Exception("GTK rekey timed out")
  64. hwsim_utils.test_connectivity(dev[0], hapd)
  65. conf = hapd.get_config()
  66. if conf['key_mgmt'] != 'FILS-SHA256':
  67. raise Exception("Unexpected config key_mgmt: " + conf['key_mgmt'])
  68. def test_fils_sk_sha384_full_auth(dev, apdev, params):
  69. """FILS SK full authentication (SHA384)"""
  70. check_fils_capa(dev[0])
  71. check_erp_capa(dev[0])
  72. start_erp_as(apdev[1], msk_dump=os.path.join(params['logdir'], "msk.lst"))
  73. bssid = apdev[0]['bssid']
  74. params = hostapd.wpa2_eap_params(ssid="fils")
  75. params['wpa_key_mgmt'] = "FILS-SHA384"
  76. params['auth_server_port'] = "18128"
  77. params['erp_send_reauth_start'] = '1'
  78. params['erp_domain'] = 'example.com'
  79. params['fils_realm'] = 'example.com'
  80. params['wpa_group_rekey'] = '1'
  81. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  82. dev[0].scan_for_bss(bssid, freq=2412)
  83. bss = dev[0].get_bss(bssid)
  84. logger.debug("BSS: " + str(bss))
  85. if "[FILS]" not in bss['flags']:
  86. raise Exception("[FILS] flag not indicated")
  87. if "[WPA2-FILS-SHA384-CCMP]" not in bss['flags']:
  88. raise Exception("[WPA2-FILS-SHA384-CCMP] flag not indicated")
  89. res = dev[0].request("SCAN_RESULTS")
  90. logger.debug("SCAN_RESULTS: " + res)
  91. if "[FILS]" not in res:
  92. raise Exception("[FILS] flag not indicated")
  93. if "[WPA2-FILS-SHA384-CCMP]" not in res:
  94. raise Exception("[WPA2-FILS-SHA384-CCMP] flag not indicated")
  95. dev[0].request("ERP_FLUSH")
  96. dev[0].connect("fils", key_mgmt="FILS-SHA384",
  97. eap="PSK", identity="psk.user@example.com",
  98. password_hex="0123456789abcdef0123456789abcdef",
  99. erp="1", scan_freq="2412")
  100. hwsim_utils.test_connectivity(dev[0], hapd)
  101. ev = dev[0].wait_event(["WPA: Group rekeying completed"], timeout=2)
  102. if ev is None:
  103. raise Exception("GTK rekey timed out")
  104. hwsim_utils.test_connectivity(dev[0], hapd)
  105. conf = hapd.get_config()
  106. if conf['key_mgmt'] != 'FILS-SHA384':
  107. raise Exception("Unexpected config key_mgmt: " + conf['key_mgmt'])
  108. def test_fils_sk_pmksa_caching(dev, apdev, params):
  109. """FILS SK and PMKSA caching"""
  110. check_fils_capa(dev[0])
  111. check_erp_capa(dev[0])
  112. start_erp_as(apdev[1], msk_dump=os.path.join(params['logdir'], "msk.lst"))
  113. bssid = apdev[0]['bssid']
  114. params = hostapd.wpa2_eap_params(ssid="fils")
  115. params['wpa_key_mgmt'] = "FILS-SHA256"
  116. params['auth_server_port'] = "18128"
  117. params['erp_domain'] = 'example.com'
  118. params['fils_realm'] = 'example.com'
  119. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  120. dev[0].scan_for_bss(bssid, freq=2412)
  121. dev[0].request("ERP_FLUSH")
  122. id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
  123. eap="PSK", identity="psk.user@example.com",
  124. password_hex="0123456789abcdef0123456789abcdef",
  125. erp="1", scan_freq="2412")
  126. pmksa = dev[0].get_pmksa(bssid)
  127. if pmksa is None:
  128. raise Exception("No PMKSA cache entry created")
  129. dev[0].request("DISCONNECT")
  130. dev[0].wait_disconnected()
  131. dev[0].dump_monitor()
  132. dev[0].select_network(id, freq=2412)
  133. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
  134. "CTRL-EVENT-CONNECTED"], timeout=10)
  135. if ev is None:
  136. raise Exception("Connection using PMKSA caching timed out")
  137. if "CTRL-EVENT-EAP-STARTED" in ev:
  138. raise Exception("Unexpected EAP exchange")
  139. hwsim_utils.test_connectivity(dev[0], hapd)
  140. pmksa2 = dev[0].get_pmksa(bssid)
  141. if pmksa2 is None:
  142. raise Exception("No PMKSA cache entry found")
  143. if pmksa['pmkid'] != pmksa2['pmkid']:
  144. raise Exception("Unexpected PMKID change")
  145. # Verify EAPOL reauthentication after FILS authentication
  146. hapd.request("EAPOL_REAUTH " + dev[0].own_addr())
  147. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
  148. if ev is None:
  149. raise Exception("EAP authentication did not start")
  150. ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=5)
  151. if ev is None:
  152. raise Exception("EAP authentication did not succeed")
  153. time.sleep(0.1)
  154. hwsim_utils.test_connectivity(dev[0], hapd)
  155. def test_fils_sk_pmksa_caching_and_cache_id(dev, apdev):
  156. """FILS SK and PMKSA caching with Cache Identifier"""
  157. check_fils_capa(dev[0])
  158. check_erp_capa(dev[0])
  159. bssid = apdev[0]['bssid']
  160. params = hostapd.wpa2_eap_params(ssid="fils")
  161. params['wpa_key_mgmt'] = "FILS-SHA256"
  162. params['auth_server_port'] = "18128"
  163. params['erp_domain'] = 'example.com'
  164. params['fils_realm'] = 'example.com'
  165. params['fils_cache_id'] = "abcd"
  166. params["radius_server_clients"] = "auth_serv/radius_clients.conf"
  167. params["radius_server_auth_port"] = '18128'
  168. params["eap_server"] = "1"
  169. params["eap_user_file"] = "auth_serv/eap_user.conf"
  170. params["ca_cert"] = "auth_serv/ca.pem"
  171. params["server_cert"] = "auth_serv/server.pem"
  172. params["private_key"] = "auth_serv/server.key"
  173. params["eap_sim_db"] = "unix:/tmp/hlr_auc_gw.sock"
  174. params["dh_file"] = "auth_serv/dh.conf"
  175. params["pac_opaque_encr_key"] = "000102030405060708090a0b0c0d0e0f"
  176. params["eap_fast_a_id"] = "101112131415161718191a1b1c1d1e1f"
  177. params["eap_fast_a_id_info"] = "test server"
  178. params["eap_server_erp"] = "1"
  179. params["erp_domain"] = "example.com"
  180. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  181. dev[0].scan_for_bss(bssid, freq=2412)
  182. dev[0].request("ERP_FLUSH")
  183. id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
  184. eap="PSK", identity="psk.user@example.com",
  185. password_hex="0123456789abcdef0123456789abcdef",
  186. erp="1", scan_freq="2412")
  187. res = dev[0].request("PMKSA")
  188. if "FILS Cache Identifier" not in res:
  189. raise Exception("PMKSA list does not include FILS Cache Identifier")
  190. pmksa = dev[0].get_pmksa(bssid)
  191. if pmksa is None:
  192. raise Exception("No PMKSA cache entry created")
  193. if "cache_id" not in pmksa:
  194. raise Exception("No FILS Cache Identifier listed")
  195. if pmksa["cache_id"] != "abcd":
  196. raise Exception("The configured FILS Cache Identifier not seen in PMKSA")
  197. bssid2 = apdev[1]['bssid']
  198. params = hostapd.wpa2_eap_params(ssid="fils")
  199. params['wpa_key_mgmt'] = "FILS-SHA256"
  200. params['auth_server_port'] = "18128"
  201. params['erp_domain'] = 'example.com'
  202. params['fils_realm'] = 'example.com'
  203. params['fils_cache_id'] = "abcd"
  204. hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
  205. dev[0].scan_for_bss(bssid2, freq=2412)
  206. dev[0].dump_monitor()
  207. if "OK" not in dev[0].request("ROAM " + bssid2):
  208. raise Exception("ROAM failed")
  209. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
  210. "CTRL-EVENT-CONNECTED"], timeout=10)
  211. if ev is None:
  212. raise Exception("Connection using PMKSA caching timed out")
  213. if "CTRL-EVENT-EAP-STARTED" in ev:
  214. raise Exception("Unexpected EAP exchange")
  215. if bssid2 not in ev:
  216. raise Exception("Failed to connect to the second AP")
  217. hwsim_utils.test_connectivity(dev[0], hapd2)
  218. pmksa2 = dev[0].get_pmksa(bssid2)
  219. if pmksa2:
  220. raise Exception("Unexpected extra PMKSA cache added")
  221. pmksa2 = dev[0].get_pmksa(bssid)
  222. if not pmksa2:
  223. raise Exception("Original PMKSA cache entry removed")
  224. if pmksa['pmkid'] != pmksa2['pmkid']:
  225. raise Exception("Unexpected PMKID change")
  226. def test_fils_sk_pmksa_caching_ctrl_ext(dev, apdev, params):
  227. """FILS SK and PMKSA caching with Cache Identifier and external management"""
  228. check_fils_capa(dev[0])
  229. check_erp_capa(dev[0])
  230. hapd_as = start_erp_as(apdev[1],
  231. msk_dump=os.path.join(params['logdir'], "msk.lst"))
  232. bssid = apdev[0]['bssid']
  233. params = hostapd.wpa2_eap_params(ssid="fils")
  234. params['wpa_key_mgmt'] = "FILS-SHA384"
  235. params['auth_server_port'] = "18128"
  236. params['erp_send_reauth_start'] = '1'
  237. params['erp_domain'] = 'example.com'
  238. params['fils_realm'] = 'example.com'
  239. params['fils_cache_id'] = "ffee"
  240. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  241. dev[0].scan_for_bss(bssid, freq=2412)
  242. dev[0].request("ERP_FLUSH")
  243. id = dev[0].connect("fils", key_mgmt="FILS-SHA384",
  244. eap="PSK", identity="psk.user@example.com",
  245. password_hex="0123456789abcdef0123456789abcdef",
  246. erp="1", scan_freq="2412")
  247. res1 = dev[0].request("PMKSA_GET %d" % id)
  248. logger.info("PMKSA_GET: " + res1)
  249. if "UNKNOWN COMMAND" in res1:
  250. raise HwsimSkip("PMKSA_GET not supported in the build")
  251. if bssid not in res1:
  252. raise Exception("PMKSA cache entry missing")
  253. if "ffee" not in res1:
  254. raise Exception("FILS Cache Identifier not seen in PMKSA cache entry")
  255. dev[0].request("DISCONNECT")
  256. dev[0].wait_disconnected()
  257. hapd_as.disable()
  258. dev[0].scan_for_bss(bssid, freq=2412)
  259. dev[0].request("PMKSA_FLUSH")
  260. dev[0].request("ERP_FLUSH")
  261. for entry in res1.splitlines():
  262. if "OK" not in dev[0].request("PMKSA_ADD %d %s" % (id, entry)):
  263. raise Exception("Failed to add PMKSA entry")
  264. bssid2 = apdev[1]['bssid']
  265. params = hostapd.wpa2_eap_params(ssid="fils")
  266. params['wpa_key_mgmt'] = "FILS-SHA384"
  267. params['auth_server_port'] = "18128"
  268. params['erp_send_reauth_start'] = '1'
  269. params['erp_domain'] = 'example.com'
  270. params['fils_realm'] = 'example.com'
  271. params['fils_cache_id'] = "ffee"
  272. hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
  273. dev[0].scan_for_bss(bssid2, freq=2412)
  274. dev[0].set_network(id, "bssid", bssid2)
  275. dev[0].select_network(id, freq=2412)
  276. ev = dev[0].wait_connected()
  277. if bssid2 not in ev:
  278. raise Exception("Unexpected BSS selected")
  279. def test_fils_sk_erp(dev, apdev, params):
  280. """FILS SK using ERP"""
  281. run_fils_sk_erp(dev, apdev, "FILS-SHA256", params)
  282. def test_fils_sk_erp_sha384(dev, apdev, params):
  283. """FILS SK using ERP and SHA384"""
  284. run_fils_sk_erp(dev, apdev, "FILS-SHA384", params)
  285. def run_fils_sk_erp(dev, apdev, key_mgmt, params):
  286. check_fils_capa(dev[0])
  287. check_erp_capa(dev[0])
  288. start_erp_as(apdev[1],
  289. msk_dump=os.path.join(params['logdir'], "msk.lst"))
  290. bssid = apdev[0]['bssid']
  291. params = hostapd.wpa2_eap_params(ssid="fils")
  292. params['wpa_key_mgmt'] = key_mgmt
  293. params['auth_server_port'] = "18128"
  294. params['erp_domain'] = 'example.com'
  295. params['fils_realm'] = 'example.com'
  296. params['disable_pmksa_caching'] = '1'
  297. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  298. dev[0].scan_for_bss(bssid, freq=2412)
  299. dev[0].request("ERP_FLUSH")
  300. id = dev[0].connect("fils", key_mgmt=key_mgmt,
  301. eap="PSK", identity="psk.user@example.com",
  302. password_hex="0123456789abcdef0123456789abcdef",
  303. erp="1", scan_freq="2412")
  304. dev[0].request("DISCONNECT")
  305. dev[0].wait_disconnected()
  306. dev[0].dump_monitor()
  307. dev[0].select_network(id, freq=2412)
  308. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
  309. "EVENT-ASSOC-REJECT",
  310. "CTRL-EVENT-CONNECTED"], timeout=10)
  311. if ev is None:
  312. raise Exception("Connection using FILS/ERP timed out")
  313. if "CTRL-EVENT-EAP-STARTED" in ev:
  314. raise Exception("Unexpected EAP exchange")
  315. if "EVENT-ASSOC-REJECT" in ev:
  316. raise Exception("Association failed")
  317. hwsim_utils.test_connectivity(dev[0], hapd)
  318. def test_fils_sk_erp_followed_by_pmksa_caching(dev, apdev, params):
  319. check_fils_capa(dev[0])
  320. check_erp_capa(dev[0])
  321. start_erp_as(apdev[1], msk_dump=os.path.join(params['logdir'], "msk.lst"))
  322. bssid = apdev[0]['bssid']
  323. params = hostapd.wpa2_eap_params(ssid="fils")
  324. params['wpa_key_mgmt'] = "FILS-SHA256"
  325. params['auth_server_port'] = "18128"
  326. params['erp_domain'] = 'example.com'
  327. params['fils_realm'] = 'example.com'
  328. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  329. dev[0].scan_for_bss(bssid, freq=2412)
  330. dev[0].request("ERP_FLUSH")
  331. id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
  332. eap="PSK", identity="psk.user@example.com",
  333. password_hex="0123456789abcdef0123456789abcdef",
  334. erp="1", scan_freq="2412")
  335. dev[0].request("DISCONNECT")
  336. dev[0].wait_disconnected()
  337. # Force the second connection to use ERP by deleting the PMKSA entry.
  338. dev[0].request("PMKSA_FLUSH")
  339. dev[0].dump_monitor()
  340. dev[0].select_network(id, freq=2412)
  341. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
  342. "EVENT-ASSOC-REJECT",
  343. "CTRL-EVENT-CONNECTED"], timeout=10)
  344. if ev is None:
  345. raise Exception("Connection using FILS/ERP timed out")
  346. if "CTRL-EVENT-EAP-STARTED" in ev:
  347. raise Exception("Unexpected EAP exchange")
  348. if "EVENT-ASSOC-REJECT" in ev:
  349. raise Exception("Association failed")
  350. hwsim_utils.test_connectivity(dev[0], hapd)
  351. pmksa = dev[0].get_pmksa(bssid)
  352. if pmksa is None:
  353. raise Exception("No PMKSA cache entry created")
  354. dev[0].request("DISCONNECT")
  355. dev[0].wait_disconnected()
  356. # The third connection is expected to use PMKSA caching for FILS
  357. # authentication.
  358. dev[0].dump_monitor()
  359. dev[0].select_network(id, freq=2412)
  360. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
  361. "EVENT-ASSOC-REJECT",
  362. "CTRL-EVENT-CONNECTED"], timeout=10)
  363. if ev is None:
  364. raise Exception("Connection using PMKSA caching timed out")
  365. if "CTRL-EVENT-EAP-STARTED" in ev:
  366. raise Exception("Unexpected EAP exchange")
  367. if "EVENT-ASSOC-REJECT" in ev:
  368. raise Exception("Association failed")
  369. hwsim_utils.test_connectivity(dev[0], hapd)
  370. pmksa2 = dev[0].get_pmksa(bssid)
  371. if pmksa2 is None:
  372. raise Exception("No PMKSA cache entry found")
  373. if pmksa['pmkid'] != pmksa2['pmkid']:
  374. raise Exception("Unexpected PMKID change")
  375. def test_fils_sk_erp_another_ssid(dev, apdev, params):
  376. """FILS SK using ERP and roam to another SSID"""
  377. check_fils_capa(dev[0])
  378. check_erp_capa(dev[0])
  379. start_erp_as(apdev[1], msk_dump=os.path.join(params['logdir'], "msk.lst"))
  380. bssid = apdev[0]['bssid']
  381. params = hostapd.wpa2_eap_params(ssid="fils")
  382. params['wpa_key_mgmt'] = "FILS-SHA256"
  383. params['auth_server_port'] = "18128"
  384. params['erp_domain'] = 'example.com'
  385. params['fils_realm'] = 'example.com'
  386. params['disable_pmksa_caching'] = '1'
  387. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  388. dev[0].scan_for_bss(bssid, freq=2412)
  389. dev[0].request("ERP_FLUSH")
  390. id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
  391. eap="PSK", identity="psk.user@example.com",
  392. password_hex="0123456789abcdef0123456789abcdef",
  393. erp="1", scan_freq="2412")
  394. dev[0].request("DISCONNECT")
  395. dev[0].wait_disconnected()
  396. hapd.disable()
  397. dev[0].flush_scan_cache()
  398. if "FAIL" in dev[0].request("PMKSA_FLUSH"):
  399. raise Exception("PMKSA_FLUSH failed")
  400. params = hostapd.wpa2_eap_params(ssid="fils2")
  401. params['wpa_key_mgmt'] = "FILS-SHA256"
  402. params['auth_server_port'] = "18128"
  403. params['erp_domain'] = 'example.com'
  404. params['fils_realm'] = 'example.com'
  405. params['disable_pmksa_caching'] = '1'
  406. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  407. dev[0].scan_for_bss(bssid, freq=2412)
  408. dev[0].dump_monitor()
  409. id = dev[0].connect("fils2", key_mgmt="FILS-SHA256",
  410. eap="PSK", identity="psk.user@example.com",
  411. password_hex="0123456789abcdef0123456789abcdef",
  412. erp="1", scan_freq="2412", wait_connect=False)
  413. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
  414. "EVENT-ASSOC-REJECT",
  415. "CTRL-EVENT-CONNECTED"], timeout=10)
  416. if ev is None:
  417. raise Exception("Connection using FILS/ERP timed out")
  418. if "CTRL-EVENT-EAP-STARTED" in ev:
  419. raise Exception("Unexpected EAP exchange")
  420. if "EVENT-ASSOC-REJECT" in ev:
  421. raise Exception("Association failed")
  422. hwsim_utils.test_connectivity(dev[0], hapd)
  423. def test_fils_sk_multiple_realms(dev, apdev, params):
  424. """FILS SK and multiple realms"""
  425. check_fils_capa(dev[0])
  426. check_erp_capa(dev[0])
  427. start_erp_as(apdev[1], msk_dump=os.path.join(params['logdir'], "msk.lst"))
  428. bssid = apdev[0]['bssid']
  429. params = hostapd.wpa2_eap_params(ssid="fils")
  430. params['wpa_key_mgmt'] = "FILS-SHA256"
  431. params['auth_server_port'] = "18128"
  432. params['erp_domain'] = 'example.com'
  433. fils_realms = [ 'r1.example.org', 'r2.EXAMPLE.org', 'r3.example.org',
  434. 'r4.example.org', 'r5.example.org', 'r6.example.org',
  435. 'r7.example.org', 'r8.example.org',
  436. 'example.com',
  437. 'r9.example.org', 'r10.example.org', 'r11.example.org',
  438. 'r12.example.org', 'r13.example.org', 'r14.example.org',
  439. 'r15.example.org', 'r16.example.org' ]
  440. params['fils_realm'] = fils_realms
  441. params['fils_cache_id'] = "1234"
  442. params['hessid'] = bssid
  443. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  444. dev[0].scan_for_bss(bssid, freq=2412)
  445. if "OK" not in dev[0].request("ANQP_GET " + bssid + " 275"):
  446. raise Exception("ANQP_GET command failed")
  447. ev = dev[0].wait_event(["GAS-QUERY-DONE"], timeout=10)
  448. if ev is None:
  449. raise Exception("GAS query timed out")
  450. bss = dev[0].get_bss(bssid)
  451. if 'fils_info' not in bss:
  452. raise Exception("FILS Indication element information missing")
  453. if bss['fils_info'] != '02b8':
  454. raise Exception("Unexpected FILS Information: " + bss['fils_info'])
  455. if 'fils_cache_id' not in bss:
  456. raise Exception("FILS Cache Identifier missing")
  457. if bss['fils_cache_id'] != '1234':
  458. raise Exception("Unexpected FILS Cache Identifier: " + bss['fils_cache_id'])
  459. if 'fils_realms' not in bss:
  460. raise Exception("FILS Realm Identifiers missing")
  461. expected = ''
  462. count = 0
  463. for realm in fils_realms:
  464. hash = hashlib.sha256(realm.lower()).digest()
  465. expected += binascii.hexlify(hash[0:2])
  466. count += 1
  467. if count == 7:
  468. break
  469. if bss['fils_realms'] != expected:
  470. raise Exception("Unexpected FILS Realm Identifiers: " + bss['fils_realms'])
  471. if 'anqp_fils_realm_info' not in bss:
  472. raise Exception("FILS Realm Information ANQP-element not seen")
  473. info = bss['anqp_fils_realm_info'];
  474. expected = ''
  475. for realm in fils_realms:
  476. hash = hashlib.sha256(realm.lower()).digest()
  477. expected += binascii.hexlify(hash[0:2])
  478. if info != expected:
  479. raise Exception("Unexpected FILS Realm Info ANQP-element: " + info)
  480. dev[0].request("ERP_FLUSH")
  481. id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
  482. eap="PSK", identity="psk.user@example.com",
  483. password_hex="0123456789abcdef0123456789abcdef",
  484. erp="1", scan_freq="2412")
  485. dev[0].request("DISCONNECT")
  486. dev[0].wait_disconnected()
  487. dev[0].dump_monitor()
  488. dev[0].select_network(id, freq=2412)
  489. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
  490. "EVENT-ASSOC-REJECT",
  491. "CTRL-EVENT-CONNECTED"], timeout=10)
  492. if ev is None:
  493. raise Exception("Connection using FILS/ERP timed out")
  494. if "CTRL-EVENT-EAP-STARTED" in ev:
  495. raise Exception("Unexpected EAP exchange")
  496. if "EVENT-ASSOC-REJECT" in ev:
  497. raise Exception("Association failed")
  498. hwsim_utils.test_connectivity(dev[0], hapd)
  499. # DHCP message op codes
  500. BOOTREQUEST=1
  501. BOOTREPLY=2
  502. OPT_PAD=0
  503. OPT_DHCP_MESSAGE_TYPE=53
  504. OPT_RAPID_COMMIT=80
  505. OPT_END=255
  506. DHCPDISCOVER=1
  507. DHCPOFFER=2
  508. DHCPREQUEST=3
  509. DHCPDECLINE=4
  510. DHCPACK=5
  511. DHCPNAK=6
  512. DHCPRELEASE=7
  513. DHCPINFORM=8
  514. def build_dhcp(req, dhcp_msg, chaddr, giaddr="0.0.0.0",
  515. ip_src="0.0.0.0", ip_dst="255.255.255.255",
  516. rapid_commit=True, override_op=None, magic_override=None,
  517. opt_end=True, extra_op=None):
  518. proto = '\x08\x00' # IPv4
  519. _ip_src = socket.inet_pton(socket.AF_INET, ip_src)
  520. _ip_dst = socket.inet_pton(socket.AF_INET, ip_dst)
  521. _ciaddr = '\x00\x00\x00\x00'
  522. _yiaddr = '\x00\x00\x00\x00'
  523. _siaddr = '\x00\x00\x00\x00'
  524. _giaddr = socket.inet_pton(socket.AF_INET, giaddr)
  525. _chaddr = binascii.unhexlify(chaddr.replace(':','')) + 10*'\x00'
  526. htype = 1 # Hardware address type; 1 = Ethernet
  527. hlen = 6 # Hardware address length
  528. hops = 0
  529. xid = 123456
  530. secs = 0
  531. flags = 0
  532. if req:
  533. op = BOOTREQUEST
  534. src_port = 68
  535. dst_port = 67
  536. else:
  537. op = BOOTREPLY
  538. src_port = 67
  539. dst_port = 68
  540. if override_op is not None:
  541. op = override_op
  542. payload = struct.pack('>BBBBLHH', op, htype, hlen, hops, xid, secs, flags)
  543. sname = 64*'\x00'
  544. file = 128*'\x00'
  545. payload += _ciaddr + _yiaddr + _siaddr + _giaddr + _chaddr + sname + file
  546. # magic - DHCP
  547. if magic_override is not None:
  548. payload += magic_override
  549. else:
  550. payload += '\x63\x82\x53\x63'
  551. # Option: DHCP Message Type
  552. if dhcp_msg is not None:
  553. payload += struct.pack('BBB', OPT_DHCP_MESSAGE_TYPE, 1, dhcp_msg)
  554. if rapid_commit:
  555. # Option: Rapid Commit
  556. payload += struct.pack('BB', OPT_RAPID_COMMIT, 0)
  557. if extra_op:
  558. payload += extra_op
  559. # End Option
  560. if opt_end:
  561. payload += struct.pack('B', OPT_END)
  562. udp = struct.pack('>HHHH', src_port, dst_port,
  563. 8 + len(payload), 0) + payload
  564. tot_len = 20 + len(udp)
  565. start = struct.pack('>BBHHBBBB', 0x45, 0, tot_len, 0, 0, 0, 128, 17)
  566. ipv4 = start + '\x00\x00' + _ip_src + _ip_dst
  567. csum = ip_checksum(ipv4)
  568. ipv4 = start + csum + _ip_src + _ip_dst
  569. return proto + ipv4 + udp
  570. def fils_hlp_config(fils_hlp_wait_time=10000):
  571. params = hostapd.wpa2_eap_params(ssid="fils")
  572. params['wpa_key_mgmt'] = "FILS-SHA256"
  573. params['auth_server_port'] = "18128"
  574. params['erp_domain'] = 'example.com'
  575. params['fils_realm'] = 'example.com'
  576. params['disable_pmksa_caching'] = '1'
  577. params['own_ip_addr'] = '127.0.0.3'
  578. params['dhcp_server'] = '127.0.0.2'
  579. params['fils_hlp_wait_time'] = str(fils_hlp_wait_time)
  580. return params
  581. def test_fils_sk_hlp(dev, apdev, params):
  582. """FILS SK HLP (rapid commit server)"""
  583. run_fils_sk_hlp(dev, apdev, True, params)
  584. def test_fils_sk_hlp_no_rapid_commit(dev, apdev, params):
  585. """FILS SK HLP (no rapid commit server)"""
  586. run_fils_sk_hlp(dev, apdev, False, params)
  587. def run_fils_sk_hlp(dev, apdev, rapid_commit_server, params):
  588. check_fils_capa(dev[0])
  589. check_erp_capa(dev[0])
  590. start_erp_as(apdev[1], msk_dump=os.path.join(params['logdir'], "msk.lst"))
  591. sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
  592. sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  593. sock.settimeout(5)
  594. sock.bind(("127.0.0.2", 67))
  595. bssid = apdev[0]['bssid']
  596. params = fils_hlp_config()
  597. params['fils_hlp_wait_time'] = '10000'
  598. if not rapid_commit_server:
  599. params['dhcp_rapid_commit_proxy'] = '1'
  600. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  601. dev[0].scan_for_bss(bssid, freq=2412)
  602. dev[0].request("ERP_FLUSH")
  603. if "OK" not in dev[0].request("FILS_HLP_REQ_FLUSH"):
  604. raise Exception("Failed to flush pending FILS HLP requests")
  605. tests = [ "",
  606. "q",
  607. "ff:ff:ff:ff:ff:ff",
  608. "ff:ff:ff:ff:ff:ff q" ]
  609. for t in tests:
  610. if "FAIL" not in dev[0].request("FILS_HLP_REQ_ADD " + t):
  611. raise Exception("Invalid FILS_HLP_REQ_ADD accepted: " + t)
  612. dhcpdisc = build_dhcp(req=True, dhcp_msg=DHCPDISCOVER,
  613. chaddr=dev[0].own_addr())
  614. tests = [ "ff:ff:ff:ff:ff:ff aabb",
  615. "ff:ff:ff:ff:ff:ff " + 255*'cc',
  616. hapd.own_addr() + " ddee010203040506070809",
  617. "ff:ff:ff:ff:ff:ff " + binascii.hexlify(dhcpdisc) ]
  618. for t in tests:
  619. if "OK" not in dev[0].request("FILS_HLP_REQ_ADD " + t):
  620. raise Exception("FILS_HLP_REQ_ADD failed: " + t)
  621. id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
  622. eap="PSK", identity="psk.user@example.com",
  623. password_hex="0123456789abcdef0123456789abcdef",
  624. erp="1", scan_freq="2412")
  625. dev[0].request("DISCONNECT")
  626. dev[0].wait_disconnected()
  627. dev[0].dump_monitor()
  628. dev[0].select_network(id, freq=2412)
  629. (msg,addr) = sock.recvfrom(1000)
  630. logger.debug("Received DHCP message from %s" % str(addr))
  631. if rapid_commit_server:
  632. # TODO: Proper rapid commit response
  633. dhcpdisc = build_dhcp(req=False, dhcp_msg=DHCPACK,
  634. chaddr=dev[0].own_addr(), giaddr="127.0.0.3")
  635. sock.sendto(dhcpdisc[2+20+8:], addr)
  636. else:
  637. dhcpdisc = build_dhcp(req=False, dhcp_msg=DHCPOFFER, rapid_commit=False,
  638. chaddr=dev[0].own_addr(), giaddr="127.0.0.3")
  639. sock.sendto(dhcpdisc[2+20+8:], addr)
  640. (msg,addr) = sock.recvfrom(1000)
  641. logger.debug("Received DHCP message from %s" % str(addr))
  642. dhcpdisc = build_dhcp(req=False, dhcp_msg=DHCPACK, rapid_commit=False,
  643. chaddr=dev[0].own_addr(), giaddr="127.0.0.3")
  644. sock.sendto(dhcpdisc[2+20+8:], addr)
  645. ev = dev[0].wait_event(["FILS-HLP-RX"], timeout=10)
  646. if ev is None:
  647. raise Exception("FILS HLP response not reported")
  648. vals = ev.split(' ')
  649. frame = binascii.unhexlify(vals[3].split('=')[1])
  650. proto, = struct.unpack('>H', frame[0:2])
  651. if proto != 0x0800:
  652. raise Exception("Unexpected ethertype in HLP response: %d" % proto)
  653. frame = frame[2:]
  654. ip = frame[0:20]
  655. if ip_checksum(ip) != '\x00\x00':
  656. raise Exception("IP header checksum mismatch in HLP response")
  657. frame = frame[20:]
  658. udp = frame[0:8]
  659. frame = frame[8:]
  660. sport, dport, ulen, ucheck = struct.unpack('>HHHH', udp)
  661. if sport != 67 or dport != 68:
  662. raise Exception("Unexpected UDP port in HLP response")
  663. dhcp = frame[0:28]
  664. frame = frame[28:]
  665. op,htype,hlen,hops,xid,secs,flags,ciaddr,yiaddr,siaddr,giaddr = struct.unpack('>4BL2H4L', dhcp)
  666. chaddr = frame[0:16]
  667. frame = frame[16:]
  668. sname = frame[0:64]
  669. frame = frame[64:]
  670. file = frame[0:128]
  671. frame = frame[128:]
  672. options = frame
  673. if options[0:4] != '\x63\x82\x53\x63':
  674. raise Exception("No DHCP magic seen in HLP response")
  675. options = options[4:]
  676. # TODO: fully parse and validate DHCPACK options
  677. if struct.pack('BBB', OPT_DHCP_MESSAGE_TYPE, 1, DHCPACK) not in options:
  678. raise Exception("DHCPACK not in HLP response")
  679. dev[0].wait_connected()
  680. dev[0].request("FILS_HLP_REQ_FLUSH")
  681. def test_fils_sk_hlp_timeout(dev, apdev, params):
  682. """FILS SK HLP (rapid commit server timeout)"""
  683. check_fils_capa(dev[0])
  684. check_erp_capa(dev[0])
  685. start_erp_as(apdev[1], msk_dump=os.path.join(params['logdir'], "msk.lst"))
  686. sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
  687. sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  688. sock.settimeout(5)
  689. sock.bind(("127.0.0.2", 67))
  690. bssid = apdev[0]['bssid']
  691. params = fils_hlp_config(fils_hlp_wait_time=30)
  692. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  693. dev[0].scan_for_bss(bssid, freq=2412)
  694. dev[0].request("ERP_FLUSH")
  695. if "OK" not in dev[0].request("FILS_HLP_REQ_FLUSH"):
  696. raise Exception("Failed to flush pending FILS HLP requests")
  697. dhcpdisc = build_dhcp(req=True, dhcp_msg=DHCPDISCOVER,
  698. chaddr=dev[0].own_addr())
  699. if "OK" not in dev[0].request("FILS_HLP_REQ_ADD " + "ff:ff:ff:ff:ff:ff " + binascii.hexlify(dhcpdisc)):
  700. raise Exception("FILS_HLP_REQ_ADD failed")
  701. id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
  702. eap="PSK", identity="psk.user@example.com",
  703. password_hex="0123456789abcdef0123456789abcdef",
  704. erp="1", scan_freq="2412")
  705. dev[0].request("DISCONNECT")
  706. dev[0].wait_disconnected()
  707. dev[0].dump_monitor()
  708. dev[0].select_network(id, freq=2412)
  709. (msg,addr) = sock.recvfrom(1000)
  710. logger.debug("Received DHCP message from %s" % str(addr))
  711. # Wait for HLP wait timeout to hit
  712. # FILS: HLP response timeout - continue with association response
  713. dev[0].wait_connected()
  714. dev[0].request("FILS_HLP_REQ_FLUSH")
  715. def test_fils_sk_hlp_oom(dev, apdev, params):
  716. """FILS SK HLP and hostapd OOM"""
  717. check_fils_capa(dev[0])
  718. check_erp_capa(dev[0])
  719. start_erp_as(apdev[1], msk_dump=os.path.join(params['logdir'], "msk.lst"))
  720. sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
  721. sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  722. sock.settimeout(5)
  723. sock.bind(("127.0.0.2", 67))
  724. bssid = apdev[0]['bssid']
  725. params = fils_hlp_config(fils_hlp_wait_time=500)
  726. params['dhcp_rapid_commit_proxy'] = '1'
  727. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  728. dev[0].scan_for_bss(bssid, freq=2412)
  729. dev[0].request("ERP_FLUSH")
  730. if "OK" not in dev[0].request("FILS_HLP_REQ_FLUSH"):
  731. raise Exception("Failed to flush pending FILS HLP requests")
  732. dhcpdisc = build_dhcp(req=True, dhcp_msg=DHCPDISCOVER,
  733. chaddr=dev[0].own_addr())
  734. if "OK" not in dev[0].request("FILS_HLP_REQ_ADD " + "ff:ff:ff:ff:ff:ff " + binascii.hexlify(dhcpdisc)):
  735. raise Exception("FILS_HLP_REQ_ADD failed")
  736. id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
  737. eap="PSK", identity="psk.user@example.com",
  738. password_hex="0123456789abcdef0123456789abcdef",
  739. erp="1", scan_freq="2412")
  740. dev[0].request("DISCONNECT")
  741. dev[0].wait_disconnected()
  742. dev[0].dump_monitor()
  743. with alloc_fail(hapd, 1, "fils_process_hlp"):
  744. dev[0].select_network(id, freq=2412)
  745. dev[0].wait_connected()
  746. dev[0].request("DISCONNECT")
  747. dev[0].wait_disconnected()
  748. dev[0].dump_monitor()
  749. with alloc_fail(hapd, 1, "fils_process_hlp_dhcp"):
  750. dev[0].select_network(id, freq=2412)
  751. dev[0].wait_connected()
  752. dev[0].request("DISCONNECT")
  753. dev[0].wait_disconnected()
  754. dev[0].dump_monitor()
  755. with alloc_fail(hapd, 1, "wpabuf_alloc;fils_process_hlp_dhcp"):
  756. dev[0].select_network(id, freq=2412)
  757. dev[0].wait_connected()
  758. dev[0].request("DISCONNECT")
  759. dev[0].wait_disconnected()
  760. dev[0].dump_monitor()
  761. with alloc_fail(hapd, 1, "wpabuf_alloc;fils_dhcp_handler"):
  762. dev[0].select_network(id, freq=2412)
  763. (msg,addr) = sock.recvfrom(1000)
  764. logger.debug("Received DHCP message from %s" % str(addr))
  765. dhcpdisc = build_dhcp(req=False, dhcp_msg=DHCPACK,
  766. chaddr=dev[0].own_addr(), giaddr="127.0.0.3")
  767. sock.sendto(dhcpdisc[2+20+8:], addr)
  768. dev[0].wait_connected()
  769. dev[0].request("DISCONNECT")
  770. dev[0].wait_disconnected()
  771. dev[0].dump_monitor()
  772. with alloc_fail(hapd, 1, "wpabuf_resize;fils_dhcp_handler"):
  773. dev[0].select_network(id, freq=2412)
  774. (msg,addr) = sock.recvfrom(1000)
  775. logger.debug("Received DHCP message from %s" % str(addr))
  776. dhcpdisc = build_dhcp(req=False, dhcp_msg=DHCPACK,
  777. chaddr=dev[0].own_addr(), giaddr="127.0.0.3")
  778. sock.sendto(dhcpdisc[2+20+8:], addr)
  779. dev[0].wait_connected()
  780. dev[0].request("DISCONNECT")
  781. dev[0].wait_disconnected()
  782. dev[0].dump_monitor()
  783. dev[0].select_network(id, freq=2412)
  784. (msg,addr) = sock.recvfrom(1000)
  785. logger.debug("Received DHCP message from %s" % str(addr))
  786. dhcpoffer = build_dhcp(req=False, dhcp_msg=DHCPOFFER, rapid_commit=False,
  787. chaddr=dev[0].own_addr(), giaddr="127.0.0.3")
  788. with alloc_fail(hapd, 1, "wpabuf_resize;fils_dhcp_request"):
  789. sock.sendto(dhcpoffer[2+20+8:], addr)
  790. dev[0].wait_connected()
  791. dev[0].request("DISCONNECT")
  792. dev[0].wait_disconnected()
  793. dev[0].request("FILS_HLP_REQ_FLUSH")
  794. def test_fils_sk_hlp_req_parsing(dev, apdev, params):
  795. """FILS SK HLP request parsing"""
  796. check_fils_capa(dev[0])
  797. check_erp_capa(dev[0])
  798. start_erp_as(apdev[1], msk_dump=os.path.join(params['logdir'], "msk.lst"))
  799. bssid = apdev[0]['bssid']
  800. params = fils_hlp_config(fils_hlp_wait_time=30)
  801. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  802. dev[0].scan_for_bss(bssid, freq=2412)
  803. dev[0].request("ERP_FLUSH")
  804. if "OK" not in dev[0].request("FILS_HLP_REQ_FLUSH"):
  805. raise Exception("Failed to flush pending FILS HLP requests")
  806. tot_len = 20 + 1
  807. start = struct.pack('>BBHHBBBB', 0x45, 0, tot_len, 0, 0, 0, 128, 17)
  808. _ip_src = '\x00\x00\x00\x00'
  809. _ip_dst = '\x00\x00\x00\x00'
  810. ipv4 = start + '\x00\x00' + _ip_src + _ip_dst
  811. csum = ip_checksum(ipv4)
  812. ipv4_overflow = start + csum + _ip_src + _ip_dst
  813. tot_len = 20
  814. start = struct.pack('>BBHHBBBB', 0x45, 0, tot_len, 0, 0, 0, 128, 123)
  815. ipv4 = start + '\x00\x00' + _ip_src + _ip_dst
  816. csum = ip_checksum(ipv4)
  817. ipv4_unknown_proto = start + csum + _ip_src + _ip_dst
  818. tot_len = 20
  819. start = struct.pack('>BBHHBBBB', 0x45, 0, tot_len, 0, 0, 0, 128, 17)
  820. ipv4 = start + '\x00\x00' + _ip_src + _ip_dst
  821. csum = ip_checksum(ipv4)
  822. ipv4_missing_udp_hdr = start + csum + _ip_src + _ip_dst
  823. src_port = 68
  824. dst_port = 67
  825. udp = struct.pack('>HHHH', src_port, dst_port, 8 + 1, 0)
  826. tot_len = 20 + len(udp)
  827. start = struct.pack('>BBHHBBBB', 0x45, 0, tot_len, 0, 0, 0, 128, 17)
  828. ipv4 = start + '\x00\x00' + _ip_src + _ip_dst
  829. csum = ip_checksum(ipv4)
  830. udp_overflow = start + csum + _ip_src + _ip_dst + udp
  831. udp = struct.pack('>HHHH', src_port, dst_port, 7, 0)
  832. tot_len = 20 + len(udp)
  833. start = struct.pack('>BBHHBBBB', 0x45, 0, tot_len, 0, 0, 0, 128, 17)
  834. ipv4 = start + '\x00\x00' + _ip_src + _ip_dst
  835. csum = ip_checksum(ipv4)
  836. udp_underflow = start + csum + _ip_src + _ip_dst + udp
  837. src_port = 123
  838. dst_port = 456
  839. udp = struct.pack('>HHHH', src_port, dst_port, 8, 0)
  840. tot_len = 20 + len(udp)
  841. start = struct.pack('>BBHHBBBB', 0x45, 0, tot_len, 0, 0, 0, 128, 17)
  842. ipv4 = start + '\x00\x00' + _ip_src + _ip_dst
  843. csum = ip_checksum(ipv4)
  844. udp_unknown_port = start + csum + _ip_src + _ip_dst + udp
  845. src_port = 68
  846. dst_port = 67
  847. udp = struct.pack('>HHHH', src_port, dst_port, 8, 0)
  848. tot_len = 20 + len(udp)
  849. start = struct.pack('>BBHHBBBB', 0x45, 0, tot_len, 0, 0, 0, 128, 17)
  850. ipv4 = start + '\x00\x00' + _ip_src + _ip_dst
  851. csum = ip_checksum(ipv4)
  852. dhcp_missing_data = start + csum + _ip_src + _ip_dst + udp
  853. dhcp_not_req = build_dhcp(req=True, dhcp_msg=DHCPDISCOVER,
  854. chaddr=dev[0].own_addr(), override_op=BOOTREPLY)
  855. dhcp_no_magic = build_dhcp(req=True, dhcp_msg=None,
  856. chaddr=dev[0].own_addr(), magic_override='',
  857. rapid_commit=False, opt_end=False)
  858. dhcp_unknown_magic = build_dhcp(req=True, dhcp_msg=DHCPDISCOVER,
  859. chaddr=dev[0].own_addr(),
  860. magic_override='\x00\x00\x00\x00')
  861. dhcp_opts = build_dhcp(req=True, dhcp_msg=DHCPNAK,
  862. chaddr=dev[0].own_addr(),
  863. extra_op='\x00\x11', opt_end=False)
  864. dhcp_opts2 = build_dhcp(req=True, dhcp_msg=DHCPNAK,
  865. chaddr=dev[0].own_addr(),
  866. extra_op='\x11\x01', opt_end=False)
  867. dhcp_valid = build_dhcp(req=True, dhcp_msg=DHCPDISCOVER,
  868. chaddr=dev[0].own_addr())
  869. tests = [ "ff",
  870. "0800",
  871. "0800" + 20*"00",
  872. "0800" + binascii.hexlify(ipv4_overflow),
  873. "0800" + binascii.hexlify(ipv4_unknown_proto),
  874. "0800" + binascii.hexlify(ipv4_missing_udp_hdr),
  875. "0800" + binascii.hexlify(udp_overflow),
  876. "0800" + binascii.hexlify(udp_underflow),
  877. "0800" + binascii.hexlify(udp_unknown_port),
  878. "0800" + binascii.hexlify(dhcp_missing_data),
  879. binascii.hexlify(dhcp_not_req),
  880. binascii.hexlify(dhcp_no_magic),
  881. binascii.hexlify(dhcp_unknown_magic) ]
  882. for t in tests:
  883. if "OK" not in dev[0].request("FILS_HLP_REQ_ADD ff:ff:ff:ff:ff:ff " + t):
  884. raise Exception("FILS_HLP_REQ_ADD failed: " + t)
  885. id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
  886. eap="PSK", identity="psk.user@example.com",
  887. password_hex="0123456789abcdef0123456789abcdef",
  888. erp="1", scan_freq="2412")
  889. dev[0].request("DISCONNECT")
  890. dev[0].wait_disconnected()
  891. dev[0].dump_monitor()
  892. dev[0].select_network(id, freq=2412)
  893. dev[0].wait_connected()
  894. dev[0].request("DISCONNECT")
  895. dev[0].wait_disconnected()
  896. dev[0].request("FILS_HLP_REQ_FLUSH")
  897. tests = [ binascii.hexlify(dhcp_opts),
  898. binascii.hexlify(dhcp_opts2) ]
  899. for t in tests:
  900. if "OK" not in dev[0].request("FILS_HLP_REQ_ADD ff:ff:ff:ff:ff:ff " + t):
  901. raise Exception("FILS_HLP_REQ_ADD failed: " + t)
  902. dev[0].dump_monitor()
  903. dev[0].select_network(id, freq=2412)
  904. dev[0].wait_connected()
  905. dev[0].request("DISCONNECT")
  906. dev[0].wait_disconnected()
  907. dev[0].request("FILS_HLP_REQ_FLUSH")
  908. if "OK" not in dev[0].request("FILS_HLP_REQ_ADD ff:ff:ff:ff:ff:ff " + binascii.hexlify(dhcp_valid)):
  909. raise Exception("FILS_HLP_REQ_ADD failed")
  910. hapd.set("own_ip_addr", "0.0.0.0")
  911. dev[0].select_network(id, freq=2412)
  912. dev[0].wait_connected()
  913. dev[0].request("DISCONNECT")
  914. dev[0].wait_disconnected()
  915. hapd.set("dhcp_server", "0.0.0.0")
  916. dev[0].select_network(id, freq=2412)
  917. dev[0].wait_connected()
  918. dev[0].request("DISCONNECT")
  919. dev[0].wait_disconnected()
  920. # FILS: Failed to bind DHCP socket: Address already in use
  921. sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
  922. sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  923. sock.settimeout(5)
  924. sock.bind(("127.0.0.2", 67))
  925. hapd.set("own_ip_addr", "127.0.0.2")
  926. hapd.set("dhcp_server", "127.0.0.2")
  927. dev[0].select_network(id, freq=2412)
  928. dev[0].wait_connected()
  929. dev[0].request("DISCONNECT")
  930. dev[0].wait_disconnected()
  931. # FILS: DHCP sendto failed: Invalid argument
  932. hapd.set("own_ip_addr", "127.0.0.3")
  933. hapd.set("dhcp_server", "127.0.0.2")
  934. hapd.set("dhcp_relay_port", "0")
  935. hapd.set("dhcp_server_port", "0")
  936. dev[0].select_network(id, freq=2412)
  937. dev[0].wait_connected()
  938. dev[0].request("DISCONNECT")
  939. dev[0].wait_disconnected()
  940. dev[0].request("FILS_HLP_REQ_FLUSH")
  941. def test_fils_sk_hlp_dhcp_parsing(dev, apdev, params):
  942. """FILS SK HLP and DHCP response parsing"""
  943. check_fils_capa(dev[0])
  944. check_erp_capa(dev[0])
  945. start_erp_as(apdev[1], msk_dump=os.path.join(params['logdir'], "msk.lst"))
  946. sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
  947. sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  948. sock.settimeout(5)
  949. sock.bind(("127.0.0.2", 67))
  950. bssid = apdev[0]['bssid']
  951. params = fils_hlp_config(fils_hlp_wait_time=30)
  952. params['dhcp_rapid_commit_proxy'] = '1'
  953. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  954. dev[0].scan_for_bss(bssid, freq=2412)
  955. dev[0].request("ERP_FLUSH")
  956. if "OK" not in dev[0].request("FILS_HLP_REQ_FLUSH"):
  957. raise Exception("Failed to flush pending FILS HLP requests")
  958. dhcpdisc = build_dhcp(req=True, dhcp_msg=DHCPDISCOVER,
  959. chaddr=dev[0].own_addr())
  960. if "OK" not in dev[0].request("FILS_HLP_REQ_ADD " + "ff:ff:ff:ff:ff:ff " + binascii.hexlify(dhcpdisc)):
  961. raise Exception("FILS_HLP_REQ_ADD failed")
  962. id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
  963. eap="PSK", identity="psk.user@example.com",
  964. password_hex="0123456789abcdef0123456789abcdef",
  965. erp="1", scan_freq="2412")
  966. dev[0].request("DISCONNECT")
  967. dev[0].wait_disconnected()
  968. dev[0].dump_monitor()
  969. with alloc_fail(hapd, 1, "fils_process_hlp"):
  970. dev[0].select_network(id, freq=2412)
  971. dev[0].wait_connected()
  972. dev[0].request("DISCONNECT")
  973. dev[0].wait_disconnected()
  974. dev[0].dump_monitor()
  975. dev[0].select_network(id, freq=2412)
  976. (msg,addr) = sock.recvfrom(1000)
  977. logger.debug("Received DHCP message from %s" % str(addr))
  978. dhcpdisc = build_dhcp(req=False, dhcp_msg=DHCPACK,
  979. chaddr=dev[0].own_addr(), giaddr="127.0.0.3")
  980. #sock.sendto(dhcpdisc[2+20+8:], addr)
  981. chaddr = binascii.unhexlify(dev[0].own_addr().replace(':','')) + 10*'\x00'
  982. tests = [ "\x00",
  983. "\x02" + 500 * "\x00",
  984. "\x02\x00\x00\x00" + 20*"\x00" + "\x7f\x00\x00\x03" + 500 * "\x00",
  985. "\x02\x00\x00\x00" + 20*"\x00" + "\x7f\x00\x00\x03" + 16*"\x00" + 64*"\x00" + 128*"\x00" + "\x63\x82\x53\x63",
  986. "\x02\x00\x00\x00" + 20*"\x00" + "\x7f\x00\x00\x03" + 16*"\x00" + 64*"\x00" + 128*"\x00" + "\x63\x82\x53\x63" + "\x00\x11",
  987. "\x02\x00\x00\x00" + 20*"\x00" + "\x7f\x00\x00\x03" + 16*"\x00" + 64*"\x00" + 128*"\x00" + "\x63\x82\x53\x63" + "\x11\x01",
  988. "\x02\x00\x00\x00" + 20*"\x00" + "\x7f\x00\x00\x03" + chaddr + 64*"\x00" + 128*"\x00" + "\x63\x82\x53\x63" + "\x35\x00\xff",
  989. "\x02\x00\x00\x00" + 20*"\x00" + "\x7f\x00\x00\x03" + chaddr + 64*"\x00" + 128*"\x00" + "\x63\x82\x53\x63" + "\x35\x01\x00\xff",
  990. 1501 * "\x00" ]
  991. for t in tests:
  992. sock.sendto(t, addr)
  993. dev[0].wait_connected()
  994. dev[0].request("DISCONNECT")
  995. dev[0].wait_disconnected()
  996. # FILS: DHCP sendto failed: Invalid argument for second DHCP TX in proxy
  997. dev[0].dump_monitor()
  998. dev[0].select_network(id, freq=2412)
  999. (msg,addr) = sock.recvfrom(1000)
  1000. logger.debug("Received DHCP message from %s" % str(addr))
  1001. hapd.set("dhcp_server_port", "0")
  1002. dhcpoffer = build_dhcp(req=False, dhcp_msg=DHCPOFFER, rapid_commit=False,
  1003. chaddr=dev[0].own_addr(), giaddr="127.0.0.3")
  1004. sock.sendto(dhcpoffer[2+20+8:], addr)
  1005. dev[0].wait_connected()
  1006. dev[0].request("DISCONNECT")
  1007. dev[0].wait_disconnected()
  1008. hapd.set("dhcp_server_port", "67")
  1009. # Options in DHCPOFFER
  1010. dev[0].dump_monitor()
  1011. dev[0].select_network(id, freq=2412)
  1012. (msg,addr) = sock.recvfrom(1000)
  1013. logger.debug("Received DHCP message from %s" % str(addr))
  1014. dhcpoffer = build_dhcp(req=False, dhcp_msg=DHCPOFFER, rapid_commit=False,
  1015. chaddr=dev[0].own_addr(), giaddr="127.0.0.3",
  1016. extra_op="\x00\x11", opt_end=False)
  1017. sock.sendto(dhcpoffer[2+20+8:], addr)
  1018. (msg,addr) = sock.recvfrom(1000)
  1019. logger.debug("Received DHCP message from %s" % str(addr))
  1020. dev[0].wait_connected()
  1021. dev[0].request("DISCONNECT")
  1022. dev[0].wait_disconnected()
  1023. # Options in DHCPOFFER (2)
  1024. dev[0].dump_monitor()
  1025. dev[0].select_network(id, freq=2412)
  1026. (msg,addr) = sock.recvfrom(1000)
  1027. logger.debug("Received DHCP message from %s" % str(addr))
  1028. dhcpoffer = build_dhcp(req=False, dhcp_msg=DHCPOFFER, rapid_commit=False,
  1029. chaddr=dev[0].own_addr(), giaddr="127.0.0.3",
  1030. extra_op="\x11\x01", opt_end=False)
  1031. sock.sendto(dhcpoffer[2+20+8:], addr)
  1032. (msg,addr) = sock.recvfrom(1000)
  1033. logger.debug("Received DHCP message from %s" % str(addr))
  1034. dev[0].wait_connected()
  1035. dev[0].request("DISCONNECT")
  1036. dev[0].wait_disconnected()
  1037. # Server ID in DHCPOFFER
  1038. dev[0].dump_monitor()
  1039. dev[0].select_network(id, freq=2412)
  1040. (msg,addr) = sock.recvfrom(1000)
  1041. logger.debug("Received DHCP message from %s" % str(addr))
  1042. dhcpoffer = build_dhcp(req=False, dhcp_msg=DHCPOFFER, rapid_commit=False,
  1043. chaddr=dev[0].own_addr(), giaddr="127.0.0.3",
  1044. extra_op="\x36\x01\x30")
  1045. sock.sendto(dhcpoffer[2+20+8:], addr)
  1046. (msg,addr) = sock.recvfrom(1000)
  1047. logger.debug("Received DHCP message from %s" % str(addr))
  1048. dev[0].wait_connected()
  1049. dev[0].request("DISCONNECT")
  1050. dev[0].wait_disconnected()
  1051. # FILS: Could not update DHCPDISCOVER
  1052. dev[0].request("FILS_HLP_REQ_FLUSH")
  1053. dhcpdisc = build_dhcp(req=True, dhcp_msg=DHCPDISCOVER,
  1054. chaddr=dev[0].own_addr(),
  1055. extra_op="\x00\x11", opt_end=False)
  1056. if "OK" not in dev[0].request("FILS_HLP_REQ_ADD " + "ff:ff:ff:ff:ff:ff " + binascii.hexlify(dhcpdisc)):
  1057. raise Exception("FILS_HLP_REQ_ADD failed")
  1058. dev[0].dump_monitor()
  1059. dev[0].select_network(id, freq=2412)
  1060. (msg,addr) = sock.recvfrom(1000)
  1061. logger.debug("Received DHCP message from %s" % str(addr))
  1062. dhcpoffer = build_dhcp(req=False, dhcp_msg=DHCPOFFER, rapid_commit=False,
  1063. chaddr=dev[0].own_addr(), giaddr="127.0.0.3",
  1064. extra_op="\x36\x01\x30")
  1065. sock.sendto(dhcpoffer[2+20+8:], addr)
  1066. dev[0].wait_connected()
  1067. dev[0].request("DISCONNECT")
  1068. dev[0].wait_disconnected()
  1069. # FILS: Could not update DHCPDISCOVER (2)
  1070. dev[0].request("FILS_HLP_REQ_FLUSH")
  1071. dhcpdisc = build_dhcp(req=True, dhcp_msg=DHCPDISCOVER,
  1072. chaddr=dev[0].own_addr(),
  1073. extra_op="\x11\x01", opt_end=False)
  1074. if "OK" not in dev[0].request("FILS_HLP_REQ_ADD " + "ff:ff:ff:ff:ff:ff " + binascii.hexlify(dhcpdisc)):
  1075. raise Exception("FILS_HLP_REQ_ADD failed")
  1076. dev[0].dump_monitor()
  1077. dev[0].select_network(id, freq=2412)
  1078. (msg,addr) = sock.recvfrom(1000)
  1079. logger.debug("Received DHCP message from %s" % str(addr))
  1080. dhcpoffer = build_dhcp(req=False, dhcp_msg=DHCPOFFER, rapid_commit=False,
  1081. chaddr=dev[0].own_addr(), giaddr="127.0.0.3",
  1082. extra_op="\x36\x01\x30")
  1083. sock.sendto(dhcpoffer[2+20+8:], addr)
  1084. dev[0].wait_connected()
  1085. dev[0].request("DISCONNECT")
  1086. dev[0].wait_disconnected()
  1087. dev[0].request("FILS_HLP_REQ_FLUSH")
  1088. def test_fils_sk_erp_and_reauth(dev, apdev, params):
  1089. """FILS SK using ERP and AP going away"""
  1090. check_fils_capa(dev[0])
  1091. check_erp_capa(dev[0])
  1092. start_erp_as(apdev[1], msk_dump=os.path.join(params['logdir'], "msk.lst"))
  1093. bssid = apdev[0]['bssid']
  1094. params = hostapd.wpa2_eap_params(ssid="fils")
  1095. params['wpa_key_mgmt'] = "FILS-SHA256"
  1096. params['auth_server_port'] = "18128"
  1097. params['erp_domain'] = 'example.com'
  1098. params['fils_realm'] = 'example.com'
  1099. params['disable_pmksa_caching'] = '1'
  1100. params['broadcast_deauth'] = '0'
  1101. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  1102. dev[0].scan_for_bss(bssid, freq=2412)
  1103. dev[0].request("ERP_FLUSH")
  1104. id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
  1105. eap="PSK", identity="psk.user@example.com",
  1106. password_hex="0123456789abcdef0123456789abcdef",
  1107. erp="1", scan_freq="2412")
  1108. hapd.disable()
  1109. dev[0].wait_disconnected()
  1110. dev[0].dump_monitor()
  1111. hapd.enable()
  1112. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
  1113. "EVENT-ASSOC-REJECT",
  1114. "CTRL-EVENT-CONNECTED"], timeout=10)
  1115. if ev is None:
  1116. raise Exception("Reconnection using FILS/ERP timed out")
  1117. if "CTRL-EVENT-EAP-STARTED" in ev:
  1118. raise Exception("Unexpected EAP exchange")
  1119. if "EVENT-ASSOC-REJECT" in ev:
  1120. raise Exception("Association failed")
  1121. def test_fils_sk_erp_sim(dev, apdev, params):
  1122. """FILS SK using ERP with SIM"""
  1123. check_fils_capa(dev[0])
  1124. check_erp_capa(dev[0])
  1125. realm='wlan.mnc001.mcc232.3gppnetwork.org'
  1126. start_erp_as(apdev[1], erp_domain=realm,
  1127. msk_dump=os.path.join(params['logdir'], "msk.lst"))
  1128. bssid = apdev[0]['bssid']
  1129. params = hostapd.wpa2_eap_params(ssid="fils")
  1130. params['wpa_key_mgmt'] = "FILS-SHA256"
  1131. params['auth_server_port'] = "18128"
  1132. params['fils_realm'] = realm
  1133. params['disable_pmksa_caching'] = '1'
  1134. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  1135. dev[0].scan_for_bss(bssid, freq=2412)
  1136. dev[0].request("ERP_FLUSH")
  1137. id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
  1138. eap="SIM", identity="1232010000000000@" + realm,
  1139. password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581",
  1140. erp="1", scan_freq="2412")
  1141. hapd.disable()
  1142. dev[0].wait_disconnected()
  1143. dev[0].dump_monitor()
  1144. hapd.enable()
  1145. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
  1146. "EVENT-ASSOC-REJECT",
  1147. "CTRL-EVENT-CONNECTED"], timeout=10)
  1148. if ev is None:
  1149. raise Exception("Reconnection using FILS/ERP timed out")
  1150. if "CTRL-EVENT-EAP-STARTED" in ev:
  1151. raise Exception("Unexpected EAP exchange")
  1152. if "EVENT-ASSOC-REJECT" in ev:
  1153. raise Exception("Association failed")
  1154. def test_fils_sk_pfs_19(dev, apdev, params):
  1155. """FILS SK with PFS (DH group 19)"""
  1156. run_fils_sk_pfs(dev, apdev, "19", params)
  1157. def test_fils_sk_pfs_20(dev, apdev, params):
  1158. """FILS SK with PFS (DH group 20)"""
  1159. run_fils_sk_pfs(dev, apdev, "20", params)
  1160. def test_fils_sk_pfs_21(dev, apdev, params):
  1161. """FILS SK with PFS (DH group 21)"""
  1162. run_fils_sk_pfs(dev, apdev, "21", params)
  1163. def test_fils_sk_pfs_25(dev, apdev, params):
  1164. """FILS SK with PFS (DH group 25)"""
  1165. run_fils_sk_pfs(dev, apdev, "25", params)
  1166. def test_fils_sk_pfs_26(dev, apdev, params):
  1167. """FILS SK with PFS (DH group 26)"""
  1168. run_fils_sk_pfs(dev, apdev, "26", params)
  1169. def test_fils_sk_pfs_27(dev, apdev, params):
  1170. """FILS SK with PFS (DH group 27)"""
  1171. run_fils_sk_pfs(dev, apdev, "27", params)
  1172. def test_fils_sk_pfs_28(dev, apdev, params):
  1173. """FILS SK with PFS (DH group 28)"""
  1174. run_fils_sk_pfs(dev, apdev, "28", params)
  1175. def test_fils_sk_pfs_29(dev, apdev, params):
  1176. """FILS SK with PFS (DH group 29)"""
  1177. run_fils_sk_pfs(dev, apdev, "29", params)
  1178. def test_fils_sk_pfs_30(dev, apdev, params):
  1179. """FILS SK with PFS (DH group 30)"""
  1180. run_fils_sk_pfs(dev, apdev, "30", params)
  1181. def run_fils_sk_pfs(dev, apdev, group, params):
  1182. check_fils_sk_pfs_capa(dev[0])
  1183. check_erp_capa(dev[0])
  1184. tls = dev[0].request("GET tls_library")
  1185. if int(group) in [ 27, 28, 29, 30 ]:
  1186. if not (tls.startswith("OpenSSL") and ("build=OpenSSL 1.0.2" in tls or "build=OpenSSL 1.1" in tls) and ("run=OpenSSL 1.0.2" in tls or "run=OpenSSL 1.1" in tls)):
  1187. raise HwsimSkip("Brainpool EC group not supported")
  1188. start_erp_as(apdev[1], msk_dump=os.path.join(params['logdir'], "msk.lst"))
  1189. bssid = apdev[0]['bssid']
  1190. params = hostapd.wpa2_eap_params(ssid="fils")
  1191. params['wpa_key_mgmt'] = "FILS-SHA256"
  1192. params['auth_server_port'] = "18128"
  1193. params['erp_domain'] = 'example.com'
  1194. params['fils_realm'] = 'example.com'
  1195. params['disable_pmksa_caching'] = '1'
  1196. params['fils_dh_group'] = group
  1197. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  1198. dev[0].scan_for_bss(bssid, freq=2412)
  1199. dev[0].request("ERP_FLUSH")
  1200. id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
  1201. eap="PSK", identity="psk.user@example.com",
  1202. password_hex="0123456789abcdef0123456789abcdef",
  1203. erp="1", fils_dh_group=group, scan_freq="2412")
  1204. dev[0].request("DISCONNECT")
  1205. dev[0].wait_disconnected()
  1206. dev[0].dump_monitor()
  1207. dev[0].select_network(id, freq=2412)
  1208. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
  1209. "EVENT-ASSOC-REJECT",
  1210. "CTRL-EVENT-CONNECTED"], timeout=10)
  1211. if ev is None:
  1212. raise Exception("Connection using FILS/ERP timed out")
  1213. if "CTRL-EVENT-EAP-STARTED" in ev:
  1214. raise Exception("Unexpected EAP exchange")
  1215. if "EVENT-ASSOC-REJECT" in ev:
  1216. raise Exception("Association failed")
  1217. hwsim_utils.test_connectivity(dev[0], hapd)
  1218. def test_fils_sk_pfs_group_mismatch(dev, apdev, params):
  1219. """FILS SK PFS DH group mismatch"""
  1220. check_fils_sk_pfs_capa(dev[0])
  1221. check_erp_capa(dev[0])
  1222. start_erp_as(apdev[1], msk_dump=os.path.join(params['logdir'], "msk.lst"))
  1223. bssid = apdev[0]['bssid']
  1224. params = hostapd.wpa2_eap_params(ssid="fils")
  1225. params['wpa_key_mgmt'] = "FILS-SHA256"
  1226. params['auth_server_port'] = "18128"
  1227. params['erp_domain'] = 'example.com'
  1228. params['fils_realm'] = 'example.com'
  1229. params['disable_pmksa_caching'] = '1'
  1230. params['fils_dh_group'] = "20"
  1231. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  1232. dev[0].scan_for_bss(bssid, freq=2412)
  1233. dev[0].request("ERP_FLUSH")
  1234. id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
  1235. eap="PSK", identity="psk.user@example.com",
  1236. password_hex="0123456789abcdef0123456789abcdef",
  1237. erp="1", fils_dh_group="19", scan_freq="2412")
  1238. dev[0].request("DISCONNECT")
  1239. dev[0].wait_disconnected()
  1240. dev[0].dump_monitor()
  1241. dev[0].select_network(id, freq=2412)
  1242. ev = dev[0].wait_event(["CTRL-EVENT-AUTH-REJECT"], timeout=10)
  1243. dev[0].request("DISCONNECT")
  1244. if ev is None:
  1245. raise Exception("Authentication rejection not seen")
  1246. if "auth_type=5 auth_transaction=2 status_code=77" not in ev:
  1247. raise Exception("Unexpected auth reject value: " + ev)
  1248. def test_fils_sk_auth_mismatch(dev, apdev, params):
  1249. """FILS SK authentication type mismatch (PFS not supported)"""
  1250. check_fils_sk_pfs_capa(dev[0])
  1251. check_erp_capa(dev[0])
  1252. start_erp_as(apdev[1], msk_dump=os.path.join(params['logdir'], "msk.lst"))
  1253. bssid = apdev[0]['bssid']
  1254. params = hostapd.wpa2_eap_params(ssid="fils")
  1255. params['wpa_key_mgmt'] = "FILS-SHA256"
  1256. params['auth_server_port'] = "18128"
  1257. params['erp_domain'] = 'example.com'
  1258. params['fils_realm'] = 'example.com'
  1259. params['disable_pmksa_caching'] = '1'
  1260. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  1261. dev[0].scan_for_bss(bssid, freq=2412)
  1262. dev[0].request("ERP_FLUSH")
  1263. id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
  1264. eap="PSK", identity="psk.user@example.com",
  1265. password_hex="0123456789abcdef0123456789abcdef",
  1266. erp="1", fils_dh_group="19", scan_freq="2412")
  1267. dev[0].request("DISCONNECT")
  1268. dev[0].wait_disconnected()
  1269. dev[0].dump_monitor()
  1270. dev[0].select_network(id, freq=2412)
  1271. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
  1272. "EVENT-ASSOC-REJECT",
  1273. "CTRL-EVENT-CONNECTED"], timeout=10)
  1274. if ev is None:
  1275. raise Exception("Connection using FILS/ERP timed out")
  1276. if "CTRL-EVENT-EAP-STARTED" not in ev:
  1277. raise Exception("No EAP exchange seen")
  1278. dev[0].wait_connected()
  1279. hwsim_utils.test_connectivity(dev[0], hapd)
  1280. def test_fils_auth_gtk_rekey(dev, apdev, params):
  1281. """GTK rekeying after FILS authentication"""
  1282. check_fils_capa(dev[0])
  1283. check_erp_capa(dev[0])
  1284. start_erp_as(apdev[1], msk_dump=os.path.join(params['logdir'], "msk.lst"))
  1285. bssid = apdev[0]['bssid']
  1286. params = hostapd.wpa2_eap_params(ssid="fils")
  1287. params['wpa_key_mgmt'] = "FILS-SHA256"
  1288. params['auth_server_port'] = "18128"
  1289. params['erp_domain'] = 'example.com'
  1290. params['fils_realm'] = 'example.com'
  1291. params['wpa_group_rekey'] = '1'
  1292. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  1293. dev[0].scan_for_bss(bssid, freq=2412)
  1294. dev[0].request("ERP_FLUSH")
  1295. id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
  1296. eap="PSK", identity="psk.user@example.com",
  1297. password_hex="0123456789abcdef0123456789abcdef",
  1298. erp="1", scan_freq="2412")
  1299. dev[0].request("DISCONNECT")
  1300. dev[0].wait_disconnected()
  1301. dev[0].dump_monitor()
  1302. dev[0].select_network(id, freq=2412)
  1303. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
  1304. "CTRL-EVENT-CONNECTED"], timeout=10)
  1305. if ev is None:
  1306. raise Exception("Connection using PMKSA caching timed out")
  1307. if "CTRL-EVENT-EAP-STARTED" in ev:
  1308. raise Exception("Unexpected EAP exchange")
  1309. dev[0].dump_monitor()
  1310. hwsim_utils.test_connectivity(dev[0], hapd)
  1311. ev = dev[0].wait_event(["WPA: Group rekeying completed"], timeout=2)
  1312. if ev is None:
  1313. raise Exception("GTK rekey timed out")
  1314. hwsim_utils.test_connectivity(dev[0], hapd)
  1315. ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=5)
  1316. if ev is not None:
  1317. raise Exception("Rekeying failed - disconnected")
  1318. hwsim_utils.test_connectivity(dev[0], hapd)
  1319. def test_fils_and_ft(dev, apdev, params):
  1320. """FILS SK using ERP and FT initial mobility domain association"""
  1321. check_fils_capa(dev[0])
  1322. check_erp_capa(dev[0])
  1323. er = start_erp_as(apdev[1],
  1324. msk_dump=os.path.join(params['logdir'], "msk.lst"))
  1325. bssid = apdev[0]['bssid']
  1326. params = hostapd.wpa2_eap_params(ssid="fils")
  1327. params['wpa_key_mgmt'] = "FILS-SHA256"
  1328. params['auth_server_port'] = "18128"
  1329. params['erp_domain'] = 'example.com'
  1330. params['fils_realm'] = 'example.com'
  1331. params['disable_pmksa_caching'] = '1'
  1332. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  1333. dev[0].scan_for_bss(bssid, freq=2412)
  1334. dev[0].request("ERP_FLUSH")
  1335. id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
  1336. eap="PSK", identity="psk.user@example.com",
  1337. password_hex="0123456789abcdef0123456789abcdef",
  1338. erp="1", scan_freq="2412")
  1339. dev[0].request("DISCONNECT")
  1340. dev[0].wait_disconnected()
  1341. hapd.disable()
  1342. dev[0].flush_scan_cache()
  1343. if "FAIL" in dev[0].request("PMKSA_FLUSH"):
  1344. raise Exception("PMKSA_FLUSH failed")
  1345. params = hostapd.wpa2_eap_params(ssid="fils-ft")
  1346. params['wpa_key_mgmt'] = "FILS-SHA256 FT-FILS-SHA256 FT-EAP"
  1347. params['auth_server_port'] = "18128"
  1348. params['erp_domain'] = 'example.com'
  1349. params['fils_realm'] = 'example.com'
  1350. params['disable_pmksa_caching'] = '1'
  1351. params["mobility_domain"] = "a1b2"
  1352. params["r0_key_lifetime"] = "10000"
  1353. params["pmk_r1_push"] = "1"
  1354. params["reassociation_deadline"] = "1000"
  1355. params['nas_identifier'] = "nas1.w1.fi"
  1356. params['r1_key_holder'] = "000102030405"
  1357. params['r0kh'] = [ "02:00:00:00:04:00 nas2.w1.fi 300102030405060708090a0b0c0d0e0f" ]
  1358. params['r1kh'] = "02:00:00:00:04:00 00:01:02:03:04:06 200102030405060708090a0b0c0d0e0f"
  1359. params['ieee80211w'] = "1"
  1360. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  1361. dev[0].scan_for_bss(bssid, freq=2412)
  1362. dev[0].dump_monitor()
  1363. id = dev[0].connect("fils-ft", key_mgmt="FILS-SHA256 FT-FILS-SHA256 FT-EAP",
  1364. ieee80211w="1",
  1365. eap="PSK", identity="psk.user@example.com",
  1366. password_hex="0123456789abcdef0123456789abcdef",
  1367. erp="1", scan_freq="2412", wait_connect=False)
  1368. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
  1369. "CTRL-EVENT-AUTH-REJECT",
  1370. "EVENT-ASSOC-REJECT",
  1371. "CTRL-EVENT-CONNECTED"], timeout=10)
  1372. if ev is None:
  1373. raise Exception("Connection using FILS/ERP timed out")
  1374. if "CTRL-EVENT-EAP-STARTED" in ev:
  1375. raise Exception("Unexpected EAP exchange")
  1376. if "CTRL-EVENT-AUTH-REJECT" in ev:
  1377. raise Exception("Authentication failed")
  1378. if "EVENT-ASSOC-REJECT" in ev:
  1379. raise Exception("Association failed")
  1380. hwsim_utils.test_connectivity(dev[0], hapd)
  1381. er.disable()
  1382. # FIX: FT-FILS-SHA256 does not currently work for FT protocol due to not
  1383. # fully defined FT Reassociation Request/Response frame MIC use in FTE.
  1384. # FT-EAP can be used to work around that in this test case to confirm the
  1385. # FT key hierarchy was properly formed in the previous step.
  1386. #params['wpa_key_mgmt'] = "FILS-SHA256 FT-FILS-SHA256"
  1387. params['wpa_key_mgmt'] = "FT-EAP"
  1388. params['nas_identifier'] = "nas2.w1.fi"
  1389. params['r1_key_holder'] = "000102030406"
  1390. params['r0kh'] = [ "02:00:00:00:03:00 nas1.w1.fi 200102030405060708090a0b0c0d0e0f" ]
  1391. params['r1kh'] = "02:00:00:00:03:00 00:01:02:03:04:05 300102030405060708090a0b0c0d0e0f"
  1392. hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
  1393. dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412", force_scan=True)
  1394. # FIX: Cannot use FT-over-DS without the FTE MIC issue addressed
  1395. #dev[0].roam_over_ds(apdev[1]['bssid'])
  1396. dev[0].roam(apdev[1]['bssid'])