test_suite_b.py 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. # Suite B tests
  2. # Copyright (c) 2014-2015, 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. import time
  7. import logging
  8. logger = logging.getLogger()
  9. import hostapd
  10. from utils import HwsimSkip, fail_test
  11. def check_suite_b_capa(dev):
  12. if "GCMP" not in dev[0].get_capability("pairwise"):
  13. raise HwsimSkip("GCMP not supported")
  14. if "BIP-GMAC-128" not in dev[0].get_capability("group_mgmt"):
  15. raise HwsimSkip("BIP-GMAC-128 not supported")
  16. if "WPA-EAP-SUITE-B" not in dev[0].get_capability("key_mgmt"):
  17. raise HwsimSkip("WPA-EAP-SUITE-B not supported")
  18. check_suite_b_tls_lib(dev)
  19. def check_suite_b_tls_lib(dev):
  20. tls = dev[0].request("GET tls_library")
  21. if not tls.startswith("OpenSSL"):
  22. raise HwsimSkip("TLS library not supported for Suite B: " + tls)
  23. supported = False
  24. for ver in [ '1.0.2', '1.1.0' ]:
  25. if "build=OpenSSL " + ver in tls and "run=OpenSSL " + ver in tls:
  26. supported = True
  27. break
  28. if not supported:
  29. raise HwsimSkip("OpenSSL version not supported for Suite B: " + tls)
  30. def suite_b_ap_params():
  31. params = { "ssid": "test-suite-b",
  32. "wpa": "2",
  33. "wpa_key_mgmt": "WPA-EAP-SUITE-B",
  34. "rsn_pairwise": "GCMP",
  35. "group_mgmt_cipher": "BIP-GMAC-128",
  36. "ieee80211w": "2",
  37. "ieee8021x": "1",
  38. "openssl_ciphers": "SUITEB128",
  39. #"dh_file": "auth_serv/dh.conf",
  40. "eap_server": "1",
  41. "eap_user_file": "auth_serv/eap_user.conf",
  42. "ca_cert": "auth_serv/ec-ca.pem",
  43. "server_cert": "auth_serv/ec-server.pem",
  44. "private_key": "auth_serv/ec-server.key" }
  45. return params
  46. def test_suite_b(dev, apdev):
  47. """WPA2/GCMP connection at Suite B 128-bit level"""
  48. check_suite_b_capa(dev)
  49. dev[0].flush_scan_cache()
  50. params = suite_b_ap_params()
  51. hapd = hostapd.add_ap(apdev[0], params)
  52. dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B", ieee80211w="2",
  53. openssl_ciphers="SUITEB128",
  54. eap="TLS", identity="tls user",
  55. ca_cert="auth_serv/ec-ca.pem",
  56. client_cert="auth_serv/ec-user.pem",
  57. private_key="auth_serv/ec-user.key",
  58. pairwise="GCMP", group="GCMP", scan_freq="2412")
  59. tls_cipher = dev[0].get_status_field("EAP TLS cipher")
  60. if tls_cipher != "ECDHE-ECDSA-AES128-GCM-SHA256":
  61. raise Exception("Unexpected TLS cipher: " + tls_cipher)
  62. bss = dev[0].get_bss(apdev[0]['bssid'])
  63. if 'flags' not in bss:
  64. raise Exception("Could not get BSS flags from BSS table")
  65. if "[WPA2-EAP-SUITE-B-GCMP]" not in bss['flags']:
  66. raise Exception("Unexpected BSS flags: " + bss['flags'])
  67. dev[0].request("DISCONNECT")
  68. dev[0].wait_disconnected(timeout=20)
  69. dev[0].dump_monitor()
  70. dev[0].request("RECONNECT")
  71. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
  72. "CTRL-EVENT-CONNECTED"], timeout=20)
  73. if ev is None:
  74. raise Exception("Roaming with the AP timed out")
  75. if "CTRL-EVENT-EAP-STARTED" in ev:
  76. raise Exception("Unexpected EAP exchange")
  77. conf = hapd.get_config()
  78. if conf['key_mgmt'] != 'WPA-EAP-SUITE-B':
  79. raise Exception("Unexpected config key_mgmt: " + conf['key_mgmt'])
  80. def suite_b_as_params():
  81. params = {}
  82. params['ssid'] = 'as'
  83. params['beacon_int'] = '2000'
  84. params['radius_server_clients'] = 'auth_serv/radius_clients.conf'
  85. params['radius_server_auth_port'] = '18129'
  86. params['eap_server'] = '1'
  87. params['eap_user_file'] = 'auth_serv/eap_user.conf'
  88. params['ca_cert'] = 'auth_serv/ec-ca.pem'
  89. params['server_cert'] = 'auth_serv/ec-server.pem'
  90. params['private_key'] = 'auth_serv/ec-server.key'
  91. params['openssl_ciphers'] = 'SUITEB128'
  92. return params
  93. def test_suite_b_radius(dev, apdev):
  94. """WPA2/GCMP (RADIUS) connection at Suite B 128-bit level"""
  95. check_suite_b_capa(dev)
  96. dev[0].flush_scan_cache()
  97. params = suite_b_as_params()
  98. hostapd.add_ap(apdev[1], params)
  99. params = { "ssid": "test-suite-b",
  100. "wpa": "2",
  101. "wpa_key_mgmt": "WPA-EAP-SUITE-B",
  102. "rsn_pairwise": "GCMP",
  103. "group_mgmt_cipher": "BIP-GMAC-128",
  104. "ieee80211w": "2",
  105. "ieee8021x": "1",
  106. 'auth_server_addr': "127.0.0.1",
  107. 'auth_server_port': "18129",
  108. 'auth_server_shared_secret': "radius",
  109. 'nas_identifier': "nas.w1.fi" }
  110. hapd = hostapd.add_ap(apdev[0], params)
  111. dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B", ieee80211w="2",
  112. openssl_ciphers="SUITEB128",
  113. eap="TLS", identity="tls user",
  114. ca_cert="auth_serv/ec-ca.pem",
  115. client_cert="auth_serv/ec-user.pem",
  116. private_key="auth_serv/ec-user.key",
  117. pairwise="GCMP", group="GCMP", scan_freq="2412")
  118. def check_suite_b_192_capa(dev):
  119. if "GCMP-256" not in dev[0].get_capability("pairwise"):
  120. raise HwsimSkip("GCMP-256 not supported")
  121. if "BIP-GMAC-256" not in dev[0].get_capability("group_mgmt"):
  122. raise HwsimSkip("BIP-GMAC-256 not supported")
  123. if "WPA-EAP-SUITE-B-192" not in dev[0].get_capability("key_mgmt"):
  124. raise HwsimSkip("WPA-EAP-SUITE-B-192 not supported")
  125. check_suite_b_tls_lib(dev)
  126. def suite_b_192_ap_params():
  127. params = { "ssid": "test-suite-b",
  128. "wpa": "2",
  129. "wpa_key_mgmt": "WPA-EAP-SUITE-B-192",
  130. "rsn_pairwise": "GCMP-256",
  131. "group_mgmt_cipher": "BIP-GMAC-256",
  132. "ieee80211w": "2",
  133. "ieee8021x": "1",
  134. "openssl_ciphers": "SUITEB192",
  135. "eap_server": "1",
  136. "eap_user_file": "auth_serv/eap_user.conf",
  137. "ca_cert": "auth_serv/ec2-ca.pem",
  138. "server_cert": "auth_serv/ec2-server.pem",
  139. "private_key": "auth_serv/ec2-server.key" }
  140. return params
  141. def test_suite_b_192(dev, apdev):
  142. """WPA2/GCMP-256 connection at Suite B 192-bit level"""
  143. check_suite_b_192_capa(dev)
  144. dev[0].flush_scan_cache()
  145. params = suite_b_192_ap_params()
  146. hapd = hostapd.add_ap(apdev[0], params)
  147. dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B-192",
  148. ieee80211w="2",
  149. openssl_ciphers="SUITEB192",
  150. eap="TLS", identity="tls user",
  151. ca_cert="auth_serv/ec2-ca.pem",
  152. client_cert="auth_serv/ec2-user.pem",
  153. private_key="auth_serv/ec2-user.key",
  154. pairwise="GCMP-256", group="GCMP-256", scan_freq="2412")
  155. tls_cipher = dev[0].get_status_field("EAP TLS cipher")
  156. if tls_cipher != "ECDHE-ECDSA-AES256-GCM-SHA384":
  157. raise Exception("Unexpected TLS cipher: " + tls_cipher)
  158. cipher = dev[0].get_status_field("mgmt_group_cipher")
  159. if cipher != "BIP-GMAC-256":
  160. raise Exception("Unexpected mgmt_group_cipher: " + cipher)
  161. bss = dev[0].get_bss(apdev[0]['bssid'])
  162. if 'flags' not in bss:
  163. raise Exception("Could not get BSS flags from BSS table")
  164. if "[WPA2-EAP-SUITE-B-192-GCMP-256]" not in bss['flags']:
  165. raise Exception("Unexpected BSS flags: " + bss['flags'])
  166. dev[0].request("DISCONNECT")
  167. dev[0].wait_disconnected(timeout=20)
  168. dev[0].dump_monitor()
  169. dev[0].request("RECONNECT")
  170. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
  171. "CTRL-EVENT-CONNECTED"], timeout=20)
  172. if ev is None:
  173. raise Exception("Roaming with the AP timed out")
  174. if "CTRL-EVENT-EAP-STARTED" in ev:
  175. raise Exception("Unexpected EAP exchange")
  176. conf = hapd.get_config()
  177. if conf['key_mgmt'] != 'WPA-EAP-SUITE-B-192':
  178. raise Exception("Unexpected config key_mgmt: " + conf['key_mgmt'])
  179. def test_suite_b_192_radius(dev, apdev):
  180. """WPA2/GCMP-256 (RADIUS) connection at Suite B 192-bit level"""
  181. check_suite_b_192_capa(dev)
  182. dev[0].flush_scan_cache()
  183. params = suite_b_as_params()
  184. params['ca_cert'] = 'auth_serv/ec2-ca.pem'
  185. params['server_cert'] = 'auth_serv/ec2-server.pem'
  186. params['private_key'] = 'auth_serv/ec2-server.key'
  187. params['openssl_ciphers'] = 'SUITEB192'
  188. hostapd.add_ap(apdev[1], params)
  189. params = { "ssid": "test-suite-b",
  190. "wpa": "2",
  191. "wpa_key_mgmt": "WPA-EAP-SUITE-B-192",
  192. "rsn_pairwise": "GCMP-256",
  193. "group_mgmt_cipher": "BIP-GMAC-256",
  194. "ieee80211w": "2",
  195. "ieee8021x": "1",
  196. 'auth_server_addr': "127.0.0.1",
  197. 'auth_server_port': "18129",
  198. 'auth_server_shared_secret': "radius",
  199. 'nas_identifier': "nas.w1.fi" }
  200. hapd = hostapd.add_ap(apdev[0], params)
  201. dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B-192",
  202. ieee80211w="2",
  203. openssl_ciphers="SUITEB192",
  204. eap="TLS", identity="tls user",
  205. ca_cert="auth_serv/ec2-ca.pem",
  206. client_cert="auth_serv/ec2-user.pem",
  207. private_key="auth_serv/ec2-user.key",
  208. pairwise="GCMP-256", group="GCMP-256", scan_freq="2412")
  209. def test_suite_b_pmkid_failure(dev, apdev):
  210. """WPA2/GCMP connection at Suite B 128-bit level and PMKID derivation failure"""
  211. check_suite_b_capa(dev)
  212. dev[0].flush_scan_cache()
  213. params = suite_b_ap_params()
  214. hapd = hostapd.add_ap(apdev[0], params)
  215. with fail_test(dev[0], 1, "rsn_pmkid_suite_b"):
  216. dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B",
  217. ieee80211w="2",
  218. openssl_ciphers="SUITEB128",
  219. eap="TLS", identity="tls user",
  220. ca_cert="auth_serv/ec-ca.pem",
  221. client_cert="auth_serv/ec-user.pem",
  222. private_key="auth_serv/ec-user.key",
  223. pairwise="GCMP", group="GCMP", scan_freq="2412")
  224. def test_suite_b_192_pmkid_failure(dev, apdev):
  225. """WPA2/GCMP-256 connection at Suite B 192-bit level and PMKID derivation failure"""
  226. check_suite_b_192_capa(dev)
  227. dev[0].flush_scan_cache()
  228. params = suite_b_192_ap_params()
  229. hapd = hostapd.add_ap(apdev[0], params)
  230. with fail_test(dev[0], 1, "rsn_pmkid_suite_b"):
  231. dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B-192",
  232. ieee80211w="2",
  233. openssl_ciphers="SUITEB192",
  234. eap="TLS", identity="tls user",
  235. ca_cert="auth_serv/ec2-ca.pem",
  236. client_cert="auth_serv/ec2-user.pem",
  237. private_key="auth_serv/ec2-user.key",
  238. pairwise="GCMP-256", group="GCMP-256", scan_freq="2412")
  239. def test_suite_b_mic_failure(dev, apdev):
  240. """WPA2/GCMP connection at Suite B 128-bit level and MIC derivation failure"""
  241. check_suite_b_capa(dev)
  242. dev[0].flush_scan_cache()
  243. params = suite_b_ap_params()
  244. hapd = hostapd.add_ap(apdev[0], params)
  245. with fail_test(dev[0], 1, "wpa_eapol_key_mic"):
  246. dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B",
  247. ieee80211w="2",
  248. openssl_ciphers="SUITEB128",
  249. eap="TLS", identity="tls user",
  250. ca_cert="auth_serv/ec-ca.pem",
  251. client_cert="auth_serv/ec-user.pem",
  252. private_key="auth_serv/ec-user.key",
  253. pairwise="GCMP", group="GCMP", scan_freq="2412",
  254. wait_connect=False)
  255. dev[0].wait_disconnected()
  256. def test_suite_b_192_mic_failure(dev, apdev):
  257. """WPA2/GCMP connection at Suite B 192-bit level and MIC derivation failure"""
  258. check_suite_b_192_capa(dev)
  259. dev[0].flush_scan_cache()
  260. params = suite_b_192_ap_params()
  261. hapd = hostapd.add_ap(apdev[0], params)
  262. with fail_test(dev[0], 1, "wpa_eapol_key_mic"):
  263. dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B-192",
  264. ieee80211w="2",
  265. openssl_ciphers="SUITEB192",
  266. eap="TLS", identity="tls user",
  267. ca_cert="auth_serv/ec2-ca.pem",
  268. client_cert="auth_serv/ec2-user.pem",
  269. private_key="auth_serv/ec2-user.key",
  270. pairwise="GCMP-256", group="GCMP-256", scan_freq="2412",
  271. wait_connect=False)
  272. dev[0].wait_disconnected()
  273. def suite_b_192_rsa_ap_params():
  274. params = { "ssid": "test-suite-b",
  275. "wpa": "2",
  276. "wpa_key_mgmt": "WPA-EAP-SUITE-B-192",
  277. "rsn_pairwise": "GCMP-256",
  278. "group_mgmt_cipher": "BIP-GMAC-256",
  279. "ieee80211w": "2",
  280. "ieee8021x": "1",
  281. "tls_flags": "[SUITEB]",
  282. "dh_file": "auth_serv/dh_param_3072.pem",
  283. "eap_server": "1",
  284. "eap_user_file": "auth_serv/eap_user.conf",
  285. "ca_cert": "auth_serv/rsa3072-ca.pem",
  286. "server_cert": "auth_serv/rsa3072-server.pem",
  287. "private_key": "auth_serv/rsa3072-server.key" }
  288. return params
  289. def test_suite_b_192_rsa(dev, apdev):
  290. """WPA2/GCMP-256 connection at Suite B 192-bit level and RSA"""
  291. run_suite_b_192_rsa(dev, apdev)
  292. def test_suite_b_192_rsa_ecdhe(dev, apdev):
  293. """WPA2/GCMP-256 connection at Suite B 192-bit level and RSA (ECDHE)"""
  294. run_suite_b_192_rsa(dev, apdev, no_dhe=True)
  295. def test_suite_b_192_rsa_dhe(dev, apdev):
  296. """WPA2/GCMP-256 connection at Suite B 192-bit level and RSA (DHE)"""
  297. run_suite_b_192_rsa(dev, apdev, no_ecdh=True)
  298. def run_suite_b_192_rsa(dev, apdev, no_ecdh=False, no_dhe=False):
  299. check_suite_b_192_capa(dev)
  300. dev[0].flush_scan_cache()
  301. params = suite_b_192_rsa_ap_params()
  302. if no_ecdh:
  303. params["tls_flags"] = "[SUITEB-NO-ECDH]"
  304. if no_dhe:
  305. del params["dh_file"]
  306. hapd = hostapd.add_ap(apdev[0], params)
  307. dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B-192",
  308. ieee80211w="2",
  309. phase1="tls_suiteb=1",
  310. eap="TLS", identity="tls user",
  311. ca_cert="auth_serv/rsa3072-ca.pem",
  312. client_cert="auth_serv/rsa3072-user.pem",
  313. private_key="auth_serv/rsa3072-user.key",
  314. pairwise="GCMP-256", group="GCMP-256", scan_freq="2412")
  315. tls_cipher = dev[0].get_status_field("EAP TLS cipher")
  316. if tls_cipher != "ECDHE-RSA-AES256-GCM-SHA384" and tls_cipher != "DHE-RSA-AES256-GCM-SHA384":
  317. raise Exception("Unexpected TLS cipher: " + tls_cipher)
  318. cipher = dev[0].get_status_field("mgmt_group_cipher")
  319. if cipher != "BIP-GMAC-256":
  320. raise Exception("Unexpected mgmt_group_cipher: " + cipher)
  321. bss = dev[0].get_bss(apdev[0]['bssid'])
  322. if 'flags' not in bss:
  323. raise Exception("Could not get BSS flags from BSS table")
  324. if "[WPA2-EAP-SUITE-B-192-GCMP-256]" not in bss['flags']:
  325. raise Exception("Unexpected BSS flags: " + bss['flags'])
  326. dev[0].request("DISCONNECT")
  327. dev[0].wait_disconnected(timeout=20)
  328. dev[0].dump_monitor()
  329. dev[0].request("RECONNECT")
  330. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
  331. "CTRL-EVENT-CONNECTED"], timeout=20)
  332. if ev is None:
  333. raise Exception("Roaming with the AP timed out")
  334. if "CTRL-EVENT-EAP-STARTED" in ev:
  335. raise Exception("Unexpected EAP exchange")
  336. conf = hapd.get_config()
  337. if conf['key_mgmt'] != 'WPA-EAP-SUITE-B-192':
  338. raise Exception("Unexpected config key_mgmt: " + conf['key_mgmt'])
  339. def test_suite_b_192_rsa_insufficient_key(dev, apdev):
  340. """WPA2/GCMP-256 connection at Suite B 192-bit level and RSA with insufficient key length"""
  341. check_suite_b_192_capa(dev)
  342. dev[0].flush_scan_cache()
  343. params = suite_b_192_rsa_ap_params()
  344. params["ca_cert"] = "auth_serv/ca.pem"
  345. params["server_cert"] = "auth_serv/server.pem"
  346. params["private_key"] = "auth_serv/server.key"
  347. hapd = hostapd.add_ap(apdev[0], params)
  348. dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B-192",
  349. ieee80211w="2",
  350. phase1="tls_suiteb=1",
  351. eap="TLS", identity="tls user",
  352. ca_cert="auth_serv/ca.pem",
  353. client_cert="auth_serv/user.pem",
  354. private_key="auth_serv/user.key",
  355. pairwise="GCMP-256", group="GCMP-256", scan_freq="2412",
  356. wait_connect=False)
  357. ev = dev[0].wait_event(["CTRL-EVENT-EAP-TLS-CERT-ERROR"], timeout=10)
  358. dev[0].request("DISCONNECT")
  359. if ev is None:
  360. raise Exception("Certificate error not reported")
  361. if "reason=11" not in ev or "err='Insufficient RSA modulus size'" not in ev:
  362. raise Exception("Unexpected error reason: " + ev)
  363. def test_suite_b_192_rsa_insufficient_dh(dev, apdev):
  364. """WPA2/GCMP-256 connection at Suite B 192-bit level and RSA with insufficient DH key length"""
  365. check_suite_b_192_capa(dev)
  366. dev[0].flush_scan_cache()
  367. params = suite_b_192_rsa_ap_params()
  368. params["tls_flags"] = "[SUITEB-NO-ECDH]"
  369. params["dh_file"] = "auth_serv/dh.conf"
  370. hapd = hostapd.add_ap(apdev[0], params)
  371. dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B-192",
  372. ieee80211w="2",
  373. phase1="tls_suiteb=1",
  374. eap="TLS", identity="tls user",
  375. ca_cert="auth_serv/rsa3072-ca.pem",
  376. client_cert="auth_serv/rsa3072-user.pem",
  377. private_key="auth_serv/rsa3072-user.key",
  378. pairwise="GCMP-256", group="GCMP-256", scan_freq="2412",
  379. wait_connect=False)
  380. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STATUS status='local TLS alert'"],
  381. timeout=10)
  382. dev[0].request("DISCONNECT")
  383. if ev is None:
  384. raise Exception("DH error not reported")
  385. if "insufficient security" not in ev and "internal error" not in ev:
  386. raise Exception("Unexpected error reason: " + ev)