1*a1157835SDaniel Fojt /*
2*a1157835SDaniel Fojt  * DPP functionality shared between hostapd and wpa_supplicant
3*a1157835SDaniel Fojt  * Copyright (c) 2017, Qualcomm Atheros, Inc.
4*a1157835SDaniel Fojt  * Copyright (c) 2018-2019, The Linux Foundation
5*a1157835SDaniel Fojt  *
6*a1157835SDaniel Fojt  * This software may be distributed under the terms of the BSD license.
7*a1157835SDaniel Fojt  * See README for more details.
8*a1157835SDaniel Fojt  */
9*a1157835SDaniel Fojt 
10*a1157835SDaniel Fojt #ifndef DPP_H
11*a1157835SDaniel Fojt #define DPP_H
12*a1157835SDaniel Fojt 
13*a1157835SDaniel Fojt #ifdef CONFIG_DPP
14*a1157835SDaniel Fojt #include <openssl/x509.h>
15*a1157835SDaniel Fojt 
16*a1157835SDaniel Fojt #include "utils/list.h"
17*a1157835SDaniel Fojt #include "common/wpa_common.h"
18*a1157835SDaniel Fojt #include "crypto/sha256.h"
19*a1157835SDaniel Fojt 
20*a1157835SDaniel Fojt struct crypto_ecdh;
21*a1157835SDaniel Fojt struct hostapd_ip_addr;
22*a1157835SDaniel Fojt struct dpp_global;
23*a1157835SDaniel Fojt 
24*a1157835SDaniel Fojt #define DPP_HDR_LEN (4 + 2) /* OUI, OUI Type, Crypto Suite, DPP frame type */
25*a1157835SDaniel Fojt #define DPP_TCP_PORT 7871
26*a1157835SDaniel Fojt 
27*a1157835SDaniel Fojt enum dpp_public_action_frame_type {
28*a1157835SDaniel Fojt 	DPP_PA_AUTHENTICATION_REQ = 0,
29*a1157835SDaniel Fojt 	DPP_PA_AUTHENTICATION_RESP = 1,
30*a1157835SDaniel Fojt 	DPP_PA_AUTHENTICATION_CONF = 2,
31*a1157835SDaniel Fojt 	DPP_PA_PEER_DISCOVERY_REQ = 5,
32*a1157835SDaniel Fojt 	DPP_PA_PEER_DISCOVERY_RESP = 6,
33*a1157835SDaniel Fojt 	DPP_PA_PKEX_EXCHANGE_REQ = 7,
34*a1157835SDaniel Fojt 	DPP_PA_PKEX_EXCHANGE_RESP = 8,
35*a1157835SDaniel Fojt 	DPP_PA_PKEX_COMMIT_REVEAL_REQ = 9,
36*a1157835SDaniel Fojt 	DPP_PA_PKEX_COMMIT_REVEAL_RESP = 10,
37*a1157835SDaniel Fojt 	DPP_PA_CONFIGURATION_RESULT = 11,
38*a1157835SDaniel Fojt };
39*a1157835SDaniel Fojt 
40*a1157835SDaniel Fojt enum dpp_attribute_id {
41*a1157835SDaniel Fojt 	DPP_ATTR_STATUS = 0x1000,
42*a1157835SDaniel Fojt 	DPP_ATTR_I_BOOTSTRAP_KEY_HASH = 0x1001,
43*a1157835SDaniel Fojt 	DPP_ATTR_R_BOOTSTRAP_KEY_HASH = 0x1002,
44*a1157835SDaniel Fojt 	DPP_ATTR_I_PROTOCOL_KEY = 0x1003,
45*a1157835SDaniel Fojt 	DPP_ATTR_WRAPPED_DATA = 0x1004,
46*a1157835SDaniel Fojt 	DPP_ATTR_I_NONCE = 0x1005,
47*a1157835SDaniel Fojt 	DPP_ATTR_I_CAPABILITIES = 0x1006,
48*a1157835SDaniel Fojt 	DPP_ATTR_R_NONCE = 0x1007,
49*a1157835SDaniel Fojt 	DPP_ATTR_R_CAPABILITIES = 0x1008,
50*a1157835SDaniel Fojt 	DPP_ATTR_R_PROTOCOL_KEY = 0x1009,
51*a1157835SDaniel Fojt 	DPP_ATTR_I_AUTH_TAG = 0x100A,
52*a1157835SDaniel Fojt 	DPP_ATTR_R_AUTH_TAG = 0x100B,
53*a1157835SDaniel Fojt 	DPP_ATTR_CONFIG_OBJ = 0x100C,
54*a1157835SDaniel Fojt 	DPP_ATTR_CONNECTOR = 0x100D,
55*a1157835SDaniel Fojt 	DPP_ATTR_CONFIG_ATTR_OBJ = 0x100E,
56*a1157835SDaniel Fojt 	DPP_ATTR_BOOTSTRAP_KEY = 0x100F,
57*a1157835SDaniel Fojt 	DPP_ATTR_OWN_NET_NK_HASH = 0x1011,
58*a1157835SDaniel Fojt 	DPP_ATTR_FINITE_CYCLIC_GROUP = 0x1012,
59*a1157835SDaniel Fojt 	DPP_ATTR_ENCRYPTED_KEY = 0x1013,
60*a1157835SDaniel Fojt 	DPP_ATTR_ENROLLEE_NONCE = 0x1014,
61*a1157835SDaniel Fojt 	DPP_ATTR_CODE_IDENTIFIER = 0x1015,
62*a1157835SDaniel Fojt 	DPP_ATTR_TRANSACTION_ID = 0x1016,
63*a1157835SDaniel Fojt 	DPP_ATTR_BOOTSTRAP_INFO = 0x1017,
64*a1157835SDaniel Fojt 	DPP_ATTR_CHANNEL = 0x1018,
65*a1157835SDaniel Fojt 	DPP_ATTR_PROTOCOL_VERSION = 0x1019,
66*a1157835SDaniel Fojt 	DPP_ATTR_ENVELOPED_DATA = 0x101A,
67*a1157835SDaniel Fojt };
68*a1157835SDaniel Fojt 
69*a1157835SDaniel Fojt enum dpp_status_error {
70*a1157835SDaniel Fojt 	DPP_STATUS_OK = 0,
71*a1157835SDaniel Fojt 	DPP_STATUS_NOT_COMPATIBLE = 1,
72*a1157835SDaniel Fojt 	DPP_STATUS_AUTH_FAILURE = 2,
73*a1157835SDaniel Fojt 	DPP_STATUS_UNWRAP_FAILURE = 3,
74*a1157835SDaniel Fojt 	DPP_STATUS_BAD_GROUP = 4,
75*a1157835SDaniel Fojt 	DPP_STATUS_CONFIGURE_FAILURE = 5,
76*a1157835SDaniel Fojt 	DPP_STATUS_RESPONSE_PENDING = 6,
77*a1157835SDaniel Fojt 	DPP_STATUS_INVALID_CONNECTOR = 7,
78*a1157835SDaniel Fojt 	DPP_STATUS_NO_MATCH = 8,
79*a1157835SDaniel Fojt 	DPP_STATUS_CONFIG_REJECTED = 9,
80*a1157835SDaniel Fojt };
81*a1157835SDaniel Fojt 
82*a1157835SDaniel Fojt #define DPP_CAPAB_ENROLLEE BIT(0)
83*a1157835SDaniel Fojt #define DPP_CAPAB_CONFIGURATOR BIT(1)
84*a1157835SDaniel Fojt #define DPP_CAPAB_ROLE_MASK (BIT(0) | BIT(1))
85*a1157835SDaniel Fojt 
86*a1157835SDaniel Fojt #define DPP_BOOTSTRAP_MAX_FREQ 30
87*a1157835SDaniel Fojt #define DPP_MAX_NONCE_LEN 32
88*a1157835SDaniel Fojt #define DPP_MAX_HASH_LEN 64
89*a1157835SDaniel Fojt #define DPP_MAX_SHARED_SECRET_LEN 66
90*a1157835SDaniel Fojt 
91*a1157835SDaniel Fojt struct dpp_curve_params {
92*a1157835SDaniel Fojt 	const char *name;
93*a1157835SDaniel Fojt 	size_t hash_len;
94*a1157835SDaniel Fojt 	size_t aes_siv_key_len;
95*a1157835SDaniel Fojt 	size_t nonce_len;
96*a1157835SDaniel Fojt 	size_t prime_len;
97*a1157835SDaniel Fojt 	const char *jwk_crv;
98*a1157835SDaniel Fojt 	u16 ike_group;
99*a1157835SDaniel Fojt 	const char *jws_alg;
100*a1157835SDaniel Fojt };
101*a1157835SDaniel Fojt 
102*a1157835SDaniel Fojt enum dpp_bootstrap_type {
103*a1157835SDaniel Fojt 	DPP_BOOTSTRAP_QR_CODE,
104*a1157835SDaniel Fojt 	DPP_BOOTSTRAP_PKEX,
105*a1157835SDaniel Fojt };
106*a1157835SDaniel Fojt 
107*a1157835SDaniel Fojt struct dpp_bootstrap_info {
108*a1157835SDaniel Fojt 	struct dl_list list;
109*a1157835SDaniel Fojt 	unsigned int id;
110*a1157835SDaniel Fojt 	enum dpp_bootstrap_type type;
111*a1157835SDaniel Fojt 	char *uri;
112*a1157835SDaniel Fojt 	u8 mac_addr[ETH_ALEN];
113*a1157835SDaniel Fojt 	char *info;
114*a1157835SDaniel Fojt 	unsigned int freq[DPP_BOOTSTRAP_MAX_FREQ];
115*a1157835SDaniel Fojt 	unsigned int num_freq;
116*a1157835SDaniel Fojt 	int own;
117*a1157835SDaniel Fojt 	EVP_PKEY *pubkey;
118*a1157835SDaniel Fojt 	u8 pubkey_hash[SHA256_MAC_LEN];
119*a1157835SDaniel Fojt 	const struct dpp_curve_params *curve;
120*a1157835SDaniel Fojt 	unsigned int pkex_t; /* number of failures before dpp_pkex
121*a1157835SDaniel Fojt 			      * instantiation */
122*a1157835SDaniel Fojt };
123*a1157835SDaniel Fojt 
124*a1157835SDaniel Fojt #define PKEX_COUNTER_T_LIMIT 5
125*a1157835SDaniel Fojt 
126*a1157835SDaniel Fojt struct dpp_pkex {
127*a1157835SDaniel Fojt 	void *msg_ctx;
128*a1157835SDaniel Fojt 	unsigned int initiator:1;
129*a1157835SDaniel Fojt 	unsigned int exchange_done:1;
130*a1157835SDaniel Fojt 	unsigned int failed:1;
131*a1157835SDaniel Fojt 	struct dpp_bootstrap_info *own_bi;
132*a1157835SDaniel Fojt 	u8 own_mac[ETH_ALEN];
133*a1157835SDaniel Fojt 	u8 peer_mac[ETH_ALEN];
134*a1157835SDaniel Fojt 	char *identifier;
135*a1157835SDaniel Fojt 	char *code;
136*a1157835SDaniel Fojt 	EVP_PKEY *x;
137*a1157835SDaniel Fojt 	EVP_PKEY *y;
138*a1157835SDaniel Fojt 	u8 Mx[DPP_MAX_SHARED_SECRET_LEN];
139*a1157835SDaniel Fojt 	u8 Nx[DPP_MAX_SHARED_SECRET_LEN];
140*a1157835SDaniel Fojt 	u8 z[DPP_MAX_HASH_LEN];
141*a1157835SDaniel Fojt 	EVP_PKEY *peer_bootstrap_key;
142*a1157835SDaniel Fojt 	struct wpabuf *exchange_req;
143*a1157835SDaniel Fojt 	struct wpabuf *exchange_resp;
144*a1157835SDaniel Fojt 	unsigned int t; /* number of failures on code use */
145*a1157835SDaniel Fojt 	unsigned int exch_req_wait_time;
146*a1157835SDaniel Fojt 	unsigned int exch_req_tries;
147*a1157835SDaniel Fojt 	unsigned int freq;
148*a1157835SDaniel Fojt };
149*a1157835SDaniel Fojt 
150*a1157835SDaniel Fojt enum dpp_akm {
151*a1157835SDaniel Fojt 	DPP_AKM_UNKNOWN,
152*a1157835SDaniel Fojt 	DPP_AKM_DPP,
153*a1157835SDaniel Fojt 	DPP_AKM_PSK,
154*a1157835SDaniel Fojt 	DPP_AKM_SAE,
155*a1157835SDaniel Fojt 	DPP_AKM_PSK_SAE,
156*a1157835SDaniel Fojt 	DPP_AKM_SAE_DPP,
157*a1157835SDaniel Fojt 	DPP_AKM_PSK_SAE_DPP,
158*a1157835SDaniel Fojt };
159*a1157835SDaniel Fojt 
160*a1157835SDaniel Fojt struct dpp_configuration {
161*a1157835SDaniel Fojt 	u8 ssid[32];
162*a1157835SDaniel Fojt 	size_t ssid_len;
163*a1157835SDaniel Fojt 	enum dpp_akm akm;
164*a1157835SDaniel Fojt 
165*a1157835SDaniel Fojt 	/* For DPP configuration (connector) */
166*a1157835SDaniel Fojt 	os_time_t netaccesskey_expiry;
167*a1157835SDaniel Fojt 
168*a1157835SDaniel Fojt 	/* TODO: groups */
169*a1157835SDaniel Fojt 	char *group_id;
170*a1157835SDaniel Fojt 
171*a1157835SDaniel Fojt 	/* For legacy configuration */
172*a1157835SDaniel Fojt 	char *passphrase;
173*a1157835SDaniel Fojt 	u8 psk[32];
174*a1157835SDaniel Fojt 	int psk_set;
175*a1157835SDaniel Fojt };
176*a1157835SDaniel Fojt 
177*a1157835SDaniel Fojt struct dpp_authentication {
178*a1157835SDaniel Fojt 	void *msg_ctx;
179*a1157835SDaniel Fojt 	u8 peer_version;
180*a1157835SDaniel Fojt 	const struct dpp_curve_params *curve;
181*a1157835SDaniel Fojt 	struct dpp_bootstrap_info *peer_bi;
182*a1157835SDaniel Fojt 	struct dpp_bootstrap_info *own_bi;
183*a1157835SDaniel Fojt 	struct dpp_bootstrap_info *tmp_own_bi;
184*a1157835SDaniel Fojt 	u8 waiting_pubkey_hash[SHA256_MAC_LEN];
185*a1157835SDaniel Fojt 	int response_pending;
186*a1157835SDaniel Fojt 	enum dpp_status_error auth_resp_status;
187*a1157835SDaniel Fojt 	enum dpp_status_error conf_resp_status;
188*a1157835SDaniel Fojt 	u8 peer_mac_addr[ETH_ALEN];
189*a1157835SDaniel Fojt 	u8 i_nonce[DPP_MAX_NONCE_LEN];
190*a1157835SDaniel Fojt 	u8 r_nonce[DPP_MAX_NONCE_LEN];
191*a1157835SDaniel Fojt 	u8 e_nonce[DPP_MAX_NONCE_LEN];
192*a1157835SDaniel Fojt 	u8 i_capab;
193*a1157835SDaniel Fojt 	u8 r_capab;
194*a1157835SDaniel Fojt 	EVP_PKEY *own_protocol_key;
195*a1157835SDaniel Fojt 	EVP_PKEY *peer_protocol_key;
196*a1157835SDaniel Fojt 	struct wpabuf *req_msg;
197*a1157835SDaniel Fojt 	struct wpabuf *resp_msg;
198*a1157835SDaniel Fojt 	/* Intersection of possible frequencies for initiating DPP
199*a1157835SDaniel Fojt 	 * Authentication exchange */
200*a1157835SDaniel Fojt 	unsigned int freq[DPP_BOOTSTRAP_MAX_FREQ];
201*a1157835SDaniel Fojt 	unsigned int num_freq, freq_idx;
202*a1157835SDaniel Fojt 	unsigned int curr_freq;
203*a1157835SDaniel Fojt 	unsigned int neg_freq;
204*a1157835SDaniel Fojt 	unsigned int num_freq_iters;
205*a1157835SDaniel Fojt 	size_t secret_len;
206*a1157835SDaniel Fojt 	u8 Mx[DPP_MAX_SHARED_SECRET_LEN];
207*a1157835SDaniel Fojt 	size_t Mx_len;
208*a1157835SDaniel Fojt 	u8 Nx[DPP_MAX_SHARED_SECRET_LEN];
209*a1157835SDaniel Fojt 	size_t Nx_len;
210*a1157835SDaniel Fojt 	u8 Lx[DPP_MAX_SHARED_SECRET_LEN];
211*a1157835SDaniel Fojt 	size_t Lx_len;
212*a1157835SDaniel Fojt 	u8 k1[DPP_MAX_HASH_LEN];
213*a1157835SDaniel Fojt 	u8 k2[DPP_MAX_HASH_LEN];
214*a1157835SDaniel Fojt 	u8 ke[DPP_MAX_HASH_LEN];
215*a1157835SDaniel Fojt 	int initiator;
216*a1157835SDaniel Fojt 	int waiting_auth_resp;
217*a1157835SDaniel Fojt 	int waiting_auth_conf;
218*a1157835SDaniel Fojt 	int auth_req_ack;
219*a1157835SDaniel Fojt 	unsigned int auth_resp_tries;
220*a1157835SDaniel Fojt 	u8 allowed_roles;
221*a1157835SDaniel Fojt 	int configurator;
222*a1157835SDaniel Fojt 	int remove_on_tx_status;
223*a1157835SDaniel Fojt 	int connect_on_tx_status;
224*a1157835SDaniel Fojt 	int waiting_conf_result;
225*a1157835SDaniel Fojt 	int auth_success;
226*a1157835SDaniel Fojt 	struct wpabuf *conf_req;
227*a1157835SDaniel Fojt 	const struct wpabuf *conf_resp; /* owned by GAS server */
228*a1157835SDaniel Fojt 	struct dpp_configuration *conf_ap;
229*a1157835SDaniel Fojt 	struct dpp_configuration *conf_sta;
230*a1157835SDaniel Fojt 	struct dpp_configurator *conf;
231*a1157835SDaniel Fojt 	char *connector; /* received signedConnector */
232*a1157835SDaniel Fojt 	u8 ssid[SSID_MAX_LEN];
233*a1157835SDaniel Fojt 	u8 ssid_len;
234*a1157835SDaniel Fojt 	char passphrase[64];
235*a1157835SDaniel Fojt 	u8 psk[PMK_LEN];
236*a1157835SDaniel Fojt 	int psk_set;
237*a1157835SDaniel Fojt 	enum dpp_akm akm;
238*a1157835SDaniel Fojt 	struct wpabuf *net_access_key;
239*a1157835SDaniel Fojt 	os_time_t net_access_key_expiry;
240*a1157835SDaniel Fojt 	struct wpabuf *c_sign_key;
241*a1157835SDaniel Fojt #ifdef CONFIG_TESTING_OPTIONS
242*a1157835SDaniel Fojt 	char *config_obj_override;
243*a1157835SDaniel Fojt 	char *discovery_override;
244*a1157835SDaniel Fojt 	char *groups_override;
245*a1157835SDaniel Fojt 	unsigned int ignore_netaccesskey_mismatch:1;
246*a1157835SDaniel Fojt #endif /* CONFIG_TESTING_OPTIONS */
247*a1157835SDaniel Fojt };
248*a1157835SDaniel Fojt 
249*a1157835SDaniel Fojt struct dpp_configurator {
250*a1157835SDaniel Fojt 	struct dl_list list;
251*a1157835SDaniel Fojt 	unsigned int id;
252*a1157835SDaniel Fojt 	int own;
253*a1157835SDaniel Fojt 	EVP_PKEY *csign;
254*a1157835SDaniel Fojt 	char *kid;
255*a1157835SDaniel Fojt 	const struct dpp_curve_params *curve;
256*a1157835SDaniel Fojt };
257*a1157835SDaniel Fojt 
258*a1157835SDaniel Fojt struct dpp_introduction {
259*a1157835SDaniel Fojt 	u8 pmkid[PMKID_LEN];
260*a1157835SDaniel Fojt 	u8 pmk[PMK_LEN_MAX];
261*a1157835SDaniel Fojt 	size_t pmk_len;
262*a1157835SDaniel Fojt };
263*a1157835SDaniel Fojt 
264*a1157835SDaniel Fojt struct dpp_relay_config {
265*a1157835SDaniel Fojt 	const struct hostapd_ip_addr *ipaddr;
266*a1157835SDaniel Fojt 	const u8 *pkhash;
267*a1157835SDaniel Fojt 
268*a1157835SDaniel Fojt 	void *cb_ctx;
269*a1157835SDaniel Fojt 	void (*tx)(void *ctx, const u8 *addr, unsigned int freq, const u8 *msg,
270*a1157835SDaniel Fojt 		   size_t len);
271*a1157835SDaniel Fojt 	void (*gas_resp_tx)(void *ctx, const u8 *addr, u8 dialog_token, int prot,
272*a1157835SDaniel Fojt 			    struct wpabuf *buf);
273*a1157835SDaniel Fojt };
274*a1157835SDaniel Fojt 
275*a1157835SDaniel Fojt struct dpp_controller_config {
276*a1157835SDaniel Fojt 	const char *configurator_params;
277*a1157835SDaniel Fojt 	int tcp_port;
278*a1157835SDaniel Fojt };
279*a1157835SDaniel Fojt 
280*a1157835SDaniel Fojt #ifdef CONFIG_TESTING_OPTIONS
281*a1157835SDaniel Fojt enum dpp_test_behavior {
282*a1157835SDaniel Fojt 	DPP_TEST_DISABLED = 0,
283*a1157835SDaniel Fojt 	DPP_TEST_AFTER_WRAPPED_DATA_AUTH_REQ = 1,
284*a1157835SDaniel Fojt 	DPP_TEST_AFTER_WRAPPED_DATA_AUTH_RESP = 2,
285*a1157835SDaniel Fojt 	DPP_TEST_AFTER_WRAPPED_DATA_AUTH_CONF = 3,
286*a1157835SDaniel Fojt 	DPP_TEST_AFTER_WRAPPED_DATA_PKEX_CR_REQ = 4,
287*a1157835SDaniel Fojt 	DPP_TEST_AFTER_WRAPPED_DATA_PKEX_CR_RESP = 5,
288*a1157835SDaniel Fojt 	DPP_TEST_AFTER_WRAPPED_DATA_CONF_REQ = 6,
289*a1157835SDaniel Fojt 	DPP_TEST_AFTER_WRAPPED_DATA_CONF_RESP = 7,
290*a1157835SDaniel Fojt 	DPP_TEST_ZERO_I_CAPAB = 8,
291*a1157835SDaniel Fojt 	DPP_TEST_ZERO_R_CAPAB = 9,
292*a1157835SDaniel Fojt 	DPP_TEST_NO_R_BOOTSTRAP_KEY_HASH_AUTH_REQ = 10,
293*a1157835SDaniel Fojt 	DPP_TEST_NO_I_BOOTSTRAP_KEY_HASH_AUTH_REQ = 11,
294*a1157835SDaniel Fojt 	DPP_TEST_NO_I_PROTO_KEY_AUTH_REQ = 12,
295*a1157835SDaniel Fojt 	DPP_TEST_NO_I_NONCE_AUTH_REQ = 13,
296*a1157835SDaniel Fojt 	DPP_TEST_NO_I_CAPAB_AUTH_REQ = 14,
297*a1157835SDaniel Fojt 	DPP_TEST_NO_WRAPPED_DATA_AUTH_REQ = 15,
298*a1157835SDaniel Fojt 	DPP_TEST_NO_STATUS_AUTH_RESP = 16,
299*a1157835SDaniel Fojt 	DPP_TEST_NO_R_BOOTSTRAP_KEY_HASH_AUTH_RESP = 17,
300*a1157835SDaniel Fojt 	DPP_TEST_NO_I_BOOTSTRAP_KEY_HASH_AUTH_RESP = 18,
301*a1157835SDaniel Fojt 	DPP_TEST_NO_R_PROTO_KEY_AUTH_RESP = 19,
302*a1157835SDaniel Fojt 	DPP_TEST_NO_R_NONCE_AUTH_RESP = 20,
303*a1157835SDaniel Fojt 	DPP_TEST_NO_I_NONCE_AUTH_RESP = 21,
304*a1157835SDaniel Fojt 	DPP_TEST_NO_R_CAPAB_AUTH_RESP = 22,
305*a1157835SDaniel Fojt 	DPP_TEST_NO_R_AUTH_AUTH_RESP = 23,
306*a1157835SDaniel Fojt 	DPP_TEST_NO_WRAPPED_DATA_AUTH_RESP = 24,
307*a1157835SDaniel Fojt 	DPP_TEST_NO_STATUS_AUTH_CONF = 25,
308*a1157835SDaniel Fojt 	DPP_TEST_NO_R_BOOTSTRAP_KEY_HASH_AUTH_CONF = 26,
309*a1157835SDaniel Fojt 	DPP_TEST_NO_I_BOOTSTRAP_KEY_HASH_AUTH_CONF = 27,
310*a1157835SDaniel Fojt 	DPP_TEST_NO_I_AUTH_AUTH_CONF = 28,
311*a1157835SDaniel Fojt 	DPP_TEST_NO_WRAPPED_DATA_AUTH_CONF = 29,
312*a1157835SDaniel Fojt 	DPP_TEST_I_NONCE_MISMATCH_AUTH_RESP = 30,
313*a1157835SDaniel Fojt 	DPP_TEST_INCOMPATIBLE_R_CAPAB_AUTH_RESP = 31,
314*a1157835SDaniel Fojt 	DPP_TEST_R_AUTH_MISMATCH_AUTH_RESP = 32,
315*a1157835SDaniel Fojt 	DPP_TEST_I_AUTH_MISMATCH_AUTH_CONF = 33,
316*a1157835SDaniel Fojt 	DPP_TEST_NO_FINITE_CYCLIC_GROUP_PKEX_EXCHANGE_REQ = 34,
317*a1157835SDaniel Fojt 	DPP_TEST_NO_ENCRYPTED_KEY_PKEX_EXCHANGE_REQ = 35,
318*a1157835SDaniel Fojt 	DPP_TEST_NO_STATUS_PKEX_EXCHANGE_RESP = 36,
319*a1157835SDaniel Fojt 	DPP_TEST_NO_ENCRYPTED_KEY_PKEX_EXCHANGE_RESP = 37,
320*a1157835SDaniel Fojt 	DPP_TEST_NO_BOOTSTRAP_KEY_PKEX_CR_REQ = 38,
321*a1157835SDaniel Fojt 	DPP_TEST_NO_I_AUTH_TAG_PKEX_CR_REQ = 39,
322*a1157835SDaniel Fojt 	DPP_TEST_NO_WRAPPED_DATA_PKEX_CR_REQ = 40,
323*a1157835SDaniel Fojt 	DPP_TEST_NO_BOOTSTRAP_KEY_PKEX_CR_RESP = 41,
324*a1157835SDaniel Fojt 	DPP_TEST_NO_R_AUTH_TAG_PKEX_CR_RESP = 42,
325*a1157835SDaniel Fojt 	DPP_TEST_NO_WRAPPED_DATA_PKEX_CR_RESP = 43,
326*a1157835SDaniel Fojt 	DPP_TEST_INVALID_ENCRYPTED_KEY_PKEX_EXCHANGE_REQ = 44,
327*a1157835SDaniel Fojt 	DPP_TEST_INVALID_ENCRYPTED_KEY_PKEX_EXCHANGE_RESP = 45,
328*a1157835SDaniel Fojt 	DPP_TEST_INVALID_STATUS_PKEX_EXCHANGE_RESP = 46,
329*a1157835SDaniel Fojt 	DPP_TEST_INVALID_BOOTSTRAP_KEY_PKEX_CR_REQ = 47,
330*a1157835SDaniel Fojt 	DPP_TEST_INVALID_BOOTSTRAP_KEY_PKEX_CR_RESP = 48,
331*a1157835SDaniel Fojt 	DPP_TEST_I_AUTH_TAG_MISMATCH_PKEX_CR_REQ = 49,
332*a1157835SDaniel Fojt 	DPP_TEST_R_AUTH_TAG_MISMATCH_PKEX_CR_RESP = 50,
333*a1157835SDaniel Fojt 	DPP_TEST_NO_E_NONCE_CONF_REQ = 51,
334*a1157835SDaniel Fojt 	DPP_TEST_NO_CONFIG_ATTR_OBJ_CONF_REQ = 52,
335*a1157835SDaniel Fojt 	DPP_TEST_NO_WRAPPED_DATA_CONF_REQ = 53,
336*a1157835SDaniel Fojt 	DPP_TEST_NO_E_NONCE_CONF_RESP = 54,
337*a1157835SDaniel Fojt 	DPP_TEST_NO_CONFIG_OBJ_CONF_RESP = 55,
338*a1157835SDaniel Fojt 	DPP_TEST_NO_STATUS_CONF_RESP = 56,
339*a1157835SDaniel Fojt 	DPP_TEST_NO_WRAPPED_DATA_CONF_RESP = 57,
340*a1157835SDaniel Fojt 	DPP_TEST_INVALID_STATUS_CONF_RESP = 58,
341*a1157835SDaniel Fojt 	DPP_TEST_E_NONCE_MISMATCH_CONF_RESP = 59,
342*a1157835SDaniel Fojt 	DPP_TEST_NO_TRANSACTION_ID_PEER_DISC_REQ = 60,
343*a1157835SDaniel Fojt 	DPP_TEST_NO_CONNECTOR_PEER_DISC_REQ = 61,
344*a1157835SDaniel Fojt 	DPP_TEST_NO_TRANSACTION_ID_PEER_DISC_RESP = 62,
345*a1157835SDaniel Fojt 	DPP_TEST_NO_STATUS_PEER_DISC_RESP = 63,
346*a1157835SDaniel Fojt 	DPP_TEST_NO_CONNECTOR_PEER_DISC_RESP = 64,
347*a1157835SDaniel Fojt 	DPP_TEST_AUTH_RESP_IN_PLACE_OF_CONF = 65,
348*a1157835SDaniel Fojt 	DPP_TEST_INVALID_I_PROTO_KEY_AUTH_REQ = 66,
349*a1157835SDaniel Fojt 	DPP_TEST_INVALID_R_PROTO_KEY_AUTH_RESP = 67,
350*a1157835SDaniel Fojt 	DPP_TEST_INVALID_R_BOOTSTRAP_KEY_HASH_AUTH_REQ = 68,
351*a1157835SDaniel Fojt 	DPP_TEST_INVALID_I_BOOTSTRAP_KEY_HASH_AUTH_REQ = 69,
352*a1157835SDaniel Fojt 	DPP_TEST_INVALID_R_BOOTSTRAP_KEY_HASH_AUTH_RESP = 70,
353*a1157835SDaniel Fojt 	DPP_TEST_INVALID_I_BOOTSTRAP_KEY_HASH_AUTH_RESP = 71,
354*a1157835SDaniel Fojt 	DPP_TEST_INVALID_R_BOOTSTRAP_KEY_HASH_AUTH_CONF = 72,
355*a1157835SDaniel Fojt 	DPP_TEST_INVALID_I_BOOTSTRAP_KEY_HASH_AUTH_CONF = 73,
356*a1157835SDaniel Fojt 	DPP_TEST_INVALID_STATUS_AUTH_RESP = 74,
357*a1157835SDaniel Fojt 	DPP_TEST_INVALID_STATUS_AUTH_CONF = 75,
358*a1157835SDaniel Fojt 	DPP_TEST_INVALID_CONFIG_ATTR_OBJ_CONF_REQ = 76,
359*a1157835SDaniel Fojt 	DPP_TEST_INVALID_TRANSACTION_ID_PEER_DISC_RESP = 77,
360*a1157835SDaniel Fojt 	DPP_TEST_INVALID_STATUS_PEER_DISC_RESP = 78,
361*a1157835SDaniel Fojt 	DPP_TEST_INVALID_CONNECTOR_PEER_DISC_RESP = 79,
362*a1157835SDaniel Fojt 	DPP_TEST_INVALID_CONNECTOR_PEER_DISC_REQ = 80,
363*a1157835SDaniel Fojt 	DPP_TEST_INVALID_I_NONCE_AUTH_REQ = 81,
364*a1157835SDaniel Fojt 	DPP_TEST_INVALID_TRANSACTION_ID_PEER_DISC_REQ = 82,
365*a1157835SDaniel Fojt 	DPP_TEST_INVALID_E_NONCE_CONF_REQ = 83,
366*a1157835SDaniel Fojt 	DPP_TEST_STOP_AT_PKEX_EXCHANGE_RESP = 84,
367*a1157835SDaniel Fojt 	DPP_TEST_STOP_AT_PKEX_CR_REQ = 85,
368*a1157835SDaniel Fojt 	DPP_TEST_STOP_AT_PKEX_CR_RESP = 86,
369*a1157835SDaniel Fojt 	DPP_TEST_STOP_AT_AUTH_REQ = 87,
370*a1157835SDaniel Fojt 	DPP_TEST_STOP_AT_AUTH_RESP = 88,
371*a1157835SDaniel Fojt 	DPP_TEST_STOP_AT_AUTH_CONF = 89,
372*a1157835SDaniel Fojt 	DPP_TEST_STOP_AT_CONF_REQ = 90,
373*a1157835SDaniel Fojt 	DPP_TEST_REJECT_CONFIG = 91,
374*a1157835SDaniel Fojt };
375*a1157835SDaniel Fojt 
376*a1157835SDaniel Fojt extern enum dpp_test_behavior dpp_test;
377*a1157835SDaniel Fojt extern u8 dpp_pkex_own_mac_override[ETH_ALEN];
378*a1157835SDaniel Fojt extern u8 dpp_pkex_peer_mac_override[ETH_ALEN];
379*a1157835SDaniel Fojt extern u8 dpp_pkex_ephemeral_key_override[600];
380*a1157835SDaniel Fojt extern size_t dpp_pkex_ephemeral_key_override_len;
381*a1157835SDaniel Fojt extern u8 dpp_protocol_key_override[600];
382*a1157835SDaniel Fojt extern size_t dpp_protocol_key_override_len;
383*a1157835SDaniel Fojt extern u8 dpp_nonce_override[DPP_MAX_NONCE_LEN];
384*a1157835SDaniel Fojt extern size_t dpp_nonce_override_len;
385*a1157835SDaniel Fojt #endif /* CONFIG_TESTING_OPTIONS */
386*a1157835SDaniel Fojt 
387*a1157835SDaniel Fojt void dpp_bootstrap_info_free(struct dpp_bootstrap_info *info);
388*a1157835SDaniel Fojt const char * dpp_bootstrap_type_txt(enum dpp_bootstrap_type type);
389*a1157835SDaniel Fojt int dpp_bootstrap_key_hash(struct dpp_bootstrap_info *bi);
390*a1157835SDaniel Fojt int dpp_parse_uri_chan_list(struct dpp_bootstrap_info *bi,
391*a1157835SDaniel Fojt 			    const char *chan_list);
392*a1157835SDaniel Fojt int dpp_parse_uri_mac(struct dpp_bootstrap_info *bi, const char *mac);
393*a1157835SDaniel Fojt int dpp_parse_uri_info(struct dpp_bootstrap_info *bi, const char *info);
394*a1157835SDaniel Fojt struct dpp_bootstrap_info * dpp_parse_qr_code(const char *uri);
395*a1157835SDaniel Fojt char * dpp_keygen(struct dpp_bootstrap_info *bi, const char *curve,
396*a1157835SDaniel Fojt 		  const u8 *privkey, size_t privkey_len);
397*a1157835SDaniel Fojt struct hostapd_hw_modes;
398*a1157835SDaniel Fojt struct dpp_authentication * dpp_auth_init(void *msg_ctx,
399*a1157835SDaniel Fojt 					  struct dpp_bootstrap_info *peer_bi,
400*a1157835SDaniel Fojt 					  struct dpp_bootstrap_info *own_bi,
401*a1157835SDaniel Fojt 					  u8 dpp_allowed_roles,
402*a1157835SDaniel Fojt 					  unsigned int neg_freq,
403*a1157835SDaniel Fojt 					  struct hostapd_hw_modes *own_modes,
404*a1157835SDaniel Fojt 					  u16 num_modes);
405*a1157835SDaniel Fojt struct dpp_authentication *
406*a1157835SDaniel Fojt dpp_auth_req_rx(void *msg_ctx, u8 dpp_allowed_roles, int qr_mutual,
407*a1157835SDaniel Fojt 		struct dpp_bootstrap_info *peer_bi,
408*a1157835SDaniel Fojt 		struct dpp_bootstrap_info *own_bi,
409*a1157835SDaniel Fojt 		unsigned int freq, const u8 *hdr, const u8 *attr_start,
410*a1157835SDaniel Fojt 		size_t attr_len);
411*a1157835SDaniel Fojt struct wpabuf *
412*a1157835SDaniel Fojt dpp_auth_resp_rx(struct dpp_authentication *auth, const u8 *hdr,
413*a1157835SDaniel Fojt 		 const u8 *attr_start, size_t attr_len);
414*a1157835SDaniel Fojt struct wpabuf * dpp_build_conf_req(struct dpp_authentication *auth,
415*a1157835SDaniel Fojt 				   const char *json);
416*a1157835SDaniel Fojt int dpp_auth_conf_rx(struct dpp_authentication *auth, const u8 *hdr,
417*a1157835SDaniel Fojt 		     const u8 *attr_start, size_t attr_len);
418*a1157835SDaniel Fojt int dpp_notify_new_qr_code(struct dpp_authentication *auth,
419*a1157835SDaniel Fojt 			   struct dpp_bootstrap_info *peer_bi);
420*a1157835SDaniel Fojt struct dpp_configuration * dpp_configuration_alloc(const char *type);
421*a1157835SDaniel Fojt int dpp_akm_psk(enum dpp_akm akm);
422*a1157835SDaniel Fojt int dpp_akm_sae(enum dpp_akm akm);
423*a1157835SDaniel Fojt int dpp_akm_legacy(enum dpp_akm akm);
424*a1157835SDaniel Fojt int dpp_akm_dpp(enum dpp_akm akm);
425*a1157835SDaniel Fojt int dpp_akm_ver2(enum dpp_akm akm);
426*a1157835SDaniel Fojt int dpp_configuration_valid(const struct dpp_configuration *conf);
427*a1157835SDaniel Fojt void dpp_configuration_free(struct dpp_configuration *conf);
428*a1157835SDaniel Fojt int dpp_set_configurator(struct dpp_global *dpp, void *msg_ctx,
429*a1157835SDaniel Fojt 			 struct dpp_authentication *auth,
430*a1157835SDaniel Fojt 			 const char *cmd);
431*a1157835SDaniel Fojt void dpp_auth_deinit(struct dpp_authentication *auth);
432*a1157835SDaniel Fojt struct wpabuf *
433*a1157835SDaniel Fojt dpp_conf_req_rx(struct dpp_authentication *auth, const u8 *attr_start,
434*a1157835SDaniel Fojt 		size_t attr_len);
435*a1157835SDaniel Fojt int dpp_conf_resp_rx(struct dpp_authentication *auth,
436*a1157835SDaniel Fojt 		     const struct wpabuf *resp);
437*a1157835SDaniel Fojt enum dpp_status_error dpp_conf_result_rx(struct dpp_authentication *auth,
438*a1157835SDaniel Fojt 					 const u8 *hdr,
439*a1157835SDaniel Fojt 					 const u8 *attr_start, size_t attr_len);
440*a1157835SDaniel Fojt struct wpabuf * dpp_build_conf_result(struct dpp_authentication *auth,
441*a1157835SDaniel Fojt 				      enum dpp_status_error status);
442*a1157835SDaniel Fojt struct wpabuf * dpp_alloc_msg(enum dpp_public_action_frame_type type,
443*a1157835SDaniel Fojt 			      size_t len);
444*a1157835SDaniel Fojt const u8 * dpp_get_attr(const u8 *buf, size_t len, u16 req_id, u16 *ret_len);
445*a1157835SDaniel Fojt int dpp_check_attrs(const u8 *buf, size_t len);
446*a1157835SDaniel Fojt int dpp_key_expired(const char *timestamp, os_time_t *expiry);
447*a1157835SDaniel Fojt const char * dpp_akm_str(enum dpp_akm akm);
448*a1157835SDaniel Fojt int dpp_configurator_get_key(const struct dpp_configurator *conf, char *buf,
449*a1157835SDaniel Fojt 			     size_t buflen);
450*a1157835SDaniel Fojt void dpp_configurator_free(struct dpp_configurator *conf);
451*a1157835SDaniel Fojt struct dpp_configurator *
452*a1157835SDaniel Fojt dpp_keygen_configurator(const char *curve, const u8 *privkey,
453*a1157835SDaniel Fojt 			size_t privkey_len);
454*a1157835SDaniel Fojt int dpp_configurator_own_config(struct dpp_authentication *auth,
455*a1157835SDaniel Fojt 				const char *curve, int ap);
456*a1157835SDaniel Fojt enum dpp_status_error
457*a1157835SDaniel Fojt dpp_peer_intro(struct dpp_introduction *intro, const char *own_connector,
458*a1157835SDaniel Fojt 	       const u8 *net_access_key, size_t net_access_key_len,
459*a1157835SDaniel Fojt 	       const u8 *csign_key, size_t csign_key_len,
460*a1157835SDaniel Fojt 	       const u8 *peer_connector, size_t peer_connector_len,
461*a1157835SDaniel Fojt 	       os_time_t *expiry);
462*a1157835SDaniel Fojt struct dpp_pkex * dpp_pkex_init(void *msg_ctx, struct dpp_bootstrap_info *bi,
463*a1157835SDaniel Fojt 				const u8 *own_mac,
464*a1157835SDaniel Fojt 				const char *identifier,
465*a1157835SDaniel Fojt 				const char *code);
466*a1157835SDaniel Fojt struct dpp_pkex * dpp_pkex_rx_exchange_req(void *msg_ctx,
467*a1157835SDaniel Fojt 					   struct dpp_bootstrap_info *bi,
468*a1157835SDaniel Fojt 					   const u8 *own_mac,
469*a1157835SDaniel Fojt 					   const u8 *peer_mac,
470*a1157835SDaniel Fojt 					   const char *identifier,
471*a1157835SDaniel Fojt 					   const char *code,
472*a1157835SDaniel Fojt 					   const u8 *buf, size_t len);
473*a1157835SDaniel Fojt struct wpabuf * dpp_pkex_rx_exchange_resp(struct dpp_pkex *pkex,
474*a1157835SDaniel Fojt 					  const u8 *peer_mac,
475*a1157835SDaniel Fojt 					  const u8 *buf, size_t len);
476*a1157835SDaniel Fojt struct wpabuf * dpp_pkex_rx_commit_reveal_req(struct dpp_pkex *pkex,
477*a1157835SDaniel Fojt 					      const u8 *hdr,
478*a1157835SDaniel Fojt 					      const u8 *buf, size_t len);
479*a1157835SDaniel Fojt int dpp_pkex_rx_commit_reveal_resp(struct dpp_pkex *pkex, const u8 *hdr,
480*a1157835SDaniel Fojt 				   const u8 *buf, size_t len);
481*a1157835SDaniel Fojt void dpp_pkex_free(struct dpp_pkex *pkex);
482*a1157835SDaniel Fojt 
483*a1157835SDaniel Fojt char * dpp_corrupt_connector_signature(const char *connector);
484*a1157835SDaniel Fojt 
485*a1157835SDaniel Fojt 
486*a1157835SDaniel Fojt struct dpp_pfs {
487*a1157835SDaniel Fojt 	struct crypto_ecdh *ecdh;
488*a1157835SDaniel Fojt 	const struct dpp_curve_params *curve;
489*a1157835SDaniel Fojt 	struct wpabuf *ie;
490*a1157835SDaniel Fojt 	struct wpabuf *secret;
491*a1157835SDaniel Fojt };
492*a1157835SDaniel Fojt 
493*a1157835SDaniel Fojt struct dpp_pfs * dpp_pfs_init(const u8 *net_access_key,
494*a1157835SDaniel Fojt 			      size_t net_access_key_len);
495*a1157835SDaniel Fojt int dpp_pfs_process(struct dpp_pfs *pfs, const u8 *peer_ie, size_t peer_ie_len);
496*a1157835SDaniel Fojt void dpp_pfs_free(struct dpp_pfs *pfs);
497*a1157835SDaniel Fojt 
498*a1157835SDaniel Fojt struct dpp_bootstrap_info * dpp_add_qr_code(struct dpp_global *dpp,
499*a1157835SDaniel Fojt 					    const char *uri);
500*a1157835SDaniel Fojt int dpp_bootstrap_gen(struct dpp_global *dpp, const char *cmd);
501*a1157835SDaniel Fojt struct dpp_bootstrap_info *
502*a1157835SDaniel Fojt dpp_bootstrap_get_id(struct dpp_global *dpp, unsigned int id);
503*a1157835SDaniel Fojt int dpp_bootstrap_remove(struct dpp_global *dpp, const char *id);
504*a1157835SDaniel Fojt struct dpp_bootstrap_info *
505*a1157835SDaniel Fojt dpp_pkex_finish(struct dpp_global *dpp, struct dpp_pkex *pkex, const u8 *peer,
506*a1157835SDaniel Fojt 		unsigned int freq);
507*a1157835SDaniel Fojt const char * dpp_bootstrap_get_uri(struct dpp_global *dpp, unsigned int id);
508*a1157835SDaniel Fojt int dpp_bootstrap_info(struct dpp_global *dpp, int id,
509*a1157835SDaniel Fojt 		       char *reply, int reply_size);
510*a1157835SDaniel Fojt void dpp_bootstrap_find_pair(struct dpp_global *dpp, const u8 *i_bootstrap,
511*a1157835SDaniel Fojt 			     const u8 *r_bootstrap,
512*a1157835SDaniel Fojt 			     struct dpp_bootstrap_info **own_bi,
513*a1157835SDaniel Fojt 			     struct dpp_bootstrap_info **peer_bi);
514*a1157835SDaniel Fojt int dpp_configurator_add(struct dpp_global *dpp, const char *cmd);
515*a1157835SDaniel Fojt int dpp_configurator_remove(struct dpp_global *dpp, const char *id);
516*a1157835SDaniel Fojt int dpp_configurator_get_key_id(struct dpp_global *dpp, unsigned int id,
517*a1157835SDaniel Fojt 				char *buf, size_t buflen);
518*a1157835SDaniel Fojt int dpp_relay_add_controller(struct dpp_global *dpp,
519*a1157835SDaniel Fojt 			     struct dpp_relay_config *config);
520*a1157835SDaniel Fojt int dpp_relay_rx_action(struct dpp_global *dpp, const u8 *src, const u8 *hdr,
521*a1157835SDaniel Fojt 			const u8 *buf, size_t len, unsigned int freq,
522*a1157835SDaniel Fojt 			const u8 *i_bootstrap, const u8 *r_bootstrap);
523*a1157835SDaniel Fojt int dpp_relay_rx_gas_req(struct dpp_global *dpp, const u8 *src, const u8 *data,
524*a1157835SDaniel Fojt 			 size_t data_len);
525*a1157835SDaniel Fojt int dpp_controller_start(struct dpp_global *dpp,
526*a1157835SDaniel Fojt 			 struct dpp_controller_config *config);
527*a1157835SDaniel Fojt void dpp_controller_stop(struct dpp_global *dpp);
528*a1157835SDaniel Fojt int dpp_tcp_init(struct dpp_global *dpp, struct dpp_authentication *auth,
529*a1157835SDaniel Fojt 		 const struct hostapd_ip_addr *addr, int port);
530*a1157835SDaniel Fojt 
531*a1157835SDaniel Fojt struct dpp_global_config {
532*a1157835SDaniel Fojt 	void *msg_ctx;
533*a1157835SDaniel Fojt 	void *cb_ctx;
534*a1157835SDaniel Fojt 	int (*process_conf_obj)(void *ctx, struct dpp_authentication *auth);
535*a1157835SDaniel Fojt };
536*a1157835SDaniel Fojt 
537*a1157835SDaniel Fojt struct dpp_global * dpp_global_init(struct dpp_global_config *config);
538*a1157835SDaniel Fojt void dpp_global_clear(struct dpp_global *dpp);
539*a1157835SDaniel Fojt void dpp_global_deinit(struct dpp_global *dpp);
540*a1157835SDaniel Fojt 
541*a1157835SDaniel Fojt #endif /* CONFIG_DPP */
542*a1157835SDaniel Fojt #endif /* DPP_H */
543