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
7import time
8import logging
9logger = logging.getLogger()
10
11import hostapd
12from utils import HwsimSkip, fail_test
13from test_ap_eap import check_tls13_support
14
15def check_suite_b_capa(dev):
16    if "GCMP" not in dev[0].get_capability("pairwise"):
17        raise HwsimSkip("GCMP not supported")
18    if "BIP-GMAC-128" not in dev[0].get_capability("group_mgmt"):
19        raise HwsimSkip("BIP-GMAC-128 not supported")
20    if "WPA-EAP-SUITE-B" not in dev[0].get_capability("key_mgmt"):
21        raise HwsimSkip("WPA-EAP-SUITE-B not supported")
22    check_suite_b_tls_lib(dev, level128=True)
23
24def check_suite_b_tls_lib(dev, dhe=False, level128=False):
25    tls = dev[0].request("GET tls_library")
26    if tls.startswith("GnuTLS"):
27        return
28    if tls.startswith("wolfSSL"):
29        return
30    if not tls.startswith("OpenSSL"):
31        raise HwsimSkip("TLS library not supported for Suite B: " + tls)
32    supported = False
33    for ver in ['1.0.2', '1.1.0', '1.1.1', '3.']:
34        if "build=OpenSSL " + ver in tls and "run=OpenSSL " + ver in tls:
35            supported = True
36            break
37        if not dhe and not level128 and "build=OpenSSL " + ver in tls and "run=BoringSSL" in tls:
38            supported = True
39            break
40    if not supported:
41        raise HwsimSkip("OpenSSL version not supported for Suite B: " + tls)
42
43def suite_b_ap_params():
44    params = {"ssid": "test-suite-b",
45              "wpa": "2",
46              "wpa_key_mgmt": "WPA-EAP-SUITE-B",
47              "rsn_pairwise": "GCMP",
48              "group_mgmt_cipher": "BIP-GMAC-128",
49              "ieee80211w": "2",
50              "ieee8021x": "1",
51              "openssl_ciphers": "SUITEB128",
52              #"dh_file": "auth_serv/dh.conf",
53              "eap_server": "1",
54              "eap_user_file": "auth_serv/eap_user.conf",
55              "ca_cert": "auth_serv/ec-ca.pem",
56              "server_cert": "auth_serv/ec-server.pem",
57              "private_key": "auth_serv/ec-server.key"}
58    return params
59
60def test_suite_b(dev, apdev):
61    """WPA2/GCMP connection at Suite B 128-bit level"""
62    check_suite_b_capa(dev)
63    dev[0].flush_scan_cache()
64    params = suite_b_ap_params()
65    hapd = hostapd.add_ap(apdev[0], params)
66
67    dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B", ieee80211w="2",
68                   openssl_ciphers="SUITEB128",
69                   eap="TLS", identity="tls user",
70                   ca_cert="auth_serv/ec-ca.pem",
71                   client_cert="auth_serv/ec-user.pem",
72                   private_key="auth_serv/ec-user.key",
73                   pairwise="GCMP", group="GCMP", scan_freq="2412")
74    hapd.wait_sta()
75    tls_cipher = dev[0].get_status_field("EAP TLS cipher")
76    if tls_cipher != "ECDHE-ECDSA-AES128-GCM-SHA256" and \
77       tls_cipher != "ECDHE-ECDSA-AES-128-GCM-AEAD":
78        raise Exception("Unexpected TLS cipher: " + tls_cipher)
79
80    bss = dev[0].get_bss(apdev[0]['bssid'])
81    if 'flags' not in bss:
82        raise Exception("Could not get BSS flags from BSS table")
83    if "[WPA2-EAP-SUITE-B-GCMP]" not in bss['flags']:
84        raise Exception("Unexpected BSS flags: " + bss['flags'])
85
86    dev[0].request("DISCONNECT")
87    dev[0].wait_disconnected(timeout=20)
88    dev[0].dump_monitor()
89    dev[0].request("RECONNECT")
90    ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
91                            "CTRL-EVENT-CONNECTED"], timeout=20)
92    if ev is None:
93        raise Exception("Roaming with the AP timed out")
94    if "CTRL-EVENT-EAP-STARTED" in ev:
95        raise Exception("Unexpected EAP exchange")
96
97    conf = hapd.get_config()
98    if conf['key_mgmt'] != 'WPA-EAP-SUITE-B':
99        raise Exception("Unexpected config key_mgmt: " + conf['key_mgmt'])
100
101    hapd.wait_sta()
102    dev[0].request("DISCONNECT")
103    dev[0].wait_disconnected(timeout=20)
104    dev[0].dump_monitor()
105    dev[0].request("RECONNECT")
106    ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
107                            "CTRL-EVENT-CONNECTED"], timeout=20)
108    if ev is None:
109        raise Exception("Roaming with the AP timed out (2)")
110    if "CTRL-EVENT-EAP-STARTED" in ev:
111        raise Exception("Unexpected EAP exchange (2)")
112
113def suite_b_as_params():
114    params = {}
115    params['ssid'] = 'as'
116    params['beacon_int'] = '2000'
117    params['radius_server_clients'] = 'auth_serv/radius_clients.conf'
118    params['radius_server_auth_port'] = '18129'
119    params['eap_server'] = '1'
120    params['eap_user_file'] = 'auth_serv/eap_user.conf'
121    params['ca_cert'] = 'auth_serv/ec-ca.pem'
122    params['server_cert'] = 'auth_serv/ec-server.pem'
123    params['private_key'] = 'auth_serv/ec-server.key'
124    params['openssl_ciphers'] = 'SUITEB128'
125    return params
126
127def test_suite_b_radius(dev, apdev):
128    """WPA2/GCMP (RADIUS) connection at Suite B 128-bit level"""
129    check_suite_b_capa(dev)
130    dev[0].flush_scan_cache()
131    params = suite_b_as_params()
132    hostapd.add_ap(apdev[1], params)
133
134    params = {"ssid": "test-suite-b",
135              "wpa": "2",
136              "wpa_key_mgmt": "WPA-EAP-SUITE-B",
137              "rsn_pairwise": "GCMP",
138              "group_mgmt_cipher": "BIP-GMAC-128",
139              "ieee80211w": "2",
140              "ieee8021x": "1",
141              'auth_server_addr': "127.0.0.1",
142              'auth_server_port': "18129",
143              'auth_server_shared_secret': "radius",
144              'nas_identifier': "nas.w1.fi"}
145    hapd = hostapd.add_ap(apdev[0], params)
146
147    dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B", ieee80211w="2",
148                   openssl_ciphers="SUITEB128",
149                   eap="TLS", identity="tls user",
150                   ca_cert="auth_serv/ec-ca.pem",
151                   client_cert="auth_serv/ec-user.pem",
152                   private_key="auth_serv/ec-user.key",
153                   pairwise="GCMP", group="GCMP", scan_freq="2412")
154
155def check_suite_b_192_capa(dev, dhe=False):
156    if "GCMP-256" not in dev[0].get_capability("pairwise"):
157        raise HwsimSkip("GCMP-256 not supported")
158    if "BIP-GMAC-256" not in dev[0].get_capability("group_mgmt"):
159        raise HwsimSkip("BIP-GMAC-256 not supported")
160    if "WPA-EAP-SUITE-B-192" not in dev[0].get_capability("key_mgmt"):
161        raise HwsimSkip("WPA-EAP-SUITE-B-192 not supported")
162    check_suite_b_tls_lib(dev, dhe=dhe)
163
164def suite_b_192_ap_params():
165    params = {"ssid": "test-suite-b",
166              "wpa": "2",
167              "wpa_key_mgmt": "WPA-EAP-SUITE-B-192",
168              "rsn_pairwise": "GCMP-256",
169              "group_mgmt_cipher": "BIP-GMAC-256",
170              "ieee80211w": "2",
171              "ieee8021x": "1",
172              "openssl_ciphers": "SUITEB192",
173              "eap_server": "1",
174              "eap_user_file": "auth_serv/eap_user.conf",
175              "ca_cert": "auth_serv/ec2-ca.pem",
176              "server_cert": "auth_serv/ec2-server.pem",
177              "private_key": "auth_serv/ec2-server.key"}
178    return params
179
180def test_suite_b_192(dev, apdev):
181    """WPA2/GCMP-256 connection at Suite B 192-bit level"""
182    check_suite_b_192_capa(dev)
183    dev[0].flush_scan_cache()
184    params = suite_b_192_ap_params()
185    hapd = hostapd.add_ap(apdev[0], params)
186
187    dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B-192",
188                   ieee80211w="2",
189                   openssl_ciphers="SUITEB192",
190                   eap="TLS", identity="tls user",
191                   ca_cert="auth_serv/ec2-ca.pem",
192                   client_cert="auth_serv/ec2-user.pem",
193                   private_key="auth_serv/ec2-user.key",
194                   pairwise="GCMP-256", group="GCMP-256", scan_freq="2412")
195    tls_cipher = dev[0].get_status_field("EAP TLS cipher")
196    if tls_cipher != "ECDHE-ECDSA-AES256-GCM-SHA384" and \
197       tls_cipher != "ECDHE-ECDSA-AES-256-GCM-AEAD":
198        raise Exception("Unexpected TLS cipher: " + tls_cipher)
199    cipher = dev[0].get_status_field("mgmt_group_cipher")
200    if cipher != "BIP-GMAC-256":
201        raise Exception("Unexpected mgmt_group_cipher: " + cipher)
202
203    bss = dev[0].get_bss(apdev[0]['bssid'])
204    if 'flags' not in bss:
205        raise Exception("Could not get BSS flags from BSS table")
206    if "[WPA2-EAP-SUITE-B-192-GCMP-256]" not in bss['flags']:
207        raise Exception("Unexpected BSS flags: " + bss['flags'])
208
209    hapd.wait_sta()
210    dev[0].request("DISCONNECT")
211    dev[0].wait_disconnected(timeout=20)
212    dev[0].dump_monitor()
213    dev[0].request("RECONNECT")
214    ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
215                            "CTRL-EVENT-CONNECTED"], timeout=20)
216    if ev is None:
217        raise Exception("Roaming with the AP timed out")
218    if "CTRL-EVENT-EAP-STARTED" in ev:
219        raise Exception("Unexpected EAP exchange")
220
221    conf = hapd.get_config()
222    if conf['key_mgmt'] != 'WPA-EAP-SUITE-B-192':
223        raise Exception("Unexpected config key_mgmt: " + conf['key_mgmt'])
224
225    hapd.wait_sta()
226    dev[0].request("DISCONNECT")
227    dev[0].wait_disconnected(timeout=20)
228    dev[0].dump_monitor()
229    dev[0].request("RECONNECT")
230    ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
231                            "CTRL-EVENT-CONNECTED"], timeout=20)
232    if ev is None:
233        raise Exception("Roaming with the AP timed out (2)")
234    if "CTRL-EVENT-EAP-STARTED" in ev:
235        raise Exception("Unexpected EAP exchange (2)")
236
237def test_suite_b_192_radius(dev, apdev):
238    """WPA2/GCMP-256 (RADIUS) connection at Suite B 192-bit level"""
239    check_suite_b_192_capa(dev)
240    dev[0].flush_scan_cache()
241    params = suite_b_as_params()
242    params['ca_cert'] = 'auth_serv/ec2-ca.pem'
243    params['server_cert'] = 'auth_serv/ec2-server.pem'
244    params['private_key'] = 'auth_serv/ec2-server.key'
245    params['openssl_ciphers'] = 'SUITEB192'
246    hostapd.add_ap(apdev[1], params)
247
248    params = {"ssid": "test-suite-b",
249              "wpa": "2",
250              "wpa_key_mgmt": "WPA-EAP-SUITE-B-192",
251              "rsn_pairwise": "GCMP-256",
252              "group_mgmt_cipher": "BIP-GMAC-256",
253              "ieee80211w": "2",
254              "ieee8021x": "1",
255              'auth_server_addr': "127.0.0.1",
256              'auth_server_port': "18129",
257              'auth_server_shared_secret': "radius",
258              'nas_identifier': "nas.w1.fi"}
259    hapd = hostapd.add_ap(apdev[0], params)
260
261    dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B-192",
262                   ieee80211w="2",
263                   openssl_ciphers="SUITEB192",
264                   eap="TLS", identity="tls user",
265                   ca_cert="auth_serv/ec2-ca.pem",
266                   client_cert="auth_serv/ec2-user.pem",
267                   private_key="auth_serv/ec2-user.key",
268                   pairwise="GCMP-256", group="GCMP-256", scan_freq="2412")
269
270def test_suite_b_192_radius_and_p256_cert(dev, apdev):
271    """Suite B 192-bit level and p256 client cert"""
272    check_suite_b_192_capa(dev)
273    dev[0].flush_scan_cache()
274    params = suite_b_as_params()
275    params['ca_cert'] = 'auth_serv/ec2-ca.pem'
276    params['server_cert'] = 'auth_serv/ec2-server.pem'
277    params['private_key'] = 'auth_serv/ec2-server.key'
278    params['openssl_ciphers'] = 'SUITEB192'
279    hostapd.add_ap(apdev[1], params)
280
281    params = {"ssid": "test-suite-b",
282              "wpa": "2",
283              "wpa_key_mgmt": "WPA-EAP-SUITE-B-192",
284              "rsn_pairwise": "GCMP-256",
285              "group_mgmt_cipher": "BIP-GMAC-256",
286              "ieee80211w": "2",
287              "ieee8021x": "1",
288              'auth_server_addr': "127.0.0.1",
289              'auth_server_port': "18129",
290              'auth_server_shared_secret': "radius",
291              'nas_identifier': "nas.w1.fi"}
292    hapd = hostapd.add_ap(apdev[0], params)
293
294    dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B-192",
295                   ieee80211w="2",
296                   #openssl_ciphers="SUITEB192",
297                   eap="TLS", identity="tls user",
298                   ca_cert="auth_serv/ec2-ca.pem",
299                   client_cert="auth_serv/ec2-user-p256.pem",
300                   private_key="auth_serv/ec2-user-p256.key",
301                   pairwise="GCMP-256", group="GCMP-256", scan_freq="2412",
302                   wait_connect=False)
303    ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
304    if ev is None:
305        raise Exception("EAP-Failure not reported")
306    ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=5)
307    if ev is None:
308        raise Exception("Disconnection not reported")
309    if "reason=23" not in ev:
310        raise Exception("Unexpected disconnection reason: " + ev)
311
312def test_suite_b_pmkid_failure(dev, apdev):
313    """WPA2/GCMP connection at Suite B 128-bit level and PMKID derivation failure"""
314    check_suite_b_capa(dev)
315    dev[0].flush_scan_cache()
316    params = suite_b_ap_params()
317    hapd = hostapd.add_ap(apdev[0], params)
318
319    with fail_test(dev[0], 1, "rsn_pmkid_suite_b"):
320        dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B",
321                       ieee80211w="2",
322                       openssl_ciphers="SUITEB128",
323                       eap="TLS", identity="tls user",
324                       ca_cert="auth_serv/ec-ca.pem",
325                       client_cert="auth_serv/ec-user.pem",
326                       private_key="auth_serv/ec-user.key",
327                       pairwise="GCMP", group="GCMP", scan_freq="2412")
328
329def test_suite_b_192_pmkid_failure(dev, apdev):
330    """WPA2/GCMP-256 connection at Suite B 192-bit level and PMKID derivation failure"""
331    check_suite_b_192_capa(dev)
332    dev[0].flush_scan_cache()
333    params = suite_b_192_ap_params()
334    hapd = hostapd.add_ap(apdev[0], params)
335
336    with fail_test(dev[0], 1, "rsn_pmkid_suite_b_192"):
337        dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B-192",
338                       ieee80211w="2",
339                       openssl_ciphers="SUITEB192",
340                       eap="TLS", identity="tls user",
341                       ca_cert="auth_serv/ec2-ca.pem",
342                       client_cert="auth_serv/ec2-user.pem",
343                       private_key="auth_serv/ec2-user.key",
344                       pairwise="GCMP-256", group="GCMP-256", scan_freq="2412")
345
346def test_suite_b_mic_failure(dev, apdev):
347    """WPA2/GCMP connection at Suite B 128-bit level and MIC derivation failure"""
348    check_suite_b_capa(dev)
349    dev[0].flush_scan_cache()
350    params = suite_b_ap_params()
351    hapd = hostapd.add_ap(apdev[0], params)
352
353    with fail_test(dev[0], 1, "wpa_eapol_key_mic"):
354        dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B",
355                       ieee80211w="2",
356                       openssl_ciphers="SUITEB128",
357                       eap="TLS", identity="tls user",
358                       ca_cert="auth_serv/ec-ca.pem",
359                       client_cert="auth_serv/ec-user.pem",
360                       private_key="auth_serv/ec-user.key",
361                       pairwise="GCMP", group="GCMP", scan_freq="2412",
362                       wait_connect=False)
363        dev[0].wait_disconnected()
364
365def test_suite_b_192_mic_failure(dev, apdev):
366    """WPA2/GCMP connection at Suite B 192-bit level and MIC derivation failure"""
367    check_suite_b_192_capa(dev)
368    dev[0].flush_scan_cache()
369    params = suite_b_192_ap_params()
370    hapd = hostapd.add_ap(apdev[0], params)
371
372    with fail_test(dev[0], 1, "wpa_eapol_key_mic"):
373        dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B-192",
374                       ieee80211w="2",
375                       openssl_ciphers="SUITEB192",
376                       eap="TLS", identity="tls user",
377                       ca_cert="auth_serv/ec2-ca.pem",
378                       client_cert="auth_serv/ec2-user.pem",
379                       private_key="auth_serv/ec2-user.key",
380                       pairwise="GCMP-256", group="GCMP-256", scan_freq="2412",
381                       wait_connect=False)
382        dev[0].wait_disconnected()
383
384def suite_b_192_rsa_ap_params():
385    params = {"ssid": "test-suite-b",
386              "wpa": "2",
387              "wpa_key_mgmt": "WPA-EAP-SUITE-B-192",
388              "rsn_pairwise": "GCMP-256",
389              "group_mgmt_cipher": "BIP-GMAC-256",
390              "ieee80211w": "2",
391              "ieee8021x": "1",
392              "tls_flags": "[SUITEB]",
393              "dh_file": "auth_serv/dh_param_3072.pem",
394              "eap_server": "1",
395              "eap_user_file": "auth_serv/eap_user.conf",
396              "ca_cert": "auth_serv/rsa3072-ca.pem",
397              "server_cert": "auth_serv/rsa3072-server.pem",
398              "private_key": "auth_serv/rsa3072-server.key"}
399    return params
400
401def test_suite_b_192_rsa(dev, apdev):
402    """WPA2/GCMP-256 connection at Suite B 192-bit level and RSA"""
403    run_suite_b_192_rsa(dev, apdev)
404
405def test_suite_b_192_rsa_tls_13(dev, apdev):
406    """WPA2/GCMP-256 connection at Suite B 192-bit level and RSA (TLS v1.3)"""
407    check_tls13_support(dev[0])
408    run_suite_b_192_rsa(dev, apdev, tls13=True)
409
410def test_suite_b_192_rsa_ecdhe(dev, apdev):
411    """WPA2/GCMP-256 connection at Suite B 192-bit level and RSA (ECDHE)"""
412    run_suite_b_192_rsa(dev, apdev, no_dhe=True)
413
414def test_suite_b_192_rsa_dhe(dev, apdev):
415    """WPA2/GCMP-256 connection at Suite B 192-bit level and RSA (DHE)"""
416    run_suite_b_192_rsa(dev, apdev, no_ecdh=True)
417
418def run_suite_b_192_rsa(dev, apdev, no_ecdh=False, no_dhe=False, tls13=False):
419    check_suite_b_192_capa(dev, dhe=no_ecdh)
420    dev[0].flush_scan_cache()
421    params = suite_b_192_rsa_ap_params()
422    tls_flags = ""
423    if no_ecdh:
424        tls_flags += "[SUITEB-NO-ECDH]"
425    if no_dhe:
426        del params["dh_file"]
427    if tls13:
428        if not no_ecdh:
429            tls_flags += "[SUITEB]"
430        tls_flags += "[ENABLE-TLSv1.3]"
431    if len(tls_flags) > 0:
432        params["tls_flags"] = tls_flags
433    hapd = hostapd.add_ap(apdev[0], params)
434
435    phase1 = "tls_suiteb=1"
436    if tls13:
437        phase1 += " tls_disable_tlsv1_0=1 tls_disable_tlsv1_1=1 tls_disable_tlsv1_2=1 tls_disable_tlsv1_3=0"
438    dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B-192",
439                   ieee80211w="2",
440                   phase1=phase1,
441                   eap="TLS", identity="tls user",
442                   ca_cert="auth_serv/rsa3072-ca.pem",
443                   client_cert="auth_serv/rsa3072-user.pem",
444                   private_key="auth_serv/rsa3072-user.key",
445                   pairwise="GCMP-256", group="GCMP-256", scan_freq="2412")
446    ver = dev[0].get_status_field("eap_tls_version")
447    logger.info("TLS version: " + ver)
448    if tls13 and ver != "TLSv1.3":
449        raise Exception("Unexpected TLS version: " + ver)
450    tls_cipher = dev[0].get_status_field("EAP TLS cipher")
451    if tls_cipher != "ECDHE-RSA-AES256-GCM-SHA384" and \
452       tls_cipher != "DHE-RSA-AES256-GCM-SHA384" and \
453       tls_cipher != "ECDHE-RSA-AES-256-GCM-AEAD" and \
454       tls_cipher != "DHE-RSA-AES-256-GCM-AEAD" and \
455       tls_cipher != "TLS_AES_256_GCM_SHA384":
456        raise Exception("Unexpected TLS cipher: " + tls_cipher)
457    cipher = dev[0].get_status_field("mgmt_group_cipher")
458    if cipher != "BIP-GMAC-256":
459        raise Exception("Unexpected mgmt_group_cipher: " + cipher)
460
461    bss = dev[0].get_bss(apdev[0]['bssid'])
462    if 'flags' not in bss:
463        raise Exception("Could not get BSS flags from BSS table")
464    if "[WPA2-EAP-SUITE-B-192-GCMP-256]" not in bss['flags']:
465        raise Exception("Unexpected BSS flags: " + bss['flags'])
466
467    hapd.wait_sta()
468    dev[0].request("DISCONNECT")
469    dev[0].wait_disconnected(timeout=20)
470    dev[0].dump_monitor()
471    dev[0].request("RECONNECT")
472    ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
473                            "CTRL-EVENT-CONNECTED"], timeout=20)
474    if ev is None:
475        raise Exception("Roaming with the AP timed out")
476    if "CTRL-EVENT-EAP-STARTED" in ev:
477        raise Exception("Unexpected EAP exchange")
478
479    conf = hapd.get_config()
480    if conf['key_mgmt'] != 'WPA-EAP-SUITE-B-192':
481        raise Exception("Unexpected config key_mgmt: " + conf['key_mgmt'])
482
483def test_suite_b_192_rsa_insufficient_key(dev, apdev):
484    """WPA2/GCMP-256 connection at Suite B 192-bit level and RSA with insufficient key length"""
485    check_suite_b_192_capa(dev)
486    dev[0].flush_scan_cache()
487    params = suite_b_192_rsa_ap_params()
488    params["ca_cert"] = "auth_serv/ca.pem"
489    params["server_cert"] = "auth_serv/server.pem"
490    params["private_key"] = "auth_serv/server.key"
491
492    try:
493        hapd = hostapd.add_ap(apdev[0], params)
494    except Exception as e:
495        hapd = hostapd.add_ap(apdev[0], suite_b_192_rsa_ap_params())
496        tls = hapd.request("GET tls_library")
497        if tls.startswith("wolfSSL"):
498            # wolfSSL fails immediately during key loading with too short key
499            raise HwsimSkip("Suite B 192-bit too short RSA key testing not supported with wolfSSL")
500        raise
501
502    dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B-192",
503                   ieee80211w="2",
504                   phase1="tls_suiteb=1",
505                   eap="TLS", identity="tls user",
506                   ca_cert="auth_serv/ca.pem",
507                   client_cert="auth_serv/user.pem",
508                   private_key="auth_serv/user.key",
509                   pairwise="GCMP-256", group="GCMP-256", scan_freq="2412",
510                   wait_connect=False)
511    ev = dev[0].wait_event(["CTRL-EVENT-EAP-TLS-CERT-ERROR"], timeout=10)
512    dev[0].request("DISCONNECT")
513    if ev is None:
514        raise Exception("Certificate error not reported")
515    if "reason=11" in ev and "err='Insufficient RSA modulus size'" in ev:
516        return
517    if "reason=11" in ev and "err='RSA key too small'" in ev:
518        return
519    if "reason=7" in ev and "err='certificate uses insecure algorithm'" in ev:
520        return
521    raise Exception("Unexpected error reason: " + ev)
522
523def test_suite_b_192_rsa_insufficient_dh(dev, apdev):
524    """WPA2/GCMP-256 connection at Suite B 192-bit level and RSA with insufficient DH key length"""
525    check_suite_b_192_capa(dev, dhe=True)
526    dev[0].flush_scan_cache()
527    params = suite_b_192_rsa_ap_params()
528    params["tls_flags"] = "[SUITEB-NO-ECDH]"
529    params["dh_file"] = "auth_serv/dh.conf"
530    try:
531        hapd = hostapd.add_ap(apdev[0], params)
532    except:
533        hapd = hostapd.add_ap(apdev[0], suite_b_192_rsa_ap_params())
534        tls = hapd.request("GET tls_library")
535        if tls.startswith("wolfSSL"):
536            # wolfSSL fails immediately during key loading with too short key
537            raise HwsimSkip("Suite B 192-bit too short RSA key testing not supported with wolfSSL")
538        raise
539
540    dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B-192",
541                   ieee80211w="2",
542                   phase1="tls_suiteb=1",
543                   eap="TLS", identity="tls user",
544                   ca_cert="auth_serv/rsa3072-ca.pem",
545                   client_cert="auth_serv/rsa3072-user.pem",
546                   private_key="auth_serv/rsa3072-user.key",
547                   pairwise="GCMP-256", group="GCMP-256", scan_freq="2412",
548                   wait_connect=False)
549    ev = dev[0].wait_event(["CTRL-EVENT-EAP-STATUS status='local TLS alert'",
550                            "CTRL-EVENT-CONNECTED", "CTRL-EVENT-EAP-FAILURE"],
551                           timeout=10)
552    dev[0].request("DISCONNECT")
553    if ev is None:
554        raise Exception("DH error not reported")
555    if "CTRL-EVENT-CONNECTED" in ev:
556        raise Exception("Unexpected connection")
557    if "insufficient security" not in ev and "internal error" not in ev \
558        and "authentication failed" not in ev:
559        raise Exception("Unexpected error reason: " + ev)
560
561def test_suite_b_192_rsa_radius(dev, apdev):
562    """WPA2/GCMP-256 (RADIUS) connection at Suite B 192-bit level and RSA (ECDHE)"""
563    check_suite_b_192_capa(dev)
564    dev[0].flush_scan_cache()
565    params = suite_b_as_params()
566    params['ca_cert'] = 'auth_serv/rsa3072-ca.pem'
567    params['server_cert'] = 'auth_serv/rsa3072-server.pem'
568    params['private_key'] = 'auth_serv/rsa3072-server.key'
569    del params['openssl_ciphers']
570    params["tls_flags"] = "[SUITEB]"
571
572    hostapd.add_ap(apdev[1], params)
573
574    params = {"ssid": "test-suite-b",
575              "wpa": "2",
576              "wpa_key_mgmt": "WPA-EAP-SUITE-B-192",
577              "rsn_pairwise": "GCMP-256",
578              "group_mgmt_cipher": "BIP-GMAC-256",
579              "ieee80211w": "2",
580              "ieee8021x": "1",
581              'auth_server_addr': "127.0.0.1",
582              'auth_server_port': "18129",
583              'auth_server_shared_secret': "radius",
584              'nas_identifier': "nas.w1.fi"}
585    hapd = hostapd.add_ap(apdev[0], params)
586
587    dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B-192",
588                   ieee80211w="2",
589                   openssl_ciphers="ECDHE-RSA-AES256-GCM-SHA384",
590                   phase1="tls_suiteb=1",
591                   eap="TLS", identity="tls user",
592                   ca_cert="auth_serv/rsa3072-ca.pem",
593                   client_cert="auth_serv/rsa3072-user.pem",
594                   private_key="auth_serv/rsa3072-user.key",
595                   pairwise="GCMP-256", group="GCMP-256",
596                   group_mgmt="BIP-GMAC-256", scan_freq="2412")
597    tls_cipher = dev[0].get_status_field("EAP TLS cipher")
598    if tls_cipher != "ECDHE-RSA-AES256-GCM-SHA384" and \
599       tls_cipher != "ECDHE-RSA-AES-256-GCM-AEAD":
600        raise Exception("Unexpected TLS cipher: " + tls_cipher)
601
602def test_suite_b_192_rsa_ecdhe_radius_rsa2048_client(dev, apdev):
603    """Suite B 192-bit level and RSA (ECDHE) and RSA2048 client"""
604    run_suite_b_192_rsa_radius_rsa2048_client(dev, apdev, True)
605
606def test_suite_b_192_rsa_dhe_radius_rsa2048_client(dev, apdev):
607    """Suite B 192-bit level and RSA (DHE) and RSA2048 client"""
608    run_suite_b_192_rsa_radius_rsa2048_client(dev, apdev, False)
609
610def run_suite_b_192_rsa_radius_rsa2048_client(dev, apdev, ecdhe):
611    check_suite_b_192_capa(dev, dhe=not ecdhe)
612    dev[0].flush_scan_cache()
613    params = suite_b_as_params()
614    params['ca_cert'] = 'auth_serv/rsa3072-ca.pem'
615    params['server_cert'] = 'auth_serv/rsa3072-server.pem'
616    params['private_key'] = 'auth_serv/rsa3072-server.key'
617    del params['openssl_ciphers']
618    if ecdhe:
619        params["tls_flags"] = "[SUITEB]"
620        ciphers = "ECDHE-RSA-AES256-GCM-SHA384"
621    else:
622        params["tls_flags"] = "[SUITEB-NO-ECDH]"
623        params["dh_file"] = "auth_serv/dh_param_3072.pem"
624        ciphers = "DHE-RSA-AES256-GCM-SHA384"
625
626    hostapd.add_ap(apdev[1], params)
627
628    params = {"ssid": "test-suite-b",
629              "wpa": "2",
630              "wpa_key_mgmt": "WPA-EAP-SUITE-B-192",
631              "rsn_pairwise": "GCMP-256",
632              "group_mgmt_cipher": "BIP-GMAC-256",
633              "ieee80211w": "2",
634              "ieee8021x": "1",
635              'auth_server_addr': "127.0.0.1",
636              'auth_server_port': "18129",
637              'auth_server_shared_secret': "radius",
638              'nas_identifier': "nas.w1.fi"}
639    hapd = hostapd.add_ap(apdev[0], params)
640
641    dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B-192",
642                   ieee80211w="2",
643                   openssl_ciphers=ciphers,
644                   phase1="tls_suiteb=1",
645                   eap="TLS", identity="tls user",
646                   ca_cert="auth_serv/rsa3072-ca.pem",
647                   client_cert="auth_serv/rsa3072-user-rsa2048.pem",
648                   private_key="auth_serv/rsa3072-user-rsa2048.key",
649                   pairwise="GCMP-256", group="GCMP-256",
650                   group_mgmt="BIP-GMAC-256", scan_freq="2412",
651                   wait_connect=False)
652    ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
653    if ev is None:
654        raise Exception("EAP-Failure not reported")
655    ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=5)
656    if ev is None:
657        raise Exception("Disconnection not reported")
658    if "reason=23" not in ev:
659        raise Exception("Unexpected disconnection reason: " + ev)
660
661def test_openssl_ecdh_curves(dev, apdev):
662    """OpenSSL ECDH curve configuration"""
663    check_suite_b_192_capa(dev)
664    dev[0].flush_scan_cache()
665    params = suite_b_192_ap_params()
666    params['wpa_key_mgmt'] = "WPA-EAP"
667    del params['openssl_ciphers']
668    hapd = hostapd.add_ap(apdev[0], params)
669
670    dev[0].connect("test-suite-b", key_mgmt="WPA-EAP",
671                   ieee80211w="2",
672                   openssl_ciphers="SUITEB192",
673                   eap="TLS", identity="tls user",
674                   ca_cert="auth_serv/ec2-ca.pem",
675                   client_cert="auth_serv/ec2-user.pem",
676                   private_key="auth_serv/ec2-user.key",
677                   pairwise="GCMP-256", group="GCMP-256", scan_freq="2412")
678    dev[0].request("REMOVE_NETWORK all")
679    dev[0].wait_disconnected()
680
681    hapd.disable()
682    hapd.set('openssl_ecdh_curves', 'foo')
683    if "FAIL" not in hapd.request("ENABLE"):
684        raise Exception("Invalid openssl_ecdh_curves value accepted")
685    hapd.set('openssl_ecdh_curves', 'P-384')
686    hapd.enable()
687
688    dev[0].connect("test-suite-b", key_mgmt="WPA-EAP",
689                   ieee80211w="2",
690                   openssl_ciphers="SUITEB192",
691                   eap="TLS", identity="tls user",
692                   ca_cert="auth_serv/ec2-ca.pem",
693                   client_cert="auth_serv/ec2-user.pem",
694                   private_key="auth_serv/ec2-user.key",
695                   pairwise="GCMP-256", group="GCMP-256", scan_freq="2412")
696    dev[0].request("REMOVE_NETWORK all")
697    dev[0].wait_disconnected()
698
699    # Check with server enforcing P-256 and client allowing only P-384
700    hapd.disable()
701    hapd.set('openssl_ecdh_curves', 'P-256')
702    hapd.enable()
703
704    dev[0].connect("test-suite-b", key_mgmt="WPA-EAP",
705                   ieee80211w="2",
706                   openssl_ciphers="SUITEB192",
707                   eap="TLS", identity="tls user",
708                   ca_cert="auth_serv/ec2-ca.pem",
709                   client_cert="auth_serv/ec2-user.pem",
710                   private_key="auth_serv/ec2-user.key",
711                   pairwise="GCMP-256", group="GCMP-256", scan_freq="2412",
712                   wait_connect=False)
713    ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
714    if ev is None:
715        raise Exception("EAP failure not reported")
716    dev[0].request("REMOVE_NETWORK all")
717    dev[0].wait_disconnected()
718
719def test_suite_b_192_pmksa_caching_roam(dev, apdev):
720    """WPA2/GCMP-256 connection at Suite B 192-bit level using PMKSA caching and roaming"""
721    check_suite_b_192_capa(dev)
722    dev[0].flush_scan_cache()
723    params = suite_b_192_ap_params()
724    hapd = hostapd.add_ap(apdev[0], params)
725    bssid = hapd.own_addr()
726
727    dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B-192",
728                   ieee80211w="2",
729                   openssl_ciphers="SUITEB192",
730                   eap="TLS", identity="tls user",
731                   ca_cert="auth_serv/ec2-ca.pem",
732                   client_cert="auth_serv/ec2-user.pem",
733                   private_key="auth_serv/ec2-user.key",
734                   pairwise="GCMP-256", group="GCMP-256", scan_freq="2412")
735    ev = dev[0].wait_event(["PMKSA-CACHE-ADDED"], timeout=5)
736    if ev is None:
737        raise Exception("PMKSA cache entry not added for AP1")
738    hapd.wait_sta()
739    dev[0].dump_monitor()
740
741    hapd2 = hostapd.add_ap(apdev[1], params)
742    bssid2 = hapd2.own_addr()
743    dev[0].scan_for_bss(bssid2, freq=2412)
744    dev[0].request("ROAM " + bssid2)
745    ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
746                            "CTRL-EVENT-CONNECTED"], timeout=20)
747    if ev is None:
748        raise Exception("Roaming with the AP timed out")
749    if "CTRL-EVENT-EAP-STARTED" not in ev:
750        raise Exception("EAP exchange not seen")
751    ev = dev[0].wait_connected()
752    if bssid2 not in ev:
753        raise Exception("Roam to AP2 connected back to AP1")
754    ev = dev[0].wait_event(["PMKSA-CACHE-ADDED"], timeout=5)
755    if ev is None:
756        raise Exception("PMKSA cache entry not added for AP2")
757    hapd2.wait_sta()
758    dev[0].dump_monitor()
759
760    dev[0].request("ROAM " + bssid)
761    ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
762                            "CTRL-EVENT-CONNECTED"], timeout=20)
763    if ev is None:
764        raise Exception("Roaming with the AP timed out")
765    if "CTRL-EVENT-EAP-STARTED" in ev:
766        raise Exception("Unexpected EAP exchange")
767    if bssid not in ev:
768        raise Exception("Roam to AP1 connected back to AP2")
769    hapd.wait_sta()
770    dev[0].dump_monitor()
771
772    dev[0].request("ROAM " + bssid2)
773    ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
774                            "CTRL-EVENT-CONNECTED"], timeout=20)
775    if ev is None:
776        raise Exception("Roaming with the AP timed out")
777    if "CTRL-EVENT-EAP-STARTED" in ev:
778        raise Exception("Unexpected EAP exchange")
779    if bssid2 not in ev:
780        raise Exception("Second roam to AP2 connected back to AP1")
781    hapd2.wait_sta()
782    dev[0].dump_monitor()
783
784def test_suite_b_192_okc(dev, apdev):
785    """WPA3/GCMP-256 connection at Suite B 192-bit level and OKC"""
786    check_suite_b_192_capa(dev)
787    dev[0].flush_scan_cache()
788    params = suite_b_192_ap_params()
789    params['okc'] = "1"
790    hapd = hostapd.add_ap(apdev[0], params)
791    bssid = hapd.own_addr()
792
793    dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B-192",
794                   ieee80211w="2",
795                   openssl_ciphers="SUITEB192",
796                   eap="TLS", identity="tls user",
797                   ca_cert="auth_serv/ec2-ca.pem",
798                   client_cert="auth_serv/ec2-user.pem",
799                   private_key="auth_serv/ec2-user.key",
800                   pairwise="GCMP-256", group="GCMP-256", okc=True,
801                   scan_freq="2412")
802    hapd.wait_sta()
803
804    pmksa = dev[0].get_pmksa(bssid)
805    if pmksa is None:
806        raise Exception("No PMKSA cache entry created")
807    if pmksa['opportunistic'] != '0':
808        raise Exception("Unexpected opportunistic PMKSA cache entry")
809
810    hapd2 = hostapd.add_ap(apdev[1], params)
811    bssid2 = hapd2.own_addr()
812    dev[0].scan_for_bss(bssid2, freq=2412)
813    dev[0].request("ROAM " + bssid2)
814    ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
815                            "CTRL-EVENT-CONNECTED"], timeout=10)
816    if ev is None:
817        raise Exception("Roaming with the AP timed out")
818    if "CTRL-EVENT-EAP-STARTED" in ev:
819        raise Exception("Unexpected EAP exchange")
820    pmksa2 = dev[0].get_pmksa(bssid2)
821    if pmksa2 is None:
822        raise Exception("No PMKSA cache entry created")
823
824    dev[0].request("ROAM " + bssid)
825    ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
826                            "CTRL-EVENT-CONNECTED"], timeout=10)
827    if ev is None:
828        raise Exception("Roaming with the AP timed out")
829    if "CTRL-EVENT-EAP-STARTED" in ev:
830        raise Exception("Unexpected EAP exchange")
831
832    pmksa1b = dev[0].get_pmksa(bssid)
833    if pmksa1b is None:
834        raise Exception("No PMKSA cache entry found")
835    if pmksa['pmkid'] != pmksa1b['pmkid']:
836        raise Exception("Unexpected PMKID change for AP1")
837
838    dev[0].request("ROAM " + bssid2)
839    ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
840                            "CTRL-EVENT-CONNECTED"], timeout=10)
841    if ev is None:
842        raise Exception("Roaming with the AP timed out")
843    if "CTRL-EVENT-EAP-STARTED" in ev:
844        raise Exception("Unexpected EAP exchange")
845    pmksa2b = dev[0].get_pmksa(bssid2)
846    if pmksa2b is None:
847        raise Exception("No PMKSA cache entry created")
848    if pmksa2['pmkid'] != pmksa2b['pmkid']:
849        raise Exception("Unexpected PMKID change for AP2")
850
851def test_suite_b_192_rsa_no_cs_match(dev, apdev):
852    """Suite B 192-bit level RSA failing (no CS match)"""
853    check_suite_b_192_capa(dev)
854    dev[0].flush_scan_cache()
855    params = suite_b_192_rsa_ap_params()
856    params['openssl_ciphers'] = "DHE-RSA-AES256-SHA"
857    hapd = hostapd.add_ap(apdev[0], params)
858
859    dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B-192",
860                   ieee80211w="2",
861                   phase1="tls_suiteb=1",
862                   eap="TLS", identity="tls user",
863                   ca_cert="auth_serv/rsa3072-ca.pem",
864                   client_cert="auth_serv/rsa3072-user.pem",
865                   private_key="auth_serv/rsa3072-user.key",
866                   pairwise="GCMP-256", group="GCMP-256", scan_freq="2412",
867                   wait_connect=False)
868    ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
869    if ev is None:
870        raise Exception("EAP-Failure not reported")
871    ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=5)
872    if ev is None:
873        raise Exception("Disconnection not reported")
874    if "reason=23" not in ev:
875        raise Exception("Unexpected disconnection reason: " + ev)
876