test_ap_psk.py 33 KB

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