test_fils.py 67 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725
  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_pfs_pmksa_caching(dev, apdev, params):
  1249. """FILS SK with PFS and PMKSA caching"""
  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['fils_dh_group'] = "19"
  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. pmksa = dev[0].get_pmksa(bssid)
  1268. if pmksa is None:
  1269. raise Exception("No PMKSA cache entry created")
  1270. dev[0].request("DISCONNECT")
  1271. dev[0].wait_disconnected()
  1272. # FILS authentication with PMKSA caching and PFS
  1273. dev[0].dump_monitor()
  1274. dev[0].select_network(id, freq=2412)
  1275. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
  1276. "CTRL-EVENT-CONNECTED"], timeout=10)
  1277. if ev is None:
  1278. raise Exception("Connection using PMKSA caching timed out")
  1279. if "CTRL-EVENT-EAP-STARTED" in ev:
  1280. raise Exception("Unexpected EAP exchange")
  1281. hwsim_utils.test_connectivity(dev[0], hapd)
  1282. pmksa2 = dev[0].get_pmksa(bssid)
  1283. if pmksa2 is None:
  1284. raise Exception("No PMKSA cache entry found")
  1285. if pmksa['pmkid'] != pmksa2['pmkid']:
  1286. raise Exception("Unexpected PMKID change")
  1287. # Verify EAPOL reauthentication after FILS authentication
  1288. hapd.request("EAPOL_REAUTH " + dev[0].own_addr())
  1289. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
  1290. if ev is None:
  1291. raise Exception("EAP authentication did not start")
  1292. ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=5)
  1293. if ev is None:
  1294. raise Exception("EAP authentication did not succeed")
  1295. time.sleep(0.1)
  1296. hwsim_utils.test_connectivity(dev[0], hapd)
  1297. dev[0].request("DISCONNECT")
  1298. dev[0].wait_disconnected()
  1299. # FILS authentication with ERP and PFS
  1300. dev[0].request("PMKSA_FLUSH")
  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-EAP-SUCCESS",
  1305. "CTRL-EVENT-CONNECTED"], timeout=10)
  1306. if ev is None:
  1307. raise Exception("Connection using ERP and PFS timed out")
  1308. if "CTRL-EVENT-EAP-STARTED" in ev:
  1309. raise Exception("Unexpected EAP exchange")
  1310. if "CTRL-EVENT-EAP-SUCCESS" not in ev:
  1311. raise Exception("ERP success not reported")
  1312. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
  1313. "SME: Trying to authenticate",
  1314. "CTRL-EVENT-CONNECTED"], timeout=10)
  1315. if ev is None:
  1316. raise Exception("Connection using ERP and PFS timed out")
  1317. if "CTRL-EVENT-EAP-STARTED" in ev:
  1318. raise Exception("Unexpected EAP exchange")
  1319. if "SME: Trying to authenticate" in ev:
  1320. raise Exception("Unexpected extra authentication round with ERP and PFS")
  1321. hwsim_utils.test_connectivity(dev[0], hapd)
  1322. pmksa3 = dev[0].get_pmksa(bssid)
  1323. if pmksa3 is None:
  1324. raise Exception("No PMKSA cache entry found")
  1325. if pmksa2['pmkid'] == pmksa3['pmkid']:
  1326. raise Exception("PMKID did not change")
  1327. dev[0].request("DISCONNECT")
  1328. dev[0].wait_disconnected()
  1329. # FILS authentication with PMKSA caching and PFS
  1330. dev[0].dump_monitor()
  1331. dev[0].select_network(id, freq=2412)
  1332. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
  1333. "CTRL-EVENT-CONNECTED"], timeout=10)
  1334. if ev is None:
  1335. raise Exception("Connection using PMKSA caching timed out")
  1336. if "CTRL-EVENT-EAP-STARTED" in ev:
  1337. raise Exception("Unexpected EAP exchange")
  1338. hwsim_utils.test_connectivity(dev[0], hapd)
  1339. pmksa4 = dev[0].get_pmksa(bssid)
  1340. if pmksa4 is None:
  1341. raise Exception("No PMKSA cache entry found")
  1342. if pmksa3['pmkid'] != pmksa4['pmkid']:
  1343. raise Exception("Unexpected PMKID change (2)")
  1344. def test_fils_sk_auth_mismatch(dev, apdev, params):
  1345. """FILS SK authentication type mismatch (PFS not supported)"""
  1346. check_fils_sk_pfs_capa(dev[0])
  1347. check_erp_capa(dev[0])
  1348. start_erp_as(apdev[1], msk_dump=os.path.join(params['logdir'], "msk.lst"))
  1349. bssid = apdev[0]['bssid']
  1350. params = hostapd.wpa2_eap_params(ssid="fils")
  1351. params['wpa_key_mgmt'] = "FILS-SHA256"
  1352. params['auth_server_port'] = "18128"
  1353. params['erp_domain'] = 'example.com'
  1354. params['fils_realm'] = 'example.com'
  1355. params['disable_pmksa_caching'] = '1'
  1356. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  1357. dev[0].scan_for_bss(bssid, freq=2412)
  1358. dev[0].request("ERP_FLUSH")
  1359. id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
  1360. eap="PSK", identity="psk.user@example.com",
  1361. password_hex="0123456789abcdef0123456789abcdef",
  1362. erp="1", fils_dh_group="19", scan_freq="2412")
  1363. dev[0].request("DISCONNECT")
  1364. dev[0].wait_disconnected()
  1365. dev[0].dump_monitor()
  1366. dev[0].select_network(id, freq=2412)
  1367. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
  1368. "EVENT-ASSOC-REJECT",
  1369. "CTRL-EVENT-CONNECTED"], timeout=10)
  1370. if ev is None:
  1371. raise Exception("Connection using FILS/ERP timed out")
  1372. if "CTRL-EVENT-EAP-STARTED" not in ev:
  1373. raise Exception("No EAP exchange seen")
  1374. dev[0].wait_connected()
  1375. hwsim_utils.test_connectivity(dev[0], hapd)
  1376. def test_fils_auth_gtk_rekey(dev, apdev, params):
  1377. """GTK rekeying after FILS authentication"""
  1378. check_fils_capa(dev[0])
  1379. check_erp_capa(dev[0])
  1380. start_erp_as(apdev[1], msk_dump=os.path.join(params['logdir'], "msk.lst"))
  1381. bssid = apdev[0]['bssid']
  1382. params = hostapd.wpa2_eap_params(ssid="fils")
  1383. params['wpa_key_mgmt'] = "FILS-SHA256"
  1384. params['auth_server_port'] = "18128"
  1385. params['erp_domain'] = 'example.com'
  1386. params['fils_realm'] = 'example.com'
  1387. params['wpa_group_rekey'] = '1'
  1388. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  1389. dev[0].scan_for_bss(bssid, freq=2412)
  1390. dev[0].request("ERP_FLUSH")
  1391. id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
  1392. eap="PSK", identity="psk.user@example.com",
  1393. password_hex="0123456789abcdef0123456789abcdef",
  1394. erp="1", scan_freq="2412")
  1395. dev[0].request("DISCONNECT")
  1396. dev[0].wait_disconnected()
  1397. dev[0].dump_monitor()
  1398. dev[0].select_network(id, freq=2412)
  1399. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
  1400. "CTRL-EVENT-CONNECTED"], timeout=10)
  1401. if ev is None:
  1402. raise Exception("Connection using PMKSA caching timed out")
  1403. if "CTRL-EVENT-EAP-STARTED" in ev:
  1404. raise Exception("Unexpected EAP exchange")
  1405. dev[0].dump_monitor()
  1406. hwsim_utils.test_connectivity(dev[0], hapd)
  1407. ev = dev[0].wait_event(["WPA: Group rekeying completed"], timeout=2)
  1408. if ev is None:
  1409. raise Exception("GTK rekey timed out")
  1410. hwsim_utils.test_connectivity(dev[0], hapd)
  1411. ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=5)
  1412. if ev is not None:
  1413. raise Exception("Rekeying failed - disconnected")
  1414. hwsim_utils.test_connectivity(dev[0], hapd)
  1415. def test_fils_and_ft(dev, apdev, params):
  1416. """FILS SK using ERP and FT initial mobility domain association"""
  1417. check_fils_capa(dev[0])
  1418. check_erp_capa(dev[0])
  1419. er = start_erp_as(apdev[1],
  1420. msk_dump=os.path.join(params['logdir'], "msk.lst"))
  1421. bssid = apdev[0]['bssid']
  1422. params = hostapd.wpa2_eap_params(ssid="fils")
  1423. params['wpa_key_mgmt'] = "FILS-SHA256"
  1424. params['auth_server_port'] = "18128"
  1425. params['erp_domain'] = 'example.com'
  1426. params['fils_realm'] = 'example.com'
  1427. params['disable_pmksa_caching'] = '1'
  1428. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  1429. dev[0].scan_for_bss(bssid, freq=2412)
  1430. dev[0].request("ERP_FLUSH")
  1431. id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
  1432. eap="PSK", identity="psk.user@example.com",
  1433. password_hex="0123456789abcdef0123456789abcdef",
  1434. erp="1", scan_freq="2412")
  1435. dev[0].request("DISCONNECT")
  1436. dev[0].wait_disconnected()
  1437. hapd.disable()
  1438. dev[0].flush_scan_cache()
  1439. if "FAIL" in dev[0].request("PMKSA_FLUSH"):
  1440. raise Exception("PMKSA_FLUSH failed")
  1441. params = hostapd.wpa2_eap_params(ssid="fils-ft")
  1442. params['wpa_key_mgmt'] = "FILS-SHA256 FT-FILS-SHA256 FT-EAP"
  1443. params['auth_server_port'] = "18128"
  1444. params['erp_domain'] = 'example.com'
  1445. params['fils_realm'] = 'example.com'
  1446. params['disable_pmksa_caching'] = '1'
  1447. params["mobility_domain"] = "a1b2"
  1448. params["r0_key_lifetime"] = "10000"
  1449. params["pmk_r1_push"] = "1"
  1450. params["reassociation_deadline"] = "1000"
  1451. params['nas_identifier'] = "nas1.w1.fi"
  1452. params['r1_key_holder'] = "000102030405"
  1453. params['r0kh'] = [ "02:00:00:00:04:00 nas2.w1.fi 300102030405060708090a0b0c0d0e0f" ]
  1454. params['r1kh'] = "02:00:00:00:04:00 00:01:02:03:04:06 200102030405060708090a0b0c0d0e0f"
  1455. params['ieee80211w'] = "1"
  1456. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  1457. dev[0].scan_for_bss(bssid, freq=2412)
  1458. dev[0].dump_monitor()
  1459. id = dev[0].connect("fils-ft", key_mgmt="FILS-SHA256 FT-FILS-SHA256 FT-EAP",
  1460. ieee80211w="1",
  1461. eap="PSK", identity="psk.user@example.com",
  1462. password_hex="0123456789abcdef0123456789abcdef",
  1463. erp="1", scan_freq="2412", wait_connect=False)
  1464. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
  1465. "CTRL-EVENT-AUTH-REJECT",
  1466. "EVENT-ASSOC-REJECT",
  1467. "CTRL-EVENT-CONNECTED"], timeout=10)
  1468. if ev is None:
  1469. raise Exception("Connection using FILS/ERP timed out")
  1470. if "CTRL-EVENT-EAP-STARTED" in ev:
  1471. raise Exception("Unexpected EAP exchange")
  1472. if "CTRL-EVENT-AUTH-REJECT" in ev:
  1473. raise Exception("Authentication failed")
  1474. if "EVENT-ASSOC-REJECT" in ev:
  1475. raise Exception("Association failed")
  1476. hwsim_utils.test_connectivity(dev[0], hapd)
  1477. er.disable()
  1478. # FIX: FT-FILS-SHA256 does not currently work for FT protocol due to not
  1479. # fully defined FT Reassociation Request/Response frame MIC use in FTE.
  1480. # FT-EAP can be used to work around that in this test case to confirm the
  1481. # FT key hierarchy was properly formed in the previous step.
  1482. #params['wpa_key_mgmt'] = "FILS-SHA256 FT-FILS-SHA256"
  1483. params['wpa_key_mgmt'] = "FT-EAP"
  1484. params['nas_identifier'] = "nas2.w1.fi"
  1485. params['r1_key_holder'] = "000102030406"
  1486. params['r0kh'] = [ "02:00:00:00:03:00 nas1.w1.fi 200102030405060708090a0b0c0d0e0f" ]
  1487. params['r1kh'] = "02:00:00:00:03:00 00:01:02:03:04:05 300102030405060708090a0b0c0d0e0f"
  1488. hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
  1489. dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412", force_scan=True)
  1490. # FIX: Cannot use FT-over-DS without the FTE MIC issue addressed
  1491. #dev[0].roam_over_ds(apdev[1]['bssid'])
  1492. dev[0].roam(apdev[1]['bssid'])