test_sae.py 47 KB

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