test_ap_ft.py 79 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995
  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. logger.info("Checking keys in memory after disassociation")
  771. buf = read_process_memory(pid, pmk)
  772. get_key_locations(buf, pmk, "PMK")
  773. get_key_locations(buf, pmkr0, "PMK-R0")
  774. get_key_locations(buf, pmkr1, "PMK-R1")
  775. # Note: PMK/PSK is still present in network configuration
  776. fname = os.path.join(params['logdir'],
  777. 'ft_psk_key_lifetime_in_memory.memctx-')
  778. verify_not_present(buf, pmkr0, fname, "PMK-R0")
  779. verify_not_present(buf, pmkr1, fname, "PMK-R1")
  780. verify_not_present(buf, kck, fname, "KCK")
  781. verify_not_present(buf, kek, fname, "KEK")
  782. verify_not_present(buf, tk, fname, "TK")
  783. if gtk in buf:
  784. get_key_locations(buf, gtk, "GTK")
  785. verify_not_present(buf, gtk, fname, "GTK")
  786. dev[0].request("REMOVE_NETWORK all")
  787. logger.info("Checking keys in memory after network profile removal")
  788. buf = read_process_memory(pid, pmk)
  789. get_key_locations(buf, pmk, "PMK")
  790. get_key_locations(buf, pmkr0, "PMK-R0")
  791. get_key_locations(buf, pmkr1, "PMK-R1")
  792. verify_not_present(buf, pmk, fname, "PMK")
  793. verify_not_present(buf, pmkr0, fname, "PMK-R0")
  794. verify_not_present(buf, pmkr1, fname, "PMK-R1")
  795. verify_not_present(buf, kck, fname, "KCK")
  796. verify_not_present(buf, kek, fname, "KEK")
  797. verify_not_present(buf, tk, fname, "TK")
  798. verify_not_present(buf, gtk, fname, "GTK")
  799. @remote_compatible
  800. def test_ap_ft_invalid_resp(dev, apdev):
  801. """WPA2-PSK-FT AP and invalid response IEs"""
  802. ssid = "test-ft"
  803. passphrase="12345678"
  804. params = ft_params1(ssid=ssid, passphrase=passphrase)
  805. hapd0 = hostapd.add_ap(apdev[0], params)
  806. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  807. scan_freq="2412")
  808. params = ft_params2(ssid=ssid, passphrase=passphrase)
  809. hapd1 = hostapd.add_ap(apdev[1], params)
  810. tests = [
  811. # Various IEs for test coverage. The last one is FTIE with invalid
  812. # R1KH-ID subelement.
  813. "020002000000" + "3800" + "38051122334455" + "3754000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010100",
  814. # FTIE with invalid R0KH-ID subelement (len=0).
  815. "020002000000" + "3754000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010300",
  816. # FTIE with invalid R0KH-ID subelement (len=49).
  817. "020002000000" + "378500010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001033101020304050607080910111213141516171819202122232425262728293031323334353637383940414243444546474849",
  818. # Invalid RSNE.
  819. "020002000000" + "3000",
  820. # Required IEs missing from protected IE count.
  821. "020002000000" + "3603a1b201" + "375200010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001" + "3900",
  822. # RIC missing from protected IE count.
  823. "020002000000" + "3603a1b201" + "375200020203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001" + "3900",
  824. # Protected IE missing.
  825. "020002000000" + "3603a1b201" + "375200ff0203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001" + "3900" + "0000" ]
  826. for t in tests:
  827. dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
  828. hapd1.set("ext_mgmt_frame_handling", "1")
  829. hapd1.dump_monitor()
  830. if "OK" not in dev[0].request("ROAM " + apdev[1]['bssid']):
  831. raise Exception("ROAM failed")
  832. auth = None
  833. for i in range(20):
  834. msg = hapd1.mgmt_rx()
  835. if msg['subtype'] == 11:
  836. auth = msg
  837. break
  838. if not auth:
  839. raise Exception("Authentication frame not seen")
  840. resp = {}
  841. resp['fc'] = auth['fc']
  842. resp['da'] = auth['sa']
  843. resp['sa'] = auth['da']
  844. resp['bssid'] = auth['bssid']
  845. resp['payload'] = binascii.unhexlify(t)
  846. hapd1.mgmt_tx(resp)
  847. hapd1.set("ext_mgmt_frame_handling", "0")
  848. dev[0].wait_disconnected()
  849. dev[0].request("RECONNECT")
  850. dev[0].wait_connected()
  851. def test_ap_ft_gcmp_256(dev, apdev):
  852. """WPA2-PSK-FT AP with GCMP-256 cipher"""
  853. if "GCMP-256" not in dev[0].get_capability("pairwise"):
  854. raise HwsimSkip("Cipher GCMP-256 not supported")
  855. ssid = "test-ft"
  856. passphrase="12345678"
  857. params = ft_params1(ssid=ssid, passphrase=passphrase)
  858. params['rsn_pairwise'] = "GCMP-256"
  859. hapd0 = hostapd.add_ap(apdev[0], params)
  860. params = ft_params2(ssid=ssid, passphrase=passphrase)
  861. params['rsn_pairwise'] = "GCMP-256"
  862. hapd1 = hostapd.add_ap(apdev[1], params)
  863. run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase,
  864. pairwise_cipher="GCMP-256", group_cipher="GCMP-256")
  865. def test_ap_ft_oom(dev, apdev):
  866. """WPA2-PSK-FT and OOM"""
  867. skip_with_fips(dev[0])
  868. ssid = "test-ft"
  869. passphrase="12345678"
  870. params = ft_params1(ssid=ssid, passphrase=passphrase)
  871. hapd0 = hostapd.add_ap(apdev[0], params)
  872. params = ft_params2(ssid=ssid, passphrase=passphrase)
  873. hapd1 = hostapd.add_ap(apdev[1], params)
  874. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  875. scan_freq="2412")
  876. if dev[0].get_status_field('bssid') == apdev[0]['bssid']:
  877. dst = apdev[1]['bssid']
  878. else:
  879. dst = apdev[0]['bssid']
  880. dev[0].scan_for_bss(dst, freq="2412")
  881. with alloc_fail(dev[0], 1, "wpa_ft_gen_req_ies"):
  882. dev[0].roam(dst)
  883. with fail_test(dev[0], 1, "wpa_ft_mic"):
  884. dev[0].roam(dst, fail_test=True)
  885. with fail_test(dev[0], 1, "os_get_random;wpa_ft_prepare_auth_request"):
  886. dev[0].roam(dst, fail_test=True)
  887. dev[0].request("REMOVE_NETWORK all")
  888. with alloc_fail(dev[0], 1, "=sme_update_ft_ies"):
  889. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  890. scan_freq="2412")
  891. def test_ap_ft_ap_oom(dev, apdev):
  892. """WPA2-PSK-FT and AP OOM"""
  893. ssid = "test-ft"
  894. passphrase="12345678"
  895. params = ft_params1(ssid=ssid, passphrase=passphrase)
  896. hapd0 = hostapd.add_ap(apdev[0], params)
  897. bssid0 = hapd0.own_addr()
  898. dev[0].scan_for_bss(bssid0, freq="2412")
  899. with alloc_fail(hapd0, 1, "wpa_ft_store_pmk_r0"):
  900. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  901. scan_freq="2412")
  902. params = ft_params2(ssid=ssid, passphrase=passphrase)
  903. hapd1 = hostapd.add_ap(apdev[1], params)
  904. bssid1 = hapd1.own_addr()
  905. dev[0].scan_for_bss(bssid1, freq="2412")
  906. # This roam will fail due to missing PMK-R0 (OOM prevented storing it)
  907. dev[0].roam(bssid1)
  908. def test_ap_ft_ap_oom2(dev, apdev):
  909. """WPA2-PSK-FT and AP OOM 2"""
  910. ssid = "test-ft"
  911. passphrase="12345678"
  912. params = ft_params1(ssid=ssid, passphrase=passphrase)
  913. hapd0 = hostapd.add_ap(apdev[0], params)
  914. bssid0 = hapd0.own_addr()
  915. dev[0].scan_for_bss(bssid0, freq="2412")
  916. with alloc_fail(hapd0, 1, "wpa_ft_store_pmk_r1"):
  917. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  918. scan_freq="2412")
  919. params = ft_params2(ssid=ssid, passphrase=passphrase)
  920. hapd1 = hostapd.add_ap(apdev[1], params)
  921. bssid1 = hapd1.own_addr()
  922. dev[0].scan_for_bss(bssid1, freq="2412")
  923. dev[0].roam(bssid1)
  924. if dev[0].get_status_field('bssid') != bssid1:
  925. raise Exception("Did not roam to AP1")
  926. # This roam will fail due to missing PMK-R1 (OOM prevented storing it)
  927. dev[0].roam(bssid0)
  928. def test_ap_ft_ap_oom3(dev, apdev):
  929. """WPA2-PSK-FT and AP OOM 3"""
  930. ssid = "test-ft"
  931. passphrase="12345678"
  932. params = ft_params1(ssid=ssid, passphrase=passphrase)
  933. hapd0 = hostapd.add_ap(apdev[0], params)
  934. bssid0 = hapd0.own_addr()
  935. dev[0].scan_for_bss(bssid0, freq="2412")
  936. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  937. scan_freq="2412")
  938. params = ft_params2(ssid=ssid, passphrase=passphrase)
  939. hapd1 = hostapd.add_ap(apdev[1], params)
  940. bssid1 = hapd1.own_addr()
  941. dev[0].scan_for_bss(bssid1, freq="2412")
  942. with alloc_fail(hapd1, 1, "wpa_ft_pull_pmk_r1"):
  943. # This will fail due to not being able to send out PMK-R1 pull request
  944. dev[0].roam(bssid1)
  945. with fail_test(hapd1, 2, "os_get_random;wpa_ft_pull_pmk_r1"):
  946. # This will fail due to not being able to send out PMK-R1 pull request
  947. dev[0].roam(bssid1)
  948. with fail_test(hapd1, 2, "aes_siv_encrypt;wpa_ft_pull_pmk_r1"):
  949. # This will fail due to not being able to send out PMK-R1 pull request
  950. dev[0].roam(bssid1)
  951. def test_ap_ft_ap_oom3b(dev, apdev):
  952. """WPA2-PSK-FT and AP OOM 3b"""
  953. ssid = "test-ft"
  954. passphrase="12345678"
  955. params = ft_params1(ssid=ssid, passphrase=passphrase)
  956. hapd0 = hostapd.add_ap(apdev[0], params)
  957. bssid0 = hapd0.own_addr()
  958. dev[0].scan_for_bss(bssid0, freq="2412")
  959. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  960. scan_freq="2412")
  961. params = ft_params2(ssid=ssid, passphrase=passphrase)
  962. hapd1 = hostapd.add_ap(apdev[1], params)
  963. bssid1 = hapd1.own_addr()
  964. dev[0].scan_for_bss(bssid1, freq="2412")
  965. with fail_test(hapd1, 1, "os_get_random;wpa_ft_pull_pmk_r1"):
  966. # This will fail due to not being able to send out PMK-R1 pull request
  967. dev[0].roam(bssid1)
  968. def test_ap_ft_ap_oom4(dev, apdev):
  969. """WPA2-PSK-FT and AP OOM 4"""
  970. ssid = "test-ft"
  971. passphrase="12345678"
  972. params = ft_params1(ssid=ssid, passphrase=passphrase)
  973. hapd0 = hostapd.add_ap(apdev[0], params)
  974. bssid0 = hapd0.own_addr()
  975. dev[0].scan_for_bss(bssid0, freq="2412")
  976. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  977. scan_freq="2412")
  978. params = ft_params2(ssid=ssid, passphrase=passphrase)
  979. hapd1 = hostapd.add_ap(apdev[1], params)
  980. bssid1 = hapd1.own_addr()
  981. dev[0].scan_for_bss(bssid1, freq="2412")
  982. with alloc_fail(hapd1, 1, "wpa_ft_gtk_subelem"):
  983. dev[0].roam(bssid1)
  984. if dev[0].get_status_field('bssid') != bssid1:
  985. raise Exception("Did not roam to AP1")
  986. with fail_test(hapd0, 1, "wpa_auth_get_seqnum;wpa_ft_gtk_subelem"):
  987. dev[0].roam(bssid0)
  988. if dev[0].get_status_field('bssid') != bssid0:
  989. raise Exception("Did not roam to AP0")
  990. with fail_test(hapd0, 1, "aes_wrap;wpa_ft_gtk_subelem"):
  991. dev[0].roam(bssid1)
  992. if dev[0].get_status_field('bssid') != bssid1:
  993. raise Exception("Did not roam to AP1")
  994. def test_ap_ft_ap_oom5(dev, apdev):
  995. """WPA2-PSK-FT and AP OOM 5"""
  996. ssid = "test-ft"
  997. passphrase="12345678"
  998. params = ft_params1(ssid=ssid, passphrase=passphrase)
  999. hapd0 = hostapd.add_ap(apdev[0], params)
  1000. bssid0 = hapd0.own_addr()
  1001. dev[0].scan_for_bss(bssid0, freq="2412")
  1002. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1003. scan_freq="2412")
  1004. params = ft_params2(ssid=ssid, passphrase=passphrase)
  1005. hapd1 = hostapd.add_ap(apdev[1], params)
  1006. bssid1 = hapd1.own_addr()
  1007. dev[0].scan_for_bss(bssid1, freq="2412")
  1008. with alloc_fail(hapd1, 1, "=wpa_ft_process_auth_req"):
  1009. # This will fail to roam
  1010. dev[0].roam(bssid1)
  1011. with fail_test(hapd1, 1, "os_get_random;wpa_ft_process_auth_req"):
  1012. # This will fail to roam
  1013. dev[0].roam(bssid1)
  1014. with fail_test(hapd1, 1, "sha256_prf_bits;wpa_pmk_r1_to_ptk;wpa_ft_process_auth_req"):
  1015. # This will fail to roam
  1016. dev[0].roam(bssid1)
  1017. with fail_test(hapd1, 3, "wpa_pmk_r1_to_ptk;wpa_ft_process_auth_req"):
  1018. # This will fail to roam
  1019. dev[0].roam(bssid1)
  1020. with fail_test(hapd1, 1, "wpa_derive_pmk_r1_name;wpa_ft_process_auth_req"):
  1021. # This will fail to roam
  1022. dev[0].roam(bssid1)
  1023. def test_ap_ft_ap_oom6(dev, apdev):
  1024. """WPA2-PSK-FT and AP OOM 6"""
  1025. ssid = "test-ft"
  1026. passphrase="12345678"
  1027. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1028. hapd0 = hostapd.add_ap(apdev[0], params)
  1029. bssid0 = hapd0.own_addr()
  1030. dev[0].scan_for_bss(bssid0, freq="2412")
  1031. with fail_test(hapd0, 1, "wpa_derive_pmk_r0;wpa_auth_derive_ptk_ft"):
  1032. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1033. scan_freq="2412")
  1034. dev[0].request("REMOVE_NETWORK all")
  1035. dev[0].wait_disconnected()
  1036. with fail_test(hapd0, 1, "wpa_derive_pmk_r1;wpa_auth_derive_ptk_ft"):
  1037. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1038. scan_freq="2412")
  1039. dev[0].request("REMOVE_NETWORK all")
  1040. dev[0].wait_disconnected()
  1041. with fail_test(hapd0, 1, "wpa_pmk_r1_to_ptk;wpa_auth_derive_ptk_ft"):
  1042. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1043. scan_freq="2412")
  1044. def test_ap_ft_ap_oom7(dev, apdev):
  1045. """WPA2-PSK-FT and AP OOM 7"""
  1046. ssid = "test-ft"
  1047. passphrase="12345678"
  1048. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1049. params["ieee80211w"] = "2"
  1050. hapd0 = hostapd.add_ap(apdev[0], params)
  1051. bssid0 = hapd0.own_addr()
  1052. dev[0].scan_for_bss(bssid0, freq="2412")
  1053. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1054. ieee80211w="2", scan_freq="2412")
  1055. params = ft_params2(ssid=ssid, passphrase=passphrase)
  1056. params["ieee80211w"] = "2"
  1057. hapd1 = hostapd.add_ap(apdev[1], params)
  1058. bssid1 = hapd1.own_addr()
  1059. dev[0].scan_for_bss(bssid1, freq="2412")
  1060. with alloc_fail(hapd1, 1, "wpa_ft_igtk_subelem"):
  1061. # This will fail to roam
  1062. dev[0].roam(bssid1)
  1063. with fail_test(hapd1, 1, "aes_wrap;wpa_ft_igtk_subelem"):
  1064. # This will fail to roam
  1065. dev[0].roam(bssid1)
  1066. with alloc_fail(hapd1, 1, "=wpa_sm_write_assoc_resp_ies"):
  1067. # This will fail to roam
  1068. dev[0].roam(bssid1)
  1069. with fail_test(hapd1, 1, "wpa_ft_mic;wpa_sm_write_assoc_resp_ies"):
  1070. # This will fail to roam
  1071. dev[0].roam(bssid1)
  1072. def test_ap_ft_ap_oom8(dev, apdev):
  1073. """WPA2-PSK-FT and AP OOM 8"""
  1074. ssid = "test-ft"
  1075. passphrase="12345678"
  1076. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1077. params['ft_psk_generate_local'] = "1";
  1078. hapd0 = hostapd.add_ap(apdev[0], params)
  1079. bssid0 = hapd0.own_addr()
  1080. dev[0].scan_for_bss(bssid0, freq="2412")
  1081. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1082. scan_freq="2412")
  1083. params = ft_params2(ssid=ssid, passphrase=passphrase)
  1084. params['ft_psk_generate_local'] = "1";
  1085. hapd1 = hostapd.add_ap(apdev[1], params)
  1086. bssid1 = hapd1.own_addr()
  1087. dev[0].scan_for_bss(bssid1, freq="2412")
  1088. with fail_test(hapd1, 1, "wpa_derive_pmk_r0;wpa_ft_psk_pmk_r1"):
  1089. # This will fail to roam
  1090. dev[0].roam(bssid1)
  1091. with fail_test(hapd1, 1, "wpa_derive_pmk_r1;wpa_ft_psk_pmk_r1"):
  1092. # This will fail to roam
  1093. dev[0].roam(bssid1)
  1094. def test_ap_ft_ap_oom9(dev, apdev):
  1095. """WPA2-PSK-FT and AP OOM 9"""
  1096. ssid = "test-ft"
  1097. passphrase="12345678"
  1098. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1099. hapd0 = hostapd.add_ap(apdev[0], params)
  1100. bssid0 = hapd0.own_addr()
  1101. dev[0].scan_for_bss(bssid0, freq="2412")
  1102. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1103. scan_freq="2412")
  1104. params = ft_params2(ssid=ssid, passphrase=passphrase)
  1105. hapd1 = hostapd.add_ap(apdev[1], params)
  1106. bssid1 = hapd1.own_addr()
  1107. dev[0].scan_for_bss(bssid1, freq="2412")
  1108. with alloc_fail(hapd0, 1, "wpa_ft_action_rx"):
  1109. # This will fail to roam
  1110. if "OK" not in dev[0].request("FT_DS " + bssid1):
  1111. raise Exception("FT_DS failed")
  1112. wait_fail_trigger(hapd0, "GET_ALLOC_FAIL")
  1113. with alloc_fail(hapd1, 1, "wpa_ft_rrb_rx_request"):
  1114. # This will fail to roam
  1115. if "OK" not in dev[0].request("FT_DS " + bssid1):
  1116. raise Exception("FT_DS failed")
  1117. wait_fail_trigger(hapd1, "GET_ALLOC_FAIL")
  1118. with alloc_fail(hapd1, 1, "wpa_ft_send_rrb_auth_resp"):
  1119. # This will fail to roam
  1120. if "OK" not in dev[0].request("FT_DS " + bssid1):
  1121. raise Exception("FT_DS failed")
  1122. wait_fail_trigger(hapd1, "GET_ALLOC_FAIL")
  1123. def test_ap_ft_ap_oom10(dev, apdev):
  1124. """WPA2-PSK-FT and AP OOM 10"""
  1125. ssid = "test-ft"
  1126. passphrase="12345678"
  1127. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1128. hapd0 = hostapd.add_ap(apdev[0], params)
  1129. bssid0 = hapd0.own_addr()
  1130. dev[0].scan_for_bss(bssid0, freq="2412")
  1131. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1132. scan_freq="2412")
  1133. params = ft_params2(ssid=ssid, passphrase=passphrase)
  1134. hapd1 = hostapd.add_ap(apdev[1], params)
  1135. bssid1 = hapd1.own_addr()
  1136. dev[0].scan_for_bss(bssid1, freq="2412")
  1137. with fail_test(hapd0, 1, "aes_siv_decrypt;wpa_ft_rrb_rx_pull"):
  1138. # This will fail to roam
  1139. if "OK" not in dev[0].request("FT_DS " + bssid1):
  1140. raise Exception("FT_DS failed")
  1141. wait_fail_trigger(hapd0, "GET_FAIL")
  1142. with fail_test(hapd0, 1, "wpa_derive_pmk_r1;wpa_ft_rrb_rx_pull"):
  1143. # This will fail to roam
  1144. if "OK" not in dev[0].request("FT_DS " + bssid1):
  1145. raise Exception("FT_DS failed")
  1146. wait_fail_trigger(hapd0, "GET_FAIL")
  1147. with fail_test(hapd0, 1, "aes_siv_encrypt;wpa_ft_rrb_rx_pull"):
  1148. # This will fail to roam
  1149. if "OK" not in dev[0].request("FT_DS " + bssid1):
  1150. raise Exception("FT_DS failed")
  1151. wait_fail_trigger(hapd0, "GET_FAIL")
  1152. with fail_test(hapd1, 1, "aes_siv_decrypt;wpa_ft_rrb_rx_resp"):
  1153. # This will fail to roam
  1154. if "OK" not in dev[0].request("FT_DS " + bssid1):
  1155. raise Exception("FT_DS failed")
  1156. wait_fail_trigger(hapd1, "GET_FAIL")
  1157. def test_ap_ft_ap_oom11(dev, apdev):
  1158. """WPA2-PSK-FT and AP OOM 11"""
  1159. ssid = "test-ft"
  1160. passphrase="12345678"
  1161. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1162. hapd0 = hostapd.add_ap(apdev[0], params)
  1163. bssid0 = hapd0.own_addr()
  1164. dev[0].scan_for_bss(bssid0, freq="2412")
  1165. with fail_test(hapd0, 1, "wpa_derive_pmk_r1;wpa_ft_generate_pmk_r1"):
  1166. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1167. scan_freq="2412")
  1168. wait_fail_trigger(hapd0, "GET_FAIL")
  1169. dev[1].scan_for_bss(bssid0, freq="2412")
  1170. with fail_test(hapd0, 1, "aes_siv_encrypt;wpa_ft_generate_pmk_r1"):
  1171. dev[1].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1172. scan_freq="2412")
  1173. wait_fail_trigger(hapd0, "GET_FAIL")
  1174. def test_ap_ft_over_ds_proto_ap(dev, apdev):
  1175. """WPA2-PSK-FT AP over DS protocol testing for AP processing"""
  1176. ssid = "test-ft"
  1177. passphrase="12345678"
  1178. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1179. hapd0 = hostapd.add_ap(apdev[0], params)
  1180. bssid0 = hapd0.own_addr()
  1181. _bssid0 = bssid0.replace(':', '')
  1182. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1183. scan_freq="2412")
  1184. addr = dev[0].own_addr()
  1185. _addr = addr.replace(':', '')
  1186. params = ft_params2(ssid=ssid, passphrase=passphrase)
  1187. hapd1 = hostapd.add_ap(apdev[1], params)
  1188. bssid1 = hapd1.own_addr()
  1189. _bssid1 = bssid1.replace(':', '')
  1190. hapd0.set("ext_mgmt_frame_handling", "1")
  1191. hdr = "d0003a01" + _bssid0 + _addr + _bssid0 + "1000"
  1192. valid = "0601" + _addr + _bssid1
  1193. tests = [ "0601",
  1194. "0601" + _addr,
  1195. "0601" + _addr + _bssid0,
  1196. "0601" + _addr + "ffffffffffff",
  1197. "0601" + _bssid0 + _bssid0,
  1198. valid,
  1199. valid + "01",
  1200. valid + "3700",
  1201. valid + "3600",
  1202. valid + "3603ffffff",
  1203. valid + "3603a1b2ff",
  1204. valid + "3603a1b2ff" + "3700",
  1205. valid + "3603a1b2ff" + "37520000" + 16*"00" + 32*"00" + 32*"00",
  1206. valid + "3603a1b2ff" + "37520001" + 16*"00" + 32*"00" + 32*"00",
  1207. valid + "3603a1b2ff" + "37550000" + 16*"00" + 32*"00" + 32*"00" + "0301aa",
  1208. valid + "3603a1b2ff" + "37550000" + 16*"00" + 32*"00" + 32*"00" + "0301aa" + "3000",
  1209. valid + "3603a1b2ff" + "37550000" + 16*"00" + 32*"00" + 32*"00" + "0301aa" + "30260100000fac040100000fac040100000facff00000100a225368fe0983b5828a37a0acb37f253",
  1210. valid + "3603a1b2ff" + "37550000" + 16*"00" + 32*"00" + 32*"00" + "0301aa" + "30260100000fac040100000fac030100000fac0400000100a225368fe0983b5828a37a0acb37f253",
  1211. valid + "3603a1b2ff" + "37550000" + 16*"00" + 32*"00" + 32*"00" + "0301aa" + "30260100000fac040100000fac040100000fac0400000100a225368fe0983b5828a37a0acb37f253",
  1212. valid + "0001" ]
  1213. for t in tests:
  1214. hapd0.dump_monitor()
  1215. if "OK" not in hapd0.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + t):
  1216. raise Exception("MGMT_RX_PROCESS failed")
  1217. hapd0.set("ext_mgmt_frame_handling", "0")
  1218. def test_ap_ft_over_ds_proto(dev, apdev):
  1219. """WPA2-PSK-FT AP over DS protocol testing"""
  1220. ssid = "test-ft"
  1221. passphrase="12345678"
  1222. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1223. hapd0 = hostapd.add_ap(apdev[0], params)
  1224. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1225. scan_freq="2412")
  1226. # FT Action Response while no FT-over-DS in progress
  1227. msg = {}
  1228. msg['fc'] = 13 << 4
  1229. msg['da'] = dev[0].own_addr()
  1230. msg['sa'] = apdev[0]['bssid']
  1231. msg['bssid'] = apdev[0]['bssid']
  1232. msg['payload'] = binascii.unhexlify("06020200000000000200000004000000")
  1233. hapd0.mgmt_tx(msg)
  1234. params = ft_params2(ssid=ssid, passphrase=passphrase)
  1235. hapd1 = hostapd.add_ap(apdev[1], params)
  1236. dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
  1237. hapd0.set("ext_mgmt_frame_handling", "1")
  1238. hapd0.dump_monitor()
  1239. dev[0].request("FT_DS " + apdev[1]['bssid'])
  1240. for i in range(0, 10):
  1241. req = hapd0.mgmt_rx()
  1242. if req is None:
  1243. raise Exception("MGMT RX wait timed out")
  1244. if req['subtype'] == 13:
  1245. break
  1246. req = None
  1247. if not req:
  1248. raise Exception("FT Action frame not received")
  1249. # FT Action Response for unexpected Target AP
  1250. msg['payload'] = binascii.unhexlify("0602020000000000" + "f20000000400" + "0000")
  1251. hapd0.mgmt_tx(msg)
  1252. # FT Action Response without MDIE
  1253. msg['payload'] = binascii.unhexlify("0602020000000000" + "020000000400" + "0000")
  1254. hapd0.mgmt_tx(msg)
  1255. # FT Action Response without FTIE
  1256. msg['payload'] = binascii.unhexlify("0602020000000000" + "020000000400" + "0000" + "3603a1b201")
  1257. hapd0.mgmt_tx(msg)
  1258. # FT Action Response with FTIE SNonce mismatch
  1259. msg['payload'] = binascii.unhexlify("0602020000000000" + "020000000400" + "0000" + "3603a1b201" + "3766000000000000000000000000000000000000c4e67ac1999bebd00ff4ae4d5dcaf87896bb060b469f7c78d49623fb395c3455ffffff6b693fe6f8d8c5dfac0a22344750775bd09437f98b238c9f87b97f790c0106000102030406030a6e6173312e77312e6669")
  1260. hapd0.mgmt_tx(msg)
  1261. @remote_compatible
  1262. def test_ap_ft_rrb(dev, apdev):
  1263. """WPA2-PSK-FT RRB protocol testing"""
  1264. ssid = "test-ft"
  1265. passphrase="12345678"
  1266. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1267. hapd0 = hostapd.add_ap(apdev[0], params)
  1268. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1269. scan_freq="2412")
  1270. _dst_ll = binascii.unhexlify(apdev[0]['bssid'].replace(':',''))
  1271. _src_ll = binascii.unhexlify(dev[0].own_addr().replace(':',''))
  1272. proto = '\x89\x0d'
  1273. ehdr = _dst_ll + _src_ll + proto
  1274. # Too short RRB frame
  1275. pkt = ehdr + '\x01'
  1276. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1277. raise Exception("DATA_TEST_FRAME failed")
  1278. # RRB discarded frame wikth unrecognized type
  1279. pkt = ehdr + '\x02' + '\x02' + '\x01\x00' + _src_ll
  1280. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1281. raise Exception("DATA_TEST_FRAME failed")
  1282. # RRB frame too short for action frame
  1283. pkt = ehdr + '\x01' + '\x02' + '\x01\x00' + _src_ll
  1284. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1285. raise Exception("DATA_TEST_FRAME failed")
  1286. # Too short RRB frame (not enough room for Action Frame body)
  1287. pkt = ehdr + '\x01' + '\x02' + '\x00\x00' + _src_ll
  1288. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1289. raise Exception("DATA_TEST_FRAME failed")
  1290. # Unexpected Action frame category
  1291. pkt = ehdr + '\x01' + '\x02' + '\x0e\x00' + _src_ll + '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
  1292. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1293. raise Exception("DATA_TEST_FRAME failed")
  1294. # Unexpected Action in RRB Request
  1295. pkt = ehdr + '\x01' + '\x00' + '\x0e\x00' + _src_ll + '\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
  1296. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1297. raise Exception("DATA_TEST_FRAME failed")
  1298. # Target AP address in RRB Request does not match with own address
  1299. pkt = ehdr + '\x01' + '\x00' + '\x0e\x00' + _src_ll + '\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
  1300. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1301. raise Exception("DATA_TEST_FRAME failed")
  1302. # Not enough room for status code in RRB Response
  1303. pkt = ehdr + '\x01' + '\x01' + '\x0e\x00' + _src_ll + '\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
  1304. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1305. raise Exception("DATA_TEST_FRAME failed")
  1306. # RRB discarded frame with unknown packet_type
  1307. pkt = ehdr + '\x01' + '\x02' + '\x0e\x00' + _src_ll + '\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
  1308. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1309. raise Exception("DATA_TEST_FRAME failed")
  1310. # RRB Response with non-zero status code; no STA match
  1311. pkt = ehdr + '\x01' + '\x01' + '\x10\x00' + _src_ll + '\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + '\xff\xff'
  1312. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1313. raise Exception("DATA_TEST_FRAME failed")
  1314. # RRB Response with zero status code and extra data; STA match
  1315. pkt = ehdr + '\x01' + '\x01' + '\x11\x00' + _src_ll + '\x06\x01' + _src_ll + '\x00\x00\x00\x00\x00\x00' + '\x00\x00' + '\x00'
  1316. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1317. raise Exception("DATA_TEST_FRAME failed")
  1318. # Too short PMK-R1 pull
  1319. pkt = ehdr + '\x01' + '\xc8' + '\x0e\x00' + _src_ll + '\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
  1320. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1321. raise Exception("DATA_TEST_FRAME failed")
  1322. # Too short PMK-R1 resp
  1323. pkt = ehdr + '\x01' + '\xc9' + '\x0e\x00' + _src_ll + '\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
  1324. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1325. raise Exception("DATA_TEST_FRAME failed")
  1326. # Too short PMK-R1 push
  1327. pkt = ehdr + '\x01' + '\xca' + '\x0e\x00' + _src_ll + '\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
  1328. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1329. raise Exception("DATA_TEST_FRAME failed")
  1330. # No matching R0KH address found for PMK-R0 pull response
  1331. pkt = ehdr + '\x01' + '\xc9' + '\x5a\x00' + _src_ll + '\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + 76*'\00'
  1332. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1333. raise Exception("DATA_TEST_FRAME failed")
  1334. @remote_compatible
  1335. def test_rsn_ie_proto_ft_psk_sta(dev, apdev):
  1336. """RSN element protocol testing for FT-PSK + PMF cases on STA side"""
  1337. bssid = apdev[0]['bssid']
  1338. ssid = "test-ft"
  1339. passphrase="12345678"
  1340. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1341. params["ieee80211w"] = "1"
  1342. # This is the RSN element used normally by hostapd
  1343. params['own_ie_override'] = '30140100000fac040100000fac040100000fac048c00' + '3603a1b201'
  1344. hapd = hostapd.add_ap(apdev[0], params)
  1345. id = dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1346. ieee80211w="1", scan_freq="2412",
  1347. pairwise="CCMP", group="CCMP")
  1348. tests = [ ('PMKIDCount field included',
  1349. '30160100000fac040100000fac040100000fac048c000000' + '3603a1b201'),
  1350. ('Extra IE before RSNE',
  1351. 'dd0400000000' + '30140100000fac040100000fac040100000fac048c00' + '3603a1b201'),
  1352. ('PMKIDCount and Group Management Cipher suite fields included',
  1353. '301a0100000fac040100000fac040100000fac048c000000000fac06' + '3603a1b201'),
  1354. ('Extra octet after defined fields (future extensibility)',
  1355. '301b0100000fac040100000fac040100000fac048c000000000fac0600' + '3603a1b201'),
  1356. ('No RSN Capabilities field (PMF disabled in practice)',
  1357. '30120100000fac040100000fac040100000fac04' + '3603a1b201') ]
  1358. for txt,ie in tests:
  1359. dev[0].request("DISCONNECT")
  1360. dev[0].wait_disconnected()
  1361. logger.info(txt)
  1362. hapd.disable()
  1363. hapd.set('own_ie_override', ie)
  1364. hapd.enable()
  1365. dev[0].request("BSS_FLUSH 0")
  1366. dev[0].scan_for_bss(bssid, 2412, force_scan=True, only_new=True)
  1367. dev[0].select_network(id, freq=2412)
  1368. dev[0].wait_connected()
  1369. dev[0].request("DISCONNECT")
  1370. dev[0].wait_disconnected()
  1371. logger.info('Invalid RSNE causing internal hostapd error')
  1372. hapd.disable()
  1373. hapd.set('own_ie_override', '30130100000fac040100000fac040100000fac048c' + '3603a1b201')
  1374. hapd.enable()
  1375. dev[0].request("BSS_FLUSH 0")
  1376. dev[0].scan_for_bss(bssid, 2412, force_scan=True, only_new=True)
  1377. dev[0].select_network(id, freq=2412)
  1378. # hostapd fails to generate EAPOL-Key msg 3/4, so this connection cannot
  1379. # complete.
  1380. ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1)
  1381. if ev is not None:
  1382. raise Exception("Unexpected connection")
  1383. dev[0].request("DISCONNECT")
  1384. logger.info('Unexpected PMKID causing internal hostapd error')
  1385. hapd.disable()
  1386. hapd.set('own_ie_override', '30260100000fac040100000fac040100000fac048c000100ffffffffffffffffffffffffffffffff' + '3603a1b201')
  1387. hapd.enable()
  1388. dev[0].request("BSS_FLUSH 0")
  1389. dev[0].scan_for_bss(bssid, 2412, force_scan=True, only_new=True)
  1390. dev[0].select_network(id, freq=2412)
  1391. # hostapd fails to generate EAPOL-Key msg 3/4, so this connection cannot
  1392. # complete.
  1393. ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1)
  1394. if ev is not None:
  1395. raise Exception("Unexpected connection")
  1396. dev[0].request("DISCONNECT")
  1397. def test_ap_ft_ptk_rekey(dev, apdev):
  1398. """WPA2-PSK-FT PTK rekeying triggered by station after roam"""
  1399. ssid = "test-ft"
  1400. passphrase="12345678"
  1401. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1402. hapd0 = hostapd.add_ap(apdev[0], params)
  1403. params = ft_params2(ssid=ssid, passphrase=passphrase)
  1404. hapd1 = hostapd.add_ap(apdev[1], params)
  1405. run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, ptk_rekey="1")
  1406. ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED",
  1407. "WPA: Key negotiation completed"], timeout=5)
  1408. if ev is None:
  1409. raise Exception("No event received after roam")
  1410. if "CTRL-EVENT-DISCONNECTED" in ev:
  1411. raise Exception("Unexpected disconnection after roam")
  1412. if dev[0].get_status_field('bssid') == apdev[0]['bssid']:
  1413. hapd = hapd0
  1414. else:
  1415. hapd = hapd1
  1416. hwsim_utils.test_connectivity(dev[0], hapd)
  1417. def test_ap_ft_ptk_rekey_ap(dev, apdev):
  1418. """WPA2-PSK-FT PTK rekeying triggered by AP after roam"""
  1419. ssid = "test-ft"
  1420. passphrase="12345678"
  1421. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1422. params['wpa_ptk_rekey'] = '2'
  1423. hapd0 = hostapd.add_ap(apdev[0], params)
  1424. params = ft_params2(ssid=ssid, passphrase=passphrase)
  1425. params['wpa_ptk_rekey'] = '2'
  1426. hapd1 = hostapd.add_ap(apdev[1], params)
  1427. run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase)
  1428. ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED",
  1429. "WPA: Key negotiation completed"], timeout=5)
  1430. if ev is None:
  1431. raise Exception("No event received after roam")
  1432. if "CTRL-EVENT-DISCONNECTED" in ev:
  1433. raise Exception("Unexpected disconnection after roam")
  1434. if dev[0].get_status_field('bssid') == apdev[0]['bssid']:
  1435. hapd = hapd0
  1436. else:
  1437. hapd = hapd1
  1438. hwsim_utils.test_connectivity(dev[0], hapd)
  1439. def test_ap_ft_internal_rrb_check(dev, apdev):
  1440. """RRB internal delivery only to WPA enabled BSS"""
  1441. ssid = "test-ft"
  1442. passphrase="12345678"
  1443. radius = hostapd.radius_params()
  1444. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1445. params['wpa_key_mgmt'] = "FT-EAP"
  1446. params["ieee8021x"] = "1"
  1447. params = dict(radius.items() + params.items())
  1448. hapd = hostapd.add_ap(apdev[0], params)
  1449. key_mgmt = hapd.get_config()['key_mgmt']
  1450. if key_mgmt.split(' ')[0] != "FT-EAP":
  1451. raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
  1452. hapd1 = hostapd.add_ap(apdev[1], { "ssid" : ssid })
  1453. # Connect to WPA enabled AP
  1454. dev[0].connect(ssid, key_mgmt="FT-EAP", proto="WPA2", ieee80211w="1",
  1455. eap="GPSK", identity="gpsk user",
  1456. password="abcdefghijklmnop0123456789abcdef",
  1457. scan_freq="2412")
  1458. # Try over_ds roaming to non-WPA-enabled AP.
  1459. # If hostapd does not check hapd->wpa_auth internally, it will crash now.
  1460. dev[0].roam_over_ds(apdev[1]['bssid'], fail_test=True)
  1461. def test_ap_ft_extra_ie(dev, apdev):
  1462. """WPA2-PSK-FT AP with WPA2-PSK enabled and unexpected MDE"""
  1463. ssid = "test-ft"
  1464. passphrase="12345678"
  1465. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1466. params["wpa_key_mgmt"] = "WPA-PSK FT-PSK"
  1467. hapd0 = hostapd.add_ap(apdev[0], params)
  1468. dev[1].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1469. scan_freq="2412")
  1470. dev[2].connect(ssid, psk=passphrase, key_mgmt="WPA-PSK", proto="WPA2",
  1471. scan_freq="2412")
  1472. try:
  1473. # Add Mobility Domain element to test AP validation code.
  1474. dev[0].request("VENDOR_ELEM_ADD 13 3603a1b201")
  1475. dev[0].connect(ssid, psk=passphrase, key_mgmt="WPA-PSK", proto="WPA2",
  1476. scan_freq="2412", wait_connect=False)
  1477. ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
  1478. "CTRL-EVENT-ASSOC-REJECT"], timeout=10)
  1479. if ev is None:
  1480. raise Exception("No connection result")
  1481. if "CTRL-EVENT-CONNECTED" in ev:
  1482. raise Exception("Non-FT association accepted with MDE")
  1483. if "status_code=43" not in ev:
  1484. raise Exception("Unexpected status code: " + ev)
  1485. dev[0].request("DISCONNECT")
  1486. finally:
  1487. dev[0].request("VENDOR_ELEM_REMOVE 13 *")
  1488. def test_ap_ft_ric(dev, apdev):
  1489. """WPA2-PSK-FT AP and RIC"""
  1490. ssid = "test-ft"
  1491. passphrase="12345678"
  1492. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1493. hapd0 = hostapd.add_ap(apdev[0], params)
  1494. params = ft_params2(ssid=ssid, passphrase=passphrase)
  1495. hapd1 = hostapd.add_ap(apdev[1], params)
  1496. dev[0].set("ric_ies", "")
  1497. dev[0].set("ric_ies", '""')
  1498. if "FAIL" not in dev[0].request("SET ric_ies q"):
  1499. raise Exception("Invalid ric_ies value accepted")
  1500. tests = [ "3900",
  1501. "3900ff04eeeeeeee",
  1502. "390400000000",
  1503. "390400000000" + "390400000000",
  1504. "390400000000" + "dd050050f20202",
  1505. "390400000000" + "dd3d0050f2020201" + 55*"00",
  1506. "390400000000" + "dd3d0050f2020201aa300010270000000000000000000000000000000000000000000000000000ffffff7f00000000000000000000000040420f00ffff0000",
  1507. "390401010000" + "dd3d0050f2020201aa3000dc050000000000000000000000000000000000000000000000000000dc050000000000000000000000000000808d5b0028230000" ]
  1508. for t in tests:
  1509. dev[0].set("ric_ies", t)
  1510. run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase,
  1511. test_connectivity=False)
  1512. dev[0].request("REMOVE_NETWORK all")
  1513. dev[0].wait_disconnected()
  1514. dev[0].dump_monitor()
  1515. def ie_hex(ies, id):
  1516. return binascii.hexlify(struct.pack('BB', id, len(ies[id])) + ies[id])
  1517. def test_ap_ft_reassoc_proto(dev, apdev):
  1518. """WPA2-PSK-FT AP Reassociation Request frame parsing"""
  1519. ssid = "test-ft"
  1520. passphrase="12345678"
  1521. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1522. hapd0 = hostapd.add_ap(apdev[0], params)
  1523. params = ft_params2(ssid=ssid, passphrase=passphrase)
  1524. hapd1 = hostapd.add_ap(apdev[1], params)
  1525. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1526. ieee80211w="1", scan_freq="2412")
  1527. if dev[0].get_status_field('bssid') == hapd0.own_addr():
  1528. hapd1ap = hapd0
  1529. hapd2ap = hapd1
  1530. else:
  1531. hapd1ap = hapd1
  1532. hapd2ap = hapd0
  1533. dev[0].scan_for_bss(hapd2ap.own_addr(), freq="2412")
  1534. hapd2ap.set("ext_mgmt_frame_handling", "1")
  1535. dev[0].request("ROAM " + hapd2ap.own_addr())
  1536. while True:
  1537. req = hapd2ap.mgmt_rx()
  1538. hapd2ap.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']))
  1539. if req['subtype'] == 11:
  1540. break
  1541. while True:
  1542. req = hapd2ap.mgmt_rx()
  1543. if req['subtype'] == 2:
  1544. break
  1545. hapd2ap.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']))
  1546. # IEEE 802.11 header + fixed fields before IEs
  1547. hdr = binascii.hexlify(req['frame'][0:34])
  1548. ies = parse_ie(binascii.hexlify(req['frame'][34:]))
  1549. # First elements: SSID, Supported Rates, Extended Supported Rates
  1550. ies1 = ie_hex(ies, 0) + ie_hex(ies, 1) + ie_hex(ies, 50)
  1551. rsne = ie_hex(ies, 48)
  1552. mde = ie_hex(ies, 54)
  1553. fte = ie_hex(ies, 55)
  1554. tests = [ ]
  1555. # RSN: Trying to use FT, but MDIE not included
  1556. tests += [ rsne ]
  1557. # RSN: Attempted to use unknown MDIE
  1558. tests += [ rsne + "3603000000" ]
  1559. # Invalid RSN pairwise cipher
  1560. tests += [ "30260100000fac040100000fac030100000fac040000010029208a42cd25c85aa571567dce10dae3" ]
  1561. # FT: No PMKID in RSNIE
  1562. tests += [ "30160100000fac040100000fac040100000fac0400000000" + ie_hex(ies, 54) ]
  1563. # FT: Invalid FTIE
  1564. tests += [ rsne + mde ]
  1565. # FT: RIC IE(s) in the frame, but not included in protected IE count
  1566. # FT: Failed to parse FT IEs
  1567. tests += [ rsne + mde + fte + "3900" ]
  1568. # FT: SNonce mismatch in FTIE
  1569. tests += [ rsne + mde + "37520000" + 16*"00" + 32*"00" + 32*"00" ]
  1570. # FT: ANonce mismatch in FTIE
  1571. tests += [ rsne + mde + fte[0:40] + 32*"00" + fte[104:] ]
  1572. # FT: No R0KH-ID subelem in FTIE
  1573. tests += [ rsne + mde + "3752" + fte[4:168] ]
  1574. # FT: R0KH-ID in FTIE did not match with the current R0KH-ID
  1575. tests += [ rsne + mde + "3755" + fte[4:168] + "0301ff" ]
  1576. # FT: No R1KH-ID subelem in FTIE
  1577. tests += [ rsne + mde + "375e" + fte[4:168] + "030a" + "nas1.w1.fi".encode("hex") ]
  1578. # FT: Unknown R1KH-ID used in ReassocReq
  1579. tests += [ rsne + mde + "3766" + fte[4:168] + "030a" + "nas1.w1.fi".encode("hex") + "0106000000000000" ]
  1580. # FT: PMKID in Reassoc Req did not match with the PMKR1Name derived from auth request
  1581. tests += [ rsne[:-32] + 16*"00" + mde + fte ]
  1582. # Invalid MIC in FTIE
  1583. tests += [ rsne + mde + fte[0:8] + 16*"00" + fte[40:] ]
  1584. for t in tests:
  1585. hapd2ap.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + ies1 + t)
  1586. def test_ap_ft_reassoc_local_fail(dev, apdev):
  1587. """WPA2-PSK-FT AP Reassociation Request frame and local failure"""
  1588. ssid = "test-ft"
  1589. passphrase="12345678"
  1590. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1591. hapd0 = hostapd.add_ap(apdev[0], params)
  1592. params = ft_params2(ssid=ssid, passphrase=passphrase)
  1593. hapd1 = hostapd.add_ap(apdev[1], params)
  1594. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1595. ieee80211w="1", scan_freq="2412")
  1596. if dev[0].get_status_field('bssid') == hapd0.own_addr():
  1597. hapd1ap = hapd0
  1598. hapd2ap = hapd1
  1599. else:
  1600. hapd1ap = hapd1
  1601. hapd2ap = hapd0
  1602. dev[0].scan_for_bss(hapd2ap.own_addr(), freq="2412")
  1603. # FT: Failed to calculate MIC
  1604. with fail_test(hapd2ap, 1, "wpa_ft_validate_reassoc"):
  1605. dev[0].request("ROAM " + hapd2ap.own_addr())
  1606. ev = dev[0].wait_event(["CTRL-EVENT-ASSOC-REJECT"], timeout=10)
  1607. dev[0].request("DISCONNECT")
  1608. if ev is None:
  1609. raise Exception("Association reject not seen")
  1610. def test_ap_ft_reassoc_replay(dev, apdev, params):
  1611. """WPA2-PSK-FT AP and replayed Reassociation Request frame"""
  1612. capfile = os.path.join(params['logdir'], "hwsim0.pcapng")
  1613. ssid = "test-ft"
  1614. passphrase="12345678"
  1615. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1616. hapd0 = hostapd.add_ap(apdev[0], params)
  1617. params = ft_params2(ssid=ssid, passphrase=passphrase)
  1618. hapd1 = hostapd.add_ap(apdev[1], params)
  1619. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1620. scan_freq="2412")
  1621. if dev[0].get_status_field('bssid') == hapd0.own_addr():
  1622. hapd1ap = hapd0
  1623. hapd2ap = hapd1
  1624. else:
  1625. hapd1ap = hapd1
  1626. hapd2ap = hapd0
  1627. dev[0].scan_for_bss(hapd2ap.own_addr(), freq="2412")
  1628. hapd2ap.set("ext_mgmt_frame_handling", "1")
  1629. dev[0].dump_monitor()
  1630. if "OK" not in dev[0].request("ROAM " + hapd2ap.own_addr()):
  1631. raise Exception("ROAM failed")
  1632. reassocreq = None
  1633. count = 0
  1634. while count < 100:
  1635. req = hapd2ap.mgmt_rx()
  1636. count += 1
  1637. hapd2ap.dump_monitor()
  1638. hapd2ap.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']))
  1639. if req['subtype'] == 2:
  1640. reassocreq = req
  1641. ev = hapd2ap.wait_event(["MGMT-TX-STATUS"], timeout=5)
  1642. if ev is None:
  1643. raise Exception("No TX status seen")
  1644. cmd = "MGMT_TX_STATUS_PROCESS %s" % (" ".join(ev.split(' ')[1:4]))
  1645. if "OK" not in hapd2ap.request(cmd):
  1646. raise Exception("MGMT_TX_STATUS_PROCESS failed")
  1647. break
  1648. hapd2ap.set("ext_mgmt_frame_handling", "0")
  1649. if reassocreq is None:
  1650. raise Exception("No Reassociation Request frame seen")
  1651. dev[0].wait_connected()
  1652. dev[0].dump_monitor()
  1653. hapd2ap.dump_monitor()
  1654. hwsim_utils.test_connectivity(dev[0], hapd2ap)
  1655. logger.info("Replay the last Reassociation Request frame")
  1656. hapd2ap.dump_monitor()
  1657. hapd2ap.set("ext_mgmt_frame_handling", "1")
  1658. hapd2ap.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']))
  1659. ev = hapd2ap.wait_event(["MGMT-TX-STATUS"], timeout=5)
  1660. if ev is None:
  1661. raise Exception("No TX status seen")
  1662. cmd = "MGMT_TX_STATUS_PROCESS %s" % (" ".join(ev.split(' ')[1:4]))
  1663. if "OK" not in hapd2ap.request(cmd):
  1664. raise Exception("MGMT_TX_STATUS_PROCESS failed")
  1665. hapd2ap.set("ext_mgmt_frame_handling", "0")
  1666. try:
  1667. hwsim_utils.test_connectivity(dev[0], hapd2ap)
  1668. ok = True
  1669. except:
  1670. ok = False
  1671. ap = hapd2ap.own_addr()
  1672. sta = dev[0].own_addr()
  1673. filt = "wlan.fc.type == 2 && " + \
  1674. "wlan.da == " + sta + " && " + \
  1675. "wlan.sa == " + ap
  1676. fields = [ "wlan.ccmp.extiv" ]
  1677. res = run_tshark(capfile, filt, fields)
  1678. vals = res.splitlines()
  1679. logger.info("CCMP PN: " + str(vals))
  1680. if len(vals) < 2:
  1681. raise Exception("Could not find all CCMP protected frames from capture")
  1682. if len(set(vals)) < len(vals):
  1683. raise Exception("Duplicate CCMP PN used")
  1684. if not ok:
  1685. raise Exception("The second hwsim connectivity test failed")