test_ap_psk.py 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977
  1. # WPA2-Personal tests
  2. # Copyright (c) 2014, Qualcomm Atheros, Inc.
  3. #
  4. # This software may be distributed under the terms of the BSD license.
  5. # See README for more details.
  6. import binascii
  7. import hashlib
  8. import hmac
  9. import logging
  10. logger = logging.getLogger()
  11. import os
  12. import re
  13. import struct
  14. import subprocess
  15. import time
  16. import hostapd
  17. import hwsim_utils
  18. def check_mib(dev, vals):
  19. mib = dev.get_mib()
  20. for v in vals:
  21. if mib[v[0]] != v[1]:
  22. raise Exception("Unexpected {} = {} (expected {})".format(v[0], mib[v[0]], v[1]))
  23. def test_ap_wpa2_psk(dev, apdev):
  24. """WPA2-PSK AP with PSK instead of passphrase"""
  25. ssid = "test-wpa2-psk"
  26. passphrase = 'qwertyuiop'
  27. psk = '602e323e077bc63bd80307ef4745b754b0ae0a925c2638ecd13a794b9527b9e6'
  28. params = hostapd.wpa2_params(ssid=ssid)
  29. params['wpa_psk'] = psk
  30. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  31. key_mgmt = hapd.get_config()['key_mgmt']
  32. if key_mgmt.split(' ')[0] != "WPA-PSK":
  33. raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
  34. dev[0].connect(ssid, raw_psk=psk, scan_freq="2412")
  35. dev[1].connect(ssid, psk=passphrase, scan_freq="2412")
  36. sig = dev[0].request("SIGNAL_POLL").splitlines()
  37. pkt = dev[0].request("PKTCNT_POLL").splitlines()
  38. if "FREQUENCY=2412" not in sig:
  39. raise Exception("Unexpected SIGNAL_POLL value: " + str(sig))
  40. if "TXBAD=0" not in pkt:
  41. raise Exception("Unexpected TXBAD value: " + str(pkt))
  42. def test_ap_wpa2_psk_file(dev, apdev):
  43. """WPA2-PSK AP with PSK from a file"""
  44. ssid = "test-wpa2-psk"
  45. passphrase = 'qwertyuiop'
  46. psk = '602e323e077bc63bd80307ef4745b754b0ae0a925c2638ecd13a794b9527b9e6'
  47. params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
  48. params['wpa_psk_file'] = 'hostapd.wpa_psk'
  49. hostapd.add_ap(apdev[0]['ifname'], params)
  50. dev[1].connect(ssid, psk="very secret", scan_freq="2412", wait_connect=False)
  51. dev[2].connect(ssid, raw_psk=psk, scan_freq="2412")
  52. dev[2].request("REMOVE_NETWORK all")
  53. dev[0].connect(ssid, psk="very secret", scan_freq="2412")
  54. dev[0].request("REMOVE_NETWORK all")
  55. dev[2].connect(ssid, psk="another passphrase for all STAs", scan_freq="2412")
  56. dev[0].connect(ssid, psk="another passphrase for all STAs", scan_freq="2412")
  57. ev = dev[1].wait_event(["WPA: 4-Way Handshake failed"], timeout=10)
  58. if ev is None:
  59. raise Exception("Timed out while waiting for failure report")
  60. dev[1].request("REMOVE_NETWORK all")
  61. def test_ap_wpa2_ptk_rekey(dev, apdev):
  62. """WPA2-PSK AP and PTK rekey enforced by station"""
  63. ssid = "test-wpa2-psk"
  64. passphrase = 'qwertyuiop'
  65. params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
  66. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  67. dev[0].connect(ssid, psk=passphrase, wpa_ptk_rekey="1", scan_freq="2412")
  68. ev = dev[0].wait_event(["WPA: Key negotiation completed"])
  69. if ev is None:
  70. raise Exception("PTK rekey timed out")
  71. hwsim_utils.test_connectivity(dev[0], hapd)
  72. def test_ap_wpa2_ptk_rekey_ap(dev, apdev):
  73. """WPA2-PSK AP and PTK rekey enforced by AP"""
  74. ssid = "test-wpa2-psk"
  75. passphrase = 'qwertyuiop'
  76. params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
  77. params['wpa_ptk_rekey'] = '2'
  78. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  79. dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
  80. ev = dev[0].wait_event(["WPA: Key negotiation completed"])
  81. if ev is None:
  82. raise Exception("PTK rekey timed out")
  83. hwsim_utils.test_connectivity(dev[0], hapd)
  84. def test_ap_wpa2_sha256_ptk_rekey(dev, apdev):
  85. """WPA2-PSK/SHA256 AKM AP and PTK rekey enforced by station"""
  86. ssid = "test-wpa2-psk"
  87. passphrase = 'qwertyuiop'
  88. params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
  89. params["wpa_key_mgmt"] = "WPA-PSK-SHA256"
  90. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  91. dev[0].connect(ssid, psk=passphrase, key_mgmt="WPA-PSK-SHA256",
  92. wpa_ptk_rekey="1", scan_freq="2412")
  93. ev = dev[0].wait_event(["WPA: Key negotiation completed"])
  94. if ev is None:
  95. raise Exception("PTK rekey timed out")
  96. hwsim_utils.test_connectivity(dev[0], hapd)
  97. check_mib(dev[0], [ ("dot11RSNAAuthenticationSuiteRequested", "00-0f-ac-6"),
  98. ("dot11RSNAAuthenticationSuiteSelected", "00-0f-ac-6") ])
  99. def test_ap_wpa2_sha256_ptk_rekey_ap(dev, apdev):
  100. """WPA2-PSK/SHA256 AKM AP and PTK rekey enforced by AP"""
  101. ssid = "test-wpa2-psk"
  102. passphrase = 'qwertyuiop'
  103. params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
  104. params["wpa_key_mgmt"] = "WPA-PSK-SHA256"
  105. params['wpa_ptk_rekey'] = '2'
  106. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  107. dev[0].connect(ssid, psk=passphrase, key_mgmt="WPA-PSK-SHA256",
  108. scan_freq="2412")
  109. ev = dev[0].wait_event(["WPA: Key negotiation completed"])
  110. if ev is None:
  111. raise Exception("PTK rekey timed out")
  112. hwsim_utils.test_connectivity(dev[0], hapd)
  113. check_mib(dev[0], [ ("dot11RSNAAuthenticationSuiteRequested", "00-0f-ac-6"),
  114. ("dot11RSNAAuthenticationSuiteSelected", "00-0f-ac-6") ])
  115. def test_ap_wpa_ptk_rekey(dev, apdev):
  116. """WPA-PSK/TKIP AP and PTK rekey enforced by station"""
  117. ssid = "test-wpa-psk"
  118. passphrase = 'qwertyuiop'
  119. params = hostapd.wpa_params(ssid=ssid, passphrase=passphrase)
  120. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  121. dev[0].connect(ssid, psk=passphrase, wpa_ptk_rekey="1", scan_freq="2412")
  122. if "[WPA-PSK-TKIP]" not in dev[0].request("SCAN_RESULTS"):
  123. raise Exception("Scan results missing WPA element info")
  124. ev = dev[0].wait_event(["WPA: Key negotiation completed"])
  125. if ev is None:
  126. raise Exception("PTK rekey timed out")
  127. hwsim_utils.test_connectivity(dev[0], hapd)
  128. def test_ap_wpa_ptk_rekey_ap(dev, apdev):
  129. """WPA-PSK/TKIP AP and PTK rekey enforced by AP"""
  130. ssid = "test-wpa-psk"
  131. passphrase = 'qwertyuiop'
  132. params = hostapd.wpa_params(ssid=ssid, passphrase=passphrase)
  133. params['wpa_ptk_rekey'] = '2'
  134. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  135. dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
  136. ev = dev[0].wait_event(["WPA: Key negotiation completed"], timeout=10)
  137. if ev is None:
  138. raise Exception("PTK rekey timed out")
  139. hwsim_utils.test_connectivity(dev[0], hapd)
  140. def test_ap_wpa_ccmp(dev, apdev):
  141. """WPA-PSK/CCMP"""
  142. ssid = "test-wpa-psk"
  143. passphrase = 'qwertyuiop'
  144. params = hostapd.wpa_params(ssid=ssid, passphrase=passphrase)
  145. params['wpa_pairwise'] = "CCMP"
  146. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  147. dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
  148. hwsim_utils.test_connectivity(dev[0], hapd)
  149. check_mib(dev[0], [ ("dot11RSNAConfigGroupCipherSize", "128"),
  150. ("dot11RSNAGroupCipherRequested", "00-50-f2-4"),
  151. ("dot11RSNAPairwiseCipherRequested", "00-50-f2-4"),
  152. ("dot11RSNAAuthenticationSuiteRequested", "00-50-f2-2"),
  153. ("dot11RSNAGroupCipherSelected", "00-50-f2-4"),
  154. ("dot11RSNAPairwiseCipherSelected", "00-50-f2-4"),
  155. ("dot11RSNAAuthenticationSuiteSelected", "00-50-f2-2"),
  156. ("dot1xSuppSuppControlledPortStatus", "Authorized") ])
  157. def test_ap_wpa2_psk_file(dev, apdev):
  158. """WPA2-PSK AP with various PSK file error and success cases"""
  159. addr0 = dev[0].p2p_dev_addr()
  160. addr1 = dev[1].p2p_dev_addr()
  161. addr2 = dev[2].p2p_dev_addr()
  162. ssid = "psk"
  163. pskfile = "/tmp/ap_wpa2_psk_file_errors.psk_file"
  164. try:
  165. os.remove(pskfile)
  166. except:
  167. pass
  168. params = { "ssid": ssid, "wpa": "2", "wpa_key_mgmt": "WPA-PSK",
  169. "rsn_pairwise": "CCMP", "wpa_psk_file": pskfile }
  170. try:
  171. # missing PSK file
  172. hapd = hostapd.add_ap(apdev[0]['ifname'], params, no_enable=True)
  173. if "FAIL" not in hapd.request("ENABLE"):
  174. raise Exception("Unexpected ENABLE success")
  175. hapd.request("DISABLE")
  176. # invalid MAC address
  177. with open(pskfile, "w") as f:
  178. f.write("\n")
  179. f.write("foo\n")
  180. if "FAIL" not in hapd.request("ENABLE"):
  181. raise Exception("Unexpected ENABLE success")
  182. hapd.request("DISABLE")
  183. # no PSK on line
  184. with open(pskfile, "w") as f:
  185. f.write("00:11:22:33:44:55\n")
  186. if "FAIL" not in hapd.request("ENABLE"):
  187. raise Exception("Unexpected ENABLE success")
  188. hapd.request("DISABLE")
  189. # invalid PSK
  190. with open(pskfile, "w") as f:
  191. f.write("00:11:22:33:44:55 1234567\n")
  192. if "FAIL" not in hapd.request("ENABLE"):
  193. raise Exception("Unexpected ENABLE success")
  194. hapd.request("DISABLE")
  195. # valid PSK file
  196. with open(pskfile, "w") as f:
  197. f.write("00:11:22:33:44:55 12345678\n")
  198. f.write(addr0 + " 123456789\n")
  199. f.write(addr1 + " 123456789a\n")
  200. f.write(addr2 + " 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\n")
  201. if "FAIL" in hapd.request("ENABLE"):
  202. raise Exception("Unexpected ENABLE failure")
  203. dev[0].connect(ssid, psk="123456789", scan_freq="2412")
  204. dev[1].connect(ssid, psk="123456789a", scan_freq="2412")
  205. dev[2].connect(ssid, raw_psk="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", scan_freq="2412")
  206. finally:
  207. try:
  208. os.remove(pskfile)
  209. except:
  210. pass
  211. def test_ap_wpa2_psk_wildcard_ssid(dev, apdev):
  212. """WPA2-PSK AP and wildcard SSID configuration"""
  213. ssid = "test-wpa2-psk"
  214. passphrase = 'qwertyuiop'
  215. psk = '602e323e077bc63bd80307ef4745b754b0ae0a925c2638ecd13a794b9527b9e6'
  216. params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
  217. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  218. dev[0].connect("", bssid=apdev[0]['bssid'], psk=passphrase,
  219. scan_freq="2412")
  220. dev[1].connect("", bssid=apdev[0]['bssid'], raw_psk=psk, scan_freq="2412")
  221. def test_ap_wpa2_gtk_rekey(dev, apdev):
  222. """WPA2-PSK AP and GTK rekey enforced by AP"""
  223. ssid = "test-wpa2-psk"
  224. passphrase = 'qwertyuiop'
  225. params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
  226. params['wpa_group_rekey'] = '1'
  227. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  228. dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
  229. ev = dev[0].wait_event(["WPA: Group rekeying completed"], timeout=2)
  230. if ev is None:
  231. raise Exception("GTK rekey timed out")
  232. hwsim_utils.test_connectivity(dev[0], hapd)
  233. def test_ap_wpa_gtk_rekey(dev, apdev):
  234. """WPA-PSK/TKIP AP and GTK rekey enforced by AP"""
  235. ssid = "test-wpa-psk"
  236. passphrase = 'qwertyuiop'
  237. params = hostapd.wpa_params(ssid=ssid, passphrase=passphrase)
  238. params['wpa_group_rekey'] = '1'
  239. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  240. dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
  241. ev = dev[0].wait_event(["WPA: Group rekeying completed"], timeout=2)
  242. if ev is None:
  243. raise Exception("GTK rekey timed out")
  244. hwsim_utils.test_connectivity(dev[0], hapd)
  245. def test_ap_wpa2_gmk_rekey(dev, apdev):
  246. """WPA2-PSK AP and GMK and GTK rekey enforced by AP"""
  247. ssid = "test-wpa2-psk"
  248. passphrase = 'qwertyuiop'
  249. params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
  250. params['wpa_group_rekey'] = '1'
  251. params['wpa_gmk_rekey'] = '2'
  252. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  253. dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
  254. for i in range(0, 3):
  255. ev = dev[0].wait_event(["WPA: Group rekeying completed"], timeout=2)
  256. if ev is None:
  257. raise Exception("GTK rekey timed out")
  258. hwsim_utils.test_connectivity(dev[0], hapd)
  259. def test_ap_wpa2_strict_rekey(dev, apdev):
  260. """WPA2-PSK AP and strict GTK rekey enforced by AP"""
  261. ssid = "test-wpa2-psk"
  262. passphrase = 'qwertyuiop'
  263. params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
  264. params['wpa_strict_rekey'] = '1'
  265. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  266. dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
  267. dev[1].connect(ssid, psk=passphrase, scan_freq="2412")
  268. dev[1].request("DISCONNECT")
  269. ev = dev[0].wait_event(["WPA: Group rekeying completed"], timeout=2)
  270. if ev is None:
  271. raise Exception("GTK rekey timed out")
  272. hwsim_utils.test_connectivity(dev[0], hapd)
  273. def test_ap_wpa2_bridge_fdb(dev, apdev):
  274. """Bridge FDB entry removal"""
  275. try:
  276. ssid = "test-wpa2-psk"
  277. passphrase = "12345678"
  278. params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
  279. params['bridge'] = 'ap-br0'
  280. hostapd.add_ap(apdev[0]['ifname'], params)
  281. subprocess.call(['sudo', 'brctl', 'setfd', 'ap-br0', '0'])
  282. subprocess.call(['sudo', 'ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
  283. dev[0].connect(ssid, psk=passphrase, scan_freq="2412",
  284. bssid=apdev[0]['bssid'])
  285. dev[1].connect(ssid, psk=passphrase, scan_freq="2412",
  286. bssid=apdev[0]['bssid'])
  287. addr0 = dev[0].p2p_interface_addr()
  288. hwsim_utils.test_connectivity_sta(dev[0], dev[1])
  289. cmd = subprocess.Popen(['brctl', 'showmacs', 'ap-br0'],
  290. stdout=subprocess.PIPE)
  291. macs1 = cmd.stdout.read()
  292. dev[0].request("DISCONNECT")
  293. dev[1].request("DISCONNECT")
  294. time.sleep(1)
  295. cmd = subprocess.Popen(['brctl', 'showmacs', 'ap-br0'],
  296. stdout=subprocess.PIPE)
  297. macs2 = cmd.stdout.read()
  298. addr1 = dev[1].p2p_interface_addr()
  299. if addr0 not in macs1 or addr1 not in macs1:
  300. raise Exception("Bridge FDB entry missing")
  301. if addr0 in macs2 or addr1 in macs2:
  302. raise Exception("Bridge FDB entry was not removed")
  303. finally:
  304. subprocess.call(['sudo', 'ip', 'link', 'set', 'dev', 'ap-br0', 'down'])
  305. subprocess.call(['sudo', 'brctl', 'delbr', 'ap-br0'])
  306. def test_ap_wpa2_already_in_bridge(dev, apdev):
  307. """hostapd behavior with interface already in bridge"""
  308. ifname = apdev[0]['ifname']
  309. br_ifname = 'ext-ap-br0'
  310. try:
  311. ssid = "test-wpa2-psk"
  312. passphrase = "12345678"
  313. subprocess.call(['brctl', 'addbr', br_ifname])
  314. subprocess.call(['brctl', 'setfd', br_ifname, '0'])
  315. subprocess.call(['ip', 'link', 'set', 'dev', br_ifname, 'up'])
  316. subprocess.call(['iw', ifname, 'set', 'type', '__ap'])
  317. subprocess.call(['brctl', 'addif', br_ifname, ifname])
  318. params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
  319. hapd = hostapd.add_ap(ifname, params)
  320. if hapd.get_driver_status_field('brname') != br_ifname:
  321. raise Exception("Bridge name not identified correctly")
  322. dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
  323. finally:
  324. subprocess.call(['ip', 'link', 'set', 'dev', br_ifname, 'down'])
  325. subprocess.call(['brctl', 'delif', br_ifname, ifname])
  326. subprocess.call(['iw', ifname, 'set', 'type', 'station'])
  327. subprocess.call(['brctl', 'delbr', br_ifname])
  328. def test_ap_wpa2_in_different_bridge(dev, apdev):
  329. """hostapd behavior with interface in different bridge"""
  330. ifname = apdev[0]['ifname']
  331. br_ifname = 'ext-ap-br0'
  332. try:
  333. ssid = "test-wpa2-psk"
  334. passphrase = "12345678"
  335. subprocess.call(['brctl', 'addbr', br_ifname])
  336. subprocess.call(['brctl', 'setfd', br_ifname, '0'])
  337. subprocess.call(['ip', 'link', 'set', 'dev', br_ifname, 'up'])
  338. subprocess.call(['iw', ifname, 'set', 'type', '__ap'])
  339. subprocess.call(['brctl', 'addif', br_ifname, ifname])
  340. time.sleep(0.5)
  341. params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
  342. params['bridge'] = 'ap-br0'
  343. hapd = hostapd.add_ap(ifname, params)
  344. subprocess.call(['brctl', 'setfd', 'ap-br0', '0'])
  345. subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
  346. brname = hapd.get_driver_status_field('brname')
  347. if brname != 'ap-br0':
  348. raise Exception("Incorrect bridge: " + brname)
  349. dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
  350. hwsim_utils.test_connectivity_iface(dev[0], hapd, "ap-br0")
  351. if hapd.get_driver_status_field("added_bridge") != "1":
  352. raise Exception("Unexpected added_bridge value")
  353. if hapd.get_driver_status_field("added_if_into_bridge") != "1":
  354. raise Exception("Unexpected added_if_into_bridge value")
  355. dev[0].request("DISCONNECT")
  356. hapd.disable()
  357. finally:
  358. subprocess.call(['ip', 'link', 'set', 'dev', br_ifname, 'down'])
  359. subprocess.call(['brctl', 'delif', br_ifname, ifname],
  360. stderr=open('/dev/null', 'w'))
  361. subprocess.call(['brctl', 'delbr', br_ifname])
  362. def test_ap_wpa2_ext_add_to_bridge(dev, apdev):
  363. """hostapd behavior with interface added to bridge externally"""
  364. ifname = apdev[0]['ifname']
  365. br_ifname = 'ext-ap-br0'
  366. try:
  367. ssid = "test-wpa2-psk"
  368. passphrase = "12345678"
  369. params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
  370. hapd = hostapd.add_ap(ifname, params)
  371. subprocess.call(['brctl', 'addbr', br_ifname])
  372. subprocess.call(['brctl', 'setfd', br_ifname, '0'])
  373. subprocess.call(['ip', 'link', 'set', 'dev', br_ifname, 'up'])
  374. subprocess.call(['brctl', 'addif', br_ifname, ifname])
  375. dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
  376. if hapd.get_driver_status_field('brname') != br_ifname:
  377. raise Exception("Bridge name not identified correctly")
  378. finally:
  379. subprocess.call(['ip', 'link', 'set', 'dev', br_ifname, 'down'])
  380. subprocess.call(['brctl', 'delif', br_ifname, ifname])
  381. subprocess.call(['brctl', 'delbr', br_ifname])
  382. def test_ap_wpa2_psk_ext(dev, apdev):
  383. """WPA2-PSK AP using external EAPOL I/O"""
  384. bssid = apdev[0]['bssid']
  385. ssid = "test-wpa2-psk"
  386. passphrase = 'qwertyuiop'
  387. psk = '602e323e077bc63bd80307ef4745b754b0ae0a925c2638ecd13a794b9527b9e6'
  388. params = hostapd.wpa2_params(ssid=ssid)
  389. params['wpa_psk'] = psk
  390. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  391. hapd.request("SET ext_eapol_frame_io 1")
  392. dev[0].request("SET ext_eapol_frame_io 1")
  393. dev[0].connect(ssid, psk=passphrase, scan_freq="2412", wait_connect=False)
  394. addr = dev[0].p2p_interface_addr()
  395. while True:
  396. ev = hapd.wait_event(["EAPOL-TX", "AP-STA-CONNECTED"], timeout=15)
  397. if ev is None:
  398. raise Exception("Timeout on EAPOL-TX from hostapd")
  399. if "AP-STA-CONNECTED" in ev:
  400. dev[0].wait_connected(timeout=15)
  401. break
  402. res = dev[0].request("EAPOL_RX " + bssid + " " + ev.split(' ')[2])
  403. if "OK" not in res:
  404. raise Exception("EAPOL_RX to wpa_supplicant failed")
  405. ev = dev[0].wait_event(["EAPOL-TX", "CTRL-EVENT-CONNECTED"], timeout=15)
  406. if ev is None:
  407. raise Exception("Timeout on EAPOL-TX from wpa_supplicant")
  408. if "CTRL-EVENT-CONNECTED" in ev:
  409. break
  410. res = hapd.request("EAPOL_RX " + addr + " " + ev.split(' ')[2])
  411. if "OK" not in res:
  412. raise Exception("EAPOL_RX to hostapd failed")
  413. def parse_eapol(data):
  414. (version, type, length) = struct.unpack('>BBH', data[0:4])
  415. payload = data[4:]
  416. if length > len(payload):
  417. raise Exception("Invalid EAPOL length")
  418. if length < len(payload):
  419. payload = payload[0:length]
  420. eapol = {}
  421. eapol['version'] = version
  422. eapol['type'] = type
  423. eapol['length'] = length
  424. eapol['payload'] = payload
  425. if type == 3:
  426. # EAPOL-Key
  427. (eapol['descr_type'],) = struct.unpack('B', payload[0:1])
  428. payload = payload[1:]
  429. if eapol['descr_type'] == 2 or eapol['descr_type'] == 254:
  430. # RSN EAPOL-Key
  431. (key_info, key_len) = struct.unpack('>HH', payload[0:4])
  432. eapol['rsn_key_info'] = key_info
  433. eapol['rsn_key_len'] = key_len
  434. eapol['rsn_replay_counter'] = payload[4:12]
  435. eapol['rsn_key_nonce'] = payload[12:44]
  436. eapol['rsn_key_iv'] = payload[44:60]
  437. eapol['rsn_key_rsc'] = payload[60:68]
  438. eapol['rsn_key_id'] = payload[68:76]
  439. eapol['rsn_key_mic'] = payload[76:92]
  440. payload = payload[92:]
  441. (eapol['rsn_key_data_len'],) = struct.unpack('>H', payload[0:2])
  442. payload = payload[2:]
  443. eapol['rsn_key_data'] = payload
  444. return eapol
  445. def build_eapol(msg):
  446. data = struct.pack(">BBH", msg['version'], msg['type'], msg['length'])
  447. if msg['type'] == 3:
  448. data += struct.pack('>BHH', msg['descr_type'], msg['rsn_key_info'],
  449. msg['rsn_key_len'])
  450. data += msg['rsn_replay_counter']
  451. data += msg['rsn_key_nonce']
  452. data += msg['rsn_key_iv']
  453. data += msg['rsn_key_rsc']
  454. data += msg['rsn_key_id']
  455. data += msg['rsn_key_mic']
  456. data += struct.pack('>H', msg['rsn_key_data_len'])
  457. data += msg['rsn_key_data']
  458. else:
  459. data += msg['payload']
  460. return data
  461. def sha1_prf(key, label, data, outlen):
  462. res = ''
  463. counter = 0
  464. while outlen > 0:
  465. m = hmac.new(key, label, hashlib.sha1)
  466. m.update(struct.pack('B', 0))
  467. m.update(data)
  468. m.update(struct.pack('B', counter))
  469. counter += 1
  470. hash = m.digest()
  471. if outlen > len(hash):
  472. res += hash
  473. outlen -= len(hash)
  474. else:
  475. res += hash[0:outlen]
  476. outlen = 0
  477. return res
  478. def pmk_to_ptk(pmk, addr1, addr2, nonce1, nonce2):
  479. if addr1 < addr2:
  480. data = binascii.unhexlify(addr1.replace(':','')) + binascii.unhexlify(addr2.replace(':',''))
  481. else:
  482. data = binascii.unhexlify(addr2.replace(':','')) + binascii.unhexlify(addr1.replace(':',''))
  483. if nonce1 < nonce2:
  484. data += nonce1 + nonce2
  485. else:
  486. data += nonce2 + nonce1
  487. label = "Pairwise key expansion"
  488. ptk = sha1_prf(pmk, label, data, 48)
  489. kck = ptk[0:16]
  490. kek = ptk[16:32]
  491. return (ptk, kck, kek)
  492. def eapol_key_mic(kck, msg):
  493. msg['rsn_key_mic'] = binascii.unhexlify('00000000000000000000000000000000')
  494. data = build_eapol(msg)
  495. m = hmac.new(kck, data, hashlib.sha1)
  496. msg['rsn_key_mic'] = m.digest()[0:16]
  497. def rsn_eapol_key_set(msg, key_info, key_len, nonce, data):
  498. msg['rsn_key_info'] = key_info
  499. msg['rsn_key_len'] = key_len
  500. if nonce:
  501. msg['rsn_key_nonce'] = nonce
  502. else:
  503. msg['rsn_key_nonce'] = binascii.unhexlify('0000000000000000000000000000000000000000000000000000000000000000')
  504. if data:
  505. msg['rsn_key_data_len'] = len(data)
  506. msg['rsn_key_data'] = data
  507. msg['length'] = 95 + len(data)
  508. else:
  509. msg['rsn_key_data_len'] = 0
  510. msg['rsn_key_data'] = ''
  511. msg['length'] = 95
  512. def recv_eapol(hapd):
  513. ev = hapd.wait_event(["EAPOL-TX"], timeout=15)
  514. if ev is None:
  515. raise Exception("Timeout on EAPOL-TX from hostapd")
  516. eapol = binascii.unhexlify(ev.split(' ')[2])
  517. return parse_eapol(eapol)
  518. def send_eapol(hapd, addr, data):
  519. res = hapd.request("EAPOL_RX " + addr + " " + binascii.hexlify(data))
  520. if "OK" not in res:
  521. raise Exception("EAPOL_RX to hostapd failed")
  522. def reply_eapol(info, hapd, addr, msg, key_info, nonce, data, kck):
  523. logger.info("Send EAPOL-Key msg " + info)
  524. rsn_eapol_key_set(msg, key_info, 0, nonce, data)
  525. eapol_key_mic(kck, msg)
  526. send_eapol(hapd, addr, build_eapol(msg))
  527. def hapd_connected(hapd):
  528. ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=15)
  529. if ev is None:
  530. raise Exception("Timeout on AP-STA-CONNECTED from hostapd")
  531. def eapol_test(apdev, dev, wpa2=True):
  532. bssid = apdev['bssid']
  533. if wpa2:
  534. ssid = "test-wpa2-psk"
  535. else:
  536. ssid = "test-wpa-psk"
  537. psk = '602e323e077bc63bd80307ef4745b754b0ae0a925c2638ecd13a794b9527b9e6'
  538. pmk = binascii.unhexlify(psk)
  539. if wpa2:
  540. params = hostapd.wpa2_params(ssid=ssid)
  541. else:
  542. params = hostapd.wpa_params(ssid=ssid)
  543. params['wpa_psk'] = psk
  544. hapd = hostapd.add_ap(apdev['ifname'], params)
  545. hapd.request("SET ext_eapol_frame_io 1")
  546. dev.request("SET ext_eapol_frame_io 1")
  547. dev.connect(ssid, psk="not used", scan_freq="2412", wait_connect=False)
  548. addr = dev.p2p_interface_addr()
  549. if wpa2:
  550. rsne = binascii.unhexlify('30140100000fac040100000fac040100000fac020000')
  551. else:
  552. rsne = binascii.unhexlify('dd160050f20101000050f20201000050f20201000050f202')
  553. snonce = binascii.unhexlify('1111111111111111111111111111111111111111111111111111111111111111')
  554. return (bssid,ssid,hapd,snonce,pmk,addr,rsne)
  555. def test_ap_wpa2_psk_ext_eapol(dev, apdev):
  556. """WPA2-PSK AP using external EAPOL supplicant"""
  557. (bssid,ssid,hapd,snonce,pmk,addr,rsne) = eapol_test(apdev[0], dev[0])
  558. msg = recv_eapol(hapd)
  559. anonce = msg['rsn_key_nonce']
  560. logger.info("Replay same data back")
  561. send_eapol(hapd, addr, build_eapol(msg))
  562. (ptk, kck, kek) = pmk_to_ptk(pmk, addr, bssid, snonce, anonce)
  563. logger.info("Truncated Key Data in EAPOL-Key msg 2/4")
  564. rsn_eapol_key_set(msg, 0x0101, 0, snonce, rsne)
  565. msg['length'] = 95 + 22 - 1
  566. send_eapol(hapd, addr, build_eapol(msg))
  567. reply_eapol("2/4", hapd, addr, msg, 0x010a, snonce, rsne, kck)
  568. msg = recv_eapol(hapd)
  569. if anonce != msg['rsn_key_nonce']:
  570. raise Exception("ANonce changed")
  571. logger.info("Replay same data back")
  572. send_eapol(hapd, addr, build_eapol(msg))
  573. reply_eapol("4/4", hapd, addr, msg, 0x030a, None, None, kck)
  574. hapd_connected(hapd)
  575. def test_ap_wpa2_psk_ext_eapol_retry1(dev, apdev):
  576. """WPA2 4-way handshake with EAPOL-Key 1/4 retransmitted"""
  577. (bssid,ssid,hapd,snonce,pmk,addr,rsne) = eapol_test(apdev[0], dev[0])
  578. msg1 = recv_eapol(hapd)
  579. anonce = msg1['rsn_key_nonce']
  580. msg2 = recv_eapol(hapd)
  581. if anonce != msg2['rsn_key_nonce']:
  582. raise Exception("ANonce changed")
  583. (ptk, kck, kek) = pmk_to_ptk(pmk, addr, bssid, snonce, anonce)
  584. logger.info("Send EAPOL-Key msg 2/4")
  585. msg = msg2
  586. rsn_eapol_key_set(msg, 0x010a, 0, snonce, rsne)
  587. eapol_key_mic(kck, msg)
  588. send_eapol(hapd, addr, build_eapol(msg))
  589. msg = recv_eapol(hapd)
  590. if anonce != msg['rsn_key_nonce']:
  591. raise Exception("ANonce changed")
  592. reply_eapol("4/4", hapd, addr, msg, 0x030a, None, None, kck)
  593. hapd_connected(hapd)
  594. def test_ap_wpa2_psk_ext_eapol_retry1b(dev, apdev):
  595. """WPA2 4-way handshake with EAPOL-Key 1/4 and 2/4 retransmitted"""
  596. (bssid,ssid,hapd,snonce,pmk,addr,rsne) = eapol_test(apdev[0], dev[0])
  597. msg1 = recv_eapol(hapd)
  598. anonce = msg1['rsn_key_nonce']
  599. msg2 = recv_eapol(hapd)
  600. if anonce != msg2['rsn_key_nonce']:
  601. raise Exception("ANonce changed")
  602. (ptk, kck, kek) = pmk_to_ptk(pmk, addr, bssid, snonce, anonce)
  603. reply_eapol("2/4 (a)", hapd, addr, msg1, 0x010a, snonce, rsne, kck)
  604. reply_eapol("2/4 (b)", hapd, addr, msg2, 0x010a, snonce, rsne, kck)
  605. msg = recv_eapol(hapd)
  606. if anonce != msg['rsn_key_nonce']:
  607. raise Exception("ANonce changed")
  608. reply_eapol("4/4", hapd, addr, msg, 0x030a, None, None, kck)
  609. hapd_connected(hapd)
  610. def test_ap_wpa2_psk_ext_eapol_retry1c(dev, apdev):
  611. """WPA2 4-way handshake with EAPOL-Key 1/4 and 2/4 retransmitted and SNonce changing"""
  612. (bssid,ssid,hapd,snonce,pmk,addr,rsne) = eapol_test(apdev[0], dev[0])
  613. msg1 = recv_eapol(hapd)
  614. anonce = msg1['rsn_key_nonce']
  615. msg2 = recv_eapol(hapd)
  616. if anonce != msg2['rsn_key_nonce']:
  617. raise Exception("ANonce changed")
  618. (ptk, kck, kek) = pmk_to_ptk(pmk, addr, bssid, snonce, anonce)
  619. reply_eapol("2/4 (a)", hapd, addr, msg1, 0x010a, snonce, rsne, kck)
  620. snonce2 = binascii.unhexlify('2222222222222222222222222222222222222222222222222222222222222222')
  621. (ptk, kck, kek) = pmk_to_ptk(pmk, addr, bssid, snonce2, anonce)
  622. reply_eapol("2/4 (b)", hapd, addr, msg2, 0x010a, snonce2, rsne, kck)
  623. msg = recv_eapol(hapd)
  624. if anonce != msg['rsn_key_nonce']:
  625. raise Exception("ANonce changed")
  626. reply_eapol("4/4", hapd, addr, msg, 0x030a, None, None, kck)
  627. hapd_connected(hapd)
  628. def test_ap_wpa2_psk_ext_eapol_retry1d(dev, apdev):
  629. """WPA2 4-way handshake with EAPOL-Key 1/4 and 2/4 retransmitted and SNonce changing and older used"""
  630. (bssid,ssid,hapd,snonce,pmk,addr,rsne) = eapol_test(apdev[0], dev[0])
  631. msg1 = recv_eapol(hapd)
  632. anonce = msg1['rsn_key_nonce']
  633. msg2 = recv_eapol(hapd)
  634. if anonce != msg2['rsn_key_nonce']:
  635. raise Exception("ANonce changed")
  636. (ptk, kck, kek) = pmk_to_ptk(pmk, addr, bssid, snonce, anonce)
  637. reply_eapol("2/4 (a)", hapd, addr, msg1, 0x010a, snonce, rsne, kck)
  638. snonce2 = binascii.unhexlify('2222222222222222222222222222222222222222222222222222222222222222')
  639. (ptk2, kck2, kek2) = pmk_to_ptk(pmk, addr, bssid, snonce2, anonce)
  640. reply_eapol("2/4 (b)", hapd, addr, msg2, 0x010a, snonce2, rsne, kck2)
  641. msg = recv_eapol(hapd)
  642. if anonce != msg['rsn_key_nonce']:
  643. raise Exception("ANonce changed")
  644. reply_eapol("4/4", hapd, addr, msg, 0x030a, None, None, kck)
  645. hapd_connected(hapd)
  646. def test_ap_wpa2_psk_ext_eapol_type_diff(dev, apdev):
  647. """WPA2 4-way handshake using external EAPOL supplicant"""
  648. (bssid,ssid,hapd,snonce,pmk,addr,rsne) = eapol_test(apdev[0], dev[0])
  649. msg = recv_eapol(hapd)
  650. anonce = msg['rsn_key_nonce']
  651. (ptk, kck, kek) = pmk_to_ptk(pmk, addr, bssid, snonce, anonce)
  652. # Incorrect descriptor type (frame dropped)
  653. msg['descr_type'] = 253
  654. rsn_eapol_key_set(msg, 0x010a, 0, snonce, rsne)
  655. eapol_key_mic(kck, msg)
  656. send_eapol(hapd, addr, build_eapol(msg))
  657. # Incorrect descriptor type, but with a workaround (frame processed)
  658. msg['descr_type'] = 254
  659. rsn_eapol_key_set(msg, 0x010a, 0, snonce, rsne)
  660. eapol_key_mic(kck, msg)
  661. send_eapol(hapd, addr, build_eapol(msg))
  662. msg = recv_eapol(hapd)
  663. if anonce != msg['rsn_key_nonce']:
  664. raise Exception("ANonce changed")
  665. logger.info("Replay same data back")
  666. send_eapol(hapd, addr, build_eapol(msg))
  667. reply_eapol("4/4", hapd, addr, msg, 0x030a, None, None, kck)
  668. hapd_connected(hapd)
  669. def test_ap_wpa_psk_ext_eapol(dev, apdev):
  670. """WPA2-PSK AP using external EAPOL supplicant"""
  671. (bssid,ssid,hapd,snonce,pmk,addr,wpae) = eapol_test(apdev[0], dev[0],
  672. wpa2=False)
  673. msg = recv_eapol(hapd)
  674. anonce = msg['rsn_key_nonce']
  675. logger.info("Replay same data back")
  676. send_eapol(hapd, addr, build_eapol(msg))
  677. logger.info("Too short data")
  678. send_eapol(hapd, addr, build_eapol(msg)[0:98])
  679. (ptk, kck, kek) = pmk_to_ptk(pmk, addr, bssid, snonce, anonce)
  680. msg['descr_type'] = 2
  681. reply_eapol("2/4(invalid type)", hapd, addr, msg, 0x010a, snonce, wpae, kck)
  682. msg['descr_type'] = 254
  683. reply_eapol("2/4", hapd, addr, msg, 0x010a, snonce, wpae, kck)
  684. msg = recv_eapol(hapd)
  685. if anonce != msg['rsn_key_nonce']:
  686. raise Exception("ANonce changed")
  687. logger.info("Replay same data back")
  688. send_eapol(hapd, addr, build_eapol(msg))
  689. reply_eapol("4/4", hapd, addr, msg, 0x030a, None, None, kck)
  690. hapd_connected(hapd)
  691. def test_ap_wpa2_psk_ext_eapol_key_info(dev, apdev):
  692. """WPA2-PSK 4-way handshake with strange key info values"""
  693. (bssid,ssid,hapd,snonce,pmk,addr,rsne) = eapol_test(apdev[0], dev[0])
  694. msg = recv_eapol(hapd)
  695. anonce = msg['rsn_key_nonce']
  696. (ptk, kck, kek) = pmk_to_ptk(pmk, addr, bssid, snonce, anonce)
  697. rsn_eapol_key_set(msg, 0x0000, 0, snonce, rsne)
  698. send_eapol(hapd, addr, build_eapol(msg))
  699. rsn_eapol_key_set(msg, 0xffff, 0, snonce, rsne)
  700. send_eapol(hapd, addr, build_eapol(msg))
  701. # SMK M1
  702. rsn_eapol_key_set(msg, 0x2802, 0, snonce, rsne)
  703. send_eapol(hapd, addr, build_eapol(msg))
  704. # SMK M3
  705. rsn_eapol_key_set(msg, 0x2002, 0, snonce, rsne)
  706. send_eapol(hapd, addr, build_eapol(msg))
  707. # Request
  708. rsn_eapol_key_set(msg, 0x0902, 0, snonce, rsne)
  709. send_eapol(hapd, addr, build_eapol(msg))
  710. # Request
  711. rsn_eapol_key_set(msg, 0x0902, 0, snonce, rsne)
  712. tmp_kck = binascii.unhexlify('00000000000000000000000000000000')
  713. eapol_key_mic(tmp_kck, msg)
  714. send_eapol(hapd, addr, build_eapol(msg))
  715. reply_eapol("2/4", hapd, addr, msg, 0x010a, snonce, rsne, kck)
  716. msg = recv_eapol(hapd)
  717. if anonce != msg['rsn_key_nonce']:
  718. raise Exception("ANonce changed")
  719. # Request (valic MIC)
  720. rsn_eapol_key_set(msg, 0x0902, 0, snonce, rsne)
  721. eapol_key_mic(kck, msg)
  722. send_eapol(hapd, addr, build_eapol(msg))
  723. # Request (valid MIC, replayed counter)
  724. rsn_eapol_key_set(msg, 0x0902, 0, snonce, rsne)
  725. eapol_key_mic(kck, msg)
  726. send_eapol(hapd, addr, build_eapol(msg))
  727. reply_eapol("4/4", hapd, addr, msg, 0x030a, None, None, kck)
  728. hapd_connected(hapd)
  729. def find_wpas_process(dev):
  730. ifname = dev.ifname
  731. cmd = subprocess.Popen(['ps', 'ax'], stdout=subprocess.PIPE)
  732. (data,err) = cmd.communicate()
  733. for l in data.splitlines():
  734. if "wpa_supplicant" not in l:
  735. continue
  736. if "-i" + ifname not in l:
  737. continue
  738. return int(l.strip().split(' ')[0])
  739. raise Exception("Could not find wpa_supplicant process")
  740. def read_process_memory(pid, key=None):
  741. buf = bytes()
  742. with open('/proc/%d/maps' % pid, 'r') as maps, \
  743. open('/proc/%d/mem' % pid, 'r') as mem:
  744. for l in maps.readlines():
  745. m = re.match(r'([0-9a-f]+)-([0-9a-f]+) ([-r][-w][-x][-p])', l)
  746. if not m:
  747. continue
  748. start = int(m.group(1), 16)
  749. end = int(m.group(2), 16)
  750. perm = m.group(3)
  751. if start > 0xffffffffffff:
  752. continue
  753. if end < start:
  754. continue
  755. if not perm.startswith('rw'):
  756. continue
  757. mem.seek(start)
  758. data = mem.read(end - start)
  759. buf += data
  760. if key and key in data:
  761. logger.info("Key found in " + l)
  762. return buf
  763. def verify_not_present(buf, key, fname, keyname):
  764. pos = buf.find(key)
  765. if pos < 0:
  766. return
  767. prefix = 2048 if pos > 2048 else pos
  768. with open(fname + keyname, 'w') as f:
  769. f.write(buf[pos - prefix:pos + 2048])
  770. raise Exception(keyname + " found after disassociation")
  771. def get_key_locations(buf, key, keyname):
  772. count = 0
  773. pos = 0
  774. while True:
  775. pos = buf.find(key, pos)
  776. if pos < 0:
  777. break
  778. logger.info("Found %s at %d" % (keyname, pos))
  779. count += 1
  780. pos += len(key)
  781. return count
  782. def test_wpa2_psk_key_lifetime_in_memory(dev, apdev, params):
  783. """WPA2-PSK and PSK/PTK lifetime in memory"""
  784. ssid = "test-wpa2-psk"
  785. passphrase = 'qwertyuiop'
  786. psk = '602e323e077bc63bd80307ef4745b754b0ae0a925c2638ecd13a794b9527b9e6'
  787. pmk = binascii.unhexlify(psk)
  788. p = hostapd.wpa2_params(ssid=ssid)
  789. p['wpa_psk'] = psk
  790. hapd = hostapd.add_ap(apdev[0]['ifname'], p)
  791. pid = find_wpas_process(dev[0])
  792. id = dev[0].connect(ssid, raw_psk=psk, scan_freq="2412",
  793. only_add_network=True)
  794. logger.info("Checking keys in memory after network profile configuration")
  795. buf = read_process_memory(pid, pmk)
  796. get_key_locations(buf, pmk, "PMK")
  797. dev[0].request("REMOVE_NETWORK all")
  798. logger.info("Checking keys in memory after network profile removal")
  799. buf = read_process_memory(pid, pmk)
  800. get_key_locations(buf, pmk, "PMK")
  801. id = dev[0].connect(ssid, psk=passphrase, scan_freq="2412",
  802. only_add_network=True)
  803. logger.info("Checking keys in memory before connection")
  804. buf = read_process_memory(pid, pmk)
  805. get_key_locations(buf, pmk, "PMK")
  806. dev[0].connect_network(id, timeout=20)
  807. time.sleep(0.1)
  808. buf = read_process_memory(pid, pmk)
  809. dev[0].request("DISCONNECT")
  810. dev[0].wait_disconnected()
  811. dev[0].relog()
  812. ptk = None
  813. gtk = None
  814. with open(os.path.join(params['logdir'], 'log0'), 'r') as f:
  815. for l in f.readlines():
  816. if "WPA: PTK - hexdump" in l:
  817. val = l.strip().split(':')[3].replace(' ', '')
  818. ptk = binascii.unhexlify(val)
  819. if "WPA: Group Key - hexdump" in l:
  820. val = l.strip().split(':')[3].replace(' ', '')
  821. gtk = binascii.unhexlify(val)
  822. if not pmk or not ptk or not gtk:
  823. raise Exception("Could not find keys from debug log")
  824. if len(gtk) != 16:
  825. raise Exception("Unexpected GTK length")
  826. kck = ptk[0:16]
  827. kek = ptk[16:32]
  828. tk = ptk[32:48]
  829. logger.info("Checking keys in memory while associated")
  830. get_key_locations(buf, pmk, "PMK")
  831. if pmk not in buf:
  832. print("PMK not found while associated")
  833. return "skip"
  834. if kck not in buf:
  835. raise Exception("KCK not found while associated")
  836. if kek not in buf:
  837. raise Exception("KEK not found while associated")
  838. if tk in buf:
  839. raise Exception("TK found from memory")
  840. if gtk in buf:
  841. raise Exception("GTK found from memory")
  842. logger.info("Checking keys in memory after disassociation")
  843. buf = read_process_memory(pid, pmk)
  844. get_key_locations(buf, pmk, "PMK")
  845. # Note: PMK/PSK is still present in network configuration
  846. fname = os.path.join(params['logdir'],
  847. 'wpa2_psk_key_lifetime_in_memory.memctx-')
  848. verify_not_present(buf, kck, fname, "KCK")
  849. verify_not_present(buf, kek, fname, "KEK")
  850. verify_not_present(buf, tk, fname, "TK")
  851. verify_not_present(buf, gtk, fname, "GTK")
  852. dev[0].request("REMOVE_NETWORK all")
  853. logger.info("Checking keys in memory after network profile removal")
  854. buf = read_process_memory(pid, pmk)
  855. get_key_locations(buf, pmk, "PMK")
  856. verify_not_present(buf, pmk, fname, "PMK")
  857. verify_not_present(buf, kck, fname, "KCK")
  858. verify_not_present(buf, kek, fname, "KEK")
  859. verify_not_present(buf, tk, fname, "TK")
  860. verify_not_present(buf, gtk, fname, "GTK")