1# Test cases for Device Provisioning Protocol (DPP)
2# Copyright (c) 2017, Qualcomm Atheros, Inc.
3# Copyright (c) 2018-2019, The Linux Foundation
4# Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc.
5#
6# This software may be distributed under the terms of the BSD license.
7# See README for more details.
8
9import base64
10import binascii
11import hashlib
12import logging
13logger = logging.getLogger()
14import os
15import socket
16import struct
17import subprocess
18import time
19try:
20    from socketserver import StreamRequestHandler, TCPServer
21except ImportError:
22    from SocketServer import StreamRequestHandler, TCPServer
23
24import hostapd
25import hwsim_utils
26from hwsim import HWSimRadio
27from utils import *
28from wpasupplicant import WpaSupplicant
29from wlantest import WlantestCapture
30
31try:
32    import OpenSSL
33    openssl_imported = True
34except ImportError:
35    openssl_imported = False
36
37def check_dpp_capab(dev, brainpool=False, min_ver=1):
38    if "UNKNOWN COMMAND" in dev.request("DPP_BOOTSTRAP_GET_URI 0"):
39        raise HwsimSkip("DPP not supported")
40    if brainpool:
41        tls = dev.request("GET tls_library")
42        if (not tls.startswith("OpenSSL") or "run=BoringSSL" in tls) and not tls.startswith("wolfSSL"):
43            raise HwsimSkip("Crypto library does not support Brainpool curves: " + tls)
44    capa = dev.request("GET_CAPABILITY dpp")
45    ver = 1
46    if capa.startswith("DPP="):
47        ver = int(capa[4:])
48    if ver < min_ver:
49        raise HwsimSkip("DPP version %d not supported" % min_ver)
50    return ver
51
52def wait_dpp_fail(dev, expected=None):
53    ev = dev.wait_event(["DPP-FAIL"], timeout=5)
54    if ev is None:
55        raise Exception("Failure not reported")
56    if expected and expected not in ev:
57        raise Exception("Unexpected result: " + ev)
58
59def test_dpp_qr_code_parsing(dev, apdev):
60    """DPP QR Code parsing"""
61    check_dpp_capab(dev[0])
62    id = []
63
64    tests = ["DPP:C:81/1,115/36;K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADM2206avxHJaHXgLMkq/24e0rsrfMP9K1Tm8gx+ovP0I=;;",
65             "DPP:C:81/1,81/2,81/3,81/4,81/5,81/6,81/7,81/8,81/9,81/10,81/11,81/12,81/13,82/14,83/1,83/2,83/3,83/4,83/5,83/6,83/7,83/8,83/9,84/5,84/6,84/7,84/8,84/9,84/10,84/11,84/12,84/13,115/36;K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADM2206avxHJaHXgLMkq/24e0rsrfMP9K1Tm8gx+ovP0I=;;",
66             "DPP:C:81/1,2,3,4,5,6,7,8,9,10,11,12,13,82/14,83/1,2,3,4,5,6,7,8,9,84/5,6,7,8,9,10,11,12,13,115/36;K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADM2206avxHJaHXgLMkq/24e0rsrfMP9K1Tm8gx+ovP0I=;;",
67             "DPP:C:81/1,2,3;K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADM2206avxHJaHXgLMkq/24e0rsrfMP9K1Tm8gx+ovP0I=;;",
68             "DPP:H:192.168.1.1;M:010203040506;K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADURzxmttZoIRIPWGoQMV00XHWCAQIhXruVWOz0NjlkIA=;;",
69             "DPP:H:192.168.1.1:12345;M:010203040506;K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADURzxmttZoIRIPWGoQMV00XHWCAQIhXruVWOz0NjlkIA=;;",
70             "DPP:H:fe80::1234:5678:9abc:def0;M:010203040506;K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADURzxmttZoIRIPWGoQMV00XHWCAQIhXruVWOz0NjlkIA=;;",
71             "DPP:H:[fe80::1234:5678:9abc:def0]:12345;M:010203040506;K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADURzxmttZoIRIPWGoQMV00XHWCAQIhXruVWOz0NjlkIA=;;",
72             "DPP:I:SN=4774LH2b4044;M:010203040506;K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADURzxmttZoIRIPWGoQMV00XHWCAQIhXruVWOz0NjlkIA=;;",
73             "DPP:I:;M:010203040506;K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADURzxmttZoIRIPWGoQMV00XHWCAQIhXruVWOz0NjlkIA=;;"]
74    for uri in tests:
75        id.append(dev[0].dpp_qr_code(uri))
76
77        uri2 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id[-1])
78        if uri != uri2:
79            raise Exception("Returned URI does not match")
80
81    tests = ["foo",
82             "DPP:",
83             "DPP:;;",
84             "DPP:C:1/2;M:;K;;",
85             "DPP:I:;M:01020304050;K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADURzxmttZoIRIPWGoQMV00XHWCAQIhXruVWOz0NjlkIA=;;",
86             "DPP:K:" + base64.b64encode(b"hello").decode() + ";;",
87             "DPP:K:MEkwEwYHKoZIzj0CAQYIKoZIzj0DAQEDMgAEXiJuIWt1Q/CPCkuULechh37UsXPmbUANOeN5U9sOQROE4o/NEFeFEejROHYwwehF;;",
88             "DPP:K:MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANNZaZA4T/kRDjnmpI1ACOJhAuTIIEk2KFOpS6XPpGF+EVr/ao3XemkE0/nzXmGaLzLqTUCJknSdxTnVPeWfCVsCAwEAAQ==;;",
89             "DPP:K:MIIBCjCB0wYHKoZIzj0CATCBxwIBATAkBgcqhkjOPQEBAhkA/////////////////////v//////////MEsEGP////////////////////7//////////AQYZCEFGeWcgOcPp+mrciQwSf643uzBRrmxAxUAMEWub8hCL2TtV5Uo04Eg6uEhltUEMQQYjagOsDCQ9ny/IOtDoYgA9P8K/YL/EBIHGSuV/8jaeGMQEe1rJM3Vc/l3oR55SBECGQD///////////////+Z3vg2FGvJsbTSKDECAQEDMgAEXiJuIWt1Q/CPCkuULechh37UsXPmbUANOeN5U9sOQROE4o/NEFeFEejROHYwwehF;;",
90             "DPP:I:foo\tbar;M:010203040506;K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADURzxmttZoIRIPWGoQMV00XHWCAQIhXruVWOz0NjlkIA=;;",
91             "DPP:C:1;K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADM2206avxHJaHXgLMkqa24e0rsrfMP9K1Tm8gx+ovP0I=;;",
92             "DPP:C:81/1a;K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADM2206avxHJaHXgLMkqa24e0rsrfMP9K1Tm8gx+ovP0I=;;",
93             "DPP:C:1/2000,81/-1;K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADM2206avxHJaHXgLMkqa24e0rsrfMP9K1Tm8gx+ovP0I=;;",
94             "DPP:C:-1/1;K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADM2206avxHJaHXgLMkqa24e0rsrfMP9K1Tm8gx+ovP0I=;;"]
95    for t in tests:
96        res = dev[0].request("DPP_QR_CODE " + t)
97        if "FAIL" not in res:
98            raise Exception("Accepted invalid QR Code: " + t)
99
100    logger.info("ID: " + str(id))
101    if len(id) != len(set(id)):
102        raise Exception("Duplicate ID returned")
103
104    if "FAIL" not in dev[0].request("DPP_BOOTSTRAP_REMOVE 12345678"):
105        raise Exception("DPP_BOOTSTRAP_REMOVE accepted unexpectedly")
106    if "OK" not in dev[0].request("DPP_BOOTSTRAP_REMOVE %d" % id[1]):
107        raise Exception("DPP_BOOTSTRAP_REMOVE failed")
108
109    id = dev[0].dpp_bootstrap_gen()
110    uri = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id)
111    logger.info("Generated URI: " + uri)
112
113    dev[0].dpp_qr_code(uri)
114
115    id = dev[0].dpp_bootstrap_gen(chan="81/1,115/36", mac="010203040506",
116                                  info="foo")
117    uri = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id)
118    logger.info("Generated URI: " + uri)
119
120    dev[0].dpp_qr_code(uri)
121
122def test_dpp_uri_version(dev, apdev):
123    """DPP URI version information"""
124    check_dpp_capab(dev[0], min_ver=2)
125
126    id0 = dev[0].dpp_bootstrap_gen()
127    uri = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
128    logger.info("Generated URI: " + uri)
129
130    id1 = dev[0].dpp_qr_code(uri)
131    uri = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id1)
132    info = dev[0].request("DPP_BOOTSTRAP_INFO %d" % id1)
133    logger.info("Parsed URI info:\n" + info)
134    capa = dev[0].request("GET_CAPABILITY dpp")
135    ver = 1
136    if capa.startswith("DPP="):
137        ver = int(capa[4:])
138    if "version=%d" % ver not in info.splitlines():
139        raise Exception("Unexpected version information (with indication)")
140
141    dev[0].set("dpp_version_override", "1")
142    id0 = dev[0].dpp_bootstrap_gen()
143    uri = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
144    logger.info("Generated URI: " + uri)
145
146    id1 = dev[0].dpp_qr_code(uri)
147    uri = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id1)
148    info = dev[0].request("DPP_BOOTSTRAP_INFO %d" % id1)
149    logger.info("Parsed URI info:\n" + info)
150    if "version=0" not in info.splitlines():
151        raise Exception("Unexpected version information (without indication)")
152
153def test_dpp_uri_supported_curves(dev, apdev):
154    """DPP URI supported curves"""
155    check_dpp_capab(dev[0], min_ver=3)
156
157    tests = [("P-256", "1"),
158             ("P-384", "2"),
159             ("P-521", "4"),
160             ("BP-256", "8"),
161             ("BP-384", "01"),
162             ("BP-512", "02"),
163             ("P-256:P-384:P-521", "7"),
164             ("P-256:BP-512", "12"),
165             ("P-256:P-384:BP-384", "31"),
166             ("P-256:P-384:P-521:BP-256:BP-384:BP-512", "f3")]
167    for t in tests:
168        logger.info("Supported list: " + t[0])
169        id0 = dev[0].dpp_bootstrap_gen(supported_curves=t[0])
170        uri = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
171        logger.info("Generated URI: " + uri)
172        if ";B:%s;" % t[1] not in uri:
173            raise Exception("Supported curves(1) not indicated correctly: " + uri)
174
175        id1 = dev[0].dpp_qr_code(uri)
176        uri = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id1)
177        info = dev[0].request("DPP_BOOTSTRAP_INFO %d" % id1)
178        logger.info("Parsed URI info:\n" + info)
179        if "supp_curves=" + t[0] not in info.splitlines():
180            raise Exception("supp_curves not indicated correctly in info")
181
182def test_dpp_uri_host(dev, apdev):
183    """DPP URI host"""
184    check_dpp_capab(dev[0], min_ver=3)
185
186    tests = [("192.168.1.1", "192.168.1.1 8908"),
187             ("192.168.1.1:12345", "192.168.1.1 12345"),
188             ("fe80::1234:5678:9abc:def0", "fe80::1234:5678:9abc:def0 8908"),
189             ("[fe80::1234:5678:9abc:def0]:12345",
190              "fe80::1234:5678:9abc:def0 12345")]
191    for t in tests:
192        logger.info("host: " + t[0])
193        id0 = dev[0].dpp_bootstrap_gen(host=t[0])
194        uri = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
195        logger.info("Generated URI: " + uri)
196        if ";H:%s;" % t[0] not in uri:
197            raise Exception("host not indicated correctly: " + uri)
198
199        info = dev[0].request("DPP_BOOTSTRAP_INFO %d" % id0)
200        logger.info("Parsed URI info:\n" + info)
201        if "host=" + t[1] not in info.splitlines():
202            raise Exception("host not indicated correctly in info")
203
204def test_dpp_qr_code_parsing_fail(dev, apdev):
205    """DPP QR Code parsing local failure"""
206    check_dpp_capab(dev[0])
207    with alloc_fail(dev[0], 1, "dpp_parse_uri_info"):
208        if "FAIL" not in dev[0].request("DPP_QR_CODE DPP:I:SN=4774LH2b4044;M:010203040506;K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADURzxmttZoIRIPWGoQMV00XHWCAQIhXruVWOz0NjlkIA=;;"):
209            raise Exception("DPP_QR_CODE failure not reported")
210
211    with alloc_fail(dev[0], 1, "dpp_parse_uri_pk"):
212        if "FAIL" not in dev[0].request("DPP_QR_CODE DPP:K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADURzxmttZoIRIPWGoQMV00XHWCAQIhXruVWOz0NjlkIA=;;"):
213            raise Exception("DPP_QR_CODE failure not reported")
214
215    with fail_test(dev[0], 1, "dpp_parse_uri_pk"):
216        if "FAIL" not in dev[0].request("DPP_QR_CODE DPP:K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADURzxmttZoIRIPWGoQMV00XHWCAQIhXruVWOz0NjlkIA=;;"):
217            raise Exception("DPP_QR_CODE failure not reported")
218
219    with alloc_fail(dev[0], 1, "dpp_parse_uri"):
220        if "FAIL" not in dev[0].request("DPP_QR_CODE DPP:I:SN=4774LH2b4044;M:010203040506;K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADURzxmttZoIRIPWGoQMV00XHWCAQIhXruVWOz0NjlkIA=;;"):
221            raise Exception("DPP_QR_CODE failure not reported")
222
223dpp_key_p256 = "30570201010420777fc55dc51e967c10ec051b91d860b5f1e6c934e48d5daffef98d032c64b170a00a06082a8648ce3d030107a124032200020c804188c7f85beb6e91070d2b3e5e39b90ca77b4d3c5251bc1844d6ca29dcad"
224dpp_key_p384 = "307402010104302f56fdd83b5345cacb630eb7c22fa5ad5daba37307c95191e2a75756d137003bd8b32dbcb00eb5650c1eb499ecfcaec0a00706052b81040022a13403320003615ec2141b5b77aebb6523f8a012755f9a34405a8398d2ceeeebca7f5ce868bf55056cba4c4ec62fad3ed26dd29e0f23"
225dpp_key_p521 = "308198020101044200c8010d5357204c252551aaf4e210343111e503fd1dc615b257058997c49b6b643c975226e93be8181cca3d83a7072defd161dfbdf433c19abe1f2ad51867a05761a00706052b81040023a1460344000301cdf3608b1305fe34a1f976095dcf001182b9973354efe156291a66830292f9babd8f412ad462958663e7a75d1d0610abdfc3dd95d40669f7ab3bc001668cfb3b7c"
226dpp_key_bp256 = "3058020101042057133a676fb60bf2a3e6797e19833c7b0f89dc192ab99ab5fa377ae23a157765a00b06092b2403030208010107a12403220002945d9bf7ce30c9c1ac0ff21ca62b984d5bb80ff69d2be8c9716ab39a10d2caf0"
227dpp_key_bp384 = "307802010104304902df9f3033a9b7128554c0851dc7127c3573eed150671dae74c0013e9896a9b1c22b6f7d43d8a2ebb7cd474dc55039a00b06092b240303020801010ba13403320003623cb5e68787f351faababf3425161571560add2e6f9a306fcbffb507735bf955bb46dd20ba246b0d5cadce73e5bd6a6"
228dpp_key_bp512 = "30819802010104405803494226eb7e50bf0e90633f37e7e35d33f5fa502165eeba721d927f9f846caf12e925701d18e123abaaaf4a7edb4fc4de21ce18bc10c4d12e8b3439f74e40a00b06092b240303020801010da144034200033b086ccd47486522d35dc16fbb2229642c2e9e87897d45abbf21f9fb52acb5a6272b31d1b227c3e53720769cc16b4cb181b26cd0d35fe463218aaedf3b6ec00a"
229
230def test_dpp_qr_code_curves(dev, apdev):
231    """DPP QR Code and supported curves"""
232    check_dpp_capab(dev[0])
233    tests = [("prime256v1", dpp_key_p256),
234             ("secp384r1", dpp_key_p384),
235             ("secp521r1", dpp_key_p521)]
236    for curve, hex in tests:
237        id = dev[0].dpp_bootstrap_gen(key=hex)
238        info = dev[0].request("DPP_BOOTSTRAP_INFO %d" % id)
239        if "FAIL" in info:
240            raise Exception("Failed to get info for " + curve)
241        if "curve=" + curve not in info:
242            raise Exception("Curve mismatch for " + curve)
243
244def test_dpp_qr_code_curves_brainpool(dev, apdev):
245    """DPP QR Code and supported Brainpool curves"""
246    check_dpp_capab(dev[0], brainpool=True)
247    tests = [("brainpoolP256r1", dpp_key_bp256),
248             ("brainpoolP384r1", dpp_key_bp384),
249             ("brainpoolP512r1", dpp_key_bp512)]
250    for curve, hex in tests:
251        id = dev[0].dpp_bootstrap_gen(key=hex)
252        info = dev[0].request("DPP_BOOTSTRAP_INFO %d" % id)
253        if "FAIL" in info:
254            raise Exception("Failed to get info for " + curve)
255        if "curve=" + curve not in info:
256            raise Exception("Curve mismatch for " + curve)
257
258def test_dpp_qr_code_unsupported_curve(dev, apdev):
259    """DPP QR Code and unsupported curve"""
260    check_dpp_capab(dev[0])
261
262    id = dev[0].request("DPP_BOOTSTRAP_GEN type=qrcode curve=unsupported")
263    if "FAIL" not in id:
264        raise Exception("Unsupported curve accepted")
265
266    tests = ["30",
267             "305f02010104187f723ed9e1b41979ec5cd02eb82696efc76b40e277661049a00a06082a8648ce3d030101a134033200043f292614dea97c43f500f069e79ae9fb48f8b07369180de5eec8fa2bc9eea5af7a46dc335f52f10cb1c0e9464201d41b"]
268    for hex in tests:
269        id = dev[0].request("DPP_BOOTSTRAP_GEN type=qrcode key=" + hex)
270        if "FAIL" not in id:
271            raise Exception("Unsupported/invalid curve accepted")
272
273def test_dpp_qr_code_keygen_fail(dev, apdev):
274    """DPP QR Code and keygen failure"""
275    check_dpp_capab(dev[0])
276
277    with alloc_fail(dev[0], 1,
278                    "crypto_ec_key_get_subject_public_key;dpp_keygen"):
279        if "FAIL" not in dev[0].request("DPP_BOOTSTRAP_GEN type=qrcode"):
280            raise Exception("Failure not reported")
281
282    with alloc_fail(dev[0], 1, "base64_gen_encode;dpp_keygen"):
283        if "FAIL" not in dev[0].request("DPP_BOOTSTRAP_GEN type=qrcode"):
284            raise Exception("Failure not reported")
285
286def test_dpp_qr_code_curve_select(dev, apdev):
287    """DPP QR Code and curve selection"""
288    check_dpp_capab(dev[0], brainpool=True)
289    check_dpp_capab(dev[1], brainpool=True)
290
291    bi = []
292    for key in [dpp_key_p256, dpp_key_p384, dpp_key_p521,
293                dpp_key_bp256, dpp_key_bp384, dpp_key_bp512]:
294        id = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True, key=key)
295        info = dev[0].request("DPP_BOOTSTRAP_INFO %d" % id)
296        for i in info.splitlines():
297            if '=' in i:
298                name, val = i.split('=')
299                if name == "curve":
300                    curve = val
301                    break
302        uri = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id)
303        bi.append((curve, uri))
304
305    for curve, uri in bi:
306        logger.info("Curve: " + curve)
307        logger.info("URI: " + uri)
308
309        dev[0].dpp_listen(2412)
310        dev[1].dpp_auth_init(uri=uri)
311        wait_auth_success(dev[0], dev[1], configurator=dev[1], enrollee=dev[0],
312                          allow_enrollee_failure=True, stop_responder=True,
313                          stop_initiator=True)
314
315def test_dpp_qr_code_auth_broadcast(dev, apdev):
316    """DPP QR Code and authentication exchange (broadcast)"""
317    check_dpp_capab(dev[0])
318    check_dpp_capab(dev[1])
319    logger.info("dev0 displays QR Code")
320    id0 = dev[0].dpp_bootstrap_gen(chan="81/1")
321    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
322    logger.info("dev1 scans QR Code and initiates DPP Authentication")
323    dev[0].dpp_listen(2412)
324    dev[1].dpp_auth_init(uri=uri0)
325    wait_auth_success(dev[0], dev[1], stop_responder=True, timeout=20)
326
327def test_dpp_qr_code_auth_unicast(dev, apdev):
328    """DPP QR Code and authentication exchange (unicast)"""
329    run_dpp_qr_code_auth_unicast(dev, apdev, None)
330
331def test_dpp_qr_code_auth_unicast_ap_enrollee(dev, apdev):
332    """DPP QR Code and authentication exchange (AP enrollee)"""
333    run_dpp_qr_code_auth_unicast(dev, apdev, None, netrole="ap")
334
335def run_dpp_configurator_enrollee(dev, apdev, conf_curve=None):
336    run_dpp_qr_code_auth_unicast(dev, apdev, None, netrole="configurator",
337                                 configurator=True, conf_curve=conf_curve,
338                                 conf="configurator")
339    ev = dev[0].wait_event(["DPP-CONFIGURATOR-ID"], timeout=2)
340    if ev is None:
341        raise Exception("No Configurator instance added")
342
343def test_dpp_configurator_enrollee(dev, apdev):
344    """DPP Configurator enrolling"""
345    run_dpp_configurator_enrollee(dev, apdev)
346
347def test_dpp_configurator_enrollee_prime256v1(dev, apdev):
348    """DPP Configurator enrolling (prime256v1)"""
349    run_dpp_configurator_enrollee(dev, apdev, conf_curve="prime256v1")
350
351def test_dpp_configurator_enrollee_secp384r1(dev, apdev):
352    """DPP Configurator enrolling (secp384r1)"""
353    run_dpp_configurator_enrollee(dev, apdev, conf_curve="secp384r1")
354
355def test_dpp_configurator_enrollee_secp521r1(dev, apdev):
356    """DPP Configurator enrolling (secp521r1)"""
357    run_dpp_configurator_enrollee(dev, apdev, conf_curve="secp521r1")
358
359def test_dpp_configurator_enrollee_brainpoolP256r1(dev, apdev):
360    """DPP Configurator enrolling (brainpoolP256r1)"""
361    run_dpp_configurator_enrollee(dev, apdev, conf_curve="brainpoolP256r1")
362
363def test_dpp_configurator_enrollee_brainpoolP384r1(dev, apdev):
364    """DPP Configurator enrolling (brainpoolP384r1)"""
365    run_dpp_configurator_enrollee(dev, apdev, conf_curve="brainpoolP384r1")
366
367def test_dpp_configurator_enrollee_brainpoolP512r1(dev, apdev):
368    """DPP Configurator enrolling (brainpoolP512r1)"""
369    run_dpp_configurator_enrollee(dev, apdev, conf_curve="brainpoolP512r1")
370
371def test_dpp_configurator_enroll_conf(dev, apdev):
372    """DPP Configurator enrolling followed by use of the new Configurator"""
373    check_dpp_capab(dev[0], min_ver=2)
374    try:
375        dev[0].set("dpp_config_processing", "2")
376        run_dpp_configurator_enroll_conf(dev, apdev)
377    finally:
378        dev[0].set("dpp_config_processing", "0", allow_fail=True)
379
380def run_dpp_configurator_enroll_conf(dev, apdev):
381    run_dpp_qr_code_auth_unicast(dev, apdev, None, netrole="configurator",
382                                 configurator=True, conf="configurator",
383                                 qr="mutual", stop_responder=False)
384    ev = dev[0].wait_event(["DPP-CONFIGURATOR-ID"], timeout=2)
385    if ev is None:
386        raise Exception("No Configurator instance added")
387    dev[1].reset()
388    dev[0].dump_monitor()
389
390    ssid = "test-network"
391    passphrase = "test-passphrase"
392    dev[0].set("dpp_configurator_params",
393               "conf=sta-psk ssid=%s pass=%s" % (binascii.hexlify(ssid.encode()).decode(), binascii.hexlify(passphrase.encode()).decode()))
394    dev[0].dpp_listen(2412, role="configurator")
395    id0 = dev[0].dpp_bootstrap_gen(chan="81/1")
396    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
397    dev[1].dpp_auth_init(uri=uri0, role="enrollee")
398    wait_auth_success(dev[0], dev[1], configurator=dev[0], enrollee=dev[1])
399
400def test_dpp_qr_code_curve_prime256v1(dev, apdev):
401    """DPP QR Code and curve prime256v1"""
402    run_dpp_qr_code_auth_unicast(dev, apdev, "prime256v1")
403
404def test_dpp_qr_code_curve_secp384r1(dev, apdev):
405    """DPP QR Code and curve secp384r1"""
406    run_dpp_qr_code_auth_unicast(dev, apdev, "secp384r1")
407
408def test_dpp_qr_code_curve_secp521r1(dev, apdev):
409    """DPP QR Code and curve secp521r1"""
410    run_dpp_qr_code_auth_unicast(dev, apdev, "secp521r1")
411
412def test_dpp_qr_code_curve_brainpoolP256r1(dev, apdev):
413    """DPP QR Code and curve brainpoolP256r1"""
414    run_dpp_qr_code_auth_unicast(dev, apdev, "brainpoolP256r1")
415
416def test_dpp_qr_code_curve_brainpoolP384r1(dev, apdev):
417    """DPP QR Code and curve brainpoolP384r1"""
418    run_dpp_qr_code_auth_unicast(dev, apdev, "brainpoolP384r1")
419
420def test_dpp_qr_code_curve_brainpoolP512r1(dev, apdev):
421    """DPP QR Code and curve brainpoolP512r1"""
422    run_dpp_qr_code_auth_unicast(dev, apdev, "brainpoolP512r1")
423
424def test_dpp_qr_code_set_key(dev, apdev):
425    """DPP QR Code and fixed bootstrapping key"""
426    run_dpp_qr_code_auth_unicast(dev, apdev, None, key="30770201010420e5143ac74682cc6869a830e8f5301a5fa569130ac329b1d7dd6f2a7495dbcbe1a00a06082a8648ce3d030107a144034200045e13e167c33dbc7d85541e5509600aa8139bbb3e39e25898992c5d01be92039ee2850f17e71506ded0d6b25677441eae249f8e225c68dd15a6354dca54006383")
427
428def run_dpp_qr_code_auth_unicast(dev, apdev, curve, netrole=None, key=None,
429                                 require_conf_success=False, init_extra=None,
430                                 require_conf_failure=False,
431                                 configurator=False, conf_curve=None,
432                                 net_access_key_curve=None,
433                                 conf=None, qr=None, stop_responder=True):
434    min_ver = 3 if net_access_key_curve else 1
435    brainpool = (curve and "brainpool" in curve) or \
436        (conf_curve and "brainpool" in conf_curve)
437    check_dpp_capab(dev[0], brainpool, min_ver=min_ver)
438    check_dpp_capab(dev[1], brainpool, min_ver=min_ver)
439    if configurator:
440        conf_id = dev[1].dpp_configurator_add(curve=conf_curve,
441                                              net_access_key_curve=net_access_key_curve)
442    else:
443        conf_id = None
444
445    if qr == "mutual":
446        logger.info("dev1 displays QR Code and dev0 scans it")
447        id1 = dev[1].dpp_bootstrap_gen(chan="81/1", mac=True, curve=curve)
448        uri1 = dev[1].request("DPP_BOOTSTRAP_GET_URI %d" % id1)
449        id1c = dev[0].dpp_qr_code(uri1)
450    else:
451        id1 = None
452
453    logger.info("dev0 displays QR Code")
454    id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True, curve=curve, key=key)
455    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
456
457    logger.info("dev1 scans QR Code and initiates DPP Authentication")
458    dev[0].dpp_listen(2412, netrole=netrole, qr=qr)
459    dev[1].dpp_auth_init(uri=uri0, extra=init_extra, configurator=conf_id,
460                         conf=conf, own=id1)
461    wait_auth_success(dev[0], dev[1], configurator=dev[1], enrollee=dev[0],
462                      allow_enrollee_failure=not require_conf_success,
463                      allow_configurator_failure=not require_conf_success,
464                      require_configurator_failure=require_conf_failure,
465                      stop_responder=stop_responder)
466
467def test_dpp_qr_code_auth_mutual(dev, apdev):
468    """DPP QR Code and authentication exchange (mutual)"""
469    check_dpp_capab(dev[0])
470    check_dpp_capab(dev[1])
471    logger.info("dev0 displays QR Code")
472    id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
473    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
474
475    logger.info("dev1 displays QR Code")
476    id1b = dev[1].dpp_bootstrap_gen(chan="81/1", mac=True)
477    uri1b = dev[1].request("DPP_BOOTSTRAP_GET_URI %d" % id1b)
478
479    logger.info("dev0 scans QR Code")
480    id0b = dev[0].dpp_qr_code(uri1b)
481
482    logger.info("dev1 scans QR Code and initiates DPP Authentication")
483    dev[0].dpp_listen(2412)
484    dev[1].dpp_auth_init(uri=uri0, own=id1b)
485
486    ev = dev[1].wait_event(["DPP-AUTH-DIRECTION"], timeout=5)
487    if ev is None:
488        raise Exception("DPP authentication direction not indicated (Initiator)")
489    if "mutual=1" not in ev:
490        raise Exception("Mutual authentication not used")
491
492    wait_auth_success(dev[0], dev[1], stop_responder=True)
493
494def test_dpp_qr_code_auth_mutual2(dev, apdev):
495    """DPP QR Code and authentication exchange (mutual2)"""
496    check_dpp_capab(dev[0])
497    check_dpp_capab(dev[1])
498    logger.info("dev0 displays QR Code")
499    id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
500    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
501
502    logger.info("dev1 displays QR Code")
503    id1b = dev[1].dpp_bootstrap_gen(chan="81/1", mac=True)
504    uri1b = dev[1].request("DPP_BOOTSTRAP_GET_URI %d" % id1b)
505
506    logger.info("dev1 scans QR Code and initiates DPP Authentication")
507    dev[0].dpp_listen(2412, qr="mutual")
508    dev[1].dpp_auth_init(uri=uri0, own=id1b)
509
510    ev = dev[1].wait_event(["DPP-RESPONSE-PENDING"], timeout=5)
511    if ev is None:
512        raise Exception("Pending response not reported")
513    ev = dev[0].wait_event(["DPP-SCAN-PEER-QR-CODE"], timeout=5)
514    if ev is None:
515        raise Exception("QR Code scan for mutual authentication not requested")
516
517    ev = dev[0].wait_event(["DPP-TX-STATUS"], timeout=1)
518    if ev is None:
519        raise Exception("No TX status reported for response")
520    time.sleep(0.1)
521
522    logger.info("dev0 scans QR Code")
523    id0b = dev[0].dpp_qr_code(uri1b)
524
525    ev = dev[1].wait_event(["DPP-AUTH-DIRECTION"], timeout=5)
526    if ev is None:
527        raise Exception("DPP authentication direction not indicated (Initiator)")
528    if "mutual=1" not in ev:
529        raise Exception("Mutual authentication not used")
530
531    wait_auth_success(dev[0], dev[1], stop_responder=True)
532
533def test_dpp_qr_code_auth_mutual_p_256(dev, apdev):
534    """DPP QR Code and authentication exchange (mutual, autogen P-256)"""
535    run_dpp_qr_code_auth_mutual(dev, apdev, "P-256")
536
537def test_dpp_qr_code_auth_mutual_p_384(dev, apdev):
538    """DPP QR Code and authentication exchange (mutual, autogen P-384)"""
539    run_dpp_qr_code_auth_mutual(dev, apdev, "P-384")
540
541def test_dpp_qr_code_auth_mutual_p_521(dev, apdev):
542    """DPP QR Code and authentication exchange (mutual, autogen P-521)"""
543    run_dpp_qr_code_auth_mutual(dev, apdev, "P-521")
544
545def test_dpp_qr_code_auth_mutual_bp_256(dev, apdev):
546    """DPP QR Code and authentication exchange (mutual, autogen BP-256)"""
547    run_dpp_qr_code_auth_mutual(dev, apdev, "BP-256")
548
549def test_dpp_qr_code_auth_mutual_bp_384(dev, apdev):
550    """DPP QR Code and authentication exchange (mutual, autogen BP-384)"""
551    run_dpp_qr_code_auth_mutual(dev, apdev, "BP-384")
552
553def test_dpp_qr_code_auth_mutual_bp_512(dev, apdev):
554    """DPP QR Code and authentication exchange (mutual, autogen BP-512)"""
555    run_dpp_qr_code_auth_mutual(dev, apdev, "BP-512")
556
557def run_dpp_qr_code_auth_mutual(dev, apdev, curve):
558    check_dpp_capab(dev[0], curve and "BP-" in curve)
559    check_dpp_capab(dev[1], curve and "BP-" in curve)
560    logger.info("dev0 displays QR Code")
561    id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True, curve=curve)
562    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
563    logger.info("dev1 scans QR Code and initiates DPP Authentication")
564    dev[0].dpp_listen(2412, qr="mutual")
565    dev[1].dpp_auth_init(uri=uri0)
566
567    ev = dev[1].wait_event(["DPP-RESPONSE-PENDING"], timeout=5)
568    if ev is None:
569        raise Exception("Pending response not reported")
570    uri = ev.split(' ')[1]
571
572    ev = dev[0].wait_event(["DPP-SCAN-PEER-QR-CODE"], timeout=5)
573    if ev is None:
574        raise Exception("QR Code scan for mutual authentication not requested")
575
576    ev = dev[0].wait_event(["DPP-TX-STATUS"], timeout=1)
577    if ev is None:
578        raise Exception("No TX status reported for response")
579    time.sleep(0.1)
580
581    logger.info("dev0 scans QR Code")
582    dev[0].dpp_qr_code(uri)
583
584    ev = dev[1].wait_event(["DPP-AUTH-DIRECTION"], timeout=5)
585    if ev is None:
586        raise Exception("DPP authentication direction not indicated (Initiator)")
587    if "mutual=1" not in ev:
588        raise Exception("Mutual authentication not used")
589
590    wait_auth_success(dev[0], dev[1], stop_responder=True)
591
592def test_dpp_auth_resp_retries(dev, apdev):
593    """DPP Authentication Response retries"""
594    check_dpp_capab(dev[0])
595    check_dpp_capab(dev[1])
596    dev[0].set("dpp_resp_max_tries", "3")
597    dev[0].set("dpp_resp_retry_time", "100")
598
599    logger.info("dev0 displays QR Code")
600    id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
601    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
602    logger.info("dev1 displays QR Code")
603    id1b = dev[1].dpp_bootstrap_gen(chan="81/1", mac=True)
604    uri1b = dev[1].request("DPP_BOOTSTRAP_GET_URI %d" % id1b)
605    logger.info("dev1 scans QR Code and initiates DPP Authentication")
606    dev[0].dpp_listen(2412, qr="mutual")
607    dev[1].dpp_auth_init(uri=uri0, own=id1b)
608
609    ev = dev[1].wait_event(["DPP-RESPONSE-PENDING"], timeout=5)
610    if ev is None:
611        raise Exception("Pending response not reported")
612    ev = dev[0].wait_event(["DPP-SCAN-PEER-QR-CODE"], timeout=5)
613    if ev is None:
614        raise Exception("QR Code scan for mutual authentication not requested")
615
616    # Stop Initiator from listening to frames to force retransmission of the
617    # DPP Authentication Response frame with Status=0
618    dev[1].request("DPP_STOP_LISTEN")
619
620    ev = dev[0].wait_event(["DPP-TX-STATUS"], timeout=1)
621    if ev is None:
622        raise Exception("No TX status reported for response")
623    time.sleep(0.1)
624
625    dev[1].dump_monitor()
626    dev[0].dump_monitor()
627
628    logger.info("dev0 scans QR Code")
629    id0b = dev[0].dpp_qr_code(uri1b)
630
631    ev = dev[0].wait_event(["DPP-TX "], timeout=5)
632    if ev is None or "type=1" not in ev:
633        raise Exception("DPP Authentication Response not sent")
634    ev = dev[0].wait_event(["DPP-TX-STATUS"], timeout=5)
635    if ev is None:
636        raise Exception("TX status for DPP Authentication Response not reported")
637    if "result=no-ACK" not in ev:
638        raise Exception("Unexpected TX status for Authentication Response: " + ev)
639
640    ev = dev[0].wait_event(["DPP-TX "], timeout=15)
641    if ev is None or "type=1" not in ev:
642        raise Exception("DPP Authentication Response retransmission not sent")
643
644def test_dpp_qr_code_auth_mutual_not_used(dev, apdev):
645    """DPP QR Code and authentication exchange (mutual not used)"""
646    check_dpp_capab(dev[0])
647    check_dpp_capab(dev[1])
648    logger.info("dev0 displays QR Code")
649    id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
650    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
651    logger.info("dev1 displays QR Code")
652    id1b = dev[1].dpp_bootstrap_gen(chan="81/1", mac=True)
653    uri1b = dev[1].request("DPP_BOOTSTRAP_GET_URI %d" % id1b)
654    logger.info("dev0 does not scan QR Code")
655    logger.info("dev1 scans QR Code and initiates DPP Authentication")
656    dev[0].dpp_listen(2412)
657    dev[1].dpp_auth_init(uri=uri0, own=id1b)
658
659    ev = dev[1].wait_event(["DPP-AUTH-DIRECTION"], timeout=5)
660    if ev is None:
661        raise Exception("DPP authentication direction not indicated (Initiator)")
662    if "mutual=0" not in ev:
663        raise Exception("Mutual authentication not used")
664
665    wait_auth_success(dev[0], dev[1], stop_responder=True)
666
667def test_dpp_qr_code_auth_mutual_curve_mismatch(dev, apdev):
668    """DPP QR Code and authentication exchange (mutual/mismatch)"""
669    check_dpp_capab(dev[0])
670    check_dpp_capab(dev[1])
671    logger.info("dev0 displays QR Code")
672    id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
673    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
674    logger.info("dev1 displays QR Code")
675    id1b = dev[1].dpp_bootstrap_gen(chan="81/1", mac=True, curve="secp384r1")
676    uri1b = dev[1].request("DPP_BOOTSTRAP_GET_URI %d" % id1b)
677    logger.info("dev0 scans QR Code")
678    id0b = dev[0].dpp_qr_code(uri1b)
679    logger.info("dev1 scans QR Code")
680    dev[1].dpp_auth_init(uri=uri0, own=id1b, expect_fail=True)
681
682def test_dpp_qr_code_auth_hostapd_mutual2(dev, apdev):
683    """DPP QR Code and authentication exchange (hostapd mutual2)"""
684    check_dpp_capab(dev[0])
685    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured"})
686    check_dpp_capab(hapd)
687    logger.info("AP displays QR Code")
688    id_h = hapd.dpp_bootstrap_gen(chan="81/1", mac=True)
689    uri_h = hapd.request("DPP_BOOTSTRAP_GET_URI %d" % id_h)
690    logger.info("dev0 displays QR Code")
691    id0b = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
692    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0b)
693    logger.info("dev0 scans QR Code and initiates DPP Authentication")
694    hapd.dpp_listen(2412, qr="mutual")
695    dev[0].dpp_auth_init(uri=uri_h, own=id0b)
696
697    ev = dev[0].wait_event(["DPP-RESPONSE-PENDING"], timeout=5)
698    if ev is None:
699        raise Exception("Pending response not reported")
700    ev = hapd.wait_event(["DPP-SCAN-PEER-QR-CODE"], timeout=5)
701    if ev is None:
702        raise Exception("QR Code scan for mutual authentication not requested")
703
704    ev = hapd.wait_event(["DPP-TX-STATUS"], timeout=1)
705    if ev is None:
706        raise Exception("No TX status reported for response")
707    time.sleep(0.1)
708
709    logger.info("AP scans QR Code")
710    hapd.dpp_qr_code(uri0)
711
712    wait_auth_success(hapd, dev[0], stop_responder=True)
713
714def test_dpp_qr_code_listen_continue(dev, apdev):
715    """DPP QR Code and listen operation needing continuation"""
716    check_dpp_capab(dev[0])
717    check_dpp_capab(dev[1])
718    logger.info("dev0 displays QR Code")
719    id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
720    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
721    dev[0].dpp_listen(2412)
722    logger.info("Wait for listen to expire and get restarted")
723    time.sleep(5.5)
724    logger.info("dev1 scans QR Code and initiates DPP Authentication")
725    dev[1].dpp_auth_init(uri=uri0)
726    wait_auth_success(dev[0], dev[1], stop_responder=True)
727
728def test_dpp_qr_code_auth_initiator_enrollee(dev, apdev):
729    """DPP QR Code and authentication exchange (Initiator in Enrollee role)"""
730    try:
731        run_dpp_qr_code_auth_initiator_enrollee(dev, apdev)
732    finally:
733        dev[0].set("gas_address3", "0")
734        dev[1].set("gas_address3", "0")
735
736def run_dpp_qr_code_auth_initiator_enrollee(dev, apdev):
737    check_dpp_capab(dev[0])
738    check_dpp_capab(dev[1])
739    dev[0].request("SET gas_address3 1")
740    dev[1].request("SET gas_address3 1")
741    logger.info("dev0 displays QR Code")
742    id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
743    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
744    logger.info("dev1 scans QR Code and initiates DPP Authentication")
745    dev[0].dpp_listen(2412)
746    dev[1].dpp_auth_init(uri=uri0, role="enrollee")
747    wait_auth_success(dev[0], dev[1], configurator=dev[0], enrollee=dev[1],
748                      allow_enrollee_failure=True, stop_responder=True)
749
750def test_dpp_qr_code_auth_initiator_either_1(dev, apdev):
751    """DPP QR Code and authentication exchange (Initiator in either role)"""
752    run_dpp_qr_code_auth_initiator_either(dev, apdev, None, dev[1], dev[0])
753
754def test_dpp_qr_code_auth_initiator_either_2(dev, apdev):
755    """DPP QR Code and authentication exchange (Initiator in either role)"""
756    run_dpp_qr_code_auth_initiator_either(dev, apdev, "enrollee",
757                                          dev[1], dev[0])
758
759def test_dpp_qr_code_auth_initiator_either_3(dev, apdev):
760    """DPP QR Code and authentication exchange (Initiator in either role)"""
761    run_dpp_qr_code_auth_initiator_either(dev, apdev, "configurator",
762                                          dev[0], dev[1])
763
764def run_dpp_qr_code_auth_initiator_either(dev, apdev, resp_role,
765                                          conf_dev, enrollee_dev):
766    check_dpp_capab(dev[0])
767    check_dpp_capab(dev[1])
768    logger.info("dev0 displays QR Code")
769    id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
770    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
771    logger.info("dev1 scans QR Code and initiates DPP Authentication")
772    dev[0].dpp_listen(2412, role=resp_role)
773    dev[1].dpp_auth_init(uri=uri0, role="either")
774    wait_auth_success(dev[0], dev[1], configurator=conf_dev,
775                      enrollee=enrollee_dev, allow_enrollee_failure=True,
776                      stop_responder=True)
777
778def run_init_incompatible_roles(dev, role="enrollee"):
779    check_dpp_capab(dev[0])
780    check_dpp_capab(dev[1])
781    logger.info("dev0 displays QR Code")
782    id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
783    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
784
785    logger.info("dev1 scans QR Code")
786    id1 = dev[1].dpp_qr_code(uri0)
787
788    logger.info("dev1 initiates DPP Authentication")
789    dev[0].dpp_listen(2412, role=role)
790    return id1
791
792def test_dpp_qr_code_auth_incompatible_roles(dev, apdev):
793    """DPP QR Code and authentication exchange (incompatible roles)"""
794    id1 = run_init_incompatible_roles(dev)
795    dev[1].dpp_auth_init(peer=id1, role="enrollee")
796    ev = dev[1].wait_event(["DPP-NOT-COMPATIBLE"], timeout=5)
797    if ev is None:
798        raise Exception("DPP-NOT-COMPATIBLE event on initiator timed out")
799    ev = dev[0].wait_event(["DPP-NOT-COMPATIBLE"], timeout=1)
800    if ev is None:
801        raise Exception("DPP-NOT-COMPATIBLE event on responder timed out")
802    dev[1].dpp_auth_init(peer=id1, role="configurator")
803    wait_auth_success(dev[0], dev[1], stop_responder=True)
804
805def test_dpp_qr_code_auth_incompatible_roles2(dev, apdev):
806    """DPP QR Code and authentication exchange (incompatible roles 2)"""
807    id1 = run_init_incompatible_roles(dev, role="configurator")
808    dev[1].dpp_auth_init(peer=id1, role="configurator")
809    ev = dev[1].wait_event(["DPP-NOT-COMPATIBLE"], timeout=5)
810    if ev is None:
811        raise Exception("DPP-NOT-COMPATIBLE event on initiator timed out")
812    ev = dev[0].wait_event(["DPP-NOT-COMPATIBLE"], timeout=1)
813    if ev is None:
814        raise Exception("DPP-NOT-COMPATIBLE event on responder timed out")
815
816def test_dpp_qr_code_auth_incompatible_roles_failure(dev, apdev):
817    """DPP QR Code and authentication exchange (incompatible roles failure)"""
818    id1 = run_init_incompatible_roles(dev, role="configurator")
819    with alloc_fail(dev[0], 1, "dpp_auth_build_resp_status"):
820        dev[1].dpp_auth_init(peer=id1, role="configurator")
821        ev = dev[0].wait_event(["DPP-NOT-COMPATIBLE"], timeout=1)
822        if ev is None:
823            raise Exception("DPP-NOT-COMPATIBLE event on responder timed out")
824
825def test_dpp_qr_code_auth_incompatible_roles_failure2(dev, apdev):
826    """DPP QR Code and authentication exchange (incompatible roles failure 2)"""
827    id1 = run_init_incompatible_roles(dev, role="configurator")
828    with alloc_fail(dev[1], 1, "dpp_auth_resp_rx_status"):
829        dev[1].dpp_auth_init(peer=id1, role="configurator")
830        wait_fail_trigger(dev[1], "GET_ALLOC_FAIL")
831
832def test_dpp_qr_code_auth_incompatible_roles_failure3(dev, apdev):
833    """DPP QR Code and authentication exchange (incompatible roles failure 3)"""
834    id1 = run_init_incompatible_roles(dev, role="configurator")
835    with fail_test(dev[1], 1, "dpp_auth_resp_rx_status"):
836        dev[1].dpp_auth_init(peer=id1, role="configurator")
837        wait_dpp_fail(dev[1], "AES-SIV decryption failed")
838
839def test_dpp_qr_code_auth_neg_chan(dev, apdev):
840    """DPP QR Code and authentication exchange with requested different channel"""
841    check_dpp_capab(dev[0])
842    check_dpp_capab(dev[1])
843    conf_id = dev[1].dpp_configurator_add()
844    logger.info("dev0 displays QR Code")
845    id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
846    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
847    logger.info("dev1 scans QR Code and initiates DPP Authentication")
848    dev[0].dpp_listen(2412)
849    dev[1].dpp_auth_init(uri=uri0, conf="sta-dpp", neg_freq=2462,
850                         configurator=conf_id)
851
852    ev = dev[1].wait_event(["DPP-TX "], timeout=5)
853    if ev is None:
854        raise Exception("DPP Authentication Request not sent")
855    if "freq=2412 type=0" not in ev:
856        raise Exception("Unexpected TX data for Authentication Request: " + ev)
857
858    ev = dev[0].wait_event(["DPP-RX"], timeout=5)
859    if ev is None:
860        raise Exception("DPP Authentication Request not received")
861    if "freq=2412 type=0" not in ev:
862        raise Exception("Unexpected RX data for Authentication Request: " + ev)
863
864    ev = dev[1].wait_event(["DPP-TX-STATUS"], timeout=5)
865    if ev is None:
866        raise Exception("TX status for DPP Authentication Request not reported")
867    if "freq=2412 result=SUCCESS" not in ev:
868        raise Exception("Unexpected TX status for Authentication Request: " + ev)
869
870    ev = dev[0].wait_event(["DPP-TX "], timeout=5)
871    if ev is None:
872        raise Exception("DPP Authentication Response not sent")
873    if "freq=2462 type=1" not in ev:
874        raise Exception("Unexpected TX data for Authentication Response: " + ev)
875
876    ev = dev[1].wait_event(["DPP-RX"], timeout=5)
877    if ev is None:
878        raise Exception("DPP Authentication Response not received")
879    if "freq=2462 type=1" not in ev:
880        raise Exception("Unexpected RX data for Authentication Response: " + ev)
881
882    ev = dev[1].wait_event(["DPP-TX "], timeout=5)
883    if ev is None:
884        raise Exception("DPP Authentication Confirm not sent")
885    if "freq=2462 type=2" not in ev:
886        raise Exception("Unexpected TX data for Authentication Confirm: " + ev)
887
888    ev = dev[0].wait_event(["DPP-RX"], timeout=5)
889    if ev is None:
890        raise Exception("DPP Authentication Confirm not received")
891    if "freq=2462 type=2" not in ev:
892        raise Exception("Unexpected RX data for Authentication Confirm: " + ev)
893
894    wait_auth_success(dev[0], dev[1], configurator=dev[1], enrollee=dev[0],
895                      stop_responder=True)
896
897def test_dpp_config_legacy(dev, apdev):
898    """DPP Config Object for legacy network using passphrase"""
899    check_dpp_capab(dev[1])
900    conf = '{"wi-fi_tech":"infra", "discovery":{"ssid":"test"},"cred":{"akm":"psk","pass":"secret passphrase"}}'
901    dev[1].set("dpp_config_obj_override", conf)
902    run_dpp_qr_code_auth_unicast(dev, apdev, "prime256v1",
903                                 require_conf_success=True)
904
905def test_dpp_config_legacy_psk_hex(dev, apdev):
906    """DPP Config Object for legacy network using PSK"""
907    check_dpp_capab(dev[1])
908    conf = '{"wi-fi_tech":"infra", "discovery":{"ssid":"test"},"cred":{"akm":"psk","psk_hex":"' + 32*"12" + '"}}'
909    dev[1].set("dpp_config_obj_override", conf)
910    run_dpp_qr_code_auth_unicast(dev, apdev, "prime256v1",
911                                 require_conf_success=True)
912
913def test_dpp_config_fragmentation(dev, apdev):
914    """DPP Config Object for legacy network requiring fragmentation"""
915    check_dpp_capab(dev[1])
916    conf = '{"wi-fi_tech":"infra", "discovery":{"ssid":"test"},"cred":{"akm":"psk","pass":"secret passphrase"}}' + 3000*' '
917    dev[1].set("dpp_config_obj_override", conf)
918    run_dpp_qr_code_auth_unicast(dev, apdev, "prime256v1",
919                                 require_conf_success=True)
920
921def test_dpp_config_legacy_gen(dev, apdev):
922    """Generate DPP Config Object for legacy network"""
923    run_dpp_qr_code_auth_unicast(dev, apdev, "prime256v1",
924                                 init_extra="conf=sta-psk pass=%s" % binascii.hexlify(b"passphrase").decode(),
925                                 require_conf_success=True)
926
927def test_dpp_config_legacy_gen_psk(dev, apdev):
928    """Generate DPP Config Object for legacy network (PSK)"""
929    run_dpp_qr_code_auth_unicast(dev, apdev, "prime256v1",
930                                 init_extra="conf=sta-psk psk=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
931                                 require_conf_success=True)
932
933def test_dpp_config_legacy_gen_two_conf(dev, apdev):
934    """Generate DPP Config Object for legacy network (two config objects)"""
935    check_dpp_capab(dev[0])
936    ssid1 = "test1"
937    pass1 = "passphrase for psk"
938    ssid2 = "test-2"
939    pass2 = "password for sae"
940    ssid1h = binascii.hexlify(ssid1.encode()).decode()
941    pass1h = binascii.hexlify(pass1.encode()).decode()
942    ssid2h = binascii.hexlify(ssid2.encode()).decode()
943    pass2h = binascii.hexlify(pass2.encode()).decode()
944    extra = "conf=sta-psk pass=%s ssid=%s @CONF-OBJ-SEP@ conf=sta-sae pass=%s ssid=%s" % (pass1h, ssid1h, pass2h, ssid2h)
945    try:
946        dev[0].set("dpp_config_processing", "1")
947        run_dpp_qr_code_auth_unicast(dev, apdev, "prime256v1",
948                                     init_extra=extra,
949                                     require_conf_success=True)
950    finally:
951        dev[0].set("dpp_config_processing", "0", allow_fail=True)
952
953    ev = dev[0].wait_event(["DPP-CONFOBJ-AKM"], timeout=5)
954    if ev is None or ev.split()[1] != "psk":
955        raise Exception("Unexpected confobj 1 AKM: " + str(ev))
956    ev = dev[0].wait_event(["DPP-CONFOBJ-SSID"], timeout=5)
957    if ev is None or ev.split()[1] != ssid1:
958        raise Exception("Unexpected confobj 1 SSID: " + str(ev))
959    ev = dev[0].wait_event(["DPP-CONFOBJ-PASS"], timeout=5)
960    if ev is None or ev.split()[1] != pass1h:
961        raise Exception("Unexpected confobj 1 pass: " + str(ev))
962
963    ev = dev[0].wait_event(["DPP-CONFOBJ-AKM"], timeout=5)
964    if ev is None or ev.split()[1] != "sae":
965        raise Exception("Unexpected confobj 2 AKM: " + str(ev))
966    ev = dev[0].wait_event(["DPP-CONFOBJ-SSID"], timeout=5)
967    if ev is None or ev.split()[1] != ssid2:
968        raise Exception("Unexpected confobj 2 SSID: " + str(ev))
969    ev = dev[0].wait_event(["DPP-CONFOBJ-PASS"], timeout=5)
970    if ev is None or ev.split()[1] != pass2h:
971        raise Exception("Unexpected confobj 2 pass: " + str(ev))
972
973    val = dev[0].get_network(0, "ssid")
974    if val != '"' + ssid1 + '"':
975        raise Exception("Unexpected network 1 ssid: " + val)
976    val = dev[0].get_network(0, "key_mgmt")
977    if val != "WPA-PSK FT-PSK WPA-PSK-SHA256":
978        raise Exception("Unexpected network 1 key_mgmt: " + val)
979
980    val = dev[0].get_network(1, "ssid")
981    if val != '"' + ssid2 + '"':
982        raise Exception("Unexpected network 2 ssid: " + val)
983    val = dev[0].get_network(1, "key_mgmt")
984    if val != "SAE FT-SAE":
985        raise Exception("Unexpected network 2 key_mgmt: " + val)
986
987def test_dpp_config_legacy_gen_two_conf_psk(dev, apdev):
988    """Generate DPP Config Object for legacy network (two config objects, psk)"""
989    check_dpp_capab(dev[0])
990    ssid1 = "test1"
991    psk1 = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
992    ssid2 = "test-2"
993    pass2 = "password for sae"
994    ssid1h = binascii.hexlify(ssid1.encode()).decode()
995    ssid2h = binascii.hexlify(ssid2.encode()).decode()
996    pass2h = binascii.hexlify(pass2.encode()).decode()
997    extra = "conf=sta-psk psk=%s ssid=%s @CONF-OBJ-SEP@ conf=sta-sae pass=%s ssid=%s" % (psk1, ssid1h, pass2h, ssid2h)
998    try:
999        dev[0].set("dpp_config_processing", "1")
1000        run_dpp_qr_code_auth_unicast(dev, apdev, "prime256v1",
1001                                     init_extra=extra,
1002                                     require_conf_success=True)
1003    finally:
1004        dev[0].set("dpp_config_processing", "0", allow_fail=True)
1005
1006    ev = dev[0].wait_event(["DPP-CONFOBJ-AKM"], timeout=5)
1007    if ev is None or ev.split()[1] != "psk":
1008        raise Exception("Unexpected confobj 1 AKM: " + str(ev))
1009    ev = dev[0].wait_event(["DPP-CONFOBJ-SSID"], timeout=5)
1010    if ev is None or ev.split()[1] != ssid1:
1011        raise Exception("Unexpected confobj 1 SSID: " + str(ev))
1012    ev = dev[0].wait_event(["DPP-CONFOBJ-PSK"], timeout=5)
1013    if ev is None or ev.split()[1] != psk1:
1014        raise Exception("Unexpected confobj 1 psk: " + str(ev))
1015
1016    ev = dev[0].wait_event(["DPP-CONFOBJ-AKM"], timeout=5)
1017    if ev is None or ev.split()[1] != "sae":
1018        raise Exception("Unexpected confobj 2 AKM: " + str(ev))
1019    ev = dev[0].wait_event(["DPP-CONFOBJ-SSID"], timeout=5)
1020    if ev is None or ev.split()[1] != ssid2:
1021        raise Exception("Unexpected confobj 2 SSID: " + str(ev))
1022    ev = dev[0].wait_event(["DPP-CONFOBJ-PASS"], timeout=5)
1023    if ev is None or ev.split()[1] != pass2h:
1024        raise Exception("Unexpected confobj 2 pass: " + str(ev))
1025
1026    val = dev[0].get_network(0, "ssid")
1027    if val != '"' + ssid1 + '"':
1028        raise Exception("Unexpected network 1 ssid: " + val)
1029    val = dev[0].get_network(0, "key_mgmt")
1030    if val != "WPA-PSK FT-PSK WPA-PSK-SHA256":
1031        raise Exception("Unexpected network 1 key_mgmt: " + val)
1032
1033    val = dev[0].get_network(1, "ssid")
1034    if val != '"' + ssid2 + '"':
1035        raise Exception("Unexpected network 2 ssid: " + val)
1036    val = dev[0].get_network(1, "key_mgmt")
1037    if val != "SAE FT-SAE":
1038        raise Exception("Unexpected network 2 key_mgmt: " + val)
1039
1040def test_dpp_config_legacy_gen_sta_ap_conf(dev, apdev):
1041    """Generate DPP Config Object for legacy network (sta and ap config)"""
1042    ssid1 = "test-AP"
1043    pass1 = "password for AP sae"
1044    ssid2 = "test-STA"
1045    pass2 = "password for STA sae"
1046    ssid1h = binascii.hexlify(ssid1.encode()).decode()
1047    pass1h = binascii.hexlify(pass1.encode()).decode()
1048    ssid2h = binascii.hexlify(ssid2.encode()).decode()
1049    pass2h = binascii.hexlify(pass2.encode()).decode()
1050    extra = "conf=ap-sae pass=%s ssid=%s @CONF-OBJ-SEP@ conf=sta-sae pass=%s ssid=%s" % (pass1h, ssid1h, pass2h, ssid2h)
1051    run_dpp_qr_code_auth_unicast(dev, apdev, "prime256v1",
1052                                 init_extra=extra,
1053                                 require_conf_success=True)
1054
1055    ev = dev[0].wait_event(["DPP-CONFOBJ-AKM"], timeout=5)
1056    if ev is None or ev.split()[1] != "sae":
1057        raise Exception("Unexpected confobj 2 AKM: " + str(ev))
1058    ev = dev[0].wait_event(["DPP-CONFOBJ-SSID"], timeout=5)
1059    if ev is None or ev.split()[1] != ssid2:
1060        raise Exception("Unexpected confobj 2 SSID: " + str(ev))
1061    ev = dev[0].wait_event(["DPP-CONFOBJ-PASS"], timeout=5)
1062    if ev is None or ev.split()[1] != pass2h:
1063        raise Exception("Unexpected confobj 2 pass: " + str(ev))
1064
1065    ev = dev[0].wait_event(["DPP-CONFOBJ-AKM"], timeout=1)
1066    if ev is not None:
1067        raise Exception("Unexpected second confobj")
1068
1069def test_dpp_config_dpp_gen_prime256v1(dev, apdev):
1070    """Generate DPP Config Object for DPP network (P-256)"""
1071    run_dpp_qr_code_auth_unicast(dev, apdev, "prime256v1",
1072                                 init_extra="conf=sta-dpp",
1073                                 require_conf_success=True,
1074                                 configurator=True)
1075
1076def test_dpp_config_dpp_gen_secp384r1(dev, apdev):
1077    """Generate DPP Config Object for DPP network (P-384)"""
1078    run_dpp_qr_code_auth_unicast(dev, apdev, "secp384r1",
1079                                 init_extra="conf=sta-dpp",
1080                                 require_conf_success=True,
1081                                 configurator=True)
1082
1083def test_dpp_config_dpp_gen_secp521r1(dev, apdev):
1084    """Generate DPP Config Object for DPP network (P-521)"""
1085    run_dpp_qr_code_auth_unicast(dev, apdev, "secp521r1",
1086                                 init_extra="conf=sta-dpp",
1087                                 require_conf_success=True,
1088                                 configurator=True)
1089
1090def test_dpp_config_dpp_gen_prime256v1_prime256v1(dev, apdev):
1091    """Generate DPP Config Object for DPP network (P-256 + P-256)"""
1092    run_dpp_qr_code_auth_unicast(dev, apdev, "prime256v1",
1093                                 init_extra="conf=sta-dpp",
1094                                 require_conf_success=True,
1095                                 configurator=True,
1096                                 conf_curve="prime256v1")
1097
1098def test_dpp_config_dpp_gen_prime256v1_secp384r1(dev, apdev):
1099    """Generate DPP Config Object for DPP network (P-256 + P-384)"""
1100    run_dpp_qr_code_auth_unicast(dev, apdev, "prime256v1",
1101                                 init_extra="conf=sta-dpp",
1102                                 require_conf_success=True,
1103                                 configurator=True,
1104                                 conf_curve="secp384r1")
1105
1106def test_dpp_config_dpp_gen_prime256v1_secp521r1(dev, apdev):
1107    """Generate DPP Config Object for DPP network (P-256 + P-521)"""
1108    run_dpp_qr_code_auth_unicast(dev, apdev, "prime256v1",
1109                                 init_extra="conf=sta-dpp",
1110                                 require_conf_success=True,
1111                                 configurator=True,
1112                                 conf_curve="secp521r1")
1113
1114def test_dpp_config_dpp_gen_secp384r1_prime256v1(dev, apdev):
1115    """Generate DPP Config Object for DPP network (P-384 + P-256)"""
1116    run_dpp_qr_code_auth_unicast(dev, apdev, "secp384r1",
1117                                 init_extra="conf=sta-dpp",
1118                                 require_conf_success=True,
1119                                 configurator=True,
1120                                 conf_curve="prime256v1")
1121
1122def test_dpp_config_dpp_gen_secp384r1_secp384r1(dev, apdev):
1123    """Generate DPP Config Object for DPP network (P-384 + P-384)"""
1124    run_dpp_qr_code_auth_unicast(dev, apdev, "secp384r1",
1125                                 init_extra="conf=sta-dpp",
1126                                 require_conf_success=True,
1127                                 configurator=True,
1128                                 conf_curve="secp384r1")
1129
1130def test_dpp_config_dpp_gen_secp384r1_secp521r1(dev, apdev):
1131    """Generate DPP Config Object for DPP network (P-384 + P-521)"""
1132    run_dpp_qr_code_auth_unicast(dev, apdev, "secp384r1",
1133                                 init_extra="conf=sta-dpp",
1134                                 require_conf_success=True,
1135                                 configurator=True,
1136                                 conf_curve="secp521r1")
1137
1138def test_dpp_config_dpp_gen_secp521r1_prime256v1(dev, apdev):
1139    """Generate DPP Config Object for DPP network (P-521 + P-256)"""
1140    run_dpp_qr_code_auth_unicast(dev, apdev, "secp521r1",
1141                                 init_extra="conf=sta-dpp",
1142                                 require_conf_success=True,
1143                                 configurator=True,
1144                                 conf_curve="prime256v1")
1145
1146def test_dpp_config_dpp_gen_secp521r1_secp384r1(dev, apdev):
1147    """Generate DPP Config Object for DPP network (P-521 + P-384)"""
1148    run_dpp_qr_code_auth_unicast(dev, apdev, "secp521r1",
1149                                 init_extra="conf=sta-dpp",
1150                                 require_conf_success=True,
1151                                 configurator=True,
1152                                 conf_curve="secp384r1")
1153
1154def test_dpp_config_dpp_gen_secp521r1_secp521r1(dev, apdev):
1155    """Generate DPP Config Object for DPP network (P-521 + P-521)"""
1156    run_dpp_qr_code_auth_unicast(dev, apdev, "secp521r1",
1157                                 init_extra="conf=sta-dpp",
1158                                 require_conf_success=True,
1159                                 configurator=True,
1160                                 conf_curve="secp521r1")
1161
1162def test_dpp_config_dpp_gen_prime256v1_secp384r1_secp384r1(dev, apdev):
1163    """Generate DPP Config Object for DPP network (P-256 + P-384 + P-384)"""
1164    run_dpp_qr_code_auth_unicast(dev, apdev, "prime256v1",
1165                                 init_extra="conf=sta-dpp",
1166                                 require_conf_success=True,
1167                                 configurator=True,
1168                                 conf_curve="secp384r1",
1169                                 net_access_key_curve="secp384r1")
1170
1171def test_dpp_config_dpp_gen_expiry(dev, apdev):
1172    """Generate DPP Config Object for DPP network with expiry value"""
1173    run_dpp_qr_code_auth_unicast(dev, apdev, "prime256v1",
1174                                 init_extra="conf=sta-dpp expiry=%d" % (time.time() + 1000),
1175                                 require_conf_success=True,
1176                                 configurator=True)
1177
1178def test_dpp_config_dpp_gen_expired_key(dev, apdev):
1179    """Generate DPP Config Object for DPP network with expiry value"""
1180    run_dpp_qr_code_auth_unicast(dev, apdev, "prime256v1",
1181                                 init_extra="conf=sta-dpp expiry=%d" % (time.time() - 10),
1182                                 require_conf_failure=True,
1183                                 configurator=True)
1184
1185def test_dpp_config_dpp_gen_3rd_party(dev, apdev):
1186    """Generate DPP Config Object for DPP network with 3rd party information"""
1187    check_dpp_capab(dev[0])
1188    check_dpp_capab(dev[1])
1189    try:
1190        dev[0].set("dpp_extra_conf_req_name", "org.example")
1191        json = '{"c":1,"d":"test"}'
1192        dev[0].set("dpp_extra_conf_req_value", json)
1193        run_dpp_config_dpp_gen_3rd_party(dev, apdev)
1194    finally:
1195        dev[0].set("dpp_extra_conf_req_name", "", allow_fail=True)
1196        dev[0].set("dpp_extra_conf_req_value", "", allow_fail=True)
1197
1198def run_dpp_config_dpp_gen_3rd_party(dev, apdev):
1199    extra = "conf_extra_name=org.example conf_extra_value="
1200    json = '{"a":1,"b":"test"}'
1201    extra += binascii.hexlify(json.encode()).decode()
1202    run_dpp_qr_code_auth_unicast(dev, apdev, "prime256v1",
1203                                 init_extra="conf=sta-dpp " + extra,
1204                                 require_conf_success=True,
1205                                 configurator=True)
1206
1207def test_dpp_config_dpp_override_prime256v1(dev, apdev):
1208    """DPP Config Object override (P-256)"""
1209    check_dpp_capab(dev[0])
1210    check_dpp_capab(dev[1])
1211    conf = '{"wi-fi_tech":"infra","discovery":{"ssid":"test"},"cred":{"akm":"dpp","signedConnector":"eyJ0eXAiOiJkcHBDb24iLCJraWQiOiJUbkdLaklsTlphYXRyRUFZcmJiamlCNjdyamtMX0FHVldYTzZxOWhESktVIiwiYWxnIjoiRVMyNTYifQ.eyJncm91cHMiOlt7Imdyb3VwSWQiOiIqIiwibmV0Um9sZSI6InN0YSJ9XSwibmV0QWNjZXNzS2V5Ijp7Imt0eSI6IkVDIiwiY3J2IjoiUC0yNTYiLCJ4IjoiYVRGNEpFR0lQS1NaMFh2OXpkQ01qbS10bjVYcE1zWUlWWjl3eVNBejFnSSIsInkiOiJRR2NIV0FfNnJiVTlYRFhBenRvWC1NNVEzc3VUbk1hcUVoVUx0bjdTU1h3In19._sm6YswxMf6hJLVTyYoU1uYUeY2VVkUNjrzjSiEhY42StD_RWowStEE-9CRsdCvLmsTptZ72_g40vTFwdId20A","csign":{"kty":"EC","crv":"P-256","x":"W4-Y5N1Pkos3UWb9A5qme0KUYRtY3CVUpekx_MapZ9s","y":"Et-M4NSF4NGjvh2VCh4B1sJ9eSCZ4RNzP2DBdP137VE","kid":"TnGKjIlNZaatrEAYrbbjiB67rjkL_AGVWXO6q9hDJKU"}}}'
1212    dev[0].set("dpp_ignore_netaccesskey_mismatch", "1")
1213    dev[1].set("dpp_config_obj_override", conf)
1214    run_dpp_qr_code_auth_unicast(dev, apdev, "prime256v1",
1215                                 require_conf_success=True)
1216
1217def test_dpp_config_dpp_override_secp384r1(dev, apdev):
1218    """DPP Config Object override (P-384)"""
1219    check_dpp_capab(dev[0])
1220    check_dpp_capab(dev[1])
1221    conf = '{"wi-fi_tech":"infra","discovery":{"ssid":"test"},"cred":{"akm":"dpp","signedConnector":"eyJ0eXAiOiJkcHBDb24iLCJraWQiOiJabi1iMndjbjRLM2pGQklkYmhGZkpVTHJTXzdESS0yMWxFQi02R3gxNjl3IiwiYWxnIjoiRVMzODQifQ.eyJncm91cHMiOlt7Imdyb3VwSWQiOiIqIiwibmV0Um9sZSI6InN0YSJ9XSwibmV0QWNjZXNzS2V5Ijp7Imt0eSI6IkVDIiwiY3J2IjoiUC0zODQiLCJ4IjoickdrSGg1UUZsOUtfWjdqYUZkVVhmbThoY1RTRjM1b25Xb1NIRXVsbVNzWW9oX1RXZGpoRjhiVGdiS0ZRN2tBViIsInkiOiJBbU1QVDA5VmFENWpGdzMwTUFKQlp2VkZXeGNlVVlKLXR5blQ0bVJ5N0xOZWxhZ0dEWHpfOExaRlpOU2FaNUdLIn19.Yn_F7m-bbOQ5PlaYQJ9-1qsuqYQ6V-rAv8nWw1COKiCYwwbt3WFBJ8DljY0dPrlg5CHJC4saXwkytpI-CpELW1yUdzYb4Lrun07d20Eo_g10ICyOl5sqQCAUElKMe_Xr","csign":{"kty":"EC","crv":"P-384","x":"dmTyXXiPV2Y8a01fujL-jo08gvzyby23XmzOtzjAiujKQZZgPJsbhfEKrZDlc6ey","y":"H5Z0av5c7bqInxYb2_OOJdNiMhVf3zlcULR0516ZZitOY4U31KhL4wl4KGV7g2XW","kid":"Zn-b2wcn4K3jFBIdbhFfJULrS_7DI-21lEB-6Gx169w"}}}'
1222    dev[0].set("dpp_ignore_netaccesskey_mismatch", "1")
1223    dev[1].set("dpp_config_obj_override", conf)
1224    run_dpp_qr_code_auth_unicast(dev, apdev, "secp384r1",
1225                                 require_conf_success=True)
1226
1227def test_dpp_config_dpp_override_secp521r1(dev, apdev):
1228    """DPP Config Object override (P-521)"""
1229    check_dpp_capab(dev[0])
1230    check_dpp_capab(dev[1])
1231    conf = '{"wi-fi_tech":"infra","discovery":{"ssid":"test"},"cred":{"akm":"dpp","signedConnector":"eyJ0eXAiOiJkcHBDb24iLCJraWQiOiJMZkhKY3hnV2ZKcG1uS2IwenZRT0F2VDB2b0ZKc0JjZnBmYzgxY3Y5ZXFnIiwiYWxnIjoiRVM1MTIifQ.eyJncm91cHMiOlt7Imdyb3VwSWQiOiIqIiwibmV0Um9sZSI6InN0YSJ9XSwibmV0QWNjZXNzS2V5Ijp7Imt0eSI6IkVDIiwiY3J2IjoiUC01MjEiLCJ4IjoiQVJlUFBrMFNISkRRR2NWbnlmM3lfbTlaQllHNjFJeElIbDN1NkdwRHVhMkU1WVd4TE1BSUtMMnZuUGtlSGFVRXljRmZaZlpYZ2JlNkViUUxMVkRVUm1VUSIsInkiOiJBWUtaYlNwUkFFNjJVYm9YZ2c1ZWRBVENzbEpzTlpwcm9RR1dUcW9Md04weXkzQkVoT3ZRZmZrOWhaR2lKZ295TzFobXFRRVRrS0pXb2tIYTBCQUpLSGZtIn19.ACEZLyPk13cM_OFScpLoCElQ2t1sxq5z2d_W_3_QslTQQe5SFiH_o8ycL4632YLAH4RV0gZcMKKRMtZdHgBYHjkzASDqgY-_aYN2SBmpfl8hw0YdDlUJWX3DJf-ofqNAlTbnGmhpSg69cEAhFn41Xgvx2MdwYcPVncxxESVOtWl5zNLK","csign":{"kty":"EC","crv":"P-521","x":"ADiOI_YJOAipEXHB-SpGl4KqokX8m8h3BVYCc8dgiwssZ061-nIIY3O1SIO6Re4Jjfy53RPgzDG6jitOgOGLtzZs","y":"AZKggKaQi0ExutSpJAU3-lqDV03sBQLA9C7KabfWoAn8qD6Vk4jU0WAJdt-wBBTF9o1nVuiqS2OxMVYrxN4lOz79","kid":"LfHJcxgWfJpmnKb0zvQOAvT0voFJsBcfpfc81cv9eqg"}}}'
1232    dev[0].set("dpp_ignore_netaccesskey_mismatch", "1")
1233    dev[1].set("dpp_config_obj_override", conf)
1234    run_dpp_qr_code_auth_unicast(dev, apdev, "secp521r1",
1235                                 require_conf_success=True)
1236
1237def test_dpp_config_override_objects(dev, apdev):
1238    """Generate DPP Config Object and override objects)"""
1239    check_dpp_capab(dev[1])
1240    discovery = '{\n"ssid":"mywifi"\n}'
1241    groups = '[\n  {"groupId":"home","netRole":"sta"},\n  {"groupId":"cottage","netRole":"sta"}\n]'
1242    dev[1].set("dpp_discovery_override", discovery)
1243    dev[1].set("dpp_groups_override", groups)
1244    run_dpp_qr_code_auth_unicast(dev, apdev, "prime256v1",
1245                                 init_extra="conf=sta-dpp",
1246                                 require_conf_success=True,
1247                                 configurator=True)
1248
1249def build_conf_obj(kty="EC", crv="P-256",
1250                   x="W4-Y5N1Pkos3UWb9A5qme0KUYRtY3CVUpekx_MapZ9s",
1251                   y="Et-M4NSF4NGjvh2VCh4B1sJ9eSCZ4RNzP2DBdP137VE",
1252                   kid="TnGKjIlNZaatrEAYrbbjiB67rjkL_AGVWXO6q9hDJKU",
1253                   prot_hdr='{"typ":"dppCon","kid":"TnGKjIlNZaatrEAYrbbjiB67rjkL_AGVWXO6q9hDJKU","alg":"ES256"}',
1254                   signed_connector=None,
1255                   no_signed_connector=False,
1256                   csign=True):
1257    conf = '{"wi-fi_tech":"infra","discovery":{"ssid":"test"},"cred":{'
1258    conf += '"akm":"dpp",'
1259
1260    if signed_connector:
1261        conn = signed_connector
1262        conf += '"signedConnector":"%s",' % conn
1263    elif not no_signed_connector:
1264        payload = '{"groups":[{"groupId":"*","netRole":"sta"}],"netAccessKey":{"kty":"EC","crv":"P-256","x":"aTF4JEGIPKSZ0Xv9zdCMjm-tn5XpMsYIVZ9wySAz1gI","y":"QGcHWA_6rbU9XDXAztoX-M5Q3suTnMaqEhULtn7SSXw"}}'
1265        sign = "_sm6YswxMf6hJLVTyYoU1uYUeY2VVkUNjrzjSiEhY42StD_RWowStEE-9CRsdCvLmsTptZ72_g40vTFwdId20A"
1266        conn = base64.urlsafe_b64encode(prot_hdr.encode()).decode().rstrip('=') + '.'
1267        conn += base64.urlsafe_b64encode(payload.encode()).decode().rstrip('=') + '.'
1268        conn += sign
1269        conf += '"signedConnector":"%s",' % conn
1270
1271    if csign:
1272        conf += '"csign":{'
1273        if kty:
1274            conf += '"kty":"%s",' % kty
1275        if crv:
1276            conf += '"crv":"%s",' % crv
1277        if x:
1278            conf += '"x":"%s",' % x
1279        if y:
1280            conf += '"y":"%s",' % y
1281        if kid:
1282            conf += '"kid":"%s"' % kid
1283        conf = conf.rstrip(',')
1284        conf += '}'
1285    else:
1286        conf = conf.rstrip(',')
1287
1288    conf += '}}'
1289
1290    return conf
1291
1292def run_dpp_config_error(dev, apdev, conf,
1293                         skip_net_access_key_mismatch=True,
1294                         conf_failure=True):
1295    check_dpp_capab(dev[0])
1296    check_dpp_capab(dev[1])
1297    if skip_net_access_key_mismatch:
1298        dev[0].set("dpp_ignore_netaccesskey_mismatch", "1")
1299    dev[1].set("dpp_config_obj_override", conf)
1300    run_dpp_qr_code_auth_unicast(dev, apdev, "prime256v1",
1301                                 require_conf_success=not conf_failure,
1302                                 require_conf_failure=conf_failure)
1303
1304def test_dpp_config_jwk_error_no_kty(dev, apdev):
1305    """DPP Config Object JWK error - no kty"""
1306    run_dpp_config_error(dev, apdev, build_conf_obj(kty=None))
1307
1308def test_dpp_config_jwk_error_unexpected_kty(dev, apdev):
1309    """DPP Config Object JWK error - unexpected kty"""
1310    run_dpp_config_error(dev, apdev, build_conf_obj(kty="unknown"))
1311
1312def test_dpp_config_jwk_error_no_crv(dev, apdev):
1313    """DPP Config Object JWK error - no crv"""
1314    run_dpp_config_error(dev, apdev, build_conf_obj(crv=None))
1315
1316def test_dpp_config_jwk_error_unsupported_crv(dev, apdev):
1317    """DPP Config Object JWK error - unsupported curve"""
1318    run_dpp_config_error(dev, apdev, build_conf_obj(crv="unsupported"))
1319
1320def test_dpp_config_jwk_error_no_x(dev, apdev):
1321    """DPP Config Object JWK error - no x"""
1322    run_dpp_config_error(dev, apdev, build_conf_obj(x=None))
1323
1324def test_dpp_config_jwk_error_invalid_x(dev, apdev):
1325    """DPP Config Object JWK error - invalid x"""
1326    run_dpp_config_error(dev, apdev, build_conf_obj(x="MTIz"))
1327
1328def test_dpp_config_jwk_error_no_y(dev, apdev):
1329    """DPP Config Object JWK error - no y"""
1330    run_dpp_config_error(dev, apdev, build_conf_obj(y=None))
1331
1332def test_dpp_config_jwk_error_invalid_y(dev, apdev):
1333    """DPP Config Object JWK error - invalid y"""
1334    run_dpp_config_error(dev, apdev, build_conf_obj(y="MTIz"))
1335
1336def test_dpp_config_jwk_error_invalid_xy(dev, apdev):
1337    """DPP Config Object JWK error - invalid x,y"""
1338    conf = build_conf_obj(x="MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY",
1339                          y="MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY")
1340    run_dpp_config_error(dev, apdev, conf)
1341
1342def test_dpp_config_jwk_error_no_kid(dev, apdev):
1343    """DPP Config Object JWK error - no kid"""
1344    # csign kid is optional field, so this results in success
1345    run_dpp_config_error(dev, apdev, build_conf_obj(kid=None),
1346                         conf_failure=False)
1347
1348def test_dpp_config_jws_error_prot_hdr_not_an_object(dev, apdev):
1349    """DPP Config Object JWS error - protected header not an object"""
1350    run_dpp_config_error(dev, apdev, build_conf_obj(prot_hdr="1"))
1351
1352def test_dpp_config_jws_error_prot_hdr_no_typ(dev, apdev):
1353    """DPP Config Object JWS error - protected header - no typ"""
1354    prot_hdr = '{"kid":"TnGKjIlNZaatrEAYrbbjiB67rjkL_AGVWXO6q9hDJKU","alg":"ES256"}'
1355    run_dpp_config_error(dev, apdev, build_conf_obj(prot_hdr=prot_hdr))
1356
1357def test_dpp_config_jws_error_prot_hdr_unsupported_typ(dev, apdev):
1358    """DPP Config Object JWS error - protected header - unsupported typ"""
1359    prot_hdr = '{"typ":"unsupported","kid":"TnGKjIlNZaatrEAYrbbjiB67rjkL_AGVWXO6q9hDJKU","alg":"ES256"}'
1360    run_dpp_config_error(dev, apdev, build_conf_obj(prot_hdr=prot_hdr))
1361
1362def test_dpp_config_jws_error_prot_hdr_no_alg(dev, apdev):
1363    """DPP Config Object JWS error - protected header - no alg"""
1364    prot_hdr = '{"typ":"dppCon","kid":"TnGKjIlNZaatrEAYrbbjiB67rjkL_AGVWXO6q9hDJKU"}'
1365    run_dpp_config_error(dev, apdev, build_conf_obj(prot_hdr=prot_hdr))
1366
1367def test_dpp_config_jws_error_prot_hdr_unexpected_alg(dev, apdev):
1368    """DPP Config Object JWS error - protected header - unexpected alg"""
1369    prot_hdr = '{"typ":"dppCon","kid":"TnGKjIlNZaatrEAYrbbjiB67rjkL_AGVWXO6q9hDJKU","alg":"unexpected"}'
1370    run_dpp_config_error(dev, apdev, build_conf_obj(prot_hdr=prot_hdr))
1371
1372def test_dpp_config_jws_error_prot_hdr_no_kid(dev, apdev):
1373    """DPP Config Object JWS error - protected header - no kid"""
1374    prot_hdr = '{"typ":"dppCon","alg":"ES256"}'
1375    run_dpp_config_error(dev, apdev, build_conf_obj(prot_hdr=prot_hdr))
1376
1377def test_dpp_config_jws_error_prot_hdr_unexpected_kid(dev, apdev):
1378    """DPP Config Object JWS error - protected header - unexpected kid"""
1379    prot_hdr = '{"typ":"dppCon","kid":"MTIz","alg":"ES256"}'
1380    run_dpp_config_error(dev, apdev, build_conf_obj(prot_hdr=prot_hdr))
1381
1382def test_dpp_config_signed_connector_error_no_dot_1(dev, apdev):
1383    """DPP Config Object signedConnector error - no dot(1)"""
1384    conn = "MTIz"
1385    run_dpp_config_error(dev, apdev, build_conf_obj(signed_connector=conn))
1386
1387def test_dpp_config_signed_connector_error_no_dot_2(dev, apdev):
1388    """DPP Config Object signedConnector error - no dot(2)"""
1389    conn = "eyJ0eXAiOiJkcHBDb24iLCJraWQiOiJUbkdLaklsTlphYXRyRUFZcmJiamlCNjdyamtMX0FHVldYTzZxOWhESktVIiwiYWxnIjoiRVMyNTYifQ.MTIz"
1390    run_dpp_config_error(dev, apdev, build_conf_obj(signed_connector=conn))
1391
1392def test_dpp_config_signed_connector_error_unexpected_signature_len(dev, apdev):
1393    """DPP Config Object signedConnector error - unexpected signature length"""
1394    conn = "eyJ0eXAiOiJkcHBDb24iLCJraWQiOiJUbkdLaklsTlphYXRyRUFZcmJiamlCNjdyamtMX0FHVldYTzZxOWhESktVIiwiYWxnIjoiRVMyNTYifQ.MTIz.MTIz"
1395    run_dpp_config_error(dev, apdev, build_conf_obj(signed_connector=conn))
1396
1397def test_dpp_config_signed_connector_error_invalid_signature_der(dev, apdev):
1398    """DPP Config Object signedConnector error - invalid signature DER"""
1399    conn = "eyJ0eXAiOiJkcHBDb24iLCJraWQiOiJUbkdLaklsTlphYXRyRUFZcmJiamlCNjdyamtMX0FHVldYTzZxOWhESktVIiwiYWxnIjoiRVMyNTYifQ.MTIz.MTI"
1400    run_dpp_config_error(dev, apdev, build_conf_obj(signed_connector=conn))
1401
1402def test_dpp_config_no_csign(dev, apdev):
1403    """DPP Config Object error - no csign"""
1404    run_dpp_config_error(dev, apdev, build_conf_obj(csign=False))
1405
1406def test_dpp_config_no_signed_connector(dev, apdev):
1407    """DPP Config Object error - no signedConnector"""
1408    run_dpp_config_error(dev, apdev, build_conf_obj(no_signed_connector=True))
1409
1410def test_dpp_config_unexpected_signed_connector_char(dev, apdev):
1411    """DPP Config Object error - unexpected signedConnector character"""
1412    run_dpp_config_error(dev, apdev, build_conf_obj(signed_connector='a\nb'))
1413
1414def test_dpp_config_root_not_an_object(dev, apdev):
1415    """DPP Config Object error - root not an object"""
1416    conf = "1"
1417    run_dpp_config_error(dev, apdev, conf)
1418
1419def test_dpp_config_no_wi_fi_tech(dev, apdev):
1420    """DPP Config Object error - no wi-fi_tech"""
1421    conf = "{}"
1422    run_dpp_config_error(dev, apdev, conf)
1423
1424def test_dpp_config_unsupported_wi_fi_tech(dev, apdev):
1425    """DPP Config Object error - unsupported wi-fi_tech"""
1426    conf = '{"wi-fi_tech":"unsupported"}'
1427    run_dpp_config_error(dev, apdev, conf)
1428
1429def test_dpp_config_no_discovery(dev, apdev):
1430    """DPP Config Object error - no discovery"""
1431    conf = '{"wi-fi_tech":"infra"}'
1432    run_dpp_config_error(dev, apdev, conf)
1433
1434def test_dpp_config_no_discovery_ssid(dev, apdev):
1435    """DPP Config Object error - no discovery::ssid"""
1436    conf = '{"wi-fi_tech":"infra","discovery":{}}'
1437    run_dpp_config_error(dev, apdev, conf)
1438
1439def test_dpp_config_too_long_discovery_ssid(dev, apdev):
1440    """DPP Config Object error - too long discovery::ssid"""
1441    conf = '{"wi-fi_tech":"infra","discovery":{"ssid":"%s"}}' % (33*'A')
1442    run_dpp_config_error(dev, apdev, conf)
1443
1444def test_dpp_config_no_cred(dev, apdev):
1445    """DPP Config Object error - no cred"""
1446    conf = '{"wi-fi_tech":"infra","discovery":{"ssid":"test"}}'
1447    run_dpp_config_error(dev, apdev, conf)
1448
1449def test_dpp_config_no_cred_akm(dev, apdev):
1450    """DPP Config Object error - no cred::akm"""
1451    conf = '{"wi-fi_tech":"infra","discovery":{"ssid":"test"},"cred":{}}'
1452    run_dpp_config_error(dev, apdev, conf)
1453
1454def test_dpp_config_unsupported_cred_akm(dev, apdev):
1455    """DPP Config Object error - unsupported cred::akm"""
1456    conf = '{"wi-fi_tech":"infra","discovery":{"ssid":"test"},"cred":{"akm":"unsupported"}}'
1457    run_dpp_config_error(dev, apdev, conf)
1458
1459def test_dpp_config_error_legacy_no_pass(dev, apdev):
1460    """DPP Config Object legacy error - no pass/psk"""
1461    conf = '{"wi-fi_tech":"infra","discovery":{"ssid":"test"},"cred":{"akm":"psk"}}'
1462    run_dpp_config_error(dev, apdev, conf)
1463
1464def test_dpp_config_error_legacy_too_short_pass(dev, apdev):
1465    """DPP Config Object legacy error - too short pass/psk"""
1466    conf = '{"wi-fi_tech":"infra","discovery":{"ssid":"test"},"cred":{"akm":"psk","pass":"1"}}'
1467    run_dpp_config_error(dev, apdev, conf)
1468
1469def test_dpp_config_error_legacy_too_long_pass(dev, apdev):
1470    """DPP Config Object legacy error - too long pass/psk"""
1471    conf = '{"wi-fi_tech":"infra","discovery":{"ssid":"test"},"cred":{"akm":"psk","pass":"%s"}}' % (64*'A')
1472    run_dpp_config_error(dev, apdev, conf)
1473
1474def test_dpp_config_error_legacy_psk_with_sae(dev, apdev):
1475    """DPP Config Object legacy error - psk_hex with SAE"""
1476    conf = '{"wi-fi_tech":"infra","discovery":{"ssid":"test"},"cred":{"akm":"sae","psk_hex":"%s"}}' % (32*"12")
1477    run_dpp_config_error(dev, apdev, conf)
1478
1479def test_dpp_config_error_legacy_no_pass_for_sae(dev, apdev):
1480    """DPP Config Object legacy error - no pass for SAE"""
1481    conf = '{"wi-fi_tech":"infra","discovery":{"ssid":"test"},"cred":{"akm":"psk+sae","psk_hex":"%s"}}' % (32*"12")
1482    run_dpp_config_error(dev, apdev, conf)
1483
1484def test_dpp_config_error_legacy_invalid_psk(dev, apdev):
1485    """DPP Config Object legacy error - invalid psk_hex"""
1486    conf = '{"wi-fi_tech":"infra","discovery":{"ssid":"test"},"cred":{"akm":"psk","psk_hex":"%s"}}' % (32*"qa")
1487    run_dpp_config_error(dev, apdev, conf)
1488
1489def test_dpp_config_error_legacy_too_short_psk(dev, apdev):
1490    """DPP Config Object legacy error - too short psk_hex"""
1491    conf = '{"wi-fi_tech":"infra","discovery":{"ssid":"test"},"cred":{"akm":"psk","psk_hex":"%s"}}' % (31*"12")
1492    run_dpp_config_error(dev, apdev, conf)
1493
1494def get_der_int_32(val):
1495    a, b = struct.unpack('BB', val[0:2])
1496    if a != 0x02:
1497        raise Exception("Invalid DER encoding of INTEGER")
1498    if b > len(val) - 2:
1499        raise Exception("Invalid length of INTEGER (truncated)")
1500    val = val[2:]
1501    if b == 32:
1502        r = val[0:32]
1503    elif b == 33:
1504        if val[0] != 0:
1505            raise Exception("Too large INTEGER (32)")
1506        r = val[1:33]
1507    elif b < 32:
1508        r = (32 - b) * b'\x00' + val[0:b]
1509    else:
1510        raise Exception("Invalid length of INTEGER (32): %d" % b)
1511    return r, val[b:]
1512
1513def ecdsa_sign(pkey, message, alg="sha256"):
1514    sign = OpenSSL.crypto.sign(pkey, message, alg)
1515    logger.debug("sign=" + binascii.hexlify(sign).decode())
1516    a, b = struct.unpack('BB', sign[0:2])
1517    if a != 0x30:
1518        raise Exception("Invalid DER encoding of ECDSA signature")
1519    if b != len(sign) - 2:
1520        raise Exception("Invalid length of ECDSA signature")
1521    sign = sign[2:]
1522
1523    r, sign = get_der_int_32(sign)
1524    s, sign = get_der_int_32(sign)
1525    if len(sign) != 0:
1526        raise Exception("Extra data at the end of ECDSA signature")
1527
1528    logger.info("r=" + binascii.hexlify(r).decode())
1529    logger.info("s=" + binascii.hexlify(s).decode())
1530    raw_sign = r + s
1531    return base64.urlsafe_b64encode(raw_sign).decode().rstrip('=')
1532
1533p256_priv_key = """-----BEGIN EC PRIVATE KEY-----
1534MHcCAQEEIBVQij9ah629f1pu3tarDQGQvrzHgAkgYd1jHGiLxNajoAoGCCqGSM49
1535AwEHoUQDQgAEAC9d2/JirKu72F2qLuv5jEFMD1Cqu9EiyGk7cOzn/2DJ51p2mEoW
1536n03N6XRvTC+G7WPol9Ng97NAM2sK57+F/Q==
1537-----END EC PRIVATE KEY-----"""
1538p256_pub_key_x = binascii.unhexlify("002f5ddbf262acabbbd85daa2eebf98c414c0f50aabbd122c8693b70ece7ff60")
1539p256_pub_key_y = binascii.unhexlify("c9e75a76984a169f4dcde9746f4c2f86ed63e897d360f7b340336b0ae7bf85fd")
1540
1541def run_dpp_config_connector(dev, apdev, expiry=None, payload=None,
1542                             skip_net_access_key_mismatch=True,
1543                             conf_failure=True):
1544    if not openssl_imported:
1545        raise HwsimSkip("OpenSSL python method not available")
1546    pkey = OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM,
1547                                          p256_priv_key)
1548    x = base64.urlsafe_b64encode(p256_pub_key_x).decode().rstrip('=')
1549    y = base64.urlsafe_b64encode(p256_pub_key_y).decode().rstrip('=')
1550
1551    pubkey = b'\x04' + p256_pub_key_x + p256_pub_key_y
1552    kid = base64.urlsafe_b64encode(hashlib.sha256(pubkey).digest()).decode().rstrip('=')
1553
1554    prot_hdr = '{"typ":"dppCon","kid":"%s","alg":"ES256"}' % kid
1555
1556    if not payload:
1557        payload = '{"groups":[{"groupId":"*","netRole":"sta"}],"netAccessKey":{"kty":"EC","crv":"P-256","x":"aTF4JEGIPKSZ0Xv9zdCMjm-tn5XpMsYIVZ9wySAz1gI","y":"QGcHWA_6rbU9XDXAztoX-M5Q3suTnMaqEhULtn7SSXw"}'
1558        if expiry:
1559            payload += ',"expiry":"%s"' % expiry
1560        payload += '}'
1561    conn = base64.urlsafe_b64encode(prot_hdr.encode()).decode().rstrip('=') + '.'
1562    conn += base64.urlsafe_b64encode(payload.encode()).decode().rstrip('=')
1563    sign = ecdsa_sign(pkey, conn)
1564    conn += '.' + sign
1565    run_dpp_config_error(dev, apdev,
1566                         build_conf_obj(x=x, y=y, signed_connector=conn),
1567                         skip_net_access_key_mismatch=skip_net_access_key_mismatch,
1568                         conf_failure=conf_failure)
1569
1570def test_dpp_config_connector_error_ext_sign(dev, apdev):
1571    """DPP Config Object connector error - external signature calculation"""
1572    run_dpp_config_connector(dev, apdev, conf_failure=False)
1573
1574def test_dpp_config_connector_error_too_short_timestamp(dev, apdev):
1575    """DPP Config Object connector error - too short timestamp"""
1576    run_dpp_config_connector(dev, apdev, expiry="1")
1577
1578def test_dpp_config_connector_error_invalid_timestamp(dev, apdev):
1579    """DPP Config Object connector error - invalid timestamp"""
1580    run_dpp_config_connector(dev, apdev, expiry=19*"1")
1581
1582def test_dpp_config_connector_error_invalid_timestamp_date(dev, apdev):
1583    """DPP Config Object connector error - invalid timestamp date"""
1584    run_dpp_config_connector(dev, apdev, expiry="9999-99-99T99:99:99Z")
1585
1586def test_dpp_config_connector_error_invalid_time_zone(dev, apdev):
1587    """DPP Config Object connector error - invalid time zone"""
1588    run_dpp_config_connector(dev, apdev, expiry="2018-01-01T00:00:00*")
1589
1590def test_dpp_config_connector_error_invalid_time_zone_2(dev, apdev):
1591    """DPP Config Object connector error - invalid time zone 2"""
1592    run_dpp_config_connector(dev, apdev, expiry="2018-01-01T00:00:00+")
1593
1594def test_dpp_config_connector_error_expired_1(dev, apdev):
1595    """DPP Config Object connector error - expired 1"""
1596    run_dpp_config_connector(dev, apdev, expiry="2018-01-01T00:00:00")
1597
1598def test_dpp_config_connector_error_expired_2(dev, apdev):
1599    """DPP Config Object connector error - expired 2"""
1600    run_dpp_config_connector(dev, apdev, expiry="2018-01-01T00:00:00Z")
1601
1602def test_dpp_config_connector_error_expired_3(dev, apdev):
1603    """DPP Config Object connector error - expired 3"""
1604    run_dpp_config_connector(dev, apdev, expiry="2018-01-01T00:00:00+01")
1605
1606def test_dpp_config_connector_error_expired_4(dev, apdev):
1607    """DPP Config Object connector error - expired 4"""
1608    run_dpp_config_connector(dev, apdev, expiry="2018-01-01T00:00:00+01:02")
1609
1610def test_dpp_config_connector_error_expired_5(dev, apdev):
1611    """DPP Config Object connector error - expired 5"""
1612    run_dpp_config_connector(dev, apdev, expiry="2018-01-01T00:00:00-01")
1613
1614def test_dpp_config_connector_error_expired_6(dev, apdev):
1615    """DPP Config Object connector error - expired 6"""
1616    run_dpp_config_connector(dev, apdev, expiry="2018-01-01T00:00:00-01:02")
1617
1618def test_dpp_config_connector_error_no_groups(dev, apdev):
1619    """DPP Config Object connector error - no groups"""
1620    payload = '{"netAccessKey":{"kty":"EC","crv":"P-256","x":"aTF4JEGIPKSZ0Xv9zdCMjm-tn5XpMsYIVZ9wySAz1gI","y":"QGcHWA_6rbU9XDXAztoX-M5Q3suTnMaqEhULtn7SSXw"}}'
1621    run_dpp_config_connector(dev, apdev, payload=payload)
1622
1623def test_dpp_config_connector_error_empty_groups(dev, apdev):
1624    """DPP Config Object connector error - empty groups"""
1625    payload = '{"groups":[],"netAccessKey":{"kty":"EC","crv":"P-256","x":"aTF4JEGIPKSZ0Xv9zdCMjm-tn5XpMsYIVZ9wySAz1gI","y":"QGcHWA_6rbU9XDXAztoX-M5Q3suTnMaqEhULtn7SSXw"}}'
1626    run_dpp_config_connector(dev, apdev, payload=payload)
1627
1628def test_dpp_config_connector_error_missing_group_id(dev, apdev):
1629    """DPP Config Object connector error - missing groupId"""
1630    payload = '{"groups":[{"netRole":"sta"}],"netAccessKey":{"kty":"EC","crv":"P-256","x":"aTF4JEGIPKSZ0Xv9zdCMjm-tn5XpMsYIVZ9wySAz1gI","y":"QGcHWA_6rbU9XDXAztoX-M5Q3suTnMaqEhULtn7SSXw"}}'
1631    run_dpp_config_connector(dev, apdev, payload=payload)
1632
1633def test_dpp_config_connector_error_missing_net_role(dev, apdev):
1634    """DPP Config Object connector error - missing netRole"""
1635    payload = '{"groups":[{"groupId":"*"}],"netAccessKey":{"kty":"EC","crv":"P-256","x":"aTF4JEGIPKSZ0Xv9zdCMjm-tn5XpMsYIVZ9wySAz1gI","y":"QGcHWA_6rbU9XDXAztoX-M5Q3suTnMaqEhULtn7SSXw"}}'
1636    run_dpp_config_connector(dev, apdev, payload=payload)
1637
1638def test_dpp_config_connector_error_missing_net_access_key(dev, apdev):
1639    """DPP Config Object connector error - missing netAccessKey"""
1640    payload = '{"groups":[{"groupId":"*","netRole":"sta"}]}'
1641    run_dpp_config_connector(dev, apdev, payload=payload)
1642
1643def test_dpp_config_connector_error_net_access_key_mismatch(dev, apdev):
1644    """DPP Config Object connector error - netAccessKey mismatch"""
1645    payload = '{"groups":[{"groupId":"*","netRole":"sta"}],"netAccessKey":{"kty":"EC","crv":"P-256","x":"aTF4JEGIPKSZ0Xv9zdCMjm-tn5XpMsYIVZ9wySAz1gI","y":"QGcHWA_6rbU9XDXAztoX-M5Q3suTnMaqEhULtn7SSXw"}}'
1646    run_dpp_config_connector(dev, apdev, payload=payload,
1647                             skip_net_access_key_mismatch=False)
1648
1649def test_dpp_gas_timeout(dev, apdev):
1650    """DPP and GAS server timeout for a query"""
1651    check_dpp_capab(dev[0])
1652    check_dpp_capab(dev[1])
1653    logger.info("dev0 displays QR Code")
1654    id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
1655    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
1656
1657    logger.info("dev1 scans QR Code and initiates DPP Authentication")
1658    dev[0].set("ext_mgmt_frame_handling", "1")
1659    dev[0].dpp_listen(2412)
1660
1661    # Force GAS fragmentation
1662    conf = '{"wi-fi_tech":"infra", "discovery":{"ssid":"test"},"cred":{"akm":"psk","pass":"secret passphrase"}}' + 3000*' '
1663    dev[1].set("dpp_config_obj_override", conf)
1664
1665    dev[1].dpp_auth_init(uri=uri0)
1666
1667    # DPP Authentication Request
1668    msg = dev[0].mgmt_rx()
1669    if "OK" not in dev[0].request("MGMT_RX_PROCESS freq={} datarate={} ssi_signal={} frame={}".format(
1670        msg['freq'], msg['datarate'], msg['ssi_signal'], binascii.hexlify(msg['frame']).decode())):
1671        raise Exception("MGMT_RX_PROCESS failed")
1672
1673    # DPP Authentication Confirmation
1674    msg = dev[0].mgmt_rx()
1675    if "OK" not in dev[0].request("MGMT_RX_PROCESS freq={} datarate={} ssi_signal={} frame={}".format(
1676        msg['freq'], msg['datarate'], msg['ssi_signal'], binascii.hexlify(msg['frame']).decode())):
1677        raise Exception("MGMT_RX_PROCESS failed")
1678
1679    wait_auth_success(dev[0], dev[1])
1680
1681    # DPP Configuration Response (GAS Initial Response frame)
1682    msg = dev[0].mgmt_rx()
1683    if "OK" not in dev[0].request("MGMT_RX_PROCESS freq={} datarate={} ssi_signal={} frame={}".format(
1684        msg['freq'], msg['datarate'], msg['ssi_signal'], binascii.hexlify(msg['frame']).decode())):
1685        raise Exception("MGMT_RX_PROCESS failed")
1686
1687    # GAS Comeback Response frame
1688    msg = dev[0].mgmt_rx()
1689    # Do not continue to force timeout on GAS server
1690
1691    ev = dev[0].wait_event(["GAS-QUERY-DONE"], timeout=10)
1692    if ev is None:
1693        raise Exception("GAS result not reported (Enrollee)")
1694    if "result=TIMEOUT" not in ev:
1695        raise Exception("Unexpected GAS result (Enrollee): " + ev)
1696    dev[0].set("ext_mgmt_frame_handling", "0")
1697
1698    ev = dev[1].wait_event(["DPP-CONF-FAILED"], timeout=65)
1699    if ev is None:
1700        raise Exception("DPP configuration failure not reported (Configurator)")
1701
1702    ev = dev[0].wait_event(["DPP-CONF-FAILED"], timeout=1)
1703    if ev is None:
1704        raise Exception("DPP configuration failure not reported (Enrollee)")
1705
1706def test_dpp_akm_sha256(dev, apdev):
1707    """DPP AKM (SHA256)"""
1708    run_dpp_akm(dev, apdev, 32)
1709
1710def test_dpp_akm_sha384(dev, apdev):
1711    """DPP AKM (SHA384)"""
1712    run_dpp_akm(dev, apdev, 48)
1713
1714def test_dpp_akm_sha512(dev, apdev):
1715    """DPP AKM (SHA512)"""
1716    run_dpp_akm(dev, apdev, 64)
1717
1718def run_dpp_akm(dev, apdev, pmk_len):
1719    check_dpp_capab(dev[0])
1720    check_dpp_capab(dev[1])
1721    params = {"ssid": "dpp",
1722              "wpa": "2",
1723              "wpa_key_mgmt": "DPP",
1724              "rsn_pairwise": "CCMP",
1725              "ieee80211w": "2"}
1726    try:
1727        hapd = hostapd.add_ap(apdev[0], params)
1728    except:
1729        raise HwsimSkip("DPP not supported")
1730
1731    conf = hapd.request("GET_CONFIG")
1732    if "key_mgmt=DPP" not in conf.splitlines():
1733        logger.info("GET_CONFIG:\n" + conf)
1734        raise Exception("GET_CONFIG did not report correct key_mgmt")
1735
1736    id = dev[0].connect("dpp", key_mgmt="DPP", ieee80211w="2", scan_freq="2412",
1737                        dpp_pfs="2", wait_connect=False)
1738    ev = dev[0].wait_event(["CTRL-EVENT-NETWORK-NOT-FOUND"], timeout=2)
1739    if not ev:
1740        raise Exception("Network mismatch not reported")
1741    dev[0].request("DISCONNECT")
1742    dev[0].dump_monitor()
1743
1744    bssid = hapd.own_addr()
1745    pmkid = 16*'11'
1746    akmp = 2**23
1747    pmk = pmk_len*'22'
1748    cmd = "PMKSA_ADD %d %s %s %s 30240 43200 %d 0" % (id, bssid, pmkid, pmk, akmp)
1749    if "OK" not in dev[0].request(cmd):
1750        raise Exception("PMKSA_ADD failed (wpa_supplicant)")
1751    dev[0].select_network(id, freq="2412")
1752    ev = dev[0].wait_event(["CTRL-EVENT-ASSOC-REJECT"], timeout=2)
1753    dev[0].request("DISCONNECT")
1754    dev[0].dump_monitor()
1755    if not ev:
1756        raise Exception("Association attempt was not rejected")
1757    if "status_code=53" not in ev:
1758        raise Exception("Unexpected status code: " + ev)
1759
1760    addr = dev[0].own_addr()
1761    cmd = "PMKSA_ADD %s %s %s 0 %d" % (addr, pmkid, pmk, akmp)
1762    if "OK" not in hapd.request(cmd):
1763        raise Exception("PMKSA_ADD failed (hostapd)")
1764
1765    cmd = "PMKSA_ADD %d %s %s %s 30240 43200 %d 0" % (id, bssid, pmkid, pmk, akmp)
1766    if "OK" not in dev[0].request(cmd):
1767        raise Exception("PMKSA_ADD failed (wpa_supplicant)")
1768    dev[0].select_network(id, freq="2412")
1769    dev[0].wait_connected()
1770    val = dev[0].get_status_field("key_mgmt")
1771    if val != "DPP":
1772        raise Exception("Unexpected key_mgmt: " + val)
1773
1774params1_csign = "3059301306072a8648ce3d020106082a8648ce3d03010703420004d02e5bd81a120762b5f0f2994777f5d40297238a6c294fd575cdf35fabec44c050a6421c401d98d659fd2ed13c961cc8287944dd3202f516977800d3ab2f39ee"
1775params1_ap_connector = "eyJ0eXAiOiJkcHBDb24iLCJraWQiOiJzOEFrYjg5bTV4UGhoYk5UbTVmVVo0eVBzNU5VMkdxYXNRY3hXUWhtQVFRIiwiYWxnIjoiRVMyNTYifQ.eyJncm91cHMiOlt7Imdyb3VwSWQiOiIqIiwibmV0Um9sZSI6ImFwIn1dLCJuZXRBY2Nlc3NLZXkiOnsia3R5IjoiRUMiLCJjcnYiOiJQLTI1NiIsIngiOiIwOHF4TlNYRzRWemdCV3BjVUdNSmc1czNvbElOVFJsRVQ1aERpNkRKY3ZjIiwieSI6IlVhaGFYQXpKRVpRQk1YaHRUQnlZZVlrOWtJYjk5UDA3UV9NcW9TVVZTVEkifX0.a5_nfMVr7Qe1SW0ZL3u6oQRm5NUCYUSfixDAJOUFN3XUfECBZ6E8fm8xjeSfdOytgRidTz0CTlIRjzPQo82dmQ"
1776params1_ap_netaccesskey = "30770201010420f6531d17f29dfab655b7c9e923478d5a345164c489aadd44a3519c3e9dcc792da00a06082a8648ce3d030107a14403420004d3cab13525c6e15ce0056a5c506309839b37a2520d4d19444f98438ba0c972f751a85a5c0cc911940131786d4c1c9879893d9086fdf4fd3b43f32aa125154932"
1777params1_sta_connector = "eyJ0eXAiOiJkcHBDb24iLCJraWQiOiJzOEFrYjg5bTV4UGhoYk5UbTVmVVo0eVBzNU5VMkdxYXNRY3hXUWhtQVFRIiwiYWxnIjoiRVMyNTYifQ.eyJncm91cHMiOlt7Imdyb3VwSWQiOiIqIiwibmV0Um9sZSI6InN0YSJ9XSwibmV0QWNjZXNzS2V5Ijp7Imt0eSI6IkVDIiwiY3J2IjoiUC0yNTYiLCJ4IjoiZWMzR3NqQ3lQMzVBUUZOQUJJdEltQnN4WXVyMGJZX1dES1lfSE9zUGdjNCIsInkiOiJTRS1HVllkdWVnTFhLMU1TQXZNMEx2QWdLREpTNWoyQVhCbE9PMTdUSTRBIn19.PDK9zsGlK-e1pEOmNxVeJfCS8pNeay6ckIS1TXCQsR64AR-9wFPCNVjqOxWvVKltehyMFqVAtOcv0IrjtMJFqQ"
1778params1_sta_netaccesskey = "30770201010420bc33380c26fd2168b69cd8242ed1df07ba89aa4813f8d4e8523de6ca3f8dd28ba00a06082a8648ce3d030107a1440342000479cdc6b230b23f7e40405340048b48981b3162eaf46d8fd60ca63f1ceb0f81ce484f8655876e7a02d72b531202f3342ef020283252e63d805c194e3b5ed32380"
1779params1_sta_pk_hash = "38f1ba82b3b49ef1c9ab616e5e94a914c75af3a4d6e25b7f112741e530f3b8e6"
1780
1781def test_dpp_network_introduction(dev, apdev):
1782    """DPP network introduction"""
1783    check_dpp_capab(dev[0])
1784    check_dpp_capab(dev[1])
1785
1786    params = {"ssid": "dpp",
1787              "wpa": "2",
1788              "wpa_key_mgmt": "DPP",
1789              "ieee80211w": "2",
1790              "rsn_pairwise": "CCMP",
1791              "dpp_connector": params1_ap_connector,
1792              "dpp_csign": params1_csign,
1793              "dpp_netaccesskey": params1_ap_netaccesskey}
1794    try:
1795        hapd = hostapd.add_ap(apdev[0], params)
1796    except:
1797        raise HwsimSkip("DPP not supported")
1798
1799    id = dev[0].connect("dpp", key_mgmt="DPP", scan_freq="2412",
1800                        ieee80211w="2",
1801                        dpp_csign=params1_csign,
1802                        dpp_connector=params1_sta_connector,
1803                        dpp_netaccesskey=params1_sta_netaccesskey)
1804    val = dev[0].get_status_field("key_mgmt")
1805    if val != "DPP":
1806        raise Exception("Unexpected key_mgmt: " + val)
1807
1808    ev = hapd.wait_sta(dev[0].own_addr())
1809    if "dpp_pkhash=" + params1_sta_pk_hash not in ev:
1810        raise Exception("dpp_pkhash not reported correctly: " + ev)
1811
1812    sta = hapd.get_sta(dev[0].own_addr())
1813    if 'dpp_pkhash' not in sta:
1814        raise Exception("dpp_pkhash not included in STA info")
1815    if sta['dpp_pkhash'] != params1_sta_pk_hash:
1816        raise Exception("Incorrect dpp_pkhash in STA info: " + sta['dpp_pkhash'])
1817
1818def test_dpp_network_introduction_expired(dev, apdev):
1819    """DPP network introduction with expired netaccesskey"""
1820    check_dpp_capab(dev[0])
1821    check_dpp_capab(dev[1])
1822
1823    params = {"ssid": "dpp",
1824              "wpa": "2",
1825              "wpa_key_mgmt": "DPP",
1826              "ieee80211w": "2",
1827              "rsn_pairwise": "CCMP",
1828              "dpp_connector": params1_ap_connector,
1829              "dpp_csign": params1_csign,
1830              "dpp_netaccesskey": params1_ap_netaccesskey,
1831              "dpp_netaccesskey_expiry": "1565530889"}
1832    try:
1833        hapd = hostapd.add_ap(apdev[0], params)
1834    except:
1835        raise HwsimSkip("DPP not supported")
1836
1837    dev[0].connect("dpp", key_mgmt="DPP", scan_freq="2412",
1838                   ieee80211w="2",
1839                   dpp_csign=params1_csign,
1840                   dpp_connector=params1_sta_connector,
1841                   dpp_netaccesskey=params1_sta_netaccesskey,
1842                   wait_connect=False)
1843    ev = hapd.wait_event(["DPP-RX"], timeout=10)
1844    if ev is None:
1845        raise Exception("No DPP Peer Discovery Request seen")
1846    if "type=5" not in ev:
1847        raise Exception("Unexpected DPP message received: " + ev)
1848    ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1)
1849    dev[0].request("DISCONNECT")
1850    if ev:
1851        raise Exception("Connection reported")
1852
1853    hapd.disable()
1854    hapd.set("dpp_netaccesskey_expiry", "2565530889")
1855    hapd.enable()
1856    dev[0].request("RECONNECT")
1857    dev[0].wait_connected()
1858
1859def test_dpp_network_introduction_clear_ap(dev, apdev):
1860    """DPP network introduction with PMKSA cleared on AP"""
1861    check_dpp_capab(dev[0])
1862    check_dpp_capab(dev[1])
1863
1864    params = {"ssid": "dpp",
1865              "wpa": "2",
1866              "wpa_key_mgmt": "DPP",
1867              "ieee80211w": "2",
1868              "rsn_pairwise": "CCMP",
1869              "dpp_connector": params1_ap_connector,
1870              "dpp_csign": params1_csign,
1871              "dpp_netaccesskey": params1_ap_netaccesskey}
1872    try:
1873        hapd = hostapd.add_ap(apdev[0], params)
1874    except:
1875        raise HwsimSkip("DPP not supported")
1876
1877    id = dev[0].connect("dpp", key_mgmt="DPP", scan_freq="2412",
1878                        ieee80211w="2",
1879                        dpp_csign=params1_csign,
1880                        dpp_connector=params1_sta_connector,
1881                        dpp_netaccesskey=params1_sta_netaccesskey)
1882    dev[0].request("DISCONNECT")
1883    dev[0].wait_disconnected()
1884    dev[0].request("RECONNECT")
1885    ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED", "DPP-INTRO"], timeout=10)
1886    if ev is None:
1887        raise Exception("Reconnection timed out")
1888    if "DPP-INTRO" in ev:
1889        raise Exception("Unexpected network introduction on reconnection")
1890    dev[0].request("DISCONNECT")
1891    dev[0].wait_disconnected()
1892
1893    hapd.request("PMKSA_FLUSH")
1894    dev[0].request("RECONNECT")
1895    ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED", "DPP-INTRO"], timeout=10)
1896    if ev is None:
1897        raise Exception("Reconnection timed out")
1898    if "DPP-INTRO" not in ev:
1899        raise Exception("No network introduction on reconnection(2)")
1900
1901def test_dpp_and_sae_akm(dev, apdev):
1902    """DPP and SAE AKMs"""
1903    check_dpp_capab(dev[0])
1904    check_dpp_capab(dev[1])
1905    check_sae_capab(dev[1])
1906
1907    params = {"ssid": "dpp+sae",
1908              "wpa": "2",
1909              "wpa_key_mgmt": "DPP SAE",
1910              "ieee80211w": "2",
1911              "rsn_pairwise": "CCMP",
1912              "sae_password": "sae-password",
1913              "dpp_connector": params1_ap_connector,
1914              "dpp_csign": params1_csign,
1915              "dpp_netaccesskey": params1_ap_netaccesskey}
1916    try:
1917        hapd = hostapd.add_ap(apdev[0], params)
1918    except:
1919        raise HwsimSkip("DPP not supported")
1920
1921    id = dev[0].connect("dpp+sae", key_mgmt="DPP", scan_freq="2412",
1922                        ieee80211w="2",
1923                        dpp_csign=params1_csign,
1924                        dpp_connector=params1_sta_connector,
1925                        dpp_netaccesskey=params1_sta_netaccesskey)
1926    val = dev[0].get_status_field("key_mgmt")
1927    if val != "DPP":
1928        raise Exception("Unexpected key_mgmt for DPP: " + val)
1929
1930    dev[1].request("SET sae_groups ")
1931    id = dev[1].connect("dpp+sae", key_mgmt="SAE", scan_freq="2412",
1932                        ieee80211w="2", psk="sae-password")
1933    val = dev[1].get_status_field("key_mgmt")
1934    if val != "SAE":
1935        raise Exception("Unexpected key_mgmt for SAE: " + val)
1936
1937def test_dpp_ap_config(dev, apdev):
1938    """DPP and AP configuration"""
1939    run_dpp_ap_config(dev, apdev)
1940
1941def test_dpp_ap_config_p256_p256(dev, apdev):
1942    """DPP and AP configuration (P-256 + P-256)"""
1943    run_dpp_ap_config(dev, apdev, curve="P-256", conf_curve="P-256")
1944
1945def test_dpp_ap_config_p256_p384(dev, apdev):
1946    """DPP and AP configuration (P-256 + P-384)"""
1947    run_dpp_ap_config(dev, apdev, curve="P-256", conf_curve="P-384")
1948
1949def test_dpp_ap_config_p256_p521(dev, apdev):
1950    """DPP and AP configuration (P-256 + P-521)"""
1951    run_dpp_ap_config(dev, apdev, curve="P-256", conf_curve="P-521")
1952
1953def test_dpp_ap_config_p384_p256(dev, apdev):
1954    """DPP and AP configuration (P-384 + P-256)"""
1955    run_dpp_ap_config(dev, apdev, curve="P-384", conf_curve="P-256")
1956
1957def test_dpp_ap_config_p384_p384(dev, apdev):
1958    """DPP and AP configuration (P-384 + P-384)"""
1959    run_dpp_ap_config(dev, apdev, curve="P-384", conf_curve="P-384")
1960
1961def test_dpp_ap_config_p384_p521(dev, apdev):
1962    """DPP and AP configuration (P-384 + P-521)"""
1963    run_dpp_ap_config(dev, apdev, curve="P-384", conf_curve="P-521")
1964
1965def test_dpp_ap_config_p521_p256(dev, apdev):
1966    """DPP and AP configuration (P-521 + P-256)"""
1967    run_dpp_ap_config(dev, apdev, curve="P-521", conf_curve="P-256")
1968
1969def test_dpp_ap_config_p521_p384(dev, apdev):
1970    """DPP and AP configuration (P-521 + P-384)"""
1971    run_dpp_ap_config(dev, apdev, curve="P-521", conf_curve="P-384")
1972
1973def test_dpp_ap_config_p521_p521(dev, apdev):
1974    """DPP and AP configuration (P-521 + P-521)"""
1975    run_dpp_ap_config(dev, apdev, curve="P-521", conf_curve="P-521")
1976
1977def test_dpp_ap_config_bp256_bp256(dev, apdev):
1978    """DPP and AP configuration (BP-256 + BP-256)"""
1979    run_dpp_ap_config(dev, apdev, curve="BP-256", conf_curve="BP-256")
1980
1981def test_dpp_ap_config_bp384_bp384(dev, apdev):
1982    """DPP and AP configuration (BP-384 + BP-384)"""
1983    run_dpp_ap_config(dev, apdev, curve="BP-384", conf_curve="BP-384")
1984
1985def test_dpp_ap_config_bp512_bp512(dev, apdev):
1986    """DPP and AP configuration (BP-512 + BP-512)"""
1987    run_dpp_ap_config(dev, apdev, curve="BP-512", conf_curve="BP-512")
1988
1989def test_dpp_ap_config_p256_bp256(dev, apdev):
1990    """DPP and AP configuration (P-256 + BP-256)"""
1991    run_dpp_ap_config(dev, apdev, curve="P-256", conf_curve="BP-256")
1992
1993def test_dpp_ap_config_bp256_p256(dev, apdev):
1994    """DPP and AP configuration (BP-256 + P-256)"""
1995    run_dpp_ap_config(dev, apdev, curve="BP-256", conf_curve="P-256")
1996
1997def test_dpp_ap_config_p521_bp512(dev, apdev):
1998    """DPP and AP configuration (P-521 + BP-512)"""
1999    run_dpp_ap_config(dev, apdev, curve="P-521", conf_curve="BP-512")
2000
2001def test_dpp_ap_config_bp512_p521(dev, apdev):
2002    """DPP and AP configuration (BP-512 + P-521)"""
2003    run_dpp_ap_config(dev, apdev, curve="BP-512", conf_curve="P-521")
2004
2005def test_dpp_ap_config_reconfig_configurator(dev, apdev):
2006    """DPP and AP configuration with Configurator reconfiguration"""
2007    run_dpp_ap_config(dev, apdev, reconf_configurator=True)
2008
2009def test_dpp_ap_config_sae(dev, apdev):
2010    """DPP and AP configuration for SAE"""
2011    run_dpp_ap_config(dev, apdev, sae=True)
2012
2013def update_hapd_config(hapd):
2014    ev = hapd.wait_event(["DPP-CONFOBJ-AKM"], timeout=1)
2015    if ev is None:
2016        raise Exception("AKM not reported (AP)")
2017    akm = ev.split(' ')[1]
2018
2019    ev = hapd.wait_event(["DPP-CONFOBJ-SSID"], timeout=1)
2020    if ev is None:
2021        raise Exception("SSID not reported (AP)")
2022    ssid = ev.split(' ')[1]
2023
2024    ev = hapd.wait_event(["DPP-CONNECTOR"], timeout=1)
2025    if ev is None:
2026        raise Exception("Connector not reported (AP)")
2027    connector = ev.split(' ')[1]
2028
2029    if akm == "sae":
2030        ev = hapd.wait_event(["DPP-CONFOBJ-PASS"], timeout=1)
2031        if ev is None:
2032            raise Exception("Password not reported (AP)")
2033        password = ev.split(' ')[1]
2034
2035    ev = hapd.wait_event(["DPP-C-SIGN-KEY"], timeout=1)
2036    if ev is None:
2037        raise Exception("C-sign-key not reported (AP)")
2038    p = ev.split(' ')
2039    csign = p[1]
2040
2041    ev = hapd.wait_event(["DPP-NET-ACCESS-KEY"], timeout=1)
2042    if ev is None:
2043        raise Exception("netAccessKey not reported (AP)")
2044    p = ev.split(' ')
2045    net_access_key = p[1]
2046    net_access_key_expiry = p[2] if len(p) > 2 else None
2047
2048    logger.info("Update AP configuration")
2049    hapd.disable()
2050    hapd.set("ssid", ssid)
2051    hapd.set("utf8_ssid", "1")
2052    hapd.set("wpa", "2")
2053    if akm == "sae":
2054        hapd.set("wpa_key_mgmt", "SAE")
2055        hapd.set("sae_password", binascii.unhexlify(password).decode())
2056    else:
2057        hapd.set("wpa_key_mgmt", "DPP")
2058    hapd.set("ieee80211w", "2")
2059    hapd.set("rsn_pairwise", "CCMP")
2060    hapd.set("dpp_connector", connector)
2061    hapd.set("dpp_csign", csign)
2062    hapd.set("dpp_netaccesskey", net_access_key)
2063    if net_access_key_expiry:
2064        hapd.set("dpp_netaccesskey_expiry", net_access_key_expiry)
2065    hapd.enable()
2066
2067def run_dpp_ap_config(dev, apdev, curve=None, conf_curve=None,
2068                      reconf_configurator=False, sae=False):
2069    if sae:
2070        check_sae_capab(dev[0])
2071        check_sae_capab(dev[1])
2072        dev[0].set("sae_groups", "")
2073        dev[1].set("sae_groups", "")
2074
2075    brainpool = (curve and "BP-" in curve) or \
2076        (conf_curve and "BP-" in conf_curve)
2077    check_dpp_capab(dev[0], brainpool)
2078    check_dpp_capab(dev[1], brainpool)
2079    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured"})
2080    check_dpp_capab(hapd)
2081
2082    id_h = hapd.dpp_bootstrap_gen(chan="81/1", mac=True, curve=curve)
2083    uri = hapd.request("DPP_BOOTSTRAP_GET_URI %d" % id_h)
2084
2085    conf_id = dev[0].dpp_configurator_add(curve=conf_curve)
2086
2087    if reconf_configurator:
2088        csign = dev[0].request("DPP_CONFIGURATOR_GET_KEY %d" % conf_id)
2089        if "FAIL" in csign or len(csign) == 0:
2090            raise Exception("DPP_CONFIGURATOR_GET_KEY failed")
2091
2092    if sae:
2093        dev[0].dpp_auth_init(uri=uri, conf="ap-sae", configurator=conf_id,
2094                             passphrase="secret SAE password")
2095    else:
2096        dev[0].dpp_auth_init(uri=uri, conf="ap-dpp", configurator=conf_id)
2097    wait_auth_success(hapd, dev[0], configurator=dev[0], enrollee=hapd)
2098    update_hapd_config(hapd)
2099
2100    id1 = dev[1].dpp_bootstrap_gen(chan="81/1", mac=True, curve=curve)
2101    uri1 = dev[1].request("DPP_BOOTSTRAP_GET_URI %d" % id1)
2102
2103    if reconf_configurator:
2104        dev[0].dpp_configurator_remove(conf_id)
2105        conf_id = dev[0].dpp_configurator_add(curve=conf_curve, key=csign)
2106
2107    dev[1].dpp_listen(2412)
2108    if sae:
2109        dev[0].dpp_auth_init(uri=uri1, conf="sta-sae", configurator=conf_id,
2110                             passphrase="secret SAE password")
2111    else:
2112        dev[0].dpp_auth_init(uri=uri1, conf="sta-dpp", configurator=conf_id)
2113    res = wait_auth_success(dev[1], dev[0],
2114                            configurator=dev[0], enrollee=dev[1],
2115                            stop_responder=True)
2116    sta_pk_hash = res['initiator-auth-success-pkhash']
2117
2118    ev = dev[1].wait_event(["DPP-CONFOBJ-SSID"], timeout=1)
2119    if ev is None:
2120        raise Exception("SSID not reported")
2121    ssid = ev.split(' ')[1]
2122
2123    ev = dev[1].wait_event(["DPP-CONNECTOR"], timeout=1)
2124    if ev is None:
2125        raise Exception("Connector not reported")
2126    connector = ev.split(' ')[1]
2127
2128    ev = dev[1].wait_event(["DPP-C-SIGN-KEY"], timeout=1)
2129    if ev is None:
2130        raise Exception("C-sign-key not reported")
2131    p = ev.split(' ')
2132    csign = p[1]
2133
2134    ev = dev[1].wait_event(["DPP-NET-ACCESS-KEY"], timeout=1)
2135    if ev is None:
2136        raise Exception("netAccessKey not reported")
2137    p = ev.split(' ')
2138    net_access_key = p[1]
2139    net_access_key_expiry = p[2] if len(p) > 2 else None
2140
2141    dev[1].dump_monitor()
2142
2143    if sae:
2144        id = dev[1].connect(ssid, key_mgmt="SAE", ieee80211w="2",
2145                            scan_freq="2412",
2146                            sae_password="secret SAE password",
2147                            only_add_network=True)
2148    else:
2149        id = dev[1].connect(ssid, key_mgmt="DPP", ieee80211w="2",
2150                            scan_freq="2412",
2151                            only_add_network=True)
2152        dev[1].set_network_quoted(id, "dpp_connector", connector)
2153        dev[1].set_network(id, "dpp_csign", csign)
2154        dev[1].set_network(id, "dpp_netaccesskey", net_access_key)
2155        if net_access_key_expiry:
2156            dev[1].set_network(id, "dpp_netaccess_expiry",
2157                               net_access_key_expiry)
2158
2159    logger.info("Check data connection")
2160    dev[1].select_network(id, freq="2412")
2161    dev[1].wait_connected()
2162
2163    if not sae:
2164        ev = hapd.wait_sta(dev[1].own_addr())
2165        if "dpp_pkhash=" + sta_pk_hash not in ev:
2166            raise Exception("dpp_pkhash not reported correctly: " + ev)
2167
2168        sta = hapd.get_sta(dev[1].own_addr())
2169        if 'dpp_pkhash' not in sta:
2170            raise Exception("dpp_pkhash not included in STA info")
2171        if sta['dpp_pkhash'] != sta_pk_hash:
2172            raise Exception("Incorrect dpp_pkhash in STA info: " + sta['dpp_pkhash'])
2173
2174        dev[1].request("DISCONNECT")
2175        dev[1].wait_disconnected()
2176        dev[1].request("RECONNECT")
2177        dev[1].wait_connected()
2178        ev = hapd.wait_sta(dev[1].own_addr())
2179        if "dpp_pkhash=" + sta_pk_hash not in ev:
2180            raise Exception("dpp_pkhash not reported correctly(2): " + ev)
2181
2182        sta = hapd.get_sta(dev[1].own_addr())
2183        if 'dpp_pkhash' not in sta:
2184            raise Exception("dpp_pkhash not included in STA info(2)")
2185        if sta['dpp_pkhash'] != sta_pk_hash:
2186            raise Exception("Incorrect dpp_pkhash in STA info(2): " + sta['dpp_pkhash'])
2187
2188def test_dpp_auto_connect_1(dev, apdev):
2189    """DPP and auto connect (1)"""
2190    try:
2191        run_dpp_auto_connect(dev, apdev, 1)
2192    finally:
2193        dev[0].set("dpp_config_processing", "0", allow_fail=True)
2194
2195def test_dpp_auto_connect_2(dev, apdev):
2196    """DPP and auto connect (2)"""
2197    try:
2198        run_dpp_auto_connect(dev, apdev, 2)
2199    finally:
2200        dev[0].set("dpp_config_processing", "0", allow_fail=True)
2201
2202def test_dpp_auto_connect_2_connect_cmd(dev, apdev):
2203    """DPP and auto connect (2) using connect_cmd"""
2204    wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
2205    wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
2206    dev_new = [wpas, dev[1]]
2207    try:
2208        run_dpp_auto_connect(dev_new, apdev, 2)
2209    finally:
2210        wpas.set("dpp_config_processing", "0", allow_fail=True)
2211
2212def test_dpp_auto_connect_2_sta_ver1(dev, apdev):
2213    """DPP and auto connect (2; STA using ver 1)"""
2214    try:
2215        run_dpp_auto_connect(dev, apdev, 2, sta_version=1)
2216    finally:
2217        dev[0].set("dpp_config_processing", "0", allow_fail=True)
2218
2219def test_dpp_auto_connect_2_ap_ver1(dev, apdev):
2220    """DPP and auto connect (2; AP using ver 1)"""
2221    try:
2222        run_dpp_auto_connect(dev, apdev, 2, ap_version=1)
2223    finally:
2224        dev[0].set("dpp_config_processing", "0", allow_fail=True)
2225
2226def test_dpp_auto_connect_2_ver1(dev, apdev):
2227    """DPP and auto connect (2; AP and STA using ver 1)"""
2228    try:
2229        run_dpp_auto_connect(dev, apdev, 2, ap_version=1, sta_version=1)
2230    finally:
2231        dev[0].set("dpp_config_processing", "0", allow_fail=True)
2232
2233def test_dpp_auto_connect_2_conf_ver1(dev, apdev):
2234    """DPP and auto connect (2; Configurator using ver 1)"""
2235    try:
2236        run_dpp_auto_connect(dev, apdev, 2, sta1_version=1)
2237    finally:
2238        dev[0].set("dpp_config_processing", "0", allow_fail=True)
2239
2240def run_dpp_auto_connect(dev, apdev, processing, ap_version=0, sta_version=0,
2241                         sta1_version=0, stop_after_prov=False):
2242    check_dpp_capab(dev[0])
2243    check_dpp_capab(dev[1])
2244
2245    csign = "30770201010420768240a3fc89d6662d9782f120527fe7fb9edc6366ab0b9c7dde96125cfd250fa00a06082a8648ce3d030107a144034200042908e1baf7bf413cc66f9e878a03e8bb1835ba94b033dbe3d6969fc8575d5eb5dfda1cb81c95cee21d0cd7d92ba30541ffa05cb6296f5dd808b0c1c2a83c0708"
2246    csign_pub = "3059301306072a8648ce3d020106082a8648ce3d030107034200042908e1baf7bf413cc66f9e878a03e8bb1835ba94b033dbe3d6969fc8575d5eb5dfda1cb81c95cee21d0cd7d92ba30541ffa05cb6296f5dd808b0c1c2a83c0708"
2247    ap_connector = "eyJ0eXAiOiJkcHBDb24iLCJraWQiOiJwYWtZbXVzd1dCdWpSYTl5OEsweDViaTVrT3VNT3dzZHRlaml2UG55ZHZzIiwiYWxnIjoiRVMyNTYifQ.eyJncm91cHMiOlt7Imdyb3VwSWQiOiIqIiwibmV0Um9sZSI6ImFwIn1dLCJuZXRBY2Nlc3NLZXkiOnsia3R5IjoiRUMiLCJjcnYiOiJQLTI1NiIsIngiOiIybU5vNXZuRkI5bEw3d1VWb1hJbGVPYzBNSEE1QXZKbnpwZXZULVVTYzVNIiwieSI6IlhzS3dqVHJlLTg5WWdpU3pKaG9CN1haeUttTU05OTl3V2ZaSVl0bi01Q3MifX0.XhjFpZgcSa7G2lHy0OCYTvaZFRo5Hyx6b7g7oYyusLC7C_73AJ4_BxEZQVYJXAtDuGvb3dXSkHEKxREP9Q6Qeg"
2248    ap_netaccesskey = "30770201010420ceba752db2ad5200fa7bc565b9c05c69b7eb006751b0b329b0279de1c19ca67ca00a06082a8648ce3d030107a14403420004da6368e6f9c507d94bef0515a1722578e73430703902f267ce97af4fe51273935ec2b08d3adefbcf588224b3261a01ed76722a630cf7df7059f64862d9fee42b"
2249
2250    params = {"ssid": "test",
2251              "wpa": "2",
2252              "wpa_key_mgmt": "DPP",
2253              "ieee80211w": "2",
2254              "rsn_pairwise": "CCMP",
2255              "dpp_connector": ap_connector,
2256              "dpp_csign": csign_pub,
2257              "dpp_netaccesskey": ap_netaccesskey}
2258    try:
2259        hapd = hostapd.add_ap(apdev[0], params)
2260        if ap_version:
2261            hapd.set("dpp_version_override", str(ap_version))
2262    except:
2263        raise HwsimSkip("DPP not supported")
2264
2265    if sta_version:
2266        dev[0].set("dpp_version_override", str(sta_version))
2267    if sta1_version:
2268        dev[1].set("dpp_version_override", str(sta1_version))
2269    conf_id = dev[1].dpp_configurator_add(key=csign)
2270    dev[0].set("dpp_config_processing", str(processing))
2271    id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
2272    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
2273    dev[0].dpp_listen(2412)
2274    dev[1].dpp_auth_init(uri=uri0, conf="sta-dpp", configurator=conf_id)
2275    wait_auth_success(dev[0], dev[1], configurator=dev[1], enrollee=dev[0])
2276    ev = dev[0].wait_event(["DPP-NETWORK-ID"], timeout=1)
2277    if ev is None:
2278        raise Exception("DPP network profile not generated")
2279    id = ev.split(' ')[1]
2280    if stop_after_prov:
2281        return id, hapd
2282
2283    if processing == 1:
2284        dev[0].select_network(id, freq=2412)
2285
2286    dev[0].wait_connected()
2287    hwsim_utils.test_connectivity(dev[0], hapd)
2288
2289def test_dpp_auto_connect_legacy(dev, apdev):
2290    """DPP and auto connect (legacy)"""
2291    try:
2292        run_dpp_auto_connect_legacy(dev, apdev)
2293    finally:
2294        dev[0].set("dpp_config_processing", "0", allow_fail=True)
2295
2296def test_dpp_auto_connect_legacy_ssid_charset(dev, apdev):
2297    """DPP and auto connect (legacy, ssid_charset)"""
2298    try:
2299        run_dpp_auto_connect_legacy(dev, apdev, ssid_charset=12345)
2300    finally:
2301        dev[0].set("dpp_config_processing", "0", allow_fail=True)
2302
2303def test_dpp_auto_connect_legacy_sae_1(dev, apdev):
2304    """DPP and auto connect (legacy SAE)"""
2305    try:
2306        run_dpp_auto_connect_legacy(dev, apdev, conf='sta-sae', psk_sae=True)
2307    finally:
2308        dev[0].set("dpp_config_processing", "0", allow_fail=True)
2309
2310def test_dpp_auto_connect_legacy_sae_2(dev, apdev):
2311    """DPP and auto connect (legacy SAE)"""
2312    try:
2313        run_dpp_auto_connect_legacy(dev, apdev, conf='sta-sae', sae_only=True)
2314    finally:
2315        dev[0].set("dpp_config_processing", "0", allow_fail=True)
2316
2317def test_dpp_auto_connect_legacy_psk_sae_1(dev, apdev):
2318    """DPP and auto connect (legacy PSK+SAE)"""
2319    try:
2320        run_dpp_auto_connect_legacy(dev, apdev, conf='sta-psk-sae',
2321                                    psk_sae=True)
2322    finally:
2323        dev[0].set("dpp_config_processing", "0", allow_fail=True)
2324
2325def test_dpp_auto_connect_legacy_psk_sae_2(dev, apdev):
2326    """DPP and auto connect (legacy PSK+SAE)"""
2327    try:
2328        run_dpp_auto_connect_legacy(dev, apdev, conf='sta-psk-sae',
2329                                    sae_only=True)
2330    finally:
2331        dev[0].set("dpp_config_processing", "0", allow_fail=True)
2332
2333def test_dpp_auto_connect_legacy_psk_sae_3(dev, apdev):
2334    """DPP and auto connect (legacy PSK+SAE)"""
2335    try:
2336        run_dpp_auto_connect_legacy(dev, apdev, conf='sta-psk-sae')
2337    finally:
2338        dev[0].set("dpp_config_processing", "0", allow_fail=True)
2339
2340def run_dpp_auto_connect_legacy(dev, apdev, conf='sta-psk',
2341                                ssid_charset=None,
2342                                psk_sae=False, sae_only=False):
2343    check_dpp_capab(dev[0])
2344    check_dpp_capab(dev[1])
2345
2346    params = hostapd.wpa2_params(ssid="dpp-legacy",
2347                                 passphrase="secret passphrase")
2348    if sae_only:
2349            params['wpa_key_mgmt'] = 'SAE'
2350            params['ieee80211w'] = '2'
2351    elif psk_sae:
2352            params['wpa_key_mgmt'] = 'WPA-PSK SAE'
2353            params['ieee80211w'] = '1'
2354            params['sae_require_mfp'] = '1'
2355
2356    hapd = hostapd.add_ap(apdev[0], params)
2357
2358    dev[0].request("SET sae_groups ")
2359    dev[0].set("dpp_config_processing", "2")
2360    id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
2361    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
2362
2363    dev[0].dpp_listen(2412)
2364    dev[1].dpp_auth_init(uri=uri0, conf=conf, ssid="dpp-legacy",
2365                         ssid_charset=ssid_charset,
2366                         passphrase="secret passphrase")
2367    wait_auth_success(dev[0], dev[1], configurator=dev[1], enrollee=dev[0])
2368    if ssid_charset:
2369        ev = dev[0].wait_event(["DPP-CONFOBJ-SSID-CHARSET"], timeout=1)
2370        if ev is None:
2371            raise Exception("ssid_charset not reported")
2372        charset = ev.split(' ')[1]
2373        if charset != str(ssid_charset):
2374            raise Exception("Incorrect ssid_charset reported: " + ev)
2375    ev = dev[0].wait_event(["DPP-NETWORK-ID"], timeout=1)
2376    if ev is None:
2377        raise Exception("DPP network profile not generated")
2378    id = ev.split(' ')[1]
2379
2380    dev[0].wait_connected()
2381
2382def test_dpp_auto_connect_legacy_pmf_required(dev, apdev):
2383    """DPP and auto connect (legacy, PMF required)"""
2384    try:
2385        run_dpp_auto_connect_legacy_pmf_required(dev, apdev)
2386    finally:
2387        dev[0].set("dpp_config_processing", "0", allow_fail=True)
2388
2389def run_dpp_auto_connect_legacy_pmf_required(dev, apdev):
2390    check_dpp_capab(dev[0])
2391    check_dpp_capab(dev[1])
2392
2393    params = hostapd.wpa2_params(ssid="dpp-legacy",
2394                                 passphrase="secret passphrase")
2395    params['wpa_key_mgmt'] = "WPA-PSK-SHA256"
2396    params['ieee80211w'] = "2"
2397    hapd = hostapd.add_ap(apdev[0], params)
2398
2399    dev[0].set("dpp_config_processing", "2")
2400    id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
2401    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
2402    dev[0].dpp_listen(2412)
2403    dev[1].dpp_auth_init(uri=uri0, conf="sta-psk", ssid="dpp-legacy",
2404                         passphrase="secret passphrase")
2405    wait_auth_success(dev[0], dev[1], configurator=dev[1], enrollee=dev[0])
2406    ev = dev[0].wait_event(["DPP-NETWORK-ID"], timeout=1)
2407    if ev is None:
2408        raise Exception("DPP network profile not generated")
2409    dev[0].wait_connected()
2410
2411def test_dpp_qr_code_auth_responder_configurator(dev, apdev):
2412    """DPP QR Code and responder as the configurator"""
2413    run_dpp_qr_code_auth_responder_configurator(dev, apdev, "")
2414
2415def test_dpp_qr_code_auth_responder_configurator_group_id(dev, apdev):
2416    """DPP QR Code and responder as the configurator with group_id)"""
2417    run_dpp_qr_code_auth_responder_configurator(dev, apdev,
2418                                                " group_id=test-group")
2419
2420def run_dpp_qr_code_auth_responder_configurator(dev, apdev, extra):
2421    check_dpp_capab(dev[0])
2422    check_dpp_capab(dev[1])
2423    conf_id = dev[0].dpp_configurator_add()
2424    id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
2425    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
2426    dev[0].set("dpp_configurator_params",
2427               " conf=sta-dpp configurator=%d%s" % (conf_id, extra))
2428    dev[0].dpp_listen(2412, role="configurator")
2429    dev[1].dpp_auth_init(uri=uri0, role="enrollee")
2430    wait_auth_success(dev[0], dev[1], configurator=dev[0], enrollee=dev[1],
2431                      stop_responder=True)
2432
2433def test_dpp_qr_code_auth_enrollee_init_netrole(dev, apdev):
2434    """DPP QR Code and enrollee initiating with netrole specified"""
2435    check_dpp_capab(dev[0])
2436    check_dpp_capab(dev[1])
2437    conf_id = dev[0].dpp_configurator_add()
2438    id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
2439    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
2440    dev[0].set("dpp_configurator_params",
2441               " conf=configurator configurator=%d" % conf_id)
2442    dev[0].dpp_listen(2412, role="configurator")
2443    dev[1].dpp_auth_init(uri=uri0, role="enrollee", netrole="configurator")
2444    wait_auth_success(dev[0], dev[1], configurator=dev[0], enrollee=dev[1],
2445                      stop_responder=True)
2446    dev[0].dump_monitor()
2447    dev[1].dump_monitor()
2448
2449    # verify that netrole resets back to sta, if not explicitly stated
2450    dev[0].set("dpp_configurator_params",
2451               "conf=sta-dpp configurator=%d" % conf_id)
2452    dev[0].dpp_listen(2412, role="configurator")
2453    dev[1].dpp_auth_init(uri=uri0, role="enrollee")
2454    wait_auth_success(dev[0], dev[1], configurator=dev[0], enrollee=dev[1],
2455                      stop_responder=True)
2456
2457def test_dpp_qr_code_hostapd_init(dev, apdev):
2458    """DPP QR Code and hostapd as initiator"""
2459    check_dpp_capab(dev[0])
2460    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
2461                                     "channel": "6"})
2462    check_dpp_capab(hapd)
2463    conf_id = dev[0].dpp_configurator_add()
2464    id0 = dev[0].dpp_bootstrap_gen(chan="81/6", mac=True)
2465    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
2466    dev[0].set("dpp_configurator_params",
2467               " conf=ap-dpp configurator=%d" % conf_id)
2468    dev[0].dpp_listen(2437, role="configurator")
2469    hapd.dpp_auth_init(uri=uri0, role="enrollee")
2470    wait_auth_success(dev[0], hapd, configurator=dev[0], enrollee=hapd,
2471                      stop_responder=True)
2472
2473def test_dpp_qr_code_hostapd_init_offchannel(dev, apdev):
2474    """DPP QR Code and hostapd as initiator (offchannel)"""
2475    run_dpp_qr_code_hostapd_init_offchannel(dev, apdev, None)
2476
2477def test_dpp_qr_code_hostapd_init_offchannel_neg_freq(dev, apdev):
2478    """DPP QR Code and hostapd as initiator (offchannel, neg_freq)"""
2479    run_dpp_qr_code_hostapd_init_offchannel(dev, apdev, "neg_freq=2437")
2480
2481def run_dpp_qr_code_hostapd_init_offchannel(dev, apdev, extra):
2482    check_dpp_capab(dev[0])
2483    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
2484                                     "channel": "6"})
2485    check_dpp_capab(hapd)
2486    conf_id = dev[0].dpp_configurator_add()
2487    id0 = dev[0].dpp_bootstrap_gen(chan="81/1,81/11", mac=True)
2488    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
2489    dev[0].set("dpp_configurator_params",
2490               " conf=ap-dpp configurator=%d" % conf_id)
2491    dev[0].dpp_listen(2462, role="configurator")
2492    hapd.dpp_auth_init(uri=uri0, role="enrollee", extra=extra)
2493    wait_auth_success(dev[0], hapd, configurator=dev[0], enrollee=hapd,
2494                      stop_responder=True)
2495
2496def test_dpp_qr_code_hostapd_init_offchannel_configurator(dev, apdev):
2497    """DPP QR Code and hostapd as initiator/Configurator (offchannel)"""
2498    check_dpp_capab(dev[0])
2499    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
2500                                     "channel": "11"})
2501    check_dpp_capab(hapd)
2502    id0 = dev[0].dpp_bootstrap_gen(chan="81/1")
2503    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
2504    dev[0].dpp_listen(2412)
2505    conf_id = hapd.dpp_configurator_add()
2506    hapd.dpp_auth_init(uri=uri0, configurator=conf_id, conf="sta-dpp")
2507    wait_auth_success(dev[0], hapd, configurator=hapd, enrollee=dev[0])
2508
2509def test_dpp_qr_code_hostapd_ignore_mismatch(dev, apdev):
2510    """DPP QR Code and hostapd ignoring netaccessKey mismatch"""
2511    check_dpp_capab(dev[0])
2512    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
2513                                     "channel": "6"})
2514    check_dpp_capab(hapd)
2515    conf_id = dev[0].dpp_configurator_add()
2516    id0 = dev[0].dpp_bootstrap_gen(chan="81/6", mac=True)
2517    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
2518    dev[0].set("dpp_configurator_params",
2519               "conf=ap-dpp configurator=%d" % conf_id)
2520    conf = '{"wi-fi_tech":"infra","discovery":{"ssid":"test"},"cred":{"akm":"dpp","signedConnector":"eyJ0eXAiOiJkcHBDb24iLCJraWQiOiJUbkdLaklsTlphYXRyRUFZcmJiamlCNjdyamtMX0FHVldYTzZxOWhESktVIiwiYWxnIjoiRVMyNTYifQ.eyJncm91cHMiOlt7Imdyb3VwSWQiOiIqIiwibmV0Um9sZSI6InN0YSJ9XSwibmV0QWNjZXNzS2V5Ijp7Imt0eSI6IkVDIiwiY3J2IjoiUC0yNTYiLCJ4IjoiYVRGNEpFR0lQS1NaMFh2OXpkQ01qbS10bjVYcE1zWUlWWjl3eVNBejFnSSIsInkiOiJRR2NIV0FfNnJiVTlYRFhBenRvWC1NNVEzc3VUbk1hcUVoVUx0bjdTU1h3In19._sm6YswxMf6hJLVTyYoU1uYUeY2VVkUNjrzjSiEhY42StD_RWowStEE-9CRsdCvLmsTptZ72_g40vTFwdId20A","csign":{"kty":"EC","crv":"P-256","x":"W4-Y5N1Pkos3UWb9A5qme0KUYRtY3CVUpekx_MapZ9s","y":"Et-M4NSF4NGjvh2VCh4B1sJ9eSCZ4RNzP2DBdP137VE","kid":"TnGKjIlNZaatrEAYrbbjiB67rjkL_AGVWXO6q9hDJKU"}}}'
2521    dev[0].set("dpp_config_obj_override", conf)
2522    dev[0].dpp_listen(2437, role="configurator")
2523    hapd.set("dpp_ignore_netaccesskey_mismatch", "1")
2524    hapd.dpp_auth_init(uri=uri0, role="enrollee")
2525    wait_auth_success(dev[0], hapd, configurator=dev[0], enrollee=hapd,
2526                      stop_responder=True)
2527
2528def test_dpp_test_vector_p_256(dev, apdev):
2529    """DPP P-256 test vector (mutual auth)"""
2530    check_dpp_capab(dev[0])
2531    check_dpp_capab(dev[1])
2532
2533    # Responder bootstrapping key
2534    priv = "54ce181a98525f217216f59b245f60e9df30ac7f6b26c939418cfc3c42d1afa0"
2535    id0 = dev[0].dpp_bootstrap_gen(chan="81/11", mac=True, key="30310201010420" + priv + "a00a06082a8648ce3d030107")
2536    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
2537
2538    # Responder protocol keypair override
2539    priv = "f798ed2e19286f6a6efe210b1863badb99af2a14b497634dbfd2a97394fb5aa5"
2540    dev[0].set("dpp_protocol_key_override",
2541               "30310201010420" + priv + "a00a06082a8648ce3d030107")
2542
2543    dev[0].set("dpp_nonce_override", "3d0cfb011ca916d796f7029ff0b43393")
2544
2545    # Initiator bootstrapping key
2546    priv = "15b2a83c5a0a38b61f2aa8200ee4994b8afdc01c58507d10d0a38f7eedf051bb"
2547    id1 = dev[1].dpp_bootstrap_gen(key="30310201010420" + priv + "a00a06082a8648ce3d030107")
2548    uri1 = dev[1].request("DPP_BOOTSTRAP_GET_URI %d" % id1)
2549
2550    # Initiator protocol keypair override
2551    priv = "a87de9afbb406c96e5f79a3df895ecac3ad406f95da66314c8cb3165e0c61783"
2552    dev[1].set("dpp_protocol_key_override",
2553               "30310201010420" + priv + "a00a06082a8648ce3d030107")
2554
2555    dev[1].set("dpp_nonce_override", "13f4602a16daeb69712263b9c46cba31")
2556
2557    dev[0].dpp_qr_code(uri1)
2558    dev[0].dpp_listen(2462, qr="mutual")
2559    dev[1].dpp_auth_init(uri=uri0, own=id1, neg_freq=2412)
2560    wait_auth_success(dev[0], dev[1])
2561
2562def test_dpp_test_vector_p_256_b(dev, apdev):
2563    """DPP P-256 test vector (Responder-only auth)"""
2564    check_dpp_capab(dev[0])
2565    check_dpp_capab(dev[1])
2566
2567    # Responder bootstrapping key
2568    priv = "54ce181a98525f217216f59b245f60e9df30ac7f6b26c939418cfc3c42d1afa0"
2569    id0 = dev[0].dpp_bootstrap_gen(chan="81/11", mac=True, key="30310201010420" + priv + "a00a06082a8648ce3d030107")
2570    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
2571
2572    # Responder protocol keypair override
2573    priv = "f798ed2e19286f6a6efe210b1863badb99af2a14b497634dbfd2a97394fb5aa5"
2574    dev[0].set("dpp_protocol_key_override",
2575               "30310201010420" + priv + "a00a06082a8648ce3d030107")
2576
2577    dev[0].set("dpp_nonce_override", "3d0cfb011ca916d796f7029ff0b43393")
2578
2579    # Initiator bootstrapping key
2580    priv = "15b2a83c5a0a38b61f2aa8200ee4994b8afdc01c58507d10d0a38f7eedf051bb"
2581    id1 = dev[1].dpp_bootstrap_gen(key="30310201010420" + priv + "a00a06082a8648ce3d030107")
2582    uri1 = dev[1].request("DPP_BOOTSTRAP_GET_URI %d" % id1)
2583
2584    # Initiator protocol keypair override
2585    priv = "a87de9afbb406c96e5f79a3df895ecac3ad406f95da66314c8cb3165e0c61783"
2586    dev[1].set("dpp_protocol_key_override",
2587               "30310201010420" + priv + "a00a06082a8648ce3d030107")
2588
2589    dev[1].set("dpp_nonce_override", "13f4602a16daeb69712263b9c46cba31")
2590
2591    dev[0].dpp_listen(2462)
2592    dev[1].dpp_auth_init(uri=uri0, own=id1, neg_freq=2412)
2593    wait_auth_success(dev[0], dev[1])
2594
2595def der_priv_key_p_521(priv):
2596    if len(priv) != 2 * 66:
2597        raise Exception("Unexpected der_priv_key_p_521 parameter: " + priv)
2598    der_prefix = "30500201010442"
2599    der_postfix = "a00706052b81040023"
2600    return der_prefix + priv + der_postfix
2601
2602def test_dpp_test_vector_p_521(dev, apdev):
2603    """DPP P-521 test vector (mutual auth)"""
2604    check_dpp_capab(dev[0])
2605    check_dpp_capab(dev[1])
2606
2607    # Responder bootstrapping key
2608    priv = "0061e54f518cdf859735da3dd64c6f72c2f086f41a6fd52915152ea2fe0f24ddaecd8883730c9c9fd82cf7c043a41021696388cf5190b731dd83638bcd56d8b6c743"
2609    id0 = dev[0].dpp_bootstrap_gen(chan="81/11", mac=True,
2610                                   key=der_priv_key_p_521(priv))
2611    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
2612
2613    # Responder protocol keypair override
2614    priv = "01d8b7b17cd1b0a33f7c66fb4220999329cdaf4f8b44b2ffadde8ab8ed8abffa9f5358c5b1caae26709ca4fb78e52a4d08f2e4f24111a36a6f440d20a0000ff51597"
2615    dev[0].set("dpp_protocol_key_override", der_priv_key_p_521(priv))
2616
2617    dev[0].set("dpp_nonce_override",
2618               "d749a782012eb0a8595af30b2dfc8d0880d004ebddb55ecc5afbdef18c400e01")
2619
2620    # Initiator bootstrapping key
2621    priv = "0060c10df14af5ef27f6e362d31bdd9eeb44be77a323ba64b08f3f03d58b92cbfe05c182a91660caa081ca344243c47b5aa088bcdf738840eb35f0218b9f26881e02"
2622    id1 = dev[1].dpp_bootstrap_gen(key=der_priv_key_p_521(priv))
2623    uri1 = dev[1].request("DPP_BOOTSTRAP_GET_URI %d" % id1)
2624
2625    # Initiator protocol keypair override
2626    priv = "019c1c08caaeec38fb931894699b095bc3ab8c1ec7ef0622d2e3eba821477c8c6fca41774f21166ad98aebda37c067d9aa08a8a2e1b5c44c61f2bae02a61f85d9661"
2627    dev[1].set("dpp_protocol_key_override", der_priv_key_p_521(priv))
2628
2629    dev[1].set("dpp_nonce_override",
2630               "de972af3847bec3ba2aedd9f5c21cfdec7bf0bc5fe8b276cbcd0267807fb15b0")
2631
2632    dev[0].dpp_qr_code(uri1)
2633    dev[0].dpp_listen(2462, qr="mutual")
2634    dev[1].dpp_auth_init(uri=uri0, own=id1, neg_freq=2412)
2635    wait_auth_success(dev[0], dev[1])
2636
2637def test_dpp_pkex(dev, apdev):
2638    """DPP and PKEX"""
2639    run_dpp_pkex(dev, apdev)
2640
2641def test_dpp_pkex_v2(dev, apdev):
2642    """DPP and PKEXv2"""
2643    run_dpp_pkex(dev, apdev, ver=2)
2644
2645def test_dpp_pkex_p256(dev, apdev):
2646    """DPP and PKEX (P-256)"""
2647    run_dpp_pkex(dev, apdev, "P-256")
2648
2649def test_dpp_pkex_p384(dev, apdev):
2650    """DPP and PKEX (P-384)"""
2651    run_dpp_pkex(dev, apdev, "P-384")
2652
2653def test_dpp_pkex_p521(dev, apdev):
2654    """DPP and PKEX (P-521)"""
2655    run_dpp_pkex(dev, apdev, "P-521")
2656
2657def test_dpp_pkex_bp256(dev, apdev):
2658    """DPP and PKEX (BP-256)"""
2659    run_dpp_pkex(dev, apdev, "brainpoolP256r1")
2660
2661def test_dpp_pkex_bp384(dev, apdev):
2662    """DPP and PKEX (BP-384)"""
2663    run_dpp_pkex(dev, apdev, "brainpoolP384r1")
2664
2665def test_dpp_pkex_bp512(dev, apdev):
2666    """DPP and PKEX (BP-512)"""
2667    run_dpp_pkex(dev, apdev, "brainpoolP512r1")
2668
2669def test_dpp_pkex_config(dev, apdev):
2670    """DPP and PKEX with initiator as the configurator"""
2671    check_dpp_capab(dev[1])
2672    conf_id = dev[1].dpp_configurator_add()
2673    run_dpp_pkex(dev, apdev,
2674                 init_extra="conf=sta-dpp configurator=%d" % (conf_id),
2675                 check_config=True)
2676
2677def test_dpp_pkex_no_identifier(dev, apdev):
2678    """DPP and PKEX without identifier"""
2679    run_dpp_pkex(dev, apdev, identifier_i=None, identifier_r=None)
2680
2681def test_dpp_pkex_identifier_mismatch(dev, apdev):
2682    """DPP and PKEX with different identifiers"""
2683    run_dpp_pkex(dev, apdev, identifier_i="foo", identifier_r="bar",
2684                 expect_no_resp=True)
2685
2686def test_dpp_pkex_identifier_mismatch2(dev, apdev):
2687    """DPP and PKEX with initiator using identifier and the responder not"""
2688    run_dpp_pkex(dev, apdev, identifier_i="foo", identifier_r=None,
2689                 expect_no_resp=True)
2690
2691def test_dpp_pkex_identifier_mismatch3(dev, apdev):
2692    """DPP and PKEX with responder using identifier and the initiator not"""
2693    run_dpp_pkex(dev, apdev, identifier_i=None, identifier_r="bar",
2694                 expect_no_resp=True)
2695
2696def run_dpp_pkex(dev, apdev, curve=None, init_extra=None, check_config=False,
2697                 identifier_i="test", identifier_r="test",
2698                 expect_no_resp=False, ver=None):
2699    min_ver = 3 if ver else 1
2700    check_dpp_capab(dev[0], curve and "brainpool" in curve, min_ver=min_ver)
2701    check_dpp_capab(dev[1], curve and "brainpool" in curve, min_ver=min_ver)
2702    dev[0].dpp_pkex_resp(2437, identifier=identifier_r, code="secret",
2703                         curve=curve)
2704    dev[1].dpp_pkex_init(identifier=identifier_i, code="secret", curve=curve,
2705                         extra=init_extra, ver=ver)
2706
2707    if expect_no_resp:
2708        ev = dev[0].wait_event(["DPP-RX"], timeout=10)
2709        if ev is None:
2710            raise Exception("DPP PKEX frame not received")
2711        ev = dev[1].wait_event(["DPP-AUTH-SUCCESS"], timeout=1)
2712        if ev is not None:
2713            raise Exception("DPP authentication succeeded")
2714        ev = dev[0].wait_event(["DPP-AUTH-SUCCESS"], timeout=0.1)
2715        if ev is not None:
2716            raise Exception("DPP authentication succeeded")
2717        return
2718
2719    wait_auth_success(dev[0], dev[1],
2720                      configurator=dev[1] if check_config else None,
2721                      enrollee=dev[0] if check_config else None)
2722
2723def test_dpp_pkex_5ghz(dev, apdev):
2724    """DPP and PKEX on 5 GHz"""
2725    try:
2726        dev[0].request("SET country US")
2727        dev[1].request("SET country US")
2728        ev = dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=1)
2729        if ev is None:
2730            ev = dev[0].wait_global_event(["CTRL-EVENT-REGDOM-CHANGE"],
2731                                          timeout=1)
2732        run_dpp_pkex_5ghz(dev, apdev)
2733    finally:
2734        dev[0].request("SET country 00")
2735        dev[1].request("SET country 00")
2736        subprocess.call(['iw', 'reg', 'set', '00'])
2737        time.sleep(0.1)
2738
2739def run_dpp_pkex_5ghz(dev, apdev):
2740    check_dpp_capab(dev[0])
2741    check_dpp_capab(dev[1])
2742    dev[0].dpp_pkex_resp(5745, identifier="test", code="secret")
2743    dev[1].dpp_pkex_init(identifier="test", code="secret")
2744    wait_auth_success(dev[0], dev[1], timeout=20)
2745
2746def test_dpp_pkex_test_vector(dev, apdev):
2747    """DPP and PKEX (P-256) test vector"""
2748    check_dpp_capab(dev[0])
2749    check_dpp_capab(dev[1])
2750
2751    init_addr = "ac:64:91:f4:52:07"
2752    resp_addr = "6e:5e:ce:6e:f3:dd"
2753
2754    identifier = "joes_key"
2755    code = "thisisreallysecret"
2756
2757    # Initiator bootstrapping private key
2758    init_priv = "5941b51acfc702cdc1c347264beb2920db88eb1a0bf03a211868b1632233c269"
2759
2760    # Responder bootstrapping private key
2761    resp_priv = "2ae8956293f49986b6d0b8169a86805d9232babb5f6813fdfe96f19d59536c60"
2762
2763    # Initiator x/X keypair override
2764    init_x_priv = "8365c5ed93d751bef2d92b410dc6adfd95670889183fac1bd66759ad85c3187a"
2765
2766    # Responder y/Y keypair override
2767    resp_y_priv = "d98faa24d7dd3f592665d71a95c862bfd02c4c48acb0c515a41cbc6e929675ea"
2768
2769    p256_prefix = "30310201010420"
2770    p256_postfix = "a00a06082a8648ce3d030107"
2771
2772    dev[0].set("dpp_pkex_own_mac_override", resp_addr)
2773    dev[0].set("dpp_pkex_peer_mac_override", init_addr)
2774    dev[1].set("dpp_pkex_own_mac_override", init_addr)
2775    dev[1].set("dpp_pkex_peer_mac_override", resp_addr)
2776
2777    # Responder y/Y keypair override
2778    dev[0].set("dpp_pkex_ephemeral_key_override",
2779               p256_prefix + resp_y_priv + p256_postfix)
2780
2781    # Initiator x/X keypair override
2782    dev[1].set("dpp_pkex_ephemeral_key_override",
2783               p256_prefix + init_x_priv + p256_postfix)
2784
2785    dev[0].dpp_pkex_resp(2437, identifier=identifier, code=code,
2786                         key=p256_prefix + resp_priv + p256_postfix)
2787    dev[1].dpp_pkex_init(identifier=identifier, code=code,
2788                         key=p256_prefix + init_priv + p256_postfix)
2789    wait_auth_success(dev[0], dev[1])
2790
2791def test_dpp_pkex_code_mismatch(dev, apdev):
2792    """DPP and PKEX with mismatching code"""
2793    check_dpp_capab(dev[0])
2794    check_dpp_capab(dev[1])
2795    dev[0].dpp_pkex_resp(2437, identifier="test", code="secret")
2796    id1 = dev[1].dpp_pkex_init(identifier="test", code="unknown")
2797    wait_dpp_fail(dev[0], "possible PKEX code mismatch")
2798    dev[0].dump_monitor()
2799    dev[1].dump_monitor()
2800    dev[1].dpp_pkex_init(identifier="test", code="secret", use_id=id1)
2801    wait_auth_success(dev[0], dev[1])
2802
2803def test_dpp_pkex_code_mismatch_limit(dev, apdev):
2804    """DPP and PKEX with mismatching code limit"""
2805    check_dpp_capab(dev[0])
2806    check_dpp_capab(dev[1])
2807    dev[0].dpp_pkex_resp(2437, identifier="test", code="secret")
2808
2809    id1 = None
2810    for i in range(5):
2811        dev[0].dump_monitor()
2812        dev[1].dump_monitor()
2813        id1 = dev[1].dpp_pkex_init(identifier="test", code="unknown",
2814                                   use_id=id1)
2815        wait_dpp_fail(dev[0], "possible PKEX code mismatch")
2816
2817    ev = dev[0].wait_event(["DPP-PKEX-T-LIMIT"], timeout=1)
2818    if ev is None:
2819        raise Exception("PKEX t limit not reported")
2820
2821def test_dpp_pkex_curve_mismatch(dev, apdev):
2822    """DPP and PKEX with mismatching curve"""
2823    check_dpp_capab(dev[0])
2824    check_dpp_capab(dev[1])
2825    dev[0].dpp_pkex_resp(2437, identifier="test", code="secret", curve="P-256")
2826    dev[1].dpp_pkex_init(identifier="test", code="secret", curve="P-384")
2827    wait_dpp_fail(dev[0], "Mismatching PKEX curve: peer=20 own=19")
2828    wait_dpp_fail(dev[1], "Peer indicated mismatching PKEX group - proposed 19")
2829
2830def test_dpp_pkex_curve_mismatch_failure(dev, apdev):
2831    """DPP and PKEX with mismatching curve (local failure)"""
2832    run_dpp_pkex_curve_mismatch_failure(dev, apdev, "=dpp_pkex_rx_exchange_req")
2833
2834def test_dpp_pkex_curve_mismatch_failure2(dev, apdev):
2835    """DPP and PKEX with mismatching curve (local failure 2)"""
2836    run_dpp_pkex_curve_mismatch_failure(dev, apdev,
2837                                        "dpp_pkex_build_exchange_resp")
2838
2839def run_dpp_pkex_curve_mismatch_failure(dev, apdev, func):
2840    check_dpp_capab(dev[0])
2841    check_dpp_capab(dev[1])
2842    dev[0].dpp_pkex_resp(2437, identifier="test", code="secret", curve="P-256")
2843
2844    with alloc_fail(dev[0], 1, func):
2845        dev[1].dpp_pkex_init(identifier="test", code="secret", curve="P-384")
2846
2847        ev = dev[0].wait_event(["DPP-FAIL"], timeout=5)
2848        if ev is None:
2849            raise Exception("Failure not reported (dev 0)")
2850        if "Mismatching PKEX curve: peer=20 own=19" not in ev:
2851            raise Exception("Unexpected result: " + ev)
2852        wait_dpp_fail(dev[0], "Mismatching PKEX curve: peer=20 own=19")
2853
2854def test_dpp_pkex_exchange_resp_processing_failure(dev, apdev):
2855    """DPP and PKEX with local failure in processing Exchange Resp"""
2856    check_dpp_capab(dev[0])
2857    check_dpp_capab(dev[1])
2858    dev[0].dpp_pkex_resp(2437, identifier="test", code="secret")
2859
2860    with fail_test(dev[1], 1, "dpp_pkex_derive_Qr;dpp_pkex_rx_exchange_resp"):
2861        dev[1].dpp_pkex_init(identifier="test", code="secret")
2862        wait_fail_trigger(dev[1], "GET_FAIL")
2863
2864def test_dpp_pkex_commit_reveal_req_processing_failure(dev, apdev):
2865    """DPP and PKEX with local failure in processing Commit Reveal Req"""
2866    check_dpp_capab(dev[0])
2867    check_dpp_capab(dev[1])
2868    dev[0].dpp_pkex_resp(2437, identifier="test", code="secret")
2869
2870    with alloc_fail(dev[0], 1,
2871                    "crypto_ec_key_get_pubkey_point;dpp_pkex_rx_commit_reveal_req"):
2872        dev[1].dpp_pkex_init(identifier="test", code="secret")
2873        wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
2874
2875def test_dpp_pkex_config2(dev, apdev):
2876    """DPP and PKEX with responder as the configurator"""
2877    check_dpp_capab(dev[0])
2878    conf_id = dev[0].dpp_configurator_add()
2879    dev[0].set("dpp_configurator_params",
2880               " conf=sta-dpp configurator=%d" % conf_id)
2881    run_dpp_pkex2(dev, apdev)
2882
2883def run_dpp_pkex2(dev, apdev, curve=None, init_extra=""):
2884    check_dpp_capab(dev[0])
2885    check_dpp_capab(dev[1])
2886    dev[0].dpp_pkex_resp(2437, identifier="test", code="secret", curve=curve,
2887                         listen_role="configurator")
2888    dev[1].dpp_pkex_init(identifier="test", code="secret", role="enrollee",
2889                         curve=curve, extra=init_extra)
2890    wait_auth_success(dev[0], dev[1], configurator=dev[0], enrollee=dev[1])
2891
2892def test_dpp_pkex_no_responder(dev, apdev):
2893    """DPP and PKEX with no responder (retry behavior)"""
2894    check_dpp_capab(dev[0])
2895    dev[0].dpp_pkex_init(identifier="test", code="secret")
2896
2897    for i in range(15):
2898        ev = dev[0].wait_event(["DPP-TX ", "DPP-FAIL"], timeout=5)
2899        if ev is None:
2900            raise Exception("DPP PKEX failure not reported")
2901        if "DPP-FAIL" not in ev:
2902            continue
2903        if "No response from PKEX peer" not in ev:
2904            raise Exception("Unexpected failure reason: " + ev)
2905        break
2906
2907def test_dpp_pkex_after_retry(dev, apdev):
2908    """DPP and PKEX completing after retry"""
2909    check_dpp_capab(dev[0])
2910    dev[0].dpp_pkex_init(identifier="test", code="secret")
2911    time.sleep(0.1)
2912    dev[1].dpp_pkex_resp(2437, identifier="test", code="secret")
2913    wait_auth_success(dev[1], dev[0], configurator=dev[0], enrollee=dev[1],
2914                      allow_enrollee_failure=True)
2915
2916def test_dpp_pkex_hostapd_responder(dev, apdev):
2917    """DPP PKEX with hostapd as responder"""
2918    check_dpp_capab(dev[0])
2919    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
2920                                     "channel": "6"})
2921    check_dpp_capab(hapd)
2922    hapd.dpp_pkex_resp(2437, identifier="test", code="secret")
2923    conf_id = dev[0].dpp_configurator_add()
2924    dev[0].dpp_pkex_init(identifier="test", code="secret",
2925                         extra="conf=ap-dpp configurator=%d" % conf_id)
2926    wait_auth_success(hapd, dev[0], configurator=dev[0], enrollee=hapd,
2927                      stop_initiator=True)
2928
2929def test_dpp_pkex_v2_hostapd_responder(dev, apdev):
2930    """DPP PKEXv2 with hostapd as responder"""
2931    check_dpp_capab(dev[0], min_ver=3)
2932    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
2933                                     "channel": "6"})
2934    check_dpp_capab(hapd, min_ver=3)
2935    hapd.dpp_pkex_resp(2437, identifier="test", code="secret")
2936    conf_id = dev[0].dpp_configurator_add()
2937    dev[0].dpp_pkex_init(identifier="test", code="secret",
2938                         extra="conf=ap-dpp configurator=%d" % conf_id, ver=2)
2939    wait_auth_success(hapd, dev[0], configurator=dev[0], enrollee=hapd,
2940                      stop_initiator=True)
2941
2942def test_dpp_pkex_hostapd_initiator(dev, apdev):
2943    """DPP PKEX with hostapd as initiator"""
2944    check_dpp_capab(dev[0])
2945    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
2946                                     "channel": "6"})
2947    check_dpp_capab(hapd)
2948    conf_id = dev[0].dpp_configurator_add()
2949    dev[0].set("dpp_configurator_params",
2950               " conf=ap-dpp configurator=%d" % conf_id)
2951    dev[0].dpp_pkex_resp(2437, identifier="test", code="secret",
2952                         listen_role="configurator")
2953    hapd.dpp_pkex_init(identifier="test", code="secret", role="enrollee")
2954    wait_auth_success(hapd, dev[0], configurator=dev[0], enrollee=hapd,
2955                      stop_initiator=True)
2956
2957def test_dpp_pkex_v2_hostapd_initiator(dev, apdev):
2958    """DPP PKEXv2 with hostapd as initiator"""
2959    check_dpp_capab(dev[0], min_ver=3)
2960    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
2961                                     "channel": "6"})
2962    check_dpp_capab(hapd, min_ver=3)
2963    conf_id = dev[0].dpp_configurator_add()
2964    dev[0].set("dpp_configurator_params",
2965               " conf=ap-dpp configurator=%d" % conf_id)
2966    dev[0].dpp_pkex_resp(2437, identifier="test", code="secret",
2967                         listen_role="configurator")
2968    hapd.dpp_pkex_init(identifier="test", code="secret", role="enrollee",
2969                       ver=2)
2970    wait_auth_success(hapd, dev[0], configurator=dev[0], enrollee=hapd,
2971                      stop_initiator=True)
2972
2973def test_dpp_pkex_hostapd_initiator_fallback(dev, apdev):
2974    """DPP PKEX with hostapd as initiator and fallback to v1"""
2975    check_dpp_capab(dev[0])
2976    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
2977                                     "channel": "6"})
2978    check_dpp_capab(hapd, min_ver=3)
2979    conf_id = dev[0].dpp_configurator_add()
2980    dev[0].set("dpp_configurator_params",
2981               " conf=ap-dpp configurator=%d" % conf_id)
2982    dev[0].dpp_listen(2437, role="configurator")
2983    hapd.dpp_pkex_init(identifier="test", code="secret", role="enrollee")
2984    while True:
2985        ev = dev[0].wait_event(["DPP-RX"], timeout=5)
2986        if ev is None:
2987            raise Exception("DPP-RX not reported")
2988        if "type=7" in ev:
2989            logger.info("Starting PKEXv1 responder")
2990            conf_id = dev[0].dpp_configurator_add()
2991            dev[0].set("dpp_configurator_params",
2992                       " conf=ap-dpp configurator=%d" % conf_id)
2993            dev[0].dpp_pkex_resp(2437, identifier="test", code="secret",
2994                                 listen_role="configurator")
2995            break
2996    wait_auth_success(hapd, dev[0], configurator=dev[0], enrollee=hapd,
2997                      stop_initiator=True)
2998
2999def test_dpp_pkex_hostapd_initiator_no_response(dev, apdev):
3000    """DPP PKEX with hostapd as initiator and no response"""
3001    check_dpp_capab(dev[0])
3002    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
3003                                     "channel": "6"})
3004    check_dpp_capab(hapd)
3005    conf_id = dev[0].dpp_configurator_add()
3006    hapd.dpp_pkex_init(identifier="test", code="secret", role="enrollee")
3007    ev = hapd.wait_event(["DPP-FAIL"], timeout=30)
3008    if not ev:
3009        raise Exception("Failure not reported")
3010    if "No response from PKEX peer" not in ev:
3011        raise Exception("Unexpected failure reason: " + ev)
3012
3013def test_dpp_pkex_hostapd_errors(dev, apdev):
3014    """DPP PKEX errors with hostapd"""
3015    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
3016                                     "channel": "6"})
3017    check_dpp_capab(hapd)
3018    id0 = hapd.dpp_bootstrap_gen(type="pkex")
3019    tests = ["own=%d" % id0,
3020             "own=%d identifier=foo" % id0,
3021             ""]
3022    for t in tests:
3023        if "FAIL" not in hapd.request("DPP_PKEX_ADD " + t):
3024            raise Exception("Invalid DPP_PKEX_ADD accepted: " + t)
3025
3026    res = hapd.request("DPP_PKEX_ADD own=%d code=foo" % id0)
3027    if "FAIL" in res:
3028        raise Exception("Failed to add PKEX responder")
3029    if "OK" not in hapd.request("DPP_PKEX_REMOVE " + res):
3030        raise Exception("Failed to remove PKEX responder")
3031    hapd.request("DPP_PKEX_REMOVE " + res)
3032
3033    res = hapd.request("DPP_PKEX_ADD own=%d code=foo" % id0)
3034    if "FAIL" in res:
3035        raise Exception("Failed to add PKEX responder")
3036    if "OK" not in hapd.request("DPP_PKEX_REMOVE *"):
3037        raise Exception("Failed to flush PKEX responders")
3038    hapd.request("DPP_PKEX_REMOVE *")
3039
3040def test_dpp_pkex_nak_curve_change(dev, apdev):
3041    """DPP PKEX with netAccessKey curve change"""
3042    try:
3043        run_dpp_pkex_nak_curve_change(dev, apdev)
3044    finally:
3045        dev[1].set("dpp_config_processing", "0", allow_fail=True)
3046
3047def test_dpp_pkex_nak_curve_change2(dev, apdev):
3048    """DPP PKEX with netAccessKey curve change (2)"""
3049    try:
3050        run_dpp_pkex_nak_curve_change(dev, apdev, failure=True)
3051    finally:
3052        dev[1].set("dpp_config_processing", "0", allow_fail=True)
3053
3054def run_dpp_pkex_nak_curve_change(dev, apdev, failure=False):
3055    check_dpp_capab(dev[0], min_ver=3)
3056    check_dpp_capab(dev[1], min_ver=3)
3057    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
3058                                     "channel": "6"})
3059    check_dpp_capab(hapd, min_ver=3)
3060    hapd.dpp_pkex_resp(2437, identifier="test-1", code="secret-1",
3061                       curve="secp384r1")
3062    conf_id = dev[0].dpp_configurator_add()
3063    dev[0].dpp_pkex_init(identifier="test-1", code="secret-1",
3064                         curve="secp384r1",
3065                         extra="conf=ap-dpp configurator=%d" % conf_id)
3066    wait_auth_success(hapd, dev[0], configurator=dev[0], enrollee=hapd,
3067                      stop_initiator=True)
3068    update_hapd_config(hapd)
3069    dev[0].dump_monitor()
3070    hapd.dump_monitor()
3071
3072    dev[1].set("dpp_config_processing", "2")
3073    dev[1].dpp_pkex_resp(2437, identifier="test-2", code="secret-2")
3074    if failure:
3075        dev[0].dpp_configurator_set(conf_id, net_access_key_curve="prime256v1")
3076    dev[0].dpp_pkex_init(identifier="test-2", code="secret-2",
3077                         extra="conf=sta-dpp configurator=%d" % conf_id)
3078    wait_auth_success(dev[1], dev[0], configurator=dev[0], enrollee=dev[1],
3079                      stop_initiator=True)
3080    if failure:
3081        ev = dev[1].wait_event(["DPP-INTRO"], timeout=10)
3082        if ev is None:
3083            raise Exception("No DPP-INTRO message seen")
3084        if "status=7" not in ev:
3085            raise Exception("Unexpected DPP-INTRO contents: " + ev)
3086    else:
3087        dev[1].wait_connected()
3088    dev[0].dump_monitor()
3089    dev[1].dump_monitor()
3090    hapd.dump_monitor()
3091
3092def test_dpp_hostapd_configurator(dev, apdev):
3093    """DPP with hostapd as configurator/initiator"""
3094    run_dpp_hostapd_configurator(dev, apdev)
3095
3096def test_dpp_hostapd_configurator_enrollee_v1(dev, apdev):
3097    """DPP with hostapd as configurator/initiator with v1 enrollee"""
3098    check_dpp_capab(dev[0])
3099    dev[0].set("dpp_version_override", "1")
3100    run_dpp_hostapd_configurator(dev, apdev)
3101
3102def run_dpp_hostapd_configurator(dev, apdev):
3103    check_dpp_capab(dev[0])
3104    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
3105                                     "channel": "1"})
3106    check_dpp_capab(hapd)
3107    conf_id = hapd.dpp_configurator_add()
3108    id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
3109    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
3110    id1 = hapd.dpp_qr_code(uri0)
3111    res = hapd.request("DPP_BOOTSTRAP_INFO %d" % id1)
3112    if "FAIL" in res:
3113        raise Exception("DPP_BOOTSTRAP_INFO failed")
3114    if "type=QRCODE" not in res:
3115        raise Exception("DPP_BOOTSTRAP_INFO did not report correct type")
3116    if "mac_addr=" + dev[0].own_addr() not in res:
3117        raise Exception("DPP_BOOTSTRAP_INFO did not report correct mac_addr")
3118    dev[0].dpp_listen(2412)
3119    hapd.dpp_auth_init(peer=id1, configurator=conf_id, conf="sta-dpp")
3120    wait_auth_success(dev[0], hapd, configurator=hapd, enrollee=dev[0],
3121                      stop_responder=True)
3122
3123def test_dpp_hostapd_configurator_responder(dev, apdev):
3124    """DPP with hostapd as configurator/responder"""
3125    check_dpp_capab(dev[0])
3126    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
3127                                     "channel": "1"})
3128    check_dpp_capab(hapd)
3129    conf_id = hapd.dpp_configurator_add()
3130    hapd.set("dpp_configurator_params",
3131             " conf=sta-dpp configurator=%d" % conf_id)
3132    id0 = hapd.dpp_bootstrap_gen(chan="81/1", mac=True)
3133    uri0 = hapd.request("DPP_BOOTSTRAP_GET_URI %d" % id0)
3134    dev[0].dpp_auth_init(uri=uri0, role="enrollee")
3135    wait_auth_success(hapd, dev[0], configurator=hapd, enrollee=dev[0],
3136                      stop_initiator=True)
3137
3138def test_dpp_hostapd_configurator_fragmentation(dev, apdev):
3139    """DPP with hostapd as configurator/initiator requiring fragmentation"""
3140    check_dpp_capab(dev[0])
3141    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
3142                                     "channel": "1"})
3143    check_dpp_capab(hapd)
3144    conf_id = hapd.dpp_configurator_add()
3145    id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
3146    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
3147    id1 = hapd.dpp_qr_code(uri0)
3148    res = hapd.request("DPP_BOOTSTRAP_INFO %d" % id1)
3149    if "FAIL" in res:
3150        raise Exception("DPP_BOOTSTRAP_INFO failed")
3151    if "type=QRCODE" not in res:
3152        raise Exception("DPP_BOOTSTRAP_INFO did not report correct type")
3153    if "mac_addr=" + dev[0].own_addr() not in res:
3154        raise Exception("DPP_BOOTSTRAP_INFO did not report correct mac_addr")
3155    dev[0].dpp_listen(2412)
3156    conf = '{"wi-fi_tech":"infra", "discovery":{"ssid":"test"},"cred":{"akm":"psk","pass":"secret passphrase"}}' + 3000*' '
3157    hapd.set("dpp_config_obj_override", conf)
3158    hapd.dpp_auth_init(peer=id1, configurator=conf_id, conf="sta-dpp")
3159    wait_auth_success(dev[0], hapd, configurator=hapd, enrollee=dev[0],
3160                      stop_responder=True)
3161
3162def test_dpp_hostapd_enrollee_fragmentation(dev, apdev):
3163    """DPP and hostapd as Enrollee with GAS fragmentation"""
3164    check_dpp_capab(dev[0])
3165    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
3166                                     "channel": "6"})
3167    check_dpp_capab(hapd)
3168    conf_id = dev[0].dpp_configurator_add()
3169    id0 = dev[0].dpp_bootstrap_gen(chan="81/6", mac=True)
3170    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
3171    conf = '{"wi-fi_tech":"infra", "discovery":{"ssid":"test"},"cred":{"akm":"psk","pass":"secret passphrase"}}' + 3000*' '
3172    dev[0].set("dpp_config_obj_override", conf)
3173    dev[0].set("dpp_configurator_params",
3174               " conf=ap-dpp configurator=%d" % conf_id)
3175    dev[0].dpp_listen(2437, role="configurator")
3176    hapd.dpp_auth_init(uri=uri0, role="enrollee")
3177    wait_auth_success(dev[0], hapd, configurator=dev[0], enrollee=hapd,
3178                      stop_responder=True)
3179
3180def test_dpp_hostapd_enrollee_gas_timeout(dev, apdev):
3181    """DPP and hostapd as Enrollee with GAS timeout"""
3182    check_dpp_capab(dev[0])
3183    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
3184                                     "channel": "6"})
3185    check_dpp_capab(hapd)
3186    conf_id = dev[0].dpp_configurator_add()
3187    id0 = dev[0].dpp_bootstrap_gen(chan="81/6", mac=True)
3188    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
3189    conf = '{"wi-fi_tech":"infra", "discovery":{"ssid":"test"},"cred":{"akm":"psk","pass":"secret passphrase"}}' + 3000*' '
3190    dev[0].set("dpp_config_obj_override", conf)
3191    dev[0].set("dpp_configurator_params",
3192               "conf=ap-dpp configurator=%d" % conf_id)
3193    dev[0].set("ext_mgmt_frame_handling", "1")
3194    dev[0].dpp_listen(2437, role="configurator")
3195    hapd.dpp_auth_init(uri=uri0, role="enrollee")
3196    process_dpp_frames(dev[0])
3197    ev = hapd.wait_event(["GAS-QUERY-DONE"], timeout=10)
3198    if "result=TIMEOUT" not in ev:
3199        raise Exception("GAS timeout not reported")
3200
3201def test_dpp_hostapd_enrollee_gas_timeout_comeback(dev, apdev):
3202    """DPP and hostapd as Enrollee with GAS timeout during comeback"""
3203    check_dpp_capab(dev[0])
3204    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
3205                                     "channel": "6"})
3206    check_dpp_capab(hapd)
3207    conf_id = dev[0].dpp_configurator_add()
3208    id0 = dev[0].dpp_bootstrap_gen(chan="81/6", mac=True)
3209    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
3210    conf = '{"wi-fi_tech":"infra", "discovery":{"ssid":"test"},"cred":{"akm":"psk","pass":"secret passphrase"}}' + 3000*' '
3211    dev[0].set("dpp_config_obj_override", conf)
3212    dev[0].set("dpp_configurator_params",
3213               "conf=ap-dpp configurator=%d" % conf_id)
3214    dev[0].set("ext_mgmt_frame_handling", "1")
3215    dev[0].dpp_listen(2437, role="configurator")
3216    hapd.dpp_auth_init(uri=uri0, role="enrollee")
3217    process_dpp_frames(dev[0], count=4)
3218    ev = hapd.wait_event(["GAS-QUERY-DONE"], timeout=10)
3219    if "result=TIMEOUT" not in ev:
3220        raise Exception("GAS timeout not reported")
3221
3222def process_dpp_frames(dev, count=3):
3223    for i in range(count):
3224        msg = dev.mgmt_rx()
3225        cmd = "MGMT_RX_PROCESS freq={} datarate={} ssi_signal={} frame={}".format(msg['freq'], msg['datarate'], msg['ssi_signal'], binascii.hexlify(msg['frame']).decode())
3226        if "OK" not in dev.request(cmd):
3227            raise Exception("MGMT_RX_PROCESS failed")
3228
3229def test_dpp_hostapd_enrollee_gas_errors(dev, apdev):
3230    """DPP and hostapd as Enrollee with GAS query local errors"""
3231    check_dpp_capab(dev[0])
3232    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
3233                                     "channel": "6"})
3234    check_dpp_capab(hapd)
3235    conf_id = dev[0].dpp_configurator_add()
3236    id0 = dev[0].dpp_bootstrap_gen(chan="81/6", mac=True)
3237    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
3238    dev[0].set("dpp_configurator_params",
3239               "conf=ap-dpp configurator=%d" % conf_id)
3240    dev[0].set("ext_mgmt_frame_handling", "1")
3241
3242    # GAS without comeback
3243    tests = [(1, "gas_query_append;gas_query_rx_initial", 3, True),
3244             (1, "gas_query_rx_initial", 3, True),
3245             (1, "gas_query_tx_initial_req", 2, True),
3246             (1, "gas_query_ap_req", 2, False)]
3247    for count, func, frame_count, wait_ev in tests:
3248        dev[0].request("DPP_STOP_LISTEN")
3249        dev[0].dpp_listen(2437, role="configurator")
3250        dev[0].dump_monitor()
3251        hapd.dump_monitor()
3252        with alloc_fail(hapd, count, func):
3253            hapd.dpp_auth_init(uri=uri0, role="enrollee")
3254            process_dpp_frames(dev[0], count=frame_count)
3255            if wait_ev:
3256                ev = hapd.wait_event(["GAS-QUERY-DONE"], timeout=10)
3257                if not ev or "result=INTERNAL_ERROR" not in ev:
3258                    raise Exception("Unexpect GAS query result: " + str(ev))
3259
3260    # GAS with comeback
3261    conf = '{"wi-fi_tech":"infra", "discovery":{"ssid":"test"},"cred":{"akm":"psk","pass":"secret passphrase"}}' + 3000*' '
3262    dev[0].set("dpp_config_obj_override", conf)
3263
3264    tests = [(1, "gas_query_append;gas_query_rx_comeback", 4),
3265             (1, "wpabuf_alloc;gas_query_tx_comeback_req", 3),
3266             (1, "hostapd_drv_send_action;gas_query_tx_comeback_req", 3)]
3267    for count, func, frame_count in tests:
3268        dev[0].request("DPP_STOP_LISTEN")
3269        dev[0].dpp_listen(2437, role="configurator")
3270        dev[0].dump_monitor()
3271        hapd.dump_monitor()
3272        with alloc_fail(hapd, count, func):
3273            hapd.dpp_auth_init(uri=uri0, role="enrollee")
3274            process_dpp_frames(dev[0], count=frame_count)
3275            ev = hapd.wait_event(["GAS-QUERY-DONE"], timeout=10)
3276            if not ev or "result=INTERNAL_ERROR" not in ev:
3277                raise Exception("Unexpect GAS query result: " + str(ev))
3278
3279def test_dpp_hostapd_enrollee_gas_proto(dev, apdev):
3280    """DPP and hostapd as Enrollee with GAS query protocol testing"""
3281    check_dpp_capab(dev[0])
3282    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
3283                                     "channel": "6"})
3284    check_dpp_capab(hapd)
3285    bssid = hapd.own_addr()
3286    conf_id = dev[0].dpp_configurator_add()
3287    id0 = dev[0].dpp_bootstrap_gen(chan="81/6", mac=True)
3288    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
3289    dev[0].set("dpp_configurator_params",
3290               "conf=ap-dpp configurator=%d" % conf_id)
3291    conf = '{"wi-fi_tech":"infra", "discovery":{"ssid":"test"},"cred":{"akm":"psk","pass":"secret passphrase"}}' + 3000*' '
3292    dev[0].set("dpp_config_obj_override", conf)
3293    dev[0].set("ext_mgmt_frame_handling", "1")
3294    dev[0].dpp_listen(2437, role="configurator")
3295    hapd.dpp_auth_init(uri=uri0, role="enrollee")
3296    process_dpp_frames(dev[0], count=3)
3297    msg = dev[0].mgmt_rx()
3298    payload = msg['payload']
3299    dialog_token, = struct.unpack('B', payload[2:3])
3300    hdr = struct.pack('<BBBHBH', 4, 13, dialog_token, 0, 0x80, 0)
3301    # GAS: Advertisement Protocol changed between initial and comeback response from 02:00:00:00:00:00
3302    adv_proto = "6c087fdd05506f9a1a02"
3303    action = binascii.hexlify(hdr).decode() + adv_proto + "0300" + "001001"
3304    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
3305    dev[0].request(cmd)
3306    ev = hapd.wait_event(["GAS-QUERY-DONE"], timeout=10)
3307    if not ev or "result=PEER_ERROR" not in ev:
3308        raise Exception("Unexpect GAS query result: " + str(ev))
3309    dev[0].request("DPP_STOP_LISTEN")
3310    hapd.dump_monitor()
3311    dev[0].dump_monitor()
3312
3313    dev[0].dpp_listen(2437, role="configurator")
3314    hapd.dpp_auth_init(uri=uri0, role="enrollee")
3315    process_dpp_frames(dev[0], count=3)
3316    msg = dev[0].mgmt_rx()
3317    payload = msg['payload']
3318    dialog_token, = struct.unpack('B', payload[2:3])
3319    # Another comeback delay
3320    hdr = struct.pack('<BBBHBH', 4, 13, dialog_token, 0, 0x80, 1)
3321    adv_proto = "6c087fdd05506f9a1a01"
3322    action = binascii.hexlify(hdr).decode() + adv_proto + "0300" + "001001"
3323    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
3324    dev[0].request(cmd)
3325    msg = dev[0].mgmt_rx()
3326    hdr = struct.pack('<BBBHBH', 4, 13, dialog_token, 0, 0x81, 1)
3327    # GAS: Invalid comeback response with non-zero frag_id and comeback_delay from 02:00:00:00:00:00
3328    action = binascii.hexlify(hdr).decode() + adv_proto + "0300" + "001001"
3329    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
3330    dev[0].request(cmd)
3331    ev = hapd.wait_event(["GAS-QUERY-DONE"], timeout=10)
3332    if not ev or "result=PEER_ERROR" not in ev:
3333        raise Exception("Unexpect GAS query result: " + str(ev))
3334    dev[0].request("DPP_STOP_LISTEN")
3335    hapd.dump_monitor()
3336    dev[0].dump_monitor()
3337
3338    dev[0].dpp_listen(2437, role="configurator")
3339    hapd.dpp_auth_init(uri=uri0, role="enrollee")
3340    process_dpp_frames(dev[0], count=3)
3341    msg = dev[0].mgmt_rx()
3342    payload = msg['payload']
3343    dialog_token, = struct.unpack('B', payload[2:3])
3344    # Valid comeback response
3345    hdr = struct.pack('<BBBHBH', 4, 13, dialog_token, 0, 0x80, 0)
3346    action = binascii.hexlify(hdr).decode() + adv_proto + "0300" + "001001"
3347    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
3348    dev[0].request(cmd)
3349    msg = dev[0].mgmt_rx()
3350    # GAS: Drop frame as possible retry of previous fragment
3351    hdr = struct.pack('<BBBHBH', 4, 13, dialog_token, 0, 0x80, 0)
3352    action = binascii.hexlify(hdr).decode() + adv_proto + "0300" + "001001"
3353    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
3354    dev[0].request(cmd)
3355    # GAS: Unexpected frag_id in response from 02:00:00:00:00:00
3356    hdr = struct.pack('<BBBHBH', 4, 13, dialog_token, 0, 0x82, 0)
3357    action = binascii.hexlify(hdr).decode() + adv_proto + "0300" + "001001"
3358    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
3359    dev[0].request(cmd)
3360    ev = hapd.wait_event(["GAS-QUERY-DONE"], timeout=10)
3361    if not ev or "result=PEER_ERROR" not in ev:
3362        raise Exception("Unexpect GAS query result: " + str(ev))
3363    dev[0].request("DPP_STOP_LISTEN")
3364    hapd.dump_monitor()
3365    dev[0].dump_monitor()
3366
3367    dev[0].dpp_listen(2437, role="configurator")
3368    hapd.dpp_auth_init(uri=uri0, role="enrollee")
3369    process_dpp_frames(dev[0], count=3)
3370    msg = dev[0].mgmt_rx()
3371    payload = msg['payload']
3372    dialog_token, = struct.unpack('B', payload[2:3])
3373    # GAS: Unexpected initial response from 02:00:00:00:00:00 dialog token 3 when waiting for comeback response
3374    hdr = struct.pack('<BBBHBH', 4, 11, dialog_token, 0, 0x80, 0)
3375    action = binascii.hexlify(hdr).decode() + adv_proto + "0300" + "001001"
3376    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
3377    dev[0].request(cmd)
3378    # GAS: Allow non-zero status for outstanding comeback response
3379    hdr = struct.pack('<BBBHBH', 4, 13, dialog_token, 95, 0x80, 0)
3380    # GAS: Ignore 1 octets of extra data after Query Response from 02:00:00:00:00:00
3381    action = binascii.hexlify(hdr).decode() + adv_proto + "0300" + "001001" + "ff"
3382    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
3383    dev[0].request(cmd)
3384    # GAS: No pending query found for 02:00:00:00:00:00 dialog token 4
3385    hdr = struct.pack('<BBBHBH', 4, 13, (dialog_token + 1) % 256, 0, 0x80, 0)
3386    action = binascii.hexlify(hdr).decode() + adv_proto + "0300" + "001001"
3387    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
3388    dev[0].request(cmd)
3389    # GAS: Truncated Query Response in response from 02:00:00:00:00:00
3390    hdr = struct.pack('<BBBHBH', 4, 13, dialog_token, 0, 0x81, 0)
3391    action = binascii.hexlify(hdr).decode() + adv_proto + "0300" + "0010"
3392    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
3393    dev[0].request(cmd)
3394    # GAS: No room for GAS Response Length
3395    hdr = struct.pack('<BBBHBH', 4, 13, dialog_token, 0, 0x81, 0)
3396    action = binascii.hexlify(hdr).decode() + adv_proto + "03"
3397    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
3398    dev[0].request(cmd)
3399    # GAS: Unexpected Advertisement Protocol element ID 0 in response from 02:00:00:00:00:00
3400    hdr = struct.pack('<BBBHBH', 4, 13, dialog_token, 0, 0x81, 0)
3401    adv_proto_broken = "0000"
3402    action = binascii.hexlify(hdr).decode() + adv_proto_broken + "0300" + "001001"
3403    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
3404    dev[0].request(cmd)
3405    # GAS: No room for Advertisement Protocol element in the response from 02:00:00:00:00:00
3406    hdr = struct.pack('<BBBHBH', 4, 13, dialog_token, 0, 0x81, 0)
3407    adv_proto_broken = "00ff"
3408    action = binascii.hexlify(hdr).decode() + adv_proto_broken + "0300" + "001001"
3409    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
3410    dev[0].request(cmd)
3411    # No room for Comeback Delay
3412    hdr = struct.pack('<BBBHBB', 4, 13, dialog_token, 0, 0x81, 0)
3413    action = binascii.hexlify(hdr).decode()
3414    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
3415    dev[0].request(cmd)
3416    # No room for frag_id
3417    hdr = struct.pack('<BBBH', 4, 13, dialog_token, 0)
3418    action = binascii.hexlify(hdr).decode()
3419    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
3420    dev[0].request(cmd)
3421    # GAS: Query to 02:00:00:00:00:00 dialog token 3 failed - status code 1
3422    hdr = struct.pack('<BBBHBH', 4, 13, dialog_token, 1, 0x81, 0)
3423    action = binascii.hexlify(hdr).decode() + adv_proto + "0300" + "001001"
3424    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
3425    dev[0].request(cmd)
3426    ev = hapd.wait_event(["GAS-QUERY-DONE"], timeout=10)
3427    if not ev or "result=FAILURE" not in ev:
3428        raise Exception("Unexpect GAS query result: " + str(ev))
3429    dev[0].request("DPP_STOP_LISTEN")
3430    hapd.dump_monitor()
3431    dev[0].dump_monitor()
3432
3433    dev[0].dpp_listen(2437, role="configurator")
3434    hapd.dpp_auth_init(uri=uri0, role="enrollee")
3435    process_dpp_frames(dev[0], count=2)
3436    msg = dev[0].mgmt_rx()
3437    payload = msg['payload']
3438    dialog_token, = struct.unpack('B', payload[2:3])
3439    # Unexpected comeback delay
3440    hdr = struct.pack('<BBBHBH', 4, 13, dialog_token, 0, 0x80, 0)
3441    adv_proto = "6c087fdd05506f9a1a01"
3442    action = binascii.hexlify(hdr).decode() + adv_proto + "0300" + "001001"
3443    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
3444    dev[0].request(cmd)
3445    # GAS: Query to 02:00:00:00:00:00 dialog token 3 failed - status code 1
3446    hdr = struct.pack('<BBBHBH', 4, 11, dialog_token, 1, 0x80, 0)
3447    action = binascii.hexlify(hdr).decode() + adv_proto + "0300" + "001001"
3448    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
3449    dev[0].request(cmd)
3450    ev = hapd.wait_event(["GAS-QUERY-DONE"], timeout=10)
3451    if not ev or "result=FAILURE" not in ev:
3452        raise Exception("Unexpect GAS query result: " + str(ev))
3453    dev[0].request("DPP_STOP_LISTEN")
3454    hapd.dump_monitor()
3455    dev[0].dump_monitor()
3456
3457def test_dpp_hostapd_enrollee_gas_tx_status_errors(dev, apdev):
3458    """DPP and hostapd as Enrollee with GAS TX status errors"""
3459    check_dpp_capab(dev[0])
3460    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
3461                                     "channel": "6"})
3462    check_dpp_capab(hapd)
3463    conf_id = dev[0].dpp_configurator_add()
3464    id0 = dev[0].dpp_bootstrap_gen(chan="81/6", mac=True)
3465    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
3466    conf = '{"wi-fi_tech":"infra", "discovery":{"ssid":"test"},"cred":{"akm":"psk","pass":"secret passphrase"}}' + 3000*' '
3467    dev[0].set("dpp_config_obj_override", conf)
3468    dev[0].set("dpp_configurator_params",
3469               "conf=ap-dpp configurator=%d" % conf_id)
3470    dev[0].set("ext_mgmt_frame_handling", "1")
3471    dev[0].dpp_listen(2437, role="configurator")
3472    hapd.dpp_auth_init(uri=uri0, role="enrollee")
3473    process_dpp_frames(dev[0], count=3)
3474
3475    hapd.set("ext_mgmt_frame_handling", "1")
3476    # GAS: TX status for unexpected destination
3477    frame = "d0003a01" + "222222222222"
3478    frame += hapd.own_addr().replace(':', '') + "ffffffffffff"
3479    frame += "5000" + "040a"
3480    hapd.request("MGMT_TX_STATUS_PROCESS stype=13 ok=1 buf=" + frame)
3481
3482    # GAS: No ACK to GAS request
3483    frame = "d0003a01" + dev[0].own_addr().replace(':', '')
3484    frame += hapd.own_addr().replace(':', '') + "ffffffffffff"
3485    frame += "5000" + "040a"
3486    hapd.request("MGMT_TX_STATUS_PROCESS stype=13 ok=0 buf=" + frame)
3487
3488    ev = hapd.wait_event(["GAS-QUERY-DONE"], timeout=10)
3489    if "result=TIMEOUT" not in ev:
3490        raise Exception("GAS timeout not reported")
3491
3492    # GAS: Unexpected TX status: dst=02:00:00:00:00:00 ok=1 - no query in progress
3493    hapd.request("MGMT_TX_STATUS_PROCESS stype=13 ok=1 buf=" + frame)
3494    hapd.set("ext_mgmt_frame_handling", "0")
3495
3496def test_dpp_hostapd_configurator_override_objects(dev, apdev):
3497    """DPP with hostapd as configurator and override objects"""
3498    check_dpp_capab(dev[0])
3499    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
3500                                     "channel": "1"})
3501    check_dpp_capab(hapd)
3502    conf_id = hapd.dpp_configurator_add()
3503    id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
3504    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
3505    id1 = hapd.dpp_qr_code(uri0)
3506    res = hapd.request("DPP_BOOTSTRAP_INFO %d" % id1)
3507    if "FAIL" in res:
3508        raise Exception("DPP_BOOTSTRAP_INFO failed")
3509    dev[0].dpp_listen(2412)
3510    discovery = '{\n"ssid":"mywifi"\n}'
3511    groups = '[\n  {"groupId":"home","netRole":"sta"},\n  {"groupId":"cottage","netRole":"sta"}\n]'
3512    hapd.set("dpp_discovery_override", discovery)
3513    hapd.set("dpp_groups_override", groups)
3514    hapd.dpp_auth_init(peer=id1, configurator=conf_id, conf="sta-dpp")
3515    wait_auth_success(dev[0], hapd, configurator=hapd, enrollee=dev[0],
3516                      stop_responder=True)
3517
3518def test_dpp_own_config(dev, apdev):
3519    """DPP configurator signing own connector"""
3520    try:
3521        run_dpp_own_config(dev, apdev)
3522    finally:
3523        dev[0].set("dpp_config_processing", "0", allow_fail=True)
3524
3525def test_dpp_own_config_group_id(dev, apdev):
3526    """DPP configurator signing own connector"""
3527    try:
3528        run_dpp_own_config(dev, apdev, extra=" group_id=test-group")
3529    finally:
3530        dev[0].set("dpp_config_processing", "0", allow_fail=True)
3531
3532def test_dpp_own_config_curve_mismatch(dev, apdev):
3533    """DPP configurator signing own connector using mismatching curve"""
3534    try:
3535        run_dpp_own_config(dev, apdev, own_curve="BP-384", expect_failure=True)
3536    finally:
3537        dev[0].set("dpp_config_processing", "0", allow_fail=True)
3538
3539def run_dpp_own_config(dev, apdev, own_curve=None, expect_failure=False,
3540                       extra=None):
3541    check_dpp_capab(dev[0], own_curve and "BP" in own_curve)
3542    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured"})
3543    check_dpp_capab(hapd)
3544    id_h = hapd.dpp_bootstrap_gen(chan="81/1", mac=True)
3545    uri = hapd.request("DPP_BOOTSTRAP_GET_URI %d" % id_h)
3546    conf_id = dev[0].dpp_configurator_add()
3547    dev[0].dpp_auth_init(uri=uri, conf="ap-dpp", configurator=conf_id,
3548                         extra=extra)
3549    wait_auth_success(hapd, dev[0], configurator=dev[0], enrollee=hapd)
3550    update_hapd_config(hapd)
3551
3552    dev[0].set("dpp_config_processing", "1")
3553    cmd = "DPP_CONFIGURATOR_SIGN conf=sta-dpp configurator=%d%s" % (conf_id, extra)
3554    if own_curve:
3555        dev[0].dpp_configurator_set(conf_id, net_access_key_curve=own_curve)
3556        cmd += " curve=" + own_curve
3557    res = dev[0].request(cmd)
3558    if "FAIL" in res:
3559        raise Exception("Failed to generate own configuration")
3560
3561    ev = dev[0].wait_event(["DPP-NETWORK-ID"], timeout=1)
3562    if ev is None:
3563        raise Exception("DPP network profile not generated")
3564    id = ev.split(' ')[1]
3565    dev[0].select_network(id, freq="2412")
3566    if expect_failure:
3567        ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1)
3568        if ev is not None:
3569            raise Exception("Unexpected connection")
3570        dev[0].request("DISCONNECT")
3571    else:
3572        dev[0].wait_connected()
3573
3574def test_dpp_own_config_ap(dev, apdev):
3575    """DPP configurator (AP) signing own connector"""
3576    try:
3577        run_dpp_own_config_ap(dev, apdev)
3578    finally:
3579        dev[0].set("dpp_config_processing", "0", allow_fail=True)
3580
3581def test_dpp_own_config_ap_group_id(dev, apdev):
3582    """DPP configurator (AP) signing own connector (group_id)"""
3583    try:
3584        run_dpp_own_config_ap(dev, apdev, extra=" group_id=test-group")
3585    finally:
3586        dev[0].set("dpp_config_processing", "0", allow_fail=True)
3587
3588def test_dpp_own_config_ap_reconf(dev, apdev):
3589    """DPP configurator (AP) signing own connector and configurator reconf"""
3590    try:
3591        run_dpp_own_config_ap(dev, apdev)
3592    finally:
3593        dev[0].set("dpp_config_processing", "0", allow_fail=True)
3594
3595def run_dpp_own_config_ap(dev, apdev, reconf_configurator=False, extra=None):
3596    check_dpp_capab(dev[0])
3597    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured"})
3598    check_dpp_capab(hapd)
3599    conf_id = hapd.dpp_configurator_add()
3600    if reconf_configurator:
3601        csign = hapd.request("DPP_CONFIGURATOR_GET_KEY %d" % conf_id)
3602        if "FAIL" in csign or len(csign) == 0:
3603            raise Exception("DPP_CONFIGURATOR_GET_KEY failed")
3604
3605    cmd = "DPP_CONFIGURATOR_SIGN conf=ap-dpp configurator=%d%s" % (conf_id, extra)
3606    res = hapd.request(cmd)
3607    if "FAIL" in res:
3608        raise Exception("Failed to generate own configuration")
3609    update_hapd_config(hapd)
3610
3611    if reconf_configurator:
3612        hapd.dpp_configurator_remove(conf_id)
3613        conf_id = hapd.dpp_configurator_add(key=csign)
3614
3615    id = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
3616    uri = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id)
3617    dev[0].set("dpp_config_processing", "2")
3618    dev[0].dpp_listen(2412)
3619    hapd.dpp_auth_init(uri=uri, conf="sta-dpp", configurator=conf_id,
3620                       extra=extra)
3621    wait_auth_success(dev[0], hapd, configurator=hapd, enrollee=dev[0])
3622    dev[0].wait_connected()
3623
3624def test_dpp_intro_mismatch(dev, apdev):
3625    """DPP network introduction mismatch cases"""
3626    try:
3627        wpas = None
3628        wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
3629        wpas.interface_add("wlan5")
3630        check_dpp_capab(wpas)
3631        run_dpp_intro_mismatch(dev, apdev, wpas)
3632    finally:
3633        dev[0].set("dpp_config_processing", "0", allow_fail=True)
3634        dev[2].set("dpp_config_processing", "0", allow_fail=True)
3635        if wpas:
3636            wpas.set("dpp_config_processing", "0", allow_fail=True)
3637
3638def run_dpp_intro_mismatch(dev, apdev, wpas):
3639    check_dpp_capab(dev[0])
3640    check_dpp_capab(dev[1], min_ver=3)
3641    check_dpp_capab(dev[2], min_ver=3)
3642    logger.info("Start AP in unconfigured state")
3643    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured"})
3644    check_dpp_capab(hapd)
3645    id_h = hapd.dpp_bootstrap_gen(chan="81/1", mac=True)
3646    uri = hapd.request("DPP_BOOTSTRAP_GET_URI %d" % id_h)
3647    logger.info("Provision AP with DPP configuration")
3648    conf_id = dev[1].dpp_configurator_add()
3649    dev[1].set("dpp_groups_override", '[{"groupId":"a","netRole":"ap"}]')
3650    dev[1].dpp_auth_init(uri=uri, conf="ap-dpp", configurator=conf_id)
3651    update_hapd_config(hapd)
3652
3653    logger.info("Provision STA0 with DPP Connector that has mismatching groupId")
3654    dev[0].set("dpp_config_processing", "2")
3655    id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
3656    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
3657    dev[0].dpp_listen(2412)
3658    dev[1].set("dpp_groups_override", '[{"groupId":"b","netRole":"sta"}]')
3659    dev[1].dpp_auth_init(uri=uri0, conf="sta-dpp", configurator=conf_id)
3660    wait_auth_success(dev[0], dev[1], configurator=dev[1], enrollee=dev[0])
3661
3662    logger.info("Provision STA2 with DPP Connector that has mismatching C-sign-key")
3663    dev[2].set("dpp_config_processing", "2")
3664    id2 = dev[2].dpp_bootstrap_gen(chan="81/1", mac=True)
3665    uri2 = dev[2].request("DPP_BOOTSTRAP_GET_URI %d" % id2)
3666    dev[2].dpp_listen(2412)
3667    conf_id_2 = dev[1].dpp_configurator_add()
3668    dev[1].set("dpp_groups_override", '')
3669    dev[1].dpp_auth_init(uri=uri2, conf="sta-dpp", configurator=conf_id_2)
3670    wait_auth_success(dev[2], dev[1], configurator=dev[1], enrollee=dev[2])
3671
3672    logger.info("Provision STA5 with DPP Connector that has mismatching netAccessKey EC group")
3673    wpas.set("dpp_config_processing", "2")
3674    id5 = wpas.dpp_bootstrap_gen(chan="81/1", mac=True, curve="P-521")
3675    uri5 = wpas.request("DPP_BOOTSTRAP_GET_URI %d" % id5)
3676    wpas.dpp_listen(2412)
3677    dev[1].set("dpp_groups_override", '')
3678    dev[1].dpp_configurator_set(conf_id, net_access_key_curve="P-521")
3679    dev[1].dpp_auth_init(uri=uri5, conf="sta-dpp", configurator=conf_id)
3680    wait_auth_success(wpas, dev[1], configurator=dev[1], enrollee=wpas)
3681
3682    logger.info("Verify network introduction results")
3683    ev = dev[0].wait_event(["DPP-INTRO"], timeout=10)
3684    if ev is None:
3685        raise Exception("DPP network introduction result not seen on STA0")
3686    if "status=8" not in ev:
3687        raise Exception("Unexpected network introduction result on STA0: " + ev)
3688
3689    ev = dev[2].wait_event(["DPP-INTRO"], timeout=5)
3690    if ev is None:
3691        raise Exception("DPP network introduction result not seen on STA2")
3692    if "status=8" not in ev:
3693        raise Exception("Unexpected network introduction result on STA2: " + ev)
3694
3695    ev = wpas.wait_event(["DPP-INTRO"], timeout=10)
3696    if ev is None:
3697        raise Exception("DPP network introduction result not seen on STA5")
3698    if "status=7" not in ev:
3699        raise Exception("Unexpected network introduction result on STA5: " + ev)
3700
3701def run_dpp_proto_init(dev, test_dev, test, mutual=False, unicast=True,
3702                       listen=True, chan="81/1", init_enrollee=False,
3703                       incompatible_roles=False):
3704    check_dpp_capab(dev[0])
3705    check_dpp_capab(dev[1])
3706    dev[test_dev].set("dpp_test", str(test))
3707    if init_enrollee:
3708        conf_id = dev[0].dpp_configurator_add()
3709    else:
3710        conf_id = dev[1].dpp_configurator_add()
3711    id0 = dev[0].dpp_bootstrap_gen(chan=chan, mac=unicast)
3712    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
3713
3714    if mutual:
3715        id1b = dev[1].dpp_bootstrap_gen(chan="81/1", mac=True)
3716        uri1b = dev[1].request("DPP_BOOTSTRAP_GET_URI %d" % id1b)
3717
3718        id0b = dev[0].dpp_qr_code(uri1b)
3719        qr = "mutual"
3720    else:
3721        qr = None
3722
3723    if init_enrollee:
3724        if incompatible_roles:
3725            role = "enrollee"
3726        else:
3727            role = "configurator"
3728        dev[0].set("dpp_configurator_params",
3729                   " conf=sta-dpp configurator=%d" % conf_id)
3730    elif incompatible_roles:
3731        role = "enrollee"
3732    else:
3733        role = None
3734
3735    if listen:
3736        dev[0].dpp_listen(2412, qr=qr, role=role)
3737
3738    role = None
3739    configurator = None
3740    conf = None
3741    own = None
3742
3743    if init_enrollee:
3744        role="enrollee"
3745    else:
3746        configurator=conf_id
3747        conf="sta-dpp"
3748        if incompatible_roles:
3749            role="enrollee"
3750    if mutual:
3751        own = id1b
3752    dev[1].dpp_auth_init(uri=uri0, role=role, configurator=configurator,
3753                         conf=conf, own=own)
3754    return uri0, role, configurator, conf, own
3755
3756def test_dpp_proto_after_wrapped_data_auth_req(dev, apdev):
3757    """DPP protocol testing - attribute after Wrapped Data in Auth Req"""
3758    run_dpp_proto_init(dev, 1, 1)
3759    ev = dev[0].wait_event(["DPP-RX"], timeout=5)
3760    if ev is None:
3761        raise Exception("DPP Authentication Request not seen")
3762    if "type=0" not in ev or "ignore=invalid-attributes" not in ev:
3763        raise Exception("Unexpected RX info: " + ev)
3764    ev = dev[1].wait_event(["DPP-RX"], timeout=0.1)
3765    if ev is not None:
3766        raise Exception("Unexpected DPP message seen")
3767
3768def test_dpp_auth_req_stop_after_ack(dev, apdev):
3769    """DPP initiator stopping after ACK, but no response"""
3770    run_dpp_proto_init(dev, 1, 1, listen=True)
3771    ev = dev[1].wait_event(["DPP-AUTH-INIT-FAILED"], timeout=5)
3772    if ev is None:
3773        raise Exception("Authentication failure not reported")
3774
3775def test_dpp_auth_req_retries(dev, apdev):
3776    """DPP initiator retries with no ACK"""
3777    check_dpp_capab(dev[1])
3778    dev[1].set("dpp_init_max_tries", "3")
3779    dev[1].set("dpp_init_retry_time", "1000")
3780    dev[1].set("dpp_resp_wait_time", "100")
3781    run_dpp_proto_init(dev, 1, 1, unicast=False, listen=False)
3782
3783    for i in range(3):
3784        ev = dev[1].wait_event(["DPP-TX "], timeout=5)
3785        if ev is None:
3786            raise Exception("Auth Req not sent (%d)" % i)
3787
3788    ev = dev[1].wait_event(["DPP-AUTH-INIT-FAILED"], timeout=5)
3789    if ev is None:
3790        raise Exception("Authentication failure not reported")
3791
3792def test_dpp_auth_req_retries_multi_chan(dev, apdev):
3793    """DPP initiator retries with no ACK and multiple channels"""
3794    check_dpp_capab(dev[1])
3795    dev[1].set("dpp_init_max_tries", "3")
3796    dev[1].set("dpp_init_retry_time", "1000")
3797    dev[1].set("dpp_resp_wait_time", "100")
3798    run_dpp_proto_init(dev, 1, 1, unicast=False, listen=False,
3799                       chan="81/1,81/6,81/11")
3800
3801    for i in range(3 * 3):
3802        ev = dev[1].wait_event(["DPP-TX "], timeout=5)
3803        if ev is None:
3804            raise Exception("Auth Req not sent (%d)" % i)
3805
3806    ev = dev[1].wait_event(["DPP-AUTH-INIT-FAILED"], timeout=5)
3807    if ev is None:
3808        raise Exception("Authentication failure not reported")
3809
3810def test_dpp_proto_after_wrapped_data_auth_resp(dev, apdev):
3811    """DPP protocol testing - attribute after Wrapped Data in Auth Resp"""
3812    run_dpp_proto_init(dev, 0, 2)
3813    ev = dev[1].wait_event(["DPP-RX"], timeout=5)
3814    if ev is None:
3815        raise Exception("DPP Authentication Response not seen")
3816    if "type=1" not in ev or "ignore=invalid-attributes" not in ev:
3817        raise Exception("Unexpected RX info: " + ev)
3818    ev = dev[0].wait_event(["DPP-RX"], timeout=1)
3819    if ev is None or "type=0" not in ev:
3820        raise Exception("DPP Authentication Request not seen")
3821    ev = dev[0].wait_event(["DPP-RX"], timeout=0.1)
3822    if ev is not None:
3823        raise Exception("Unexpected DPP message seen")
3824
3825def test_dpp_proto_after_wrapped_data_auth_conf(dev, apdev):
3826    """DPP protocol testing - attribute after Wrapped Data in Auth Conf"""
3827    run_dpp_proto_init(dev, 1, 3)
3828    ev = dev[0].wait_event(["DPP-RX"], timeout=5)
3829    if ev is None or "type=0" not in ev:
3830        raise Exception("DPP Authentication Request not seen")
3831    ev = dev[0].wait_event(["DPP-RX"], timeout=5)
3832    if ev is None:
3833        raise Exception("DPP Authentication Confirm not seen")
3834    if "type=2" not in ev or "ignore=invalid-attributes" not in ev:
3835        raise Exception("Unexpected RX info: " + ev)
3836
3837def test_dpp_proto_after_wrapped_data_conf_req(dev, apdev):
3838    """DPP protocol testing - attribute after Wrapped Data in Conf Req"""
3839    run_dpp_proto_init(dev, 0, 6)
3840    ev = dev[1].wait_event(["DPP-CONF-FAILED"], timeout=10)
3841    if ev is None:
3842        raise Exception("DPP Configuration failure not seen")
3843
3844def test_dpp_proto_after_wrapped_data_conf_resp(dev, apdev):
3845    """DPP protocol testing - attribute after Wrapped Data in Conf Resp"""
3846    run_dpp_proto_init(dev, 1, 7)
3847    ev = dev[0].wait_event(["DPP-CONF-FAILED"], timeout=10)
3848    if ev is None:
3849        raise Exception("DPP Configuration failure not seen")
3850
3851def test_dpp_proto_zero_i_capab(dev, apdev):
3852    """DPP protocol testing - zero I-capability in Auth Req"""
3853    run_dpp_proto_init(dev, 1, 8)
3854    wait_dpp_fail(dev[0], "Invalid role in I-capabilities 0x00")
3855    ev = dev[1].wait_event(["DPP-RX"], timeout=0.1)
3856    if ev is not None:
3857        raise Exception("Unexpected DPP message seen")
3858
3859def test_dpp_proto_zero_r_capab(dev, apdev):
3860    """DPP protocol testing - zero R-capability in Auth Resp"""
3861    run_dpp_proto_init(dev, 0, 9)
3862    wait_dpp_fail(dev[1], "Unexpected role in R-capabilities 0x00")
3863    ev = dev[0].wait_event(["DPP-RX"], timeout=1)
3864    if ev is None or "type=0" not in ev:
3865        raise Exception("DPP Authentication Request not seen")
3866    ev = dev[0].wait_event(["DPP-RX"], timeout=0.1)
3867    if ev is not None:
3868        raise Exception("Unexpected DPP message seen")
3869
3870def run_dpp_proto_auth_req_missing(dev, test, reason, mutual=False):
3871    run_dpp_proto_init(dev, 1, test, mutual=mutual)
3872    wait_dpp_fail(dev[0], reason)
3873    ev = dev[1].wait_event(["DPP-RX"], timeout=0.1)
3874    if ev is not None:
3875        raise Exception("Unexpected DPP message seen")
3876
3877def test_dpp_proto_auth_req_no_r_bootstrap_key(dev, apdev):
3878    """DPP protocol testing - no R-bootstrap key in Auth Req"""
3879    run_dpp_proto_auth_req_missing(dev, 10, "Missing or invalid required Responder Bootstrapping Key Hash attribute")
3880
3881def test_dpp_proto_auth_req_invalid_r_bootstrap_key(dev, apdev):
3882    """DPP protocol testing - invalid R-bootstrap key in Auth Req"""
3883    run_dpp_proto_auth_req_missing(dev, 68, "No matching own bootstrapping key found - ignore message")
3884
3885def test_dpp_proto_auth_req_no_i_bootstrap_key(dev, apdev):
3886    """DPP protocol testing - no I-bootstrap key in Auth Req"""
3887    run_dpp_proto_auth_req_missing(dev, 11, "Missing or invalid required Initiator Bootstrapping Key Hash attribute")
3888
3889def test_dpp_proto_auth_req_invalid_i_bootstrap_key(dev, apdev):
3890    """DPP protocol testing - invalid I-bootstrap key in Auth Req"""
3891    run_dpp_proto_init(dev, 1, 69, mutual=True)
3892    ev = dev[0].wait_event(["DPP-SCAN-PEER-QR-CODE"], timeout=5)
3893    if ev is None:
3894        raise Exception("DPP scan request not seen")
3895    ev = dev[1].wait_event(["DPP-RESPONSE-PENDING"], timeout=5)
3896    if ev is None:
3897        raise Exception("DPP response pending indication not seen")
3898
3899def test_dpp_proto_auth_req_no_i_proto_key(dev, apdev):
3900    """DPP protocol testing - no I-proto key in Auth Req"""
3901    run_dpp_proto_auth_req_missing(dev, 12, "Missing required Initiator Protocol Key attribute")
3902
3903def test_dpp_proto_auth_req_invalid_i_proto_key(dev, apdev):
3904    """DPP protocol testing - invalid I-proto key in Auth Req"""
3905    run_dpp_proto_auth_req_missing(dev, 66, "Invalid Initiator Protocol Key")
3906
3907def test_dpp_proto_auth_req_no_i_nonce(dev, apdev):
3908    """DPP protocol testing - no I-nonce in Auth Req"""
3909    run_dpp_proto_auth_req_missing(dev, 13, "Missing or invalid I-nonce")
3910
3911def test_dpp_proto_auth_req_invalid_i_nonce(dev, apdev):
3912    """DPP protocol testing - invalid I-nonce in Auth Req"""
3913    run_dpp_proto_auth_req_missing(dev, 81, "Missing or invalid I-nonce")
3914
3915def test_dpp_proto_auth_req_no_i_capab(dev, apdev):
3916    """DPP protocol testing - no I-capab in Auth Req"""
3917    run_dpp_proto_auth_req_missing(dev, 14, "Missing or invalid I-capab")
3918
3919def test_dpp_proto_auth_req_no_wrapped_data(dev, apdev):
3920    """DPP protocol testing - no Wrapped Data in Auth Req"""
3921    run_dpp_proto_auth_req_missing(dev, 15, "Missing or invalid required Wrapped Data attribute")
3922
3923def run_dpp_proto_auth_resp_missing(dev, test, reason,
3924                                    incompatible_roles=False):
3925    run_dpp_proto_init(dev, 0, test, mutual=True,
3926                       incompatible_roles=incompatible_roles)
3927    if reason is None:
3928        if incompatible_roles:
3929            ev = dev[0].wait_event(["DPP-NOT-COMPATIBLE"], timeout=5)
3930            if ev is None:
3931                raise Exception("DPP-NOT-COMPATIBLE not reported")
3932        time.sleep(0.1)
3933        return
3934    wait_dpp_fail(dev[1], reason)
3935    ev = dev[0].wait_event(["DPP-RX"], timeout=1)
3936    if ev is None or "type=0" not in ev:
3937        raise Exception("DPP Authentication Request not seen")
3938    ev = dev[0].wait_event(["DPP-RX"], timeout=0.1)
3939    if ev is not None:
3940        raise Exception("Unexpected DPP message seen")
3941
3942def test_dpp_proto_auth_resp_no_status(dev, apdev):
3943    """DPP protocol testing - no Status in Auth Resp"""
3944    run_dpp_proto_auth_resp_missing(dev, 16, "Missing or invalid required DPP Status attribute")
3945
3946def test_dpp_proto_auth_resp_status_no_status(dev, apdev):
3947    """DPP protocol testing - no Status in Auth Resp(status)"""
3948    run_dpp_proto_auth_resp_missing(dev, 16,
3949                                    "Missing or invalid required DPP Status attribute",
3950                                    incompatible_roles=True)
3951
3952def test_dpp_proto_auth_resp_invalid_status(dev, apdev):
3953    """DPP protocol testing - invalid Status in Auth Resp"""
3954    run_dpp_proto_auth_resp_missing(dev, 74, "Responder reported failure")
3955
3956def test_dpp_proto_auth_resp_no_r_bootstrap_key(dev, apdev):
3957    """DPP protocol testing - no R-bootstrap key in Auth Resp"""
3958    run_dpp_proto_auth_resp_missing(dev, 17, "Missing or invalid required Responder Bootstrapping Key Hash attribute")
3959
3960def test_dpp_proto_auth_resp_status_no_r_bootstrap_key(dev, apdev):
3961    """DPP protocol testing - no R-bootstrap key in Auth Resp(status)"""
3962    run_dpp_proto_auth_resp_missing(dev, 17,
3963                                    "Missing or invalid required Responder Bootstrapping Key Hash attribute",
3964                                    incompatible_roles=True)
3965
3966def test_dpp_proto_auth_resp_invalid_r_bootstrap_key(dev, apdev):
3967    """DPP protocol testing - invalid R-bootstrap key in Auth Resp"""
3968    run_dpp_proto_auth_resp_missing(dev, 70, "Unexpected Responder Bootstrapping Key Hash value")
3969
3970def test_dpp_proto_auth_resp_status_invalid_r_bootstrap_key(dev, apdev):
3971    """DPP protocol testing - invalid R-bootstrap key in Auth Resp(status)"""
3972    run_dpp_proto_auth_resp_missing(dev, 70,
3973                                    "Unexpected Responder Bootstrapping Key Hash value",
3974                                    incompatible_roles=True)
3975
3976def test_dpp_proto_auth_resp_no_i_bootstrap_key(dev, apdev):
3977    """DPP protocol testing - no I-bootstrap key in Auth Resp"""
3978    run_dpp_proto_auth_resp_missing(dev, 18, None)
3979
3980def test_dpp_proto_auth_resp_status_no_i_bootstrap_key(dev, apdev):
3981    """DPP protocol testing - no I-bootstrap key in Auth Resp(status)"""
3982    run_dpp_proto_auth_resp_missing(dev, 18, None, incompatible_roles=True)
3983
3984def test_dpp_proto_auth_resp_invalid_i_bootstrap_key(dev, apdev):
3985    """DPP protocol testing - invalid I-bootstrap key in Auth Resp"""
3986    run_dpp_proto_auth_resp_missing(dev, 71, "Initiator Bootstrapping Key Hash attribute did not match")
3987
3988def test_dpp_proto_auth_resp_status_invalid_i_bootstrap_key(dev, apdev):
3989    """DPP protocol testing - invalid I-bootstrap key in Auth Resp(status)"""
3990    run_dpp_proto_auth_resp_missing(dev, 71,
3991                                    "Initiator Bootstrapping Key Hash attribute did not match",
3992                                    incompatible_roles=True)
3993
3994def test_dpp_proto_auth_resp_no_r_proto_key(dev, apdev):
3995    """DPP protocol testing - no R-Proto Key in Auth Resp"""
3996    run_dpp_proto_auth_resp_missing(dev, 19, "Missing required Responder Protocol Key attribute")
3997
3998def test_dpp_proto_auth_resp_invalid_r_proto_key(dev, apdev):
3999    """DPP protocol testing - invalid R-Proto Key in Auth Resp"""
4000    run_dpp_proto_auth_resp_missing(dev, 67, "Invalid Responder Protocol Key")
4001
4002def test_dpp_proto_auth_resp_no_r_nonce(dev, apdev):
4003    """DPP protocol testing - no R-nonce in Auth Resp"""
4004    run_dpp_proto_auth_resp_missing(dev, 20, "Missing or invalid R-nonce")
4005
4006def test_dpp_proto_auth_resp_no_i_nonce(dev, apdev):
4007    """DPP protocol testing - no I-nonce in Auth Resp"""
4008    run_dpp_proto_auth_resp_missing(dev, 21, "Missing or invalid I-nonce")
4009
4010def test_dpp_proto_auth_resp_status_no_i_nonce(dev, apdev):
4011    """DPP protocol testing - no I-nonce in Auth Resp(status)"""
4012    run_dpp_proto_auth_resp_missing(dev, 21, "Missing or invalid I-nonce",
4013                                    incompatible_roles=True)
4014
4015def test_dpp_proto_auth_resp_no_r_capab(dev, apdev):
4016    """DPP protocol testing - no R-capab in Auth Resp"""
4017    run_dpp_proto_auth_resp_missing(dev, 22, "Missing or invalid R-capabilities")
4018
4019def test_dpp_proto_auth_resp_no_r_auth(dev, apdev):
4020    """DPP protocol testing - no R-auth in Auth Resp"""
4021    run_dpp_proto_auth_resp_missing(dev, 23, "Missing or invalid Secondary Wrapped Data")
4022
4023def test_dpp_proto_auth_resp_no_wrapped_data(dev, apdev):
4024    """DPP protocol testing - no Wrapped Data in Auth Resp"""
4025    run_dpp_proto_auth_resp_missing(dev, 24, "Missing or invalid required Wrapped Data attribute")
4026
4027def test_dpp_proto_auth_resp_i_nonce_mismatch(dev, apdev):
4028    """DPP protocol testing - I-nonce mismatch in Auth Resp"""
4029    run_dpp_proto_init(dev, 0, 30, mutual=True)
4030    wait_dpp_fail(dev[1], "I-nonce mismatch")
4031    ev = dev[0].wait_event(["DPP-RX"], timeout=1)
4032    if ev is None or "type=0" not in ev:
4033        raise Exception("DPP Authentication Request not seen")
4034    ev = dev[0].wait_event(["DPP-RX"], timeout=0.1)
4035    if ev is not None:
4036        raise Exception("Unexpected DPP message seen")
4037
4038def test_dpp_proto_auth_resp_incompatible_r_capab(dev, apdev):
4039    """DPP protocol testing - Incompatible R-capab in Auth Resp"""
4040    run_dpp_proto_init(dev, 0, 31, mutual=True)
4041    wait_dpp_fail(dev[1], "Unexpected role in R-capabilities 0x02")
4042    wait_dpp_fail(dev[0], "Peer reported incompatible R-capab role")
4043
4044def test_dpp_proto_auth_resp_r_auth_mismatch(dev, apdev):
4045    """DPP protocol testing - R-auth mismatch in Auth Resp"""
4046    run_dpp_proto_init(dev, 0, 32, mutual=True)
4047    wait_dpp_fail(dev[1], "Mismatching Responder Authenticating Tag")
4048    wait_dpp_fail(dev[0], "Peer reported authentication failure")
4049
4050def test_dpp_proto_auth_resp_r_auth_mismatch_failure(dev, apdev):
4051    """DPP protocol testing - Auth Conf RX processing failure"""
4052    with alloc_fail(dev[0], 1, "dpp_auth_conf_rx_failure"):
4053        run_dpp_proto_init(dev, 0, 32, mutual=True)
4054        wait_dpp_fail(dev[0], "Authentication failed")
4055
4056def test_dpp_proto_auth_resp_r_auth_mismatch_failure2(dev, apdev):
4057    """DPP protocol testing - Auth Conf RX processing failure 2"""
4058    with fail_test(dev[0], 1, "dpp_auth_conf_rx_failure"):
4059        run_dpp_proto_init(dev, 0, 32, mutual=True)
4060        wait_dpp_fail(dev[0], "AES-SIV decryption failed")
4061
4062def run_dpp_proto_auth_conf_missing(dev, test, reason):
4063    run_dpp_proto_init(dev, 1, test, mutual=True)
4064    if reason is None:
4065        time.sleep(0.1)
4066        return
4067    wait_dpp_fail(dev[0], reason)
4068
4069def test_dpp_proto_auth_conf_no_status(dev, apdev):
4070    """DPP protocol testing - no Status in Auth Conf"""
4071    run_dpp_proto_auth_conf_missing(dev, 25, "Missing or invalid required DPP Status attribute")
4072
4073def test_dpp_proto_auth_conf_invalid_status(dev, apdev):
4074    """DPP protocol testing - invalid Status in Auth Conf"""
4075    run_dpp_proto_auth_conf_missing(dev, 75, "Authentication failed")
4076
4077def test_dpp_proto_auth_conf_no_r_bootstrap_key(dev, apdev):
4078    """DPP protocol testing - no R-bootstrap key in Auth Conf"""
4079    run_dpp_proto_auth_conf_missing(dev, 26, "Missing or invalid required Responder Bootstrapping Key Hash attribute")
4080
4081def test_dpp_proto_auth_conf_invalid_r_bootstrap_key(dev, apdev):
4082    """DPP protocol testing - invalid R-bootstrap key in Auth Conf"""
4083    run_dpp_proto_auth_conf_missing(dev, 72, "Responder Bootstrapping Key Hash mismatch")
4084
4085def test_dpp_proto_auth_conf_no_i_bootstrap_key(dev, apdev):
4086    """DPP protocol testing - no I-bootstrap key in Auth Conf"""
4087    run_dpp_proto_auth_conf_missing(dev, 27, "Missing Initiator Bootstrapping Key Hash attribute")
4088
4089def test_dpp_proto_auth_conf_invalid_i_bootstrap_key(dev, apdev):
4090    """DPP protocol testing - invalid I-bootstrap key in Auth Conf"""
4091    run_dpp_proto_auth_conf_missing(dev, 73, "Initiator Bootstrapping Key Hash mismatch")
4092
4093def test_dpp_proto_auth_conf_no_i_auth(dev, apdev):
4094    """DPP protocol testing - no I-Auth in Auth Conf"""
4095    run_dpp_proto_auth_conf_missing(dev, 28, "Missing or invalid Initiator Authenticating Tag")
4096
4097def test_dpp_proto_auth_conf_no_wrapped_data(dev, apdev):
4098    """DPP protocol testing - no Wrapped Data in Auth Conf"""
4099    run_dpp_proto_auth_conf_missing(dev, 29, "Missing or invalid required Wrapped Data attribute")
4100
4101def test_dpp_proto_auth_conf_i_auth_mismatch(dev, apdev):
4102    """DPP protocol testing - I-auth mismatch in Auth Conf"""
4103    run_dpp_proto_init(dev, 1, 33, mutual=True)
4104    wait_dpp_fail(dev[0], "Mismatching Initiator Authenticating Tag")
4105
4106def test_dpp_proto_auth_conf_replaced_by_resp(dev, apdev):
4107    """DPP protocol testing - Auth Conf replaced by Resp"""
4108    run_dpp_proto_init(dev, 1, 65, mutual=True)
4109    wait_dpp_fail(dev[0], "Unexpected Authentication Response")
4110
4111def run_dpp_proto_conf_req_missing(dev, test, reason):
4112    res = run_dpp_proto_init(dev, 0, test)
4113    wait_dpp_fail(dev[1], reason)
4114    return res
4115
4116def test_dpp_proto_conf_req_no_e_nonce(dev, apdev):
4117    """DPP protocol testing - no E-nonce in Conf Req"""
4118    res = run_dpp_proto_conf_req_missing(dev, 51,
4119                                         "Missing or invalid Enrollee Nonce attribute")
4120    # Verify that the DPP session has been cleared on failure during GAS request
4121    # handling.
4122    dev[0].set("dpp_test", "0")
4123    dev[1].dpp_listen(freq=2412)
4124    id0 = dev[1].dpp_bootstrap_gen(chan="81/1", mac=True)
4125    uri0 = dev[1].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
4126    dev[0].dpp_auth_init(uri=uri0)
4127    wait_auth_success(dev[1], dev[0])
4128
4129def test_dpp_proto_conf_req_invalid_e_nonce(dev, apdev):
4130    """DPP protocol testing - invalid E-nonce in Conf Req"""
4131    run_dpp_proto_conf_req_missing(dev, 83,
4132                                   "Missing or invalid Enrollee Nonce attribute")
4133
4134def test_dpp_proto_conf_req_no_config_attr_obj(dev, apdev):
4135    """DPP protocol testing - no Config Attr Obj in Conf Req"""
4136    run_dpp_proto_conf_req_missing(dev, 52,
4137                                   "Missing or invalid Config Attributes attribute")
4138
4139def test_dpp_proto_conf_req_invalid_config_attr_obj(dev, apdev):
4140    """DPP protocol testing - invalid Config Attr Obj in Conf Req"""
4141    run_dpp_proto_conf_req_missing(dev, 76,
4142                                   "Unsupported wi-fi_tech")
4143
4144def test_dpp_proto_conf_req_no_wrapped_data(dev, apdev):
4145    """DPP protocol testing - no Wrapped Data in Conf Req"""
4146    run_dpp_proto_conf_req_missing(dev, 53,
4147                                   "Missing or invalid required Wrapped Data attribute")
4148
4149def run_dpp_proto_conf_resp_missing(dev, test, reason):
4150    run_dpp_proto_init(dev, 1, test)
4151    wait_dpp_fail(dev[0], reason)
4152
4153def test_dpp_proto_conf_resp_no_e_nonce(dev, apdev):
4154    """DPP protocol testing - no E-nonce in Conf Resp"""
4155    run_dpp_proto_conf_resp_missing(dev, 54,
4156                                    "Missing or invalid Enrollee Nonce attribute")
4157
4158def test_dpp_proto_conf_resp_no_config_obj(dev, apdev):
4159    """DPP protocol testing - no Config Object in Conf Resp"""
4160    run_dpp_proto_conf_resp_missing(dev, 55,
4161                                    "Missing required Configuration Object attribute")
4162
4163def test_dpp_proto_conf_resp_no_status(dev, apdev):
4164    """DPP protocol testing - no Status in Conf Resp"""
4165    run_dpp_proto_conf_resp_missing(dev, 56,
4166                                    "Missing or invalid required DPP Status attribute")
4167
4168def test_dpp_proto_conf_resp_no_wrapped_data(dev, apdev):
4169    """DPP protocol testing - no Wrapped Data in Conf Resp"""
4170    run_dpp_proto_conf_resp_missing(dev, 57,
4171                                    "Missing or invalid required Wrapped Data attribute")
4172
4173def test_dpp_proto_conf_resp_invalid_status(dev, apdev):
4174    """DPP protocol testing - invalid Status in Conf Resp"""
4175    run_dpp_proto_conf_resp_missing(dev, 58,
4176                                    "Configurator rejected configuration")
4177
4178def test_dpp_proto_conf_resp_e_nonce_mismatch(dev, apdev):
4179    """DPP protocol testing - E-nonce mismatch in Conf Resp"""
4180    run_dpp_proto_conf_resp_missing(dev, 59,
4181                                    "Enrollee Nonce mismatch")
4182
4183def test_dpp_proto_stop_at_auth_req(dev, apdev):
4184    """DPP protocol testing - stop when receiving Auth Req"""
4185    run_dpp_proto_init(dev, 0, 87)
4186    ev = dev[1].wait_event(["DPP-AUTH-INIT-FAILED"], timeout=5)
4187    if ev is None:
4188        raise Exception("Authentication init failure not reported")
4189
4190def test_dpp_proto_stop_at_auth_resp(dev, apdev):
4191    """DPP protocol testing - stop when receiving Auth Resp"""
4192    uri0, role, configurator, conf, own = run_dpp_proto_init(dev, 1, 88)
4193
4194    ev = dev[1].wait_event(["DPP-TX "], timeout=5)
4195    if ev is None:
4196        raise Exception("Auth Req TX not seen")
4197
4198    ev = dev[0].wait_event(["DPP-TX "], timeout=5)
4199    if ev is None:
4200        raise Exception("Auth Resp TX not seen")
4201
4202    ev = dev[1].wait_event(["DPP-TX "], timeout=0.1)
4203    if ev is not None:
4204        raise Exception("Unexpected Auth Conf TX")
4205
4206    ev = dev[0].wait_event(["DPP-FAIL"], timeout=2)
4207    if ev is None or "No Auth Confirm received" not in ev:
4208        raise Exception("DPP-FAIL for missing Auth Confirm not reported")
4209    time.sleep(0.1)
4210
4211    # Try again without special testing behavior to confirm Responder is able
4212    # to accept a new provisioning attempt.
4213    dev[1].set("dpp_test", "0")
4214    dev[1].dpp_auth_init(uri=uri0, role=role, configurator=configurator,
4215                         conf=conf, own=own)
4216    wait_auth_success(dev[0], dev[1])
4217
4218def test_dpp_proto_stop_at_auth_conf(dev, apdev):
4219    """DPP protocol testing - stop when receiving Auth Conf"""
4220    run_dpp_proto_init(dev, 0, 89, init_enrollee=True)
4221    ev = dev[1].wait_event(["GAS-QUERY-START"], timeout=10)
4222    if ev is None:
4223        raise Exception("Enrollee did not start GAS")
4224    ev = dev[1].wait_event(["GAS-QUERY-DONE"], timeout=10)
4225    if ev is None:
4226        raise Exception("Enrollee did not time out GAS")
4227    if "result=TIMEOUT" not in ev:
4228        raise Exception("Unexpected GAS result: " + ev)
4229
4230def test_dpp_proto_stop_at_auth_conf_tx(dev, apdev):
4231    """DPP protocol testing - stop when transmitting Auth Conf (Registrar)"""
4232    run_dpp_proto_init(dev, 1, 89, init_enrollee=True)
4233    wait_auth_success(dev[0], dev[1], timeout=10)
4234    ev = dev[1].wait_event(["GAS-QUERY-START"], timeout=0.1)
4235    if ev is not None:
4236        raise Exception("Unexpected GAS query")
4237
4238    # There is currently no timeout on GAS server side, so no event to wait for
4239    # in this case.
4240
4241def test_dpp_proto_stop_at_auth_conf_tx2(dev, apdev):
4242    """DPP protocol testing - stop when transmitting Auth Conf (Enrollee)"""
4243    run_dpp_proto_init(dev, 1, 89)
4244    wait_auth_success(dev[0], dev[1], timeout=10)
4245
4246    ev = dev[0].wait_event(["GAS-QUERY-DONE"], timeout=5)
4247    if ev is None or "result=TIMEOUT" not in ev:
4248        raise Exception("GAS query did not time out")
4249
4250def test_dpp_proto_stop_at_conf_req(dev, apdev):
4251    """DPP protocol testing - stop when receiving Auth Req"""
4252    run_dpp_proto_init(dev, 1, 90)
4253    ev = dev[0].wait_event(["GAS-QUERY-START"], timeout=10)
4254    if ev is None:
4255        raise Exception("Enrollee did not start GAS")
4256    ev = dev[0].wait_event(["GAS-QUERY-DONE"], timeout=10)
4257    if ev is None:
4258        raise Exception("Enrollee did not time out GAS")
4259    if "result=TIMEOUT" not in ev:
4260        raise Exception("Unexpected GAS result: " + ev)
4261
4262def run_dpp_proto_init_pkex(dev, test_dev, test):
4263    check_dpp_capab(dev[0])
4264    check_dpp_capab(dev[1])
4265    dev[test_dev].set("dpp_test", str(test))
4266    dev[0].dpp_pkex_resp(2437, identifier="test", code="secret")
4267    dev[1].dpp_pkex_init(identifier="test", code="secret")
4268
4269def test_dpp_proto_after_wrapped_data_pkex_cr_req(dev, apdev):
4270    """DPP protocol testing - attribute after Wrapped Data in PKEX CR Req"""
4271    run_dpp_proto_init_pkex(dev, 1, 4)
4272    ev = dev[0].wait_event(["DPP-RX"], timeout=5)
4273    if ev is None or ("type=7" not in ev and "type=18" not in ev):
4274        raise Exception("PKEX Exchange Request not seen")
4275    ev = dev[0].wait_event(["DPP-RX"], timeout=5)
4276    if ev is None or "type=9" not in ev:
4277        raise Exception("PKEX Commit-Reveal Request not seen")
4278    if "ignore=invalid-attributes" not in ev:
4279        raise Exception("Unexpected RX info: " + ev)
4280
4281def test_dpp_proto_after_wrapped_data_pkex_cr_resp(dev, apdev):
4282    """DPP protocol testing - attribute after Wrapped Data in PKEX CR Resp"""
4283    run_dpp_proto_init_pkex(dev, 0, 5)
4284    ev = dev[1].wait_event(["DPP-RX"], timeout=5)
4285    if ev is None or "type=8" not in ev:
4286        raise Exception("PKEX Exchange Response not seen")
4287    ev = dev[1].wait_event(["DPP-RX"], timeout=5)
4288    if ev is None or "type=10" not in ev:
4289        raise Exception("PKEX Commit-Reveal Response not seen")
4290    if "ignore=invalid-attributes" not in ev:
4291        raise Exception("Unexpected RX info: " + ev)
4292
4293def run_dpp_proto_pkex_req_missing(dev, test, reason):
4294    run_dpp_proto_init_pkex(dev, 1, test)
4295    wait_dpp_fail(dev[0], reason)
4296
4297def run_dpp_proto_pkex_resp_missing(dev, test, reason):
4298    run_dpp_proto_init_pkex(dev, 0, test)
4299    wait_dpp_fail(dev[1], reason)
4300
4301def test_dpp_proto_pkex_exchange_req_no_finite_cyclic_group(dev, apdev):
4302    """DPP protocol testing - no Finite Cyclic Group in PKEX Exchange Request"""
4303    run_dpp_proto_pkex_req_missing(dev, 34,
4304                                   "Missing or invalid Finite Cyclic Group attribute")
4305
4306def test_dpp_proto_pkex_exchange_req_no_encrypted_key(dev, apdev):
4307    """DPP protocol testing - no Encrypted Key in PKEX Exchange Request"""
4308    run_dpp_proto_pkex_req_missing(dev, 35,
4309                                   "Missing Encrypted Key attribute")
4310
4311def test_dpp_proto_pkex_exchange_resp_no_status(dev, apdev):
4312    """DPP protocol testing - no Status in PKEX Exchange Response"""
4313    run_dpp_proto_pkex_resp_missing(dev, 36, "No DPP Status attribute")
4314
4315def test_dpp_proto_pkex_exchange_resp_no_encrypted_key(dev, apdev):
4316    """DPP protocol testing - no Encrypted Key in PKEX Exchange Response"""
4317    run_dpp_proto_pkex_resp_missing(dev, 37, "Missing Encrypted Key attribute")
4318
4319def test_dpp_proto_pkex_cr_req_no_bootstrap_key(dev, apdev):
4320    """DPP protocol testing - no Bootstrap Key in PKEX Commit-Reveal Request"""
4321    run_dpp_proto_pkex_req_missing(dev, 38,
4322                                   "No valid peer bootstrapping key found")
4323
4324def test_dpp_proto_pkex_cr_req_no_i_auth_tag(dev, apdev):
4325    """DPP protocol testing - no I-Auth Tag in PKEX Commit-Reveal Request"""
4326    run_dpp_proto_pkex_req_missing(dev, 39, "No valid u (I-Auth tag) found")
4327
4328def test_dpp_proto_pkex_cr_req_no_wrapped_data(dev, apdev):
4329    """DPP protocol testing - no Wrapped Data in PKEX Commit-Reveal Request"""
4330    run_dpp_proto_pkex_req_missing(dev, 40, "Missing or invalid required Wrapped Data attribute")
4331
4332def test_dpp_proto_pkex_cr_resp_no_bootstrap_key(dev, apdev):
4333    """DPP protocol testing - no Bootstrap Key in PKEX Commit-Reveal Response"""
4334    run_dpp_proto_pkex_resp_missing(dev, 41,
4335                                   "No valid peer bootstrapping key found")
4336
4337def test_dpp_proto_pkex_cr_resp_no_r_auth_tag(dev, apdev):
4338    """DPP protocol testing - no R-Auth Tag in PKEX Commit-Reveal Response"""
4339    run_dpp_proto_pkex_resp_missing(dev, 42, "No valid v (R-Auth tag) found")
4340
4341def test_dpp_proto_pkex_cr_resp_no_wrapped_data(dev, apdev):
4342    """DPP protocol testing - no Wrapped Data in PKEX Commit-Reveal Response"""
4343    run_dpp_proto_pkex_resp_missing(dev, 43, "Missing or invalid required Wrapped Data attribute")
4344
4345def test_dpp_proto_pkex_exchange_req_invalid_encrypted_key(dev, apdev):
4346    """DPP protocol testing - invalid Encrypted Key in PKEX Exchange Request"""
4347    run_dpp_proto_pkex_req_missing(dev, 44,
4348                                   "Invalid Encrypted Key value")
4349
4350def test_dpp_proto_pkex_exchange_resp_invalid_encrypted_key(dev, apdev):
4351    """DPP protocol testing - invalid Encrypted Key in PKEX Exchange Response"""
4352    run_dpp_proto_pkex_resp_missing(dev, 45,
4353                                    "Invalid Encrypted Key value")
4354
4355def test_dpp_proto_pkex_exchange_resp_invalid_status(dev, apdev):
4356    """DPP protocol testing - invalid Status in PKEX Exchange Response"""
4357    run_dpp_proto_pkex_resp_missing(dev, 46,
4358                                    "PKEX failed (peer indicated failure)")
4359
4360def test_dpp_proto_pkex_cr_req_invalid_bootstrap_key(dev, apdev):
4361    """DPP protocol testing - invalid Bootstrap Key in PKEX Commit-Reveal Request"""
4362    run_dpp_proto_pkex_req_missing(dev, 47,
4363                                   "Peer bootstrapping key is invalid")
4364
4365def test_dpp_proto_pkex_cr_resp_invalid_bootstrap_key(dev, apdev):
4366    """DPP protocol testing - invalid Bootstrap Key in PKEX Commit-Reveal Response"""
4367    run_dpp_proto_pkex_resp_missing(dev, 48,
4368                                    "Peer bootstrapping key is invalid")
4369
4370def test_dpp_proto_pkex_cr_req_i_auth_tag_mismatch(dev, apdev):
4371    """DPP protocol testing - I-auth tag mismatch in PKEX Commit-Reveal Request"""
4372    run_dpp_proto_pkex_req_missing(dev, 49, "No valid u (I-Auth tag) found")
4373
4374def test_dpp_proto_pkex_cr_resp_r_auth_tag_mismatch(dev, apdev):
4375    """DPP protocol testing - R-auth tag mismatch in PKEX Commit-Reveal Response"""
4376    run_dpp_proto_pkex_resp_missing(dev, 50, "No valid v (R-Auth tag) found")
4377
4378def test_dpp_proto_stop_at_pkex_exchange_resp(dev, apdev):
4379    """DPP protocol testing - stop when receiving PKEX Exchange Response"""
4380    run_dpp_proto_init_pkex(dev, 1, 84)
4381
4382    ev = dev[1].wait_event(["DPP-TX "], timeout=5)
4383    if ev is None:
4384        raise Exception("PKEX Exchange Req TX not seen")
4385
4386    ev = dev[0].wait_event(["DPP-TX "], timeout=5)
4387    if ev is None:
4388        raise Exception("PKEX Exchange Resp not seen")
4389
4390    ev = dev[1].wait_event(["DPP-TX "], timeout=0.1)
4391    if ev is not None:
4392        raise Exception("Unexpected PKEX CR Req TX")
4393
4394def test_dpp_proto_stop_at_pkex_cr_req(dev, apdev):
4395    """DPP protocol testing - stop when receiving PKEX CR Request"""
4396    run_dpp_proto_init_pkex(dev, 0, 85)
4397
4398    ev = dev[1].wait_event(["DPP-TX "], timeout=5)
4399    if ev is None:
4400        raise Exception("PKEX Exchange Req TX not seen")
4401
4402    ev = dev[0].wait_event(["DPP-TX "], timeout=5)
4403    if ev is None:
4404        raise Exception("PKEX Exchange Resp not seen")
4405
4406    ev = dev[1].wait_event(["DPP-TX "], timeout=5)
4407    if ev is None:
4408        raise Exception("PKEX CR Req TX not seen")
4409
4410    ev = dev[0].wait_event(["DPP-TX "], timeout=0.1)
4411    if ev is not None:
4412        raise Exception("Unexpected PKEX CR Resp TX")
4413
4414def test_dpp_proto_stop_at_pkex_cr_resp(dev, apdev):
4415    """DPP protocol testing - stop when receiving PKEX CR Response"""
4416    run_dpp_proto_init_pkex(dev, 1, 86)
4417
4418    ev = dev[1].wait_event(["DPP-TX "], timeout=5)
4419    if ev is None:
4420        raise Exception("PKEX Exchange Req TX not seen")
4421
4422    ev = dev[0].wait_event(["DPP-TX "], timeout=5)
4423    if ev is None:
4424        raise Exception("PKEX Exchange Resp not seen")
4425
4426    ev = dev[1].wait_event(["DPP-TX "], timeout=5)
4427    if ev is None:
4428        raise Exception("PKEX CR Req TX not seen")
4429
4430    ev = dev[0].wait_event(["DPP-TX "], timeout=5)
4431    if ev is None:
4432        raise Exception("PKEX CR Resp TX not seen")
4433
4434    ev = dev[1].wait_event(["DPP-TX "], timeout=0.1)
4435    if ev is not None:
4436        raise Exception("Unexpected Auth Req TX")
4437
4438def test_dpp_proto_network_introduction(dev, apdev):
4439    """DPP protocol testing - network introduction"""
4440    check_dpp_capab(dev[0])
4441    check_dpp_capab(dev[1])
4442
4443    params = {"ssid": "dpp",
4444              "wpa": "2",
4445              "wpa_key_mgmt": "DPP",
4446              "ieee80211w": "2",
4447              "rsn_pairwise": "CCMP",
4448              "dpp_connector": params1_ap_connector,
4449              "dpp_csign": params1_csign,
4450              "dpp_netaccesskey": params1_ap_netaccesskey}
4451    try:
4452        hapd = hostapd.add_ap(apdev[0], params)
4453    except:
4454        raise HwsimSkip("DPP not supported")
4455
4456    for test in [60, 61, 80, 82]:
4457        dev[0].set("dpp_test", str(test))
4458        dev[0].connect("dpp", key_mgmt="DPP", scan_freq="2412", ieee80211w="2",
4459                       dpp_csign=params1_csign,
4460                       dpp_connector=params1_sta_connector,
4461                       dpp_netaccesskey=params1_sta_netaccesskey,
4462                       wait_connect=False)
4463
4464        ev = dev[0].wait_event(["DPP-TX "], timeout=10)
4465        if ev is None or "type=5" not in ev:
4466            raise Exception("Peer Discovery Request TX not reported")
4467        ev = dev[0].wait_event(["DPP-TX-STATUS"], timeout=2)
4468        if ev is None or "result=SUCCESS" not in ev:
4469            raise Exception("Peer Discovery Request TX status not reported")
4470
4471        ev = hapd.wait_event(["DPP-RX"], timeout=10)
4472        if ev is None or "type=5" not in ev:
4473            raise Exception("Peer Discovery Request RX not reported")
4474
4475        if test == 80:
4476            ev = dev[0].wait_event(["DPP-INTRO"], timeout=10)
4477            if ev is None:
4478                raise Exception("DPP-INTRO not reported for test 80")
4479            if "status=7" not in ev:
4480                raise Exception("Unexpected result in test 80: " + ev)
4481
4482        dev[0].request("REMOVE_NETWORK all")
4483        dev[0].dump_monitor()
4484        hapd.dump_monitor()
4485    dev[0].set("dpp_test", "0")
4486
4487    for test in [62, 63, 64, 77, 78, 79]:
4488        hapd.set("dpp_test", str(test))
4489        dev[0].connect("dpp", key_mgmt="DPP", scan_freq="2412", ieee80211w="2",
4490                       dpp_csign=params1_csign,
4491                       dpp_connector=params1_sta_connector,
4492                       dpp_netaccesskey=params1_sta_netaccesskey,
4493                       wait_connect=False)
4494
4495        ev = dev[0].wait_event(["DPP-INTRO"], timeout=10)
4496        if ev is None:
4497            raise Exception("Peer introduction result not reported (test %d)" % test)
4498        if test == 77:
4499            if "fail=transaction_id_mismatch" not in ev:
4500                raise Exception("Connector validation failure not reported")
4501        elif test == 78:
4502            if "status=254" not in ev:
4503                raise Exception("Invalid status value not reported")
4504        elif test == 79:
4505            if "fail=peer_connector_validation_failed" not in ev:
4506                raise Exception("Connector validation failure not reported")
4507        elif "status=" in ev:
4508            raise Exception("Unexpected peer introduction result (test %d): " % test + ev)
4509
4510        dev[0].request("REMOVE_NETWORK all")
4511        dev[0].dump_monitor()
4512        hapd.dump_monitor()
4513    hapd.set("dpp_test", "0")
4514
4515    dev[0].connect("dpp", key_mgmt="DPP", scan_freq="2412", ieee80211w="2",
4516                   dpp_csign=params1_csign, dpp_connector=params1_sta_connector,
4517                   dpp_netaccesskey=params1_sta_netaccesskey)
4518
4519def test_dpp_hostapd_auth_conf_timeout(dev, apdev):
4520    """DPP Authentication Confirm timeout in hostapd"""
4521    check_dpp_capab(dev[0])
4522    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured"})
4523    check_dpp_capab(hapd)
4524    id_h = hapd.dpp_bootstrap_gen(chan="81/1", mac=True)
4525    uri_h = hapd.request("DPP_BOOTSTRAP_GET_URI %d" % id_h)
4526    hapd.dpp_listen(2412)
4527    dev[0].set("dpp_test", "88")
4528    dev[0].dpp_auth_init(uri=uri_h)
4529    ev = hapd.wait_event(["DPP-FAIL"], timeout=10)
4530    if ev is None:
4531        raise Exception("DPP-FAIL not reported")
4532    if "No Auth Confirm received" not in ev:
4533        raise Exception("Unexpected failure reason: " + ev)
4534
4535def test_dpp_hostapd_auth_resp_retries(dev, apdev):
4536    """DPP Authentication Response retries in hostapd"""
4537    check_dpp_capab(dev[0])
4538    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured"})
4539    check_dpp_capab(hapd)
4540
4541    hapd.set("dpp_resp_max_tries", "3")
4542    hapd.set("dpp_resp_retry_time", "100")
4543
4544    id_h = hapd.dpp_bootstrap_gen(chan="81/1", mac=True)
4545    uri_h = hapd.request("DPP_BOOTSTRAP_GET_URI %d" % id_h)
4546    id0b = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
4547    uri0b = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0b)
4548    hapd.dpp_listen(2412, qr="mutual")
4549    dev[0].dpp_auth_init(uri=uri_h, own=id0b)
4550
4551    ev = dev[0].wait_event(["DPP-RESPONSE-PENDING"], timeout=5)
4552    if ev is None:
4553        raise Exception("Pending response not reported")
4554    ev = hapd.wait_event(["DPP-SCAN-PEER-QR-CODE"], timeout=5)
4555    if ev is None:
4556        raise Exception("QR Code scan for mutual authentication not requested")
4557
4558    # Stop Initiator from listening to frames to force retransmission of the
4559    # DPP Authentication Response frame with Status=0
4560    dev[0].request("DPP_STOP_LISTEN")
4561
4562    ev = hapd.wait_event(["DPP-TX-STATUS"], timeout=1)
4563    if ev is None:
4564        raise Exception("No TX status reported for response")
4565    time.sleep(0.1)
4566
4567    hapd.dump_monitor()
4568    dev[0].dump_monitor()
4569
4570    id0b = hapd.dpp_qr_code(uri0b)
4571
4572    ev = hapd.wait_event(["DPP-TX "], timeout=5)
4573    if ev is None or "type=1" not in ev:
4574        raise Exception("DPP Authentication Response not sent")
4575    ev = hapd.wait_event(["DPP-TX-STATUS"], timeout=5)
4576    if ev is None:
4577        raise Exception("TX status for DPP Authentication Response not reported")
4578    if "result=FAILED" not in ev:
4579        raise Exception("Unexpected TX status for Authentication Response: " + ev)
4580
4581    ev = hapd.wait_event(["DPP-TX "], timeout=15)
4582    if ev is None or "type=1" not in ev:
4583        raise Exception("DPP Authentication Response retransmission not sent")
4584
4585def test_dpp_qr_code_no_chan_list_unicast(dev, apdev):
4586    """DPP QR Code and no channel list (unicast)"""
4587    run_dpp_qr_code_chan_list(dev, apdev, True, 2417, None)
4588
4589def test_dpp_qr_code_chan_list_unicast(dev, apdev):
4590    """DPP QR Code and 2.4 GHz channels (unicast)"""
4591    run_dpp_qr_code_chan_list(dev, apdev, True, 2417,
4592                              "81/1,81/2,81/3,81/4,81/5,81/6,81/7,81/8,81/9,81/10,81/11,81/12,81/13")
4593
4594def test_dpp_qr_code_chan_list_unicast2(dev, apdev):
4595    """DPP QR Code and 2.4 GHz channels (unicast 2)"""
4596    run_dpp_qr_code_chan_list(dev, apdev, True, 2417,
4597                              "81/1,2,3,4,5,6,7,8,9,10,11,12,13")
4598
4599def test_dpp_qr_code_chan_list_no_peer_unicast(dev, apdev):
4600    """DPP QR Code and channel list and no peer (unicast)"""
4601    run_dpp_qr_code_chan_list(dev, apdev, True, 2417, "81/1,81/6,81/11",
4602                              no_wait=True)
4603    ev = dev[1].wait_event(["DPP-AUTH-INIT-FAILED"], timeout=5)
4604    if ev is None:
4605        raise Exception("Initiation failure not reported")
4606
4607def test_dpp_qr_code_no_chan_list_broadcast(dev, apdev):
4608    """DPP QR Code and no channel list (broadcast)"""
4609    run_dpp_qr_code_chan_list(dev, apdev, False, 2412, None, timeout=20)
4610
4611def test_dpp_qr_code_chan_list_broadcast(dev, apdev):
4612    """DPP QR Code and some 2.4 GHz channels (broadcast)"""
4613    run_dpp_qr_code_chan_list(dev, apdev, False, 2412, "81/1,81/6,81/11",
4614                              timeout=10)
4615
4616def run_dpp_qr_code_chan_list(dev, apdev, unicast, listen_freq, chanlist,
4617                              no_wait=False, timeout=5):
4618    check_dpp_capab(dev[0])
4619    check_dpp_capab(dev[1])
4620    dev[1].set("dpp_init_max_tries", "3")
4621    dev[1].set("dpp_init_retry_time", "100")
4622    dev[1].set("dpp_resp_wait_time", "1000")
4623
4624    logger.info("dev0 displays QR Code")
4625    id0 = dev[0].dpp_bootstrap_gen(chan=chanlist, mac=unicast)
4626    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
4627    logger.info("dev1 scans QR Code and initiates DPP Authentication")
4628    dev[0].dpp_listen(listen_freq)
4629    dev[1].dpp_auth_init(uri=uri0)
4630    if no_wait:
4631        return
4632    wait_auth_success(dev[0], dev[1], timeout=timeout, configurator=dev[1],
4633                      enrollee=dev[0], allow_enrollee_failure=True,
4634                      stop_responder=True)
4635
4636def test_dpp_qr_code_chan_list_no_match(dev, apdev):
4637    """DPP QR Code and no matching supported channel"""
4638    check_dpp_capab(dev[0])
4639    check_dpp_capab(dev[1])
4640    id0 = dev[0].dpp_bootstrap_gen(chan="123/123")
4641    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
4642    dev[1].dpp_auth_init(uri=uri0, expect_fail=True)
4643
4644def test_dpp_pkex_alloc_fail(dev, apdev):
4645    """DPP/PKEX and memory allocation failures"""
4646    check_dpp_capab(dev[0])
4647    check_dpp_capab(dev[1])
4648
4649    tests = [(1, "=dpp_keygen_configurator"),
4650             (1, "base64_gen_encode;dpp_keygen_configurator")]
4651    for count, func in tests:
4652        with alloc_fail(dev[1], count, func):
4653            cmd = "DPP_CONFIGURATOR_ADD"
4654            res = dev[1].request(cmd)
4655            if "FAIL" not in res:
4656                raise Exception("Unexpected DPP_CONFIGURATOR_ADD success")
4657
4658    conf_id = dev[1].dpp_configurator_add()
4659
4660    id0 = None
4661    id1 = None
4662
4663    # Local error cases on the Initiator
4664    tests = [(1, "crypto_ec_key_get_pubkey_point"),
4665             (1, "dpp_alloc_msg;dpp_pkex_build_exchange_req"),
4666             (1, "dpp_alloc_msg;dpp_pkex_build_commit_reveal_req"),
4667             (1, "dpp_alloc_msg;dpp_auth_build_req"),
4668             (1, "dpp_alloc_msg;dpp_auth_build_conf"),
4669             (1, "dpp_bootstrap_key_hash"),
4670             (1, "dpp_auth_init"),
4671             (1, "dpp_alloc_auth"),
4672             (1, "=dpp_auth_resp_rx"),
4673             (1, "dpp_build_conf_start"),
4674             (1, "dpp_build_conf_obj_dpp"),
4675             (2, "dpp_build_conf_obj_dpp"),
4676             (3, "dpp_build_conf_obj_dpp"),
4677             (4, "dpp_build_conf_obj_dpp"),
4678             (5, "dpp_build_conf_obj_dpp"),
4679             (6, "dpp_build_conf_obj_dpp"),
4680             (7, "dpp_build_conf_obj_dpp"),
4681             (8, "dpp_build_conf_obj_dpp"),
4682             (1, "dpp_conf_req_rx"),
4683             (2, "dpp_conf_req_rx"),
4684             (3, "dpp_conf_req_rx"),
4685             (4, "dpp_conf_req_rx"),
4686             (5, "dpp_conf_req_rx"),
4687             (6, "dpp_conf_req_rx"),
4688             (7, "dpp_conf_req_rx"),
4689             (1, "dpp_pkex_init"),
4690             (2, "dpp_pkex_init"),
4691             (3, "dpp_pkex_init"),
4692             (1, "dpp_pkex_derive_z"),
4693             (1, "=dpp_pkex_rx_commit_reveal_resp"),
4694             (1, "crypto_ec_key_get_pubkey_point;dpp_build_jwk"),
4695             (2, "crypto_ec_key_get_pubkey_point;dpp_build_jwk"),
4696             (1, "crypto_ec_key_get_pubkey_point;dpp_auth_init")]
4697    for count, func in tests:
4698        dev[0].request("DPP_STOP_LISTEN")
4699        dev[1].request("DPP_STOP_LISTEN")
4700        dev[0].dump_monitor()
4701        dev[1].dump_monitor()
4702        id0 = dev[0].dpp_pkex_resp(2437, identifier="test", code="secret",
4703                                   use_id=id0)
4704
4705        with alloc_fail(dev[1], count, func):
4706            id1 = dev[1].dpp_pkex_init(identifier="test", code="secret",
4707                                       use_id=id1,
4708                                       extra="conf=sta-dpp configurator=%d" % conf_id,
4709                                       allow_fail=True)
4710            wait_fail_trigger(dev[1], "GET_ALLOC_FAIL", max_iter=100)
4711            ev = dev[0].wait_event(["GAS-QUERY-START"], timeout=0.01)
4712            if ev:
4713                dev[0].request("DPP_STOP_LISTEN")
4714                dev[0].wait_event(["GAS-QUERY-DONE"], timeout=3)
4715
4716    # Local error cases on the Responder
4717    tests = [(1, "crypto_ec_key_get_pubkey_point"),
4718             (1, "dpp_alloc_msg;dpp_pkex_build_exchange_resp"),
4719             (1, "dpp_alloc_msg;dpp_pkex_build_commit_reveal_resp"),
4720             (1, "dpp_alloc_msg;dpp_auth_build_resp"),
4721             (1, "crypto_ec_key_get_pubkey_point;dpp_auth_build_resp_ok"),
4722             (1, "dpp_alloc_auth"),
4723             (1, "=dpp_auth_req_rx"),
4724             (1, "=dpp_auth_conf_rx"),
4725             (1, "json_parse;dpp_parse_jws_prot_hdr"),
4726             (1, "json_get_member_base64url;dpp_parse_jws_prot_hdr"),
4727             (1, "json_get_member_base64url;dpp_parse_jwk"),
4728             (2, "json_get_member_base64url;dpp_parse_jwk"),
4729             (1, "json_parse;dpp_parse_connector"),
4730             (1, "dpp_parse_jwk;dpp_parse_connector"),
4731             (1, "dpp_parse_jwk;dpp_parse_cred_dpp"),
4732             (1, "crypto_ec_key_get_pubkey_point;dpp_check_pubkey_match"),
4733             (1, "base64_gen_decode;dpp_process_signed_connector"),
4734             (1, "dpp_parse_jws_prot_hdr;dpp_process_signed_connector"),
4735             (2, "base64_gen_decode;dpp_process_signed_connector"),
4736             (3, "base64_gen_decode;dpp_process_signed_connector"),
4737             (4, "base64_gen_decode;dpp_process_signed_connector"),
4738             (1, "json_parse;dpp_parse_conf_obj"),
4739             (1, "dpp_conf_resp_rx"),
4740             (1, "=dpp_pkex_derive_z"),
4741             (1, "=dpp_pkex_rx_exchange_req"),
4742             (2, "=dpp_pkex_rx_exchange_req"),
4743             (3, "=dpp_pkex_rx_exchange_req"),
4744             (1, "=dpp_pkex_rx_commit_reveal_req"),
4745             (1, "crypto_ec_key_get_pubkey_point;dpp_pkex_rx_commit_reveal_req"),
4746             (1, "dpp_bootstrap_key_hash")]
4747    for count, func in tests:
4748        dev[0].request("DPP_STOP_LISTEN")
4749        dev[1].request("DPP_STOP_LISTEN")
4750        dev[0].dump_monitor()
4751        dev[1].dump_monitor()
4752        id0 = dev[0].dpp_pkex_resp(2437, identifier="test", code="secret",
4753                                   use_id=id0)
4754
4755        with alloc_fail(dev[0], count, func):
4756            id1 = dev[1].dpp_pkex_init(identifier="test", code="secret",
4757                                       use_id=id1,
4758                                       extra="conf=sta-dpp configurator=%d" % conf_id)
4759            wait_fail_trigger(dev[0], "GET_ALLOC_FAIL", max_iter=100)
4760            ev = dev[0].wait_event(["GAS-QUERY-START"], timeout=0.01)
4761            if ev:
4762                dev[0].request("DPP_STOP_LISTEN")
4763                dev[0].wait_event(["GAS-QUERY-DONE"], timeout=3)
4764
4765def test_dpp_pkex_test_fail(dev, apdev):
4766    """DPP/PKEX and local failures"""
4767    check_dpp_capab(dev[0])
4768    check_dpp_capab(dev[1])
4769
4770    tests = [(1, "dpp_keygen_configurator")]
4771    for count, func in tests:
4772        with fail_test(dev[1], count, func):
4773            cmd = "DPP_CONFIGURATOR_ADD"
4774            res = dev[1].request(cmd)
4775            if "FAIL" not in res:
4776                raise Exception("Unexpected DPP_CONFIGURATOR_ADD success")
4777
4778    tests = [(1, "dpp_keygen")]
4779    for count, func in tests:
4780        with fail_test(dev[1], count, func):
4781            cmd = "DPP_BOOTSTRAP_GEN type=pkex"
4782            res = dev[1].request(cmd)
4783            if "FAIL" not in res:
4784                raise Exception("Unexpected DPP_BOOTSTRAP_GEN success")
4785
4786    conf_id = dev[1].dpp_configurator_add()
4787
4788    id0 = None
4789    id1 = None
4790
4791    # Local error cases on the Initiator
4792    tests = [(1, "aes_siv_encrypt;dpp_auth_build_req"),
4793             (1, "os_get_random;dpp_auth_init"),
4794             (1, "dpp_derive_k1;dpp_auth_init"),
4795             (1, "dpp_hkdf_expand;dpp_derive_k1;dpp_auth_init"),
4796             (1, "dpp_gen_i_auth;dpp_auth_build_conf"),
4797             (1, "aes_siv_encrypt;dpp_auth_build_conf"),
4798             (1, "dpp_derive_k2;dpp_auth_resp_rx"),
4799             (1, "dpp_hkdf_expand;dpp_derive_k2;dpp_auth_resp_rx"),
4800             (1, "dpp_derive_bk_ke;dpp_auth_resp_rx"),
4801             (1, "dpp_hkdf_expand;dpp_derive_bk_ke;dpp_auth_resp_rx"),
4802             (1, "dpp_gen_r_auth;dpp_auth_resp_rx"),
4803             (1, "aes_siv_encrypt;dpp_build_conf_resp"),
4804             (1, "dpp_pkex_derive_Qi;dpp_pkex_build_exchange_req"),
4805             (1, "aes_siv_encrypt;dpp_pkex_build_commit_reveal_req"),
4806             (1, "hmac_sha256_vector;dpp_pkex_rx_exchange_resp"),
4807             (1, "aes_siv_decrypt;dpp_pkex_rx_commit_reveal_resp"),
4808             (1, "hmac_sha256_vector;dpp_pkex_rx_commit_reveal_resp"),
4809             (1, "dpp_bootstrap_key_hash")]
4810    for count, func in tests:
4811        dev[0].request("DPP_STOP_LISTEN")
4812        dev[1].request("DPP_STOP_LISTEN")
4813        dev[0].dump_monitor()
4814        dev[1].dump_monitor()
4815        id0 = dev[0].dpp_pkex_resp(2437, identifier="test", code="secret",
4816                                   use_id=id0)
4817
4818        with fail_test(dev[1], count, func):
4819            id1 = dev[1].dpp_pkex_init(identifier="test", code="secret",
4820                                       use_id=id1,
4821                                       extra="conf=sta-dpp configurator=%d" % conf_id,
4822                                       allow_fail=True)
4823            wait_fail_trigger(dev[1], "GET_FAIL", max_iter=100)
4824            ev = dev[0].wait_event(["GAS-QUERY-START"], timeout=0.01)
4825            if ev:
4826                dev[0].request("DPP_STOP_LISTEN")
4827                dev[0].wait_event(["GAS-QUERY-DONE"], timeout=3)
4828
4829    # Local error cases on the Responder
4830    tests = [(1, "aes_siv_encrypt;dpp_auth_build_resp"),
4831             (1, "aes_siv_encrypt;dpp_auth_build_resp;dpp_auth_build_resp_ok"),
4832             (1, "os_get_random;dpp_build_conf_req"),
4833             (1, "aes_siv_encrypt;dpp_build_conf_req"),
4834             (1, "os_get_random;dpp_auth_build_resp_ok"),
4835             (1, "dpp_derive_k2;dpp_auth_build_resp_ok"),
4836             (1, "dpp_derive_bk_ke;dpp_auth_build_resp_ok"),
4837             (1, "dpp_gen_r_auth;dpp_auth_build_resp_ok"),
4838             (1, "aes_siv_encrypt;dpp_auth_build_resp_ok"),
4839             (1, "dpp_derive_k1;dpp_auth_req_rx"),
4840             (1, "aes_siv_decrypt;dpp_auth_req_rx"),
4841             (1, "aes_siv_decrypt;dpp_auth_conf_rx"),
4842             (1, "dpp_gen_i_auth;dpp_auth_conf_rx"),
4843             (1, "dpp_check_pubkey_match"),
4844             (1, "aes_siv_decrypt;dpp_conf_resp_rx"),
4845             (1, "hmac_sha256_kdf;dpp_pkex_derive_z"),
4846             (1, "dpp_pkex_derive_Qi;dpp_pkex_rx_exchange_req"),
4847             (1, "dpp_pkex_derive_Qr;dpp_pkex_rx_exchange_req"),
4848             (1, "aes_siv_encrypt;dpp_pkex_build_commit_reveal_resp"),
4849             (1, "aes_siv_decrypt;dpp_pkex_rx_commit_reveal_req"),
4850             (1, "hmac_sha256_vector;dpp_pkex_rx_commit_reveal_req"),
4851             (2, "hmac_sha256_vector;dpp_pkex_rx_commit_reveal_req")]
4852    for count, func in tests:
4853        dev[0].request("DPP_STOP_LISTEN")
4854        dev[1].request("DPP_STOP_LISTEN")
4855        dev[0].dump_monitor()
4856        dev[1].dump_monitor()
4857        id0 = dev[0].dpp_pkex_resp(2437, identifier="test", code="secret",
4858                                   use_id=id0)
4859
4860        with fail_test(dev[0], count, func):
4861            id1 = dev[1].dpp_pkex_init(identifier="test", code="secret",
4862                                       use_id=id1,
4863                                       extra="conf=sta-dpp configurator=%d" % conf_id)
4864            wait_fail_trigger(dev[0], "GET_FAIL", max_iter=100)
4865            ev = dev[0].wait_event(["GAS-QUERY-START"], timeout=0.01)
4866            if ev:
4867                dev[0].request("DPP_STOP_LISTEN")
4868                dev[0].wait_event(["GAS-QUERY-DONE"], timeout=3)
4869
4870def test_dpp_keygen_configurator_error(dev, apdev):
4871    """DPP Configurator keygen error case"""
4872    check_dpp_capab(dev[0])
4873    if "FAIL" not in dev[0].request("DPP_CONFIGURATOR_ADD curve=unknown"):
4874        raise Exception("Unexpected success of invalid DPP_CONFIGURATOR_ADD")
4875
4876def rx_process_frame(dev, msg=None):
4877    if msg is None:
4878        msg = dev.mgmt_rx()
4879    if msg is None:
4880        raise Exception("No management frame RX reported")
4881    if "OK" not in dev.request("MGMT_RX_PROCESS freq={} datarate={} ssi_signal={} frame={}".format(
4882        msg['freq'], msg['datarate'], msg['ssi_signal'], binascii.hexlify(msg['frame']).decode())):
4883        raise Exception("MGMT_RX_PROCESS failed")
4884    return msg
4885
4886def wait_auth_success(responder, initiator, configurator=None, enrollee=None,
4887                      allow_enrollee_failure=False,
4888                      allow_configurator_failure=False,
4889                      require_configurator_failure=False,
4890                      timeout=5, stop_responder=False, stop_initiator=False):
4891    res = {}
4892    ev = responder.wait_event(["DPP-AUTH-SUCCESS", "DPP-FAIL",
4893                               "MGMT-RX"], timeout=timeout)
4894    if ev and "MGMT-RX" in ev:
4895        res['responder-mgmt-rx'] = ev
4896        ev = responder.wait_event(["DPP-AUTH-SUCCESS", "DPP-FAIL"],
4897                                  timeout=timeout)
4898    if ev is None or "DPP-AUTH-SUCCESS" not in ev:
4899        raise Exception("DPP authentication did not succeed (Responder)")
4900    for i in ev.split(' '):
4901        a = i.split('=')
4902        if len(a) < 2:
4903            continue
4904        res['responder-auth-success-' + a[0]] = a[1]
4905    ev = initiator.wait_event(["DPP-AUTH-SUCCESS", "DPP-FAIL"], timeout=5)
4906    if ev is None or "DPP-AUTH-SUCCESS" not in ev:
4907        raise Exception("DPP authentication did not succeed (Initiator)")
4908    for i in ev.split(' '):
4909        a = i.split('=')
4910        if len(a) < 2:
4911            continue
4912        res['initiator-auth-success-' + a[0]] = a[1]
4913    if configurator:
4914        ev = configurator.wait_event(["DPP-CONF-SENT",
4915                                      "DPP-CONF-FAILED"], timeout=5)
4916        if ev is None:
4917            raise Exception("DPP configuration not completed (Configurator)")
4918        if "DPP-CONF-FAILED" in ev and not allow_configurator_failure:
4919            raise Exception("DPP configuration did not succeed (Configurator)")
4920        if "DPP-CONF-SENT" in ev and require_configurator_failure:
4921            raise Exception("DPP configuration succeeded (Configurator)")
4922        if "DPP-CONF-SENT" in ev and "wait_conn_status=1" in ev:
4923            res['wait_conn_status'] = True
4924    if enrollee:
4925        ev = enrollee.wait_event(["DPP-CONF-RECEIVED",
4926                                  "DPP-CONF-FAILED"], timeout=5)
4927        if ev is None:
4928            raise Exception("DPP configuration not completed (Enrollee)")
4929        if "DPP-CONF-FAILED" in ev and not allow_enrollee_failure:
4930            raise Exception("DPP configuration did not succeed (Enrollee)")
4931    if stop_responder:
4932        responder.request("DPP_STOP_LISTEN")
4933    if stop_initiator:
4934        initiator.request("DPP_STOP_LISTEN")
4935    return res
4936
4937def wait_conf_completion(configurator, enrollee):
4938    ev = configurator.wait_event(["DPP-CONF-SENT"], timeout=5)
4939    if ev is None:
4940        raise Exception("DPP configuration not completed (Configurator)")
4941    ev = enrollee.wait_event(["DPP-CONF-RECEIVED", "DPP-CONF-FAILED"],
4942                             timeout=5)
4943    if ev is None:
4944        raise Exception("DPP configuration not completed (Enrollee)")
4945
4946def start_dpp(dev):
4947    id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
4948    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
4949
4950    conf = '{"wi-fi_tech":"infra", "discovery":{"ssid":"test"},"cred":{"akm":"psk","pass":"secret passphrase"}}' + 3000*' '
4951    dev[0].set("dpp_config_obj_override", conf)
4952
4953    dev[0].set("ext_mgmt_frame_handling", "1")
4954    dev[0].dpp_listen(2412)
4955    dev[1].dpp_auth_init(uri=uri0, role="enrollee")
4956
4957def test_dpp_gas_timeout_handling(dev, apdev):
4958    """DPP and GAS timeout handling"""
4959    check_dpp_capab(dev[0])
4960    check_dpp_capab(dev[1])
4961    start_dpp(dev)
4962
4963    # DPP Authentication Request
4964    rx_process_frame(dev[0])
4965
4966    # DPP Authentication Confirmation
4967    rx_process_frame(dev[0])
4968
4969    res = wait_auth_success(dev[0], dev[1])
4970    if 'responder-mgmt-rx' in res:
4971        msg = dev[0].mgmt_rx_parse(res['responder-mgmt-rx'])
4972    else:
4973        msg = None
4974
4975    # DPP Configuration Request (GAS Initial Request frame)
4976    rx_process_frame(dev[0], msg)
4977
4978    # DPP Configuration Request (GAS Comeback Request frame)
4979    rx_process_frame(dev[0])
4980
4981    # Wait for GAS timeout
4982    ev = dev[1].wait_event(["DPP-CONF-FAILED"], timeout=5)
4983    if ev is None:
4984        raise Exception("DPP configuration not completed (Enrollee)")
4985
4986def test_dpp_gas_comeback_after_failure(dev, apdev):
4987    """DPP and GAS comeback after failure"""
4988    check_dpp_capab(dev[0])
4989    check_dpp_capab(dev[1])
4990    start_dpp(dev)
4991
4992    # DPP Authentication Request
4993    rx_process_frame(dev[0])
4994
4995    # DPP Authentication Confirmation
4996    rx_process_frame(dev[0])
4997
4998    res = wait_auth_success(dev[0], dev[1])
4999    if 'responder-mgmt-rx' in res:
5000        msg = dev[0].mgmt_rx_parse(res['responder-mgmt-rx'])
5001    else:
5002        msg = None
5003
5004    # DPP Configuration Request (GAS Initial Request frame)
5005    rx_process_frame(dev[0], msg)
5006
5007    # DPP Configuration Request (GAS Comeback Request frame)
5008    msg = dev[0].mgmt_rx()
5009    frame = binascii.hexlify(msg['frame']).decode()
5010    with alloc_fail(dev[0], 1, "gas_build_comeback_resp;gas_server_handle_rx_comeback_req"):
5011        if "OK" not in dev[0].request("MGMT_RX_PROCESS freq={} datarate={} ssi_signal={} frame={}".format(msg['freq'], msg['datarate'], msg['ssi_signal'], frame)):
5012            raise Exception("MGMT_RX_PROCESS failed")
5013        wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
5014    # Try the same frame again - this is expected to fail since the response has
5015    # already been freed.
5016    if "OK" not in dev[0].request("MGMT_RX_PROCESS freq={} datarate={} ssi_signal={} frame={}".format(msg['freq'], msg['datarate'], msg['ssi_signal'], frame)):
5017        raise Exception("MGMT_RX_PROCESS failed")
5018
5019    # DPP Configuration Request (GAS Comeback Request frame retry)
5020    msg = dev[0].mgmt_rx()
5021
5022def test_dpp_gas(dev, apdev):
5023    """DPP and GAS protocol testing"""
5024    ver0 = check_dpp_capab(dev[0])
5025    ver1 = check_dpp_capab(dev[1])
5026    start_dpp(dev)
5027
5028    # DPP Authentication Request
5029    rx_process_frame(dev[0])
5030
5031    # DPP Authentication Confirmation
5032    rx_process_frame(dev[0])
5033
5034    res = wait_auth_success(dev[0], dev[1])
5035
5036    # DPP Configuration Request (GAS Initial Request frame)
5037    if 'responder-mgmt-rx' in res:
5038        msg = dev[0].mgmt_rx_parse(res['responder-mgmt-rx'])
5039    else:
5040        msg = dev[0].mgmt_rx()
5041
5042    # Protected Dual of GAS Initial Request frame (dropped by GAS server)
5043    if msg == None:
5044        raise Exception("GAS Initial Request frame not received")
5045    frame = binascii.hexlify(msg['frame'])
5046    frame = frame[0:48] + b"09" + frame[50:]
5047    frame = frame.decode()
5048    if "OK" not in dev[0].request("MGMT_RX_PROCESS freq={} datarate={} ssi_signal={} frame={}".format(msg['freq'], msg['datarate'], msg['ssi_signal'], frame)):
5049        raise Exception("MGMT_RX_PROCESS failed")
5050
5051    with alloc_fail(dev[0], 1, "gas_server_send_resp"):
5052        frame = binascii.hexlify(msg['frame']).decode()
5053        if "OK" not in dev[0].request("MGMT_RX_PROCESS freq={} datarate={} ssi_signal={} frame={}".format(msg['freq'], msg['datarate'], msg['ssi_signal'], frame)):
5054            raise Exception("MGMT_RX_PROCESS failed")
5055        wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
5056
5057    with alloc_fail(dev[0], 1, "gas_build_initial_resp;gas_server_send_resp"):
5058        frame = binascii.hexlify(msg['frame']).decode()
5059        if "OK" not in dev[0].request("MGMT_RX_PROCESS freq={} datarate={} ssi_signal={} frame={}".format(msg['freq'], msg['datarate'], msg['ssi_signal'], frame)):
5060            raise Exception("MGMT_RX_PROCESS failed")
5061        wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
5062
5063    # Add extra data after Query Request field to trigger
5064    # "GAS: Ignored extra data after Query Request field"
5065    frame = binascii.hexlify(msg['frame']).decode() + "00"
5066    if "OK" not in dev[0].request("MGMT_RX_PROCESS freq={} datarate={} ssi_signal={} frame={}".format(msg['freq'], msg['datarate'], msg['ssi_signal'], frame)):
5067        raise Exception("MGMT_RX_PROCESS failed")
5068
5069    # DPP Configuration Request (GAS Comeback Request frame)
5070    rx_process_frame(dev[0])
5071
5072    # DPP Configuration Request (GAS Comeback Request frame)
5073    rx_process_frame(dev[0])
5074
5075    # DPP Configuration Request (GAS Comeback Request frame)
5076    rx_process_frame(dev[0])
5077
5078    if ver0 >= 2 and ver1 >= 2:
5079        # DPP Configuration Result
5080        rx_process_frame(dev[0])
5081
5082    wait_conf_completion(dev[0], dev[1])
5083
5084def test_dpp_truncated_attr(dev, apdev):
5085    """DPP and truncated attribute"""
5086    check_dpp_capab(dev[0])
5087    check_dpp_capab(dev[1])
5088    start_dpp(dev)
5089
5090    # DPP Authentication Request
5091    msg = dev[0].mgmt_rx()
5092    frame = msg['frame']
5093
5094    # DPP: Truncated message - not enough room for the attribute - dropped
5095    frame1 = binascii.hexlify(frame[0:36]).decode()
5096    if "OK" not in dev[0].request("MGMT_RX_PROCESS freq={} datarate={} ssi_signal={} frame={}".format(msg['freq'], msg['datarate'], msg['ssi_signal'], frame1)):
5097        raise Exception("MGMT_RX_PROCESS failed")
5098    ev = dev[0].wait_event(["DPP-RX"], timeout=5)
5099    if ev is None or "ignore=invalid-attributes" not in ev:
5100        raise Exception("Invalid attribute error not reported")
5101
5102    # DPP: Unexpected octets (3) after the last attribute
5103    frame2 = binascii.hexlify(frame).decode() + "000000"
5104    if "OK" not in dev[0].request("MGMT_RX_PROCESS freq={} datarate={} ssi_signal={} frame={}".format(msg['freq'], msg['datarate'], msg['ssi_signal'], frame2)):
5105        raise Exception("MGMT_RX_PROCESS failed")
5106    ev = dev[0].wait_event(["DPP-RX"], timeout=5)
5107    if ev is None or "ignore=invalid-attributes" not in ev:
5108        raise Exception("Invalid attribute error not reported")
5109
5110def test_dpp_bootstrap_key_autogen_issues(dev, apdev):
5111    """DPP bootstrap key autogen issues"""
5112    check_dpp_capab(dev[0])
5113    check_dpp_capab(dev[1])
5114
5115    logger.info("dev0 displays QR Code")
5116    id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
5117    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
5118
5119    logger.info("dev1 scans QR Code")
5120    id1 = dev[1].dpp_qr_code(uri0)
5121
5122    logger.info("dev1 initiates DPP Authentication")
5123    dev[0].dpp_listen(2412)
5124    with alloc_fail(dev[1], 1, "dpp_autogen_bootstrap_key"):
5125        dev[1].dpp_auth_init(peer=id1, expect_fail=True)
5126    with alloc_fail(dev[1], 1, "dpp_gen_uri;dpp_autogen_bootstrap_key"):
5127        dev[1].dpp_auth_init(peer=id1, expect_fail=True)
5128    with fail_test(dev[1], 1, "dpp_keygen;dpp_autogen_bootstrap_key"):
5129        dev[1].dpp_auth_init(peer=id1, expect_fail=True)
5130    dev[0].request("DPP_STOP_LISTEN")
5131
5132def test_dpp_auth_resp_status_failure(dev, apdev):
5133    """DPP and Auth Resp(status) build failure"""
5134    with alloc_fail(dev[0], 1, "dpp_auth_build_resp"):
5135        run_dpp_proto_auth_resp_missing(dev, 99999, None,
5136                                        incompatible_roles=True)
5137
5138def test_dpp_auth_resp_aes_siv_issue(dev, apdev):
5139    """DPP Auth Resp AES-SIV issue"""
5140    check_dpp_capab(dev[0])
5141    check_dpp_capab(dev[1])
5142    logger.info("dev0 displays QR Code")
5143    id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
5144    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
5145    logger.info("dev1 scans QR Code and initiates DPP Authentication")
5146    dev[0].dpp_listen(2412)
5147    with fail_test(dev[1], 1, "aes_siv_decrypt;dpp_auth_resp_rx"):
5148        dev[1].dpp_auth_init(uri=uri0)
5149        wait_dpp_fail(dev[1], "AES-SIV decryption failed")
5150    dev[0].request("DPP_STOP_LISTEN")
5151
5152def test_dpp_invalid_legacy_params(dev, apdev):
5153    """DPP invalid legacy parameters"""
5154    check_dpp_capab(dev[0])
5155    check_dpp_capab(dev[1])
5156    id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
5157    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
5158    # No pass/psk
5159    dev[1].dpp_auth_init(uri=uri0, conf="sta-psk", ssid="dpp-legacy",
5160                         expect_fail=True)
5161
5162def test_dpp_invalid_legacy_params2(dev, apdev):
5163    """DPP invalid legacy parameters 2"""
5164    check_dpp_capab(dev[0])
5165    check_dpp_capab(dev[1])
5166    id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
5167    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
5168    dev[0].set("dpp_configurator_params",
5169               " conf=sta-psk ssid=%s" % (binascii.hexlify(b"dpp-legacy").decode()))
5170    dev[0].dpp_listen(2412, role="configurator")
5171    dev[1].dpp_auth_init(uri=uri0, role="enrollee")
5172    # No pass/psk
5173    ev = dev[0].wait_event(["DPP: Failed to set configurator parameters"],
5174                           timeout=5)
5175    if ev is None:
5176        raise Exception("DPP configuration failure not reported")
5177
5178def test_dpp_legacy_params_failure(dev, apdev):
5179    """DPP legacy parameters local failure"""
5180    check_dpp_capab(dev[0])
5181    check_dpp_capab(dev[1])
5182    id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
5183    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
5184    dev[0].dpp_listen(2412)
5185    with alloc_fail(dev[1], 1, "dpp_build_conf_obj_legacy"):
5186        dev[1].dpp_auth_init(uri=uri0, conf="sta-psk", passphrase="passphrase",
5187                             ssid="dpp-legacy")
5188        ev = dev[0].wait_event(["DPP-CONF-FAILED"], timeout=5)
5189        if ev is None:
5190            raise Exception("DPP configuration failure not reported")
5191
5192def test_dpp_invalid_configurator_key(dev, apdev):
5193    """DPP invalid configurator key"""
5194    check_dpp_capab(dev[0])
5195
5196    if "FAIL" not in dev[0].request("DPP_CONFIGURATOR_ADD key=aa"):
5197        raise Exception("Invalid key accepted")
5198
5199    with alloc_fail(dev[0], 1, "dpp_keygen_configurator"):
5200        if "FAIL" not in dev[0].request("DPP_CONFIGURATOR_ADD key=" + dpp_key_p256):
5201            raise Exception("Error not reported")
5202
5203    with alloc_fail(dev[0], 1,
5204                    "crypto_ec_key_get_pubkey_point;dpp_keygen_configurator"):
5205        if "FAIL" not in dev[0].request("DPP_CONFIGURATOR_ADD key=" + dpp_key_p256):
5206            raise Exception("Error not reported")
5207
5208    with alloc_fail(dev[0], 1, "base64_gen_encode;dpp_keygen_configurator"):
5209        if "FAIL" not in dev[0].request("DPP_CONFIGURATOR_ADD key=" + dpp_key_p256):
5210            raise Exception("Error not reported")
5211
5212    with fail_test(dev[0], 1, "dpp_keygen_configurator"):
5213        if "FAIL" not in dev[0].request("DPP_CONFIGURATOR_ADD key=" + dpp_key_p256):
5214            raise Exception("Error not reported")
5215
5216def test_dpp_own_config_sign_fail(dev, apdev):
5217    """DPP own config signing failure"""
5218    check_dpp_capab(dev[0])
5219    conf_id = dev[0].dpp_configurator_add()
5220    tests = ["",
5221             " ",
5222             " conf=sta-dpp",
5223             " configurator=%d" % conf_id,
5224             " conf=sta-dpp configurator=%d curve=unsupported" % conf_id]
5225    for t in tests:
5226        if "FAIL" not in dev[0].request("DPP_CONFIGURATOR_SIGN " + t):
5227            raise Exception("Invalid command accepted: " + t)
5228
5229def test_dpp_peer_intro_failures(dev, apdev):
5230    """DPP peer introduction failures"""
5231    try:
5232        run_dpp_peer_intro_failures(dev, apdev)
5233    finally:
5234        dev[0].set("dpp_config_processing", "0", allow_fail=True)
5235
5236def run_dpp_peer_intro_failures(dev, apdev):
5237    check_dpp_capab(dev[0])
5238    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured"})
5239    check_dpp_capab(hapd)
5240
5241    conf_id = hapd.dpp_configurator_add(key=dpp_key_p256)
5242    csign = hapd.request("DPP_CONFIGURATOR_GET_KEY %d" % conf_id)
5243    if "FAIL" in csign or len(csign) == 0:
5244        raise Exception("DPP_CONFIGURATOR_GET_KEY failed")
5245
5246    conf_id2 = dev[0].dpp_configurator_add(key=csign)
5247    csign2 = dev[0].request("DPP_CONFIGURATOR_GET_KEY %d" % conf_id2)
5248
5249    if csign != csign2:
5250        raise Exception("Unexpected difference in configurator key")
5251
5252    cmd = "DPP_CONFIGURATOR_SIGN  conf=ap-dpp configurator=%d" % conf_id
5253    res = hapd.request(cmd)
5254    if "FAIL" in res:
5255        raise Exception("Failed to generate own configuration")
5256    update_hapd_config(hapd)
5257
5258    dev[0].set("dpp_config_processing", "1")
5259    cmd = "DPP_CONFIGURATOR_SIGN  conf=sta-dpp configurator=%d" % conf_id
5260    res = dev[0].request(cmd)
5261    if "FAIL" in res:
5262        raise Exception("Failed to generate own configuration")
5263    ev = dev[0].wait_event(["DPP-NETWORK-ID"], timeout=1)
5264    if ev is None:
5265        raise Exception("DPP network profile not generated")
5266    id = ev.split(' ')[1]
5267    dev[0].select_network(id, freq=2412)
5268    dev[0].wait_connected()
5269    dev[0].request("DISCONNECT")
5270    dev[0].wait_disconnected()
5271    dev[0].dump_monitor()
5272
5273    tests = ["eyJ0eXAiOiJkcHBDb24iLCJraWQiOiIwTlNSNTlxRTc0alFfZTFLVGVPV1lYY1pTWnFUaDdNXzU0aHJPcFRpaFJnIiwiYWxnIjoiRVMyNTYifQ.eyJncm91cHMiOltdLCJuZXRBY2Nlc3NLZXkiOnsia3R5IjoiRUMiLCJjcnYiOiJQLTI1NiIsIngiOiJiVmFMRGlBT09OQmFjcVFVN1pYamFBVEtEMVhhbDVlUExqOUZFZUl3VkN3IiwieSI6Il95c25JR1hTYjBvNEsyMWg0anZmSkZxMHdVNnlPNWp1VUFPd3FuM0dHVHMifX0.WgzZBOJaisWBRxvtXPbVYPXU7OIZxs6sZD-cPOLmJVTIYZKdMkSOMvP5b6si_j61FIrjhm43tmGq1P6cpoxB_g",
5274             "eyJ0eXAiOiJkcHBDb24iLCJraWQiOiIwTlNSNTlxRTc0alFfZTFLVGVPV1lYY1pTWnFUaDdNXzU0aHJPcFRpaFJnIiwiYWxnIjoiRVMyNTYifQ.eyJncm91cHMiOlt7fV0sIm5ldEFjY2Vzc0tleSI6eyJrdHkiOiJFQyIsImNydiI6IlAtMjU2IiwieCI6IkJhY3BWSDNpNDBrZklNS0RHa1FFRzhCODBCaEk4cEFmTWpLbzM5NlFZT2ciLCJ5IjoiMjBDYjhDNjRsSjFzQzV2NXlKMnBFZXRRempxMjI4YVV2cHMxNmQ0M3EwQSJ9fQ.dG2y8VvZQJ5hfob8E5F2FAeR7Nd700qstYkxDgA2QfARaNMZ0_SfKfoG-yKXsIZNM-TvGBfACgfhagG9Oaw_Xw",
5275             "eyJ0eXAiOiJkcHBDb24iLCJraWQiOiIwTlNSNTlxRTc0alFfZTFLVGVPV1lYY1pTWnFUaDdNXzU0aHJPcFRpaFJnIiwiYWxnIjoiRVMyNTYifQ.eyJncm91cHMiOlt7Imdyb3VwSWQiOiIqIn1dLCJuZXRBY2Nlc3NLZXkiOnsia3R5IjoiRUMiLCJjcnYiOiJQLTI1NiIsIngiOiJkc2VmcmJWWlhad0RMWHRpLWlObDBBYkFIOXpqeFFKd0R1SUd5NzNuZGU0IiwieSI6IjZFQnExN3cwYW1fZlh1OUQ4UGxWYk9XZ2I3b19DcTUxWHlmSG8wcHJyeDQifX0.caBvdDUtXrhnS61-juVZ_2FQdprepv0yZjC04G4ERvLUpeX7cgu0Hp-A1aFDogP1PEFGpkaEdcAWRQnSSRiIKQ"]
5276    for t in tests:
5277        dev[0].set_network_quoted(id, "dpp_connector", t)
5278        dev[0].select_network(id, freq=2412)
5279        ev = dev[0].wait_event(["DPP-INTRO"], timeout=5)
5280        if ev is None or "status=8" not in ev:
5281            raise Exception("Introduction failure not reported")
5282        dev[0].request("DISCONNECT")
5283        dev[0].dump_monitor()
5284
5285def test_dpp_peer_intro_local_failures(dev, apdev):
5286    """DPP peer introduction local failures"""
5287    check_dpp_capab(dev[0])
5288    check_dpp_capab(dev[1])
5289
5290    params = {"ssid": "dpp",
5291              "wpa": "2",
5292              "wpa_key_mgmt": "DPP",
5293              "ieee80211w": "2",
5294              "rsn_pairwise": "CCMP",
5295              "dpp_connector": params1_ap_connector,
5296              "dpp_csign": params1_csign,
5297              "dpp_netaccesskey": params1_ap_netaccesskey}
5298    try:
5299        hapd = hostapd.add_ap(apdev[0], params)
5300    except:
5301        raise HwsimSkip("DPP not supported")
5302
5303    tests = ["dpp_derive_pmk",
5304             "dpp_hkdf_expand;dpp_derive_pmk",
5305             "dpp_derive_pmkid"]
5306    for func in tests:
5307        with fail_test(dev[0], 1, func):
5308            dev[0].connect("dpp", key_mgmt="DPP", scan_freq="2412",
5309                           ieee80211w="2",
5310                           dpp_csign=params1_csign,
5311                           dpp_connector=params1_sta_connector,
5312                           dpp_netaccesskey=params1_sta_netaccesskey,
5313                           wait_connect=False)
5314            ev = dev[0].wait_event(["DPP-INTRO"], timeout=10)
5315            if ev is None or "fail=peer_connector_validation_failed" not in ev:
5316                raise Exception("Introduction failure not reported")
5317            dev[0].request("REMOVE_NETWORK all")
5318            dev[0].dump_monitor()
5319
5320    tests = [(1, "base64_gen_decode;dpp_peer_intro"),
5321             (1, "json_parse;dpp_peer_intro"),
5322             (50, "json_parse;dpp_peer_intro"),
5323             (1, "=dpp_check_signed_connector;dpp_peer_intro"),
5324             (1, "dpp_parse_jwk")]
5325    for count, func in tests:
5326        with alloc_fail(dev[0], count, func):
5327            dev[0].connect("dpp", key_mgmt="DPP", scan_freq="2412",
5328                           ieee80211w="2",
5329                           dpp_csign=params1_csign,
5330                           dpp_connector=params1_sta_connector,
5331                           dpp_netaccesskey=params1_sta_netaccesskey,
5332                           wait_connect=False)
5333            ev = dev[0].wait_event(["DPP-INTRO"], timeout=10)
5334            if ev is None or "fail=peer_connector_validation_failed" not in ev:
5335                raise Exception("Introduction failure not reported")
5336            dev[0].request("REMOVE_NETWORK all")
5337            dev[0].dump_monitor()
5338
5339    parts = params1_ap_connector.split('.')
5340    for ap_connector in ['.'.join(parts[0:2]), '.'.join(parts[0:1])]:
5341        hapd.set("dpp_connector", ap_connector)
5342        dev[0].connect("dpp", key_mgmt="DPP", scan_freq="2412",
5343                       ieee80211w="2",
5344                       dpp_csign=params1_csign,
5345                       dpp_connector=params1_sta_connector,
5346                       dpp_netaccesskey=params1_sta_netaccesskey,
5347                       wait_connect=False)
5348        ev = dev[0].wait_event(["DPP-TX-STATUS"], timeout=10)
5349        if ev is None:
5350            raise Exception("No TX status reported")
5351        dev[0].request("REMOVE_NETWORK all")
5352        dev[0].dump_monitor()
5353
5354    hapd.set("dpp_netaccesskey", "00")
5355    dev[0].connect("dpp", key_mgmt="DPP", scan_freq="2412",
5356                   ieee80211w="2",
5357                   dpp_csign=params1_csign,
5358                   dpp_connector=params1_sta_connector,
5359                   dpp_netaccesskey=params1_sta_netaccesskey,
5360                   wait_connect=False)
5361    ev = dev[0].wait_event(["DPP-TX-STATUS"], timeout=10)
5362    if ev is None:
5363        raise Exception("No TX status reported")
5364    dev[0].request("REMOVE_NETWORK all")
5365    dev[0].dump_monitor()
5366
5367    hapd.set("dpp_csign", "00")
5368    dev[0].connect("dpp", key_mgmt="DPP", scan_freq="2412",
5369                   ieee80211w="2",
5370                   dpp_csign=params1_csign,
5371                   dpp_connector=params1_sta_connector,
5372                   dpp_netaccesskey=params1_sta_netaccesskey,
5373                   wait_connect=False)
5374    ev = dev[0].wait_event(["DPP-TX-STATUS"], timeout=10)
5375    if ev is None:
5376        raise Exception("No TX status reported")
5377    dev[0].request("REMOVE_NETWORK all")
5378
5379def run_dpp_configurator_id_unknown(dev):
5380    check_dpp_capab(dev)
5381    conf_id = dev.dpp_configurator_add()
5382    if "FAIL" not in dev.request("DPP_CONFIGURATOR_GET_KEY %d" % (conf_id + 1)):
5383        raise Exception("DPP_CONFIGURATOR_GET_KEY with incorrect id accepted")
5384
5385    cmd = "DPP_CONFIGURATOR_SIGN  conf=sta-dpp configurator=%d" % (conf_id + 1)
5386    if "FAIL" not in dev.request(cmd):
5387        raise Exception("DPP_CONFIGURATOR_SIGN with incorrect id accepted")
5388
5389def test_dpp_configurator_id_unknown(dev, apdev):
5390    """DPP and unknown configurator id"""
5391    run_dpp_configurator_id_unknown(dev[0])
5392    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured"})
5393    run_dpp_configurator_id_unknown(hapd)
5394
5395def run_dpp_bootstrap_gen_failures(dev):
5396    check_dpp_capab(dev)
5397
5398    tests = ["type=unsupported",
5399             "type=qrcode chan=-1",
5400             "type=qrcode mac=a",
5401             "type=qrcode key=qq",
5402             "type=qrcode key=",
5403             "type=qrcode info=abc\tdef"]
5404    for t in tests:
5405        if "FAIL" not in dev.request("DPP_BOOTSTRAP_GEN " + t):
5406            raise Exception("Command accepted unexpectedly")
5407
5408    id = dev.dpp_bootstrap_gen()
5409    uri = dev.request("DPP_BOOTSTRAP_GET_URI %d" % id)
5410    if not uri.startswith("DPP:"):
5411        raise Exception("Could not get URI")
5412    if "FAIL" not in dev.request("DPP_BOOTSTRAP_GET_URI 0"):
5413        raise Exception("Failure not reported")
5414    info = dev.request("DPP_BOOTSTRAP_INFO %d" % id)
5415    if not info.startswith("type=QRCODE"):
5416        raise Exception("Could not get info")
5417    if "FAIL" not in dev.request("DPP_BOOTSTRAP_REMOVE 0"):
5418        raise Exception("Failure not reported")
5419    if "FAIL" in dev.request("DPP_BOOTSTRAP_REMOVE *"):
5420        raise Exception("Failed to remove bootstrap info")
5421    if "FAIL" not in dev.request("DPP_BOOTSTRAP_GET_URI %d" % id):
5422        raise Exception("Failure not reported")
5423    if "FAIL" not in dev.request("DPP_BOOTSTRAP_INFO %d" % id):
5424        raise Exception("Failure not reported")
5425
5426    func = "dpp_bootstrap_gen"
5427    with alloc_fail(dev, 1, "=" + func):
5428        if "FAIL" not in dev.request("DPP_BOOTSTRAP_GEN type=qrcode"):
5429            raise Exception("Command accepted unexpectedly")
5430
5431    with alloc_fail(dev, 1, "dpp_gen_uri;dpp_bootstrap_gen"):
5432        if "FAIL" not in dev.request("DPP_BOOTSTRAP_GEN type=qrcode"):
5433            raise Exception("Command accepted unexpectedly")
5434
5435    with alloc_fail(dev, 1, "get_param"):
5436        dev.request("DPP_BOOTSTRAP_GEN type=qrcode curve=foo")
5437
5438def test_dpp_bootstrap_gen_failures(dev, apdev):
5439    """DPP_BOOTSTRAP_GEN/REMOVE/GET_URI/INFO error cases"""
5440    run_dpp_bootstrap_gen_failures(dev[0])
5441    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured"})
5442    run_dpp_bootstrap_gen_failures(hapd)
5443
5444def test_dpp_listen_continue(dev, apdev):
5445    """DPP and continue listen state"""
5446    check_dpp_capab(dev[0])
5447    check_dpp_capab(dev[1])
5448    id = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
5449    uri = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id)
5450    dev[0].dpp_listen(2412)
5451    time.sleep(5.1)
5452    dev[1].dpp_auth_init(uri=uri)
5453    wait_auth_success(dev[0], dev[1], configurator=dev[1], enrollee=dev[0],
5454                      allow_enrollee_failure=True, stop_responder=True,
5455                      stop_initiator=True)
5456
5457def test_dpp_network_addition_failure(dev, apdev):
5458    """DPP network addition failure"""
5459    try:
5460        run_dpp_network_addition_failure(dev, apdev)
5461    finally:
5462        dev[0].set("dpp_config_processing", "0", allow_fail=True)
5463
5464def run_dpp_network_addition_failure(dev, apdev):
5465    check_dpp_capab(dev[0])
5466    conf_id = dev[0].dpp_configurator_add()
5467    dev[0].set("dpp_config_processing", "1")
5468    cmd = "DPP_CONFIGURATOR_SIGN  conf=sta-dpp configurator=%d" % conf_id
5469    tests = [(1, "=wpas_dpp_add_network"),
5470             (2, "=wpas_dpp_add_network"),
5471             (3, "=wpas_dpp_add_network"),
5472             (4, "=wpas_dpp_add_network"),
5473             (1, "wpa_config_add_network;wpas_dpp_add_network")]
5474    for count, func in tests:
5475        with alloc_fail(dev[0], count, func):
5476            res = dev[0].request(cmd)
5477            if "OK" in res:
5478                ev = dev[0].wait_event(["DPP-NET-ACCESS-KEY"], timeout=2)
5479                if ev is None:
5480                    raise Exception("Config object not processed")
5481            wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
5482        dev[0].dump_monitor()
5483
5484    cmd = "DPP_CONFIGURATOR_SIGN  conf=sta-psk pass=%s configurator=%d" % (binascii.hexlify(b"passphrase").decode(), conf_id)
5485    tests = [(1, "wpa_config_set_quoted;wpas_dpp_add_network")]
5486    for count, func in tests:
5487        with alloc_fail(dev[0], count, func):
5488            res = dev[0].request(cmd)
5489            if "OK" in res:
5490                ev = dev[0].wait_event(["DPP-NET-ACCESS-KEY"], timeout=2)
5491                if ev is None:
5492                    raise Exception("Config object not processed")
5493            wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
5494        dev[0].dump_monitor()
5495
5496def test_dpp_two_initiators(dev, apdev):
5497    """DPP and two initiators"""
5498    check_dpp_capab(dev[0])
5499    check_dpp_capab(dev[1])
5500    check_dpp_capab(dev[2])
5501    id = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
5502    uri = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id)
5503    dev[0].dpp_listen(2412)
5504    peer = dev[2].dpp_qr_code(uri)
5505    dev[1].dpp_auth_init(uri=uri)
5506    ev = dev[0].wait_event(["DPP-RX"], timeout=5)
5507    if ev is None:
5508        raise Exeption("No DPP Authentication Request seen")
5509    dev[2].dpp_auth_init(uri=uri, peer=peer)
5510    ev = dev[0].wait_event(["DPP-FAIL"], timeout=5)
5511    if ev is None:
5512        raise Exception("Failure not reported")
5513    skip = False
5514    if "Configurator rejected configuration" in ev:
5515        # Race condition prevented real test from being executed
5516        skip = True
5517    elif "DPP-FAIL Already in DPP authentication exchange - ignore new one" not in ev:
5518        raise Exception("Unexpected result: " + ev)
5519
5520    ev = dev[0].wait_event(["DPP-CONF-FAILED"], timeout=2)
5521    if ev is None:
5522        raise Exception("DPP configuration result not seen (Enrollee)")
5523    ev = dev[1].wait_event(["DPP-CONF-SENT"], timeout=2)
5524    if ev is None:
5525        raise Exception("DPP configuration result not seen (Responder)")
5526
5527    dev[0].request("DPP_STOP_LISTEN")
5528    dev[1].request("DPP_STOP_LISTEN")
5529    dev[2].request("DPP_STOP_LISTEN")
5530
5531    if skip:
5532        raise HwsimSkip("dpp_two_initiators not fully executed due to race condition")
5533
5534def test_dpp_conf_file_update(dev, apdev, params):
5535    """DPP provisioning updating wpa_supplicant configuration file"""
5536    config = os.path.join(params['logdir'], 'dpp_conf_file_update.conf')
5537    with open(config, "w") as f:
5538        f.write("update_config=1\n")
5539    wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
5540    wpas.interface_add("wlan5", config=config)
5541    check_dpp_capab(wpas)
5542    wpas.set("dpp_config_processing", "1")
5543    run_dpp_qr_code_auth_unicast([wpas, dev[1]], apdev, None,
5544                                 init_extra="conf=sta-dpp",
5545                                 require_conf_success=True,
5546                                 configurator=True)
5547    wpas.interface_remove("wlan5")
5548
5549    with open(config, "r") as f:
5550        res = f.read()
5551    for i in ["network={", "dpp_connector=", "key_mgmt=DPP", "ieee80211w=2",
5552              "dpp_netaccesskey=", "dpp_csign="]:
5553        if i not in res:
5554            raise Exception("Configuration file missing '%s'" % i)
5555
5556    wpas.interface_add("wlan5", config=config)
5557    if len(wpas.list_networks()) != 1:
5558        raise Exception("Unexpected number of networks")
5559
5560def test_dpp_duplicated_auth_resp(dev, apdev):
5561    """DPP and duplicated Authentication Response"""
5562    check_dpp_capab(dev[0])
5563    check_dpp_capab(dev[1])
5564    id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
5565    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
5566    dev[0].set("ext_mgmt_frame_handling", "1")
5567    dev[1].set("ext_mgmt_frame_handling", "1")
5568    dev[0].dpp_listen(2412)
5569    dev[1].dpp_auth_init(uri=uri0)
5570
5571    # DPP Authentication Request
5572    rx_process_frame(dev[0])
5573
5574    # DPP Authentication Response
5575    msg = rx_process_frame(dev[1])
5576    frame = binascii.hexlify(msg['frame']).decode()
5577    # Duplicated frame
5578    if "OK" not in dev[1].request("MGMT_RX_PROCESS freq={} datarate={} ssi_signal={} frame={}".format(msg['freq'], msg['datarate'], msg['ssi_signal'], frame)):
5579        raise Exception("MGMT_RX_PROCESS failed")
5580    # Modified frame - nonzero status
5581    if frame[2*32:2*37] != "0010010000":
5582        raise Exception("Could not find Status attribute")
5583    frame2 = frame[0:2*32] + "0010010001" + frame[2*37:]
5584    if "OK" not in dev[1].request("MGMT_RX_PROCESS freq={} datarate={} ssi_signal={} frame={}".format(msg['freq'], msg['datarate'], msg['ssi_signal'], frame2)):
5585        raise Exception("MGMT_RX_PROCESS failed")
5586    frame2 = frame[0:2*32] + "00100100ff" + frame[2*37:]
5587    if "OK" not in dev[1].request("MGMT_RX_PROCESS freq={} datarate={} ssi_signal={} frame={}".format(msg['freq'], msg['datarate'], msg['ssi_signal'], frame2)):
5588        raise Exception("MGMT_RX_PROCESS failed")
5589
5590    # DPP Authentication Confirmation
5591    rx_process_frame(dev[0])
5592
5593    wait_auth_success(dev[0], dev[1])
5594
5595    # DPP Configuration Request
5596    rx_process_frame(dev[1])
5597
5598    # DPP Configuration Response
5599    rx_process_frame(dev[0])
5600
5601    wait_conf_completion(dev[1], dev[0])
5602
5603def test_dpp_duplicated_auth_conf(dev, apdev):
5604    """DPP and duplicated Authentication Confirmation"""
5605    check_dpp_capab(dev[0])
5606    check_dpp_capab(dev[1])
5607    id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
5608    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
5609    dev[0].set("ext_mgmt_frame_handling", "1")
5610    dev[1].set("ext_mgmt_frame_handling", "1")
5611    dev[0].dpp_listen(2412)
5612    dev[1].dpp_auth_init(uri=uri0)
5613
5614    # DPP Authentication Request
5615    rx_process_frame(dev[0])
5616
5617    # DPP Authentication Response
5618    rx_process_frame(dev[1])
5619
5620    # DPP Authentication Confirmation
5621    msg = rx_process_frame(dev[0])
5622    # Duplicated frame
5623    if "OK" not in dev[0].request("MGMT_RX_PROCESS freq={} datarate={} ssi_signal={} frame={}".format(msg['freq'], msg['datarate'], msg['ssi_signal'], binascii.hexlify(msg['frame']).decode())):
5624        raise Exception("MGMT_RX_PROCESS failed")
5625
5626    wait_auth_success(dev[0], dev[1])
5627
5628    # DPP Configuration Request
5629    rx_process_frame(dev[1])
5630
5631    # DPP Configuration Response
5632    rx_process_frame(dev[0])
5633
5634    wait_conf_completion(dev[1], dev[0])
5635
5636def test_dpp_enrollee_reject_config(dev, apdev):
5637    """DPP and Enrollee rejecting Config Object"""
5638    check_dpp_capab(dev[0])
5639    check_dpp_capab(dev[1])
5640    dev[0].set("dpp_test", "91")
5641    id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
5642    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
5643    dev[0].dpp_listen(2412)
5644    dev[1].dpp_auth_init(uri=uri0, conf="sta-sae", ssid="dpp-legacy",
5645                         passphrase="secret passphrase")
5646    wait_auth_success(dev[0], dev[1], configurator=dev[1], enrollee=dev[0],
5647                      allow_enrollee_failure=True,
5648                      allow_configurator_failure=True)
5649
5650def test_dpp_enrollee_ap_reject_config(dev, apdev):
5651    """DPP and Enrollee AP rejecting Config Object"""
5652    check_dpp_capab(dev[0])
5653    check_dpp_capab(dev[1])
5654    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured"})
5655    check_dpp_capab(hapd)
5656    hapd.set("dpp_test", "91")
5657    conf_id = dev[0].dpp_configurator_add()
5658    id_h = hapd.dpp_bootstrap_gen(chan="81/1", mac=True)
5659    uri = hapd.request("DPP_BOOTSTRAP_GET_URI %d" % id_h)
5660    dev[0].dpp_auth_init(uri=uri, conf="ap-dpp", configurator=conf_id)
5661    wait_auth_success(hapd, dev[0], configurator=dev[0], enrollee=hapd,
5662                      allow_enrollee_failure=True,
5663                      allow_configurator_failure=True)
5664
5665def test_dpp_legacy_and_dpp_akm(dev, apdev):
5666    """DPP and provisoning DPP and legacy AKMs"""
5667    try:
5668        run_dpp_legacy_and_dpp_akm(dev, apdev)
5669    finally:
5670        dev[0].set("dpp_config_processing", "0", allow_fail=True)
5671
5672def run_dpp_legacy_and_dpp_akm(dev, apdev):
5673    check_dpp_capab(dev[0], min_ver=2)
5674    check_dpp_capab(dev[1], min_ver=2)
5675
5676    csign = "30770201010420768240a3fc89d6662d9782f120527fe7fb9edc6366ab0b9c7dde96125cfd250fa00a06082a8648ce3d030107a144034200042908e1baf7bf413cc66f9e878a03e8bb1835ba94b033dbe3d6969fc8575d5eb5dfda1cb81c95cee21d0cd7d92ba30541ffa05cb6296f5dd808b0c1c2a83c0708"
5677    csign_pub = "3059301306072a8648ce3d020106082a8648ce3d030107034200042908e1baf7bf413cc66f9e878a03e8bb1835ba94b033dbe3d6969fc8575d5eb5dfda1cb81c95cee21d0cd7d92ba30541ffa05cb6296f5dd808b0c1c2a83c0708"
5678    ap_connector = "eyJ0eXAiOiJkcHBDb24iLCJraWQiOiJwYWtZbXVzd1dCdWpSYTl5OEsweDViaTVrT3VNT3dzZHRlaml2UG55ZHZzIiwiYWxnIjoiRVMyNTYifQ.eyJncm91cHMiOlt7Imdyb3VwSWQiOiIqIiwibmV0Um9sZSI6ImFwIn1dLCJuZXRBY2Nlc3NLZXkiOnsia3R5IjoiRUMiLCJjcnYiOiJQLTI1NiIsIngiOiIybU5vNXZuRkI5bEw3d1VWb1hJbGVPYzBNSEE1QXZKbnpwZXZULVVTYzVNIiwieSI6IlhzS3dqVHJlLTg5WWdpU3pKaG9CN1haeUttTU05OTl3V2ZaSVl0bi01Q3MifX0.XhjFpZgcSa7G2lHy0OCYTvaZFRo5Hyx6b7g7oYyusLC7C_73AJ4_BxEZQVYJXAtDuGvb3dXSkHEKxREP9Q6Qeg"
5679    ap_netaccesskey = "30770201010420ceba752db2ad5200fa7bc565b9c05c69b7eb006751b0b329b0279de1c19ca67ca00a06082a8648ce3d030107a14403420004da6368e6f9c507d94bef0515a1722578e73430703902f267ce97af4fe51273935ec2b08d3adefbcf588224b3261a01ed76722a630cf7df7059f64862d9fee42b"
5680
5681    ssid = "dpp-both"
5682    passphrase = "secret passphrase"
5683    params = {"ssid": ssid,
5684              "wpa": "2",
5685              "wpa_key_mgmt": "DPP WPA-PSK SAE",
5686              "ieee80211w": "1",
5687              "sae_require_mfp": '1',
5688              "rsn_pairwise": "CCMP",
5689              "wpa_passphrase": passphrase,
5690              "dpp_connector": ap_connector,
5691              "dpp_csign": csign_pub,
5692              "dpp_netaccesskey": ap_netaccesskey}
5693    try:
5694        hapd = hostapd.add_ap(apdev[0], params)
5695    except:
5696        raise HwsimSkip("DPP not supported")
5697
5698    dev[0].request("SET sae_groups ")
5699    conf_id = dev[1].dpp_configurator_add(key=csign)
5700    dev[0].set("dpp_config_processing", "1")
5701    id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
5702    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
5703    dev[0].dpp_listen(2412)
5704    dev[1].dpp_auth_init(uri=uri0, conf="sta-psk-sae-dpp", ssid=ssid,
5705                         passphrase=passphrase, configurator=conf_id)
5706    wait_auth_success(dev[0], dev[1], configurator=dev[1], enrollee=dev[0],
5707                      allow_enrollee_failure=True,
5708                      allow_configurator_failure=True)
5709    ev = dev[0].wait_event(["DPP-NETWORK-ID"], timeout=1)
5710    if ev is None:
5711        raise Exception("DPP network profile not generated")
5712    id0 = ev.split(' ')[1]
5713
5714    key_mgmt = dev[0].get_network(id0, "key_mgmt").split(' ')
5715    for m in ["SAE", "WPA-PSK", "DPP"]:
5716        if m not in key_mgmt:
5717            raise Exception("%s missing from key_mgmt" % m)
5718
5719    dev[0].scan_for_bss(hapd.own_addr(), freq=2412)
5720    dev[0].select_network(id0, freq=2412)
5721    dev[0].wait_connected()
5722
5723    dev[0].request("DISCONNECT")
5724    dev[0].wait_disconnected()
5725    hapd.disable()
5726
5727    params = {"ssid": ssid,
5728              "wpa": "2",
5729              "wpa_key_mgmt": "WPA-PSK SAE",
5730              "ieee80211w": "1",
5731              "sae_require_mfp": '1',
5732              "rsn_pairwise": "CCMP",
5733              "wpa_passphrase": passphrase}
5734    hapd2 = hostapd.add_ap(apdev[1], params)
5735
5736    dev[0].request("BSS_FLUSH 0")
5737    dev[0].scan_for_bss(hapd2.own_addr(), freq=2412, force_scan=True,
5738                        only_new=True)
5739    dev[0].select_network(id0, freq=2412)
5740    dev[0].wait_connected()
5741
5742    dev[0].request("DISCONNECT")
5743    dev[0].wait_disconnected()
5744
5745def test_dpp_controller_relay(dev, apdev, params):
5746    """DPP Controller/Relay"""
5747    try:
5748        run_dpp_controller_relay(dev, apdev, params)
5749    finally:
5750        dev[0].set("dpp_config_processing", "0", allow_fail=True)
5751        dev[1].request("DPP_CONTROLLER_STOP")
5752
5753def test_dpp_controller_relay_chirp(dev, apdev, params):
5754    """DPP Controller/Relay with chirping"""
5755    try:
5756        run_dpp_controller_relay(dev, apdev, params, chirp=True)
5757    finally:
5758        dev[0].set("dpp_config_processing", "0", allow_fail=True)
5759        dev[1].request("DPP_CONTROLLER_STOP")
5760
5761def test_dpp_controller_relay_chirp_duplicate(dev, apdev, params):
5762    """DPP Controller/Relay with chirping (duplicate)"""
5763    try:
5764        run_dpp_controller_relay(dev, apdev, params, chirp=True,
5765                                 duplicate=True)
5766    finally:
5767        dev[0].set("dpp_config_processing", "0", allow_fail=True)
5768        dev[1].request("DPP_CONTROLLER_STOP")
5769
5770def test_dpp_controller_relay_discover(dev, apdev, params):
5771    """DPP Controller/Relay with need to discover Controller"""
5772    try:
5773        run_dpp_controller_relay(dev, apdev, params, chirp=True, discover=True)
5774    finally:
5775        dev[0].set("dpp_config_processing", "0", allow_fail=True)
5776        dev[1].request("DPP_CONTROLLER_STOP")
5777
5778def run_dpp_controller_relay(dev, apdev, params, chirp=False, discover=False,
5779                             duplicate=False):
5780    check_dpp_capab(dev[0], min_ver=2)
5781    check_dpp_capab(dev[1], min_ver=2)
5782    cap_lo = params['prefix'] + ".lo.pcap"
5783
5784    with WlantestCapture('lo', cap_lo):
5785        run_dpp_controller_relay2(dev, apdev, params, chirp, discover,
5786                                  duplicate)
5787
5788def run_dpp_controller_relay2(dev, apdev, params, chirp=False, discover=False,
5789                              duplicate=False):
5790    # Controller
5791    conf_id = dev[1].dpp_configurator_add()
5792    dev[1].set("dpp_configurator_params",
5793               "conf=sta-dpp configurator=%d" % conf_id)
5794    id_c = dev[1].dpp_bootstrap_gen()
5795    uri_c = dev[1].request("DPP_BOOTSTRAP_GET_URI %d" % id_c)
5796    res = dev[1].request("DPP_BOOTSTRAP_INFO %d" % id_c)
5797    pkhash = None
5798    for line in res.splitlines():
5799        name, value = line.split('=')
5800        if name == "pkhash":
5801            pkhash = value
5802            break
5803    if not pkhash:
5804        raise Exception("Could not fetch public key hash from Controller")
5805    if "OK" not in dev[1].request("DPP_CONTROLLER_START"):
5806        raise Exception("Failed to start Controller")
5807
5808    # Relay
5809    params = {"ssid": "unconfigured",
5810              "channel": "6"}
5811    if discover:
5812        params["dpp_relay_port"] = "11111"
5813    else:
5814        params["dpp_controller"] = "ipaddr=127.0.0.1 pkhash=" + pkhash
5815    if chirp:
5816        params["channel"] = "11"
5817        params["dpp_configurator_connectivity"] = "1"
5818    relay = hostapd.add_ap(apdev[1], params)
5819    check_dpp_capab(relay)
5820
5821    # Enroll Relay to the network
5822    # TODO: Do this over TCP once direct Enrollee-over-TCP case is supported
5823    if chirp:
5824        id_h = relay.dpp_bootstrap_gen(chan="81/11", mac=True)
5825    else:
5826        id_h = relay.dpp_bootstrap_gen(chan="81/6", mac=True)
5827    uri_r = relay.request("DPP_BOOTSTRAP_GET_URI %d" % id_h)
5828    dev[1].dpp_auth_init(uri=uri_r, conf="ap-dpp", configurator=conf_id)
5829    wait_auth_success(relay, dev[1], configurator=dev[1], enrollee=relay)
5830    update_hapd_config(relay)
5831
5832    dev[0].flush_scan_cache()
5833
5834    # Initiate from Enrollee with broadcast DPP Authentication Request or
5835    # using chirping
5836    dev[0].set("dpp_config_processing", "2")
5837    if chirp:
5838        id1 = dev[0].dpp_bootstrap_gen()
5839        uri = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id1)
5840        idc = dev[1].dpp_qr_code(uri)
5841        dev[1].dpp_bootstrap_set(idc, conf="sta-dpp", configurator=conf_id)
5842        if duplicate:
5843            relay.set("ext_mgmt_frame_handling", "1")
5844        if "OK" not in dev[0].request("DPP_CHIRP own=%d iter=5" % id1):
5845            raise Exception("DPP_CHIRP failed")
5846        if duplicate:
5847            for i in range(10):
5848                msg = relay.mgmt_rx(timeout=30)
5849                if msg is None:
5850                    raise Exception("MGMT RX wait timed out")
5851                relay.request("MGMT_RX_PROCESS freq=2462 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(msg['frame']).decode())
5852                if msg['subtype'] == 13:
5853                    # Process duplicate Presence Announcement
5854                    relay.request("MGMT_RX_PROCESS freq=2462 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(msg['frame']).decode())
5855                    break
5856            relay.set("ext_mgmt_frame_handling", "0")
5857        ev = relay.wait_event(["DPP-RX"], timeout=30)
5858        if ev is None:
5859            raise Exception("Presence Announcement not seen")
5860        if "type=13" not in ev:
5861            raise Exception("Unexpected DPP frame received: " + ev)
5862    else:
5863        dev[0].dpp_auth_init(uri=uri_c, role="enrollee")
5864    if discover:
5865        ev = relay.wait_event(["DPP-RELAY-NEEDS-CONTROLLER"], timeout=30)
5866        if ev is None:
5867            raise Exception("Relay did not indicate need for a Controller")
5868        cmd = "DPP_RELAY_ADD_CONTROLLER 127.0.0.1 " + pkhash
5869        if "OK" not in relay.request(cmd):
5870            raise Exception("Could not add Controller to Relay")
5871
5872    wait_auth_success(dev[1], dev[0], configurator=dev[1], enrollee=dev[0],
5873                      allow_enrollee_failure=True,
5874                      allow_configurator_failure=True,
5875                      timeout=100 if discover else 5)
5876    ev = dev[0].wait_event(["DPP-NETWORK-ID"], timeout=1)
5877    if ev is None:
5878        raise Exception("DPP network id not reported")
5879    network = int(ev.split(' ')[1])
5880    dev[0].wait_connected()
5881    relay.wait_sta()
5882    dev[0].dump_monitor()
5883    dev[0].request("DISCONNECT")
5884    dev[0].wait_disconnected()
5885    dev[0].dump_monitor()
5886    relay.wait_sta_disconnect()
5887
5888    if "OK" not in dev[0].request("DPP_RECONFIG %s" % network):
5889        raise Exception("Failed to start reconfiguration")
5890    ev = dev[0].wait_event(["DPP-NETWORK-ID"], timeout=15)
5891    if ev is None:
5892        raise Exception("DPP network id not reported for reconfiguration")
5893    network2 = int(ev.split(' ')[1])
5894    if network == network2:
5895        raise Exception("Network ID did not change")
5896    dev[0].wait_connected()
5897    relay.wait_sta()
5898
5899def test_dpp_controller_init_through_relay(dev, apdev, params):
5900    """DPP Controller initiating through Relay"""
5901    try:
5902        run_dpp_controller_init_through_relay(dev, apdev, params)
5903    finally:
5904        dev[0].set("dpp_config_processing", "0", allow_fail=True)
5905        dev[1].request("DPP_CONTROLLER_STOP")
5906
5907def test_dpp_controller_init_through_relay_dynamic(dev, apdev, params):
5908    """DPP Controller initiating through Relay (dynamic addition)"""
5909    try:
5910        run_dpp_controller_init_through_relay(dev, apdev, params, dynamic=True)
5911    finally:
5912        dev[0].set("dpp_config_processing", "0", allow_fail=True)
5913        dev[1].request("DPP_CONTROLLER_STOP")
5914
5915def test_dpp_controller_init_through_relay_add(dev, apdev, params):
5916    """DPP Controller initiating through Relay (add Controller connection)"""
5917    try:
5918        run_dpp_controller_init_through_relay(dev, apdev, params, add=True)
5919    finally:
5920        dev[0].set("dpp_config_processing", "0", allow_fail=True)
5921        dev[1].request("DPP_CONTROLLER_STOP")
5922
5923def run_dpp_controller_init_through_relay(dev, apdev, params, dynamic=False,
5924                                          add=False):
5925    check_dpp_capab(dev[0], min_ver=2)
5926    check_dpp_capab(dev[1], min_ver=2)
5927    cap_lo = os.path.join(params['prefix'], ".lo.pcap")
5928
5929    with WlantestCapture('lo', cap_lo):
5930        run_dpp_controller_init_through_relay2(dev, apdev, params, dynamic,
5931                                               add)
5932
5933def run_dpp_controller_init_through_relay2(dev, apdev, params, dynamic=False,
5934                                           add=False):
5935    # Controller
5936    conf_id = dev[1].dpp_configurator_add()
5937    dev[1].set("dpp_configurator_params",
5938               "conf=sta-dpp configurator=%d" % conf_id)
5939    if not dynamic:
5940        id_c = dev[1].dpp_bootstrap_gen()
5941        res = dev[1].request("DPP_BOOTSTRAP_INFO %d" % id_c)
5942        pkhash = None
5943        for line in res.splitlines():
5944            name, value = line.split('=')
5945            if name == "pkhash":
5946                pkhash = value
5947                break
5948        if not pkhash:
5949            raise Exception("Could not fetch public key hash from Controller")
5950    if "OK" not in dev[1].request("DPP_CONTROLLER_START"):
5951        raise Exception("Failed to start Controller")
5952
5953    # Relay
5954    port = 11111
5955    params = {"ssid": "unconfigured",
5956              "channel": "6",
5957              "dpp_relay_port": str(port)}
5958    if not dynamic and not add:
5959        params["dpp_controller"] = "ipaddr=127.0.0.1 pkhash=" + pkhash
5960    relay = hostapd.add_ap(apdev[0], params)
5961    check_dpp_capab(relay)
5962
5963    # Enroll Relay to the network
5964    # TODO: Do this over TCP once direct Enrollee-over-TCP case is supported
5965    id_h = relay.dpp_bootstrap_gen(chan="81/6", mac=True)
5966    uri_r = relay.request("DPP_BOOTSTRAP_GET_URI %d" % id_h)
5967    dev[1].dpp_auth_init(uri=uri_r, conf="ap-dpp", configurator=conf_id)
5968    wait_auth_success(relay, dev[1], configurator=dev[1], enrollee=relay)
5969    update_hapd_config(relay)
5970
5971    dev[0].flush_scan_cache()
5972
5973    # Initiate from Controller with broadcast DPP Authentication Request
5974    dev[0].set("dpp_config_processing", "2")
5975    dev[0].dpp_listen(2437)
5976    id_e = dev[0].dpp_bootstrap_gen()
5977    uri_e = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id_e)
5978    dev[1].dpp_auth_init(uri=uri_e, conf="sta-dpp", configurator=conf_id,
5979                         tcp_addr="127.0.0.1", tcp_port=str(port))
5980    wait_auth_success(dev[1], dev[0], configurator=dev[1], enrollee=dev[0],
5981                      allow_enrollee_failure=True,
5982                      allow_configurator_failure=True)
5983    ev = dev[0].wait_event(["DPP-NETWORK-ID"], timeout=1)
5984    if ev is None:
5985        raise Exception("DPP network id not reported")
5986    network = int(ev.split(' ')[1])
5987    dev[0].wait_connected()
5988    relay.wait_sta()
5989    dev[0].dump_monitor()
5990    dev[0].request("DISCONNECT")
5991    dev[0].wait_disconnected()
5992    relay.wait_sta_disconnect()
5993    dev[0].dump_monitor()
5994
5995    if add:
5996        cmd = "DPP_RELAY_ADD_CONTROLLER 127.0.0.1 " + pkhash
5997        if "OK" not in relay.request(cmd):
5998            raise Exception("Could not add Controller to Relay")
5999    if not dynamic:
6000        if "OK" not in dev[0].request("DPP_RECONFIG %s" % network):
6001            raise Exception("Failed to start reconfiguration")
6002        ev = dev[0].wait_event(["DPP-NETWORK-ID"], timeout=15)
6003        if ev is None:
6004            raise Exception("DPP network id not reported for reconfiguration")
6005        network2 = int(ev.split(' ')[1])
6006        if network == network2:
6007            raise Exception("Network ID did not change")
6008        dev[0].wait_connected()
6009    if add:
6010        relay.request("DPP_RELAY_REMOVE_CONTROLLER 127.0.0.1")
6011
6012class MyTCPServer(TCPServer):
6013    def __init__(self, addr, handler):
6014        self.allow_reuse_address = True
6015        TCPServer.__init__(self, addr, handler)
6016
6017class DPPControllerServer(StreamRequestHandler):
6018        def handle(self):
6019            data = self.rfile.read()
6020            # Do not reply
6021
6022def test_dpp_relay_incomplete_connections(dev, apdev):
6023    """DPP Relay and incomplete connections"""
6024    check_dpp_capab(dev[0], min_ver=2)
6025    check_dpp_capab(dev[1], min_ver=2)
6026
6027    id_c = dev[1].dpp_bootstrap_gen()
6028    uri_c = dev[1].request("DPP_BOOTSTRAP_GET_URI %d" % id_c)
6029    res = dev[1].request("DPP_BOOTSTRAP_INFO %d" % id_c)
6030    pkhash = None
6031    for line in res.splitlines():
6032        name, value = line.split('=')
6033        if name == "pkhash":
6034            pkhash = value
6035            break
6036    if not pkhash:
6037        raise Exception("Could not fetch public key hash from Controller")
6038
6039    params = {"ssid": "unconfigured",
6040              "channel": "6",
6041              "dpp_controller": "ipaddr=127.0.0.1 pkhash=" + pkhash}
6042    hapd = hostapd.add_ap(apdev[0], params)
6043    check_dpp_capab(hapd)
6044
6045    server = MyTCPServer(("127.0.0.1", 8908), DPPControllerServer)
6046    server.timeout = 30
6047
6048    hapd.set("ext_mgmt_frame_handling", "1")
6049    dev[0].dpp_auth_init(uri=uri_c, role="enrollee")
6050    msg = hapd.mgmt_rx()
6051    if msg is None:
6052        raise Exception("MGMT RX wait timed out")
6053    dev[0].request("DPP_STOP_LISTEN")
6054    frame = msg['frame']
6055    for i in range(20):
6056        if i == 14:
6057            time.sleep(20)
6058        addr = struct.pack('6B', 0x02, 0, 0, 0, 0, i)
6059        tmp = frame[0:10] + addr + frame[16:]
6060        hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(tmp).decode())
6061        ev = hapd.wait_event(["DPP-FAIL"], timeout=0.1)
6062        if ev:
6063            raise Exception("DPP relay failed [%d]: %s" % (i + 1, ev))
6064
6065    server.server_close()
6066
6067def test_dpp_tcp(dev, apdev, params):
6068    """DPP over TCP"""
6069    prefix = "dpp_tcp"
6070    cap_lo = os.path.join(params['logdir'], prefix + ".lo.pcap")
6071    try:
6072        run_dpp_tcp(dev[0], dev[1], cap_lo)
6073    finally:
6074        dev[1].request("DPP_CONTROLLER_STOP")
6075
6076def test_dpp_tcp_port(dev, apdev, params):
6077    """DPP over TCP and specified port"""
6078    prefix = "dpp_tcp_port"
6079    cap_lo = os.path.join(params['logdir'], prefix + ".lo.pcap")
6080    try:
6081        run_dpp_tcp(dev[0], dev[1], cap_lo, port="23456")
6082    finally:
6083        dev[1].request("DPP_CONTROLLER_STOP")
6084
6085def test_dpp_tcp_mutual(dev, apdev, params):
6086    """DPP over TCP (mutual)"""
6087    cap_lo = os.path.join(params['prefix'], ".lo.pcap")
6088    try:
6089        run_dpp_tcp(dev[0], dev[1], cap_lo, mutual=True)
6090    finally:
6091        dev[1].request("DPP_CONTROLLER_STOP")
6092
6093def test_dpp_tcp_mutual_hostapd_conf(dev, apdev, params):
6094    """DPP over TCP (mutual, hostapd as Configurator)"""
6095    cap_lo = os.path.join(params['prefix'], ".lo.pcap")
6096    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured"})
6097    run_dpp_tcp(dev[0], hapd, cap_lo, mutual=True)
6098
6099def run_dpp_tcp(dev0, dev1, cap_lo, port=None, mutual=False):
6100    check_dpp_capab(dev0)
6101    check_dpp_capab(dev1)
6102
6103    with WlantestCapture('lo', cap_lo):
6104        run_dpp_tcp2(dev0, dev1, cap_lo, port, mutual)
6105
6106def run_dpp_tcp2(dev0, dev1, cap_lo, port=None, mutual=False):
6107    # Controller
6108    conf_id = dev1.dpp_configurator_add()
6109    dev1.set("dpp_configurator_params",
6110             " conf=sta-dpp configurator=%d" % conf_id)
6111    id_c = dev1.dpp_bootstrap_gen()
6112    uri_c = dev1.request("DPP_BOOTSTRAP_GET_URI %d" % id_c)
6113    res = dev1.request("DPP_BOOTSTRAP_INFO %d" % id_c)
6114    pkhash = None
6115    for line in res.splitlines():
6116        name, value = line.split('=')
6117        if name == "pkhash":
6118            pkhash = value
6119            break
6120    if not pkhash:
6121        raise Exception("Could not fetch public key hash from Controller")
6122    req = "DPP_CONTROLLER_START"
6123    if port:
6124        req += " tcp_port=" + port
6125    if mutual:
6126        req += " qr=mutual"
6127        id0 = dev0.dpp_bootstrap_gen()
6128        uri0 = dev0.request("DPP_BOOTSTRAP_GET_URI %d" % id0)
6129        own = id0
6130    else:
6131        own = None
6132    if "OK" not in dev1.request(req):
6133        raise Exception("Failed to start Controller")
6134
6135    # Initiate from Enrollee with broadcast DPP Authentication Request
6136    dev0.dpp_auth_init(uri=uri_c, own=own, role="enrollee",
6137                       tcp_addr="127.0.0.1", tcp_port=port)
6138
6139    if mutual:
6140        ev = dev0.wait_event(["DPP-RESPONSE-PENDING"], timeout=5)
6141        if ev is None:
6142            raise Exception("Pending response not reported")
6143        ev = dev1.wait_event(["DPP-SCAN-PEER-QR-CODE"], timeout=5)
6144        if ev is None:
6145            raise Exception("QR Code scan for mutual authentication not requested")
6146
6147        time.sleep(0.1)
6148
6149        id1 = dev1.dpp_qr_code(uri0)
6150
6151        ev = dev0.wait_event(["DPP-AUTH-DIRECTION"], timeout=5)
6152        if ev is None:
6153            raise Exception("DPP authentication direction not indicated (Initiator)")
6154        if "mutual=1" not in ev:
6155            raise Exception("Mutual authentication not used")
6156
6157    wait_auth_success(dev1, dev0, configurator=dev1, enrollee=dev0,
6158                      allow_enrollee_failure=True,
6159                      allow_configurator_failure=True)
6160
6161def test_dpp_tcp_conf_init(dev, apdev, params):
6162    """DPP over TCP (Configurator initiates)"""
6163    cap_lo = os.path.join(params['prefix'], ".lo.pcap")
6164    try:
6165        run_dpp_tcp_conf_init(dev[0], dev[1], cap_lo)
6166    finally:
6167        dev[1].request("DPP_CONTROLLER_STOP")
6168
6169def test_dpp_tcp_conf_init_hostapd_enrollee(dev, apdev, params):
6170    """DPP over TCP (Configurator initiates, hostapd as Enrollee)"""
6171    cap_lo = os.path.join(params['prefix'], ".lo.pcap")
6172    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured"})
6173    run_dpp_tcp_conf_init(dev[0], hapd, cap_lo, conf="ap-dpp")
6174
6175def run_dpp_tcp_conf_init(dev0, dev1, cap_lo, port=None, conf="sta-dpp"):
6176    check_dpp_capab(dev0, min_ver=2)
6177    check_dpp_capab(dev1, min_ver=2)
6178
6179    with WlantestCapture('lo', cap_lo):
6180        run_dpp_tcp_conf_init2(dev0, dev1, cap_lo, port, conf)
6181
6182def run_dpp_tcp_conf_init2(dev0, dev1, cap_lo, port=None, conf="sta-dpp"):
6183    id_c = dev1.dpp_bootstrap_gen()
6184    uri_c = dev1.request("DPP_BOOTSTRAP_GET_URI %d" % id_c)
6185    res = dev1.request("DPP_BOOTSTRAP_INFO %d" % id_c)
6186    req = "DPP_CONTROLLER_START role=enrollee"
6187    if port:
6188        req += " tcp_port=" + port
6189    if "OK" not in dev1.request(req):
6190        raise Exception("Failed to start Controller")
6191
6192    conf_id = dev0.dpp_configurator_add()
6193    dev0.dpp_auth_init(uri=uri_c, role="configurator", conf=conf,
6194                       configurator=conf_id,
6195                       tcp_addr="127.0.0.1", tcp_port=port)
6196    wait_auth_success(dev1, dev0, configurator=dev0, enrollee=dev1,
6197                      allow_enrollee_failure=True,
6198                      allow_configurator_failure=True)
6199
6200def test_dpp_tcp_controller_management_hostapd(dev, apdev, params):
6201    """DPP Controller management in hostapd"""
6202    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured"})
6203    check_dpp_capab(hapd)
6204    conf_id = hapd.dpp_configurator_add()
6205    if "OK" not in hapd.request("DPP_CONTROLLER_START"):
6206        raise Exception("Failed to start Controller")
6207    if "FAIL" not in hapd.request("DPP_CONTROLLER_START"):
6208        raise Exception("DPP_CONTROLLER_START succeeded while already running Controller")
6209    hapd.request("DPP_CONTROLLER_STOP")
6210    hapd.dpp_configurator_remove(conf_id)
6211    if "FAIL" not in hapd.request("DPP_CONFIGURATOR_REMOVE %d" % conf_id):
6212        raise Exception("Removal of unknown Configurator accepted")
6213
6214def test_dpp_tcp_controller_management_hostapd2(dev, apdev, params):
6215    """DPP Controller management in hostapd over interface addition/removal"""
6216    check_dpp_capab(dev[0], min_ver=2)
6217    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured"})
6218    check_dpp_capab(hapd, min_ver=2)
6219    hapd2 = hostapd.add_ap(apdev[1], {"ssid": "unconfigured"})
6220    check_dpp_capab(hapd2, min_ver=2)
6221    id_c = hapd.dpp_bootstrap_gen()
6222    uri_c = hapd.request("DPP_BOOTSTRAP_GET_URI %d" % id_c)
6223    if "OK" not in hapd.request("DPP_CONTROLLER_START role=enrollee"):
6224        raise Exception("Failed to start Controller")
6225
6226    conf_id = dev[0].dpp_configurator_add()
6227    dev[0].dpp_auth_init(uri=uri_c, role="configurator", conf="sta-dpp",
6228                       configurator=conf_id, tcp_addr="127.0.0.1")
6229    ev = dev[0].wait_event(["DPP-AUTH-SUCCESS"], timeout=5)
6230    if ev is None:
6231        raise Exception("DPP Authentication did not succeed")
6232    ev = dev[0].wait_event(["DPP-CONF-SENT"], timeout=5)
6233    if ev is None:
6234        raise Exception("DPP Configuration did not succeed")
6235
6236    hapd_global = hostapd.HostapdGlobal(apdev)
6237    hapd_global.remove(apdev[0]['ifname'])
6238
6239    dev[0].dpp_auth_init(uri=uri_c, role="configurator", conf="sta-dpp",
6240                       configurator=conf_id, tcp_addr="127.0.0.1")
6241    ev = dev[0].wait_event(["DPP-AUTH-SUCCESS"], timeout=5)
6242    if ev is not None:
6243        raise Exception("Unexpected DPP Authentication success")
6244
6245def test_dpp_tcp_controller_start_failure(dev, apdev, params):
6246    """DPP Controller startup failure"""
6247    check_dpp_capab(dev[0])
6248
6249    try:
6250        if "OK" not in dev[0].request("DPP_CONTROLLER_START"):
6251            raise Exception("Could not start Controller")
6252        if "OK" in dev[0].request("DPP_CONTROLLER_START"):
6253            raise Exception("Second Controller start not rejected")
6254    finally:
6255        dev[0].request("DPP_CONTROLLER_STOP")
6256
6257    tests = ["dpp_controller_start",
6258             "eloop_sock_table_add_sock;?eloop_register_sock;dpp_controller_start"]
6259    for func in tests:
6260        with alloc_fail(dev[0], 1, func):
6261            if "FAIL" not in dev[0].request("DPP_CONTROLLER_START"):
6262                raise Exception("Failure not reported during OOM")
6263
6264def test_dpp_tcp_init_failure(dev, apdev, params):
6265    """DPP TCP init failure"""
6266    check_dpp_capab(dev[0])
6267    check_dpp_capab(dev[1])
6268    id_c = dev[1].dpp_bootstrap_gen()
6269    uri_c = dev[1].request("DPP_BOOTSTRAP_GET_URI %d" % id_c)
6270    peer = dev[0].dpp_qr_code(uri_c)
6271    tests = ["dpp_tcp_init",
6272             "eloop_sock_table_add_sock;?eloop_register_sock;dpp_tcp_init",
6273             "dpp_tcp_encaps"]
6274    cmd = "DPP_AUTH_INIT peer=%d tcp_addr=127.0.0.1" % peer
6275    for func in tests:
6276        with alloc_fail(dev[0], 1, func):
6277            if "FAIL" not in dev[0].request(cmd):
6278                raise Exception("DPP_AUTH_INIT accepted during OOM")
6279
6280def test_dpp_controller_rx_failure(dev, apdev, params):
6281    """DPP Controller RX failure"""
6282    check_dpp_capab(dev[0])
6283    check_dpp_capab(dev[1])
6284    try:
6285        run_dpp_controller_rx_failure(dev, apdev)
6286    finally:
6287        dev[0].request("DPP_CONTROLLER_STOP")
6288
6289def run_dpp_controller_rx_failure(dev, apdev):
6290    if "OK" not in dev[0].request("DPP_CONTROLLER_START"):
6291        raise Exception("Could not start Controller")
6292    id_c = dev[0].dpp_bootstrap_gen()
6293    uri_c = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id_c)
6294    peer = dev[1].dpp_qr_code(uri_c)
6295    tests = ["dpp_controller_tcp_cb",
6296             "eloop_sock_table_add_sock;?eloop_register_sock;dpp_controller_tcp_cb",
6297             "dpp_controller_rx",
6298             "dpp_controller_rx_auth_req",
6299             "wpabuf_alloc;=dpp_tcp_send_msg;dpp_controller_rx_auth_req"]
6300    cmd = "DPP_AUTH_INIT peer=%d tcp_addr=127.0.0.1" % peer
6301    for func in tests:
6302        with alloc_fail(dev[0], 1, func):
6303            if "OK" not in dev[1].request(cmd):
6304                raise Exception("Failed to initiate TCP connection")
6305            wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
6306
6307def test_dpp_controller_rx_errors(dev, apdev, params):
6308    """DPP Controller RX error cases"""
6309    check_dpp_capab(dev[0])
6310    check_dpp_capab(dev[1])
6311    try:
6312        run_dpp_controller_rx_errors(dev, apdev)
6313    finally:
6314        dev[0].request("DPP_CONTROLLER_STOP")
6315
6316def run_dpp_controller_rx_errors(dev, apdev):
6317    if "OK" not in dev[0].request("DPP_CONTROLLER_START"):
6318        raise Exception("Could not start Controller")
6319
6320    addr = ("127.0.0.1", 8908)
6321
6322    tests = [b"abc",
6323             b"abcd",
6324             b"\x00\x00\x00\x00",
6325             b"\x00\x00\x00\x01",
6326             b"\x00\x00\x00\x01\x09",
6327             b"\x00\x00\x00\x07\x09\x50\x6f\x9a\x1a\xff\xff",
6328             b"\x00\x00\x00\x07\x09\x50\x6f\x9a\x1a\x01\xff",
6329             b"\x00\x00\x00\x07\x09\x50\x6f\x9a\x1a\x01\x00",
6330             b"\x00\x00\x00\x08\x09\x50\x6f\x9a\x1a\x01\x00\xff",
6331             b"\x00\x00\x00\x01\x0a",
6332             b"\x00\x00\x00\x04\x0a\xff\xff\xff",
6333             b"\x00\x00\x00\x01\x0b",
6334             b"\x00\x00\x00\x08\x0b\xff\xff\xff\xff\xff\xff\xff",
6335             b"\x00\x00\x00\x08\x0b\xff\x00\x00\xff\xff\xff\xff",
6336             b"\x00\x00\x00\x08\x0b\xff\x00\x00\xff\xff\x6c\x00",
6337             b"\x00\x00\x00\x0a\x0b\xff\x00\x00\xff\xff\x6c\x02\xff\xff",
6338             b"\x00\x00\x00\x10\x0b\xff\x00\x00\xff\xff\x6c\x08\xff\xdd\x05\x50\x6f\x9a\x1a\x01",
6339             b"\x00\x00\x00\x12\x0b\xff\x00\x00\xff\xff\x6c\x08\xff\xdd\x05\x50\x6f\x9a\x1a\x01\x00\x00",
6340             b"\x00\x00\x00\x01\xff",
6341             b"\x00\x00\x00\x01\xff\xee"]
6342    #define WLAN_PA_GAS_INITIAL_REQ 10
6343    #define WLAN_PA_GAS_INITIAL_RESP 11
6344
6345    for t in tests:
6346        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
6347                             socket.IPPROTO_TCP)
6348        sock.settimeout(0.1)
6349        sock.connect(addr)
6350        sock.send(t)
6351        sock.shutdown(1)
6352        try:
6353            sock.recv(10)
6354        except socket.timeout:
6355            pass
6356        sock.close()
6357
6358def test_dpp_conn_status_success(dev, apdev):
6359    """DPP connection status - success"""
6360    try:
6361        run_dpp_conn_status(dev, apdev)
6362    finally:
6363        dev[0].set("dpp_config_processing", "0", allow_fail=True)
6364
6365def test_dpp_conn_status_wrong_passphrase(dev, apdev):
6366    """DPP connection status - wrong passphrase"""
6367    try:
6368        run_dpp_conn_status(dev, apdev, result=2)
6369    finally:
6370        dev[0].set("dpp_config_processing", "0", allow_fail=True)
6371
6372def test_dpp_conn_status_no_ap(dev, apdev):
6373    """DPP connection status - no AP"""
6374    try:
6375        run_dpp_conn_status(dev, apdev, result=10)
6376    finally:
6377        dev[0].set("dpp_config_processing", "0", allow_fail=True)
6378
6379def test_dpp_conn_status_connector_mismatch(dev, apdev):
6380    """DPP connection status - invalid Connector"""
6381    try:
6382        run_dpp_conn_status(dev, apdev, result=8)
6383    finally:
6384        dev[0].set("dpp_config_processing", "0", allow_fail=True)
6385
6386def test_dpp_conn_status_assoc_reject(dev, apdev):
6387    """DPP connection status - association rejection"""
6388    try:
6389        dev[0].request("TEST_ASSOC_IE 30020000")
6390        run_dpp_conn_status(dev, apdev, assoc_reject=True)
6391    finally:
6392        dev[0].set("dpp_config_processing", "0", allow_fail=True)
6393
6394def run_dpp_conn_status(dev, apdev, result=0, assoc_reject=False):
6395    check_dpp_capab(dev[0], min_ver=2)
6396    check_dpp_capab(dev[1], min_ver=2)
6397
6398    if result != 10:
6399        if result == 7 or result == 8:
6400            params = {"ssid": "dpp-status",
6401                      "wpa": "2",
6402                      "wpa_key_mgmt": "DPP",
6403                      "ieee80211w": "2",
6404                      "rsn_pairwise": "CCMP",
6405                      "dpp_connector": params1_ap_connector,
6406                      "dpp_csign": params1_csign,
6407                      "dpp_netaccesskey": params1_ap_netaccesskey}
6408        else:
6409            if result == 2:
6410                passphrase = "wrong passphrase"
6411            else:
6412                passphrase = "secret passphrase"
6413            params = hostapd.wpa2_params(ssid="dpp-status",
6414                                         passphrase=passphrase)
6415        try:
6416            hapd = hostapd.add_ap(apdev[0], params)
6417        except:
6418            raise HwsimSkip("DPP not supported")
6419
6420    dev[0].request("SET sae_groups ")
6421    dev[0].set("dpp_config_processing", "2")
6422    id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
6423    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
6424
6425    dev[0].dpp_listen(2412)
6426    if result == 7 or result == 8:
6427        conf = 'sta-dpp'
6428        passphrase = None
6429        configurator = dev[1].dpp_configurator_add()
6430    else:
6431        conf = 'sta-psk'
6432        passphrase = "secret passphrase"
6433        configurator = None
6434    dev[1].dpp_auth_init(uri=uri0, conf=conf, ssid="dpp-status",
6435                         passphrase=passphrase, configurator=configurator,
6436                         conn_status=True)
6437    res = wait_auth_success(dev[0], dev[1], configurator=dev[1],
6438                            enrollee=dev[0])
6439    if 'wait_conn_status' not in res:
6440        raise Exception("Configurator did not request connection status")
6441
6442    if assoc_reject and result == 0:
6443        result = 2
6444    ev = dev[1].wait_event(["DPP-CONN-STATUS-RESULT"], timeout=20)
6445    if ev is None:
6446        raise Exception("No connection status reported")
6447    if "timeout" in ev:
6448        raise Exception("Connection status result timeout")
6449    if "result=%d" % result not in ev:
6450        raise Exception("Unexpected connection status result: " + ev)
6451    if "ssid=dpp-status" not in ev:
6452        raise Exception("SSID not reported")
6453
6454    if result == 0:
6455        dev[0].wait_connected()
6456    if result == 10 and "channel_list=" not in ev:
6457        raise Exception("Channel list not reported for no-AP")
6458
6459def test_dpp_conn_status_success_hostapd_configurator(dev, apdev):
6460    """DPP connection status - success with hostapd as Configurator"""
6461    try:
6462        run_dpp_conn_status_hostapd_configurator(dev, apdev)
6463    finally:
6464        dev[0].set("dpp_config_processing", "0", allow_fail=True)
6465
6466def run_dpp_conn_status_hostapd_configurator(dev, apdev):
6467    check_dpp_capab(dev[0])
6468    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
6469                                     "channel": "1"})
6470    check_dpp_capab(hapd)
6471    conf_id = hapd.dpp_configurator_add()
6472
6473    cmd = "DPP_CONFIGURATOR_SIGN conf=ap-dpp configurator=%d" % conf_id
6474    res = hapd.request(cmd)
6475    if "FAIL" in res:
6476        raise Exception("Failed to generate own configuration")
6477    update_hapd_config(hapd)
6478
6479    id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
6480    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
6481    id1 = hapd.dpp_qr_code(uri0)
6482    res = hapd.request("DPP_BOOTSTRAP_INFO %d" % id1)
6483    if "FAIL" in res:
6484        raise Exception("DPP_BOOTSTRAP_INFO failed")
6485    if "type=QRCODE" not in res:
6486        raise Exception("DPP_BOOTSTRAP_INFO did not report correct type")
6487    if "mac_addr=" + dev[0].own_addr() not in res:
6488        raise Exception("DPP_BOOTSTRAP_INFO did not report correct mac_addr")
6489    dev[0].set("dpp_config_processing", "2")
6490    dev[0].dpp_listen(2412)
6491    hapd.dpp_auth_init(peer=id1, configurator=conf_id, conf="sta-dpp",
6492                       conn_status=True)
6493    res = wait_auth_success(dev[0], hapd, configurator=hapd, enrollee=dev[0])
6494    if 'wait_conn_status' not in res:
6495        raise Exception("Configurator did not request connection status")
6496    ev = hapd.wait_event(["DPP-CONN-STATUS-RESULT"], timeout=20)
6497    if ev is None:
6498        raise Exception("No connection status reported")
6499    if "result=0" not in ev:
6500        raise Exception("Unexpected connection status: " + ev)
6501
6502def test_dpp_mud_url(dev, apdev):
6503    """DPP MUD URL"""
6504    check_dpp_capab(dev[0])
6505    try:
6506        dev[0].set("dpp_name", "Test Enrollee")
6507        dev[0].set("dpp_mud_url", "https://example.com/mud")
6508        run_dpp_qr_code_auth_unicast(dev, apdev, None)
6509    finally:
6510        dev[0].set("dpp_mud_url", "")
6511        dev[0].set("dpp_name", "Test")
6512
6513def test_dpp_mud_url_hostapd(dev, apdev):
6514    """DPP MUD URL from hostapd"""
6515    check_dpp_capab(dev[0])
6516    check_dpp_capab(dev[1])
6517    params = {"ssid": "unconfigured",
6518              "dpp_name": "AP Enrollee",
6519              "dpp_mud_url": "https://example.com/mud"}
6520    hapd = hostapd.add_ap(apdev[0], params)
6521    check_dpp_capab(hapd)
6522
6523    id_h = hapd.dpp_bootstrap_gen(chan="81/1", mac=True)
6524    uri = hapd.request("DPP_BOOTSTRAP_GET_URI %d" % id_h)
6525
6526    conf_id = dev[0].dpp_configurator_add()
6527    dev[0].dpp_auth_init(uri=uri, conf="ap-dpp", configurator=conf_id)
6528    wait_auth_success(hapd, dev[0], configurator=dev[0], enrollee=hapd)
6529    update_hapd_config(hapd)
6530
6531def test_dpp_config_save(dev, apdev, params):
6532    """DPP configuration saving"""
6533    config = os.path.join(params['logdir'], 'dpp_config_save.conf')
6534    run_dpp_config_save(dev, apdev, config, "test", '"test"')
6535
6536def test_dpp_config_save2(dev, apdev, params):
6537    """DPP configuration saving (2)"""
6538    config = os.path.join(params['logdir'], 'dpp_config_save2.conf')
6539    run_dpp_config_save(dev, apdev, config, "\\u0001*", '012a')
6540
6541def test_dpp_config_save3(dev, apdev, params):
6542    """DPP configuration saving (3)"""
6543    config = os.path.join(params['logdir'], 'dpp_config_save3.conf')
6544    run_dpp_config_save(dev, apdev, config, "\\u0001*\\u00c2\\u00bc\\u00c3\\u009e\\u00c3\\u00bf", '012ac2bcc39ec3bf')
6545
6546def run_dpp_config_save(dev, apdev, config, conf_ssid, exp_ssid):
6547    check_dpp_capab(dev[1])
6548    with open(config, "w") as f:
6549        f.write("update_config=1\n" +
6550                "dpp_config_processing=1\n")
6551    wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
6552    wpas.interface_add("wlan5", config=config)
6553    check_dpp_capab(wpas)
6554    conf = '{"wi-fi_tech":"infra", "discovery":{"ssid":"' + conf_ssid + '"},"cred":{"akm":"psk","pass":"secret passphrase"}}'
6555    dev[1].set("dpp_config_obj_override", conf)
6556    dpp_dev = [wpas, dev[1]]
6557    run_dpp_qr_code_auth_unicast(dpp_dev, apdev, "prime256v1",
6558                                 require_conf_success=True)
6559    if "OK" not in wpas.request("SAVE_CONFIG"):
6560        raise Exception("Failed to save configuration file")
6561    with open(config, "r") as f:
6562        data = f.read()
6563        logger.info("Saved configuration:\n" + data)
6564        if 'ssid=' + exp_ssid + '\n' not in data:
6565            raise Exception("SSID not saved")
6566        if 'psk="secret passphrase"' not in data:
6567            raise Exception("Passphtase not saved")
6568
6569def test_dpp_nfc_uri(dev, apdev):
6570    """DPP bootstrapping via NFC URI record"""
6571    check_dpp_capab(dev[0])
6572    check_dpp_capab(dev[1])
6573
6574    id = dev[0].dpp_bootstrap_gen(type="nfc-uri", chan="81/1", mac=True)
6575    uri = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id)
6576    logger.info("Generated URI: " + uri)
6577    info = dev[0].request("DPP_BOOTSTRAP_INFO %d" % id)
6578    logger.info("Bootstrapping info:\n" + info)
6579    if "type=NFC-URI" not in info:
6580        raise Exception("Unexpected bootstrapping info contents")
6581
6582    dev[0].dpp_listen(2412)
6583    conf_id = dev[1].dpp_configurator_add()
6584    dev[1].dpp_auth_init(nfc_uri=uri, configurator=conf_id, conf="sta-dpp")
6585    wait_auth_success(dev[0], dev[1], configurator=dev[1], enrollee=dev[0])
6586
6587def test_dpp_nfc_uri_hostapd(dev, apdev):
6588    """DPP bootstrapping via NFC URI record (hostapd)"""
6589    check_dpp_capab(dev[0])
6590
6591    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured"})
6592    check_dpp_capab(hapd)
6593
6594    id = hapd.dpp_bootstrap_gen(type="nfc-uri", chan="81/1", mac=True)
6595    uri = hapd.request("DPP_BOOTSTRAP_GET_URI %d" % id)
6596    logger.info("Generated URI: " + uri)
6597    info = hapd.request("DPP_BOOTSTRAP_INFO %d" % id)
6598    logger.info("Bootstrapping info:\n" + info)
6599    if "type=NFC-URI" not in info:
6600        raise Exception("Unexpected bootstrapping info contents")
6601
6602    hapd.dpp_listen(2412)
6603    conf_id = dev[0].dpp_configurator_add()
6604    dev[0].dpp_auth_init(nfc_uri=uri, configurator=conf_id, conf="ap-dpp")
6605    wait_auth_success(hapd, dev[0], configurator=dev[0], enrollee=hapd)
6606
6607def test_dpp_nfc_uri_hostapd_tag_read(dev, apdev):
6608    """DPP bootstrapping via NFC URI record (hostapd reading tag)"""
6609    check_dpp_capab(dev[0])
6610
6611    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured"})
6612    check_dpp_capab(hapd)
6613
6614    id = dev[0].dpp_bootstrap_gen(type="nfc-uri", chan="81/1", mac=True)
6615    uri = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id)
6616    info = dev[0].request("DPP_BOOTSTRAP_INFO %d" % id)
6617    conf_id = dev[0].dpp_configurator_add()
6618    dev[0].set("dpp_configurator_params",
6619               "conf=ap-dpp configurator=%d" % conf_id)
6620    dev[0].dpp_listen(2412)
6621
6622    hapd.dpp_auth_init(nfc_uri=uri, role="enrollee")
6623    wait_auth_success(dev[0], hapd, configurator=dev[0], enrollee=hapd)
6624
6625def test_dpp_nfc_negotiated_handover(dev, apdev):
6626    """DPP bootstrapping via NFC negotiated handover"""
6627    run_dpp_nfc_negotiated_handover(dev)
6628
6629def test_dpp_nfc_negotiated_handover_diff_curve(dev, apdev):
6630    """DPP bootstrapping via NFC negotiated handover (different curve)"""
6631    run_dpp_nfc_negotiated_handover(dev, curve0="prime256v1",
6632                                    curve1="secp384r1")
6633
6634def test_dpp_nfc_negotiated_handover_hostapd_sel(dev, apdev):
6635    """DPP bootstrapping via NFC negotiated handover (hostapd as selector)"""
6636    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
6637                                     "channel": "6"})
6638    check_dpp_capab(hapd)
6639    run_dpp_nfc_negotiated_handover([dev[0], hapd], conf="ap-dpp")
6640
6641def test_dpp_nfc_negotiated_handover_hostapd_req(dev, apdev):
6642    """DPP bootstrapping via NFC negotiated handover (hostapd as requestor)"""
6643    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
6644                                     "channel": "6"})
6645    check_dpp_capab(hapd)
6646    run_dpp_nfc_negotiated_handover([hapd, dev[0]])
6647
6648def run_dpp_nfc_negotiated_handover(dev, curve0=None, curve1=None,
6649                                    conf="sta-dpp"):
6650    check_dpp_capab(dev[0])
6651    check_dpp_capab(dev[1])
6652
6653    id0 = dev[0].dpp_bootstrap_gen(type="nfc-uri", chan="81/6,11", mac=True,
6654                                   curve=curve0)
6655    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
6656    logger.info("Generated URI[0]: " + uri0)
6657    id1 = dev[1].dpp_bootstrap_gen(type="nfc-uri", chan="81/1,6,11", mac=True,
6658                                   curve=curve1)
6659    uri1 = dev[1].request("DPP_BOOTSTRAP_GET_URI %d" % id1)
6660    logger.info("Generated URI[1]: " + uri1)
6661
6662    # dev[0] acting as NFC Handover Requestor
6663    # dev[1] acting as NFC Handover Selector
6664    res = dev[1].request("DPP_NFC_HANDOVER_REQ own=%d uri=%s" % (id1, uri0))
6665    if "FAIL" in res:
6666        raise Exception("Failed to process NFC Handover Request")
6667    info = dev[1].request("DPP_BOOTSTRAP_INFO %d" % id1)
6668    logger.info("Updated local bootstrapping info:\n" + info)
6669    freq = None
6670    for line in info.splitlines():
6671        if line.startswith("use_freq="):
6672            freq = int(line.split('=')[1])
6673    if freq is None:
6674        raise Exception("Selected channel not indicated")
6675    uri1 = dev[1].request("DPP_BOOTSTRAP_GET_URI %d" % id1)
6676    logger.info("Updated URI[1]: " + uri1)
6677    dev[1].dpp_listen(freq)
6678    res = dev[0].request("DPP_NFC_HANDOVER_SEL own=%d uri=%s" % (id0, uri1))
6679    if "FAIL" in res:
6680        raise Exception("Failed to process NFC Handover Select")
6681    peer = int(res)
6682
6683    conf_id = dev[0].dpp_configurator_add()
6684    dev[0].dpp_auth_init(peer=peer, own=id0, configurator=conf_id,
6685                         conf=conf)
6686    wait_auth_success(dev[1], dev[0], configurator=dev[0], enrollee=dev[1])
6687
6688def test_dpp_nfc_errors_hostapd(dev, apdev):
6689    """DPP NFC operation failures in hostapd"""
6690    check_dpp_capab(dev[0])
6691    check_dpp_capab(dev[1])
6692
6693    id0 = dev[0].dpp_bootstrap_gen(type="nfc-uri", chan="81/11", mac=True,
6694                                   curve="secp384r1")
6695    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
6696
6697    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
6698                                     "channel": "6"})
6699    check_dpp_capab(hapd)
6700
6701    id_h = hapd.dpp_bootstrap_gen(type="nfc-uri", chan="81/6", mac=True)
6702    uri_h = hapd.request("DPP_BOOTSTRAP_GET_URI %d" % id_h)
6703
6704    tests = ["",
6705             "own=123456789",
6706             "own=%d" % id_h,
6707             "own=%d uri=%s" % (id_h, "foo")]
6708    for t in tests:
6709        if "FAIL" not in hapd.request("DPP_NFC_HANDOVER_REQ " + t):
6710            raise Exception("Invalid DPP_NFC_HANDOVER_REQ accepted")
6711        if "FAIL" not in hapd.request("DPP_NFC_HANDOVER_SEL " + t):
6712            raise Exception("Invalid DPP_NFC_HANDOVER_SEL accepted")
6713
6714    # DPP: Peer (NFC Handover Selector) used different curve
6715    if "FAIL" not in hapd.request("DPP_NFC_HANDOVER_SEL own=%d uri=%s" % (id_h, uri0)):
6716        raise Exception("Invalid DPP_NFC_HANDOVER_SEL accepted")
6717
6718    # DPP: No common channel found
6719    if "FAIL" not in hapd.request("DPP_NFC_HANDOVER_REQ own=%d uri=%s" % (id_h, uri0)):
6720        raise Exception("DPP_NFC_HANDOVER_REQ with local error accepted")
6721
6722def test_dpp_with_p2p_device(dev, apdev):
6723    """DPP exchange when driver uses a separate P2P Device interface"""
6724    check_dpp_capab(dev[0])
6725    with HWSimRadio(use_p2p_device=True) as (radio, iface):
6726        wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
6727        wpas.interface_add(iface)
6728        check_dpp_capab(wpas)
6729        id1 = wpas.dpp_bootstrap_gen(chan="81/1", mac=True)
6730        uri1 = wpas.request("DPP_BOOTSTRAP_GET_URI %d" % id1)
6731        wpas.dpp_listen(2412)
6732        time.sleep(7)
6733        dev[0].dpp_auth_init(uri=uri1)
6734        wait_auth_success(wpas, dev[0], configurator=dev[0], enrollee=wpas,
6735                          allow_enrollee_failure=True)
6736
6737@long_duration_test
6738def test_dpp_chirp(dev, apdev):
6739    """DPP chirp"""
6740    check_dpp_capab(dev[0])
6741    dev[0].flush_scan_cache()
6742
6743    params = {"ssid": "dpp",
6744              "channel": "11"}
6745    hapd = hostapd.add_ap(apdev[0], params)
6746    check_dpp_capab(hapd)
6747    dpp_cc = False
6748
6749    id1 = dev[0].dpp_bootstrap_gen(chan="81/1")
6750    if "OK" not in dev[0].request("DPP_CHIRP own=%d iter=5" % id1):
6751        raise Exception("DPP_CHIRP failed")
6752    chan1 = 0
6753    chan6 = 0
6754    chan11 = 0
6755    for i in range(30):
6756        ev = dev[0].wait_event(["DPP-CHIRP-STOPPED",
6757                                "DPP-TX "], timeout=60)
6758        if ev is None:
6759            raise Exception("DPP chirp stop not reported")
6760        if "DPP-CHIRP-STOPPED" in ev:
6761            break
6762        if "type=13" not in ev:
6763            continue
6764        freq = int(ev.split(' ')[2].split('=')[1])
6765        if freq == 2412:
6766            chan1 += 1
6767        elif freq == 2437:
6768            chan6 += 1
6769        elif freq == 2462:
6770            chan11 += 1
6771        if not dpp_cc:
6772            hapd.set("dpp_configurator_connectivity", "1")
6773            if "OK" not in hapd.request("UPDATE_BEACON"):
6774                raise Exception("UPDATE_BEACON failed")
6775            dpp_cc = True
6776    if chan1 != 5 or chan6 != 5 or chan11 != 1:
6777        raise Exception("Unexpected number of presence announcements sent: %d %d %d" % (chan1, chan6, chan11))
6778    ev = hapd.wait_event(["DPP-CHIRP-RX"], timeout=1)
6779    if ev is None:
6780        raise Exception("No chirp received on the AP")
6781    if "freq=2462" not in ev:
6782        raise Exception("Chirp reception reported on unexpected channel: " + ev)
6783    if "src=" + dev[0].own_addr() not in ev:
6784        raise Exception("Unexpected chirp source reported: " + ev)
6785
6786@long_duration_test
6787def test_dpp_chirp_listen(dev, apdev):
6788    """DPP chirp with listen"""
6789    check_dpp_capab(dev[0])
6790    check_dpp_capab(dev[1])
6791
6792    id1 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
6793    uri = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id1)
6794
6795    if "OK" not in dev[0].request("DPP_CHIRP own=%d iter=2 listen=2412" % id1):
6796        raise Exception("DPP_CHIRP failed")
6797    for i in range(30):
6798        ev = dev[0].wait_event(["DPP-CHIRP-STOPPED",
6799                                "DPP-TX "], timeout=60)
6800        if ev is None:
6801            raise Exception("DPP chirp stop not reported")
6802        if "DPP-CHIRP-STOPPED" in ev:
6803            break
6804
6805def test_dpp_chirp_configurator(dev, apdev):
6806    """DPP chirp with a standalone Configurator"""
6807    check_dpp_capab(dev[0])
6808    check_dpp_capab(dev[1])
6809
6810    id1 = dev[0].dpp_bootstrap_gen(chan="81/1")
6811    uri = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id1)
6812
6813    conf_id = dev[1].dpp_configurator_add()
6814    idc = dev[1].dpp_qr_code(uri)
6815    dev[1].dpp_bootstrap_set(idc, conf="sta-dpp", configurator=conf_id)
6816    dev[1].dpp_listen(2437)
6817
6818    if "OK" not in dev[0].request("DPP_CHIRP own=%d iter=2" % id1):
6819        raise Exception("DPP_CHIRP failed")
6820
6821    ev = dev[1].wait_event(["DPP-RX"], timeout=10)
6822    if ev is None:
6823        raise Exception("Presence Announcement not seen")
6824    if "type=13" not in ev:
6825        raise Exception("Unexpected DPP frame received: " + ev)
6826
6827    ev = dev[1].wait_event(["DPP-TX"], timeout=10)
6828    if ev is None:
6829        raise Exception("Authentication Request TX not seen")
6830    if "type=0" not in ev:
6831        raise Exception("Unexpected DPP frame TX: " + ev)
6832    if "dst=" + dev[0].own_addr() not in ev:
6833        raise Exception("Unexpected Authentication Request destination: " + ev)
6834
6835    wait_auth_success(dev[0], dev[1], dev[1], dev[0])
6836
6837def test_dpp_chirp_ap_as_configurator(dev, apdev):
6838    """DPP chirp with an AP as a standalone Configurator"""
6839    check_dpp_capab(dev[0], min_ver=2)
6840
6841    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured"})
6842    check_dpp_capab(hapd, min_ver=2)
6843
6844    id1 = dev[0].dpp_bootstrap_gen(chan="81/1")
6845    uri = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id1)
6846
6847    conf_id = hapd.dpp_configurator_add()
6848    idc = hapd.dpp_qr_code(uri)
6849    hapd.dpp_bootstrap_set(idc, conf="sta-dpp", configurator=conf_id)
6850    hapd.dpp_listen(2412)
6851
6852    if "OK" not in dev[0].request("DPP_CHIRP own=%d iter=2" % id1):
6853        raise Exception("DPP_CHIRP failed")
6854
6855    wait_auth_success(dev[0], hapd, hapd, dev[0])
6856
6857def test_dpp_chirp_configurator_inits(dev, apdev):
6858    """DPP chirp with a standalone Configurator initiating"""
6859    check_dpp_capab(dev[0])
6860    check_dpp_capab(dev[1])
6861
6862    id1 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
6863    uri = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id1)
6864
6865    conf_id = dev[1].dpp_configurator_add()
6866    idc = dev[1].dpp_qr_code(uri)
6867
6868    if "OK" not in dev[0].request("DPP_CHIRP own=%d iter=2 listen=2412" % id1):
6869        raise Exception("DPP_CHIRP failed")
6870    for i in range(2):
6871        ev = dev[0].wait_event(["DPP-TX "], timeout=10)
6872        if ev is None or "type=13" not in ev:
6873            raise Exception("Presence Announcement not sent")
6874
6875    dev[1].dpp_auth_init(uri=uri, conf="sta-dpp", configurator=conf_id)
6876    wait_auth_success(dev[0], dev[1], dev[1], dev[0], timeout=10)
6877
6878def test_dpp_chirp_ap(dev, apdev):
6879    """DPP chirp by an AP"""
6880    check_dpp_capab(dev[0], min_ver=2)
6881
6882    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
6883                                     "start_disabled": "1"})
6884    check_dpp_capab(hapd, min_ver=2)
6885
6886    id_h = hapd.dpp_bootstrap_gen(chan="81/1", mac=True)
6887    uri = hapd.request("DPP_BOOTSTRAP_GET_URI %d" % id_h)
6888
6889    conf_id = dev[0].dpp_configurator_add()
6890    idc = dev[0].dpp_qr_code(uri)
6891    dev[0].dpp_bootstrap_set(idc, conf="ap-dpp", configurator=conf_id)
6892    dev[0].dpp_listen(2437)
6893    if "OK" not in hapd.request("DPP_CHIRP own=%d iter=5" % id_h):
6894        raise Exception("DPP_CHIRP failed")
6895    wait_auth_success(hapd, dev[0], configurator=dev[0], enrollee=hapd,
6896                      timeout=20)
6897    update_hapd_config(hapd)
6898
6899@long_duration_test
6900def test_dpp_chirp_ap_5g(dev, apdev):
6901    """DPP chirp by an AP on 5 GHz"""
6902    check_dpp_capab(dev[0], min_ver=2)
6903
6904    try:
6905        hapd = None
6906        hapd2 = None
6907
6908        params = {"ssid": "unconfigured",
6909                  "country_code": "US",
6910                  "hw_mode": "a",
6911                  "channel": "40",
6912                  "dpp_configurator_connectivity": "1"}
6913        hapd2 = hostapd.add_ap(apdev[1], params)
6914        check_dpp_capab(hapd2, min_ver=2)
6915
6916        params = {"ssid": "unconfigured",
6917                  "country_code": "US",
6918                  "hw_mode": "a",
6919                  "channel": "36",
6920                  "start_disabled": "1"}
6921        hapd = hostapd.add_ap(apdev[0], params)
6922        check_dpp_capab(hapd, min_ver=2)
6923
6924        id_h = hapd.dpp_bootstrap_gen(chan="81/1", mac=True)
6925        uri = hapd.request("DPP_BOOTSTRAP_GET_URI %d" % id_h)
6926
6927        # First, check chirping iteration and timeout
6928        if "OK" not in hapd.request("DPP_CHIRP own=%d iter=2" % id_h):
6929            raise Exception("DPP_CHIRP failed")
6930        chan1 = 0
6931        chan6 = 0
6932        chan40 = 0
6933        chan149 = 0
6934        for i in range(30):
6935            ev = hapd.wait_event(["DPP-CHIRP-STOPPED", "DPP-TX "], timeout=60)
6936            if ev is None:
6937                raise Exception("DPP chirp stop not reported")
6938            if "DPP-CHIRP-STOPPED" in ev:
6939                break
6940            if "type=13" not in ev:
6941                continue
6942            freq = int(ev.split(' ')[2].split('=')[1])
6943            if freq == 2412:
6944                chan1 += 1
6945            elif freq == 2437:
6946                chan6 += 1
6947            elif freq == 5200:
6948                chan40 += 1
6949            elif freq == 5745:
6950                chan149 += 1
6951        if not chan1 or not chan6 or not chan40 or not chan149:
6952            raise Exception("Chirp not sent on all channels")
6953
6954        # Then, check successful chirping
6955        conf_id = dev[0].dpp_configurator_add()
6956        idc = dev[0].dpp_qr_code(uri)
6957        dev[0].dpp_bootstrap_set(idc, conf="ap-dpp", configurator=conf_id)
6958        dev[0].dpp_listen(5200)
6959        # Workaround for some strange issues in the Authentication Request frame
6960        # not getting transmitted. An extra wait of one second here seems to
6961        # avoid that?!
6962        time.sleep(1)
6963        if "OK" not in hapd.request("DPP_CHIRP own=%d iter=5" % id_h):
6964            raise Exception("DPP_CHIRP failed")
6965        wait_auth_success(hapd, dev[0], configurator=dev[0], enrollee=hapd,
6966                          timeout=40)
6967        update_hapd_config(hapd)
6968    finally:
6969        clear_regdom(hapd, dev)
6970        clear_scan_cache(apdev[0])
6971
6972def test_dpp_chirp_ap_errors(dev, apdev):
6973    """DPP chirp errors in hostapd"""
6974    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
6975                                     "start_disabled": "1"})
6976    check_dpp_capab(hapd, min_ver=2)
6977
6978    id_h = hapd.dpp_bootstrap_gen(chan="81/1", mac=True)
6979    uri = hapd.request("DPP_BOOTSTRAP_GET_URI %d" % id_h)
6980    tests = ["",
6981             "own=%d" % (id_h + 1),
6982             "own=%d iter=-1" % id_h,
6983             "own=%d listen=0" % id_h]
6984    for t in tests:
6985        if "FAIL" not in hapd.request("DPP_CHIRP " + t):
6986            raise Exception("Invalid DPP_CHIRP accepted: " + t)
6987    if "OK" not in hapd.request("DPP_CHIRP own=%d iter=5" % id_h):
6988        raise Exception("DPP_CHIRP failed")
6989
6990    hapd.request("DPP_STOP_CHIRP")
6991
6992def start_dpp_pfs_ap(apdev, pfs, sae=False):
6993    params = {"ssid": "dpp",
6994              "wpa": "2",
6995              "wpa_key_mgmt": "DPP",
6996              "dpp_pfs": str(pfs),
6997              "ieee80211w": "2",
6998              "rsn_pairwise": "CCMP",
6999              "dpp_connector": params1_ap_connector,
7000              "dpp_csign": params1_csign,
7001              "dpp_netaccesskey": params1_ap_netaccesskey}
7002    if sae:
7003        params["wpa_key_mgmt"] = "DPP SAE"
7004        params["sae_password"] = "sae-password"
7005    try:
7006        hapd = hostapd.add_ap(apdev, params)
7007    except:
7008        raise HwsimSkip("DPP not supported")
7009    return hapd
7010
7011def run_dpp_pfs_sta(dev, pfs, fail=False, pfs_expected=None, sae=False):
7012    key_mgmt = "DPP SAE" if sae else "DPP"
7013    psk = "sae-password" if sae else None
7014    dev.connect("dpp", key_mgmt=key_mgmt, scan_freq="2412",
7015                ieee80211w="2", dpp_pfs=str(pfs),
7016                dpp_csign=params1_csign,
7017                dpp_connector=params1_sta_connector,
7018                dpp_netaccesskey=params1_sta_netaccesskey,
7019                psk=psk,
7020                wait_connect=not fail)
7021    if fail:
7022        for i in range(2):
7023            ev = dev.wait_event(["CTRL-EVENT-ASSOC-REJECT",
7024                                 "CTRL-EVENT-CONNECTED"], timeout=10)
7025            if ev is None:
7026                raise Exception("Connection result not reported")
7027            if "CTRL-EVENT-CONNECTED" in ev:
7028                raise Exception("Unexpected connection")
7029        dev.request("REMOVE_NETWORK all")
7030    else:
7031        if pfs_expected is not None:
7032            res = dev.get_status_field("dpp_pfs")
7033            pfs_used = res == "1"
7034            if pfs_expected != pfs_used:
7035                raise Exception("Unexpected PFS negotiation result")
7036        dev.request("REMOVE_NETWORK all")
7037        dev.wait_disconnected()
7038    dev.dump_monitor()
7039
7040def test_dpp_pfs_ap_0(dev, apdev):
7041    """DPP PFS AP default"""
7042    check_dpp_capab(dev[0])
7043    hapd = start_dpp_pfs_ap(apdev[0], 0)
7044    run_dpp_pfs_sta(dev[0], 0, pfs_expected=True)
7045    run_dpp_pfs_sta(dev[0], 1, pfs_expected=True)
7046    run_dpp_pfs_sta(dev[0], 2, pfs_expected=False)
7047
7048def test_dpp_pfs_ap_1(dev, apdev):
7049    """DPP PFS AP required"""
7050    check_dpp_capab(dev[0])
7051    hapd = start_dpp_pfs_ap(apdev[0], 1)
7052    run_dpp_pfs_sta(dev[0], 0, pfs_expected=True)
7053    run_dpp_pfs_sta(dev[0], 1, pfs_expected=True)
7054    run_dpp_pfs_sta(dev[0], 2, fail=True)
7055
7056def test_dpp_pfs_ap_2(dev, apdev):
7057    """DPP PFS AP not allowed"""
7058    check_dpp_capab(dev[0])
7059    hapd = start_dpp_pfs_ap(apdev[0], 2)
7060    run_dpp_pfs_sta(dev[0], 0, pfs_expected=False)
7061    run_dpp_pfs_sta(dev[0], 1, fail=True)
7062    run_dpp_pfs_sta(dev[0], 2, pfs_expected=False)
7063
7064def test_dpp_pfs_connect_cmd(dev, apdev):
7065    """DPP PFS and cfg80211 connect command"""
7066    wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
7067    wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
7068    check_dpp_capab(wpas)
7069    hapd = start_dpp_pfs_ap(apdev[0], 0)
7070    run_dpp_pfs_sta(wpas, 0, pfs_expected=True)
7071    run_dpp_pfs_sta(wpas, 1, pfs_expected=True)
7072    run_dpp_pfs_sta(wpas, 2, pfs_expected=False)
7073
7074def test_dpp_pfs_connect_cmd_ap_2(dev, apdev):
7075    """DPP PFS and cfg80211 connect command (PFS not allowed by AP)"""
7076    wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
7077    wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
7078    check_dpp_capab(wpas)
7079    hapd = start_dpp_pfs_ap(apdev[0], 2)
7080    run_dpp_pfs_sta(wpas, 0, pfs_expected=False)
7081    run_dpp_pfs_sta(wpas, 1, fail=True)
7082    run_dpp_pfs_sta(wpas, 2, pfs_expected=False)
7083
7084def test_dpp_pfs_connect_cmd_ap_2_sae(dev, apdev):
7085    """DPP PFS and cfg80211 connect command (PFS not allowed by AP; SAE enabled)"""
7086    wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
7087    wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
7088    check_dpp_capab(wpas)
7089    check_sae_capab(wpas)
7090    hapd = start_dpp_pfs_ap(apdev[0], 2, sae=True)
7091    run_dpp_pfs_sta(wpas, 0, pfs_expected=False, sae=True)
7092    run_dpp_pfs_sta(wpas, 1, fail=True, sae=True)
7093    run_dpp_pfs_sta(wpas, 2, pfs_expected=False, sae=True)
7094
7095def test_dpp_pfs_ap_0_sta_ver1(dev, apdev):
7096    """DPP PFS AP default with version 1 STA"""
7097    check_dpp_capab(dev[0])
7098    dev[0].set("dpp_version_override", "1")
7099    hapd = start_dpp_pfs_ap(apdev[0], 0)
7100    run_dpp_pfs_sta(dev[0], 0, pfs_expected=False)
7101
7102def test_dpp_pfs_errors(dev, apdev):
7103    """DPP PFS error cases"""
7104    check_dpp_capab(dev[0], min_ver=2)
7105    hapd = start_dpp_pfs_ap(apdev[0], 1)
7106    tests = [(1, "dpp_pfs_init"),
7107             (1, "crypto_ecdh_init;dpp_pfs_init"),
7108             (1, "wpabuf_alloc;dpp_pfs_init")]
7109    for count, func in tests:
7110        with alloc_fail(dev[0], count, func):
7111            dev[0].connect("dpp", key_mgmt="DPP", scan_freq="2412",
7112                           ieee80211w="2", dpp_pfs="1",
7113                           dpp_csign=params1_csign,
7114                           dpp_connector=params1_sta_connector,
7115                           dpp_netaccesskey=params1_sta_netaccesskey)
7116            dev[0].request("REMOVE_NETWORK all")
7117            dev[0].wait_disconnected()
7118            dev[0].dump_monitor()
7119            hapd.dump_monitor()
7120
7121def test_dpp_reconfig_connector(dev, apdev):
7122    """DPP reconfiguration connector"""
7123    try:
7124        run_dpp_reconfig_connector(dev, apdev)
7125    finally:
7126        dev[0].set("dpp_config_processing", "0", allow_fail=True)
7127
7128def test_dpp_reconfig_connector_different_groups(dev, apdev):
7129    """DPP reconfiguration connector with different groups"""
7130    try:
7131        run_dpp_reconfig_connector(dev, apdev, conf_curve="secp384r1")
7132    finally:
7133        dev[0].set("dpp_config_processing", "0", allow_fail=True)
7134
7135@long_duration_test
7136def test_dpp_reconfig_retries(dev, apdev):
7137    """DPP reconfiguration retries"""
7138    try:
7139        run_dpp_reconfig_connector(dev, apdev, test_retries=True)
7140        for i in range(4):
7141            ev = dev[0].wait_event(["DPP-TX "], timeout=120)
7142            if ev is None or "type=14" not in ev:
7143                raise Exception("Reconfig Announcement not sent")
7144        dev[0].request("DPP_STOP_LISTEN")
7145    finally:
7146        dev[0].set("dpp_config_processing", "0", allow_fail=True)
7147
7148def run_dpp_reconfig_connector(dev, apdev, conf_curve=None,
7149                               test_retries=False):
7150    check_dpp_capab(dev[0], min_ver=2)
7151    check_dpp_capab(dev[1], min_ver=2)
7152
7153    ssid = "reconfig"
7154    passphrase = "secret passphrase"
7155    passphrase2 = "another secret passphrase"
7156    params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
7157    hapd = hostapd.add_ap(apdev[0], params)
7158
7159    dev[0].set("dpp_config_processing", "2")
7160    id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
7161    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
7162    dev[0].dpp_listen(2412)
7163    configurator = dev[1].dpp_configurator_add(curve=conf_curve)
7164    conf = 'sta-psk'
7165    dev[1].dpp_auth_init(uri=uri0, conf=conf, ssid=ssid,
7166                         passphrase=passphrase, configurator=configurator,
7167                         conn_status=True)
7168    res = wait_auth_success(dev[0], dev[1], configurator=dev[1],
7169                            enrollee=dev[0])
7170    if 'wait_conn_status' not in res:
7171        raise Exception("Configurator did not request connection status")
7172    ev = dev[1].wait_event(["DPP-CONN-STATUS-RESULT"], timeout=20)
7173    if ev is None:
7174        raise Exception("No connection status reported")
7175    dev[1].dump_monitor()
7176
7177    ev = dev[0].wait_event(["DPP-CONFOBJ-SSID"], timeout=1)
7178    if ev is None:
7179        raise Exception("SSID not reported")
7180    res_ssid = ev.split(' ')[1]
7181    if res_ssid != ssid:
7182        raise Exception("Unexpected SSID value")
7183
7184    ev = dev[0].wait_event(["DPP-CONNECTOR"], timeout=1)
7185    if ev is None:
7186        raise Exception("Connector not reported")
7187    connector = ev.split(' ')[1]
7188
7189    ev = dev[0].wait_event(["DPP-C-SIGN-KEY"], timeout=1)
7190    if ev is None:
7191        raise Exception("C-sign-key not reported")
7192    p = ev.split(' ')
7193    csign = p[1]
7194
7195    ev = dev[0].wait_event(["DPP-NET-ACCESS-KEY"], timeout=1)
7196    if ev is None:
7197        raise Exception("netAccessKey not reported")
7198    p = ev.split(' ')
7199    net_access_key = p[1]
7200    net_access_key_expiry = p[2] if len(p) > 2 else None
7201
7202    ev = dev[0].wait_event(["DPP-NETWORK-ID"], timeout=1)
7203    if ev is None:
7204        raise Exception("DPP network profile not generated")
7205    id = ev.split(' ')[1]
7206
7207    dev[0].wait_connected()
7208
7209    n_key_mgmt = dev[0].get_network(id, "key_mgmt")
7210    if n_key_mgmt != "WPA-PSK FT-PSK WPA-PSK-SHA256":
7211        raise Exception("Unexpected key_mgmt: " + n_key_mgmt)
7212    n_connector = dev[0].get_network(id, "dpp_connector")
7213    if n_connector.strip('"') != connector:
7214        raise Exception("Connector mismatch: %s %s" % (n_connector, connector))
7215    n_csign = dev[0].get_network(id, "dpp_csign")
7216    if n_csign.strip('"') != csign:
7217        raise Exception("csign mismatch: %s %s" % (n_csign, csign))
7218    n_net_access_key = dev[0].get_network(id, "dpp_netaccesskey")
7219    if n_net_access_key.strip('"') != net_access_key:
7220        raise Exception("net_access_key mismatch: %s %s" % (n_net_access_key,
7221                                                            net_access_key))
7222
7223    dev[0].request("DISCONNECT")
7224    dev[0].wait_disconnected()
7225
7226    hapd.disable()
7227    hapd.set("wpa_passphrase", passphrase2)
7228    hapd.enable()
7229
7230    time.sleep(0.1)
7231    dev[0].dump_monitor()
7232    dev[1].dump_monitor()
7233
7234    if test_retries:
7235        dev[1].request("DPP_STOP_LISTEN")
7236        if "OK" not in dev[0].request("DPP_RECONFIG %s iter=10" % id):
7237            raise Exception("Failed to start reconfiguration")
7238        return
7239
7240    dev[1].set("dpp_configurator_params",
7241               "conf=sta-psk ssid=%s pass=%s conn_status=1" % (binascii.hexlify(ssid.encode()).decode(), binascii.hexlify(passphrase2.encode()).decode()))
7242    dev[1].dpp_listen(2437)
7243
7244    if "OK" not in dev[0].request("DPP_RECONFIG %s" % id):
7245        raise Exception("Failed to start reconfiguration")
7246    ev = dev[0].wait_event(["DPP-TX "], timeout=10)
7247    if ev is None or "type=14" not in ev:
7248        raise Exception("Reconfig Announcement not sent")
7249
7250    ev = dev[1].wait_event(["DPP-RX"], timeout=5)
7251    if ev is None:
7252        raise Exception("DPP Reconfig Announcement not received")
7253    if "freq=2437 type=14" not in ev:
7254        raise Exception("Unexpected RX data for Reconfig Announcement: " + ev)
7255
7256    ev = dev[0].wait_event(["DPP-RX"], timeout=5)
7257    if ev is None or "freq=2437 type=15" not in ev:
7258        raise Exception("DPP Reconfig Authentication Request not received")
7259
7260    ev = dev[1].wait_event(["DPP-RX"], timeout=5)
7261    if ev is None or "freq=2437 type=16" not in ev:
7262        raise Exception("DPP Reconfig Authentication Response not received")
7263
7264    ev = dev[0].wait_event(["DPP-RX"], timeout=5)
7265    if ev is None or "freq=2437 type=17" not in ev:
7266        raise Exception("DPP Reconfig Authentication Confirm not received")
7267
7268    ev = dev[0].wait_event(["GAS-QUERY-START"], timeout=5)
7269    if ev is None or "freq=2437" not in ev:
7270        raise Exception("DPP Config Request (GAS) not transmitted")
7271
7272    ev = dev[1].wait_event(["DPP-CONF-REQ-RX"], timeout=5)
7273    if ev is None:
7274        raise Exception("DPP Config Request (GAS) not received")
7275
7276    ev = dev[0].wait_event(["GAS-QUERY-DONE"], timeout=5)
7277    if ev is None or "freq=2437" not in ev:
7278        raise Exception("DPP Config Response (GAS) not received")
7279
7280    ev = dev[1].wait_event(["DPP-RX"], timeout=5)
7281    if ev is None or "freq=2437 type=11" not in ev:
7282        raise Exception("DPP Config Result not received")
7283
7284    ev = dev[1].wait_event(["DPP-CONF-SENT"], timeout=5)
7285    if ev is None:
7286        raise Exception("DPP Config Response (GAS) not transmitted")
7287
7288    ev = dev[0].wait_event(["DPP-CONF-RECEIVED", "DPP-CONF-FAILED"], timeout=5)
7289    if ev is None:
7290        raise Exception("DPP config response reception result not indicated")
7291    if "DPP-CONF-RECEIVED" not in ev:
7292        raise Exception("Reconfiguration failed")
7293
7294    dev[0].wait_connected()
7295
7296    ev = dev[1].wait_event(["DPP-CONN-STATUS-RESULT"], timeout=20)
7297    if ev is None:
7298        raise Exception("No connection status reported")
7299
7300def test_dpp_reconfig_hostapd_configurator(dev, apdev):
7301    """DPP reconfiguration with hostapd as configurator"""
7302    try:
7303        run_dpp_reconfig_hostapd_configurator(dev, apdev)
7304    finally:
7305        dev[0].set("dpp_config_processing", "0", allow_fail=True)
7306
7307def run_dpp_reconfig_hostapd_configurator(dev, apdev):
7308    ssid = "reconfig-ap"
7309    check_dpp_capab(dev[0], min_ver=2)
7310    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured"})
7311    check_dpp_capab(hapd, min_ver=2)
7312    conf_id = hapd.dpp_configurator_add()
7313
7314    cmd = "DPP_CONFIGURATOR_SIGN conf=ap-dpp configurator=%d ssid=%s" % (conf_id, binascii.hexlify(ssid.encode()).decode())
7315    res = hapd.request(cmd)
7316    if "FAIL" in res:
7317        raise Exception("Failed to generate own configuration")
7318    hapd.set("dpp_configurator_connectivity", "1")
7319    update_hapd_config(hapd)
7320
7321    id = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
7322    uri = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id)
7323    dev[0].set("dpp_config_processing", "2")
7324    dev[0].dpp_listen(2412)
7325    hapd.dpp_auth_init(uri=uri, conf="sta-dpp", configurator=conf_id,
7326                       extra="expiry=%d" % (time.time() + 10), ssid=ssid)
7327    wait_auth_success(dev[0], hapd, configurator=hapd, enrollee=dev[0])
7328    ev = dev[0].wait_event(["DPP-NETWORK-ID"], timeout=1)
7329    if ev is None:
7330        raise Exception("DPP network id not reported")
7331    network = int(ev.split(' ')[1])
7332    dev[0].wait_connected()
7333    hapd.wait_sta()
7334    dev[0].request("DISCONNECT")
7335    dev[0].wait_disconnected()
7336    hapd.wait_sta_disconnect()
7337    dev[0].dump_monitor()
7338    time.sleep(10)
7339    if "FAIL" in dev[0].request("PMKSA_FLUSH"):
7340        raise Exception("PMKSA_FLUSH failed")
7341    dev[0].request("RECONNECT")
7342    ev = dev[0].wait_event(["DPP-MISSING-CONNECTOR", "CTRL-EVENT-CONNECTED"],
7343                           timeout=15)
7344    if ev is None or "DPP-MISSING-CONNECTOR" not in ev:
7345        raise Exception("Missing Connector not reported")
7346    if "netAccessKey expired" not in ev:
7347        raise Exception("netAccessKey expiry not indicated")
7348    dev[0].request("DISCONNECT")
7349    dev[0].dump_monitor()
7350
7351    hapd.set("dpp_configurator_params",
7352             "conf=sta-dpp configurator=%d ssid=%s" % (conf_id, binascii.hexlify(ssid.encode()).decode()))
7353
7354    if "OK" not in dev[0].request("DPP_RECONFIG %s" % network):
7355        raise Exception("Failed to start reconfiguration")
7356    ev = dev[0].wait_event(["DPP-NETWORK-ID"], timeout=15)
7357    if ev is None:
7358        raise Exception("DPP network id not reported for reconfiguration")
7359    network2 = int(ev.split(' ')[1])
7360    if network == network2:
7361        raise Exception("Network ID did not change")
7362    dev[0].wait_connected()
7363    hapd.wait_sta()
7364
7365def test_dpp_qr_code_auth_rand_mac_addr(dev, apdev):
7366    """DPP QR Code and authentication exchange (rand_mac_addr=1)"""
7367    flags = int(dev[0].get_driver_status_field('capa.flags'), 16)
7368    if flags & 0x0000400000000000 == 0:
7369        raise HwsimSkip("Driver does not support random GAS TA")
7370
7371    try:
7372        dev[0].set("gas_rand_mac_addr", "1")
7373        run_dpp_qr_code_auth_unicast(dev, apdev, None)
7374    finally:
7375        dev[0].set("gas_rand_mac_addr", "0")
7376
7377def dpp_sign_cert(cacert, cakey, csr_der):
7378    csr = OpenSSL.crypto.load_certificate_request(OpenSSL.crypto.FILETYPE_ASN1,
7379                                                  csr_der)
7380    cert = OpenSSL.crypto.X509()
7381    cert.set_serial_number(12345)
7382    cert.gmtime_adj_notBefore(-10)
7383    cert.gmtime_adj_notAfter(100000)
7384    cert.set_pubkey(csr.get_pubkey())
7385    dn = csr.get_subject()
7386    cert.set_subject(dn)
7387    cert.set_version(2)
7388    cert.add_extensions([
7389        OpenSSL.crypto.X509Extension(b"basicConstraints", True,
7390                                     b"CA:FALSE"),
7391        OpenSSL.crypto.X509Extension(b"subjectKeyIdentifier", False,
7392                                     b"hash", subject=cert),
7393        OpenSSL.crypto.X509Extension(b"authorityKeyIdentifier", False,
7394                                     b"keyid:always", issuer=cacert),
7395    ])
7396    cert.set_issuer(cacert.get_subject())
7397    cert.sign(cakey, "sha256")
7398    return cert
7399
7400def test_dpp_enterprise(dev, apdev, params):
7401    """DPP and enterprise EAP-TLS provisioning"""
7402    check_dpp_capab(dev[0], min_ver=2)
7403    try:
7404        dev[0].set("dpp_config_processing", "2")
7405        run_dpp_enterprise(dev, apdev, params)
7406    finally:
7407        dev[0].set("dpp_config_processing", "0", allow_fail=True)
7408
7409def run_dpp_enterprise(dev, apdev, params):
7410    if not openssl_imported:
7411        raise HwsimSkip("OpenSSL python method not available")
7412    check_dpp_capab(dev[0])
7413    check_dpp_capab(dev[1])
7414
7415    cert_file = params['prefix'] + ".cert.pem"
7416    pkcs7_file = params['prefix'] + ".pkcs7.der"
7417
7418    params = {"ssid": "dpp-ent",
7419              "wpa": "2",
7420              "wpa_key_mgmt": "WPA-EAP",
7421              "rsn_pairwise": "CCMP",
7422              "ieee8021x": "1",
7423              "eap_server": "1",
7424              "eap_user_file": "auth_serv/eap_user.conf",
7425              "ca_cert": "auth_serv/ec-ca.pem",
7426              "server_cert": "auth_serv/ec-server.pem",
7427              "private_key": "auth_serv/ec-server.key"}
7428    hapd = hostapd.add_ap(apdev[0], params)
7429
7430    with open("auth_serv/ec-ca.pem", "rb") as f:
7431        res = f.read()
7432        cacert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
7433                                                 res)
7434
7435    with open("auth_serv/ec-ca.key", "rb") as f:
7436        res = f.read()
7437        cakey = OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM, res)
7438
7439    conf_id = dev[1].dpp_configurator_add()
7440    id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
7441    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
7442    dev[0].dpp_listen(2412)
7443    csrattrs = "MAsGCSqGSIb3DQEJBw=="
7444    id1 = dev[1].dpp_auth_init(uri=uri0, configurator=conf_id, conf="sta-dot1x",
7445                               csrattrs=csrattrs, ssid="dpp-ent")
7446
7447    ev = dev[1].wait_event(["DPP-CSR"], timeout=10)
7448    if ev is None:
7449        raise Exception("Configurator did not receive CSR")
7450    id1_csr = int(ev.split(' ')[1].split('=')[1])
7451    if id1 != id1_csr:
7452        raise Exception("Peer bootstrapping ID mismatch in CSR event")
7453    csr = ev.split(' ')[2]
7454    if not csr.startswith("csr="):
7455        raise Exception("Could not parse CSR event: " + ev)
7456    csr = csr[4:]
7457    csr = base64.b64decode(csr.encode())
7458    logger.info("CSR: " + binascii.hexlify(csr).decode())
7459
7460    cert = dpp_sign_cert(cacert, cakey, csr)
7461    with open(cert_file, 'wb') as f:
7462        f.write(OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM,
7463                                                cert))
7464    subprocess.check_call(['openssl', 'crl2pkcs7', '-nocrl',
7465                           '-certfile', cert_file,
7466                           '-certfile', 'auth_serv/ec-ca.pem',
7467                           '-outform', 'DER', '-out', pkcs7_file])
7468
7469    #caCert = base64.b64encode(b"TODO").decode()
7470    #res = dev[1].request("DPP_CA_SET peer=%d name=caCert value=%s" % (id1, caCert))
7471    #if "OK" not in res:
7472    #    raise Exception("Failed to set caCert")
7473
7474    name = "server.w1.fi"
7475    res = dev[1].request("DPP_CA_SET peer=%d name=trustedEapServerName value=%s" % (id1, name))
7476    if "OK" not in res:
7477        raise Exception("Failed to set trustedEapServerName")
7478
7479    with open(pkcs7_file, 'rb') as f:
7480        pkcs7_der = f.read()
7481        certbag = base64.b64encode(pkcs7_der).decode()
7482    res = dev[1].request("DPP_CA_SET peer=%d name=certBag value=%s" % (id1, certbag))
7483    if "OK" not in res:
7484        raise Exception("Failed to set certBag")
7485
7486    ev = dev[1].wait_event(["DPP-CONF-SENT", "DPP-CONF-FAILED"], timeout=5)
7487    if ev is None:
7488        raise Exception("DPP configuration not completed (Configurator)")
7489    if "DPP-CONF-FAILED" in ev:
7490        raise Exception("DPP configuration did not succeed (Configurator)")
7491
7492    ev = dev[0].wait_event(["DPP-CONF-RECEIVED", "DPP-CONF-FAILED"],
7493                           timeout=1)
7494    if ev is None:
7495        raise Exception("DPP configuration not completed (Enrollee)")
7496    if "DPP-CONF-FAILED" in ev:
7497        raise Exception("DPP configuration did not succeed (Enrollee)")
7498
7499    ev = dev[0].wait_event(["DPP-CERTBAG"], timeout=1)
7500    if ev is None:
7501        raise Exception("DPP-CERTBAG not reported")
7502    certbag = base64.b64decode(ev.split(' ')[1].encode())
7503    if certbag != pkcs7_der:
7504        raise Exception("DPP-CERTBAG mismatch")
7505
7506    #ev = dev[0].wait_event(["DPP-CACERT"], timeout=1)
7507    #if ev is None:
7508    #    raise Exception("DPP-CACERT not reported")
7509
7510    ev = dev[0].wait_event(["DPP-SERVER-NAME"], timeout=1)
7511    if ev is None:
7512        raise Exception("DPP-SERVER-NAME not reported")
7513    if ev.split(' ')[1] != name:
7514        raise Exception("DPP-SERVER-NAME mismatch: " + ev)
7515
7516    ev = dev[0].wait_event(["DPP-NETWORK-ID"], timeout=1)
7517    if ev is None:
7518        raise Exception("DPP network profile not generated")
7519    id = ev.split(' ')[1]
7520
7521    dev[0].wait_connected()
7522
7523def test_dpp_enterprise_reject(dev, apdev, params):
7524    """DPP and enterprise EAP-TLS provisioning and CSR getting rejected"""
7525    check_dpp_capab(dev[0])
7526    check_dpp_capab(dev[1])
7527
7528    conf_id = dev[1].dpp_configurator_add()
7529    id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
7530    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
7531    dev[0].dpp_listen(2412)
7532    csrattrs = "MAsGCSqGSIb3DQEJBw=="
7533    id1 = dev[1].dpp_auth_init(uri=uri0, configurator=conf_id, conf="sta-dot1x",
7534                               csrattrs=csrattrs, ssid="dpp-ent")
7535
7536    ev = dev[1].wait_event(["DPP-CSR"], timeout=10)
7537    if ev is None:
7538        raise Exception("Configurator did not receive CSR")
7539
7540    res = dev[1].request("DPP_CA_SET peer=%d name=status value=5" % id1)
7541    if "OK" not in res:
7542        raise Exception("Failed to set status")
7543
7544    ev = dev[1].wait_event(["DPP-CONF-SENT", "DPP-CONF-FAILED"], timeout=5)
7545    if ev is None:
7546        raise Exception("DPP configuration not completed (Configurator)")
7547    if "DPP-CONF-FAILED" in ev:
7548        raise Exception("DPP configuration did not succeed (Configurator)")
7549
7550    ev = dev[0].wait_event(["DPP-CONF-RECEIVED", "DPP-CONF-FAILED"],
7551                           timeout=1)
7552    if ev is None:
7553        raise Exception("DPP configuration not completed (Enrollee)")
7554    if "DPP-CONF-FAILED" not in ev:
7555        raise Exception("DPP configuration did not fail (Enrollee)")
7556
7557def test_dpp_enterprise_tcp(dev, apdev, params):
7558    """DPP over TCP for enterprise provisioning"""
7559    if not openssl_imported:
7560        raise HwsimSkip("OpenSSL python method not available")
7561
7562    try:
7563        run_dpp_enterprise_tcp(dev, apdev, params)
7564    finally:
7565        dev[1].request("DPP_CONTROLLER_STOP")
7566
7567def run_dpp_enterprise_tcp(dev, apdev, params):
7568    check_dpp_capab(dev[0])
7569    check_dpp_capab(dev[1])
7570
7571    cap_lo = params['prefix'] + ".lo.pcap"
7572
7573    with WlantestCapture('lo', cap_lo) as wt:
7574        _run_dpp_enterprise_tcp(dev, apdev, params, wt)
7575
7576def _run_dpp_enterprise_tcp(dev, apdev, params, wt):
7577    # Controller
7578    conf_id = dev[1].dpp_configurator_add()
7579    csrattrs = "MAsGCSqGSIb3DQEJBw=="
7580    dev[1].set("dpp_configurator_params",
7581               "conf=sta-dot1x configurator=%d csrattrs=%s" % (conf_id, csrattrs))
7582    id_c = dev[1].dpp_bootstrap_gen()
7583    uri_c = dev[1].request("DPP_BOOTSTRAP_GET_URI %d" % id_c)
7584    res = dev[1].request("DPP_BOOTSTRAP_INFO %d" % id_c)
7585    req = "DPP_CONTROLLER_START"
7586    if "OK" not in dev[1].request(req):
7587        raise Exception("Failed to start Controller")
7588
7589    dev[0].dpp_auth_init(uri=uri_c, role="enrollee", tcp_addr="127.0.0.1")
7590    run_dpp_enterprise_tcp_end(params, dev, wt)
7591
7592def run_dpp_enterprise_tcp_end(params, dev, wt):
7593    cert_file = params['prefix'] + ".cert.pem"
7594    pkcs7_file = params['prefix'] + ".pkcs7.der"
7595
7596    with open("auth_serv/ec-ca.pem", "rb") as f:
7597        res = f.read()
7598        cacert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
7599                                                 res)
7600
7601    with open("auth_serv/ec-ca.key", "rb") as f:
7602        res = f.read()
7603        cakey = OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM, res)
7604
7605    ev = dev[1].wait_event(["DPP-CSR"], timeout=10)
7606    if ev is None:
7607        raise Exception("Configurator did not receive CSR")
7608    id1_csr = int(ev.split(' ')[1].split('=')[1])
7609    csr = ev.split(' ')[2]
7610    if not csr.startswith("csr="):
7611        raise Exception("Could not parse CSR event: " + ev)
7612    csr = csr[4:]
7613    csr = base64.b64decode(csr.encode())
7614    logger.info("CSR: " + binascii.hexlify(csr).decode())
7615
7616    cert = dpp_sign_cert(cacert, cakey, csr)
7617    with open(cert_file, 'wb') as f:
7618        f.write(OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM,
7619                                                cert))
7620    subprocess.check_call(['openssl', 'crl2pkcs7', '-nocrl',
7621                           '-certfile', cert_file,
7622                           '-certfile', 'auth_serv/ec-ca.pem',
7623                           '-outform', 'DER', '-out', pkcs7_file])
7624
7625    with open(pkcs7_file, 'rb') as f:
7626        pkcs7_der = f.read()
7627        certbag = base64.b64encode(pkcs7_der).decode()
7628    res = dev[1].request("DPP_CA_SET peer=%d name=certBag value=%s" % (id1_csr, certbag))
7629    if "OK" not in res:
7630        raise Exception("Failed to set certBag")
7631
7632    ev = dev[1].wait_event(["DPP-CONF-SENT", "DPP-CONF-FAILED"], timeout=5)
7633    if ev is None:
7634        raise Exception("DPP configuration not completed (Configurator)")
7635    if "DPP-CONF-FAILED" in ev:
7636        raise Exception("DPP configuration did not succeed (Configurator)")
7637
7638    ev = dev[0].wait_event(["DPP-CONF-RECEIVED", "DPP-CONF-FAILED"],
7639                           timeout=1)
7640    if ev is None:
7641        raise Exception("DPP configuration not completed (Enrollee)")
7642    if "DPP-CONF-RECEIVED" not in ev:
7643        raise Exception("DPP configuration did not succeed (Enrollee)")
7644
7645def test_dpp_enterprise_tcp2(dev, apdev, params):
7646    """DPP over TCP for enterprise provisioning (Controller initiating)"""
7647    if not openssl_imported:
7648        raise HwsimSkip("OpenSSL python method not available")
7649
7650    try:
7651        run_dpp_enterprise_tcp2(dev, apdev, params)
7652    finally:
7653        dev[0].request("DPP_CONTROLLER_STOP")
7654        dev[1].request("DPP_CONTROLLER_STOP")
7655
7656def run_dpp_enterprise_tcp2(dev, apdev, params):
7657    check_dpp_capab(dev[0])
7658    check_dpp_capab(dev[1])
7659
7660    cap_lo = params['prefix'] + ".lo.pcap"
7661
7662    with WlantestCapture('lo', cap_lo) as wt:
7663        _run_dpp_enterprise_tcp2(dev, apdev, params, wt)
7664
7665def _run_dpp_enterprise_tcp2(dev, apdev, params, wt):
7666    # Client/Enrollee/Responder
7667    id_e = dev[0].dpp_bootstrap_gen()
7668    uri_e = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id_e)
7669    req = "DPP_CONTROLLER_START"
7670    if "OK" not in dev[0].request(req):
7671        raise Exception("Failed to start Client/Enrollee")
7672
7673    # Controller/Configurator/Initiator
7674    conf_id = dev[1].dpp_configurator_add()
7675    csrattrs = "MAsGCSqGSIb3DQEJBw=="
7676    dev[1].dpp_auth_init(uri=uri_e, role="configurator", configurator=conf_id,
7677                         conf="sta-dot1x", csrattrs=csrattrs,
7678                         tcp_addr="127.0.0.1")
7679
7680    run_dpp_enterprise_tcp_end(params, dev, wt)
7681
7682def test_dpp_qr_code_config_event_initiator(dev, apdev):
7683    """DPP QR Code and config event on Configurator Initiator"""
7684    run_dpp_qr_code_config_event_initiator(dev, apdev)
7685
7686def test_dpp_qr_code_config_event_initiator_set_comeback(dev, apdev):
7687    """DPP QR Code and config event on Configurator Initiator (set comeback)"""
7688    run_dpp_qr_code_config_event_initiator(dev, apdev, set_comeback=True)
7689
7690def test_dpp_qr_code_config_event_initiator_slow(dev, apdev):
7691    """DPP QR Code and config event on Configurator Initiator (slow)"""
7692    run_dpp_qr_code_config_event_initiator(dev, apdev, slow=True)
7693
7694def test_dpp_qr_code_config_event_initiator_failure(dev, apdev):
7695    """DPP QR Code and config event on Configurator Initiator (failure)"""
7696    run_dpp_qr_code_config_event_initiator(dev, apdev, failure=True)
7697
7698def test_dpp_qr_code_config_event_initiator_no_response(dev, apdev):
7699    """DPP QR Code and config event on Configurator Initiator (no response)"""
7700    run_dpp_qr_code_config_event_initiator(dev, apdev, failure=True,
7701                                           no_response=True)
7702
7703def run_dpp_qr_code_config_event_initiator(dev, apdev, set_comeback=False,
7704                                           slow=False, failure=False,
7705                                           no_response=False):
7706    check_dpp_capab(dev[0])
7707    check_dpp_capab(dev[1])
7708    id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
7709    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
7710    dev[0].dpp_listen(2412)
7711    id1 = dev[1].dpp_auth_init(uri=uri0, conf="query")
7712    wait_auth_success(dev[0], dev[1])
7713    ev = dev[1].wait_event(["DPP-CONF-NEEDED"])
7714    if ev is None:
7715        raise Exception("Configuration query not seen")
7716    if "peer=%d " % id1 not in ev:
7717        raise Exception("Peer id mismatch: " + ev)
7718    if "net_role=sta" not in ev:
7719        raise Exception("Net role mismatch: " + ev)
7720
7721    if set_comeback:
7722        if "OK" not in dev[1].request(("DPP_CONF_SET peer=%d comeback=123" % id1)):
7723            raise Exception("DPP_CONF_SET failed")
7724
7725    if slow:
7726        time.sleep(0.100)
7727
7728    if failure:
7729        conf = "conf=failure"
7730    else:
7731        ssid = "sae"
7732        password = "password"
7733        conf = "conf=sta-sae"
7734        conf += " ssid=" + binascii.hexlify(ssid.encode()).decode()
7735        conf += " pass=" + binascii.hexlify(password.encode()).decode()
7736    if not no_response:
7737        if "OK" not in dev[1].request(("DPP_CONF_SET peer=%d " % id1) + conf):
7738            raise Exception("DPP_CONF_SET failed")
7739
7740    ev = dev[0].wait_event(["DPP-CONF-RECEIVED", "DPP-CONF-FAILED"], timeout=65)
7741    if ev is None:
7742        raise Exception("DPP configuration not completed (Enrollee)")
7743    if failure and "DPP-CONF-FAILED" not in ev:
7744        raise Exception("DPP configuration did not fail (Enrollee)")
7745    if (not failure) and "DPP-CONF-RECEIVED" not in ev:
7746        raise Exception("DPP configuration did not succeed (Enrollee)")
7747    time.sleep(0.01)
7748    dev[0].dump_monitor()
7749    dev[1].dump_monitor()
7750
7751def test_dpp_qr_code_config_event_initiator_both(dev, apdev):
7752    """DPP QR Code and config event on Configurator/Enrollee Initiator"""
7753    check_dpp_capab(dev[0])
7754    check_dpp_capab(dev[1])
7755    id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
7756    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
7757    ssid = "sae"
7758    password = "password"
7759    dev[0].set("dpp_configurator_params",
7760               "conf=sta-sae ssid=%s pass=%s" % (binascii.hexlify(ssid.encode()).decode(), binascii.hexlify(password.encode()).decode()))
7761    dev[0].dpp_listen(2412, role="configurator")
7762    id1 = dev[1].dpp_auth_init(uri=uri0, conf="query", role="either")
7763    wait_auth_success(dev[0], dev[1], configurator=dev[0], enrollee=dev[1])
7764    time.sleep(0.01)
7765    dev[0].dump_monitor()
7766    dev[1].dump_monitor()
7767
7768def test_dpp_tcp_qr_code_config_event_initiator(dev, apdev, params):
7769    """DPP over TCP (Configurator initiates with config event)"""
7770    try:
7771        run_dpp_tcp_qr_code_config_event_initiator(dev[0], dev[1])
7772    finally:
7773        dev[1].request("DPP_CONTROLLER_STOP")
7774
7775def run_dpp_tcp_qr_code_config_event_initiator(dev0, dev1):
7776    check_dpp_capab(dev0, min_ver=2)
7777    check_dpp_capab(dev1, min_ver=2)
7778
7779    id_c = dev1.dpp_bootstrap_gen()
7780    uri_c = dev1.request("DPP_BOOTSTRAP_GET_URI %d" % id_c)
7781    res = dev1.request("DPP_BOOTSTRAP_INFO %d" % id_c)
7782    req = "DPP_CONTROLLER_START role=enrollee"
7783    if "OK" not in dev1.request(req):
7784        raise Exception("Failed to start Controller")
7785
7786    conf_id = dev0.dpp_configurator_add()
7787    id1 = dev0.dpp_auth_init(uri=uri_c, role="configurator", conf="query",
7788                             tcp_addr="127.0.0.1")
7789    wait_auth_success(dev1, dev0)
7790    ev = dev0.wait_event(["DPP-CONF-NEEDED"])
7791    if ev is None:
7792        raise Exception("Configuration query not seen")
7793    if "peer=%d " % id1 not in ev:
7794        raise Exception("Peer id mismatch: " + ev)
7795    if "net_role=sta" not in ev:
7796        raise Exception("Net role mismatch: " + ev)
7797
7798    ssid = "sae"
7799    password = "password"
7800    conf = "conf=sta-sae"
7801    conf += " ssid=" + binascii.hexlify(ssid.encode()).decode()
7802    conf += " pass=" + binascii.hexlify(password.encode()).decode()
7803    if "OK" not in dev0.request(("DPP_CONF_SET peer=%d " % id1) + conf):
7804        raise Exception("DPP_CONF_SET failed")
7805
7806    ev = dev1.wait_event(["DPP-CONF-RECEIVED", "DPP-CONF-FAILED"], timeout=15)
7807    if ev is None:
7808        raise Exception("DPP configuration not completed (Enrollee)")
7809    if "DPP-CONF-RECEIVED" not in ev:
7810        raise Exception("DPP configuration did not succeed (Enrollee)")
7811    time.sleep(0.01)
7812    dev0.dump_monitor()
7813    dev1.dump_monitor()
7814
7815def test_dpp_qr_code_config_event_responder(dev, apdev):
7816    """DPP QR Code and config event on Configurator Responder"""
7817    check_dpp_capab(dev[0])
7818    check_dpp_capab(dev[1])
7819    id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
7820    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
7821    dev[0].set("dpp_configurator_params", "conf=query")
7822    dev[0].dpp_listen(2412, role="configurator")
7823    dev[1].dpp_auth_init(uri=uri0, role="enrollee")
7824    wait_auth_success(dev[0], dev[1])
7825    ev = dev[0].wait_event(["DPP-CONF-NEEDED"])
7826    if ev is None:
7827        raise Exception("Configuration query not seen")
7828    if "net_role=sta" not in ev:
7829        raise Exception("Net role mismatch: " + ev)
7830    peer_id = int(ev.split()[1].split('=')[1])
7831
7832    ssid = "sae"
7833    password = "password"
7834    conf = "conf=sta-sae"
7835    conf += " ssid=" + binascii.hexlify(ssid.encode()).decode()
7836    conf += " pass=" + binascii.hexlify(password.encode()).decode()
7837    if "OK" not in dev[0].request(("DPP_CONF_SET peer=%d " % peer_id) + conf):
7838        raise Exception("DPP_CONF_SET failed")
7839
7840    ev = dev[1].wait_event(["DPP-CONF-RECEIVED", "DPP-CONF-FAILED"], timeout=15)
7841    if ev is None:
7842        raise Exception("DPP configuration not completed (Enrollee)")
7843    if "DPP-CONF-RECEIVED" not in ev:
7844        raise Exception("DPP configuration did not succeed (Enrollee)")
7845    time.sleep(0.01)
7846    dev[0].dump_monitor()
7847    dev[1].dump_monitor()
7848
7849def test_dpp_discard_public_action(dev, apdev):
7850    """DPP and discarding Public Action frames"""
7851    check_dpp_capab(dev[0])
7852    check_dpp_capab(dev[1])
7853    id0 = dev[0].dpp_bootstrap_gen(chan="81/1")
7854    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
7855    dev[0].dpp_listen(2412)
7856    dev[1].set("dpp_discard_public_action", "1")
7857    dev[1].dpp_auth_init(uri=uri0)
7858    ev = dev[0].wait_event(["DPP-FAIL"], timeout=5)
7859    if ev is None:
7860        raise Exception("Failure not reported")
7861    if "No Auth Confirm received" not in ev:
7862        raise Exception("Unexpected failure reason: " + ev)
7863