test_sae.py 53 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225
  1. # Test cases for SAE
  2. # Copyright (c) 2013-2016, 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 hwsim_utils
  13. import hostapd
  14. from wpasupplicant import WpaSupplicant
  15. from utils import HwsimSkip, alloc_fail, fail_test, wait_fail_trigger
  16. from test_ap_psk import find_wpas_process, read_process_memory, verify_not_present, get_key_locations
  17. @remote_compatible
  18. def test_sae(dev, apdev):
  19. """SAE with default group"""
  20. if "SAE" not in dev[0].get_capability("auth_alg"):
  21. raise HwsimSkip("SAE not supported")
  22. params = hostapd.wpa2_params(ssid="test-sae",
  23. passphrase="12345678")
  24. params['wpa_key_mgmt'] = 'SAE'
  25. hapd = hostapd.add_ap(apdev[0], params)
  26. key_mgmt = hapd.get_config()['key_mgmt']
  27. if key_mgmt.split(' ')[0] != "SAE":
  28. raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
  29. dev[0].request("SET sae_groups ")
  30. id = dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
  31. scan_freq="2412")
  32. if dev[0].get_status_field('sae_group') != '19':
  33. raise Exception("Expected default SAE group not used")
  34. bss = dev[0].get_bss(apdev[0]['bssid'])
  35. if 'flags' not in bss:
  36. raise Exception("Could not get BSS flags from BSS table")
  37. if "[WPA2-SAE-CCMP]" not in bss['flags']:
  38. raise Exception("Unexpected BSS flags: " + bss['flags'])
  39. res = hapd.request("STA-FIRST")
  40. if "sae_group=19" not in res.splitlines():
  41. raise Exception("hostapd STA output did not specify SAE group")
  42. @remote_compatible
  43. def test_sae_password_ecc(dev, apdev):
  44. """SAE with number of different passwords (ECC)"""
  45. if "SAE" not in dev[0].get_capability("auth_alg"):
  46. raise HwsimSkip("SAE not supported")
  47. params = hostapd.wpa2_params(ssid="test-sae",
  48. passphrase="12345678")
  49. params['wpa_key_mgmt'] = 'SAE'
  50. hapd = hostapd.add_ap(apdev[0], params)
  51. dev[0].request("SET sae_groups 19")
  52. for i in range(10):
  53. password = "12345678-" + str(i)
  54. hapd.set("wpa_passphrase", password)
  55. dev[0].connect("test-sae", psk=password, key_mgmt="SAE",
  56. scan_freq="2412")
  57. dev[0].request("REMOVE_NETWORK all")
  58. dev[0].wait_disconnected()
  59. @remote_compatible
  60. def test_sae_password_ffc(dev, apdev):
  61. """SAE with number of different passwords (FFC)"""
  62. if "SAE" not in dev[0].get_capability("auth_alg"):
  63. raise HwsimSkip("SAE not supported")
  64. params = hostapd.wpa2_params(ssid="test-sae",
  65. passphrase="12345678")
  66. params['wpa_key_mgmt'] = 'SAE'
  67. params['sae_groups'] = '22'
  68. hapd = hostapd.add_ap(apdev[0], params)
  69. dev[0].request("SET sae_groups 22")
  70. for i in range(10):
  71. password = "12345678-" + str(i)
  72. hapd.set("wpa_passphrase", password)
  73. dev[0].connect("test-sae", psk=password, key_mgmt="SAE",
  74. scan_freq="2412")
  75. dev[0].request("REMOVE_NETWORK all")
  76. dev[0].wait_disconnected()
  77. @remote_compatible
  78. def test_sae_pmksa_caching(dev, apdev):
  79. """SAE and PMKSA caching"""
  80. if "SAE" not in dev[0].get_capability("auth_alg"):
  81. raise HwsimSkip("SAE not supported")
  82. params = hostapd.wpa2_params(ssid="test-sae",
  83. passphrase="12345678")
  84. params['wpa_key_mgmt'] = 'SAE'
  85. hapd = hostapd.add_ap(apdev[0], params)
  86. dev[0].request("SET sae_groups ")
  87. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
  88. scan_freq="2412")
  89. ev = hapd.wait_event([ "AP-STA-CONNECTED" ], timeout=5)
  90. if ev is None:
  91. raise Exception("No connection event received from hostapd")
  92. dev[0].request("DISCONNECT")
  93. dev[0].wait_disconnected()
  94. dev[0].request("RECONNECT")
  95. dev[0].wait_connected(timeout=15, error="Reconnect timed out")
  96. if dev[0].get_status_field('sae_group') is not None:
  97. raise Exception("SAE group claimed to have been used")
  98. @remote_compatible
  99. def test_sae_pmksa_caching_disabled(dev, apdev):
  100. """SAE and PMKSA caching disabled"""
  101. if "SAE" not in dev[0].get_capability("auth_alg"):
  102. raise HwsimSkip("SAE not supported")
  103. params = hostapd.wpa2_params(ssid="test-sae",
  104. passphrase="12345678")
  105. params['wpa_key_mgmt'] = 'SAE'
  106. params['disable_pmksa_caching'] = '1'
  107. hapd = hostapd.add_ap(apdev[0], params)
  108. dev[0].request("SET sae_groups ")
  109. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
  110. scan_freq="2412")
  111. ev = hapd.wait_event([ "AP-STA-CONNECTED" ], timeout=5)
  112. if ev is None:
  113. raise Exception("No connection event received from hostapd")
  114. dev[0].request("DISCONNECT")
  115. dev[0].wait_disconnected()
  116. dev[0].request("RECONNECT")
  117. dev[0].wait_connected(timeout=15, error="Reconnect timed out")
  118. if dev[0].get_status_field('sae_group') != '19':
  119. raise Exception("Expected default SAE group not used")
  120. def test_sae_groups(dev, apdev):
  121. """SAE with all supported groups"""
  122. if "SAE" not in dev[0].get_capability("auth_alg"):
  123. raise HwsimSkip("SAE not supported")
  124. # This is the full list of supported groups, but groups 14-16 (2048-4096 bit
  125. # MODP) and group 21 (521-bit random ECP group) are a bit too slow on some
  126. # VMs and can result in hitting the mac80211 authentication timeout, so
  127. # allow them to fail and just report such failures in the debug log.
  128. sae_groups = [ 19, 25, 26, 20, 21, 2, 5, 14, 15, 16, 22, 23, 24 ]
  129. tls = dev[0].request("GET tls_library")
  130. if tls.startswith("OpenSSL") and "build=OpenSSL 1.0.2" in tls and "run=OpenSSL 1.0.2" in tls:
  131. logger.info("Add Brainpool EC groups since OpenSSL is new enough")
  132. sae_groups += [ 27, 28, 29, 30 ]
  133. heavy_groups = [ 14, 15, 16 ]
  134. groups = [str(g) for g in sae_groups]
  135. params = hostapd.wpa2_params(ssid="test-sae-groups",
  136. passphrase="12345678")
  137. params['wpa_key_mgmt'] = 'SAE'
  138. params['sae_groups'] = ' '.join(groups)
  139. hostapd.add_ap(apdev[0], params)
  140. for g in groups:
  141. logger.info("Testing SAE group " + g)
  142. dev[0].request("SET sae_groups " + g)
  143. id = dev[0].connect("test-sae-groups", psk="12345678", key_mgmt="SAE",
  144. scan_freq="2412", wait_connect=False)
  145. if int(g) in heavy_groups:
  146. ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=5)
  147. if ev is None:
  148. logger.info("No connection with heavy SAE group %s did not connect - likely hitting timeout in mac80211" % g)
  149. dev[0].remove_network(id)
  150. time.sleep(0.1)
  151. dev[0].dump_monitor()
  152. continue
  153. logger.info("Connection with heavy SAE group " + g)
  154. else:
  155. ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=10)
  156. if ev is None:
  157. if "BoringSSL" in tls and int(g) in [ 25 ]:
  158. logger.info("Ignore connection failure with group " + g + " with BoringSSL")
  159. dev[0].remove_network(id)
  160. dev[0].dump_monitor()
  161. continue
  162. raise Exception("Connection timed out with group " + g)
  163. if dev[0].get_status_field('sae_group') != g:
  164. raise Exception("Expected SAE group not used")
  165. dev[0].remove_network(id)
  166. dev[0].wait_disconnected()
  167. dev[0].dump_monitor()
  168. @remote_compatible
  169. def test_sae_group_nego(dev, apdev):
  170. """SAE group negotiation"""
  171. if "SAE" not in dev[0].get_capability("auth_alg"):
  172. raise HwsimSkip("SAE not supported")
  173. params = hostapd.wpa2_params(ssid="test-sae-group-nego",
  174. passphrase="12345678")
  175. params['wpa_key_mgmt'] = 'SAE'
  176. params['sae_groups'] = '19'
  177. hostapd.add_ap(apdev[0], params)
  178. dev[0].request("SET sae_groups 25 26 20 19")
  179. dev[0].connect("test-sae-group-nego", psk="12345678", key_mgmt="SAE",
  180. scan_freq="2412")
  181. if dev[0].get_status_field('sae_group') != '19':
  182. raise Exception("Expected SAE group not used")
  183. @remote_compatible
  184. def test_sae_anti_clogging(dev, apdev):
  185. """SAE anti clogging"""
  186. if "SAE" not in dev[0].get_capability("auth_alg"):
  187. raise HwsimSkip("SAE not supported")
  188. params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
  189. params['wpa_key_mgmt'] = 'SAE'
  190. params['sae_anti_clogging_threshold'] = '1'
  191. hostapd.add_ap(apdev[0], params)
  192. dev[0].request("SET sae_groups ")
  193. dev[1].request("SET sae_groups ")
  194. id = {}
  195. for i in range(0, 2):
  196. dev[i].scan(freq="2412")
  197. id[i] = dev[i].connect("test-sae", psk="12345678", key_mgmt="SAE",
  198. scan_freq="2412", only_add_network=True)
  199. for i in range(0, 2):
  200. dev[i].select_network(id[i])
  201. for i in range(0, 2):
  202. dev[i].wait_connected(timeout=10)
  203. def test_sae_forced_anti_clogging(dev, apdev):
  204. """SAE anti clogging (forced)"""
  205. if "SAE" not in dev[0].get_capability("auth_alg"):
  206. raise HwsimSkip("SAE not supported")
  207. params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
  208. params['wpa_key_mgmt'] = 'SAE WPA-PSK'
  209. params['sae_anti_clogging_threshold'] = '0'
  210. hostapd.add_ap(apdev[0], params)
  211. dev[2].connect("test-sae", psk="12345678", scan_freq="2412")
  212. for i in range(0, 2):
  213. dev[i].request("SET sae_groups ")
  214. dev[i].connect("test-sae", psk="12345678", key_mgmt="SAE",
  215. scan_freq="2412")
  216. def test_sae_mixed(dev, apdev):
  217. """Mixed SAE and non-SAE network"""
  218. if "SAE" not in dev[0].get_capability("auth_alg"):
  219. raise HwsimSkip("SAE not supported")
  220. params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
  221. params['wpa_key_mgmt'] = 'SAE WPA-PSK'
  222. params['sae_anti_clogging_threshold'] = '0'
  223. hostapd.add_ap(apdev[0], params)
  224. dev[2].connect("test-sae", psk="12345678", scan_freq="2412")
  225. for i in range(0, 2):
  226. dev[i].request("SET sae_groups ")
  227. dev[i].connect("test-sae", psk="12345678", key_mgmt="SAE",
  228. scan_freq="2412")
  229. def test_sae_mixed_mfp(dev, apdev):
  230. """Mixed SAE and non-SAE network and MFP required with SAE"""
  231. if "SAE" not in dev[0].get_capability("auth_alg"):
  232. raise HwsimSkip("SAE not supported")
  233. params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
  234. params['wpa_key_mgmt'] = 'SAE WPA-PSK'
  235. params["ieee80211w"] = "1"
  236. params['sae_require_mfp'] = '1'
  237. hostapd.add_ap(apdev[0], params)
  238. dev[0].request("SET sae_groups ")
  239. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", ieee80211w="2",
  240. scan_freq="2412")
  241. dev[0].dump_monitor()
  242. dev[1].request("SET sae_groups ")
  243. dev[1].connect("test-sae", psk="12345678", key_mgmt="SAE", ieee80211w="0",
  244. scan_freq="2412", wait_connect=False)
  245. ev = dev[1].wait_event(["CTRL-EVENT-CONNECTED",
  246. "CTRL-EVENT-ASSOC-REJECT"], timeout=10)
  247. if ev is None:
  248. raise Exception("No connection result reported")
  249. if "CTRL-EVENT-ASSOC-REJECT" not in ev:
  250. raise Exception("SAE connection without MFP was not rejected")
  251. if "status_code=31" not in ev:
  252. raise Exception("Unexpected status code in rejection: " + ev)
  253. dev[1].request("DISCONNECT")
  254. dev[1].dump_monitor()
  255. dev[2].connect("test-sae", psk="12345678", ieee80211w="0", scan_freq="2412")
  256. dev[2].dump_monitor()
  257. @remote_compatible
  258. def test_sae_missing_password(dev, apdev):
  259. """SAE and missing password"""
  260. if "SAE" not in dev[0].get_capability("auth_alg"):
  261. raise HwsimSkip("SAE not supported")
  262. params = hostapd.wpa2_params(ssid="test-sae",
  263. passphrase="12345678")
  264. params['wpa_key_mgmt'] = 'SAE'
  265. hapd = hostapd.add_ap(apdev[0], params)
  266. dev[0].request("SET sae_groups ")
  267. id = dev[0].connect("test-sae",
  268. raw_psk="46b4a73b8a951ad53ebd2e0afdb9c5483257edd4c21d12b7710759da70945858",
  269. key_mgmt="SAE", scan_freq="2412", wait_connect=False)
  270. ev = dev[0].wait_event(['CTRL-EVENT-SSID-TEMP-DISABLED'], timeout=10)
  271. if ev is None:
  272. raise Exception("Invalid network not temporarily disabled")
  273. def test_sae_key_lifetime_in_memory(dev, apdev, params):
  274. """SAE and key lifetime in memory"""
  275. if "SAE" not in dev[0].get_capability("auth_alg"):
  276. raise HwsimSkip("SAE not supported")
  277. password = "5ad144a7c1f5a5503baa6fa01dabc15b1843e8c01662d78d16b70b5cd23cf8b"
  278. p = hostapd.wpa2_params(ssid="test-sae", passphrase=password)
  279. p['wpa_key_mgmt'] = 'SAE'
  280. hapd = hostapd.add_ap(apdev[0], p)
  281. pid = find_wpas_process(dev[0])
  282. dev[0].request("SET sae_groups ")
  283. id = dev[0].connect("test-sae", psk=password, key_mgmt="SAE",
  284. scan_freq="2412")
  285. # The decrypted copy of GTK is freed only after the CTRL-EVENT-CONNECTED
  286. # event has been delivered, so verify that wpa_supplicant has returned to
  287. # eloop before reading process memory.
  288. time.sleep(1)
  289. dev[0].ping()
  290. buf = read_process_memory(pid, password)
  291. dev[0].request("DISCONNECT")
  292. dev[0].wait_disconnected()
  293. dev[0].relog()
  294. sae_k = None
  295. sae_keyseed = None
  296. sae_kck = None
  297. pmk = None
  298. ptk = None
  299. gtk = None
  300. with open(os.path.join(params['logdir'], 'log0'), 'r') as f:
  301. for l in f.readlines():
  302. if "SAE: k - hexdump" in l:
  303. val = l.strip().split(':')[3].replace(' ', '')
  304. sae_k = binascii.unhexlify(val)
  305. if "SAE: keyseed - hexdump" in l:
  306. val = l.strip().split(':')[3].replace(' ', '')
  307. sae_keyseed = binascii.unhexlify(val)
  308. if "SAE: KCK - hexdump" in l:
  309. val = l.strip().split(':')[3].replace(' ', '')
  310. sae_kck = binascii.unhexlify(val)
  311. if "SAE: PMK - hexdump" in l:
  312. val = l.strip().split(':')[3].replace(' ', '')
  313. pmk = binascii.unhexlify(val)
  314. if "WPA: PTK - hexdump" in l:
  315. val = l.strip().split(':')[3].replace(' ', '')
  316. ptk = binascii.unhexlify(val)
  317. if "WPA: Group Key - hexdump" in l:
  318. val = l.strip().split(':')[3].replace(' ', '')
  319. gtk = binascii.unhexlify(val)
  320. if not sae_k or not sae_keyseed or not sae_kck or not pmk or not ptk or not gtk:
  321. raise Exception("Could not find keys from debug log")
  322. if len(gtk) != 16:
  323. raise Exception("Unexpected GTK length")
  324. kck = ptk[0:16]
  325. kek = ptk[16:32]
  326. tk = ptk[32:48]
  327. fname = os.path.join(params['logdir'],
  328. 'sae_key_lifetime_in_memory.memctx-')
  329. logger.info("Checking keys in memory while associated")
  330. get_key_locations(buf, password, "Password")
  331. get_key_locations(buf, pmk, "PMK")
  332. if password not in buf:
  333. raise HwsimSkip("Password not found while associated")
  334. if pmk not in buf:
  335. raise HwsimSkip("PMK not found while associated")
  336. if kck not in buf:
  337. raise Exception("KCK not found while associated")
  338. if kek not in buf:
  339. raise Exception("KEK not found while associated")
  340. #if tk in buf:
  341. # raise Exception("TK found from memory")
  342. verify_not_present(buf, sae_k, fname, "SAE(k)")
  343. verify_not_present(buf, sae_keyseed, fname, "SAE(keyseed)")
  344. verify_not_present(buf, sae_kck, fname, "SAE(KCK)")
  345. logger.info("Checking keys in memory after disassociation")
  346. buf = read_process_memory(pid, password)
  347. # Note: Password is still present in network configuration
  348. # Note: PMK is in PMKSA cache
  349. get_key_locations(buf, password, "Password")
  350. get_key_locations(buf, pmk, "PMK")
  351. verify_not_present(buf, kck, fname, "KCK")
  352. verify_not_present(buf, kek, fname, "KEK")
  353. verify_not_present(buf, tk, fname, "TK")
  354. if gtk in buf:
  355. get_key_locations(buf, gtk, "GTK")
  356. verify_not_present(buf, gtk, fname, "GTK")
  357. verify_not_present(buf, sae_k, fname, "SAE(k)")
  358. verify_not_present(buf, sae_keyseed, fname, "SAE(keyseed)")
  359. verify_not_present(buf, sae_kck, fname, "SAE(KCK)")
  360. dev[0].request("PMKSA_FLUSH")
  361. logger.info("Checking keys in memory after PMKSA cache flush")
  362. buf = read_process_memory(pid, password)
  363. get_key_locations(buf, password, "Password")
  364. get_key_locations(buf, pmk, "PMK")
  365. verify_not_present(buf, pmk, fname, "PMK")
  366. dev[0].request("REMOVE_NETWORK all")
  367. logger.info("Checking keys in memory after network profile removal")
  368. buf = read_process_memory(pid, password)
  369. get_key_locations(buf, password, "Password")
  370. get_key_locations(buf, pmk, "PMK")
  371. verify_not_present(buf, password, fname, "password")
  372. verify_not_present(buf, pmk, fname, "PMK")
  373. verify_not_present(buf, kck, fname, "KCK")
  374. verify_not_present(buf, kek, fname, "KEK")
  375. verify_not_present(buf, tk, fname, "TK")
  376. verify_not_present(buf, gtk, fname, "GTK")
  377. verify_not_present(buf, sae_k, fname, "SAE(k)")
  378. verify_not_present(buf, sae_keyseed, fname, "SAE(keyseed)")
  379. verify_not_present(buf, sae_kck, fname, "SAE(KCK)")
  380. @remote_compatible
  381. def test_sae_oom_wpas(dev, apdev):
  382. """SAE and OOM in wpa_supplicant"""
  383. if "SAE" not in dev[0].get_capability("auth_alg"):
  384. raise HwsimSkip("SAE not supported")
  385. params = hostapd.wpa2_params(ssid="test-sae",
  386. passphrase="12345678")
  387. params['wpa_key_mgmt'] = 'SAE'
  388. hapd = hostapd.add_ap(apdev[0], params)
  389. dev[0].request("SET sae_groups 25")
  390. tls = dev[0].request("GET tls_library")
  391. if "BoringSSL" in tls:
  392. dev[0].request("SET sae_groups 26")
  393. with alloc_fail(dev[0], 1, "sae_set_group"):
  394. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
  395. scan_freq="2412")
  396. dev[0].request("REMOVE_NETWORK all")
  397. dev[0].request("SET sae_groups ")
  398. with alloc_fail(dev[0], 2, "sae_set_group"):
  399. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
  400. scan_freq="2412")
  401. dev[0].request("REMOVE_NETWORK all")
  402. with alloc_fail(dev[0], 1, "wpabuf_alloc;sme_auth_build_sae_commit"):
  403. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
  404. scan_freq="2412")
  405. dev[0].request("REMOVE_NETWORK all")
  406. with alloc_fail(dev[0], 1, "wpabuf_alloc;sme_auth_build_sae_confirm"):
  407. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
  408. scan_freq="2412", wait_connect=False)
  409. wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
  410. dev[0].request("REMOVE_NETWORK all")
  411. with alloc_fail(dev[0], 1, "=sme_authenticate"):
  412. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
  413. scan_freq="2412", wait_connect=False)
  414. wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
  415. dev[0].request("REMOVE_NETWORK all")
  416. with alloc_fail(dev[0], 1, "radio_add_work;sme_authenticate"):
  417. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
  418. scan_freq="2412", wait_connect=False)
  419. wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
  420. dev[0].request("REMOVE_NETWORK all")
  421. @remote_compatible
  422. def test_sae_proto_ecc(dev, apdev):
  423. """SAE protocol testing (ECC)"""
  424. if "SAE" not in dev[0].get_capability("auth_alg"):
  425. raise HwsimSkip("SAE not supported")
  426. params = hostapd.wpa2_params(ssid="test-sae",
  427. passphrase="12345678")
  428. params['wpa_key_mgmt'] = 'SAE'
  429. hapd = hostapd.add_ap(apdev[0], params)
  430. bssid = apdev[0]['bssid']
  431. dev[0].request("SET sae_groups 19")
  432. tests = [ ("Confirm mismatch",
  433. "1300" + "033d3635b39666ed427fd4a3e7d37acec2810afeaf1687f746a14163ff0e6d03" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02f8",
  434. "0000800edebc3f260dc1fe7e0b20888af2b8a3316252ec37388a8504e25b73dc4240"),
  435. ("Commit without even full cyclic group field",
  436. "13",
  437. None),
  438. ("Too short commit",
  439. "1300" + "033d3635b39666ed427fd4a3e7d37acec2810afeaf1687f746a14163ff0e6d03" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02",
  440. None),
  441. ("Invalid commit scalar (0)",
  442. "1300" + "0000000000000000000000000000000000000000000000000000000000000000" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02f8",
  443. None),
  444. ("Invalid commit scalar (1)",
  445. "1300" + "0000000000000000000000000000000000000000000000000000000000000001" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02f8",
  446. None),
  447. ("Invalid commit scalar (> r)",
  448. "1300" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02f8",
  449. None),
  450. ("Commit element not on curve",
  451. "1300" + "033d3635b39666ed427fd4a3e7d37acec2810afeaf1687f746a14163ff0e6d03" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728d0000000000000000000000000000000000000000000000000000000000000000",
  452. None),
  453. ("Invalid commit element (y coordinate > P)",
  454. "1300" + "033d3635b39666ed427fd4a3e7d37acec2810afeaf1687f746a14163ff0e6d03" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
  455. None),
  456. ("Invalid commit element (x coordinate > P)",
  457. "1300" + "033d3635b39666ed427fd4a3e7d37acec2810afeaf1687f746a14163ff0e6d03" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02f8",
  458. None),
  459. ("Different group in commit",
  460. "1400" + "033d3635b39666ed427fd4a3e7d37acec2810afeaf1687f746a14163ff0e6d03" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02f8",
  461. None),
  462. ("Too short confirm",
  463. "1300" + "033d3635b39666ed427fd4a3e7d37acec2810afeaf1687f746a14163ff0e6d03" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02f8",
  464. "0000800edebc3f260dc1fe7e0b20888af2b8a3316252ec37388a8504e25b73dc42")]
  465. for (note, commit, confirm) in tests:
  466. logger.info(note)
  467. dev[0].scan_for_bss(bssid, freq=2412)
  468. hapd.set("ext_mgmt_frame_handling", "1")
  469. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
  470. scan_freq="2412", wait_connect=False)
  471. logger.info("Commit")
  472. for i in range(0, 10):
  473. req = hapd.mgmt_rx()
  474. if req is None:
  475. raise Exception("MGMT RX wait timed out (commit)")
  476. if req['subtype'] == 11:
  477. break
  478. req = None
  479. if not req:
  480. raise Exception("Authentication frame (commit) not received")
  481. hapd.dump_monitor()
  482. resp = {}
  483. resp['fc'] = req['fc']
  484. resp['da'] = req['sa']
  485. resp['sa'] = req['da']
  486. resp['bssid'] = req['bssid']
  487. resp['payload'] = binascii.unhexlify("030001000000" + commit)
  488. hapd.mgmt_tx(resp)
  489. if confirm:
  490. logger.info("Confirm")
  491. for i in range(0, 10):
  492. req = hapd.mgmt_rx()
  493. if req is None:
  494. raise Exception("MGMT RX wait timed out (confirm)")
  495. if req['subtype'] == 11:
  496. break
  497. req = None
  498. if not req:
  499. raise Exception("Authentication frame (confirm) not received")
  500. hapd.dump_monitor()
  501. resp = {}
  502. resp['fc'] = req['fc']
  503. resp['da'] = req['sa']
  504. resp['sa'] = req['da']
  505. resp['bssid'] = req['bssid']
  506. resp['payload'] = binascii.unhexlify("030002000000" + confirm)
  507. hapd.mgmt_tx(resp)
  508. time.sleep(0.1)
  509. dev[0].request("REMOVE_NETWORK all")
  510. hapd.set("ext_mgmt_frame_handling", "0")
  511. hapd.dump_monitor()
  512. @remote_compatible
  513. def test_sae_proto_ffc(dev, apdev):
  514. """SAE protocol testing (FFC)"""
  515. if "SAE" not in dev[0].get_capability("auth_alg"):
  516. raise HwsimSkip("SAE not supported")
  517. params = hostapd.wpa2_params(ssid="test-sae",
  518. passphrase="12345678")
  519. params['wpa_key_mgmt'] = 'SAE'
  520. hapd = hostapd.add_ap(apdev[0], params)
  521. bssid = apdev[0]['bssid']
  522. dev[0].request("SET sae_groups 2")
  523. tests = [ ("Confirm mismatch",
  524. "0200" + "0c70519d874e3e4930a917cc5e17ea7a26028211159f217bab28b8d6c56691805e49f03249b2c6e22c7c9f86b30e04ccad2deedd5e5108ae07b737c00001c59cd0eb08b1dfc7f1b06a1542e2b6601a963c066e0c65940983a03917ae57a101ce84b5cbbc76ff33ebb990aac2e54aa0f0ab6ec0a58113d927683502b2cb2347d2" + "a8c00117493cdffa5dd671e934bc9cb1a69f39e25e9dd9cd9afd3aea2441a0f5491211c7ba50a753563f9ce943b043557cb71193b28e86ed9544f4289c471bf91b70af5c018cf4663e004165b0fd0bc1d8f3f78adf42eee92bcbc55246fd3ee9f107ab965dc7d4986f23eb71d616ebfe6bfe0a6c1ac5dc1718acee17c9a17486",
  525. "0000f3116a9731f1259622e3eb55d4b3b50ba16f8c5f5565b28e609b180c51460251"),
  526. ("Too short commit",
  527. "0200" + "0c70519d874e3e4930a917cc5e17ea7a26028211159f217bab28b8d6c56691805e49f03249b2c6e22c7c9f86b30e04ccad2deedd5e5108ae07b737c00001c59cd0eb08b1dfc7f1b06a1542e2b6601a963c066e0c65940983a03917ae57a101ce84b5cbbc76ff33ebb990aac2e54aa0f0ab6ec0a58113d927683502b2cb2347d2" + "a8c00117493cdffa5dd671e934bc9cb1a69f39e25e9dd9cd9afd3aea2441a0f5491211c7ba50a753563f9ce943b043557cb71193b28e86ed9544f4289c471bf91b70af5c018cf4663e004165b0fd0bc1d8f3f78adf42eee92bcbc55246fd3ee9f107ab965dc7d4986f23eb71d616ebfe6bfe0a6c1ac5dc1718acee17c9a174",
  528. None),
  529. ("Invalid element (0) in commit",
  530. "0200" + "0c70519d874e3e4930a917cc5e17ea7a26028211159f217bab28b8d6c56691805e49f03249b2c6e22c7c9f86b30e04ccad2deedd5e5108ae07b737c00001c59cd0eb08b1dfc7f1b06a1542e2b6601a963c066e0c65940983a03917ae57a101ce84b5cbbc76ff33ebb990aac2e54aa0f0ab6ec0a58113d927683502b2cb2347d2" + "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  531. None),
  532. ("Invalid element (1) in commit",
  533. "0200" + "0c70519d874e3e4930a917cc5e17ea7a26028211159f217bab28b8d6c56691805e49f03249b2c6e22c7c9f86b30e04ccad2deedd5e5108ae07b737c00001c59cd0eb08b1dfc7f1b06a1542e2b6601a963c066e0c65940983a03917ae57a101ce84b5cbbc76ff33ebb990aac2e54aa0f0ab6ec0a58113d927683502b2cb2347d2" + "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
  534. None),
  535. ("Invalid element (> P) in commit",
  536. "0200" + "0c70519d874e3e4930a917cc5e17ea7a26028211159f217bab28b8d6c56691805e49f03249b2c6e22c7c9f86b30e04ccad2deedd5e5108ae07b737c00001c59cd0eb08b1dfc7f1b06a1542e2b6601a963c066e0c65940983a03917ae57a101ce84b5cbbc76ff33ebb990aac2e54aa0f0ab6ec0a58113d927683502b2cb2347d2" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
  537. None) ]
  538. for (note, commit, confirm) in tests:
  539. logger.info(note)
  540. dev[0].scan_for_bss(bssid, freq=2412)
  541. hapd.set("ext_mgmt_frame_handling", "1")
  542. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
  543. scan_freq="2412", wait_connect=False)
  544. logger.info("Commit")
  545. for i in range(0, 10):
  546. req = hapd.mgmt_rx()
  547. if req is None:
  548. raise Exception("MGMT RX wait timed out (commit)")
  549. if req['subtype'] == 11:
  550. break
  551. req = None
  552. if not req:
  553. raise Exception("Authentication frame (commit) not received")
  554. hapd.dump_monitor()
  555. resp = {}
  556. resp['fc'] = req['fc']
  557. resp['da'] = req['sa']
  558. resp['sa'] = req['da']
  559. resp['bssid'] = req['bssid']
  560. resp['payload'] = binascii.unhexlify("030001000000" + commit)
  561. hapd.mgmt_tx(resp)
  562. if confirm:
  563. logger.info("Confirm")
  564. for i in range(0, 10):
  565. req = hapd.mgmt_rx()
  566. if req is None:
  567. raise Exception("MGMT RX wait timed out (confirm)")
  568. if req['subtype'] == 11:
  569. break
  570. req = None
  571. if not req:
  572. raise Exception("Authentication frame (confirm) not received")
  573. hapd.dump_monitor()
  574. resp = {}
  575. resp['fc'] = req['fc']
  576. resp['da'] = req['sa']
  577. resp['sa'] = req['da']
  578. resp['bssid'] = req['bssid']
  579. resp['payload'] = binascii.unhexlify("030002000000" + confirm)
  580. hapd.mgmt_tx(resp)
  581. time.sleep(0.1)
  582. dev[0].request("REMOVE_NETWORK all")
  583. hapd.set("ext_mgmt_frame_handling", "0")
  584. hapd.dump_monitor()
  585. def test_sae_proto_confirm_replay(dev, apdev):
  586. """SAE protocol testing - Confirm replay"""
  587. if "SAE" not in dev[0].get_capability("auth_alg"):
  588. raise HwsimSkip("SAE not supported")
  589. params = hostapd.wpa2_params(ssid="test-sae",
  590. passphrase="12345678")
  591. params['wpa_key_mgmt'] = 'SAE'
  592. hapd = hostapd.add_ap(apdev[0], params)
  593. bssid = apdev[0]['bssid']
  594. dev[0].request("SET sae_groups 19")
  595. dev[0].scan_for_bss(bssid, freq=2412)
  596. hapd.set("ext_mgmt_frame_handling", "1")
  597. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
  598. scan_freq="2412", wait_connect=False)
  599. logger.info("Commit")
  600. for i in range(0, 10):
  601. req = hapd.mgmt_rx()
  602. if req is None:
  603. raise Exception("MGMT RX wait timed out (commit)")
  604. if req['subtype'] == 11:
  605. break
  606. req = None
  607. if not req:
  608. raise Exception("Authentication frame (commit) not received")
  609. bssid = hapd.own_addr().replace(':', '')
  610. addr = dev[0].own_addr().replace(':', '')
  611. hdr = "b0003a01" + bssid + addr + bssid + "1000"
  612. hapd.dump_monitor()
  613. hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + req['frame'].encode('hex'))
  614. logger.info("Confirm")
  615. for i in range(0, 10):
  616. req = hapd.mgmt_rx()
  617. if req is None:
  618. raise Exception("MGMT RX wait timed out (confirm)")
  619. if req['subtype'] == 11:
  620. break
  621. req = None
  622. if not req:
  623. raise Exception("Authentication frame (confirm) not received")
  624. hapd.dump_monitor()
  625. hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + req['frame'].encode('hex'))
  626. logger.info("Replay Confirm")
  627. hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + req['frame'].encode('hex'))
  628. logger.info("Association Request")
  629. for i in range(0, 10):
  630. req = hapd.mgmt_rx()
  631. if req is None:
  632. raise Exception("MGMT RX wait timed out (AssocReq)")
  633. if req['subtype'] == 0:
  634. break
  635. req = None
  636. if not req:
  637. raise Exception("Association Request frame not received")
  638. hapd.dump_monitor()
  639. hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + req['frame'].encode('hex'))
  640. ev = hapd.wait_event(["MGMT-TX-STATUS"], timeout=5)
  641. if ev is None:
  642. raise Exception("Management frame TX status not reported (1)")
  643. if "stype=1 ok=1" not in ev:
  644. raise Exception("Unexpected management frame TX status (1): " + ev)
  645. cmd = "MGMT_TX_STATUS_PROCESS %s" % (" ".join(ev.split(' ')[1:4]))
  646. if "OK" not in hapd.request(cmd):
  647. raise Exception("MGMT_TX_STATUS_PROCESS failed")
  648. hapd.set("ext_mgmt_frame_handling", "0")
  649. dev[0].wait_connected()
  650. def test_sae_proto_hostapd(dev, apdev):
  651. """SAE protocol testing with hostapd"""
  652. params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
  653. params['wpa_key_mgmt'] = 'SAE'
  654. params['sae_groups'] = "19 65535"
  655. hapd = hostapd.add_ap(apdev[0], params)
  656. hapd.set("ext_mgmt_frame_handling", "1")
  657. bssid = hapd.own_addr().replace(':', '')
  658. addr = "020000000000"
  659. addr2 = "020000000001"
  660. hdr = "b0003a01" + bssid + addr + bssid + "1000"
  661. hdr2 = "b0003a01" + bssid + addr2 + bssid + "1000"
  662. group = "1300"
  663. scalar = "f7df19f4a7fef1d3b895ea1de150b7c5a7a705c8ebb31a52b623e0057908bd93"
  664. element_x = "21931572027f2e953e2a49fab3d992944102cc95aa19515fc068b394fb25ae3c"
  665. element_y = "cb4eeb94d7b0b789abfdb73a67ab9d6d5efa94dd553e0e724a6289821cbce530"
  666. hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + "030001000000" + group + scalar + element_x + element_y)
  667. # "SAE: Not enough data for scalar"
  668. hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + "030001000000" + group + scalar[:-2])
  669. # "SAE: Do not allow group to be changed"
  670. hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + "030001000000" + "ffff" + scalar[:-2])
  671. # "SAE: Unsupported Finite Cyclic Group 65535"
  672. hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr2 + "030001000000" + "ffff" + scalar[:-2])
  673. @remote_compatible
  674. def test_sae_no_ffc_by_default(dev, apdev):
  675. """SAE and default groups rejecting FFC"""
  676. if "SAE" not in dev[0].get_capability("auth_alg"):
  677. raise HwsimSkip("SAE not supported")
  678. params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
  679. params['wpa_key_mgmt'] = 'SAE'
  680. hapd = hostapd.add_ap(apdev[0], params)
  681. dev[0].request("SET sae_groups 5")
  682. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", scan_freq="2412",
  683. wait_connect=False)
  684. ev = dev[0].wait_event(["SME: Trying to authenticate"], timeout=3)
  685. if ev is None:
  686. raise Exception("Did not try to authenticate")
  687. ev = dev[0].wait_event(["SME: Trying to authenticate"], timeout=3)
  688. if ev is None:
  689. raise Exception("Did not try to authenticate (2)")
  690. dev[0].request("REMOVE_NETWORK all")
  691. def sae_reflection_attack(apdev, dev, group):
  692. if "SAE" not in dev.get_capability("auth_alg"):
  693. raise HwsimSkip("SAE not supported")
  694. params = hostapd.wpa2_params(ssid="test-sae",
  695. passphrase="no-knowledge-of-passphrase")
  696. params['wpa_key_mgmt'] = 'SAE'
  697. hapd = hostapd.add_ap(apdev, params)
  698. bssid = apdev['bssid']
  699. dev.scan_for_bss(bssid, freq=2412)
  700. hapd.set("ext_mgmt_frame_handling", "1")
  701. dev.request("SET sae_groups %d" % group)
  702. dev.connect("test-sae", psk="reflection-attack", key_mgmt="SAE",
  703. scan_freq="2412", wait_connect=False)
  704. # Commit
  705. for i in range(0, 10):
  706. req = hapd.mgmt_rx()
  707. if req is None:
  708. raise Exception("MGMT RX wait timed out")
  709. if req['subtype'] == 11:
  710. break
  711. req = None
  712. if not req:
  713. raise Exception("Authentication frame not received")
  714. resp = {}
  715. resp['fc'] = req['fc']
  716. resp['da'] = req['sa']
  717. resp['sa'] = req['da']
  718. resp['bssid'] = req['bssid']
  719. resp['payload'] = req['payload']
  720. hapd.mgmt_tx(resp)
  721. # Confirm
  722. req = hapd.mgmt_rx(timeout=0.5)
  723. if req is not None:
  724. if req['subtype'] == 11:
  725. raise Exception("Unexpected Authentication frame seen")
  726. @remote_compatible
  727. def test_sae_reflection_attack_ecc(dev, apdev):
  728. """SAE reflection attack (ECC)"""
  729. sae_reflection_attack(apdev[0], dev[0], 19)
  730. @remote_compatible
  731. def test_sae_reflection_attack_ffc(dev, apdev):
  732. """SAE reflection attack (FFC)"""
  733. sae_reflection_attack(apdev[0], dev[0], 5)
  734. def sae_reflection_attack_internal(apdev, dev, group):
  735. if "SAE" not in dev.get_capability("auth_alg"):
  736. raise HwsimSkip("SAE not supported")
  737. params = hostapd.wpa2_params(ssid="test-sae",
  738. passphrase="no-knowledge-of-passphrase")
  739. params['wpa_key_mgmt'] = 'SAE'
  740. params['sae_reflection_attack'] = '1'
  741. hapd = hostapd.add_ap(apdev, params)
  742. bssid = apdev['bssid']
  743. dev.scan_for_bss(bssid, freq=2412)
  744. dev.request("SET sae_groups %d" % group)
  745. dev.connect("test-sae", psk="reflection-attack", key_mgmt="SAE",
  746. scan_freq="2412", wait_connect=False)
  747. ev = dev.wait_event(["CTRL-EVENT-CONNECTED"], timeout=1)
  748. if ev is not None:
  749. raise Exception("Unexpected connection")
  750. @remote_compatible
  751. def test_sae_reflection_attack_ecc_internal(dev, apdev):
  752. """SAE reflection attack (ECC) - internal"""
  753. sae_reflection_attack_internal(apdev[0], dev[0], 19)
  754. @remote_compatible
  755. def test_sae_reflection_attack_ffc_internal(dev, apdev):
  756. """SAE reflection attack (FFC) - internal"""
  757. sae_reflection_attack_internal(apdev[0], dev[0], 5)
  758. @remote_compatible
  759. def test_sae_commit_override(dev, apdev):
  760. """SAE commit override (hostapd)"""
  761. if "SAE" not in dev[0].get_capability("auth_alg"):
  762. raise HwsimSkip("SAE not supported")
  763. params = hostapd.wpa2_params(ssid="test-sae",
  764. passphrase="12345678")
  765. params['wpa_key_mgmt'] = 'SAE'
  766. params['sae_commit_override'] = '13ffbad00d215867a7c5ff37d87bb9bdb7cb116e520f71e8d7a794ca2606d537ddc6c099c40e7a25372b80a8fd443cd7dd222c8ea21b8ef372d4b3e316c26a73fd999cc79ad483eb826e7b3893ea332da68fa13224bcdeb4fb18b0584dd100a2c514'
  767. hapd = hostapd.add_ap(apdev[0], params)
  768. dev[0].request("SET sae_groups ")
  769. dev[0].connect("test-sae", psk="test-sae", key_mgmt="SAE",
  770. scan_freq="2412", wait_connect=False)
  771. ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1)
  772. if ev is not None:
  773. raise Exception("Unexpected connection")
  774. @remote_compatible
  775. def test_sae_commit_override2(dev, apdev):
  776. """SAE commit override (wpa_supplicant)"""
  777. if "SAE" not in dev[0].get_capability("auth_alg"):
  778. raise HwsimSkip("SAE not supported")
  779. params = hostapd.wpa2_params(ssid="test-sae",
  780. passphrase="12345678")
  781. params['wpa_key_mgmt'] = 'SAE'
  782. hapd = hostapd.add_ap(apdev[0], params)
  783. dev[0].request("SET sae_groups ")
  784. dev[0].set('sae_commit_override', '13ffbad00d215867a7c5ff37d87bb9bdb7cb116e520f71e8d7a794ca2606d537ddc6c099c40e7a25372b80a8fd443cd7dd222c8ea21b8ef372d4b3e316c26a73fd999cc79ad483eb826e7b3893ea332da68fa13224bcdeb4fb18b0584dd100a2c514')
  785. dev[0].connect("test-sae", psk="test-sae", key_mgmt="SAE",
  786. scan_freq="2412", wait_connect=False)
  787. ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1)
  788. if ev is not None:
  789. raise Exception("Unexpected connection")
  790. @remote_compatible
  791. def test_sae_anti_clogging_proto(dev, apdev):
  792. """SAE anti clogging protocol testing"""
  793. if "SAE" not in dev[0].get_capability("auth_alg"):
  794. raise HwsimSkip("SAE not supported")
  795. params = hostapd.wpa2_params(ssid="test-sae",
  796. passphrase="no-knowledge-of-passphrase")
  797. params['wpa_key_mgmt'] = 'SAE'
  798. hapd = hostapd.add_ap(apdev[0], params)
  799. bssid = apdev[0]['bssid']
  800. dev[0].scan_for_bss(bssid, freq=2412)
  801. hapd.set("ext_mgmt_frame_handling", "1")
  802. dev[0].request("SET sae_groups ")
  803. dev[0].connect("test-sae", psk="anti-cloggign", key_mgmt="SAE",
  804. scan_freq="2412", wait_connect=False)
  805. # Commit
  806. for i in range(0, 10):
  807. req = hapd.mgmt_rx()
  808. if req is None:
  809. raise Exception("MGMT RX wait timed out")
  810. if req['subtype'] == 11:
  811. break
  812. req = None
  813. if not req:
  814. raise Exception("Authentication frame not received")
  815. resp = {}
  816. resp['fc'] = req['fc']
  817. resp['da'] = req['sa']
  818. resp['sa'] = req['da']
  819. resp['bssid'] = req['bssid']
  820. resp['payload'] = binascii.unhexlify("030001004c00" + "ffff00")
  821. hapd.mgmt_tx(resp)
  822. # Confirm (not received due to DH group being rejected)
  823. req = hapd.mgmt_rx(timeout=0.5)
  824. if req is not None:
  825. if req['subtype'] == 11:
  826. raise Exception("Unexpected Authentication frame seen")
  827. @remote_compatible
  828. def test_sae_no_random(dev, apdev):
  829. """SAE and no random numbers available"""
  830. if "SAE" not in dev[0].get_capability("auth_alg"):
  831. raise HwsimSkip("SAE not supported")
  832. params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
  833. params['wpa_key_mgmt'] = 'SAE'
  834. hapd = hostapd.add_ap(apdev[0], params)
  835. dev[0].request("SET sae_groups ")
  836. tests = [ (1, "os_get_random;sae_get_rand"),
  837. (1, "os_get_random;get_rand_1_to_p_1"),
  838. (1, "os_get_random;get_random_qr_qnr"),
  839. (1, "os_get_random;sae_derive_pwe_ecc") ]
  840. for count, func in tests:
  841. with fail_test(dev[0], count, func):
  842. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
  843. scan_freq="2412")
  844. dev[0].request("REMOVE_NETWORK all")
  845. dev[0].wait_disconnected()
  846. @remote_compatible
  847. def test_sae_pwe_failure(dev, apdev):
  848. """SAE and pwe failure"""
  849. if "SAE" not in dev[0].get_capability("auth_alg"):
  850. raise HwsimSkip("SAE not supported")
  851. params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
  852. params['wpa_key_mgmt'] = 'SAE'
  853. params['sae_groups'] = '19 5'
  854. hapd = hostapd.add_ap(apdev[0], params)
  855. dev[0].request("SET sae_groups 19")
  856. with fail_test(dev[0], 1, "hmac_sha256_vector;sae_derive_pwe_ecc"):
  857. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
  858. scan_freq="2412")
  859. dev[0].request("REMOVE_NETWORK all")
  860. dev[0].wait_disconnected()
  861. with fail_test(dev[0], 1, "sae_test_pwd_seed_ecc"):
  862. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
  863. scan_freq="2412")
  864. dev[0].request("REMOVE_NETWORK all")
  865. dev[0].wait_disconnected()
  866. dev[0].request("SET sae_groups 5")
  867. with fail_test(dev[0], 1, "hmac_sha256_vector;sae_derive_pwe_ffc"):
  868. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
  869. scan_freq="2412")
  870. dev[0].request("REMOVE_NETWORK all")
  871. dev[0].wait_disconnected()
  872. dev[0].request("SET sae_groups 5")
  873. with fail_test(dev[0], 1, "sae_test_pwd_seed_ffc"):
  874. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
  875. scan_freq="2412")
  876. dev[0].request("REMOVE_NETWORK all")
  877. dev[0].wait_disconnected()
  878. with fail_test(dev[0], 2, "sae_test_pwd_seed_ffc"):
  879. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
  880. scan_freq="2412")
  881. dev[0].request("REMOVE_NETWORK all")
  882. dev[0].wait_disconnected()
  883. @remote_compatible
  884. def test_sae_bignum_failure(dev, apdev):
  885. """SAE and bignum failure"""
  886. if "SAE" not in dev[0].get_capability("auth_alg"):
  887. raise HwsimSkip("SAE not supported")
  888. params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
  889. params['wpa_key_mgmt'] = 'SAE'
  890. params['sae_groups'] = '19 5 22'
  891. hapd = hostapd.add_ap(apdev[0], params)
  892. dev[0].request("SET sae_groups 19")
  893. tests = [ (1, "crypto_bignum_init_set;get_rand_1_to_p_1"),
  894. (1, "crypto_bignum_init;is_quadratic_residue_blind"),
  895. (1, "crypto_bignum_mulmod;is_quadratic_residue_blind"),
  896. (2, "crypto_bignum_mulmod;is_quadratic_residue_blind"),
  897. (3, "crypto_bignum_mulmod;is_quadratic_residue_blind"),
  898. (1, "crypto_bignum_legendre;is_quadratic_residue_blind"),
  899. (1, "crypto_bignum_init_set;sae_test_pwd_seed_ecc"),
  900. (1, "crypto_ec_point_compute_y_sqr;sae_test_pwd_seed_ecc"),
  901. (1, "crypto_bignum_init_set;get_random_qr_qnr"),
  902. (1, "crypto_bignum_to_bin;sae_derive_pwe_ecc"),
  903. (1, "crypto_ec_point_init;sae_derive_pwe_ecc"),
  904. (1, "crypto_ec_point_solve_y_coord;sae_derive_pwe_ecc"),
  905. (1, "crypto_ec_point_init;sae_derive_commit_element_ecc"),
  906. (1, "crypto_ec_point_mul;sae_derive_commit_element_ecc"),
  907. (1, "crypto_ec_point_invert;sae_derive_commit_element_ecc"),
  908. (1, "crypto_bignum_init;=sae_derive_commit"),
  909. (1, "crypto_ec_point_init;sae_derive_k_ecc"),
  910. (1, "crypto_ec_point_mul;sae_derive_k_ecc"),
  911. (1, "crypto_ec_point_add;sae_derive_k_ecc"),
  912. (2, "crypto_ec_point_mul;sae_derive_k_ecc"),
  913. (1, "crypto_ec_point_to_bin;sae_derive_k_ecc"),
  914. (1, "crypto_bignum_legendre;get_random_qr_qnr"),
  915. (1, "sha256_prf;sae_derive_keys"),
  916. (1, "crypto_bignum_init;sae_derive_keys"),
  917. (1, "crypto_bignum_init_set;sae_parse_commit_scalar"),
  918. (1, "crypto_bignum_to_bin;sae_parse_commit_element_ecc"),
  919. (1, "crypto_ec_point_from_bin;sae_parse_commit_element_ecc") ]
  920. for count, func in tests:
  921. with fail_test(dev[0], count, func):
  922. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
  923. scan_freq="2412", wait_connect=False)
  924. wait_fail_trigger(dev[0], "GET_FAIL")
  925. dev[0].request("REMOVE_NETWORK all")
  926. dev[0].request("SET sae_groups 5")
  927. tests = [ (1, "crypto_bignum_init_set;sae_set_group"),
  928. (2, "crypto_bignum_init_set;sae_set_group"),
  929. (1, "crypto_bignum_init_set;sae_get_rand"),
  930. (1, "crypto_bignum_init_set;sae_test_pwd_seed_ffc"),
  931. (1, "crypto_bignum_exptmod;sae_test_pwd_seed_ffc"),
  932. (1, "crypto_bignum_init;sae_derive_pwe_ffc"),
  933. (1, "crypto_bignum_init;sae_derive_commit_element_ffc"),
  934. (1, "crypto_bignum_exptmod;sae_derive_commit_element_ffc"),
  935. (1, "crypto_bignum_inverse;sae_derive_commit_element_ffc"),
  936. (1, "crypto_bignum_init;sae_derive_k_ffc"),
  937. (1, "crypto_bignum_exptmod;sae_derive_k_ffc"),
  938. (1, "crypto_bignum_mulmod;sae_derive_k_ffc"),
  939. (2, "crypto_bignum_exptmod;sae_derive_k_ffc"),
  940. (1, "crypto_bignum_to_bin;sae_derive_k_ffc"),
  941. (1, "crypto_bignum_init_set;sae_parse_commit_element_ffc"),
  942. (1, "crypto_bignum_init;sae_parse_commit_element_ffc"),
  943. (2, "crypto_bignum_init_set;sae_parse_commit_element_ffc"),
  944. (1, "crypto_bignum_exptmod;sae_parse_commit_element_ffc") ]
  945. for count, func in tests:
  946. with fail_test(dev[0], count, func):
  947. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
  948. scan_freq="2412", wait_connect=False)
  949. wait_fail_trigger(dev[0], "GET_FAIL")
  950. dev[0].request("REMOVE_NETWORK all")
  951. dev[0].request("SET sae_groups 22")
  952. tests = [ (1, "crypto_bignum_init_set;sae_test_pwd_seed_ffc"),
  953. (1, "crypto_bignum_sub;sae_test_pwd_seed_ffc"),
  954. (1, "crypto_bignum_div;sae_test_pwd_seed_ffc") ]
  955. for count, func in tests:
  956. with fail_test(dev[0], count, func):
  957. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
  958. scan_freq="2412", wait_connect=False)
  959. wait_fail_trigger(dev[0], "GET_FAIL")
  960. dev[0].request("REMOVE_NETWORK all")
  961. def test_sae_invalid_anti_clogging_token_req(dev, apdev):
  962. """SAE and invalid anti-clogging token request"""
  963. if "SAE" not in dev[0].get_capability("auth_alg"):
  964. raise HwsimSkip("SAE not supported")
  965. params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
  966. params['wpa_key_mgmt'] = 'SAE'
  967. # Beacon more frequently since Probe Request frames are practically ignored
  968. # in this test setup (ext_mgmt_frame_handled=1 on hostapd side) and
  969. # wpa_supplicant scans may end up getting ignored if no new results are
  970. # available due to the missing Probe Response frames.
  971. params['beacon_int'] = '20'
  972. hapd = hostapd.add_ap(apdev[0], params)
  973. bssid = apdev[0]['bssid']
  974. dev[0].request("SET sae_groups 19")
  975. dev[0].scan_for_bss(bssid, freq=2412)
  976. hapd.set("ext_mgmt_frame_handling", "1")
  977. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
  978. scan_freq="2412", wait_connect=False)
  979. ev = dev[0].wait_event(["SME: Trying to authenticate"])
  980. if ev is None:
  981. raise Exception("No authentication attempt seen (1)")
  982. dev[0].dump_monitor()
  983. for i in range(0, 10):
  984. req = hapd.mgmt_rx()
  985. if req is None:
  986. raise Exception("MGMT RX wait timed out (commit)")
  987. if req['subtype'] == 11:
  988. break
  989. req = None
  990. if not req:
  991. raise Exception("Authentication frame (commit) not received")
  992. hapd.dump_monitor()
  993. resp = {}
  994. resp['fc'] = req['fc']
  995. resp['da'] = req['sa']
  996. resp['sa'] = req['da']
  997. resp['bssid'] = req['bssid']
  998. resp['payload'] = binascii.unhexlify("030001004c0013")
  999. hapd.mgmt_tx(resp)
  1000. ev = hapd.wait_event(["MGMT-TX-STATUS"], timeout=5)
  1001. if ev is None:
  1002. raise Exception("Management frame TX status not reported (1)")
  1003. if "stype=11 ok=1" not in ev:
  1004. raise Exception("Unexpected management frame TX status (1): " + ev)
  1005. ev = dev[0].wait_event(["SME: Trying to authenticate"])
  1006. if ev is None:
  1007. raise Exception("No authentication attempt seen (2)")
  1008. dev[0].dump_monitor()
  1009. for i in range(0, 10):
  1010. req = hapd.mgmt_rx()
  1011. if req is None:
  1012. raise Exception("MGMT RX wait timed out (commit) (2)")
  1013. if req['subtype'] == 11:
  1014. break
  1015. req = None
  1016. if not req:
  1017. raise Exception("Authentication frame (commit) not received (2)")
  1018. hapd.dump_monitor()
  1019. resp = {}
  1020. resp['fc'] = req['fc']
  1021. resp['da'] = req['sa']
  1022. resp['sa'] = req['da']
  1023. resp['bssid'] = req['bssid']
  1024. resp['payload'] = binascii.unhexlify("030001000100")
  1025. hapd.mgmt_tx(resp)
  1026. ev = hapd.wait_event(["MGMT-TX-STATUS"], timeout=5)
  1027. if ev is None:
  1028. raise Exception("Management frame TX status not reported (1)")
  1029. if "stype=11 ok=1" not in ev:
  1030. raise Exception("Unexpected management frame TX status (1): " + ev)
  1031. ev = dev[0].wait_event(["SME: Trying to authenticate"])
  1032. if ev is None:
  1033. raise Exception("No authentication attempt seen (3)")
  1034. dev[0].dump_monitor()
  1035. dev[0].request("DISCONNECT")
  1036. def test_sae_password(dev, apdev):
  1037. """SAE and sae_password in hostapd configuration"""
  1038. if "SAE" not in dev[0].get_capability("auth_alg"):
  1039. raise HwsimSkip("SAE not supported")
  1040. params = hostapd.wpa2_params(ssid="test-sae",
  1041. passphrase="12345678")
  1042. params['wpa_key_mgmt'] = 'SAE WPA-PSK'
  1043. params['sae_password'] = "sae-password"
  1044. hapd = hostapd.add_ap(apdev[0], params)
  1045. dev[0].request("SET sae_groups ")
  1046. dev[0].connect("test-sae", psk="sae-password", key_mgmt="SAE",
  1047. scan_freq="2412")
  1048. dev[1].connect("test-sae", psk="12345678", scan_freq="2412")
  1049. dev[2].request("SET sae_groups ")
  1050. dev[2].connect("test-sae", sae_password="sae-password", key_mgmt="SAE",
  1051. scan_freq="2412")
  1052. def test_sae_password_short(dev, apdev):
  1053. """SAE and short password"""
  1054. if "SAE" not in dev[0].get_capability("auth_alg"):
  1055. raise HwsimSkip("SAE not supported")
  1056. params = hostapd.wpa2_params(ssid="test-sae")
  1057. params['wpa_key_mgmt'] = 'SAE'
  1058. params['sae_password'] = "secret"
  1059. hapd = hostapd.add_ap(apdev[0], params)
  1060. dev[0].request("SET sae_groups ")
  1061. dev[0].connect("test-sae", sae_password="secret", key_mgmt="SAE",
  1062. scan_freq="2412")
  1063. def test_sae_password_long(dev, apdev):
  1064. """SAE and long password"""
  1065. if "SAE" not in dev[0].get_capability("auth_alg"):
  1066. raise HwsimSkip("SAE not supported")
  1067. params = hostapd.wpa2_params(ssid="test-sae")
  1068. params['wpa_key_mgmt'] = 'SAE'
  1069. params['sae_password'] = 100*"A"
  1070. hapd = hostapd.add_ap(apdev[0], params)
  1071. dev[0].request("SET sae_groups ")
  1072. dev[0].connect("test-sae", sae_password=100*"A", key_mgmt="SAE",
  1073. scan_freq="2412")
  1074. def test_sae_connect_cmd(dev, apdev):
  1075. """SAE with connect command"""
  1076. wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
  1077. wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
  1078. if "SAE" not in wpas.get_capability("auth_alg"):
  1079. raise HwsimSkip("SAE not supported")
  1080. params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
  1081. params['wpa_key_mgmt'] = 'SAE'
  1082. hapd = hostapd.add_ap(apdev[0], params)
  1083. wpas.request("SET sae_groups ")
  1084. wpas.connect("test-sae", psk="12345678", key_mgmt="SAE",
  1085. scan_freq="2412", wait_connect=False)
  1086. # mac80211_hwsim does not support SAE offload, so accept both a successful
  1087. # connection and association rejection.
  1088. ev = wpas.wait_event(["CTRL-EVENT-CONNECTED", "CTRL-EVENT-ASSOC-REJECT",
  1089. "Association request to the driver failed"],
  1090. timeout=15)
  1091. if ev is None:
  1092. raise Exception("No connection result reported")