test_sae.py 52 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203
  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. def test_sae_mixed_mfp(dev, apdev):
  229. """Mixed SAE and non-SAE network and MFP required with SAE"""
  230. if "SAE" not in dev[0].get_capability("auth_alg"):
  231. raise HwsimSkip("SAE not supported")
  232. params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
  233. params['wpa_key_mgmt'] = 'SAE WPA-PSK'
  234. params["ieee80211w"] = "1"
  235. params['sae_require_mfp'] = '1'
  236. hostapd.add_ap(apdev[0], params)
  237. dev[0].request("SET sae_groups ")
  238. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", ieee80211w="2",
  239. scan_freq="2412")
  240. dev[0].dump_monitor()
  241. dev[1].request("SET sae_groups ")
  242. dev[1].connect("test-sae", psk="12345678", key_mgmt="SAE", ieee80211w="0",
  243. scan_freq="2412", wait_connect=False)
  244. ev = dev[1].wait_event(["CTRL-EVENT-CONNECTED",
  245. "CTRL-EVENT-ASSOC-REJECT"], timeout=10)
  246. if ev is None:
  247. raise Exception("No connection result reported")
  248. if "CTRL-EVENT-ASSOC-REJECT" not in ev:
  249. raise Exception("SAE connection without MFP was not rejected")
  250. if "status_code=31" not in ev:
  251. raise Exception("Unexpected status code in rejection: " + ev)
  252. dev[1].request("DISCONNECT")
  253. dev[1].dump_monitor()
  254. dev[2].connect("test-sae", psk="12345678", ieee80211w="0", scan_freq="2412")
  255. dev[2].dump_monitor()
  256. @remote_compatible
  257. def test_sae_missing_password(dev, apdev):
  258. """SAE and missing password"""
  259. if "SAE" not in dev[0].get_capability("auth_alg"):
  260. raise HwsimSkip("SAE not supported")
  261. params = hostapd.wpa2_params(ssid="test-sae",
  262. passphrase="12345678")
  263. params['wpa_key_mgmt'] = 'SAE'
  264. hapd = hostapd.add_ap(apdev[0], params)
  265. dev[0].request("SET sae_groups ")
  266. id = dev[0].connect("test-sae",
  267. raw_psk="46b4a73b8a951ad53ebd2e0afdb9c5483257edd4c21d12b7710759da70945858",
  268. key_mgmt="SAE", scan_freq="2412", wait_connect=False)
  269. ev = dev[0].wait_event(['CTRL-EVENT-SSID-TEMP-DISABLED'], timeout=10)
  270. if ev is None:
  271. raise Exception("Invalid network not temporarily disabled")
  272. def test_sae_key_lifetime_in_memory(dev, apdev, params):
  273. """SAE and key lifetime in memory"""
  274. if "SAE" not in dev[0].get_capability("auth_alg"):
  275. raise HwsimSkip("SAE not supported")
  276. password = "5ad144a7c1f5a5503baa6fa01dabc15b1843e8c01662d78d16b70b5cd23cf8b"
  277. p = hostapd.wpa2_params(ssid="test-sae", passphrase=password)
  278. p['wpa_key_mgmt'] = 'SAE'
  279. hapd = hostapd.add_ap(apdev[0], p)
  280. pid = find_wpas_process(dev[0])
  281. dev[0].request("SET sae_groups ")
  282. id = dev[0].connect("test-sae", psk=password, key_mgmt="SAE",
  283. scan_freq="2412")
  284. # The decrypted copy of GTK is freed only after the CTRL-EVENT-CONNECTED
  285. # event has been delivered, so verify that wpa_supplicant has returned to
  286. # eloop before reading process memory.
  287. time.sleep(1)
  288. dev[0].ping()
  289. buf = read_process_memory(pid, password)
  290. dev[0].request("DISCONNECT")
  291. dev[0].wait_disconnected()
  292. dev[0].relog()
  293. sae_k = None
  294. sae_keyseed = None
  295. sae_kck = None
  296. pmk = None
  297. ptk = None
  298. gtk = None
  299. with open(os.path.join(params['logdir'], 'log0'), 'r') as f:
  300. for l in f.readlines():
  301. if "SAE: k - hexdump" in l:
  302. val = l.strip().split(':')[3].replace(' ', '')
  303. sae_k = binascii.unhexlify(val)
  304. if "SAE: keyseed - hexdump" in l:
  305. val = l.strip().split(':')[3].replace(' ', '')
  306. sae_keyseed = binascii.unhexlify(val)
  307. if "SAE: KCK - hexdump" in l:
  308. val = l.strip().split(':')[3].replace(' ', '')
  309. sae_kck = binascii.unhexlify(val)
  310. if "SAE: PMK - hexdump" in l:
  311. val = l.strip().split(':')[3].replace(' ', '')
  312. pmk = binascii.unhexlify(val)
  313. if "WPA: PTK - hexdump" in l:
  314. val = l.strip().split(':')[3].replace(' ', '')
  315. ptk = binascii.unhexlify(val)
  316. if "WPA: Group Key - hexdump" in l:
  317. val = l.strip().split(':')[3].replace(' ', '')
  318. gtk = binascii.unhexlify(val)
  319. if not sae_k or not sae_keyseed or not sae_kck or not pmk or not ptk or not gtk:
  320. raise Exception("Could not find keys from debug log")
  321. if len(gtk) != 16:
  322. raise Exception("Unexpected GTK length")
  323. kck = ptk[0:16]
  324. kek = ptk[16:32]
  325. tk = ptk[32:48]
  326. fname = os.path.join(params['logdir'],
  327. 'sae_key_lifetime_in_memory.memctx-')
  328. logger.info("Checking keys in memory while associated")
  329. get_key_locations(buf, password, "Password")
  330. get_key_locations(buf, pmk, "PMK")
  331. if password not in buf:
  332. raise HwsimSkip("Password not found while associated")
  333. if pmk not in buf:
  334. raise HwsimSkip("PMK not found while associated")
  335. if kck not in buf:
  336. raise Exception("KCK not found while associated")
  337. if kek not in buf:
  338. raise Exception("KEK not found while associated")
  339. #if tk in buf:
  340. # raise Exception("TK found from memory")
  341. verify_not_present(buf, sae_k, fname, "SAE(k)")
  342. verify_not_present(buf, sae_keyseed, fname, "SAE(keyseed)")
  343. verify_not_present(buf, sae_kck, fname, "SAE(KCK)")
  344. logger.info("Checking keys in memory after disassociation")
  345. buf = read_process_memory(pid, password)
  346. # Note: Password is still present in network configuration
  347. # Note: PMK is in PMKSA cache
  348. get_key_locations(buf, password, "Password")
  349. get_key_locations(buf, pmk, "PMK")
  350. verify_not_present(buf, kck, fname, "KCK")
  351. verify_not_present(buf, kek, fname, "KEK")
  352. verify_not_present(buf, tk, fname, "TK")
  353. if gtk in buf:
  354. get_key_locations(buf, gtk, "GTK")
  355. verify_not_present(buf, gtk, fname, "GTK")
  356. verify_not_present(buf, sae_k, fname, "SAE(k)")
  357. verify_not_present(buf, sae_keyseed, fname, "SAE(keyseed)")
  358. verify_not_present(buf, sae_kck, fname, "SAE(KCK)")
  359. dev[0].request("PMKSA_FLUSH")
  360. logger.info("Checking keys in memory after PMKSA cache flush")
  361. buf = read_process_memory(pid, password)
  362. get_key_locations(buf, password, "Password")
  363. get_key_locations(buf, pmk, "PMK")
  364. verify_not_present(buf, pmk, fname, "PMK")
  365. dev[0].request("REMOVE_NETWORK all")
  366. logger.info("Checking keys in memory after network profile removal")
  367. buf = read_process_memory(pid, password)
  368. get_key_locations(buf, password, "Password")
  369. get_key_locations(buf, pmk, "PMK")
  370. verify_not_present(buf, password, fname, "password")
  371. verify_not_present(buf, pmk, fname, "PMK")
  372. verify_not_present(buf, kck, fname, "KCK")
  373. verify_not_present(buf, kek, fname, "KEK")
  374. verify_not_present(buf, tk, fname, "TK")
  375. verify_not_present(buf, gtk, fname, "GTK")
  376. verify_not_present(buf, sae_k, fname, "SAE(k)")
  377. verify_not_present(buf, sae_keyseed, fname, "SAE(keyseed)")
  378. verify_not_present(buf, sae_kck, fname, "SAE(KCK)")
  379. @remote_compatible
  380. def test_sae_oom_wpas(dev, apdev):
  381. """SAE and OOM in wpa_supplicant"""
  382. if "SAE" not in dev[0].get_capability("auth_alg"):
  383. raise HwsimSkip("SAE not supported")
  384. params = hostapd.wpa2_params(ssid="test-sae",
  385. passphrase="12345678")
  386. params['wpa_key_mgmt'] = 'SAE'
  387. hapd = hostapd.add_ap(apdev[0], params)
  388. dev[0].request("SET sae_groups 25")
  389. tls = dev[0].request("GET tls_library")
  390. if "BoringSSL" in tls:
  391. dev[0].request("SET sae_groups 26")
  392. with alloc_fail(dev[0], 1, "sae_set_group"):
  393. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
  394. scan_freq="2412")
  395. dev[0].request("REMOVE_NETWORK all")
  396. dev[0].request("SET sae_groups ")
  397. with alloc_fail(dev[0], 2, "sae_set_group"):
  398. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
  399. scan_freq="2412")
  400. dev[0].request("REMOVE_NETWORK all")
  401. with alloc_fail(dev[0], 1, "wpabuf_alloc;sme_auth_build_sae_commit"):
  402. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
  403. scan_freq="2412")
  404. dev[0].request("REMOVE_NETWORK all")
  405. with alloc_fail(dev[0], 1, "wpabuf_alloc;sme_auth_build_sae_confirm"):
  406. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
  407. scan_freq="2412", wait_connect=False)
  408. wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
  409. dev[0].request("REMOVE_NETWORK all")
  410. with alloc_fail(dev[0], 1, "=sme_authenticate"):
  411. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
  412. scan_freq="2412", wait_connect=False)
  413. wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
  414. dev[0].request("REMOVE_NETWORK all")
  415. with alloc_fail(dev[0], 1, "radio_add_work;sme_authenticate"):
  416. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
  417. scan_freq="2412", wait_connect=False)
  418. wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
  419. dev[0].request("REMOVE_NETWORK all")
  420. @remote_compatible
  421. def test_sae_proto_ecc(dev, apdev):
  422. """SAE protocol testing (ECC)"""
  423. if "SAE" not in dev[0].get_capability("auth_alg"):
  424. raise HwsimSkip("SAE not supported")
  425. params = hostapd.wpa2_params(ssid="test-sae",
  426. passphrase="12345678")
  427. params['wpa_key_mgmt'] = 'SAE'
  428. hapd = hostapd.add_ap(apdev[0], params)
  429. bssid = apdev[0]['bssid']
  430. dev[0].request("SET sae_groups 19")
  431. tests = [ ("Confirm mismatch",
  432. "1300" + "033d3635b39666ed427fd4a3e7d37acec2810afeaf1687f746a14163ff0e6d03" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02f8",
  433. "0000800edebc3f260dc1fe7e0b20888af2b8a3316252ec37388a8504e25b73dc4240"),
  434. ("Commit without even full cyclic group field",
  435. "13",
  436. None),
  437. ("Too short commit",
  438. "1300" + "033d3635b39666ed427fd4a3e7d37acec2810afeaf1687f746a14163ff0e6d03" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02",
  439. None),
  440. ("Invalid commit scalar (0)",
  441. "1300" + "0000000000000000000000000000000000000000000000000000000000000000" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02f8",
  442. None),
  443. ("Invalid commit scalar (1)",
  444. "1300" + "0000000000000000000000000000000000000000000000000000000000000001" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02f8",
  445. None),
  446. ("Invalid commit scalar (> r)",
  447. "1300" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02f8",
  448. None),
  449. ("Commit element not on curve",
  450. "1300" + "033d3635b39666ed427fd4a3e7d37acec2810afeaf1687f746a14163ff0e6d03" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728d0000000000000000000000000000000000000000000000000000000000000000",
  451. None),
  452. ("Invalid commit element (y coordinate > P)",
  453. "1300" + "033d3635b39666ed427fd4a3e7d37acec2810afeaf1687f746a14163ff0e6d03" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
  454. None),
  455. ("Invalid commit element (x coordinate > P)",
  456. "1300" + "033d3635b39666ed427fd4a3e7d37acec2810afeaf1687f746a14163ff0e6d03" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02f8",
  457. None),
  458. ("Different group in commit",
  459. "1400" + "033d3635b39666ed427fd4a3e7d37acec2810afeaf1687f746a14163ff0e6d03" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02f8",
  460. None),
  461. ("Too short confirm",
  462. "1300" + "033d3635b39666ed427fd4a3e7d37acec2810afeaf1687f746a14163ff0e6d03" + "559cb8928db4ce4e3cbd6555e837591995e5ebe503ef36b503d9ca519d63728dd3c7c676b8e8081831b6bc3a64bdf136061a7de175e17d1965bfa41983ed02f8",
  463. "0000800edebc3f260dc1fe7e0b20888af2b8a3316252ec37388a8504e25b73dc42")]
  464. for (note, commit, confirm) in tests:
  465. logger.info(note)
  466. dev[0].scan_for_bss(bssid, freq=2412)
  467. hapd.set("ext_mgmt_frame_handling", "1")
  468. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
  469. scan_freq="2412", wait_connect=False)
  470. logger.info("Commit")
  471. for i in range(0, 10):
  472. req = hapd.mgmt_rx()
  473. if req is None:
  474. raise Exception("MGMT RX wait timed out (commit)")
  475. if req['subtype'] == 11:
  476. break
  477. req = None
  478. if not req:
  479. raise Exception("Authentication frame (commit) not received")
  480. hapd.dump_monitor()
  481. resp = {}
  482. resp['fc'] = req['fc']
  483. resp['da'] = req['sa']
  484. resp['sa'] = req['da']
  485. resp['bssid'] = req['bssid']
  486. resp['payload'] = binascii.unhexlify("030001000000" + commit)
  487. hapd.mgmt_tx(resp)
  488. if confirm:
  489. logger.info("Confirm")
  490. for i in range(0, 10):
  491. req = hapd.mgmt_rx()
  492. if req is None:
  493. raise Exception("MGMT RX wait timed out (confirm)")
  494. if req['subtype'] == 11:
  495. break
  496. req = None
  497. if not req:
  498. raise Exception("Authentication frame (confirm) not received")
  499. hapd.dump_monitor()
  500. resp = {}
  501. resp['fc'] = req['fc']
  502. resp['da'] = req['sa']
  503. resp['sa'] = req['da']
  504. resp['bssid'] = req['bssid']
  505. resp['payload'] = binascii.unhexlify("030002000000" + confirm)
  506. hapd.mgmt_tx(resp)
  507. time.sleep(0.1)
  508. dev[0].request("REMOVE_NETWORK all")
  509. hapd.set("ext_mgmt_frame_handling", "0")
  510. hapd.dump_monitor()
  511. @remote_compatible
  512. def test_sae_proto_ffc(dev, apdev):
  513. """SAE protocol testing (FFC)"""
  514. if "SAE" not in dev[0].get_capability("auth_alg"):
  515. raise HwsimSkip("SAE not supported")
  516. params = hostapd.wpa2_params(ssid="test-sae",
  517. passphrase="12345678")
  518. params['wpa_key_mgmt'] = 'SAE'
  519. hapd = hostapd.add_ap(apdev[0], params)
  520. bssid = apdev[0]['bssid']
  521. dev[0].request("SET sae_groups 2")
  522. tests = [ ("Confirm mismatch",
  523. "0200" + "0c70519d874e3e4930a917cc5e17ea7a26028211159f217bab28b8d6c56691805e49f03249b2c6e22c7c9f86b30e04ccad2deedd5e5108ae07b737c00001c59cd0eb08b1dfc7f1b06a1542e2b6601a963c066e0c65940983a03917ae57a101ce84b5cbbc76ff33ebb990aac2e54aa0f0ab6ec0a58113d927683502b2cb2347d2" + "a8c00117493cdffa5dd671e934bc9cb1a69f39e25e9dd9cd9afd3aea2441a0f5491211c7ba50a753563f9ce943b043557cb71193b28e86ed9544f4289c471bf91b70af5c018cf4663e004165b0fd0bc1d8f3f78adf42eee92bcbc55246fd3ee9f107ab965dc7d4986f23eb71d616ebfe6bfe0a6c1ac5dc1718acee17c9a17486",
  524. "0000f3116a9731f1259622e3eb55d4b3b50ba16f8c5f5565b28e609b180c51460251"),
  525. ("Too short commit",
  526. "0200" + "0c70519d874e3e4930a917cc5e17ea7a26028211159f217bab28b8d6c56691805e49f03249b2c6e22c7c9f86b30e04ccad2deedd5e5108ae07b737c00001c59cd0eb08b1dfc7f1b06a1542e2b6601a963c066e0c65940983a03917ae57a101ce84b5cbbc76ff33ebb990aac2e54aa0f0ab6ec0a58113d927683502b2cb2347d2" + "a8c00117493cdffa5dd671e934bc9cb1a69f39e25e9dd9cd9afd3aea2441a0f5491211c7ba50a753563f9ce943b043557cb71193b28e86ed9544f4289c471bf91b70af5c018cf4663e004165b0fd0bc1d8f3f78adf42eee92bcbc55246fd3ee9f107ab965dc7d4986f23eb71d616ebfe6bfe0a6c1ac5dc1718acee17c9a174",
  527. None),
  528. ("Invalid element (0) in commit",
  529. "0200" + "0c70519d874e3e4930a917cc5e17ea7a26028211159f217bab28b8d6c56691805e49f03249b2c6e22c7c9f86b30e04ccad2deedd5e5108ae07b737c00001c59cd0eb08b1dfc7f1b06a1542e2b6601a963c066e0c65940983a03917ae57a101ce84b5cbbc76ff33ebb990aac2e54aa0f0ab6ec0a58113d927683502b2cb2347d2" + "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  530. None),
  531. ("Invalid element (1) in commit",
  532. "0200" + "0c70519d874e3e4930a917cc5e17ea7a26028211159f217bab28b8d6c56691805e49f03249b2c6e22c7c9f86b30e04ccad2deedd5e5108ae07b737c00001c59cd0eb08b1dfc7f1b06a1542e2b6601a963c066e0c65940983a03917ae57a101ce84b5cbbc76ff33ebb990aac2e54aa0f0ab6ec0a58113d927683502b2cb2347d2" + "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
  533. None),
  534. ("Invalid element (> P) in commit",
  535. "0200" + "0c70519d874e3e4930a917cc5e17ea7a26028211159f217bab28b8d6c56691805e49f03249b2c6e22c7c9f86b30e04ccad2deedd5e5108ae07b737c00001c59cd0eb08b1dfc7f1b06a1542e2b6601a963c066e0c65940983a03917ae57a101ce84b5cbbc76ff33ebb990aac2e54aa0f0ab6ec0a58113d927683502b2cb2347d2" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
  536. None) ]
  537. for (note, commit, confirm) in tests:
  538. logger.info(note)
  539. dev[0].scan_for_bss(bssid, freq=2412)
  540. hapd.set("ext_mgmt_frame_handling", "1")
  541. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
  542. scan_freq="2412", wait_connect=False)
  543. logger.info("Commit")
  544. for i in range(0, 10):
  545. req = hapd.mgmt_rx()
  546. if req is None:
  547. raise Exception("MGMT RX wait timed out (commit)")
  548. if req['subtype'] == 11:
  549. break
  550. req = None
  551. if not req:
  552. raise Exception("Authentication frame (commit) not received")
  553. hapd.dump_monitor()
  554. resp = {}
  555. resp['fc'] = req['fc']
  556. resp['da'] = req['sa']
  557. resp['sa'] = req['da']
  558. resp['bssid'] = req['bssid']
  559. resp['payload'] = binascii.unhexlify("030001000000" + commit)
  560. hapd.mgmt_tx(resp)
  561. if confirm:
  562. logger.info("Confirm")
  563. for i in range(0, 10):
  564. req = hapd.mgmt_rx()
  565. if req is None:
  566. raise Exception("MGMT RX wait timed out (confirm)")
  567. if req['subtype'] == 11:
  568. break
  569. req = None
  570. if not req:
  571. raise Exception("Authentication frame (confirm) not received")
  572. hapd.dump_monitor()
  573. resp = {}
  574. resp['fc'] = req['fc']
  575. resp['da'] = req['sa']
  576. resp['sa'] = req['da']
  577. resp['bssid'] = req['bssid']
  578. resp['payload'] = binascii.unhexlify("030002000000" + confirm)
  579. hapd.mgmt_tx(resp)
  580. time.sleep(0.1)
  581. dev[0].request("REMOVE_NETWORK all")
  582. hapd.set("ext_mgmt_frame_handling", "0")
  583. hapd.dump_monitor()
  584. def test_sae_proto_confirm_replay(dev, apdev):
  585. """SAE protocol testing - Confirm replay"""
  586. if "SAE" not in dev[0].get_capability("auth_alg"):
  587. raise HwsimSkip("SAE not supported")
  588. params = hostapd.wpa2_params(ssid="test-sae",
  589. passphrase="12345678")
  590. params['wpa_key_mgmt'] = 'SAE'
  591. hapd = hostapd.add_ap(apdev[0], params)
  592. bssid = apdev[0]['bssid']
  593. dev[0].request("SET sae_groups 19")
  594. dev[0].scan_for_bss(bssid, freq=2412)
  595. hapd.set("ext_mgmt_frame_handling", "1")
  596. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
  597. scan_freq="2412", wait_connect=False)
  598. logger.info("Commit")
  599. for i in range(0, 10):
  600. req = hapd.mgmt_rx()
  601. if req is None:
  602. raise Exception("MGMT RX wait timed out (commit)")
  603. if req['subtype'] == 11:
  604. break
  605. req = None
  606. if not req:
  607. raise Exception("Authentication frame (commit) not received")
  608. bssid = hapd.own_addr().replace(':', '')
  609. addr = dev[0].own_addr().replace(':', '')
  610. hdr = "b0003a01" + bssid + addr + bssid + "1000"
  611. hapd.dump_monitor()
  612. hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + req['frame'].encode('hex'))
  613. logger.info("Confirm")
  614. for i in range(0, 10):
  615. req = hapd.mgmt_rx()
  616. if req is None:
  617. raise Exception("MGMT RX wait timed out (confirm)")
  618. if req['subtype'] == 11:
  619. break
  620. req = None
  621. if not req:
  622. raise Exception("Authentication frame (confirm) not received")
  623. hapd.dump_monitor()
  624. hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + req['frame'].encode('hex'))
  625. logger.info("Replay Confirm")
  626. hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + req['frame'].encode('hex'))
  627. logger.info("Association Request")
  628. for i in range(0, 10):
  629. req = hapd.mgmt_rx()
  630. if req is None:
  631. raise Exception("MGMT RX wait timed out (AssocReq)")
  632. if req['subtype'] == 0:
  633. break
  634. req = None
  635. if not req:
  636. raise Exception("Association Request frame not received")
  637. hapd.dump_monitor()
  638. hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + req['frame'].encode('hex'))
  639. ev = hapd.wait_event(["MGMT-TX-STATUS"], timeout=5)
  640. if ev is None:
  641. raise Exception("Management frame TX status not reported (1)")
  642. if "stype=1 ok=1" not in ev:
  643. raise Exception("Unexpected management frame TX status (1): " + ev)
  644. cmd = "MGMT_TX_STATUS_PROCESS %s" % (" ".join(ev.split(' ')[1:4]))
  645. if "OK" not in hapd.request(cmd):
  646. raise Exception("MGMT_TX_STATUS_PROCESS failed")
  647. hapd.set("ext_mgmt_frame_handling", "0")
  648. dev[0].wait_connected()
  649. def test_sae_proto_hostapd(dev, apdev):
  650. """SAE protocol testing with hostapd"""
  651. params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
  652. params['wpa_key_mgmt'] = 'SAE'
  653. params['sae_groups'] = "19 65535"
  654. hapd = hostapd.add_ap(apdev[0], params)
  655. hapd.set("ext_mgmt_frame_handling", "1")
  656. bssid = hapd.own_addr().replace(':', '')
  657. addr = "020000000000"
  658. addr2 = "020000000001"
  659. hdr = "b0003a01" + bssid + addr + bssid + "1000"
  660. hdr2 = "b0003a01" + bssid + addr2 + bssid + "1000"
  661. group = "1300"
  662. scalar = "f7df19f4a7fef1d3b895ea1de150b7c5a7a705c8ebb31a52b623e0057908bd93"
  663. element_x = "21931572027f2e953e2a49fab3d992944102cc95aa19515fc068b394fb25ae3c"
  664. element_y = "cb4eeb94d7b0b789abfdb73a67ab9d6d5efa94dd553e0e724a6289821cbce530"
  665. hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + "030001000000" + group + scalar + element_x + element_y)
  666. # "SAE: Not enough data for scalar"
  667. hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + "030001000000" + group + scalar[:-2])
  668. # "SAE: Do not allow group to be changed"
  669. hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + "030001000000" + "ffff" + scalar[:-2])
  670. # "SAE: Unsupported Finite Cyclic Group 65535"
  671. hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr2 + "030001000000" + "ffff" + scalar[:-2])
  672. @remote_compatible
  673. def test_sae_no_ffc_by_default(dev, apdev):
  674. """SAE and default groups rejecting FFC"""
  675. if "SAE" not in dev[0].get_capability("auth_alg"):
  676. raise HwsimSkip("SAE not supported")
  677. params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
  678. params['wpa_key_mgmt'] = 'SAE'
  679. hapd = hostapd.add_ap(apdev[0], params)
  680. dev[0].request("SET sae_groups 5")
  681. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", scan_freq="2412",
  682. wait_connect=False)
  683. ev = dev[0].wait_event(["SME: Trying to authenticate"], timeout=3)
  684. if ev is None:
  685. raise Exception("Did not try to authenticate")
  686. ev = dev[0].wait_event(["SME: Trying to authenticate"], timeout=3)
  687. if ev is None:
  688. raise Exception("Did not try to authenticate (2)")
  689. dev[0].request("REMOVE_NETWORK all")
  690. def sae_reflection_attack(apdev, dev, group):
  691. if "SAE" not in dev.get_capability("auth_alg"):
  692. raise HwsimSkip("SAE not supported")
  693. params = hostapd.wpa2_params(ssid="test-sae",
  694. passphrase="no-knowledge-of-passphrase")
  695. params['wpa_key_mgmt'] = 'SAE'
  696. hapd = hostapd.add_ap(apdev, params)
  697. bssid = apdev['bssid']
  698. dev.scan_for_bss(bssid, freq=2412)
  699. hapd.set("ext_mgmt_frame_handling", "1")
  700. dev.request("SET sae_groups %d" % group)
  701. dev.connect("test-sae", psk="reflection-attack", key_mgmt="SAE",
  702. scan_freq="2412", wait_connect=False)
  703. # Commit
  704. for i in range(0, 10):
  705. req = hapd.mgmt_rx()
  706. if req is None:
  707. raise Exception("MGMT RX wait timed out")
  708. if req['subtype'] == 11:
  709. break
  710. req = None
  711. if not req:
  712. raise Exception("Authentication frame not received")
  713. resp = {}
  714. resp['fc'] = req['fc']
  715. resp['da'] = req['sa']
  716. resp['sa'] = req['da']
  717. resp['bssid'] = req['bssid']
  718. resp['payload'] = req['payload']
  719. hapd.mgmt_tx(resp)
  720. # Confirm
  721. req = hapd.mgmt_rx(timeout=0.5)
  722. if req is not None:
  723. if req['subtype'] == 11:
  724. raise Exception("Unexpected Authentication frame seen")
  725. @remote_compatible
  726. def test_sae_reflection_attack_ecc(dev, apdev):
  727. """SAE reflection attack (ECC)"""
  728. sae_reflection_attack(apdev[0], dev[0], 19)
  729. @remote_compatible
  730. def test_sae_reflection_attack_ffc(dev, apdev):
  731. """SAE reflection attack (FFC)"""
  732. sae_reflection_attack(apdev[0], dev[0], 5)
  733. def sae_reflection_attack_internal(apdev, dev, group):
  734. if "SAE" not in dev.get_capability("auth_alg"):
  735. raise HwsimSkip("SAE not supported")
  736. params = hostapd.wpa2_params(ssid="test-sae",
  737. passphrase="no-knowledge-of-passphrase")
  738. params['wpa_key_mgmt'] = 'SAE'
  739. params['sae_reflection_attack'] = '1'
  740. hapd = hostapd.add_ap(apdev, params)
  741. bssid = apdev['bssid']
  742. dev.scan_for_bss(bssid, freq=2412)
  743. dev.request("SET sae_groups %d" % group)
  744. dev.connect("test-sae", psk="reflection-attack", key_mgmt="SAE",
  745. scan_freq="2412", wait_connect=False)
  746. ev = dev.wait_event(["CTRL-EVENT-CONNECTED"], timeout=1)
  747. if ev is not None:
  748. raise Exception("Unexpected connection")
  749. @remote_compatible
  750. def test_sae_reflection_attack_ecc_internal(dev, apdev):
  751. """SAE reflection attack (ECC) - internal"""
  752. sae_reflection_attack_internal(apdev[0], dev[0], 19)
  753. @remote_compatible
  754. def test_sae_reflection_attack_ffc_internal(dev, apdev):
  755. """SAE reflection attack (FFC) - internal"""
  756. sae_reflection_attack_internal(apdev[0], dev[0], 5)
  757. @remote_compatible
  758. def test_sae_commit_override(dev, apdev):
  759. """SAE commit override (hostapd)"""
  760. if "SAE" not in dev[0].get_capability("auth_alg"):
  761. raise HwsimSkip("SAE not supported")
  762. params = hostapd.wpa2_params(ssid="test-sae",
  763. passphrase="12345678")
  764. params['wpa_key_mgmt'] = 'SAE'
  765. params['sae_commit_override'] = '13ffbad00d215867a7c5ff37d87bb9bdb7cb116e520f71e8d7a794ca2606d537ddc6c099c40e7a25372b80a8fd443cd7dd222c8ea21b8ef372d4b3e316c26a73fd999cc79ad483eb826e7b3893ea332da68fa13224bcdeb4fb18b0584dd100a2c514'
  766. hapd = hostapd.add_ap(apdev[0], params)
  767. dev[0].request("SET sae_groups ")
  768. dev[0].connect("test-sae", psk="test-sae", key_mgmt="SAE",
  769. scan_freq="2412", wait_connect=False)
  770. ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1)
  771. if ev is not None:
  772. raise Exception("Unexpected connection")
  773. @remote_compatible
  774. def test_sae_commit_override2(dev, apdev):
  775. """SAE commit override (wpa_supplicant)"""
  776. if "SAE" not in dev[0].get_capability("auth_alg"):
  777. raise HwsimSkip("SAE not supported")
  778. params = hostapd.wpa2_params(ssid="test-sae",
  779. passphrase="12345678")
  780. params['wpa_key_mgmt'] = 'SAE'
  781. hapd = hostapd.add_ap(apdev[0], params)
  782. dev[0].request("SET sae_groups ")
  783. dev[0].set('sae_commit_override', '13ffbad00d215867a7c5ff37d87bb9bdb7cb116e520f71e8d7a794ca2606d537ddc6c099c40e7a25372b80a8fd443cd7dd222c8ea21b8ef372d4b3e316c26a73fd999cc79ad483eb826e7b3893ea332da68fa13224bcdeb4fb18b0584dd100a2c514')
  784. dev[0].connect("test-sae", psk="test-sae", key_mgmt="SAE",
  785. scan_freq="2412", wait_connect=False)
  786. ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1)
  787. if ev is not None:
  788. raise Exception("Unexpected connection")
  789. @remote_compatible
  790. def test_sae_anti_clogging_proto(dev, apdev):
  791. """SAE anti clogging protocol testing"""
  792. if "SAE" not in dev[0].get_capability("auth_alg"):
  793. raise HwsimSkip("SAE not supported")
  794. params = hostapd.wpa2_params(ssid="test-sae",
  795. passphrase="no-knowledge-of-passphrase")
  796. params['wpa_key_mgmt'] = 'SAE'
  797. hapd = hostapd.add_ap(apdev[0], params)
  798. bssid = apdev[0]['bssid']
  799. dev[0].scan_for_bss(bssid, freq=2412)
  800. hapd.set("ext_mgmt_frame_handling", "1")
  801. dev[0].request("SET sae_groups ")
  802. dev[0].connect("test-sae", psk="anti-cloggign", key_mgmt="SAE",
  803. scan_freq="2412", wait_connect=False)
  804. # Commit
  805. for i in range(0, 10):
  806. req = hapd.mgmt_rx()
  807. if req is None:
  808. raise Exception("MGMT RX wait timed out")
  809. if req['subtype'] == 11:
  810. break
  811. req = None
  812. if not req:
  813. raise Exception("Authentication frame not received")
  814. resp = {}
  815. resp['fc'] = req['fc']
  816. resp['da'] = req['sa']
  817. resp['sa'] = req['da']
  818. resp['bssid'] = req['bssid']
  819. resp['payload'] = binascii.unhexlify("030001004c00" + "ffff00")
  820. hapd.mgmt_tx(resp)
  821. # Confirm (not received due to DH group being rejected)
  822. req = hapd.mgmt_rx(timeout=0.5)
  823. if req is not None:
  824. if req['subtype'] == 11:
  825. raise Exception("Unexpected Authentication frame seen")
  826. @remote_compatible
  827. def test_sae_no_random(dev, apdev):
  828. """SAE and no random numbers available"""
  829. if "SAE" not in dev[0].get_capability("auth_alg"):
  830. raise HwsimSkip("SAE not supported")
  831. params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
  832. params['wpa_key_mgmt'] = 'SAE'
  833. hapd = hostapd.add_ap(apdev[0], params)
  834. dev[0].request("SET sae_groups ")
  835. tests = [ (1, "os_get_random;sae_get_rand"),
  836. (1, "os_get_random;get_rand_1_to_p_1"),
  837. (1, "os_get_random;get_random_qr_qnr"),
  838. (1, "os_get_random;sae_derive_pwe_ecc") ]
  839. for count, func in tests:
  840. with fail_test(dev[0], count, func):
  841. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
  842. scan_freq="2412")
  843. dev[0].request("REMOVE_NETWORK all")
  844. dev[0].wait_disconnected()
  845. @remote_compatible
  846. def test_sae_pwe_failure(dev, apdev):
  847. """SAE and pwe failure"""
  848. if "SAE" not in dev[0].get_capability("auth_alg"):
  849. raise HwsimSkip("SAE not supported")
  850. params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
  851. params['wpa_key_mgmt'] = 'SAE'
  852. params['sae_groups'] = '19 5'
  853. hapd = hostapd.add_ap(apdev[0], params)
  854. dev[0].request("SET sae_groups 19")
  855. with fail_test(dev[0], 1, "hmac_sha256_vector;sae_derive_pwe_ecc"):
  856. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
  857. scan_freq="2412")
  858. dev[0].request("REMOVE_NETWORK all")
  859. dev[0].wait_disconnected()
  860. with fail_test(dev[0], 1, "sae_test_pwd_seed_ecc"):
  861. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
  862. scan_freq="2412")
  863. dev[0].request("REMOVE_NETWORK all")
  864. dev[0].wait_disconnected()
  865. dev[0].request("SET sae_groups 5")
  866. with fail_test(dev[0], 1, "hmac_sha256_vector;sae_derive_pwe_ffc"):
  867. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
  868. scan_freq="2412")
  869. dev[0].request("REMOVE_NETWORK all")
  870. dev[0].wait_disconnected()
  871. dev[0].request("SET sae_groups 5")
  872. with fail_test(dev[0], 1, "sae_test_pwd_seed_ffc"):
  873. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
  874. scan_freq="2412")
  875. dev[0].request("REMOVE_NETWORK all")
  876. dev[0].wait_disconnected()
  877. with fail_test(dev[0], 2, "sae_test_pwd_seed_ffc"):
  878. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
  879. scan_freq="2412")
  880. dev[0].request("REMOVE_NETWORK all")
  881. dev[0].wait_disconnected()
  882. @remote_compatible
  883. def test_sae_bignum_failure(dev, apdev):
  884. """SAE and bignum failure"""
  885. if "SAE" not in dev[0].get_capability("auth_alg"):
  886. raise HwsimSkip("SAE not supported")
  887. params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
  888. params['wpa_key_mgmt'] = 'SAE'
  889. params['sae_groups'] = '19 5 22'
  890. hapd = hostapd.add_ap(apdev[0], params)
  891. dev[0].request("SET sae_groups 19")
  892. tests = [ (1, "crypto_bignum_init_set;get_rand_1_to_p_1"),
  893. (1, "crypto_bignum_init;is_quadratic_residue_blind"),
  894. (1, "crypto_bignum_mulmod;is_quadratic_residue_blind"),
  895. (2, "crypto_bignum_mulmod;is_quadratic_residue_blind"),
  896. (3, "crypto_bignum_mulmod;is_quadratic_residue_blind"),
  897. (1, "crypto_bignum_legendre;is_quadratic_residue_blind"),
  898. (1, "crypto_bignum_init_set;sae_test_pwd_seed_ecc"),
  899. (1, "crypto_ec_point_compute_y_sqr;sae_test_pwd_seed_ecc"),
  900. (1, "crypto_bignum_init_set;get_random_qr_qnr"),
  901. (1, "crypto_bignum_to_bin;sae_derive_pwe_ecc"),
  902. (1, "crypto_ec_point_init;sae_derive_pwe_ecc"),
  903. (1, "crypto_ec_point_solve_y_coord;sae_derive_pwe_ecc"),
  904. (1, "crypto_ec_point_init;sae_derive_commit_element_ecc"),
  905. (1, "crypto_ec_point_mul;sae_derive_commit_element_ecc"),
  906. (1, "crypto_ec_point_invert;sae_derive_commit_element_ecc"),
  907. (1, "crypto_bignum_init;=sae_derive_commit"),
  908. (1, "crypto_ec_point_init;sae_derive_k_ecc"),
  909. (1, "crypto_ec_point_mul;sae_derive_k_ecc"),
  910. (1, "crypto_ec_point_add;sae_derive_k_ecc"),
  911. (2, "crypto_ec_point_mul;sae_derive_k_ecc"),
  912. (1, "crypto_ec_point_to_bin;sae_derive_k_ecc"),
  913. (1, "crypto_bignum_legendre;get_random_qr_qnr"),
  914. (1, "sha256_prf;sae_derive_keys"),
  915. (1, "crypto_bignum_init;sae_derive_keys"),
  916. (1, "crypto_bignum_init_set;sae_parse_commit_scalar"),
  917. (1, "crypto_bignum_to_bin;sae_parse_commit_element_ecc"),
  918. (1, "crypto_ec_point_from_bin;sae_parse_commit_element_ecc") ]
  919. for count, func in tests:
  920. with fail_test(dev[0], count, func):
  921. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
  922. scan_freq="2412", wait_connect=False)
  923. wait_fail_trigger(dev[0], "GET_FAIL")
  924. dev[0].request("REMOVE_NETWORK all")
  925. dev[0].request("SET sae_groups 5")
  926. tests = [ (1, "crypto_bignum_init_set;sae_set_group"),
  927. (2, "crypto_bignum_init_set;sae_set_group"),
  928. (1, "crypto_bignum_init_set;sae_get_rand"),
  929. (1, "crypto_bignum_init_set;sae_test_pwd_seed_ffc"),
  930. (1, "crypto_bignum_exptmod;sae_test_pwd_seed_ffc"),
  931. (1, "crypto_bignum_init;sae_derive_pwe_ffc"),
  932. (1, "crypto_bignum_init;sae_derive_commit_element_ffc"),
  933. (1, "crypto_bignum_exptmod;sae_derive_commit_element_ffc"),
  934. (1, "crypto_bignum_inverse;sae_derive_commit_element_ffc"),
  935. (1, "crypto_bignum_init;sae_derive_k_ffc"),
  936. (1, "crypto_bignum_exptmod;sae_derive_k_ffc"),
  937. (1, "crypto_bignum_mulmod;sae_derive_k_ffc"),
  938. (2, "crypto_bignum_exptmod;sae_derive_k_ffc"),
  939. (1, "crypto_bignum_to_bin;sae_derive_k_ffc"),
  940. (1, "crypto_bignum_init_set;sae_parse_commit_element_ffc"),
  941. (1, "crypto_bignum_init;sae_parse_commit_element_ffc"),
  942. (2, "crypto_bignum_init_set;sae_parse_commit_element_ffc"),
  943. (1, "crypto_bignum_exptmod;sae_parse_commit_element_ffc") ]
  944. for count, func in tests:
  945. with fail_test(dev[0], count, func):
  946. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
  947. scan_freq="2412", wait_connect=False)
  948. wait_fail_trigger(dev[0], "GET_FAIL")
  949. dev[0].request("REMOVE_NETWORK all")
  950. dev[0].request("SET sae_groups 22")
  951. tests = [ (1, "crypto_bignum_init_set;sae_test_pwd_seed_ffc"),
  952. (1, "crypto_bignum_sub;sae_test_pwd_seed_ffc"),
  953. (1, "crypto_bignum_div;sae_test_pwd_seed_ffc") ]
  954. for count, func in tests:
  955. with fail_test(dev[0], count, func):
  956. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
  957. scan_freq="2412", wait_connect=False)
  958. wait_fail_trigger(dev[0], "GET_FAIL")
  959. dev[0].request("REMOVE_NETWORK all")
  960. def test_sae_invalid_anti_clogging_token_req(dev, apdev):
  961. """SAE and invalid anti-clogging token request"""
  962. if "SAE" not in dev[0].get_capability("auth_alg"):
  963. raise HwsimSkip("SAE not supported")
  964. params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
  965. params['wpa_key_mgmt'] = 'SAE'
  966. # Beacon more frequently since Probe Request frames are practically ignored
  967. # in this test setup (ext_mgmt_frame_handled=1 on hostapd side) and
  968. # wpa_supplicant scans may end up getting ignored if no new results are
  969. # available due to the missing Probe Response frames.
  970. params['beacon_int'] = '20'
  971. hapd = hostapd.add_ap(apdev[0], params)
  972. bssid = apdev[0]['bssid']
  973. dev[0].request("SET sae_groups 19")
  974. dev[0].scan_for_bss(bssid, freq=2412)
  975. hapd.set("ext_mgmt_frame_handling", "1")
  976. dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
  977. scan_freq="2412", wait_connect=False)
  978. ev = dev[0].wait_event(["SME: Trying to authenticate"])
  979. if ev is None:
  980. raise Exception("No authentication attempt seen (1)")
  981. dev[0].dump_monitor()
  982. for i in range(0, 10):
  983. req = hapd.mgmt_rx()
  984. if req is None:
  985. raise Exception("MGMT RX wait timed out (commit)")
  986. if req['subtype'] == 11:
  987. break
  988. req = None
  989. if not req:
  990. raise Exception("Authentication frame (commit) not received")
  991. hapd.dump_monitor()
  992. resp = {}
  993. resp['fc'] = req['fc']
  994. resp['da'] = req['sa']
  995. resp['sa'] = req['da']
  996. resp['bssid'] = req['bssid']
  997. resp['payload'] = binascii.unhexlify("030001004c0013")
  998. hapd.mgmt_tx(resp)
  999. ev = hapd.wait_event(["MGMT-TX-STATUS"], timeout=5)
  1000. if ev is None:
  1001. raise Exception("Management frame TX status not reported (1)")
  1002. if "stype=11 ok=1" not in ev:
  1003. raise Exception("Unexpected management frame TX status (1): " + ev)
  1004. ev = dev[0].wait_event(["SME: Trying to authenticate"])
  1005. if ev is None:
  1006. raise Exception("No authentication attempt seen (2)")
  1007. dev[0].dump_monitor()
  1008. for i in range(0, 10):
  1009. req = hapd.mgmt_rx()
  1010. if req is None:
  1011. raise Exception("MGMT RX wait timed out (commit) (2)")
  1012. if req['subtype'] == 11:
  1013. break
  1014. req = None
  1015. if not req:
  1016. raise Exception("Authentication frame (commit) not received (2)")
  1017. hapd.dump_monitor()
  1018. resp = {}
  1019. resp['fc'] = req['fc']
  1020. resp['da'] = req['sa']
  1021. resp['sa'] = req['da']
  1022. resp['bssid'] = req['bssid']
  1023. resp['payload'] = binascii.unhexlify("030001000100")
  1024. hapd.mgmt_tx(resp)
  1025. ev = hapd.wait_event(["MGMT-TX-STATUS"], timeout=5)
  1026. if ev is None:
  1027. raise Exception("Management frame TX status not reported (1)")
  1028. if "stype=11 ok=1" not in ev:
  1029. raise Exception("Unexpected management frame TX status (1): " + ev)
  1030. ev = dev[0].wait_event(["SME: Trying to authenticate"])
  1031. if ev is None:
  1032. raise Exception("No authentication attempt seen (3)")
  1033. dev[0].dump_monitor()
  1034. dev[0].request("DISCONNECT")
  1035. def test_sae_password(dev, apdev):
  1036. """SAE and sae_password in hostapd configuration"""
  1037. if "SAE" not in dev[0].get_capability("auth_alg"):
  1038. raise HwsimSkip("SAE not supported")
  1039. params = hostapd.wpa2_params(ssid="test-sae",
  1040. passphrase="12345678")
  1041. params['wpa_key_mgmt'] = 'SAE WPA-PSK'
  1042. params['sae_password'] = "sae-password"
  1043. hapd = hostapd.add_ap(apdev[0], params)
  1044. dev[0].request("SET sae_groups ")
  1045. dev[0].connect("test-sae", psk="sae-password", key_mgmt="SAE",
  1046. scan_freq="2412")
  1047. dev[1].connect("test-sae", psk="12345678", scan_freq="2412")
  1048. dev[2].request("SET sae_groups ")
  1049. dev[2].connect("test-sae", sae_password="sae-password", key_mgmt="SAE",
  1050. scan_freq="2412")
  1051. def test_sae_password_short(dev, apdev):
  1052. """SAE and short password"""
  1053. if "SAE" not in dev[0].get_capability("auth_alg"):
  1054. raise HwsimSkip("SAE not supported")
  1055. params = hostapd.wpa2_params(ssid="test-sae")
  1056. params['wpa_key_mgmt'] = 'SAE'
  1057. params['sae_password'] = "secret"
  1058. hapd = hostapd.add_ap(apdev[0], params)
  1059. dev[0].request("SET sae_groups ")
  1060. dev[0].connect("test-sae", sae_password="secret", key_mgmt="SAE",
  1061. scan_freq="2412")
  1062. def test_sae_password_long(dev, apdev):
  1063. """SAE and long password"""
  1064. if "SAE" not in dev[0].get_capability("auth_alg"):
  1065. raise HwsimSkip("SAE not supported")
  1066. params = hostapd.wpa2_params(ssid="test-sae")
  1067. params['wpa_key_mgmt'] = 'SAE'
  1068. params['sae_password'] = 100*"A"
  1069. hapd = hostapd.add_ap(apdev[0], params)
  1070. dev[0].request("SET sae_groups ")
  1071. dev[0].connect("test-sae", sae_password=100*"A", key_mgmt="SAE",
  1072. scan_freq="2412")