]>
Commit | Line | Data |
---|---|---|
b652daca | 1 | # Suite B tests |
4113a96b | 2 | # Copyright (c) 2014-2015, Jouni Malinen <j@w1.fi> |
b652daca JM |
3 | # |
4 | # This software may be distributed under the terms of the BSD license. | |
5 | # See README for more details. | |
6 | ||
7 | import time | |
8 | import logging | |
9 | logger = logging.getLogger() | |
10 | ||
11 | import hostapd | |
fe6e56a2 | 12 | from utils import HwsimSkip, fail_test |
b652daca | 13 | |
6e3ee4c5 | 14 | def check_suite_b_capa(dev): |
b652daca | 15 | if "GCMP" not in dev[0].get_capability("pairwise"): |
81e787b7 | 16 | raise HwsimSkip("GCMP not supported") |
4113a96b JM |
17 | if "BIP-GMAC-128" not in dev[0].get_capability("group_mgmt"): |
18 | raise HwsimSkip("BIP-GMAC-128 not supported") | |
19 | if "WPA-EAP-SUITE-B" not in dev[0].get_capability("key_mgmt"): | |
20 | raise HwsimSkip("WPA-EAP-SUITE-B not supported") | |
a2bc326e JM |
21 | check_suite_b_tls_lib(dev) |
22 | ||
23 | def check_suite_b_tls_lib(dev): | |
4113a96b JM |
24 | tls = dev[0].request("GET tls_library") |
25 | if not tls.startswith("OpenSSL"): | |
26 | raise HwsimSkip("TLS library not supported for Suite B: " + tls); | |
a2bc326e JM |
27 | supported = False |
28 | for ver in [ '1.0.2', '1.1.0' ]: | |
29 | if "build=OpenSSL " + ver in tls and "run=OpenSSL " + ver in tls: | |
30 | supported = True | |
31 | break | |
32 | if not supported: | |
4113a96b JM |
33 | raise HwsimSkip("OpenSSL version not supported for Suite B: " + tls) |
34 | ||
fe6e56a2 | 35 | def suite_b_ap_params(): |
4113a96b JM |
36 | params = { "ssid": "test-suite-b", |
37 | "wpa": "2", | |
38 | "wpa_key_mgmt": "WPA-EAP-SUITE-B", | |
39 | "rsn_pairwise": "GCMP", | |
40 | "group_mgmt_cipher": "BIP-GMAC-128", | |
41 | "ieee80211w": "2", | |
42 | "ieee8021x": "1", | |
43 | "openssl_ciphers": "SUITEB128", | |
44 | #"dh_file": "auth_serv/dh.conf", | |
45 | "eap_server": "1", | |
46 | "eap_user_file": "auth_serv/eap_user.conf", | |
47 | "ca_cert": "auth_serv/ec-ca.pem", | |
48 | "server_cert": "auth_serv/ec-server.pem", | |
49 | "private_key": "auth_serv/ec-server.key" } | |
fe6e56a2 JM |
50 | return params |
51 | ||
52 | def test_suite_b(dev, apdev): | |
53 | """WPA2/GCMP connection at Suite B 128-bit level""" | |
54 | check_suite_b_capa(dev) | |
55 | dev[0].flush_scan_cache() | |
56 | params = suite_b_ap_params() | |
b652daca | 57 | hapd = hostapd.add_ap(apdev[0]['ifname'], params) |
4113a96b JM |
58 | |
59 | dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B", ieee80211w="2", | |
60 | openssl_ciphers="SUITEB128", | |
61 | eap="TLS", identity="tls user", | |
62 | ca_cert="auth_serv/ec-ca.pem", | |
63 | client_cert="auth_serv/ec-user.pem", | |
64 | private_key="auth_serv/ec-user.key", | |
b652daca | 65 | pairwise="GCMP", group="GCMP", scan_freq="2412") |
4113a96b JM |
66 | tls_cipher = dev[0].get_status_field("EAP TLS cipher") |
67 | if tls_cipher != "ECDHE-ECDSA-AES128-GCM-SHA256": | |
68 | raise Exception("Unexpected TLS cipher: " + tls_cipher) | |
d463c556 JM |
69 | |
70 | bss = dev[0].get_bss(apdev[0]['bssid']) | |
71 | if 'flags' not in bss: | |
72 | raise Exception("Could not get BSS flags from BSS table") | |
73 | if "[WPA2-EAP-SUITE-B-GCMP]" not in bss['flags']: | |
74 | raise Exception("Unexpected BSS flags: " + bss['flags']) | |
75 | ||
b652daca | 76 | dev[0].request("DISCONNECT") |
5f35a5e2 | 77 | dev[0].wait_disconnected(timeout=20) |
b652daca JM |
78 | dev[0].dump_monitor() |
79 | dev[0].request("RECONNECT") | |
80 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED", | |
81 | "CTRL-EVENT-CONNECTED"], timeout=20) | |
82 | if ev is None: | |
83 | raise Exception("Roaming with the AP timed out") | |
84 | if "CTRL-EVENT-EAP-STARTED" in ev: | |
85 | raise Exception("Unexpected EAP exchange") | |
37551fe3 | 86 | |
6e3ee4c5 JM |
87 | def suite_b_as_params(): |
88 | params = {} | |
89 | params['ssid'] = 'as' | |
90 | params['beacon_int'] = '2000' | |
91 | params['radius_server_clients'] = 'auth_serv/radius_clients.conf' | |
92 | params['radius_server_auth_port'] = '18129' | |
93 | params['eap_server'] = '1' | |
94 | params['eap_user_file'] = 'auth_serv/eap_user.conf' | |
95 | params['ca_cert'] = 'auth_serv/ec-ca.pem' | |
96 | params['server_cert'] = 'auth_serv/ec-server.pem' | |
97 | params['private_key'] = 'auth_serv/ec-server.key' | |
98 | params['openssl_ciphers'] = 'SUITEB128' | |
99 | return params | |
100 | ||
101 | def test_suite_b_radius(dev, apdev): | |
102 | """WPA2/GCMP (RADIUS) connection at Suite B 128-bit level""" | |
103 | check_suite_b_capa(dev) | |
104 | dev[0].flush_scan_cache() | |
105 | params = suite_b_as_params() | |
106 | hostapd.add_ap(apdev[1]['ifname'], params) | |
107 | ||
108 | params = { "ssid": "test-suite-b", | |
109 | "wpa": "2", | |
110 | "wpa_key_mgmt": "WPA-EAP-SUITE-B", | |
111 | "rsn_pairwise": "GCMP", | |
112 | "group_mgmt_cipher": "BIP-GMAC-128", | |
113 | "ieee80211w": "2", | |
114 | "ieee8021x": "1", | |
115 | 'auth_server_addr': "127.0.0.1", | |
116 | 'auth_server_port': "18129", | |
117 | 'auth_server_shared_secret': "radius", | |
118 | 'nas_identifier': "nas.w1.fi" } | |
119 | hapd = hostapd.add_ap(apdev[0]['ifname'], params) | |
120 | ||
121 | dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B", ieee80211w="2", | |
122 | openssl_ciphers="SUITEB128", | |
123 | eap="TLS", identity="tls user", | |
124 | ca_cert="auth_serv/ec-ca.pem", | |
125 | client_cert="auth_serv/ec-user.pem", | |
126 | private_key="auth_serv/ec-user.key", | |
127 | pairwise="GCMP", group="GCMP", scan_freq="2412") | |
128 | ||
129 | def check_suite_b_192_capa(dev): | |
37551fe3 JM |
130 | if "GCMP-256" not in dev[0].get_capability("pairwise"): |
131 | raise HwsimSkip("GCMP-256 not supported") | |
132 | if "BIP-GMAC-256" not in dev[0].get_capability("group_mgmt"): | |
133 | raise HwsimSkip("BIP-GMAC-256 not supported") | |
134 | if "WPA-EAP-SUITE-B-192" not in dev[0].get_capability("key_mgmt"): | |
135 | raise HwsimSkip("WPA-EAP-SUITE-B-192 not supported") | |
a2bc326e | 136 | check_suite_b_tls_lib(dev) |
37551fe3 | 137 | |
fe6e56a2 | 138 | def suite_b_192_ap_params(): |
37551fe3 JM |
139 | params = { "ssid": "test-suite-b", |
140 | "wpa": "2", | |
141 | "wpa_key_mgmt": "WPA-EAP-SUITE-B-192", | |
142 | "rsn_pairwise": "GCMP-256", | |
143 | "group_mgmt_cipher": "BIP-GMAC-256", | |
144 | "ieee80211w": "2", | |
145 | "ieee8021x": "1", | |
146 | "openssl_ciphers": "SUITEB192", | |
147 | "eap_server": "1", | |
148 | "eap_user_file": "auth_serv/eap_user.conf", | |
149 | "ca_cert": "auth_serv/ec2-ca.pem", | |
150 | "server_cert": "auth_serv/ec2-server.pem", | |
151 | "private_key": "auth_serv/ec2-server.key" } | |
fe6e56a2 JM |
152 | return params |
153 | ||
154 | def test_suite_b_192(dev, apdev): | |
155 | """WPA2/GCMP-256 connection at Suite B 192-bit level""" | |
156 | check_suite_b_192_capa(dev) | |
157 | dev[0].flush_scan_cache() | |
158 | params = suite_b_192_ap_params() | |
37551fe3 JM |
159 | hapd = hostapd.add_ap(apdev[0]['ifname'], params) |
160 | ||
161 | dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B-192", | |
162 | ieee80211w="2", | |
163 | openssl_ciphers="SUITEB192", | |
164 | eap="TLS", identity="tls user", | |
165 | ca_cert="auth_serv/ec2-ca.pem", | |
166 | client_cert="auth_serv/ec2-user.pem", | |
167 | private_key="auth_serv/ec2-user.key", | |
168 | pairwise="GCMP-256", group="GCMP-256", scan_freq="2412") | |
169 | tls_cipher = dev[0].get_status_field("EAP TLS cipher") | |
170 | if tls_cipher != "ECDHE-ECDSA-AES256-GCM-SHA384": | |
171 | raise Exception("Unexpected TLS cipher: " + tls_cipher) | |
172 | ||
173 | bss = dev[0].get_bss(apdev[0]['bssid']) | |
174 | if 'flags' not in bss: | |
175 | raise Exception("Could not get BSS flags from BSS table") | |
176 | if "[WPA2-EAP-SUITE-B-192-GCMP-256]" not in bss['flags']: | |
177 | raise Exception("Unexpected BSS flags: " + bss['flags']) | |
178 | ||
179 | dev[0].request("DISCONNECT") | |
180 | dev[0].wait_disconnected(timeout=20) | |
181 | dev[0].dump_monitor() | |
182 | dev[0].request("RECONNECT") | |
183 | ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED", | |
184 | "CTRL-EVENT-CONNECTED"], timeout=20) | |
185 | if ev is None: | |
186 | raise Exception("Roaming with the AP timed out") | |
187 | if "CTRL-EVENT-EAP-STARTED" in ev: | |
188 | raise Exception("Unexpected EAP exchange") | |
6e3ee4c5 JM |
189 | |
190 | def test_suite_b_192_radius(dev, apdev): | |
191 | """WPA2/GCMP-256 (RADIUS) connection at Suite B 192-bit level""" | |
192 | check_suite_b_192_capa(dev) | |
193 | dev[0].flush_scan_cache() | |
194 | params = suite_b_as_params() | |
195 | params['ca_cert'] = 'auth_serv/ec2-ca.pem' | |
196 | params['server_cert'] = 'auth_serv/ec2-server.pem' | |
197 | params['private_key'] = 'auth_serv/ec2-server.key' | |
198 | params['openssl_ciphers'] = 'SUITEB192' | |
199 | hostapd.add_ap(apdev[1]['ifname'], params) | |
200 | ||
201 | params = { "ssid": "test-suite-b", | |
202 | "wpa": "2", | |
203 | "wpa_key_mgmt": "WPA-EAP-SUITE-B-192", | |
204 | "rsn_pairwise": "GCMP-256", | |
205 | "group_mgmt_cipher": "BIP-GMAC-256", | |
206 | "ieee80211w": "2", | |
207 | "ieee8021x": "1", | |
208 | 'auth_server_addr': "127.0.0.1", | |
209 | 'auth_server_port': "18129", | |
210 | 'auth_server_shared_secret': "radius", | |
211 | 'nas_identifier': "nas.w1.fi" } | |
212 | hapd = hostapd.add_ap(apdev[0]['ifname'], params) | |
213 | ||
214 | dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B-192", | |
215 | ieee80211w="2", | |
216 | openssl_ciphers="SUITEB192", | |
217 | eap="TLS", identity="tls user", | |
218 | ca_cert="auth_serv/ec2-ca.pem", | |
219 | client_cert="auth_serv/ec2-user.pem", | |
220 | private_key="auth_serv/ec2-user.key", | |
221 | pairwise="GCMP-256", group="GCMP-256", scan_freq="2412") | |
fe6e56a2 JM |
222 | |
223 | def test_suite_b_pmkid_failure(dev, apdev): | |
224 | """WPA2/GCMP connection at Suite B 128-bit level and PMKID derivation failure""" | |
225 | check_suite_b_capa(dev) | |
226 | dev[0].flush_scan_cache() | |
227 | params = suite_b_ap_params() | |
228 | hapd = hostapd.add_ap(apdev[0]['ifname'], params) | |
229 | ||
230 | with fail_test(dev[0], 1, "rsn_pmkid_suite_b"): | |
231 | dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B", | |
232 | ieee80211w="2", | |
233 | openssl_ciphers="SUITEB128", | |
234 | eap="TLS", identity="tls user", | |
235 | ca_cert="auth_serv/ec-ca.pem", | |
236 | client_cert="auth_serv/ec-user.pem", | |
237 | private_key="auth_serv/ec-user.key", | |
238 | pairwise="GCMP", group="GCMP", scan_freq="2412") | |
239 | ||
240 | def test_suite_b_192_pmkid_failure(dev, apdev): | |
241 | """WPA2/GCMP-256 connection at Suite B 192-bit level and PMKID derivation failure""" | |
242 | check_suite_b_192_capa(dev) | |
243 | dev[0].flush_scan_cache() | |
244 | params = suite_b_192_ap_params() | |
245 | hapd = hostapd.add_ap(apdev[0]['ifname'], params) | |
246 | ||
247 | with fail_test(dev[0], 1, "rsn_pmkid_suite_b"): | |
248 | dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B-192", | |
249 | ieee80211w="2", | |
250 | openssl_ciphers="SUITEB192", | |
251 | eap="TLS", identity="tls user", | |
252 | ca_cert="auth_serv/ec2-ca.pem", | |
253 | client_cert="auth_serv/ec2-user.pem", | |
254 | private_key="auth_serv/ec2-user.key", | |
255 | pairwise="GCMP-256", group="GCMP-256", scan_freq="2412") | |
256 | ||
257 | def test_suite_b_mic_failure(dev, apdev): | |
258 | """WPA2/GCMP connection at Suite B 128-bit level and MIC derivation failure""" | |
259 | check_suite_b_capa(dev) | |
260 | dev[0].flush_scan_cache() | |
261 | params = suite_b_ap_params() | |
262 | hapd = hostapd.add_ap(apdev[0]['ifname'], params) | |
263 | ||
264 | with fail_test(dev[0], 1, "wpa_eapol_key_mic"): | |
265 | dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B", | |
266 | ieee80211w="2", | |
267 | openssl_ciphers="SUITEB128", | |
268 | eap="TLS", identity="tls user", | |
269 | ca_cert="auth_serv/ec-ca.pem", | |
270 | client_cert="auth_serv/ec-user.pem", | |
271 | private_key="auth_serv/ec-user.key", | |
272 | pairwise="GCMP", group="GCMP", scan_freq="2412", | |
273 | wait_connect=False) | |
274 | dev[0].wait_disconnected() | |
275 | ||
276 | def test_suite_b_192_mic_failure(dev, apdev): | |
277 | """WPA2/GCMP connection at Suite B 192-bit level and MIC derivation failure""" | |
278 | check_suite_b_capa(dev) | |
279 | dev[0].flush_scan_cache() | |
280 | params = suite_b_192_ap_params() | |
281 | hapd = hostapd.add_ap(apdev[0]['ifname'], params) | |
282 | ||
283 | with fail_test(dev[0], 1, "wpa_eapol_key_mic"): | |
284 | dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B-192", | |
285 | ieee80211w="2", | |
286 | openssl_ciphers="SUITEB192", | |
287 | eap="TLS", identity="tls user", | |
288 | ca_cert="auth_serv/ec2-ca.pem", | |
289 | client_cert="auth_serv/ec2-user.pem", | |
290 | private_key="auth_serv/ec2-user.key", | |
291 | pairwise="GCMP-256", group="GCMP-256", scan_freq="2412", | |
292 | wait_connect=False) | |
293 | dev[0].wait_disconnected() |