test_ap_ft.py 82 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055
  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], 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], 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. def test_ap_ft_eap_pull_wildcard(dev, apdev):
  512. """WPA2-EAP-FT AP (pull PMK) - wildcard R0KH/R1KH"""
  513. ssid = "test-ft"
  514. passphrase="12345678"
  515. radius = hostapd.radius_params()
  516. params = ft_params1(ssid=ssid, passphrase=passphrase, discovery=True)
  517. params['wpa_key_mgmt'] = "WPA-EAP FT-EAP"
  518. params["ieee8021x"] = "1"
  519. params["pmk_r1_push"] = "0"
  520. params["r0kh"] = "ff:ff:ff:ff:ff:ff * 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"
  521. params["r1kh"] = "00:00:00:00:00:00 00:00:00:00:00:00 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"
  522. params["ft_psk_generate_local"] = "1"
  523. params["eap_server"] = "0"
  524. params = dict(radius.items() + params.items())
  525. hapd = hostapd.add_ap(apdev[0], params)
  526. params = ft_params2(ssid=ssid, passphrase=passphrase, discovery=True)
  527. params['wpa_key_mgmt'] = "WPA-EAP FT-EAP"
  528. params["ieee8021x"] = "1"
  529. params["pmk_r1_push"] = "0"
  530. params["r0kh"] = "ff:ff:ff:ff:ff:ff * 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"
  531. params["r1kh"] = "00:00:00:00:00:00 00:00:00:00:00:00 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"
  532. params["ft_psk_generate_local"] = "1"
  533. params["eap_server"] = "0"
  534. params = dict(radius.items() + params.items())
  535. hapd1 = hostapd.add_ap(apdev[1], params)
  536. run_roams(dev[0], apdev, hapd, hapd1, ssid, passphrase, eap=True)
  537. @remote_compatible
  538. def test_ap_ft_mismatching_rrb_key_push(dev, apdev):
  539. """WPA2-PSK-FT AP over DS with mismatching RRB key (push)"""
  540. ssid = "test-ft"
  541. passphrase="12345678"
  542. params = ft_params1(ssid=ssid, passphrase=passphrase)
  543. params["ieee80211w"] = "2"
  544. hapd0 = hostapd.add_ap(apdev[0], params)
  545. params = ft_params2_incorrect_rrb_key(ssid=ssid, passphrase=passphrase)
  546. params["ieee80211w"] = "2"
  547. hapd1 = hostapd.add_ap(apdev[1], params)
  548. run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
  549. fail_test=True)
  550. @remote_compatible
  551. def test_ap_ft_mismatching_rrb_key_pull(dev, apdev):
  552. """WPA2-PSK-FT AP over DS with mismatching RRB key (pull)"""
  553. ssid = "test-ft"
  554. passphrase="12345678"
  555. params = ft_params1(ssid=ssid, passphrase=passphrase)
  556. params["pmk_r1_push"] = "0"
  557. hapd0 = hostapd.add_ap(apdev[0], params)
  558. params = ft_params2_incorrect_rrb_key(ssid=ssid, passphrase=passphrase)
  559. params["pmk_r1_push"] = "0"
  560. hapd1 = hostapd.add_ap(apdev[1], params)
  561. run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
  562. fail_test=True)
  563. @remote_compatible
  564. def test_ap_ft_mismatching_r0kh_id_pull(dev, apdev):
  565. """WPA2-PSK-FT AP over DS with mismatching R0KH-ID (pull)"""
  566. ssid = "test-ft"
  567. passphrase="12345678"
  568. params = ft_params1(ssid=ssid, passphrase=passphrase)
  569. params["pmk_r1_push"] = "0"
  570. params["nas_identifier"] = "nas0.w1.fi"
  571. hostapd.add_ap(apdev[0], params)
  572. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  573. scan_freq="2412")
  574. params = ft_params2(ssid=ssid, passphrase=passphrase)
  575. params["pmk_r1_push"] = "0"
  576. hostapd.add_ap(apdev[1], params)
  577. dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
  578. dev[0].roam_over_ds(apdev[1]['bssid'], fail_test=True)
  579. @remote_compatible
  580. def test_ap_ft_mismatching_rrb_r0kh_push(dev, apdev):
  581. """WPA2-PSK-FT AP over DS with mismatching R0KH key (push)"""
  582. ssid = "test-ft"
  583. passphrase="12345678"
  584. params = ft_params1(ssid=ssid, passphrase=passphrase)
  585. params["ieee80211w"] = "2"
  586. hapd0 = hostapd.add_ap(apdev[0], params)
  587. params = ft_params2_r0kh_mismatch(ssid=ssid, passphrase=passphrase)
  588. params["ieee80211w"] = "2"
  589. hapd1 = hostapd.add_ap(apdev[1], params)
  590. run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
  591. fail_test=True)
  592. @remote_compatible
  593. def test_ap_ft_mismatching_rrb_r0kh_pull(dev, apdev):
  594. """WPA2-PSK-FT AP over DS with mismatching R0KH key (pull)"""
  595. ssid = "test-ft"
  596. passphrase="12345678"
  597. params = ft_params1_r0kh_mismatch(ssid=ssid, passphrase=passphrase)
  598. params["pmk_r1_push"] = "0"
  599. hapd0 = hostapd.add_ap(apdev[0], params)
  600. params = ft_params2(ssid=ssid, passphrase=passphrase)
  601. params["pmk_r1_push"] = "0"
  602. hapd1 = hostapd.add_ap(apdev[1], params)
  603. run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
  604. fail_test=True)
  605. def test_ap_ft_mismatching_rrb_key_push_eap(dev, apdev):
  606. """WPA2-EAP-FT AP over DS with mismatching RRB key (push)"""
  607. ssid = "test-ft"
  608. passphrase="12345678"
  609. radius = hostapd.radius_params()
  610. params = ft_params1(ssid=ssid, passphrase=passphrase)
  611. params["ieee80211w"] = "2";
  612. params['wpa_key_mgmt'] = "FT-EAP"
  613. params["ieee8021x"] = "1"
  614. params = dict(radius.items() + params.items())
  615. hapd0 = hostapd.add_ap(apdev[0], params)
  616. params = ft_params2_incorrect_rrb_key(ssid=ssid, passphrase=passphrase)
  617. params["ieee80211w"] = "2";
  618. params['wpa_key_mgmt'] = "FT-EAP"
  619. params["ieee8021x"] = "1"
  620. params = dict(radius.items() + params.items())
  621. hapd1 = hostapd.add_ap(apdev[1], params)
  622. run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
  623. fail_test=True, eap=True)
  624. def test_ap_ft_mismatching_rrb_key_pull_eap(dev, apdev):
  625. """WPA2-EAP-FT AP over DS with mismatching RRB key (pull)"""
  626. ssid = "test-ft"
  627. passphrase="12345678"
  628. radius = hostapd.radius_params()
  629. params = ft_params1(ssid=ssid, passphrase=passphrase)
  630. params["pmk_r1_push"] = "0"
  631. params['wpa_key_mgmt'] = "FT-EAP"
  632. params["ieee8021x"] = "1"
  633. params = dict(radius.items() + params.items())
  634. hapd0 = hostapd.add_ap(apdev[0], params)
  635. params = ft_params2_incorrect_rrb_key(ssid=ssid, passphrase=passphrase)
  636. params["pmk_r1_push"] = "0"
  637. params['wpa_key_mgmt'] = "FT-EAP"
  638. params["ieee8021x"] = "1"
  639. params = dict(radius.items() + params.items())
  640. hapd1 = hostapd.add_ap(apdev[1], params)
  641. run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
  642. fail_test=True, eap=True)
  643. def test_ap_ft_mismatching_r0kh_id_pull_eap(dev, apdev):
  644. """WPA2-EAP-FT AP over DS with mismatching R0KH-ID (pull)"""
  645. ssid = "test-ft"
  646. passphrase="12345678"
  647. radius = hostapd.radius_params()
  648. params = ft_params1(ssid=ssid, passphrase=passphrase)
  649. params["pmk_r1_push"] = "0"
  650. params["nas_identifier"] = "nas0.w1.fi"
  651. params['wpa_key_mgmt'] = "FT-EAP"
  652. params["ieee8021x"] = "1"
  653. params = dict(radius.items() + params.items())
  654. hostapd.add_ap(apdev[0], params)
  655. dev[0].connect(ssid, key_mgmt="FT-EAP", proto="WPA2", ieee80211w="1",
  656. eap="GPSK", identity="gpsk user",
  657. password="abcdefghijklmnop0123456789abcdef",
  658. scan_freq="2412")
  659. params = ft_params2(ssid=ssid, passphrase=passphrase)
  660. params["pmk_r1_push"] = "0"
  661. params['wpa_key_mgmt'] = "FT-EAP"
  662. params["ieee8021x"] = "1"
  663. params = dict(radius.items() + params.items())
  664. hostapd.add_ap(apdev[1], params)
  665. dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
  666. dev[0].roam_over_ds(apdev[1]['bssid'], fail_test=True)
  667. def test_ap_ft_mismatching_rrb_r0kh_push_eap(dev, apdev):
  668. """WPA2-EAP-FT AP over DS with mismatching R0KH key (push)"""
  669. ssid = "test-ft"
  670. passphrase="12345678"
  671. radius = hostapd.radius_params()
  672. params = ft_params1(ssid=ssid, passphrase=passphrase)
  673. params["ieee80211w"] = "2";
  674. params['wpa_key_mgmt'] = "FT-EAP"
  675. params["ieee8021x"] = "1"
  676. params = dict(radius.items() + params.items())
  677. hapd0 = hostapd.add_ap(apdev[0], params)
  678. params = ft_params2_r0kh_mismatch(ssid=ssid, passphrase=passphrase)
  679. params["ieee80211w"] = "2";
  680. params['wpa_key_mgmt'] = "FT-EAP"
  681. params["ieee8021x"] = "1"
  682. params = dict(radius.items() + params.items())
  683. hapd1 = hostapd.add_ap(apdev[1], params)
  684. run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
  685. fail_test=True, eap=True)
  686. def test_ap_ft_mismatching_rrb_r0kh_pull_eap(dev, apdev):
  687. """WPA2-EAP-FT AP over DS with mismatching R0KH key (pull)"""
  688. ssid = "test-ft"
  689. passphrase="12345678"
  690. radius = hostapd.radius_params()
  691. params = ft_params1_r0kh_mismatch(ssid=ssid, passphrase=passphrase)
  692. params["pmk_r1_push"] = "0"
  693. params['wpa_key_mgmt'] = "FT-EAP"
  694. params["ieee8021x"] = "1"
  695. params = dict(radius.items() + params.items())
  696. hapd0 = hostapd.add_ap(apdev[0], params)
  697. params = ft_params2(ssid=ssid, passphrase=passphrase)
  698. params["pmk_r1_push"] = "0"
  699. params['wpa_key_mgmt'] = "FT-EAP"
  700. params["ieee8021x"] = "1"
  701. params = dict(radius.items() + params.items())
  702. hapd1 = hostapd.add_ap(apdev[1], params)
  703. run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
  704. fail_test=True, eap=True)
  705. def test_ap_ft_gtk_rekey(dev, apdev):
  706. """WPA2-PSK-FT AP and GTK rekey"""
  707. ssid = "test-ft"
  708. passphrase="12345678"
  709. params = ft_params1(ssid=ssid, passphrase=passphrase)
  710. params['wpa_group_rekey'] = '1'
  711. hapd = hostapd.add_ap(apdev[0], params)
  712. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  713. ieee80211w="1", scan_freq="2412")
  714. ev = dev[0].wait_event(["WPA: Group rekeying completed"], timeout=2)
  715. if ev is None:
  716. raise Exception("GTK rekey timed out after initial association")
  717. hwsim_utils.test_connectivity(dev[0], hapd)
  718. params = ft_params2(ssid=ssid, passphrase=passphrase)
  719. params['wpa_group_rekey'] = '1'
  720. hapd1 = hostapd.add_ap(apdev[1], params)
  721. dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
  722. dev[0].roam(apdev[1]['bssid'])
  723. if dev[0].get_status_field('bssid') != apdev[1]['bssid']:
  724. raise Exception("Did not connect to correct AP")
  725. hwsim_utils.test_connectivity(dev[0], hapd1)
  726. ev = dev[0].wait_event(["WPA: Group rekeying completed"], timeout=2)
  727. if ev is None:
  728. raise Exception("GTK rekey timed out after FT protocol")
  729. hwsim_utils.test_connectivity(dev[0], hapd1)
  730. def test_ft_psk_key_lifetime_in_memory(dev, apdev, params):
  731. """WPA2-PSK-FT and key lifetime in memory"""
  732. ssid = "test-ft"
  733. passphrase="04c2726b4b8d5f1b4db9c07aa4d9e9d8f765cb5d25ec817e6cc4fcdd5255db0"
  734. psk = '93c90846ff67af9037ed83fb72b63dbeddaa81d47f926c20909b5886f1d9358d'
  735. pmk = binascii.unhexlify(psk)
  736. p = ft_params1(ssid=ssid, passphrase=passphrase)
  737. hapd0 = hostapd.add_ap(apdev[0], p)
  738. p = ft_params2(ssid=ssid, passphrase=passphrase)
  739. hapd1 = hostapd.add_ap(apdev[1], p)
  740. pid = find_wpas_process(dev[0])
  741. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  742. scan_freq="2412")
  743. # The decrypted copy of GTK is freed only after the CTRL-EVENT-CONNECTED
  744. # event has been delivered, so verify that wpa_supplicant has returned to
  745. # eloop before reading process memory.
  746. time.sleep(1)
  747. dev[0].ping()
  748. buf = read_process_memory(pid, pmk)
  749. dev[0].request("DISCONNECT")
  750. dev[0].wait_disconnected()
  751. dev[0].relog()
  752. pmkr0 = None
  753. pmkr1 = None
  754. ptk = None
  755. gtk = None
  756. with open(os.path.join(params['logdir'], 'log0'), 'r') as f:
  757. for l in f.readlines():
  758. if "FT: PMK-R0 - hexdump" in l:
  759. val = l.strip().split(':')[3].replace(' ', '')
  760. pmkr0 = binascii.unhexlify(val)
  761. if "FT: PMK-R1 - hexdump" in l:
  762. val = l.strip().split(':')[3].replace(' ', '')
  763. pmkr1 = binascii.unhexlify(val)
  764. if "FT: KCK - hexdump" in l:
  765. val = l.strip().split(':')[3].replace(' ', '')
  766. kck = binascii.unhexlify(val)
  767. if "FT: KEK - hexdump" in l:
  768. val = l.strip().split(':')[3].replace(' ', '')
  769. kek = binascii.unhexlify(val)
  770. if "FT: TK - hexdump" in l:
  771. val = l.strip().split(':')[3].replace(' ', '')
  772. tk = binascii.unhexlify(val)
  773. if "WPA: Group Key - hexdump" in l:
  774. val = l.strip().split(':')[3].replace(' ', '')
  775. gtk = binascii.unhexlify(val)
  776. if not pmkr0 or not pmkr1 or not kck or not kek or not tk or not gtk:
  777. raise Exception("Could not find keys from debug log")
  778. if len(gtk) != 16:
  779. raise Exception("Unexpected GTK length")
  780. logger.info("Checking keys in memory while associated")
  781. get_key_locations(buf, pmk, "PMK")
  782. get_key_locations(buf, pmkr0, "PMK-R0")
  783. get_key_locations(buf, pmkr1, "PMK-R1")
  784. if pmk not in buf:
  785. raise HwsimSkip("PMK not found while associated")
  786. if pmkr0 not in buf:
  787. raise HwsimSkip("PMK-R0 not found while associated")
  788. if pmkr1 not in buf:
  789. raise HwsimSkip("PMK-R1 not found while associated")
  790. if kck not in buf:
  791. raise Exception("KCK not found while associated")
  792. if kek not in buf:
  793. raise Exception("KEK not found while associated")
  794. #if tk in buf:
  795. # raise Exception("TK found from memory")
  796. logger.info("Checking keys in memory after disassociation")
  797. buf = read_process_memory(pid, pmk)
  798. get_key_locations(buf, pmk, "PMK")
  799. get_key_locations(buf, pmkr0, "PMK-R0")
  800. get_key_locations(buf, pmkr1, "PMK-R1")
  801. # Note: PMK/PSK is still present in network configuration
  802. fname = os.path.join(params['logdir'],
  803. 'ft_psk_key_lifetime_in_memory.memctx-')
  804. verify_not_present(buf, pmkr0, fname, "PMK-R0")
  805. verify_not_present(buf, pmkr1, fname, "PMK-R1")
  806. verify_not_present(buf, kck, fname, "KCK")
  807. verify_not_present(buf, kek, fname, "KEK")
  808. verify_not_present(buf, tk, fname, "TK")
  809. if gtk in buf:
  810. get_key_locations(buf, gtk, "GTK")
  811. verify_not_present(buf, gtk, fname, "GTK")
  812. dev[0].request("REMOVE_NETWORK all")
  813. logger.info("Checking keys in memory after network profile removal")
  814. buf = read_process_memory(pid, pmk)
  815. get_key_locations(buf, pmk, "PMK")
  816. get_key_locations(buf, pmkr0, "PMK-R0")
  817. get_key_locations(buf, pmkr1, "PMK-R1")
  818. verify_not_present(buf, pmk, fname, "PMK")
  819. verify_not_present(buf, pmkr0, fname, "PMK-R0")
  820. verify_not_present(buf, pmkr1, fname, "PMK-R1")
  821. verify_not_present(buf, kck, fname, "KCK")
  822. verify_not_present(buf, kek, fname, "KEK")
  823. verify_not_present(buf, tk, fname, "TK")
  824. verify_not_present(buf, gtk, fname, "GTK")
  825. @remote_compatible
  826. def test_ap_ft_invalid_resp(dev, apdev):
  827. """WPA2-PSK-FT AP and invalid response IEs"""
  828. ssid = "test-ft"
  829. passphrase="12345678"
  830. params = ft_params1(ssid=ssid, passphrase=passphrase)
  831. hapd0 = hostapd.add_ap(apdev[0], params)
  832. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  833. scan_freq="2412")
  834. params = ft_params2(ssid=ssid, passphrase=passphrase)
  835. hapd1 = hostapd.add_ap(apdev[1], params)
  836. tests = [
  837. # Various IEs for test coverage. The last one is FTIE with invalid
  838. # R1KH-ID subelement.
  839. "020002000000" + "3800" + "38051122334455" + "3754000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010100",
  840. # FTIE with invalid R0KH-ID subelement (len=0).
  841. "020002000000" + "3754000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010300",
  842. # FTIE with invalid R0KH-ID subelement (len=49).
  843. "020002000000" + "378500010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001033101020304050607080910111213141516171819202122232425262728293031323334353637383940414243444546474849",
  844. # Invalid RSNE.
  845. "020002000000" + "3000",
  846. # Required IEs missing from protected IE count.
  847. "020002000000" + "3603a1b201" + "375200010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001" + "3900",
  848. # RIC missing from protected IE count.
  849. "020002000000" + "3603a1b201" + "375200020203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001" + "3900",
  850. # Protected IE missing.
  851. "020002000000" + "3603a1b201" + "375200ff0203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001" + "3900" + "0000" ]
  852. for t in tests:
  853. dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
  854. hapd1.set("ext_mgmt_frame_handling", "1")
  855. hapd1.dump_monitor()
  856. if "OK" not in dev[0].request("ROAM " + apdev[1]['bssid']):
  857. raise Exception("ROAM failed")
  858. auth = None
  859. for i in range(20):
  860. msg = hapd1.mgmt_rx()
  861. if msg['subtype'] == 11:
  862. auth = msg
  863. break
  864. if not auth:
  865. raise Exception("Authentication frame not seen")
  866. resp = {}
  867. resp['fc'] = auth['fc']
  868. resp['da'] = auth['sa']
  869. resp['sa'] = auth['da']
  870. resp['bssid'] = auth['bssid']
  871. resp['payload'] = binascii.unhexlify(t)
  872. hapd1.mgmt_tx(resp)
  873. hapd1.set("ext_mgmt_frame_handling", "0")
  874. dev[0].wait_disconnected()
  875. dev[0].request("RECONNECT")
  876. dev[0].wait_connected()
  877. def test_ap_ft_gcmp_256(dev, apdev):
  878. """WPA2-PSK-FT AP with GCMP-256 cipher"""
  879. if "GCMP-256" not in dev[0].get_capability("pairwise"):
  880. raise HwsimSkip("Cipher GCMP-256 not supported")
  881. ssid = "test-ft"
  882. passphrase="12345678"
  883. params = ft_params1(ssid=ssid, passphrase=passphrase)
  884. params['rsn_pairwise'] = "GCMP-256"
  885. hapd0 = hostapd.add_ap(apdev[0], params)
  886. params = ft_params2(ssid=ssid, passphrase=passphrase)
  887. params['rsn_pairwise'] = "GCMP-256"
  888. hapd1 = hostapd.add_ap(apdev[1], params)
  889. run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase,
  890. pairwise_cipher="GCMP-256", group_cipher="GCMP-256")
  891. def test_ap_ft_oom(dev, apdev):
  892. """WPA2-PSK-FT and OOM"""
  893. skip_with_fips(dev[0])
  894. ssid = "test-ft"
  895. passphrase="12345678"
  896. params = ft_params1(ssid=ssid, passphrase=passphrase)
  897. hapd0 = hostapd.add_ap(apdev[0], params)
  898. params = ft_params2(ssid=ssid, passphrase=passphrase)
  899. hapd1 = hostapd.add_ap(apdev[1], params)
  900. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  901. scan_freq="2412")
  902. if dev[0].get_status_field('bssid') == apdev[0]['bssid']:
  903. dst = apdev[1]['bssid']
  904. else:
  905. dst = apdev[0]['bssid']
  906. dev[0].scan_for_bss(dst, freq="2412")
  907. with alloc_fail(dev[0], 1, "wpa_ft_gen_req_ies"):
  908. dev[0].roam(dst)
  909. with fail_test(dev[0], 1, "wpa_ft_mic"):
  910. dev[0].roam(dst, fail_test=True)
  911. with fail_test(dev[0], 1, "os_get_random;wpa_ft_prepare_auth_request"):
  912. dev[0].roam(dst, fail_test=True)
  913. dev[0].request("REMOVE_NETWORK all")
  914. with alloc_fail(dev[0], 1, "=sme_update_ft_ies"):
  915. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  916. scan_freq="2412")
  917. def test_ap_ft_ap_oom(dev, apdev):
  918. """WPA2-PSK-FT and AP OOM"""
  919. ssid = "test-ft"
  920. passphrase="12345678"
  921. params = ft_params1(ssid=ssid, passphrase=passphrase)
  922. hapd0 = hostapd.add_ap(apdev[0], params)
  923. bssid0 = hapd0.own_addr()
  924. dev[0].scan_for_bss(bssid0, freq="2412")
  925. with alloc_fail(hapd0, 1, "wpa_ft_store_pmk_r0"):
  926. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  927. scan_freq="2412")
  928. params = ft_params2(ssid=ssid, passphrase=passphrase)
  929. hapd1 = hostapd.add_ap(apdev[1], params)
  930. bssid1 = hapd1.own_addr()
  931. dev[0].scan_for_bss(bssid1, freq="2412")
  932. # This roam will fail due to missing PMK-R0 (OOM prevented storing it)
  933. dev[0].roam(bssid1)
  934. def test_ap_ft_ap_oom2(dev, apdev):
  935. """WPA2-PSK-FT and AP OOM 2"""
  936. ssid = "test-ft"
  937. passphrase="12345678"
  938. params = ft_params1(ssid=ssid, passphrase=passphrase)
  939. hapd0 = hostapd.add_ap(apdev[0], params)
  940. bssid0 = hapd0.own_addr()
  941. dev[0].scan_for_bss(bssid0, freq="2412")
  942. with alloc_fail(hapd0, 1, "wpa_ft_store_pmk_r1"):
  943. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  944. scan_freq="2412")
  945. params = ft_params2(ssid=ssid, passphrase=passphrase)
  946. hapd1 = hostapd.add_ap(apdev[1], params)
  947. bssid1 = hapd1.own_addr()
  948. dev[0].scan_for_bss(bssid1, freq="2412")
  949. dev[0].roam(bssid1)
  950. if dev[0].get_status_field('bssid') != bssid1:
  951. raise Exception("Did not roam to AP1")
  952. # This roam will fail due to missing PMK-R1 (OOM prevented storing it)
  953. dev[0].roam(bssid0)
  954. def test_ap_ft_ap_oom3(dev, apdev):
  955. """WPA2-PSK-FT and AP OOM 3"""
  956. ssid = "test-ft"
  957. passphrase="12345678"
  958. params = ft_params1(ssid=ssid, passphrase=passphrase)
  959. hapd0 = hostapd.add_ap(apdev[0], params)
  960. bssid0 = hapd0.own_addr()
  961. dev[0].scan_for_bss(bssid0, freq="2412")
  962. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  963. scan_freq="2412")
  964. params = ft_params2(ssid=ssid, passphrase=passphrase)
  965. hapd1 = hostapd.add_ap(apdev[1], params)
  966. bssid1 = hapd1.own_addr()
  967. dev[0].scan_for_bss(bssid1, freq="2412")
  968. with alloc_fail(hapd1, 1, "wpa_ft_pull_pmk_r1"):
  969. # This will fail due to not being able to send out PMK-R1 pull request
  970. dev[0].roam(bssid1)
  971. with fail_test(hapd1, 2, "os_get_random;wpa_ft_pull_pmk_r1"):
  972. # This will fail due to not being able to send out PMK-R1 pull request
  973. dev[0].roam(bssid1)
  974. with fail_test(hapd1, 2, "aes_siv_encrypt;wpa_ft_pull_pmk_r1"):
  975. # This will fail due to not being able to send out PMK-R1 pull request
  976. dev[0].roam(bssid1)
  977. def test_ap_ft_ap_oom3b(dev, apdev):
  978. """WPA2-PSK-FT and AP OOM 3b"""
  979. ssid = "test-ft"
  980. passphrase="12345678"
  981. params = ft_params1(ssid=ssid, passphrase=passphrase)
  982. hapd0 = hostapd.add_ap(apdev[0], params)
  983. bssid0 = hapd0.own_addr()
  984. dev[0].scan_for_bss(bssid0, freq="2412")
  985. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  986. scan_freq="2412")
  987. params = ft_params2(ssid=ssid, passphrase=passphrase)
  988. hapd1 = hostapd.add_ap(apdev[1], params)
  989. bssid1 = hapd1.own_addr()
  990. dev[0].scan_for_bss(bssid1, freq="2412")
  991. with fail_test(hapd1, 1, "os_get_random;wpa_ft_pull_pmk_r1"):
  992. # This will fail due to not being able to send out PMK-R1 pull request
  993. dev[0].roam(bssid1)
  994. def test_ap_ft_ap_oom4(dev, apdev):
  995. """WPA2-PSK-FT and AP OOM 4"""
  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_gtk_subelem"):
  1009. dev[0].roam(bssid1)
  1010. if dev[0].get_status_field('bssid') != bssid1:
  1011. raise Exception("Did not roam to AP1")
  1012. with fail_test(hapd0, 1, "wpa_auth_get_seqnum;wpa_ft_gtk_subelem"):
  1013. dev[0].roam(bssid0)
  1014. if dev[0].get_status_field('bssid') != bssid0:
  1015. raise Exception("Did not roam to AP0")
  1016. with fail_test(hapd0, 1, "aes_wrap;wpa_ft_gtk_subelem"):
  1017. dev[0].roam(bssid1)
  1018. if dev[0].get_status_field('bssid') != bssid1:
  1019. raise Exception("Did not roam to AP1")
  1020. def test_ap_ft_ap_oom5(dev, apdev):
  1021. """WPA2-PSK-FT and AP OOM 5"""
  1022. ssid = "test-ft"
  1023. passphrase="12345678"
  1024. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1025. hapd0 = hostapd.add_ap(apdev[0], params)
  1026. bssid0 = hapd0.own_addr()
  1027. dev[0].scan_for_bss(bssid0, freq="2412")
  1028. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1029. scan_freq="2412")
  1030. params = ft_params2(ssid=ssid, passphrase=passphrase)
  1031. hapd1 = hostapd.add_ap(apdev[1], params)
  1032. bssid1 = hapd1.own_addr()
  1033. dev[0].scan_for_bss(bssid1, freq="2412")
  1034. with alloc_fail(hapd1, 1, "=wpa_ft_process_auth_req"):
  1035. # This will fail to roam
  1036. dev[0].roam(bssid1)
  1037. with fail_test(hapd1, 1, "os_get_random;wpa_ft_process_auth_req"):
  1038. # This will fail to roam
  1039. dev[0].roam(bssid1)
  1040. with fail_test(hapd1, 1, "sha256_prf_bits;wpa_pmk_r1_to_ptk;wpa_ft_process_auth_req"):
  1041. # This will fail to roam
  1042. dev[0].roam(bssid1)
  1043. with fail_test(hapd1, 3, "wpa_pmk_r1_to_ptk;wpa_ft_process_auth_req"):
  1044. # This will fail to roam
  1045. dev[0].roam(bssid1)
  1046. with fail_test(hapd1, 1, "wpa_derive_pmk_r1_name;wpa_ft_process_auth_req"):
  1047. # This will fail to roam
  1048. dev[0].roam(bssid1)
  1049. def test_ap_ft_ap_oom6(dev, apdev):
  1050. """WPA2-PSK-FT and AP OOM 6"""
  1051. ssid = "test-ft"
  1052. passphrase="12345678"
  1053. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1054. hapd0 = hostapd.add_ap(apdev[0], params)
  1055. bssid0 = hapd0.own_addr()
  1056. dev[0].scan_for_bss(bssid0, freq="2412")
  1057. with fail_test(hapd0, 1, "wpa_derive_pmk_r0;wpa_auth_derive_ptk_ft"):
  1058. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1059. scan_freq="2412")
  1060. dev[0].request("REMOVE_NETWORK all")
  1061. dev[0].wait_disconnected()
  1062. with fail_test(hapd0, 1, "wpa_derive_pmk_r1;wpa_auth_derive_ptk_ft"):
  1063. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1064. scan_freq="2412")
  1065. dev[0].request("REMOVE_NETWORK all")
  1066. dev[0].wait_disconnected()
  1067. with fail_test(hapd0, 1, "wpa_pmk_r1_to_ptk;wpa_auth_derive_ptk_ft"):
  1068. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1069. scan_freq="2412")
  1070. def test_ap_ft_ap_oom7(dev, apdev):
  1071. """WPA2-PSK-FT and AP OOM 7"""
  1072. ssid = "test-ft"
  1073. passphrase="12345678"
  1074. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1075. params["ieee80211w"] = "2"
  1076. hapd0 = hostapd.add_ap(apdev[0], params)
  1077. bssid0 = hapd0.own_addr()
  1078. dev[0].scan_for_bss(bssid0, freq="2412")
  1079. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1080. ieee80211w="2", scan_freq="2412")
  1081. params = ft_params2(ssid=ssid, passphrase=passphrase)
  1082. params["ieee80211w"] = "2"
  1083. hapd1 = hostapd.add_ap(apdev[1], params)
  1084. bssid1 = hapd1.own_addr()
  1085. dev[0].scan_for_bss(bssid1, freq="2412")
  1086. with alloc_fail(hapd1, 1, "wpa_ft_igtk_subelem"):
  1087. # This will fail to roam
  1088. dev[0].roam(bssid1)
  1089. with fail_test(hapd1, 1, "aes_wrap;wpa_ft_igtk_subelem"):
  1090. # This will fail to roam
  1091. dev[0].roam(bssid1)
  1092. with alloc_fail(hapd1, 1, "=wpa_sm_write_assoc_resp_ies"):
  1093. # This will fail to roam
  1094. dev[0].roam(bssid1)
  1095. with fail_test(hapd1, 1, "wpa_ft_mic;wpa_sm_write_assoc_resp_ies"):
  1096. # This will fail to roam
  1097. dev[0].roam(bssid1)
  1098. def test_ap_ft_ap_oom8(dev, apdev):
  1099. """WPA2-PSK-FT and AP OOM 8"""
  1100. ssid = "test-ft"
  1101. passphrase="12345678"
  1102. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1103. params['ft_psk_generate_local'] = "1";
  1104. hapd0 = hostapd.add_ap(apdev[0], params)
  1105. bssid0 = hapd0.own_addr()
  1106. dev[0].scan_for_bss(bssid0, freq="2412")
  1107. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1108. scan_freq="2412")
  1109. params = ft_params2(ssid=ssid, passphrase=passphrase)
  1110. params['ft_psk_generate_local'] = "1";
  1111. hapd1 = hostapd.add_ap(apdev[1], params)
  1112. bssid1 = hapd1.own_addr()
  1113. dev[0].scan_for_bss(bssid1, freq="2412")
  1114. with fail_test(hapd1, 1, "wpa_derive_pmk_r0;wpa_ft_psk_pmk_r1"):
  1115. # This will fail to roam
  1116. dev[0].roam(bssid1)
  1117. with fail_test(hapd1, 1, "wpa_derive_pmk_r1;wpa_ft_psk_pmk_r1"):
  1118. # This will fail to roam
  1119. dev[0].roam(bssid1)
  1120. def test_ap_ft_ap_oom9(dev, apdev):
  1121. """WPA2-PSK-FT and AP OOM 9"""
  1122. ssid = "test-ft"
  1123. passphrase="12345678"
  1124. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1125. hapd0 = hostapd.add_ap(apdev[0], params)
  1126. bssid0 = hapd0.own_addr()
  1127. dev[0].scan_for_bss(bssid0, freq="2412")
  1128. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1129. scan_freq="2412")
  1130. params = ft_params2(ssid=ssid, passphrase=passphrase)
  1131. hapd1 = hostapd.add_ap(apdev[1], params)
  1132. bssid1 = hapd1.own_addr()
  1133. dev[0].scan_for_bss(bssid1, freq="2412")
  1134. with alloc_fail(hapd0, 1, "wpa_ft_action_rx"):
  1135. # This will fail to roam
  1136. if "OK" not in dev[0].request("FT_DS " + bssid1):
  1137. raise Exception("FT_DS failed")
  1138. wait_fail_trigger(hapd0, "GET_ALLOC_FAIL")
  1139. with alloc_fail(hapd1, 1, "wpa_ft_rrb_rx_request"):
  1140. # This will fail to roam
  1141. if "OK" not in dev[0].request("FT_DS " + bssid1):
  1142. raise Exception("FT_DS failed")
  1143. wait_fail_trigger(hapd1, "GET_ALLOC_FAIL")
  1144. with alloc_fail(hapd1, 1, "wpa_ft_send_rrb_auth_resp"):
  1145. # This will fail to roam
  1146. if "OK" not in dev[0].request("FT_DS " + bssid1):
  1147. raise Exception("FT_DS failed")
  1148. wait_fail_trigger(hapd1, "GET_ALLOC_FAIL")
  1149. def test_ap_ft_ap_oom10(dev, apdev):
  1150. """WPA2-PSK-FT and AP OOM 10"""
  1151. ssid = "test-ft"
  1152. passphrase="12345678"
  1153. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1154. hapd0 = hostapd.add_ap(apdev[0], params)
  1155. bssid0 = hapd0.own_addr()
  1156. dev[0].scan_for_bss(bssid0, freq="2412")
  1157. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1158. scan_freq="2412")
  1159. params = ft_params2(ssid=ssid, passphrase=passphrase)
  1160. hapd1 = hostapd.add_ap(apdev[1], params)
  1161. bssid1 = hapd1.own_addr()
  1162. dev[0].scan_for_bss(bssid1, freq="2412")
  1163. with fail_test(hapd0, 1, "aes_siv_decrypt;wpa_ft_rrb_rx_pull"):
  1164. # This will fail to roam
  1165. if "OK" not in dev[0].request("FT_DS " + bssid1):
  1166. raise Exception("FT_DS failed")
  1167. wait_fail_trigger(hapd0, "GET_FAIL")
  1168. with fail_test(hapd0, 1, "wpa_derive_pmk_r1;wpa_ft_rrb_rx_pull"):
  1169. # This will fail to roam
  1170. if "OK" not in dev[0].request("FT_DS " + bssid1):
  1171. raise Exception("FT_DS failed")
  1172. wait_fail_trigger(hapd0, "GET_FAIL")
  1173. with fail_test(hapd0, 1, "aes_siv_encrypt;wpa_ft_rrb_rx_pull"):
  1174. # This will fail to roam
  1175. if "OK" not in dev[0].request("FT_DS " + bssid1):
  1176. raise Exception("FT_DS failed")
  1177. wait_fail_trigger(hapd0, "GET_FAIL")
  1178. with fail_test(hapd1, 1, "aes_siv_decrypt;wpa_ft_rrb_rx_resp"):
  1179. # This will fail to roam
  1180. if "OK" not in dev[0].request("FT_DS " + bssid1):
  1181. raise Exception("FT_DS failed")
  1182. wait_fail_trigger(hapd1, "GET_FAIL")
  1183. def test_ap_ft_ap_oom11(dev, apdev):
  1184. """WPA2-PSK-FT and AP OOM 11"""
  1185. ssid = "test-ft"
  1186. passphrase="12345678"
  1187. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1188. hapd0 = hostapd.add_ap(apdev[0], params)
  1189. bssid0 = hapd0.own_addr()
  1190. dev[0].scan_for_bss(bssid0, freq="2412")
  1191. with fail_test(hapd0, 1, "wpa_derive_pmk_r1;wpa_ft_generate_pmk_r1"):
  1192. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1193. scan_freq="2412")
  1194. wait_fail_trigger(hapd0, "GET_FAIL")
  1195. dev[1].scan_for_bss(bssid0, freq="2412")
  1196. with fail_test(hapd0, 1, "aes_siv_encrypt;wpa_ft_generate_pmk_r1"):
  1197. dev[1].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1198. scan_freq="2412")
  1199. wait_fail_trigger(hapd0, "GET_FAIL")
  1200. def test_ap_ft_over_ds_proto_ap(dev, apdev):
  1201. """WPA2-PSK-FT AP over DS protocol testing for AP processing"""
  1202. ssid = "test-ft"
  1203. passphrase="12345678"
  1204. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1205. hapd0 = hostapd.add_ap(apdev[0], params)
  1206. bssid0 = hapd0.own_addr()
  1207. _bssid0 = bssid0.replace(':', '')
  1208. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1209. scan_freq="2412")
  1210. addr = dev[0].own_addr()
  1211. _addr = addr.replace(':', '')
  1212. params = ft_params2(ssid=ssid, passphrase=passphrase)
  1213. hapd1 = hostapd.add_ap(apdev[1], params)
  1214. bssid1 = hapd1.own_addr()
  1215. _bssid1 = bssid1.replace(':', '')
  1216. hapd0.set("ext_mgmt_frame_handling", "1")
  1217. hdr = "d0003a01" + _bssid0 + _addr + _bssid0 + "1000"
  1218. valid = "0601" + _addr + _bssid1
  1219. tests = [ "0601",
  1220. "0601" + _addr,
  1221. "0601" + _addr + _bssid0,
  1222. "0601" + _addr + "ffffffffffff",
  1223. "0601" + _bssid0 + _bssid0,
  1224. valid,
  1225. valid + "01",
  1226. valid + "3700",
  1227. valid + "3600",
  1228. valid + "3603ffffff",
  1229. valid + "3603a1b2ff",
  1230. valid + "3603a1b2ff" + "3700",
  1231. valid + "3603a1b2ff" + "37520000" + 16*"00" + 32*"00" + 32*"00",
  1232. valid + "3603a1b2ff" + "37520001" + 16*"00" + 32*"00" + 32*"00",
  1233. valid + "3603a1b2ff" + "37550000" + 16*"00" + 32*"00" + 32*"00" + "0301aa",
  1234. valid + "3603a1b2ff" + "37550000" + 16*"00" + 32*"00" + 32*"00" + "0301aa" + "3000",
  1235. valid + "3603a1b2ff" + "37550000" + 16*"00" + 32*"00" + 32*"00" + "0301aa" + "30260100000fac040100000fac040100000facff00000100a225368fe0983b5828a37a0acb37f253",
  1236. valid + "3603a1b2ff" + "37550000" + 16*"00" + 32*"00" + 32*"00" + "0301aa" + "30260100000fac040100000fac030100000fac0400000100a225368fe0983b5828a37a0acb37f253",
  1237. valid + "3603a1b2ff" + "37550000" + 16*"00" + 32*"00" + 32*"00" + "0301aa" + "30260100000fac040100000fac040100000fac0400000100a225368fe0983b5828a37a0acb37f253",
  1238. valid + "0001" ]
  1239. for t in tests:
  1240. hapd0.dump_monitor()
  1241. if "OK" not in hapd0.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + t):
  1242. raise Exception("MGMT_RX_PROCESS failed")
  1243. hapd0.set("ext_mgmt_frame_handling", "0")
  1244. def test_ap_ft_over_ds_proto(dev, apdev):
  1245. """WPA2-PSK-FT AP over DS protocol testing"""
  1246. ssid = "test-ft"
  1247. passphrase="12345678"
  1248. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1249. hapd0 = hostapd.add_ap(apdev[0], params)
  1250. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1251. scan_freq="2412")
  1252. # FT Action Response while no FT-over-DS in progress
  1253. msg = {}
  1254. msg['fc'] = 13 << 4
  1255. msg['da'] = dev[0].own_addr()
  1256. msg['sa'] = apdev[0]['bssid']
  1257. msg['bssid'] = apdev[0]['bssid']
  1258. msg['payload'] = binascii.unhexlify("06020200000000000200000004000000")
  1259. hapd0.mgmt_tx(msg)
  1260. params = ft_params2(ssid=ssid, passphrase=passphrase)
  1261. hapd1 = hostapd.add_ap(apdev[1], params)
  1262. dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
  1263. hapd0.set("ext_mgmt_frame_handling", "1")
  1264. hapd0.dump_monitor()
  1265. dev[0].request("FT_DS " + apdev[1]['bssid'])
  1266. for i in range(0, 10):
  1267. req = hapd0.mgmt_rx()
  1268. if req is None:
  1269. raise Exception("MGMT RX wait timed out")
  1270. if req['subtype'] == 13:
  1271. break
  1272. req = None
  1273. if not req:
  1274. raise Exception("FT Action frame not received")
  1275. # FT Action Response for unexpected Target AP
  1276. msg['payload'] = binascii.unhexlify("0602020000000000" + "f20000000400" + "0000")
  1277. hapd0.mgmt_tx(msg)
  1278. # FT Action Response without MDIE
  1279. msg['payload'] = binascii.unhexlify("0602020000000000" + "020000000400" + "0000")
  1280. hapd0.mgmt_tx(msg)
  1281. # FT Action Response without FTIE
  1282. msg['payload'] = binascii.unhexlify("0602020000000000" + "020000000400" + "0000" + "3603a1b201")
  1283. hapd0.mgmt_tx(msg)
  1284. # FT Action Response with FTIE SNonce mismatch
  1285. msg['payload'] = binascii.unhexlify("0602020000000000" + "020000000400" + "0000" + "3603a1b201" + "3766000000000000000000000000000000000000c4e67ac1999bebd00ff4ae4d5dcaf87896bb060b469f7c78d49623fb395c3455ffffff6b693fe6f8d8c5dfac0a22344750775bd09437f98b238c9f87b97f790c0106000102030406030a6e6173312e77312e6669")
  1286. hapd0.mgmt_tx(msg)
  1287. @remote_compatible
  1288. def test_ap_ft_rrb(dev, apdev):
  1289. """WPA2-PSK-FT RRB protocol testing"""
  1290. ssid = "test-ft"
  1291. passphrase="12345678"
  1292. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1293. hapd0 = hostapd.add_ap(apdev[0], params)
  1294. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1295. scan_freq="2412")
  1296. _dst_ll = binascii.unhexlify(apdev[0]['bssid'].replace(':',''))
  1297. _src_ll = binascii.unhexlify(dev[0].own_addr().replace(':',''))
  1298. proto = '\x89\x0d'
  1299. ehdr = _dst_ll + _src_ll + proto
  1300. # Too short RRB frame
  1301. pkt = ehdr + '\x01'
  1302. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1303. raise Exception("DATA_TEST_FRAME failed")
  1304. # RRB discarded frame wikth unrecognized type
  1305. pkt = ehdr + '\x02' + '\x02' + '\x01\x00' + _src_ll
  1306. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1307. raise Exception("DATA_TEST_FRAME failed")
  1308. # RRB frame too short for action frame
  1309. pkt = ehdr + '\x01' + '\x02' + '\x01\x00' + _src_ll
  1310. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1311. raise Exception("DATA_TEST_FRAME failed")
  1312. # Too short RRB frame (not enough room for Action Frame body)
  1313. pkt = ehdr + '\x01' + '\x02' + '\x00\x00' + _src_ll
  1314. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1315. raise Exception("DATA_TEST_FRAME failed")
  1316. # Unexpected Action frame category
  1317. pkt = ehdr + '\x01' + '\x02' + '\x0e\x00' + _src_ll + '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
  1318. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1319. raise Exception("DATA_TEST_FRAME failed")
  1320. # Unexpected Action in RRB Request
  1321. pkt = ehdr + '\x01' + '\x00' + '\x0e\x00' + _src_ll + '\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
  1322. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1323. raise Exception("DATA_TEST_FRAME failed")
  1324. # Target AP address in RRB Request does not match with own address
  1325. pkt = ehdr + '\x01' + '\x00' + '\x0e\x00' + _src_ll + '\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
  1326. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1327. raise Exception("DATA_TEST_FRAME failed")
  1328. # Not enough room for status code in RRB Response
  1329. pkt = ehdr + '\x01' + '\x01' + '\x0e\x00' + _src_ll + '\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
  1330. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1331. raise Exception("DATA_TEST_FRAME failed")
  1332. # RRB discarded frame with unknown packet_type
  1333. pkt = ehdr + '\x01' + '\x02' + '\x0e\x00' + _src_ll + '\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
  1334. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1335. raise Exception("DATA_TEST_FRAME failed")
  1336. # RRB Response with non-zero status code; no STA match
  1337. pkt = ehdr + '\x01' + '\x01' + '\x10\x00' + _src_ll + '\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + '\xff\xff'
  1338. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1339. raise Exception("DATA_TEST_FRAME failed")
  1340. # RRB Response with zero status code and extra data; STA match
  1341. pkt = ehdr + '\x01' + '\x01' + '\x11\x00' + _src_ll + '\x06\x01' + _src_ll + '\x00\x00\x00\x00\x00\x00' + '\x00\x00' + '\x00'
  1342. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1343. raise Exception("DATA_TEST_FRAME failed")
  1344. # Too short PMK-R1 pull
  1345. pkt = ehdr + '\x01' + '\xc8' + '\x0e\x00' + _src_ll + '\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
  1346. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1347. raise Exception("DATA_TEST_FRAME failed")
  1348. # Too short PMK-R1 resp
  1349. pkt = ehdr + '\x01' + '\xc9' + '\x0e\x00' + _src_ll + '\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
  1350. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1351. raise Exception("DATA_TEST_FRAME failed")
  1352. # Too short PMK-R1 push
  1353. pkt = ehdr + '\x01' + '\xca' + '\x0e\x00' + _src_ll + '\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
  1354. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1355. raise Exception("DATA_TEST_FRAME failed")
  1356. # No matching R0KH address found for PMK-R0 pull response
  1357. pkt = ehdr + '\x01' + '\xc9' + '\x5a\x00' + _src_ll + '\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + 76*'\00'
  1358. if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
  1359. raise Exception("DATA_TEST_FRAME failed")
  1360. @remote_compatible
  1361. def test_rsn_ie_proto_ft_psk_sta(dev, apdev):
  1362. """RSN element protocol testing for FT-PSK + PMF cases on STA side"""
  1363. bssid = apdev[0]['bssid']
  1364. ssid = "test-ft"
  1365. passphrase="12345678"
  1366. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1367. params["ieee80211w"] = "1"
  1368. # This is the RSN element used normally by hostapd
  1369. params['own_ie_override'] = '30140100000fac040100000fac040100000fac048c00' + '3603a1b201'
  1370. hapd = hostapd.add_ap(apdev[0], params)
  1371. id = dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1372. ieee80211w="1", scan_freq="2412",
  1373. pairwise="CCMP", group="CCMP")
  1374. tests = [ ('PMKIDCount field included',
  1375. '30160100000fac040100000fac040100000fac048c000000' + '3603a1b201'),
  1376. ('Extra IE before RSNE',
  1377. 'dd0400000000' + '30140100000fac040100000fac040100000fac048c00' + '3603a1b201'),
  1378. ('PMKIDCount and Group Management Cipher suite fields included',
  1379. '301a0100000fac040100000fac040100000fac048c000000000fac06' + '3603a1b201'),
  1380. ('Extra octet after defined fields (future extensibility)',
  1381. '301b0100000fac040100000fac040100000fac048c000000000fac0600' + '3603a1b201'),
  1382. ('No RSN Capabilities field (PMF disabled in practice)',
  1383. '30120100000fac040100000fac040100000fac04' + '3603a1b201') ]
  1384. for txt,ie in tests:
  1385. dev[0].request("DISCONNECT")
  1386. dev[0].wait_disconnected()
  1387. logger.info(txt)
  1388. hapd.disable()
  1389. hapd.set('own_ie_override', ie)
  1390. hapd.enable()
  1391. dev[0].request("BSS_FLUSH 0")
  1392. dev[0].scan_for_bss(bssid, 2412, force_scan=True, only_new=True)
  1393. dev[0].select_network(id, freq=2412)
  1394. dev[0].wait_connected()
  1395. dev[0].request("DISCONNECT")
  1396. dev[0].wait_disconnected()
  1397. logger.info('Invalid RSNE causing internal hostapd error')
  1398. hapd.disable()
  1399. hapd.set('own_ie_override', '30130100000fac040100000fac040100000fac048c' + '3603a1b201')
  1400. hapd.enable()
  1401. dev[0].request("BSS_FLUSH 0")
  1402. dev[0].scan_for_bss(bssid, 2412, force_scan=True, only_new=True)
  1403. dev[0].select_network(id, freq=2412)
  1404. # hostapd fails to generate EAPOL-Key msg 3/4, so this connection cannot
  1405. # complete.
  1406. ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1)
  1407. if ev is not None:
  1408. raise Exception("Unexpected connection")
  1409. dev[0].request("DISCONNECT")
  1410. logger.info('Unexpected PMKID causing internal hostapd error')
  1411. hapd.disable()
  1412. hapd.set('own_ie_override', '30260100000fac040100000fac040100000fac048c000100ffffffffffffffffffffffffffffffff' + '3603a1b201')
  1413. hapd.enable()
  1414. dev[0].request("BSS_FLUSH 0")
  1415. dev[0].scan_for_bss(bssid, 2412, force_scan=True, only_new=True)
  1416. dev[0].select_network(id, freq=2412)
  1417. # hostapd fails to generate EAPOL-Key msg 3/4, so this connection cannot
  1418. # complete.
  1419. ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1)
  1420. if ev is not None:
  1421. raise Exception("Unexpected connection")
  1422. dev[0].request("DISCONNECT")
  1423. def test_ap_ft_ptk_rekey(dev, apdev):
  1424. """WPA2-PSK-FT PTK rekeying triggered by station after roam"""
  1425. ssid = "test-ft"
  1426. passphrase="12345678"
  1427. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1428. hapd0 = hostapd.add_ap(apdev[0], params)
  1429. params = ft_params2(ssid=ssid, passphrase=passphrase)
  1430. hapd1 = hostapd.add_ap(apdev[1], params)
  1431. run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, ptk_rekey="1")
  1432. ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED",
  1433. "WPA: Key negotiation completed"], timeout=5)
  1434. if ev is None:
  1435. raise Exception("No event received after roam")
  1436. if "CTRL-EVENT-DISCONNECTED" in ev:
  1437. raise Exception("Unexpected disconnection after roam")
  1438. if dev[0].get_status_field('bssid') == apdev[0]['bssid']:
  1439. hapd = hapd0
  1440. else:
  1441. hapd = hapd1
  1442. hwsim_utils.test_connectivity(dev[0], hapd)
  1443. def test_ap_ft_ptk_rekey_ap(dev, apdev):
  1444. """WPA2-PSK-FT PTK rekeying triggered by AP after roam"""
  1445. ssid = "test-ft"
  1446. passphrase="12345678"
  1447. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1448. params['wpa_ptk_rekey'] = '2'
  1449. hapd0 = hostapd.add_ap(apdev[0], params)
  1450. params = ft_params2(ssid=ssid, passphrase=passphrase)
  1451. params['wpa_ptk_rekey'] = '2'
  1452. hapd1 = hostapd.add_ap(apdev[1], params)
  1453. run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase)
  1454. ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED",
  1455. "WPA: Key negotiation completed"], timeout=5)
  1456. if ev is None:
  1457. raise Exception("No event received after roam")
  1458. if "CTRL-EVENT-DISCONNECTED" in ev:
  1459. raise Exception("Unexpected disconnection after roam")
  1460. if dev[0].get_status_field('bssid') == apdev[0]['bssid']:
  1461. hapd = hapd0
  1462. else:
  1463. hapd = hapd1
  1464. hwsim_utils.test_connectivity(dev[0], hapd)
  1465. def test_ap_ft_internal_rrb_check(dev, apdev):
  1466. """RRB internal delivery only to WPA enabled BSS"""
  1467. ssid = "test-ft"
  1468. passphrase="12345678"
  1469. radius = hostapd.radius_params()
  1470. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1471. params['wpa_key_mgmt'] = "FT-EAP"
  1472. params["ieee8021x"] = "1"
  1473. params = dict(radius.items() + params.items())
  1474. hapd = hostapd.add_ap(apdev[0], params)
  1475. key_mgmt = hapd.get_config()['key_mgmt']
  1476. if key_mgmt.split(' ')[0] != "FT-EAP":
  1477. raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
  1478. hapd1 = hostapd.add_ap(apdev[1], { "ssid" : ssid })
  1479. # Connect to WPA enabled AP
  1480. dev[0].connect(ssid, key_mgmt="FT-EAP", proto="WPA2", ieee80211w="1",
  1481. eap="GPSK", identity="gpsk user",
  1482. password="abcdefghijklmnop0123456789abcdef",
  1483. scan_freq="2412")
  1484. # Try over_ds roaming to non-WPA-enabled AP.
  1485. # If hostapd does not check hapd->wpa_auth internally, it will crash now.
  1486. dev[0].roam_over_ds(apdev[1]['bssid'], fail_test=True)
  1487. def test_ap_ft_extra_ie(dev, apdev):
  1488. """WPA2-PSK-FT AP with WPA2-PSK enabled and unexpected MDE"""
  1489. ssid = "test-ft"
  1490. passphrase="12345678"
  1491. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1492. params["wpa_key_mgmt"] = "WPA-PSK FT-PSK"
  1493. hapd0 = hostapd.add_ap(apdev[0], params)
  1494. dev[1].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1495. scan_freq="2412")
  1496. dev[2].connect(ssid, psk=passphrase, key_mgmt="WPA-PSK", proto="WPA2",
  1497. scan_freq="2412")
  1498. try:
  1499. # Add Mobility Domain element to test AP validation code.
  1500. dev[0].request("VENDOR_ELEM_ADD 13 3603a1b201")
  1501. dev[0].connect(ssid, psk=passphrase, key_mgmt="WPA-PSK", proto="WPA2",
  1502. scan_freq="2412", wait_connect=False)
  1503. ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
  1504. "CTRL-EVENT-ASSOC-REJECT"], timeout=10)
  1505. if ev is None:
  1506. raise Exception("No connection result")
  1507. if "CTRL-EVENT-CONNECTED" in ev:
  1508. raise Exception("Non-FT association accepted with MDE")
  1509. if "status_code=43" not in ev:
  1510. raise Exception("Unexpected status code: " + ev)
  1511. dev[0].request("DISCONNECT")
  1512. finally:
  1513. dev[0].request("VENDOR_ELEM_REMOVE 13 *")
  1514. def test_ap_ft_ric(dev, apdev):
  1515. """WPA2-PSK-FT AP and RIC"""
  1516. ssid = "test-ft"
  1517. passphrase="12345678"
  1518. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1519. hapd0 = hostapd.add_ap(apdev[0], params)
  1520. params = ft_params2(ssid=ssid, passphrase=passphrase)
  1521. hapd1 = hostapd.add_ap(apdev[1], params)
  1522. dev[0].set("ric_ies", "")
  1523. dev[0].set("ric_ies", '""')
  1524. if "FAIL" not in dev[0].request("SET ric_ies q"):
  1525. raise Exception("Invalid ric_ies value accepted")
  1526. tests = [ "3900",
  1527. "3900ff04eeeeeeee",
  1528. "390400000000",
  1529. "390400000000" + "390400000000",
  1530. "390400000000" + "dd050050f20202",
  1531. "390400000000" + "dd3d0050f2020201" + 55*"00",
  1532. "390400000000" + "dd3d0050f2020201aa300010270000000000000000000000000000000000000000000000000000ffffff7f00000000000000000000000040420f00ffff0000",
  1533. "390401010000" + "dd3d0050f2020201aa3000dc050000000000000000000000000000000000000000000000000000dc050000000000000000000000000000808d5b0028230000" ]
  1534. for t in tests:
  1535. dev[0].set("ric_ies", t)
  1536. run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase,
  1537. test_connectivity=False)
  1538. dev[0].request("REMOVE_NETWORK all")
  1539. dev[0].wait_disconnected()
  1540. dev[0].dump_monitor()
  1541. def ie_hex(ies, id):
  1542. return binascii.hexlify(struct.pack('BB', id, len(ies[id])) + ies[id])
  1543. def test_ap_ft_reassoc_proto(dev, apdev):
  1544. """WPA2-PSK-FT AP Reassociation Request frame parsing"""
  1545. ssid = "test-ft"
  1546. passphrase="12345678"
  1547. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1548. hapd0 = hostapd.add_ap(apdev[0], params)
  1549. params = ft_params2(ssid=ssid, passphrase=passphrase)
  1550. hapd1 = hostapd.add_ap(apdev[1], params)
  1551. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1552. ieee80211w="1", scan_freq="2412")
  1553. if dev[0].get_status_field('bssid') == hapd0.own_addr():
  1554. hapd1ap = hapd0
  1555. hapd2ap = hapd1
  1556. else:
  1557. hapd1ap = hapd1
  1558. hapd2ap = hapd0
  1559. dev[0].scan_for_bss(hapd2ap.own_addr(), freq="2412")
  1560. hapd2ap.set("ext_mgmt_frame_handling", "1")
  1561. dev[0].request("ROAM " + hapd2ap.own_addr())
  1562. while True:
  1563. req = hapd2ap.mgmt_rx()
  1564. hapd2ap.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']))
  1565. if req['subtype'] == 11:
  1566. break
  1567. while True:
  1568. req = hapd2ap.mgmt_rx()
  1569. if req['subtype'] == 2:
  1570. break
  1571. hapd2ap.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']))
  1572. # IEEE 802.11 header + fixed fields before IEs
  1573. hdr = binascii.hexlify(req['frame'][0:34])
  1574. ies = parse_ie(binascii.hexlify(req['frame'][34:]))
  1575. # First elements: SSID, Supported Rates, Extended Supported Rates
  1576. ies1 = ie_hex(ies, 0) + ie_hex(ies, 1) + ie_hex(ies, 50)
  1577. rsne = ie_hex(ies, 48)
  1578. mde = ie_hex(ies, 54)
  1579. fte = ie_hex(ies, 55)
  1580. tests = [ ]
  1581. # RSN: Trying to use FT, but MDIE not included
  1582. tests += [ rsne ]
  1583. # RSN: Attempted to use unknown MDIE
  1584. tests += [ rsne + "3603000000" ]
  1585. # Invalid RSN pairwise cipher
  1586. tests += [ "30260100000fac040100000fac030100000fac040000010029208a42cd25c85aa571567dce10dae3" ]
  1587. # FT: No PMKID in RSNIE
  1588. tests += [ "30160100000fac040100000fac040100000fac0400000000" + ie_hex(ies, 54) ]
  1589. # FT: Invalid FTIE
  1590. tests += [ rsne + mde ]
  1591. # FT: RIC IE(s) in the frame, but not included in protected IE count
  1592. # FT: Failed to parse FT IEs
  1593. tests += [ rsne + mde + fte + "3900" ]
  1594. # FT: SNonce mismatch in FTIE
  1595. tests += [ rsne + mde + "37520000" + 16*"00" + 32*"00" + 32*"00" ]
  1596. # FT: ANonce mismatch in FTIE
  1597. tests += [ rsne + mde + fte[0:40] + 32*"00" + fte[104:] ]
  1598. # FT: No R0KH-ID subelem in FTIE
  1599. tests += [ rsne + mde + "3752" + fte[4:168] ]
  1600. # FT: R0KH-ID in FTIE did not match with the current R0KH-ID
  1601. tests += [ rsne + mde + "3755" + fte[4:168] + "0301ff" ]
  1602. # FT: No R1KH-ID subelem in FTIE
  1603. tests += [ rsne + mde + "375e" + fte[4:168] + "030a" + "nas1.w1.fi".encode("hex") ]
  1604. # FT: Unknown R1KH-ID used in ReassocReq
  1605. tests += [ rsne + mde + "3766" + fte[4:168] + "030a" + "nas1.w1.fi".encode("hex") + "0106000000000000" ]
  1606. # FT: PMKID in Reassoc Req did not match with the PMKR1Name derived from auth request
  1607. tests += [ rsne[:-32] + 16*"00" + mde + fte ]
  1608. # Invalid MIC in FTIE
  1609. tests += [ rsne + mde + fte[0:8] + 16*"00" + fte[40:] ]
  1610. for t in tests:
  1611. hapd2ap.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + ies1 + t)
  1612. def test_ap_ft_reassoc_local_fail(dev, apdev):
  1613. """WPA2-PSK-FT AP Reassociation Request frame and local failure"""
  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. ieee80211w="1", 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. # FT: Failed to calculate MIC
  1630. with fail_test(hapd2ap, 1, "wpa_ft_validate_reassoc"):
  1631. dev[0].request("ROAM " + hapd2ap.own_addr())
  1632. ev = dev[0].wait_event(["CTRL-EVENT-ASSOC-REJECT"], timeout=10)
  1633. dev[0].request("DISCONNECT")
  1634. if ev is None:
  1635. raise Exception("Association reject not seen")
  1636. def test_ap_ft_reassoc_replay(dev, apdev, params):
  1637. """WPA2-PSK-FT AP and replayed Reassociation Request frame"""
  1638. capfile = os.path.join(params['logdir'], "hwsim0.pcapng")
  1639. ssid = "test-ft"
  1640. passphrase="12345678"
  1641. params = ft_params1(ssid=ssid, passphrase=passphrase)
  1642. hapd0 = hostapd.add_ap(apdev[0], params)
  1643. params = ft_params2(ssid=ssid, passphrase=passphrase)
  1644. hapd1 = hostapd.add_ap(apdev[1], params)
  1645. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1646. scan_freq="2412")
  1647. if dev[0].get_status_field('bssid') == hapd0.own_addr():
  1648. hapd1ap = hapd0
  1649. hapd2ap = hapd1
  1650. else:
  1651. hapd1ap = hapd1
  1652. hapd2ap = hapd0
  1653. dev[0].scan_for_bss(hapd2ap.own_addr(), freq="2412")
  1654. hapd2ap.set("ext_mgmt_frame_handling", "1")
  1655. dev[0].dump_monitor()
  1656. if "OK" not in dev[0].request("ROAM " + hapd2ap.own_addr()):
  1657. raise Exception("ROAM failed")
  1658. reassocreq = None
  1659. count = 0
  1660. while count < 100:
  1661. req = hapd2ap.mgmt_rx()
  1662. count += 1
  1663. hapd2ap.dump_monitor()
  1664. hapd2ap.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']))
  1665. if req['subtype'] == 2:
  1666. reassocreq = req
  1667. ev = hapd2ap.wait_event(["MGMT-TX-STATUS"], timeout=5)
  1668. if ev is None:
  1669. raise Exception("No TX status seen")
  1670. cmd = "MGMT_TX_STATUS_PROCESS %s" % (" ".join(ev.split(' ')[1:4]))
  1671. if "OK" not in hapd2ap.request(cmd):
  1672. raise Exception("MGMT_TX_STATUS_PROCESS failed")
  1673. break
  1674. hapd2ap.set("ext_mgmt_frame_handling", "0")
  1675. if reassocreq is None:
  1676. raise Exception("No Reassociation Request frame seen")
  1677. dev[0].wait_connected()
  1678. dev[0].dump_monitor()
  1679. hapd2ap.dump_monitor()
  1680. hwsim_utils.test_connectivity(dev[0], hapd2ap)
  1681. logger.info("Replay the last Reassociation Request frame")
  1682. hapd2ap.dump_monitor()
  1683. hapd2ap.set("ext_mgmt_frame_handling", "1")
  1684. hapd2ap.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']))
  1685. ev = hapd2ap.wait_event(["MGMT-TX-STATUS"], timeout=5)
  1686. if ev is None:
  1687. raise Exception("No TX status seen")
  1688. cmd = "MGMT_TX_STATUS_PROCESS %s" % (" ".join(ev.split(' ')[1:4]))
  1689. if "OK" not in hapd2ap.request(cmd):
  1690. raise Exception("MGMT_TX_STATUS_PROCESS failed")
  1691. hapd2ap.set("ext_mgmt_frame_handling", "0")
  1692. try:
  1693. hwsim_utils.test_connectivity(dev[0], hapd2ap)
  1694. ok = True
  1695. except:
  1696. ok = False
  1697. ap = hapd2ap.own_addr()
  1698. sta = dev[0].own_addr()
  1699. filt = "wlan.fc.type == 2 && " + \
  1700. "wlan.da == " + sta + " && " + \
  1701. "wlan.sa == " + ap
  1702. fields = [ "wlan.ccmp.extiv" ]
  1703. res = run_tshark(capfile, filt, fields)
  1704. vals = res.splitlines()
  1705. logger.info("CCMP PN: " + str(vals))
  1706. if len(vals) < 2:
  1707. raise Exception("Could not find all CCMP protected frames from capture")
  1708. if len(set(vals)) < len(vals):
  1709. raise Exception("Duplicate CCMP PN used")
  1710. if not ok:
  1711. raise Exception("The second hwsim connectivity test failed")
  1712. def test_ap_ft_psk_file(dev, apdev):
  1713. """WPA2-PSK-FT AP with PSK from a file"""
  1714. ssid = "test-ft"
  1715. passphrase="12345678"
  1716. params = ft_params1a(ssid=ssid, passphrase=passphrase)
  1717. params['wpa_psk_file'] = 'hostapd.wpa_psk'
  1718. hapd = hostapd.add_ap(apdev[0], params)
  1719. dev[1].connect(ssid, psk="very secret",
  1720. key_mgmt="FT-PSK", proto="WPA2", ieee80211w="1",
  1721. scan_freq="2412", wait_connect=False)
  1722. dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
  1723. ieee80211w="1", scan_freq="2412")
  1724. dev[0].request("REMOVE_NETWORK all")
  1725. dev[0].wait_disconnected()
  1726. dev[0].connect(ssid, psk="very secret", key_mgmt="FT-PSK", proto="WPA2",
  1727. ieee80211w="1", scan_freq="2412")
  1728. dev[0].request("REMOVE_NETWORK all")
  1729. dev[0].wait_disconnected()
  1730. dev[0].connect(ssid, psk="secret passphrase",
  1731. key_mgmt="FT-PSK", proto="WPA2", ieee80211w="1",
  1732. scan_freq="2412")
  1733. dev[2].connect(ssid, psk="another passphrase for all STAs",
  1734. key_mgmt="FT-PSK", proto="WPA2", ieee80211w="1",
  1735. scan_freq="2412")
  1736. ev = dev[1].wait_event(["WPA: 4-Way Handshake failed"], timeout=10)
  1737. if ev is None:
  1738. raise Exception("Timed out while waiting for failure report")
  1739. dev[1].request("REMOVE_NETWORK all")