test_ap_ft.py 79 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996
  1. # Fast BSS Transition tests
  2. # Copyright (c) 2013-2017, Jouni Malinen <j@w1.fi>
  3. #
  4. # This software may be distributed under the terms of the BSD license.
  5. # See README for more details.
  6. from remotehost import remote_compatible
  7. import binascii
  8. import os
  9. import time
  10. import logging
  11. logger = logging.getLogger()
  12. import struct
  13. import hwsim_utils
  14. import hostapd
  15. from tshark import run_tshark
  16. from utils import HwsimSkip, alloc_fail, fail_test, wait_fail_trigger, skip_with_fips, parse_ie
  17. from wlantest import Wlantest
  18. from test_ap_psk import check_mib, find_wpas_process, read_process_memory, verify_not_present, get_key_locations
  19. def ft_base_rsn():
  20. params = { "wpa": "2",
  21. "wpa_key_mgmt": "FT-PSK",
  22. "rsn_pairwise": "CCMP" }
  23. return params
  24. def ft_base_mixed():
  25. params = { "wpa": "3",
  26. "wpa_key_mgmt": "WPA-PSK FT-PSK",
  27. "wpa_pairwise": "TKIP",
  28. "rsn_pairwise": "CCMP" }
  29. return params
  30. def ft_params(rsn=True, ssid=None, passphrase=None):
  31. if rsn:
  32. params = ft_base_rsn()
  33. else:
  34. params = ft_base_mixed()
  35. if ssid:
  36. params["ssid"] = ssid
  37. if passphrase:
  38. params["wpa_passphrase"] = passphrase
  39. params["mobility_domain"] = "a1b2"
  40. params["r0_key_lifetime"] = "10000"
  41. params["pmk_r1_push"] = "1"
  42. params["reassociation_deadline"] = "1000"
  43. return params
  44. def ft_params1a(rsn=True, ssid=None, passphrase=None):
  45. params = ft_params(rsn, ssid, passphrase)
  46. params['nas_identifier'] = "nas1.w1.fi"
  47. params['r1_key_holder'] = "000102030405"
  48. return params
  49. def ft_params1(rsn=True, ssid=None, passphrase=None, discovery=False):
  50. params = ft_params1a(rsn, ssid, passphrase)
  51. if discovery:
  52. params['r0kh'] = "ff:ff:ff:ff:ff:ff * 100102030405060708090a0b0c0d0e0f100102030405060708090a0b0c0d0e0f"
  53. params['r1kh'] = "00:00:00:00:00:00 00:00:00:00:00:00 100102030405060708090a0b0c0d0e0f100102030405060708090a0b0c0d0e0f"
  54. else:
  55. params['r0kh'] = [ "02:00:00:00:03:00 nas1.w1.fi 100102030405060708090a0b0c0d0e0f100102030405060708090a0b0c0d0e0f",
  56. "02:00:00:00:04:00 nas2.w1.fi 300102030405060708090a0b0c0d0e0f300102030405060708090a0b0c0d0e0f" ]
  57. params['r1kh'] = "02:00:00:00:04:00 00:01:02:03:04:06 200102030405060708090a0b0c0d0e0f200102030405060708090a0b0c0d0e0f"
  58. return params
  59. def ft_params1_old_key(rsn=True, ssid=None, passphrase=None):
  60. params = ft_params1a(rsn, ssid, passphrase)
  61. params['r0kh'] = [ "02:00:00:00:03:00 nas1.w1.fi 100102030405060708090a0b0c0d0e0f",
  62. "02:00:00:00:04:00 nas2.w1.fi 300102030405060708090a0b0c0d0e0f" ]
  63. params['r1kh'] = "02:00:00:00:04:00 00:01:02:03:04:06 200102030405060708090a0b0c0d0e0f"
  64. return params
  65. def ft_params2a(rsn=True, ssid=None, passphrase=None):
  66. params = ft_params(rsn, ssid, passphrase)
  67. params['nas_identifier'] = "nas2.w1.fi"
  68. params['r1_key_holder'] = "000102030406"
  69. return params
  70. def ft_params2(rsn=True, ssid=None, passphrase=None, discovery=False):
  71. params = ft_params2a(rsn, ssid, passphrase)
  72. if discovery:
  73. params['r0kh'] = "ff:ff:ff:ff:ff:ff * 100102030405060708090a0b0c0d0e0f100102030405060708090a0b0c0d0e0f"
  74. params['r1kh'] = "00:00:00:00:00:00 00:00:00:00:00:00 100102030405060708090a0b0c0d0e0f100102030405060708090a0b0c0d0e0f"
  75. else:
  76. params['r0kh'] = [ "02:00:00:00:03:00 nas1.w1.fi 200102030405060708090a0b0c0d0e0f200102030405060708090a0b0c0d0e0f",
  77. "02:00:00:00:04:00 nas2.w1.fi 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f" ]
  78. params['r1kh'] = "02:00:00:00:03:00 00:01:02:03:04:05 300102030405060708090a0b0c0d0e0f300102030405060708090a0b0c0d0e0f"
  79. return params
  80. def ft_params2_old_key(rsn=True, ssid=None, passphrase=None):
  81. params = ft_params2a(rsn, ssid, passphrase)
  82. params['r0kh'] = [ "02:00:00:00:03:00 nas1.w1.fi 200102030405060708090a0b0c0d0e0f",
  83. "02:00:00:00:04:00 nas2.w1.fi 000102030405060708090a0b0c0d0e0f" ]
  84. params['r1kh'] = "02:00:00:00:03:00 00:01:02:03:04:05 300102030405060708090a0b0c0d0e0f"
  85. return params
  86. def ft_params1_r0kh_mismatch(rsn=True, ssid=None, passphrase=None):
  87. params = ft_params(rsn, ssid, passphrase)
  88. params['nas_identifier'] = "nas1.w1.fi"
  89. params['r1_key_holder'] = "000102030405"
  90. params['r0kh'] = [ "02:00:00:00:03:00 nas1.w1.fi 100102030405060708090a0b0c0d0e0f100102030405060708090a0b0c0d0e0f",
  91. "12:00:00:00:04:00 nas2.w1.fi 300102030405060708090a0b0c0d0e0f300102030405060708090a0b0c0d0e0f" ]
  92. params['r1kh'] = "12:00:00:00:04:00 10:01:02:03:04:06 200102030405060708090a0b0c0d0e0f200102030405060708090a0b0c0d0e0f"
  93. return params
  94. def ft_params2_incorrect_rrb_key(rsn=True, ssid=None, passphrase=None):
  95. params = ft_params(rsn, ssid, passphrase)
  96. params['nas_identifier'] = "nas2.w1.fi"
  97. params['r1_key_holder'] = "000102030406"
  98. params['r0kh'] = [ "02:00:00:00:03:00 nas1.w1.fi 200102030405060708090a0b0c0d0ef1200102030405060708090a0b0c0d0ef1",
  99. "02:00:00:00:04:00 nas2.w1.fi 000102030405060708090a0b0c0d0ef2000102030405060708090a0b0c0d0ef2" ]
  100. params['r1kh'] = "02:00:00:00:03:00 00:01:02:03:04:05 300102030405060708090a0b0c0d0ef3300102030405060708090a0b0c0d0ef3"
  101. return params
  102. def ft_params2_r0kh_mismatch(rsn=True, ssid=None, passphrase=None):
  103. params = ft_params(rsn, ssid, passphrase)
  104. params['nas_identifier'] = "nas2.w1.fi"
  105. params['r1_key_holder'] = "000102030406"
  106. params['r0kh'] = [ "12:00:00:00:03:00 nas1.w1.fi 200102030405060708090a0b0c0d0e0f200102030405060708090a0b0c0d0e0f",
  107. "02:00:00:00:04:00 nas2.w1.fi 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f" ]
  108. params['r1kh'] = "12:00:00:00:03:00 10:01:02:03:04:05 300102030405060708090a0b0c0d0e0f300102030405060708090a0b0c0d0e0f"
  109. return params
  110. def run_roams(dev, apdev, hapd0, hapd1, ssid, passphrase, over_ds=False,
  111. sae=False, eap=False, fail_test=False, roams=1,
  112. pairwise_cipher="CCMP", group_cipher="TKIP CCMP", ptk_rekey="0",
  113. test_connectivity=True):
  114. logger.info("Connect to first AP")
  115. if eap:
  116. dev.connect(ssid, key_mgmt="FT-EAP", proto="WPA2", ieee80211w="1",
  117. eap="GPSK", identity="gpsk user",
  118. password="abcdefghijklmnop0123456789abcdef",
  119. scan_freq="2412",
  120. pairwise=pairwise_cipher, group=group_cipher,
  121. wpa_ptk_rekey=ptk_rekey)
  122. else:
  123. if sae:
  124. key_mgmt="FT-SAE"
  125. else:
  126. key_mgmt="FT-PSK"
  127. dev.connect(ssid, psk=passphrase, key_mgmt=key_mgmt, proto="WPA2",
  128. ieee80211w="1", scan_freq="2412",
  129. pairwise=pairwise_cipher, group=group_cipher,
  130. wpa_ptk_rekey=ptk_rekey)
  131. if dev.get_status_field('bssid') == apdev[0]['bssid']:
  132. ap1 = apdev[0]
  133. ap2 = apdev[1]
  134. hapd1ap = hapd0
  135. hapd2ap = hapd1
  136. else:
  137. ap1 = apdev[1]
  138. ap2 = apdev[0]
  139. hapd1ap = hapd1
  140. hapd2ap = hapd0
  141. if test_connectivity:
  142. hwsim_utils.test_connectivity(dev, hapd1ap)
  143. dev.scan_for_bss(ap2['bssid'], freq="2412")
  144. for i in range(0, roams):
  145. logger.info("Roam to the second AP")
  146. if over_ds:
  147. dev.roam_over_ds(ap2['bssid'], fail_test=fail_test)
  148. else:
  149. dev.roam(ap2['bssid'], fail_test=fail_test)
  150. if fail_test:
  151. return
  152. if dev.get_status_field('bssid') != ap2['bssid']:
  153. raise Exception("Did not connect to correct AP")
  154. if (i == 0 or i == roams - 1) and test_connectivity:
  155. hwsim_utils.test_connectivity(dev, hapd2ap)
  156. logger.info("Roam back to the first AP")
  157. if over_ds:
  158. dev.roam_over_ds(ap1['bssid'])
  159. else:
  160. dev.roam(ap1['bssid'])
  161. if dev.get_status_field('bssid') != ap1['bssid']:
  162. raise Exception("Did not connect to correct AP")
  163. if (i == 0 or i == roams - 1) and test_connectivity:
  164. hwsim_utils.test_connectivity(dev, hapd1ap)
  165. def test_ap_ft(dev, apdev):
  166. """WPA2-PSK-FT AP"""
  167. ssid = "test-ft"
  168. passphrase="12345678"
  169. params = ft_params1(ssid=ssid, passphrase=passphrase)
  170. hapd0 = hostapd.add_ap(apdev[0], params)
  171. params = ft_params2(ssid=ssid, passphrase=passphrase)
  172. hapd1 = hostapd.add_ap(apdev[1], params)
  173. run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase)
  174. if "[WPA2-FT/PSK-CCMP]" not in dev[0].request("SCAN_RESULTS"):
  175. raise Exception("Scan results missing RSN element info")
  176. def test_ap_ft_old_key(dev, apdev):
  177. """WPA2-PSK-FT AP (old key)"""
  178. ssid = "test-ft"
  179. passphrase="12345678"
  180. params = ft_params1_old_key(ssid=ssid, passphrase=passphrase)
  181. hapd0 = hostapd.add_ap(apdev[0], params)
  182. params = ft_params2_old_key(ssid=ssid, passphrase=passphrase)
  183. hapd1 = hostapd.add_ap(apdev[1], params)
  184. run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase)
  185. def test_ap_ft_multi_akm(dev, apdev):
  186. """WPA2-PSK-FT AP with non-FT AKMs enabled"""
  187. ssid = "test-ft"
  188. passphrase="12345678"
  189. params = ft_params1(ssid=ssid, passphrase=passphrase)
  190. params["wpa_key_mgmt"] = "FT-PSK WPA-PSK WPA-PSK-SHA256"
  191. hapd0 = hostapd.add_ap(apdev[0], params)
  192. params = ft_params2(ssid=ssid, passphrase=passphrase)
  193. params["wpa_key_mgmt"] = "FT-PSK WPA-PSK WPA-PSK-SHA256"
  194. hapd1 = hostapd.add_ap(apdev[1], params)
  195. Wlantest.setup(hapd0)
  196. wt = Wlantest()
  197. wt.flush()
  198. wt.add_passphrase(passphrase)
  199. run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase)
  200. if "[WPA2-PSK+FT/PSK+PSK-SHA256-CCMP]" not in dev[0].request("SCAN_RESULTS"):
  201. raise Exception("Scan results missing RSN element info")
  202. dev[1].connect(ssid, psk=passphrase, scan_freq="2412")
  203. dev[2].connect(ssid, psk=passphrase, key_mgmt="WPA-PSK-SHA256",
  204. scan_freq="2412")
  205. def test_ap_ft_local_key_gen(dev, apdev):
  206. """WPA2-PSK-FT AP with local key generation (without pull/push)"""
  207. ssid = "test-ft"
  208. passphrase="12345678"
  209. params = ft_params1a(ssid=ssid, passphrase=passphrase)
  210. params['ft_psk_generate_local'] = "1";
  211. del params['pmk_r1_push']
  212. hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
  213. params = ft_params2a(ssid=ssid, passphrase=passphrase)
  214. params['ft_psk_generate_local'] = "1";
  215. del params['pmk_r1_push']
  216. hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
  217. run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase)
  218. if "[WPA2-FT/PSK-CCMP]" not in dev[0].request("SCAN_RESULTS"):
  219. raise Exception("Scan results missing RSN element info")
  220. def test_ap_ft_many(dev, apdev):
  221. """WPA2-PSK-FT AP multiple times"""
  222. ssid = "test-ft"
  223. passphrase="12345678"
  224. params = ft_params1(ssid=ssid, passphrase=passphrase)
  225. hapd0 = hostapd.add_ap(apdev[0], params)
  226. params = ft_params2(ssid=ssid, passphrase=passphrase)
  227. hapd1 = hostapd.add_ap(apdev[1], params)
  228. run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, roams=50)
  229. def test_ap_ft_mixed(dev, apdev):
  230. """WPA2-PSK-FT mixed-mode AP"""
  231. ssid = "test-ft-mixed"
  232. passphrase="12345678"
  233. params = ft_params1(rsn=False, ssid=ssid, passphrase=passphrase)
  234. hapd = hostapd.add_ap(apdev[0], params)
  235. key_mgmt = hapd.get_config()['key_mgmt']
  236. vals = key_mgmt.split(' ')
  237. if vals[0] != "WPA-PSK" or vals[1] != "FT-PSK":
  238. raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
  239. params = ft_params2(rsn=False, ssid=ssid, passphrase=passphrase)
  240. hapd1 = hostapd.add_ap(apdev[1], params)
  241. run_roams(dev[0], apdev, hapd, hapd1, ssid, passphrase)
  242. def test_ap_ft_pmf(dev, apdev):
  243. """WPA2-PSK-FT AP with PMF"""
  244. ssid = "test-ft"
  245. passphrase="12345678"
  246. params = ft_params1(ssid=ssid, passphrase=passphrase)
  247. params["ieee80211w"] = "2"
  248. hapd0 = hostapd.add_ap(apdev[0], params)
  249. params = ft_params2(ssid=ssid, passphrase=passphrase)
  250. params["ieee80211w"] = "2"
  251. hapd1 = hostapd.add_ap(apdev[1], params)
  252. run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase)
  253. def test_ap_ft_over_ds(dev, apdev):
  254. """WPA2-PSK-FT AP over DS"""
  255. ssid = "test-ft"
  256. passphrase="12345678"
  257. params = ft_params1(ssid=ssid, passphrase=passphrase)
  258. hapd0 = hostapd.add_ap(apdev[0], params)
  259. params = ft_params2(ssid=ssid, passphrase=passphrase)
  260. hapd1 = hostapd.add_ap(apdev[1], params)
  261. run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True)
  262. check_mib(dev[0], [ ("dot11RSNAAuthenticationSuiteRequested", "00-0f-ac-4"),
  263. ("dot11RSNAAuthenticationSuiteSelected", "00-0f-ac-4") ])
  264. def test_ap_ft_over_ds_disabled(dev, apdev):
  265. """WPA2-PSK-FT AP over DS disabled"""
  266. ssid = "test-ft"
  267. passphrase="12345678"
  268. params = ft_params1(ssid=ssid, passphrase=passphrase)
  269. params['ft_over_ds'] = '0'
  270. hapd0 = hostapd.add_ap(apdev[0], params)
  271. params = ft_params2(ssid=ssid, passphrase=passphrase)
  272. params['ft_over_ds'] = '0'
  273. hapd1 = hostapd.add_ap(apdev[1], params)
  274. run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
  275. fail_test=True)
  276. def test_ap_ft_over_ds_many(dev, apdev):
  277. """WPA2-PSK-FT AP over DS multiple times"""
  278. ssid = "test-ft"
  279. passphrase="12345678"
  280. params = ft_params1(ssid=ssid, passphrase=passphrase)
  281. hapd0 = hostapd.add_ap(apdev[0], params)
  282. params = ft_params2(ssid=ssid, passphrase=passphrase)
  283. hapd1 = hostapd.add_ap(apdev[1], params)
  284. run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
  285. roams=50)
  286. @remote_compatible
  287. def test_ap_ft_over_ds_unknown_target(dev, apdev):
  288. """WPA2-PSK-FT AP"""
  289. ssid = "test-ft"
  290. passphrase="12345678"
  291. params = ft_params1(ssid=ssid, passphrase=passphrase)
  292. hapd0 = hostapd.add_ap(apdev[0], params)
  293. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  294. scan_freq="2412")
  295. dev[0].roam_over_ds("02:11:22:33:44:55", fail_test=True)
  296. @remote_compatible
  297. def test_ap_ft_over_ds_unexpected(dev, apdev):
  298. """WPA2-PSK-FT AP over DS and unexpected response"""
  299. ssid = "test-ft"
  300. passphrase="12345678"
  301. params = ft_params1(ssid=ssid, passphrase=passphrase)
  302. hapd0 = hostapd.add_ap(apdev[0], params)
  303. params = ft_params2(ssid=ssid, passphrase=passphrase)
  304. hapd1 = hostapd.add_ap(apdev[1], params)
  305. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  306. scan_freq="2412")
  307. if dev[0].get_status_field('bssid') == apdev[0]['bssid']:
  308. ap1 = apdev[0]
  309. ap2 = apdev[1]
  310. hapd1ap = hapd0
  311. hapd2ap = hapd1
  312. else:
  313. ap1 = apdev[1]
  314. ap2 = apdev[0]
  315. hapd1ap = hapd1
  316. hapd2ap = hapd0
  317. addr = dev[0].own_addr()
  318. hapd1ap.set("ext_mgmt_frame_handling", "1")
  319. logger.info("Foreign STA address")
  320. msg = {}
  321. msg['fc'] = 13 << 4
  322. msg['da'] = addr
  323. msg['sa'] = ap1['bssid']
  324. msg['bssid'] = ap1['bssid']
  325. msg['payload'] = binascii.unhexlify("06021122334455660102030405060000")
  326. hapd1ap.mgmt_tx(msg)
  327. logger.info("No over-the-DS in progress")
  328. msg['payload'] = binascii.unhexlify("0602" + addr.replace(':', '') + "0102030405060000")
  329. hapd1ap.mgmt_tx(msg)
  330. logger.info("Non-zero status code")
  331. msg['payload'] = binascii.unhexlify("0602" + addr.replace(':', '') + "0102030405060100")
  332. hapd1ap.mgmt_tx(msg)
  333. hapd1ap.dump_monitor()
  334. dev[0].scan_for_bss(ap2['bssid'], freq="2412")
  335. if "OK" not in dev[0].request("FT_DS " + ap2['bssid']):
  336. raise Exception("FT_DS failed")
  337. req = hapd1ap.mgmt_rx()
  338. logger.info("Foreign Target AP")
  339. msg['payload'] = binascii.unhexlify("0602" + addr.replace(':', '') + "0102030405060000")
  340. hapd1ap.mgmt_tx(msg)
  341. addrs = addr.replace(':', '') + ap2['bssid'].replace(':', '')
  342. logger.info("No IEs")
  343. msg['payload'] = binascii.unhexlify("0602" + addrs + "0000")
  344. hapd1ap.mgmt_tx(msg)
  345. logger.info("Invalid IEs (trigger parsing failure)")
  346. msg['payload'] = binascii.unhexlify("0602" + addrs + "00003700")
  347. hapd1ap.mgmt_tx(msg)
  348. logger.info("Too short MDIE")
  349. msg['payload'] = binascii.unhexlify("0602" + addrs + "000036021122")
  350. hapd1ap.mgmt_tx(msg)
  351. logger.info("Mobility domain mismatch")
  352. msg['payload'] = binascii.unhexlify("0602" + addrs + "00003603112201")
  353. hapd1ap.mgmt_tx(msg)
  354. logger.info("No FTIE")
  355. msg['payload'] = binascii.unhexlify("0602" + addrs + "00003603a1b201")
  356. hapd1ap.mgmt_tx(msg)
  357. logger.info("FTIE SNonce mismatch")
  358. msg['payload'] = binascii.unhexlify("0602" + addrs + "00003603a1b201375e0000" + "00000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + "1000000000000000000000000000000000000000000000000000000000000001" + "030a6e6173322e77312e6669")
  359. hapd1ap.mgmt_tx(msg)
  360. logger.info("No R0KH-ID subelem in FTIE")
  361. snonce = binascii.hexlify(req['payload'][111:111+32])
  362. msg['payload'] = binascii.unhexlify("0602" + addrs + "00003603a1b20137520000" + "00000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + snonce)
  363. hapd1ap.mgmt_tx(msg)
  364. logger.info("No R0KH-ID subelem mismatch in FTIE")
  365. snonce = binascii.hexlify(req['payload'][111:111+32])
  366. msg['payload'] = binascii.unhexlify("0602" + addrs + "00003603a1b201375e0000" + "00000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + snonce + "030a11223344556677889900")
  367. hapd1ap.mgmt_tx(msg)
  368. logger.info("No R1KH-ID subelem in FTIE")
  369. r0khid = binascii.hexlify(req['payload'][145:145+10])
  370. msg['payload'] = binascii.unhexlify("0602" + addrs + "00003603a1b201375e0000" + "00000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + snonce + "030a" + r0khid)
  371. hapd1ap.mgmt_tx(msg)
  372. logger.info("No RSNE")
  373. r0khid = binascii.hexlify(req['payload'][145:145+10])
  374. msg['payload'] = binascii.unhexlify("0602" + addrs + "00003603a1b20137660000" + "00000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + snonce + "030a" + r0khid + "0106000102030405")
  375. hapd1ap.mgmt_tx(msg)
  376. def test_ap_ft_pmf_over_ds(dev, apdev):
  377. """WPA2-PSK-FT AP over DS with PMF"""
  378. ssid = "test-ft"
  379. passphrase="12345678"
  380. params = ft_params1(ssid=ssid, passphrase=passphrase)
  381. params["ieee80211w"] = "2"
  382. hapd0 = hostapd.add_ap(apdev[0], params)
  383. params = ft_params2(ssid=ssid, passphrase=passphrase)
  384. params["ieee80211w"] = "2"
  385. hapd1 = hostapd.add_ap(apdev[1], params)
  386. run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True)
  387. def test_ap_ft_over_ds_pull(dev, apdev):
  388. """WPA2-PSK-FT AP over DS (pull PMK)"""
  389. ssid = "test-ft"
  390. passphrase="12345678"
  391. params = ft_params1(ssid=ssid, passphrase=passphrase)
  392. params["pmk_r1_push"] = "0"
  393. hapd0 = hostapd.add_ap(apdev[0], params)
  394. params = ft_params2(ssid=ssid, passphrase=passphrase)
  395. params["pmk_r1_push"] = "0"
  396. hapd1 = hostapd.add_ap(apdev[1], params)
  397. run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True)
  398. def test_ap_ft_over_ds_pull_old_key(dev, apdev):
  399. """WPA2-PSK-FT AP over DS (pull PMK; old key)"""
  400. ssid = "test-ft"
  401. passphrase="12345678"
  402. params = ft_params1_old_key(ssid=ssid, passphrase=passphrase)
  403. params["pmk_r1_push"] = "0"
  404. hapd0 = hostapd.add_ap(apdev[0], params)
  405. params = ft_params2_old_key(ssid=ssid, passphrase=passphrase)
  406. params["pmk_r1_push"] = "0"
  407. hapd1 = hostapd.add_ap(apdev[1], params)
  408. run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True)
  409. def test_ap_ft_sae(dev, apdev):
  410. """WPA2-PSK-FT-SAE AP"""
  411. if "SAE" not in dev[0].get_capability("auth_alg"):
  412. raise HwsimSkip("SAE not supported")
  413. ssid = "test-ft"
  414. passphrase="12345678"
  415. params = ft_params1(ssid=ssid, passphrase=passphrase)
  416. params['wpa_key_mgmt'] = "FT-SAE"
  417. hapd0 = hostapd.add_ap(apdev[0], params)
  418. params = ft_params2(ssid=ssid, passphrase=passphrase)
  419. params['wpa_key_mgmt'] = "FT-SAE"
  420. hapd = hostapd.add_ap(apdev[1], params)
  421. key_mgmt = hapd.get_config()['key_mgmt']
  422. if key_mgmt.split(' ')[0] != "FT-SAE":
  423. raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
  424. dev[0].request("SET sae_groups ")
  425. run_roams(dev[0], apdev, hapd0, hapd, ssid, passphrase, sae=True)
  426. def test_ap_ft_sae_over_ds(dev, apdev):
  427. """WPA2-PSK-FT-SAE AP over DS"""
  428. if "SAE" not in dev[0].get_capability("auth_alg"):
  429. raise HwsimSkip("SAE not supported")
  430. ssid = "test-ft"
  431. passphrase="12345678"
  432. params = ft_params1(ssid=ssid, passphrase=passphrase)
  433. params['wpa_key_mgmt'] = "FT-SAE"
  434. hapd0 = hostapd.add_ap(apdev[0], params)
  435. params = ft_params2(ssid=ssid, passphrase=passphrase)
  436. params['wpa_key_mgmt'] = "FT-SAE"
  437. hapd1 = hostapd.add_ap(apdev[1], params)
  438. dev[0].request("SET sae_groups ")
  439. run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, sae=True,
  440. over_ds=True)
  441. def generic_ap_ft_eap(dev, apdev, over_ds=False, discovery=False, roams=1):
  442. ssid = "test-ft"
  443. passphrase="12345678"
  444. radius = hostapd.radius_params()
  445. params = ft_params1(ssid=ssid, passphrase=passphrase, discovery=discovery)
  446. params['wpa_key_mgmt'] = "FT-EAP"
  447. params["ieee8021x"] = "1"
  448. params = dict(radius.items() + params.items())
  449. hapd = hostapd.add_ap(apdev[0], params)
  450. key_mgmt = hapd.get_config()['key_mgmt']
  451. if key_mgmt.split(' ')[0] != "FT-EAP":
  452. raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
  453. params = ft_params2(ssid=ssid, passphrase=passphrase, discovery=discovery)
  454. params['wpa_key_mgmt'] = "FT-EAP"
  455. params["ieee8021x"] = "1"
  456. params = dict(radius.items() + params.items())
  457. hapd1 = hostapd.add_ap(apdev[1], params)
  458. run_roams(dev[0], apdev, hapd, hapd1, ssid, passphrase, eap=True,
  459. over_ds=over_ds, roams=roams)
  460. if "[WPA2-FT/EAP-CCMP]" not in dev[0].request("SCAN_RESULTS"):
  461. raise Exception("Scan results missing RSN element info")
  462. check_mib(dev[0], [ ("dot11RSNAAuthenticationSuiteRequested", "00-0f-ac-3"),
  463. ("dot11RSNAAuthenticationSuiteSelected", "00-0f-ac-3") ])
  464. # Verify EAPOL reauthentication after FT protocol
  465. if dev[0].get_status_field('bssid') == apdev[0]['bssid']:
  466. ap = hapd
  467. else:
  468. ap = hapd1
  469. ap.request("EAPOL_REAUTH " + dev[0].own_addr())
  470. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
  471. if ev is None:
  472. raise Exception("EAP authentication did not start")
  473. ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=5)
  474. if ev is None:
  475. raise Exception("EAP authentication did not succeed")
  476. time.sleep(0.1)
  477. hwsim_utils.test_connectivity(dev[0], ap)
  478. def test_ap_ft_eap(dev, apdev):
  479. """WPA2-EAP-FT AP"""
  480. generic_ap_ft_eap(dev, apdev)
  481. def test_ap_ft_eap_over_ds(dev, apdev):
  482. """WPA2-EAP-FT AP using over-the-DS"""
  483. generic_ap_ft_eap(dev, apdev, over_ds=True)
  484. def test_ap_ft_eap_dis(dev, apdev):
  485. """WPA2-EAP-FT AP with AP discovery"""
  486. generic_ap_ft_eap(dev, apdev, discovery=True)
  487. def test_ap_ft_eap_dis_over_ds(dev, apdev):
  488. """WPA2-EAP-FT AP with AP discovery and over-the-DS"""
  489. generic_ap_ft_eap(dev, apdev, over_ds=True, discovery=True)
  490. def test_ap_ft_eap_pull(dev, apdev):
  491. """WPA2-EAP-FT AP (pull PMK)"""
  492. ssid = "test-ft"
  493. passphrase="12345678"
  494. radius = hostapd.radius_params()
  495. params = ft_params1(ssid=ssid, passphrase=passphrase)
  496. params['wpa_key_mgmt'] = "FT-EAP"
  497. params["ieee8021x"] = "1"
  498. params["pmk_r1_push"] = "0"
  499. params = dict(radius.items() + params.items())
  500. hapd = hostapd.add_ap(apdev[0], params)
  501. key_mgmt = hapd.get_config()['key_mgmt']
  502. if key_mgmt.split(' ')[0] != "FT-EAP":
  503. raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
  504. params = ft_params2(ssid=ssid, passphrase=passphrase)
  505. params['wpa_key_mgmt'] = "FT-EAP"
  506. params["ieee8021x"] = "1"
  507. params["pmk_r1_push"] = "0"
  508. params = dict(radius.items() + params.items())
  509. hapd1 = hostapd.add_ap(apdev[1], params)
  510. run_roams(dev[0], apdev, hapd, hapd1, ssid, passphrase, eap=True)
  511. @remote_compatible
  512. def test_ap_ft_mismatching_rrb_key_push(dev, apdev):
  513. """WPA2-PSK-FT AP over DS with mismatching RRB key (push)"""
  514. ssid = "test-ft"
  515. passphrase="12345678"
  516. params = ft_params1(ssid=ssid, passphrase=passphrase)
  517. params["ieee80211w"] = "2"
  518. hapd0 = hostapd.add_ap(apdev[0], params)
  519. params = ft_params2_incorrect_rrb_key(ssid=ssid, passphrase=passphrase)
  520. params["ieee80211w"] = "2"
  521. hapd1 = hostapd.add_ap(apdev[1], params)
  522. run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
  523. fail_test=True)
  524. @remote_compatible
  525. def test_ap_ft_mismatching_rrb_key_pull(dev, apdev):
  526. """WPA2-PSK-FT AP over DS with mismatching RRB key (pull)"""
  527. ssid = "test-ft"
  528. passphrase="12345678"
  529. params = ft_params1(ssid=ssid, passphrase=passphrase)
  530. params["pmk_r1_push"] = "0"
  531. hapd0 = hostapd.add_ap(apdev[0], params)
  532. params = ft_params2_incorrect_rrb_key(ssid=ssid, passphrase=passphrase)
  533. params["pmk_r1_push"] = "0"
  534. hapd1 = hostapd.add_ap(apdev[1], params)
  535. run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
  536. fail_test=True)
  537. @remote_compatible
  538. def test_ap_ft_mismatching_r0kh_id_pull(dev, apdev):
  539. """WPA2-PSK-FT AP over DS with mismatching R0KH-ID (pull)"""
  540. ssid = "test-ft"
  541. passphrase="12345678"
  542. params = ft_params1(ssid=ssid, passphrase=passphrase)
  543. params["pmk_r1_push"] = "0"
  544. params["nas_identifier"] = "nas0.w1.fi"
  545. hostapd.add_ap(apdev[0], params)
  546. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  547. scan_freq="2412")
  548. params = ft_params2(ssid=ssid, passphrase=passphrase)
  549. params["pmk_r1_push"] = "0"
  550. hostapd.add_ap(apdev[1], params)
  551. dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
  552. dev[0].roam_over_ds(apdev[1]['bssid'], fail_test=True)
  553. @remote_compatible
  554. def test_ap_ft_mismatching_rrb_r0kh_push(dev, apdev):
  555. """WPA2-PSK-FT AP over DS with mismatching R0KH key (push)"""
  556. ssid = "test-ft"
  557. passphrase="12345678"
  558. params = ft_params1(ssid=ssid, passphrase=passphrase)
  559. params["ieee80211w"] = "2"
  560. hapd0 = hostapd.add_ap(apdev[0], params)
  561. params = ft_params2_r0kh_mismatch(ssid=ssid, passphrase=passphrase)
  562. params["ieee80211w"] = "2"
  563. hapd1 = hostapd.add_ap(apdev[1], params)
  564. run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
  565. fail_test=True)
  566. @remote_compatible
  567. def test_ap_ft_mismatching_rrb_r0kh_pull(dev, apdev):
  568. """WPA2-PSK-FT AP over DS with mismatching R0KH key (pull)"""
  569. ssid = "test-ft"
  570. passphrase="12345678"
  571. params = ft_params1_r0kh_mismatch(ssid=ssid, passphrase=passphrase)
  572. params["pmk_r1_push"] = "0"
  573. hapd0 = hostapd.add_ap(apdev[0], params)
  574. params = ft_params2(ssid=ssid, passphrase=passphrase)
  575. params["pmk_r1_push"] = "0"
  576. hapd1 = hostapd.add_ap(apdev[1], params)
  577. run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
  578. fail_test=True)
  579. def test_ap_ft_mismatching_rrb_key_push_eap(dev, apdev):
  580. """WPA2-EAP-FT AP over DS with mismatching RRB key (push)"""
  581. ssid = "test-ft"
  582. passphrase="12345678"
  583. radius = hostapd.radius_params()
  584. params = ft_params1(ssid=ssid, passphrase=passphrase)
  585. params["ieee80211w"] = "2";
  586. params['wpa_key_mgmt'] = "FT-EAP"
  587. params["ieee8021x"] = "1"
  588. params = dict(radius.items() + params.items())
  589. hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
  590. params = ft_params2_incorrect_rrb_key(ssid=ssid, passphrase=passphrase)
  591. params["ieee80211w"] = "2";
  592. params['wpa_key_mgmt'] = "FT-EAP"
  593. params["ieee8021x"] = "1"
  594. params = dict(radius.items() + params.items())
  595. hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
  596. run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
  597. fail_test=True, eap=True)
  598. def test_ap_ft_mismatching_rrb_key_pull_eap(dev, apdev):
  599. """WPA2-EAP-FT AP over DS with mismatching RRB key (pull)"""
  600. ssid = "test-ft"
  601. passphrase="12345678"
  602. radius = hostapd.radius_params()
  603. params = ft_params1(ssid=ssid, passphrase=passphrase)
  604. params["pmk_r1_push"] = "0"
  605. params['wpa_key_mgmt'] = "FT-EAP"
  606. params["ieee8021x"] = "1"
  607. params = dict(radius.items() + params.items())
  608. hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
  609. params = ft_params2_incorrect_rrb_key(ssid=ssid, passphrase=passphrase)
  610. params["pmk_r1_push"] = "0"
  611. params['wpa_key_mgmt'] = "FT-EAP"
  612. params["ieee8021x"] = "1"
  613. params = dict(radius.items() + params.items())
  614. hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
  615. run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
  616. fail_test=True, eap=True)
  617. def test_ap_ft_mismatching_r0kh_id_pull_eap(dev, apdev):
  618. """WPA2-EAP-FT AP over DS with mismatching R0KH-ID (pull)"""
  619. ssid = "test-ft"
  620. passphrase="12345678"
  621. radius = hostapd.radius_params()
  622. params = ft_params1(ssid=ssid, passphrase=passphrase)
  623. params["pmk_r1_push"] = "0"
  624. params["nas_identifier"] = "nas0.w1.fi"
  625. params['wpa_key_mgmt'] = "FT-EAP"
  626. params["ieee8021x"] = "1"
  627. params = dict(radius.items() + params.items())
  628. hostapd.add_ap(apdev[0]['ifname'], params)
  629. dev[0].connect(ssid, key_mgmt="FT-EAP", proto="WPA2", ieee80211w="1",
  630. eap="GPSK", identity="gpsk user",
  631. password="abcdefghijklmnop0123456789abcdef",
  632. scan_freq="2412")
  633. params = ft_params2(ssid=ssid, passphrase=passphrase)
  634. params["pmk_r1_push"] = "0"
  635. params['wpa_key_mgmt'] = "FT-EAP"
  636. params["ieee8021x"] = "1"
  637. params = dict(radius.items() + params.items())
  638. hostapd.add_ap(apdev[1]['ifname'], params)
  639. dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
  640. dev[0].roam_over_ds(apdev[1]['bssid'], fail_test=True)
  641. def test_ap_ft_mismatching_rrb_r0kh_push_eap(dev, apdev):
  642. """WPA2-EAP-FT AP over DS with mismatching R0KH key (push)"""
  643. ssid = "test-ft"
  644. passphrase="12345678"
  645. radius = hostapd.radius_params()
  646. params = ft_params1(ssid=ssid, passphrase=passphrase)
  647. params["ieee80211w"] = "2";
  648. params['wpa_key_mgmt'] = "FT-EAP"
  649. params["ieee8021x"] = "1"
  650. params = dict(radius.items() + params.items())
  651. hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
  652. params = ft_params2_r0kh_mismatch(ssid=ssid, passphrase=passphrase)
  653. params["ieee80211w"] = "2";
  654. params['wpa_key_mgmt'] = "FT-EAP"
  655. params["ieee8021x"] = "1"
  656. params = dict(radius.items() + params.items())
  657. hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
  658. run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
  659. fail_test=True, eap=True)
  660. def test_ap_ft_mismatching_rrb_r0kh_pull_eap(dev, apdev):
  661. """WPA2-EAP-FT AP over DS with mismatching R0KH key (pull)"""
  662. ssid = "test-ft"
  663. passphrase="12345678"
  664. radius = hostapd.radius_params()
  665. params = ft_params1_r0kh_mismatch(ssid=ssid, passphrase=passphrase)
  666. params["pmk_r1_push"] = "0"
  667. params['wpa_key_mgmt'] = "FT-EAP"
  668. params["ieee8021x"] = "1"
  669. params = dict(radius.items() + params.items())
  670. hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
  671. params = ft_params2(ssid=ssid, passphrase=passphrase)
  672. params["pmk_r1_push"] = "0"
  673. params['wpa_key_mgmt'] = "FT-EAP"
  674. params["ieee8021x"] = "1"
  675. params = dict(radius.items() + params.items())
  676. hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
  677. run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
  678. fail_test=True, eap=True)
  679. def test_ap_ft_gtk_rekey(dev, apdev):
  680. """WPA2-PSK-FT AP and GTK rekey"""
  681. ssid = "test-ft"
  682. passphrase="12345678"
  683. params = ft_params1(ssid=ssid, passphrase=passphrase)
  684. params['wpa_group_rekey'] = '1'
  685. hapd = hostapd.add_ap(apdev[0], params)
  686. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  687. ieee80211w="1", scan_freq="2412")
  688. ev = dev[0].wait_event(["WPA: Group rekeying completed"], timeout=2)
  689. if ev is None:
  690. raise Exception("GTK rekey timed out after initial association")
  691. hwsim_utils.test_connectivity(dev[0], hapd)
  692. params = ft_params2(ssid=ssid, passphrase=passphrase)
  693. params['wpa_group_rekey'] = '1'
  694. hapd1 = hostapd.add_ap(apdev[1], params)
  695. dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
  696. dev[0].roam(apdev[1]['bssid'])
  697. if dev[0].get_status_field('bssid') != apdev[1]['bssid']:
  698. raise Exception("Did not connect to correct AP")
  699. hwsim_utils.test_connectivity(dev[0], hapd1)
  700. ev = dev[0].wait_event(["WPA: Group rekeying completed"], timeout=2)
  701. if ev is None:
  702. raise Exception("GTK rekey timed out after FT protocol")
  703. hwsim_utils.test_connectivity(dev[0], hapd1)
  704. def test_ft_psk_key_lifetime_in_memory(dev, apdev, params):
  705. """WPA2-PSK-FT and key lifetime in memory"""
  706. ssid = "test-ft"
  707. passphrase="04c2726b4b8d5f1b4db9c07aa4d9e9d8f765cb5d25ec817e6cc4fcdd5255db0"
  708. psk = '93c90846ff67af9037ed83fb72b63dbeddaa81d47f926c20909b5886f1d9358d'
  709. pmk = binascii.unhexlify(psk)
  710. p = ft_params1(ssid=ssid, passphrase=passphrase)
  711. hapd0 = hostapd.add_ap(apdev[0], p)
  712. p = ft_params2(ssid=ssid, passphrase=passphrase)
  713. hapd1 = hostapd.add_ap(apdev[1], p)
  714. pid = find_wpas_process(dev[0])
  715. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  716. scan_freq="2412")
  717. # The decrypted copy of GTK is freed only after the CTRL-EVENT-CONNECTED
  718. # event has been delivered, so verify that wpa_supplicant has returned to
  719. # eloop before reading process memory.
  720. time.sleep(1)
  721. dev[0].ping()
  722. buf = read_process_memory(pid, pmk)
  723. dev[0].request("DISCONNECT")
  724. dev[0].wait_disconnected()
  725. dev[0].relog()
  726. pmkr0 = None
  727. pmkr1 = None
  728. ptk = None
  729. gtk = None
  730. with open(os.path.join(params['logdir'], 'log0'), 'r') as f:
  731. for l in f.readlines():
  732. if "FT: PMK-R0 - hexdump" in l:
  733. val = l.strip().split(':')[3].replace(' ', '')
  734. pmkr0 = binascii.unhexlify(val)
  735. if "FT: PMK-R1 - hexdump" in l:
  736. val = l.strip().split(':')[3].replace(' ', '')
  737. pmkr1 = binascii.unhexlify(val)
  738. if "FT: KCK - hexdump" in l:
  739. val = l.strip().split(':')[3].replace(' ', '')
  740. kck = binascii.unhexlify(val)
  741. if "FT: KEK - hexdump" in l:
  742. val = l.strip().split(':')[3].replace(' ', '')
  743. kek = binascii.unhexlify(val)
  744. if "FT: TK - hexdump" in l:
  745. val = l.strip().split(':')[3].replace(' ', '')
  746. tk = binascii.unhexlify(val)
  747. if "WPA: Group Key - hexdump" in l:
  748. val = l.strip().split(':')[3].replace(' ', '')
  749. gtk = binascii.unhexlify(val)
  750. if not pmkr0 or not pmkr1 or not kck or not kek or not tk or not gtk:
  751. raise Exception("Could not find keys from debug log")
  752. if len(gtk) != 16:
  753. raise Exception("Unexpected GTK length")
  754. logger.info("Checking keys in memory while associated")
  755. get_key_locations(buf, pmk, "PMK")
  756. get_key_locations(buf, pmkr0, "PMK-R0")
  757. get_key_locations(buf, pmkr1, "PMK-R1")
  758. if pmk not in buf:
  759. raise HwsimSkip("PMK not found while associated")
  760. if pmkr0 not in buf:
  761. raise HwsimSkip("PMK-R0 not found while associated")
  762. if pmkr1 not in buf:
  763. raise HwsimSkip("PMK-R1 not found while associated")
  764. if kck not in buf:
  765. raise Exception("KCK not found while associated")
  766. if kek not in buf:
  767. raise Exception("KEK not found while associated")
  768. if tk in buf:
  769. raise Exception("TK found from memory")
  770. if gtk in buf:
  771. get_key_locations(buf, gtk, "GTK")
  772. raise Exception("GTK found from memory")
  773. logger.info("Checking keys in memory after disassociation")
  774. buf = read_process_memory(pid, pmk)
  775. get_key_locations(buf, pmk, "PMK")
  776. get_key_locations(buf, pmkr0, "PMK-R0")
  777. get_key_locations(buf, pmkr1, "PMK-R1")
  778. # Note: PMK/PSK is still present in network configuration
  779. fname = os.path.join(params['logdir'],
  780. 'ft_psk_key_lifetime_in_memory.memctx-')
  781. verify_not_present(buf, pmkr0, fname, "PMK-R0")
  782. verify_not_present(buf, pmkr1, fname, "PMK-R1")
  783. verify_not_present(buf, kck, fname, "KCK")
  784. verify_not_present(buf, kek, fname, "KEK")
  785. verify_not_present(buf, tk, fname, "TK")
  786. verify_not_present(buf, gtk, fname, "GTK")
  787. dev[0].request("REMOVE_NETWORK all")
  788. logger.info("Checking keys in memory after network profile removal")
  789. buf = read_process_memory(pid, pmk)
  790. get_key_locations(buf, pmk, "PMK")
  791. get_key_locations(buf, pmkr0, "PMK-R0")
  792. get_key_locations(buf, pmkr1, "PMK-R1")
  793. verify_not_present(buf, pmk, fname, "PMK")
  794. verify_not_present(buf, pmkr0, fname, "PMK-R0")
  795. verify_not_present(buf, pmkr1, fname, "PMK-R1")
  796. verify_not_present(buf, kck, fname, "KCK")
  797. verify_not_present(buf, kek, fname, "KEK")
  798. verify_not_present(buf, tk, fname, "TK")
  799. verify_not_present(buf, gtk, fname, "GTK")
  800. @remote_compatible
  801. def test_ap_ft_invalid_resp(dev, apdev):
  802. """WPA2-PSK-FT AP and invalid response IEs"""
  803. ssid = "test-ft"
  804. passphrase="12345678"
  805. params = ft_params1(ssid=ssid, passphrase=passphrase)
  806. hapd0 = hostapd.add_ap(apdev[0], params)
  807. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  808. scan_freq="2412")
  809. params = ft_params2(ssid=ssid, passphrase=passphrase)
  810. hapd1 = hostapd.add_ap(apdev[1], params)
  811. tests = [
  812. # Various IEs for test coverage. The last one is FTIE with invalid
  813. # R1KH-ID subelement.
  814. "020002000000" + "3800" + "38051122334455" + "3754000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010100",
  815. # FTIE with invalid R0KH-ID subelement (len=0).
  816. "020002000000" + "3754000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010300",
  817. # FTIE with invalid R0KH-ID subelement (len=49).
  818. "020002000000" + "378500010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001033101020304050607080910111213141516171819202122232425262728293031323334353637383940414243444546474849",
  819. # Invalid RSNE.
  820. "020002000000" + "3000",
  821. # Required IEs missing from protected IE count.
  822. "020002000000" + "3603a1b201" + "375200010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001" + "3900",
  823. # RIC missing from protected IE count.
  824. "020002000000" + "3603a1b201" + "375200020203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001" + "3900",
  825. # Protected IE missing.
  826. "020002000000" + "3603a1b201" + "375200ff0203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001" + "3900" + "0000" ]
  827. for t in tests:
  828. dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
  829. hapd1.set("ext_mgmt_frame_handling", "1")
  830. hapd1.dump_monitor()
  831. if "OK" not in dev[0].request("ROAM " + apdev[1]['bssid']):
  832. raise Exception("ROAM failed")
  833. auth = None
  834. for i in range(20):
  835. msg = hapd1.mgmt_rx()
  836. if msg['subtype'] == 11:
  837. auth = msg
  838. break
  839. if not auth:
  840. raise Exception("Authentication frame not seen")
  841. resp = {}
  842. resp['fc'] = auth['fc']
  843. resp['da'] = auth['sa']
  844. resp['sa'] = auth['da']
  845. resp['bssid'] = auth['bssid']
  846. resp['payload'] = binascii.unhexlify(t)
  847. hapd1.mgmt_tx(resp)
  848. hapd1.set("ext_mgmt_frame_handling", "0")
  849. dev[0].wait_disconnected()
  850. dev[0].request("RECONNECT")
  851. dev[0].wait_connected()
  852. def test_ap_ft_gcmp_256(dev, apdev):
  853. """WPA2-PSK-FT AP with GCMP-256 cipher"""
  854. if "GCMP-256" not in dev[0].get_capability("pairwise"):
  855. raise HwsimSkip("Cipher GCMP-256 not supported")
  856. ssid = "test-ft"
  857. passphrase="12345678"
  858. params = ft_params1(ssid=ssid, passphrase=passphrase)
  859. params['rsn_pairwise'] = "GCMP-256"
  860. hapd0 = hostapd.add_ap(apdev[0], params)
  861. params = ft_params2(ssid=ssid, passphrase=passphrase)
  862. params['rsn_pairwise'] = "GCMP-256"
  863. hapd1 = hostapd.add_ap(apdev[1], params)
  864. run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase,
  865. pairwise_cipher="GCMP-256", group_cipher="GCMP-256")
  866. def test_ap_ft_oom(dev, apdev):
  867. """WPA2-PSK-FT and OOM"""
  868. skip_with_fips(dev[0])
  869. ssid = "test-ft"
  870. passphrase="12345678"
  871. params = ft_params1(ssid=ssid, passphrase=passphrase)
  872. hapd0 = hostapd.add_ap(apdev[0], params)
  873. params = ft_params2(ssid=ssid, passphrase=passphrase)
  874. hapd1 = hostapd.add_ap(apdev[1], params)
  875. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  876. scan_freq="2412")
  877. if dev[0].get_status_field('bssid') == apdev[0]['bssid']:
  878. dst = apdev[1]['bssid']
  879. else:
  880. dst = apdev[0]['bssid']
  881. dev[0].scan_for_bss(dst, freq="2412")
  882. with alloc_fail(dev[0], 1, "wpa_ft_gen_req_ies"):
  883. dev[0].roam(dst)
  884. with fail_test(dev[0], 1, "wpa_ft_mic"):
  885. dev[0].roam(dst, fail_test=True)
  886. with fail_test(dev[0], 1, "os_get_random;wpa_ft_prepare_auth_request"):
  887. dev[0].roam(dst, fail_test=True)
  888. dev[0].request("REMOVE_NETWORK all")
  889. with alloc_fail(dev[0], 1, "=sme_update_ft_ies"):
  890. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  891. scan_freq="2412")
  892. def test_ap_ft_ap_oom(dev, apdev):
  893. """WPA2-PSK-FT and AP OOM"""
  894. ssid = "test-ft"
  895. passphrase="12345678"
  896. params = ft_params1(ssid=ssid, passphrase=passphrase)
  897. hapd0 = hostapd.add_ap(apdev[0], params)
  898. bssid0 = hapd0.own_addr()
  899. dev[0].scan_for_bss(bssid0, freq="2412")
  900. with alloc_fail(hapd0, 1, "wpa_ft_store_pmk_r0"):
  901. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  902. scan_freq="2412")
  903. params = ft_params2(ssid=ssid, passphrase=passphrase)
  904. hapd1 = hostapd.add_ap(apdev[1], params)
  905. bssid1 = hapd1.own_addr()
  906. dev[0].scan_for_bss(bssid1, freq="2412")
  907. # This roam will fail due to missing PMK-R0 (OOM prevented storing it)
  908. dev[0].roam(bssid1)
  909. def test_ap_ft_ap_oom2(dev, apdev):
  910. """WPA2-PSK-FT and AP OOM 2"""
  911. ssid = "test-ft"
  912. passphrase="12345678"
  913. params = ft_params1(ssid=ssid, passphrase=passphrase)
  914. hapd0 = hostapd.add_ap(apdev[0], params)
  915. bssid0 = hapd0.own_addr()
  916. dev[0].scan_for_bss(bssid0, freq="2412")
  917. with alloc_fail(hapd0, 1, "wpa_ft_store_pmk_r1"):
  918. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  919. scan_freq="2412")
  920. params = ft_params2(ssid=ssid, passphrase=passphrase)
  921. hapd1 = hostapd.add_ap(apdev[1], params)
  922. bssid1 = hapd1.own_addr()
  923. dev[0].scan_for_bss(bssid1, freq="2412")
  924. dev[0].roam(bssid1)
  925. if dev[0].get_status_field('bssid') != bssid1:
  926. raise Exception("Did not roam to AP1")
  927. # This roam will fail due to missing PMK-R1 (OOM prevented storing it)
  928. dev[0].roam(bssid0)
  929. def test_ap_ft_ap_oom3(dev, apdev):
  930. """WPA2-PSK-FT and AP OOM 3"""
  931. ssid = "test-ft"
  932. passphrase="12345678"
  933. params = ft_params1(ssid=ssid, passphrase=passphrase)
  934. hapd0 = hostapd.add_ap(apdev[0], params)
  935. bssid0 = hapd0.own_addr()
  936. dev[0].scan_for_bss(bssid0, freq="2412")
  937. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  938. scan_freq="2412")
  939. params = ft_params2(ssid=ssid, passphrase=passphrase)
  940. hapd1 = hostapd.add_ap(apdev[1], params)
  941. bssid1 = hapd1.own_addr()
  942. dev[0].scan_for_bss(bssid1, freq="2412")
  943. with alloc_fail(hapd1, 1, "wpa_ft_pull_pmk_r1"):
  944. # This will fail due to not being able to send out PMK-R1 pull request
  945. dev[0].roam(bssid1)
  946. with fail_test(hapd1, 2, "os_get_random;wpa_ft_pull_pmk_r1"):
  947. # This will fail due to not being able to send out PMK-R1 pull request
  948. dev[0].roam(bssid1)
  949. with fail_test(hapd1, 2, "aes_siv_encrypt;wpa_ft_pull_pmk_r1"):
  950. # This will fail due to not being able to send out PMK-R1 pull request
  951. dev[0].roam(bssid1)
  952. def test_ap_ft_ap_oom3b(dev, apdev):
  953. """WPA2-PSK-FT and AP OOM 3b"""
  954. ssid = "test-ft"
  955. passphrase="12345678"
  956. params = ft_params1(ssid=ssid, passphrase=passphrase)
  957. hapd0 = hostapd.add_ap(apdev[0], params)
  958. bssid0 = hapd0.own_addr()
  959. dev[0].scan_for_bss(bssid0, freq="2412")
  960. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  961. scan_freq="2412")
  962. params = ft_params2(ssid=ssid, passphrase=passphrase)
  963. hapd1 = hostapd.add_ap(apdev[1], params)
  964. bssid1 = hapd1.own_addr()
  965. dev[0].scan_for_bss(bssid1, freq="2412")
  966. with fail_test(hapd1, 1, "os_get_random;wpa_ft_pull_pmk_r1"):
  967. # This will fail due to not being able to send out PMK-R1 pull request
  968. dev[0].roam(bssid1)
  969. def test_ap_ft_ap_oom4(dev, apdev):
  970. """WPA2-PSK-FT and AP OOM 4"""
  971. ssid = "test-ft"
  972. passphrase="12345678"
  973. params = ft_params1(ssid=ssid, passphrase=passphrase)
  974. hapd0 = hostapd.add_ap(apdev[0], params)
  975. bssid0 = hapd0.own_addr()
  976. dev[0].scan_for_bss(bssid0, freq="2412")
  977. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  978. scan_freq="2412")
  979. params = ft_params2(ssid=ssid, passphrase=passphrase)
  980. hapd1 = hostapd.add_ap(apdev[1], params)
  981. bssid1 = hapd1.own_addr()
  982. dev[0].scan_for_bss(bssid1, freq="2412")
  983. with alloc_fail(hapd1, 1, "wpa_ft_gtk_subelem"):
  984. dev[0].roam(bssid1)
  985. if dev[0].get_status_field('bssid') != bssid1:
  986. raise Exception("Did not roam to AP1")
  987. with fail_test(hapd0, 1, "wpa_auth_get_seqnum;wpa_ft_gtk_subelem"):
  988. dev[0].roam(bssid0)
  989. if dev[0].get_status_field('bssid') != bssid0:
  990. raise Exception("Did not roam to AP0")
  991. with fail_test(hapd0, 1, "aes_wrap;wpa_ft_gtk_subelem"):
  992. dev[0].roam(bssid1)
  993. if dev[0].get_status_field('bssid') != bssid1:
  994. raise Exception("Did not roam to AP1")
  995. def test_ap_ft_ap_oom5(dev, apdev):
  996. """WPA2-PSK-FT and AP OOM 5"""
  997. ssid = "test-ft"
  998. passphrase="12345678"
  999. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1000. hapd0 = hostapd.add_ap(apdev[0], params)
  1001. bssid0 = hapd0.own_addr()
  1002. dev[0].scan_for_bss(bssid0, freq="2412")
  1003. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1004. scan_freq="2412")
  1005. params = ft_params2(ssid=ssid, passphrase=passphrase)
  1006. hapd1 = hostapd.add_ap(apdev[1], params)
  1007. bssid1 = hapd1.own_addr()
  1008. dev[0].scan_for_bss(bssid1, freq="2412")
  1009. with alloc_fail(hapd1, 1, "=wpa_ft_process_auth_req"):
  1010. # This will fail to roam
  1011. dev[0].roam(bssid1)
  1012. with fail_test(hapd1, 1, "os_get_random;wpa_ft_process_auth_req"):
  1013. # This will fail to roam
  1014. dev[0].roam(bssid1)
  1015. with fail_test(hapd1, 1, "sha256_prf_bits;wpa_pmk_r1_to_ptk;wpa_ft_process_auth_req"):
  1016. # This will fail to roam
  1017. dev[0].roam(bssid1)
  1018. with fail_test(hapd1, 3, "wpa_pmk_r1_to_ptk;wpa_ft_process_auth_req"):
  1019. # This will fail to roam
  1020. dev[0].roam(bssid1)
  1021. with fail_test(hapd1, 1, "wpa_derive_pmk_r1_name;wpa_ft_process_auth_req"):
  1022. # This will fail to roam
  1023. dev[0].roam(bssid1)
  1024. def test_ap_ft_ap_oom6(dev, apdev):
  1025. """WPA2-PSK-FT and AP OOM 6"""
  1026. ssid = "test-ft"
  1027. passphrase="12345678"
  1028. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1029. hapd0 = hostapd.add_ap(apdev[0], params)
  1030. bssid0 = hapd0.own_addr()
  1031. dev[0].scan_for_bss(bssid0, freq="2412")
  1032. with fail_test(hapd0, 1, "wpa_derive_pmk_r0;wpa_auth_derive_ptk_ft"):
  1033. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1034. scan_freq="2412")
  1035. dev[0].request("REMOVE_NETWORK all")
  1036. dev[0].wait_disconnected()
  1037. with fail_test(hapd0, 1, "wpa_derive_pmk_r1;wpa_auth_derive_ptk_ft"):
  1038. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1039. scan_freq="2412")
  1040. dev[0].request("REMOVE_NETWORK all")
  1041. dev[0].wait_disconnected()
  1042. with fail_test(hapd0, 1, "wpa_pmk_r1_to_ptk;wpa_auth_derive_ptk_ft"):
  1043. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1044. scan_freq="2412")
  1045. def test_ap_ft_ap_oom7(dev, apdev):
  1046. """WPA2-PSK-FT and AP OOM 7"""
  1047. ssid = "test-ft"
  1048. passphrase="12345678"
  1049. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1050. params["ieee80211w"] = "2"
  1051. hapd0 = hostapd.add_ap(apdev[0], params)
  1052. bssid0 = hapd0.own_addr()
  1053. dev[0].scan_for_bss(bssid0, freq="2412")
  1054. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1055. ieee80211w="2", scan_freq="2412")
  1056. params = ft_params2(ssid=ssid, passphrase=passphrase)
  1057. params["ieee80211w"] = "2"
  1058. hapd1 = hostapd.add_ap(apdev[1], params)
  1059. bssid1 = hapd1.own_addr()
  1060. dev[0].scan_for_bss(bssid1, freq="2412")
  1061. with alloc_fail(hapd1, 1, "wpa_ft_igtk_subelem"):
  1062. # This will fail to roam
  1063. dev[0].roam(bssid1)
  1064. with fail_test(hapd1, 1, "aes_wrap;wpa_ft_igtk_subelem"):
  1065. # This will fail to roam
  1066. dev[0].roam(bssid1)
  1067. with alloc_fail(hapd1, 1, "=wpa_sm_write_assoc_resp_ies"):
  1068. # This will fail to roam
  1069. dev[0].roam(bssid1)
  1070. with fail_test(hapd1, 1, "wpa_ft_mic;wpa_sm_write_assoc_resp_ies"):
  1071. # This will fail to roam
  1072. dev[0].roam(bssid1)
  1073. def test_ap_ft_ap_oom8(dev, apdev):
  1074. """WPA2-PSK-FT and AP OOM 8"""
  1075. ssid = "test-ft"
  1076. passphrase="12345678"
  1077. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1078. params['ft_psk_generate_local'] = "1";
  1079. hapd0 = hostapd.add_ap(apdev[0], params)
  1080. bssid0 = hapd0.own_addr()
  1081. dev[0].scan_for_bss(bssid0, freq="2412")
  1082. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1083. scan_freq="2412")
  1084. params = ft_params2(ssid=ssid, passphrase=passphrase)
  1085. params['ft_psk_generate_local'] = "1";
  1086. hapd1 = hostapd.add_ap(apdev[1], params)
  1087. bssid1 = hapd1.own_addr()
  1088. dev[0].scan_for_bss(bssid1, freq="2412")
  1089. with fail_test(hapd1, 1, "wpa_derive_pmk_r0;wpa_ft_psk_pmk_r1"):
  1090. # This will fail to roam
  1091. dev[0].roam(bssid1)
  1092. with fail_test(hapd1, 1, "wpa_derive_pmk_r1;wpa_ft_psk_pmk_r1"):
  1093. # This will fail to roam
  1094. dev[0].roam(bssid1)
  1095. def test_ap_ft_ap_oom9(dev, apdev):
  1096. """WPA2-PSK-FT and AP OOM 9"""
  1097. ssid = "test-ft"
  1098. passphrase="12345678"
  1099. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1100. hapd0 = hostapd.add_ap(apdev[0], params)
  1101. bssid0 = hapd0.own_addr()
  1102. dev[0].scan_for_bss(bssid0, freq="2412")
  1103. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1104. scan_freq="2412")
  1105. params = ft_params2(ssid=ssid, passphrase=passphrase)
  1106. hapd1 = hostapd.add_ap(apdev[1], params)
  1107. bssid1 = hapd1.own_addr()
  1108. dev[0].scan_for_bss(bssid1, freq="2412")
  1109. with alloc_fail(hapd0, 1, "wpa_ft_action_rx"):
  1110. # This will fail to roam
  1111. if "OK" not in dev[0].request("FT_DS " + bssid1):
  1112. raise Exception("FT_DS failed")
  1113. wait_fail_trigger(hapd0, "GET_ALLOC_FAIL")
  1114. with alloc_fail(hapd1, 1, "wpa_ft_rrb_rx_request"):
  1115. # This will fail to roam
  1116. if "OK" not in dev[0].request("FT_DS " + bssid1):
  1117. raise Exception("FT_DS failed")
  1118. wait_fail_trigger(hapd1, "GET_ALLOC_FAIL")
  1119. with alloc_fail(hapd1, 1, "wpa_ft_send_rrb_auth_resp"):
  1120. # This will fail to roam
  1121. if "OK" not in dev[0].request("FT_DS " + bssid1):
  1122. raise Exception("FT_DS failed")
  1123. wait_fail_trigger(hapd1, "GET_ALLOC_FAIL")
  1124. def test_ap_ft_ap_oom10(dev, apdev):
  1125. """WPA2-PSK-FT and AP OOM 10"""
  1126. ssid = "test-ft"
  1127. passphrase="12345678"
  1128. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1129. hapd0 = hostapd.add_ap(apdev[0], params)
  1130. bssid0 = hapd0.own_addr()
  1131. dev[0].scan_for_bss(bssid0, freq="2412")
  1132. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1133. scan_freq="2412")
  1134. params = ft_params2(ssid=ssid, passphrase=passphrase)
  1135. hapd1 = hostapd.add_ap(apdev[1], params)
  1136. bssid1 = hapd1.own_addr()
  1137. dev[0].scan_for_bss(bssid1, freq="2412")
  1138. with fail_test(hapd0, 1, "aes_siv_decrypt;wpa_ft_rrb_rx_pull"):
  1139. # This will fail to roam
  1140. if "OK" not in dev[0].request("FT_DS " + bssid1):
  1141. raise Exception("FT_DS failed")
  1142. wait_fail_trigger(hapd0, "GET_FAIL")
  1143. with fail_test(hapd0, 1, "wpa_derive_pmk_r1;wpa_ft_rrb_rx_pull"):
  1144. # This will fail to roam
  1145. if "OK" not in dev[0].request("FT_DS " + bssid1):
  1146. raise Exception("FT_DS failed")
  1147. wait_fail_trigger(hapd0, "GET_FAIL")
  1148. with fail_test(hapd0, 1, "aes_siv_encrypt;wpa_ft_rrb_rx_pull"):
  1149. # This will fail to roam
  1150. if "OK" not in dev[0].request("FT_DS " + bssid1):
  1151. raise Exception("FT_DS failed")
  1152. wait_fail_trigger(hapd0, "GET_FAIL")
  1153. with fail_test(hapd1, 1, "aes_siv_decrypt;wpa_ft_rrb_rx_resp"):
  1154. # This will fail to roam
  1155. if "OK" not in dev[0].request("FT_DS " + bssid1):
  1156. raise Exception("FT_DS failed")
  1157. wait_fail_trigger(hapd1, "GET_FAIL")
  1158. def test_ap_ft_ap_oom11(dev, apdev):
  1159. """WPA2-PSK-FT and AP OOM 11"""
  1160. ssid = "test-ft"
  1161. passphrase="12345678"
  1162. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1163. hapd0 = hostapd.add_ap(apdev[0], params)
  1164. bssid0 = hapd0.own_addr()
  1165. dev[0].scan_for_bss(bssid0, freq="2412")
  1166. with fail_test(hapd0, 1, "wpa_derive_pmk_r1;wpa_ft_generate_pmk_r1"):
  1167. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1168. scan_freq="2412")
  1169. wait_fail_trigger(hapd0, "GET_FAIL")
  1170. dev[1].scan_for_bss(bssid0, freq="2412")
  1171. with fail_test(hapd0, 1, "aes_siv_encrypt;wpa_ft_generate_pmk_r1"):
  1172. dev[1].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1173. scan_freq="2412")
  1174. wait_fail_trigger(hapd0, "GET_FAIL")
  1175. def test_ap_ft_over_ds_proto_ap(dev, apdev):
  1176. """WPA2-PSK-FT AP over DS protocol testing for AP processing"""
  1177. ssid = "test-ft"
  1178. passphrase="12345678"
  1179. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1180. hapd0 = hostapd.add_ap(apdev[0], params)
  1181. bssid0 = hapd0.own_addr()
  1182. _bssid0 = bssid0.replace(':', '')
  1183. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1184. scan_freq="2412")
  1185. addr = dev[0].own_addr()
  1186. _addr = addr.replace(':', '')
  1187. params = ft_params2(ssid=ssid, passphrase=passphrase)
  1188. hapd1 = hostapd.add_ap(apdev[1], params)
  1189. bssid1 = hapd1.own_addr()
  1190. _bssid1 = bssid1.replace(':', '')
  1191. hapd0.set("ext_mgmt_frame_handling", "1")
  1192. hdr = "d0003a01" + _bssid0 + _addr + _bssid0 + "1000"
  1193. valid = "0601" + _addr + _bssid1
  1194. tests = [ "0601",
  1195. "0601" + _addr,
  1196. "0601" + _addr + _bssid0,
  1197. "0601" + _addr + "ffffffffffff",
  1198. "0601" + _bssid0 + _bssid0,
  1199. valid,
  1200. valid + "01",
  1201. valid + "3700",
  1202. valid + "3600",
  1203. valid + "3603ffffff",
  1204. valid + "3603a1b2ff",
  1205. valid + "3603a1b2ff" + "3700",
  1206. valid + "3603a1b2ff" + "37520000" + 16*"00" + 32*"00" + 32*"00",
  1207. valid + "3603a1b2ff" + "37520001" + 16*"00" + 32*"00" + 32*"00",
  1208. valid + "3603a1b2ff" + "37550000" + 16*"00" + 32*"00" + 32*"00" + "0301aa",
  1209. valid + "3603a1b2ff" + "37550000" + 16*"00" + 32*"00" + 32*"00" + "0301aa" + "3000",
  1210. valid + "3603a1b2ff" + "37550000" + 16*"00" + 32*"00" + 32*"00" + "0301aa" + "30260100000fac040100000fac040100000facff00000100a225368fe0983b5828a37a0acb37f253",
  1211. valid + "3603a1b2ff" + "37550000" + 16*"00" + 32*"00" + 32*"00" + "0301aa" + "30260100000fac040100000fac030100000fac0400000100a225368fe0983b5828a37a0acb37f253",
  1212. valid + "3603a1b2ff" + "37550000" + 16*"00" + 32*"00" + 32*"00" + "0301aa" + "30260100000fac040100000fac040100000fac0400000100a225368fe0983b5828a37a0acb37f253",
  1213. valid + "0001" ]
  1214. for t in tests:
  1215. hapd0.dump_monitor()
  1216. if "OK" not in hapd0.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + t):
  1217. raise Exception("MGMT_RX_PROCESS failed")
  1218. hapd0.set("ext_mgmt_frame_handling", "0")
  1219. def test_ap_ft_over_ds_proto(dev, apdev):
  1220. """WPA2-PSK-FT AP over DS protocol testing"""
  1221. ssid = "test-ft"
  1222. passphrase="12345678"
  1223. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1224. hapd0 = hostapd.add_ap(apdev[0], params)
  1225. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1226. scan_freq="2412")
  1227. # FT Action Response while no FT-over-DS in progress
  1228. msg = {}
  1229. msg['fc'] = 13 << 4
  1230. msg['da'] = dev[0].own_addr()
  1231. msg['sa'] = apdev[0]['bssid']
  1232. msg['bssid'] = apdev[0]['bssid']
  1233. msg['payload'] = binascii.unhexlify("06020200000000000200000004000000")
  1234. hapd0.mgmt_tx(msg)
  1235. params = ft_params2(ssid=ssid, passphrase=passphrase)
  1236. hapd1 = hostapd.add_ap(apdev[1], params)
  1237. dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
  1238. hapd0.set("ext_mgmt_frame_handling", "1")
  1239. hapd0.dump_monitor()
  1240. dev[0].request("FT_DS " + apdev[1]['bssid'])
  1241. for i in range(0, 10):
  1242. req = hapd0.mgmt_rx()
  1243. if req is None:
  1244. raise Exception("MGMT RX wait timed out")
  1245. if req['subtype'] == 13:
  1246. break
  1247. req = None
  1248. if not req:
  1249. raise Exception("FT Action frame not received")
  1250. # FT Action Response for unexpected Target AP
  1251. msg['payload'] = binascii.unhexlify("0602020000000000" + "f20000000400" + "0000")
  1252. hapd0.mgmt_tx(msg)
  1253. # FT Action Response without MDIE
  1254. msg['payload'] = binascii.unhexlify("0602020000000000" + "020000000400" + "0000")
  1255. hapd0.mgmt_tx(msg)
  1256. # FT Action Response without FTIE
  1257. msg['payload'] = binascii.unhexlify("0602020000000000" + "020000000400" + "0000" + "3603a1b201")
  1258. hapd0.mgmt_tx(msg)
  1259. # FT Action Response with FTIE SNonce mismatch
  1260. msg['payload'] = binascii.unhexlify("0602020000000000" + "020000000400" + "0000" + "3603a1b201" + "3766000000000000000000000000000000000000c4e67ac1999bebd00ff4ae4d5dcaf87896bb060b469f7c78d49623fb395c3455ffffff6b693fe6f8d8c5dfac0a22344750775bd09437f98b238c9f87b97f790c0106000102030406030a6e6173312e77312e6669")
  1261. hapd0.mgmt_tx(msg)
  1262. @remote_compatible
  1263. def test_ap_ft_rrb(dev, apdev):
  1264. """WPA2-PSK-FT RRB protocol testing"""
  1265. ssid = "test-ft"
  1266. passphrase="12345678"
  1267. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1268. hapd0 = hostapd.add_ap(apdev[0], params)
  1269. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1270. scan_freq="2412")
  1271. _dst_ll = binascii.unhexlify(apdev[0]['bssid'].replace(':',''))
  1272. _src_ll = binascii.unhexlify(dev[0].own_addr().replace(':',''))
  1273. proto = '\x89\x0d'
  1274. ehdr = _dst_ll + _src_ll + proto
  1275. # Too short RRB frame
  1276. pkt = ehdr + '\x01'
  1277. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1278. raise Exception("DATA_TEST_FRAME failed")
  1279. # RRB discarded frame wikth unrecognized type
  1280. pkt = ehdr + '\x02' + '\x02' + '\x01\x00' + _src_ll
  1281. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1282. raise Exception("DATA_TEST_FRAME failed")
  1283. # RRB frame too short for action frame
  1284. pkt = ehdr + '\x01' + '\x02' + '\x01\x00' + _src_ll
  1285. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1286. raise Exception("DATA_TEST_FRAME failed")
  1287. # Too short RRB frame (not enough room for Action Frame body)
  1288. pkt = ehdr + '\x01' + '\x02' + '\x00\x00' + _src_ll
  1289. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1290. raise Exception("DATA_TEST_FRAME failed")
  1291. # Unexpected Action frame category
  1292. pkt = ehdr + '\x01' + '\x02' + '\x0e\x00' + _src_ll + '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
  1293. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1294. raise Exception("DATA_TEST_FRAME failed")
  1295. # Unexpected Action in RRB Request
  1296. pkt = ehdr + '\x01' + '\x00' + '\x0e\x00' + _src_ll + '\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
  1297. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1298. raise Exception("DATA_TEST_FRAME failed")
  1299. # Target AP address in RRB Request does not match with own address
  1300. pkt = ehdr + '\x01' + '\x00' + '\x0e\x00' + _src_ll + '\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
  1301. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1302. raise Exception("DATA_TEST_FRAME failed")
  1303. # Not enough room for status code in RRB Response
  1304. pkt = ehdr + '\x01' + '\x01' + '\x0e\x00' + _src_ll + '\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
  1305. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1306. raise Exception("DATA_TEST_FRAME failed")
  1307. # RRB discarded frame with unknown packet_type
  1308. pkt = ehdr + '\x01' + '\x02' + '\x0e\x00' + _src_ll + '\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
  1309. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1310. raise Exception("DATA_TEST_FRAME failed")
  1311. # RRB Response with non-zero status code; no STA match
  1312. pkt = ehdr + '\x01' + '\x01' + '\x10\x00' + _src_ll + '\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + '\xff\xff'
  1313. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1314. raise Exception("DATA_TEST_FRAME failed")
  1315. # RRB Response with zero status code and extra data; STA match
  1316. pkt = ehdr + '\x01' + '\x01' + '\x11\x00' + _src_ll + '\x06\x01' + _src_ll + '\x00\x00\x00\x00\x00\x00' + '\x00\x00' + '\x00'
  1317. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1318. raise Exception("DATA_TEST_FRAME failed")
  1319. # Too short PMK-R1 pull
  1320. pkt = ehdr + '\x01' + '\xc8' + '\x0e\x00' + _src_ll + '\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
  1321. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1322. raise Exception("DATA_TEST_FRAME failed")
  1323. # Too short PMK-R1 resp
  1324. pkt = ehdr + '\x01' + '\xc9' + '\x0e\x00' + _src_ll + '\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
  1325. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1326. raise Exception("DATA_TEST_FRAME failed")
  1327. # Too short PMK-R1 push
  1328. pkt = ehdr + '\x01' + '\xca' + '\x0e\x00' + _src_ll + '\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
  1329. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1330. raise Exception("DATA_TEST_FRAME failed")
  1331. # No matching R0KH address found for PMK-R0 pull response
  1332. pkt = ehdr + '\x01' + '\xc9' + '\x5a\x00' + _src_ll + '\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + 76*'\00'
  1333. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1334. raise Exception("DATA_TEST_FRAME failed")
  1335. @remote_compatible
  1336. def test_rsn_ie_proto_ft_psk_sta(dev, apdev):
  1337. """RSN element protocol testing for FT-PSK + PMF cases on STA side"""
  1338. bssid = apdev[0]['bssid']
  1339. ssid = "test-ft"
  1340. passphrase="12345678"
  1341. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1342. params["ieee80211w"] = "1"
  1343. # This is the RSN element used normally by hostapd
  1344. params['own_ie_override'] = '30140100000fac040100000fac040100000fac048c00' + '3603a1b201'
  1345. hapd = hostapd.add_ap(apdev[0], params)
  1346. id = dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1347. ieee80211w="1", scan_freq="2412",
  1348. pairwise="CCMP", group="CCMP")
  1349. tests = [ ('PMKIDCount field included',
  1350. '30160100000fac040100000fac040100000fac048c000000' + '3603a1b201'),
  1351. ('Extra IE before RSNE',
  1352. 'dd0400000000' + '30140100000fac040100000fac040100000fac048c00' + '3603a1b201'),
  1353. ('PMKIDCount and Group Management Cipher suite fields included',
  1354. '301a0100000fac040100000fac040100000fac048c000000000fac06' + '3603a1b201'),
  1355. ('Extra octet after defined fields (future extensibility)',
  1356. '301b0100000fac040100000fac040100000fac048c000000000fac0600' + '3603a1b201'),
  1357. ('No RSN Capabilities field (PMF disabled in practice)',
  1358. '30120100000fac040100000fac040100000fac04' + '3603a1b201') ]
  1359. for txt,ie in tests:
  1360. dev[0].request("DISCONNECT")
  1361. dev[0].wait_disconnected()
  1362. logger.info(txt)
  1363. hapd.disable()
  1364. hapd.set('own_ie_override', ie)
  1365. hapd.enable()
  1366. dev[0].request("BSS_FLUSH 0")
  1367. dev[0].scan_for_bss(bssid, 2412, force_scan=True, only_new=True)
  1368. dev[0].select_network(id, freq=2412)
  1369. dev[0].wait_connected()
  1370. dev[0].request("DISCONNECT")
  1371. dev[0].wait_disconnected()
  1372. logger.info('Invalid RSNE causing internal hostapd error')
  1373. hapd.disable()
  1374. hapd.set('own_ie_override', '30130100000fac040100000fac040100000fac048c' + '3603a1b201')
  1375. hapd.enable()
  1376. dev[0].request("BSS_FLUSH 0")
  1377. dev[0].scan_for_bss(bssid, 2412, force_scan=True, only_new=True)
  1378. dev[0].select_network(id, freq=2412)
  1379. # hostapd fails to generate EAPOL-Key msg 3/4, so this connection cannot
  1380. # complete.
  1381. ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1)
  1382. if ev is not None:
  1383. raise Exception("Unexpected connection")
  1384. dev[0].request("DISCONNECT")
  1385. logger.info('Unexpected PMKID causing internal hostapd error')
  1386. hapd.disable()
  1387. hapd.set('own_ie_override', '30260100000fac040100000fac040100000fac048c000100ffffffffffffffffffffffffffffffff' + '3603a1b201')
  1388. hapd.enable()
  1389. dev[0].request("BSS_FLUSH 0")
  1390. dev[0].scan_for_bss(bssid, 2412, force_scan=True, only_new=True)
  1391. dev[0].select_network(id, freq=2412)
  1392. # hostapd fails to generate EAPOL-Key msg 3/4, so this connection cannot
  1393. # complete.
  1394. ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1)
  1395. if ev is not None:
  1396. raise Exception("Unexpected connection")
  1397. dev[0].request("DISCONNECT")
  1398. def test_ap_ft_ptk_rekey(dev, apdev):
  1399. """WPA2-PSK-FT PTK rekeying triggered by station after roam"""
  1400. ssid = "test-ft"
  1401. passphrase="12345678"
  1402. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1403. hapd0 = hostapd.add_ap(apdev[0], params)
  1404. params = ft_params2(ssid=ssid, passphrase=passphrase)
  1405. hapd1 = hostapd.add_ap(apdev[1], params)
  1406. run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, ptk_rekey="1")
  1407. ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED",
  1408. "WPA: Key negotiation completed"], timeout=5)
  1409. if ev is None:
  1410. raise Exception("No event received after roam")
  1411. if "CTRL-EVENT-DISCONNECTED" in ev:
  1412. raise Exception("Unexpected disconnection after roam")
  1413. if dev[0].get_status_field('bssid') == apdev[0]['bssid']:
  1414. hapd = hapd0
  1415. else:
  1416. hapd = hapd1
  1417. hwsim_utils.test_connectivity(dev[0], hapd)
  1418. def test_ap_ft_ptk_rekey_ap(dev, apdev):
  1419. """WPA2-PSK-FT PTK rekeying triggered by AP after roam"""
  1420. ssid = "test-ft"
  1421. passphrase="12345678"
  1422. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1423. params['wpa_ptk_rekey'] = '2'
  1424. hapd0 = hostapd.add_ap(apdev[0], params)
  1425. params = ft_params2(ssid=ssid, passphrase=passphrase)
  1426. params['wpa_ptk_rekey'] = '2'
  1427. hapd1 = hostapd.add_ap(apdev[1], params)
  1428. run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase)
  1429. ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED",
  1430. "WPA: Key negotiation completed"], timeout=5)
  1431. if ev is None:
  1432. raise Exception("No event received after roam")
  1433. if "CTRL-EVENT-DISCONNECTED" in ev:
  1434. raise Exception("Unexpected disconnection after roam")
  1435. if dev[0].get_status_field('bssid') == apdev[0]['bssid']:
  1436. hapd = hapd0
  1437. else:
  1438. hapd = hapd1
  1439. hwsim_utils.test_connectivity(dev[0], hapd)
  1440. def test_ap_ft_internal_rrb_check(dev, apdev):
  1441. """RRB internal delivery only to WPA enabled BSS"""
  1442. ssid = "test-ft"
  1443. passphrase="12345678"
  1444. radius = hostapd.radius_params()
  1445. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1446. params['wpa_key_mgmt'] = "FT-EAP"
  1447. params["ieee8021x"] = "1"
  1448. params = dict(radius.items() + params.items())
  1449. hapd = hostapd.add_ap(apdev[0], params)
  1450. key_mgmt = hapd.get_config()['key_mgmt']
  1451. if key_mgmt.split(' ')[0] != "FT-EAP":
  1452. raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
  1453. hapd1 = hostapd.add_ap(apdev[1], { "ssid" : ssid })
  1454. # Connect to WPA enabled AP
  1455. dev[0].connect(ssid, key_mgmt="FT-EAP", proto="WPA2", ieee80211w="1",
  1456. eap="GPSK", identity="gpsk user",
  1457. password="abcdefghijklmnop0123456789abcdef",
  1458. scan_freq="2412")
  1459. # Try over_ds roaming to non-WPA-enabled AP.
  1460. # If hostapd does not check hapd->wpa_auth internally, it will crash now.
  1461. dev[0].roam_over_ds(apdev[1]['bssid'], fail_test=True)
  1462. def test_ap_ft_extra_ie(dev, apdev):
  1463. """WPA2-PSK-FT AP with WPA2-PSK enabled and unexpected MDE"""
  1464. ssid = "test-ft"
  1465. passphrase="12345678"
  1466. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1467. params["wpa_key_mgmt"] = "WPA-PSK FT-PSK"
  1468. hapd0 = hostapd.add_ap(apdev[0], params)
  1469. dev[1].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1470. scan_freq="2412")
  1471. dev[2].connect(ssid, psk=passphrase, key_mgmt="WPA-PSK", proto="WPA2",
  1472. scan_freq="2412")
  1473. try:
  1474. # Add Mobility Domain element to test AP validation code.
  1475. dev[0].request("VENDOR_ELEM_ADD 13 3603a1b201")
  1476. dev[0].connect(ssid, psk=passphrase, key_mgmt="WPA-PSK", proto="WPA2",
  1477. scan_freq="2412", wait_connect=False)
  1478. ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
  1479. "CTRL-EVENT-ASSOC-REJECT"], timeout=10)
  1480. if ev is None:
  1481. raise Exception("No connection result")
  1482. if "CTRL-EVENT-CONNECTED" in ev:
  1483. raise Exception("Non-FT association accepted with MDE")
  1484. if "status_code=43" not in ev:
  1485. raise Exception("Unexpected status code: " + ev)
  1486. dev[0].request("DISCONNECT")
  1487. finally:
  1488. dev[0].request("VENDOR_ELEM_REMOVE 13 *")
  1489. def test_ap_ft_ric(dev, apdev):
  1490. """WPA2-PSK-FT AP and RIC"""
  1491. ssid = "test-ft"
  1492. passphrase="12345678"
  1493. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1494. hapd0 = hostapd.add_ap(apdev[0], params)
  1495. params = ft_params2(ssid=ssid, passphrase=passphrase)
  1496. hapd1 = hostapd.add_ap(apdev[1], params)
  1497. dev[0].set("ric_ies", "")
  1498. dev[0].set("ric_ies", '""')
  1499. if "FAIL" not in dev[0].request("SET ric_ies q"):
  1500. raise Exception("Invalid ric_ies value accepted")
  1501. tests = [ "3900",
  1502. "3900ff04eeeeeeee",
  1503. "390400000000",
  1504. "390400000000" + "390400000000",
  1505. "390400000000" + "dd050050f20202",
  1506. "390400000000" + "dd3d0050f2020201" + 55*"00",
  1507. "390400000000" + "dd3d0050f2020201aa300010270000000000000000000000000000000000000000000000000000ffffff7f00000000000000000000000040420f00ffff0000",
  1508. "390401010000" + "dd3d0050f2020201aa3000dc050000000000000000000000000000000000000000000000000000dc050000000000000000000000000000808d5b0028230000" ]
  1509. for t in tests:
  1510. dev[0].set("ric_ies", t)
  1511. run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase,
  1512. test_connectivity=False)
  1513. dev[0].request("REMOVE_NETWORK all")
  1514. dev[0].wait_disconnected()
  1515. dev[0].dump_monitor()
  1516. def ie_hex(ies, id):
  1517. return binascii.hexlify(struct.pack('BB', id, len(ies[id])) + ies[id])
  1518. def test_ap_ft_reassoc_proto(dev, apdev):
  1519. """WPA2-PSK-FT AP Reassociation Request frame parsing"""
  1520. ssid = "test-ft"
  1521. passphrase="12345678"
  1522. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1523. hapd0 = hostapd.add_ap(apdev[0], params)
  1524. params = ft_params2(ssid=ssid, passphrase=passphrase)
  1525. hapd1 = hostapd.add_ap(apdev[1], params)
  1526. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1527. ieee80211w="1", scan_freq="2412")
  1528. if dev[0].get_status_field('bssid') == hapd0.own_addr():
  1529. hapd1ap = hapd0
  1530. hapd2ap = hapd1
  1531. else:
  1532. hapd1ap = hapd1
  1533. hapd2ap = hapd0
  1534. dev[0].scan_for_bss(hapd2ap.own_addr(), freq="2412")
  1535. hapd2ap.set("ext_mgmt_frame_handling", "1")
  1536. dev[0].request("ROAM " + hapd2ap.own_addr())
  1537. while True:
  1538. req = hapd2ap.mgmt_rx()
  1539. hapd2ap.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']))
  1540. if req['subtype'] == 11:
  1541. break
  1542. while True:
  1543. req = hapd2ap.mgmt_rx()
  1544. if req['subtype'] == 2:
  1545. break
  1546. hapd2ap.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']))
  1547. # IEEE 802.11 header + fixed fields before IEs
  1548. hdr = binascii.hexlify(req['frame'][0:34])
  1549. ies = parse_ie(binascii.hexlify(req['frame'][34:]))
  1550. # First elements: SSID, Supported Rates, Extended Supported Rates
  1551. ies1 = ie_hex(ies, 0) + ie_hex(ies, 1) + ie_hex(ies, 50)
  1552. rsne = ie_hex(ies, 48)
  1553. mde = ie_hex(ies, 54)
  1554. fte = ie_hex(ies, 55)
  1555. tests = [ ]
  1556. # RSN: Trying to use FT, but MDIE not included
  1557. tests += [ rsne ]
  1558. # RSN: Attempted to use unknown MDIE
  1559. tests += [ rsne + "3603000000" ]
  1560. # Invalid RSN pairwise cipher
  1561. tests += [ "30260100000fac040100000fac030100000fac040000010029208a42cd25c85aa571567dce10dae3" ]
  1562. # FT: No PMKID in RSNIE
  1563. tests += [ "30160100000fac040100000fac040100000fac0400000000" + ie_hex(ies, 54) ]
  1564. # FT: Invalid FTIE
  1565. tests += [ rsne + mde ]
  1566. # FT: RIC IE(s) in the frame, but not included in protected IE count
  1567. # FT: Failed to parse FT IEs
  1568. tests += [ rsne + mde + fte + "3900" ]
  1569. # FT: SNonce mismatch in FTIE
  1570. tests += [ rsne + mde + "37520000" + 16*"00" + 32*"00" + 32*"00" ]
  1571. # FT: ANonce mismatch in FTIE
  1572. tests += [ rsne + mde + fte[0:40] + 32*"00" + fte[104:] ]
  1573. # FT: No R0KH-ID subelem in FTIE
  1574. tests += [ rsne + mde + "3752" + fte[4:168] ]
  1575. # FT: R0KH-ID in FTIE did not match with the current R0KH-ID
  1576. tests += [ rsne + mde + "3755" + fte[4:168] + "0301ff" ]
  1577. # FT: No R1KH-ID subelem in FTIE
  1578. tests += [ rsne + mde + "375e" + fte[4:168] + "030a" + "nas1.w1.fi".encode("hex") ]
  1579. # FT: Unknown R1KH-ID used in ReassocReq
  1580. tests += [ rsne + mde + "3766" + fte[4:168] + "030a" + "nas1.w1.fi".encode("hex") + "0106000000000000" ]
  1581. # FT: PMKID in Reassoc Req did not match with the PMKR1Name derived from auth request
  1582. tests += [ rsne[:-32] + 16*"00" + mde + fte ]
  1583. # Invalid MIC in FTIE
  1584. tests += [ rsne + mde + fte[0:8] + 16*"00" + fte[40:] ]
  1585. for t in tests:
  1586. hapd2ap.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + ies1 + t)
  1587. def test_ap_ft_reassoc_local_fail(dev, apdev):
  1588. """WPA2-PSK-FT AP Reassociation Request frame and local failure"""
  1589. ssid = "test-ft"
  1590. passphrase="12345678"
  1591. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1592. hapd0 = hostapd.add_ap(apdev[0], params)
  1593. params = ft_params2(ssid=ssid, passphrase=passphrase)
  1594. hapd1 = hostapd.add_ap(apdev[1], params)
  1595. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1596. ieee80211w="1", scan_freq="2412")
  1597. if dev[0].get_status_field('bssid') == hapd0.own_addr():
  1598. hapd1ap = hapd0
  1599. hapd2ap = hapd1
  1600. else:
  1601. hapd1ap = hapd1
  1602. hapd2ap = hapd0
  1603. dev[0].scan_for_bss(hapd2ap.own_addr(), freq="2412")
  1604. # FT: Failed to calculate MIC
  1605. with fail_test(hapd2ap, 1, "wpa_ft_validate_reassoc"):
  1606. dev[0].request("ROAM " + hapd2ap.own_addr())
  1607. ev = dev[0].wait_event(["CTRL-EVENT-ASSOC-REJECT"], timeout=10)
  1608. dev[0].request("DISCONNECT")
  1609. if ev is None:
  1610. raise Exception("Association reject not seen")
  1611. def test_ap_ft_reassoc_replay(dev, apdev, params):
  1612. """WPA2-PSK-FT AP and replayed Reassociation Request frame"""
  1613. capfile = os.path.join(params['logdir'], "hwsim0.pcapng")
  1614. ssid = "test-ft"
  1615. passphrase="12345678"
  1616. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1617. hapd0 = hostapd.add_ap(apdev[0], params)
  1618. params = ft_params2(ssid=ssid, passphrase=passphrase)
  1619. hapd1 = hostapd.add_ap(apdev[1], params)
  1620. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1621. scan_freq="2412")
  1622. if dev[0].get_status_field('bssid') == hapd0.own_addr():
  1623. hapd1ap = hapd0
  1624. hapd2ap = hapd1
  1625. else:
  1626. hapd1ap = hapd1
  1627. hapd2ap = hapd0
  1628. dev[0].scan_for_bss(hapd2ap.own_addr(), freq="2412")
  1629. hapd2ap.set("ext_mgmt_frame_handling", "1")
  1630. dev[0].dump_monitor()
  1631. if "OK" not in dev[0].request("ROAM " + hapd2ap.own_addr()):
  1632. raise Exception("ROAM failed")
  1633. reassocreq = None
  1634. count = 0
  1635. while count < 100:
  1636. req = hapd2ap.mgmt_rx()
  1637. count += 1
  1638. hapd2ap.dump_monitor()
  1639. hapd2ap.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']))
  1640. if req['subtype'] == 2:
  1641. reassocreq = req
  1642. ev = hapd2ap.wait_event(["MGMT-TX-STATUS"], timeout=5)
  1643. if ev is None:
  1644. raise Exception("No TX status seen")
  1645. cmd = "MGMT_TX_STATUS_PROCESS %s" % (" ".join(ev.split(' ')[1:4]))
  1646. if "OK" not in hapd2ap.request(cmd):
  1647. raise Exception("MGMT_TX_STATUS_PROCESS failed")
  1648. break
  1649. hapd2ap.set("ext_mgmt_frame_handling", "0")
  1650. if reassocreq is None:
  1651. raise Exception("No Reassociation Request frame seen")
  1652. dev[0].wait_connected()
  1653. dev[0].dump_monitor()
  1654. hapd2ap.dump_monitor()
  1655. hwsim_utils.test_connectivity(dev[0], hapd2ap)
  1656. logger.info("Replay the last Reassociation Request frame")
  1657. hapd2ap.dump_monitor()
  1658. hapd2ap.set("ext_mgmt_frame_handling", "1")
  1659. hapd2ap.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']))
  1660. ev = hapd2ap.wait_event(["MGMT-TX-STATUS"], timeout=5)
  1661. if ev is None:
  1662. raise Exception("No TX status seen")
  1663. cmd = "MGMT_TX_STATUS_PROCESS %s" % (" ".join(ev.split(' ')[1:4]))
  1664. if "OK" not in hapd2ap.request(cmd):
  1665. raise Exception("MGMT_TX_STATUS_PROCESS failed")
  1666. hapd2ap.set("ext_mgmt_frame_handling", "0")
  1667. try:
  1668. hwsim_utils.test_connectivity(dev[0], hapd2ap)
  1669. ok = True
  1670. except:
  1671. ok = False
  1672. ap = hapd2ap.own_addr()
  1673. sta = dev[0].own_addr()
  1674. filt = "wlan.fc.type == 2 && " + \
  1675. "wlan.da == " + sta + " && " + \
  1676. "wlan.sa == " + ap
  1677. fields = [ "wlan.ccmp.extiv" ]
  1678. res = run_tshark(capfile, filt, fields)
  1679. vals = res.splitlines()
  1680. logger.info("CCMP PN: " + str(vals))
  1681. if len(vals) < 2:
  1682. raise Exception("Could not find all CCMP protected frames from capture")
  1683. if len(set(vals)) < len(vals):
  1684. raise Exception("Duplicate CCMP PN used")
  1685. if not ok:
  1686. raise Exception("The second hwsim connectivity test failed")