| Dmitry Shmidt | d2986c2 | 2017-10-23 14:22:09 -0700 | [diff] [blame] | 1 | /* | 
|  | 2 | * DPP functionality shared between hostapd and wpa_supplicant | 
|  | 3 | * Copyright (c) 2017, Qualcomm Atheros, Inc. | 
|  | 4 | * | 
|  | 5 | * This software may be distributed under the terms of the BSD license. | 
|  | 6 | * See README for more details. | 
|  | 7 | */ | 
|  | 8 |  | 
|  | 9 | #ifndef DPP_H | 
|  | 10 | #define DPP_H | 
|  | 11 |  | 
|  | 12 | #include <openssl/x509.h> | 
|  | 13 |  | 
|  | 14 | #include "utils/list.h" | 
|  | 15 | #include "common/wpa_common.h" | 
|  | 16 | #include "crypto/sha256.h" | 
|  | 17 |  | 
|  | 18 | #define DPP_HDR_LEN (4 + 2) /* OUI, OUI Type, Crypto Suite, DPP frame type */ | 
|  | 19 |  | 
|  | 20 | enum dpp_public_action_frame_type { | 
|  | 21 | DPP_PA_AUTHENTICATION_REQ = 0, | 
|  | 22 | DPP_PA_AUTHENTICATION_RESP = 1, | 
|  | 23 | DPP_PA_AUTHENTICATION_CONF = 2, | 
|  | 24 | DPP_PA_PEER_DISCOVERY_REQ = 5, | 
|  | 25 | DPP_PA_PEER_DISCOVERY_RESP = 6, | 
|  | 26 | DPP_PA_PKEX_EXCHANGE_REQ = 7, | 
|  | 27 | DPP_PA_PKEX_EXCHANGE_RESP = 8, | 
|  | 28 | DPP_PA_PKEX_COMMIT_REVEAL_REQ = 9, | 
|  | 29 | DPP_PA_PKEX_COMMIT_REVEAL_RESP = 10, | 
|  | 30 | }; | 
|  | 31 |  | 
|  | 32 | enum dpp_attribute_id { | 
|  | 33 | DPP_ATTR_STATUS = 0x1000, | 
|  | 34 | DPP_ATTR_I_BOOTSTRAP_KEY_HASH = 0x1001, | 
|  | 35 | DPP_ATTR_R_BOOTSTRAP_KEY_HASH = 0x1002, | 
|  | 36 | DPP_ATTR_I_PROTOCOL_KEY = 0x1003, | 
|  | 37 | DPP_ATTR_WRAPPED_DATA = 0x1004, | 
|  | 38 | DPP_ATTR_I_NONCE = 0x1005, | 
|  | 39 | DPP_ATTR_I_CAPABILITIES = 0x1006, | 
|  | 40 | DPP_ATTR_R_NONCE = 0x1007, | 
|  | 41 | DPP_ATTR_R_CAPABILITIES = 0x1008, | 
|  | 42 | DPP_ATTR_R_PROTOCOL_KEY = 0x1009, | 
|  | 43 | DPP_ATTR_I_AUTH_TAG = 0x100A, | 
|  | 44 | DPP_ATTR_R_AUTH_TAG = 0x100B, | 
|  | 45 | DPP_ATTR_CONFIG_OBJ = 0x100C, | 
|  | 46 | DPP_ATTR_CONNECTOR = 0x100D, | 
|  | 47 | DPP_ATTR_CONFIG_ATTR_OBJ = 0x100E, | 
|  | 48 | DPP_ATTR_BOOTSTRAP_KEY = 0x100F, | 
|  | 49 | DPP_ATTR_OWN_NET_NK_HASH = 0x1011, | 
|  | 50 | DPP_ATTR_FINITE_CYCLIC_GROUP = 0x1012, | 
|  | 51 | DPP_ATTR_ENCRYPTED_KEY = 0x1013, | 
|  | 52 | DPP_ATTR_ENROLLEE_NONCE = 0x1014, | 
|  | 53 | DPP_ATTR_CODE_IDENTIFIER = 0x1015, | 
|  | 54 | DPP_ATTR_TRANSACTION_ID = 0x1016, | 
|  | 55 | }; | 
|  | 56 |  | 
|  | 57 | enum dpp_status_error { | 
|  | 58 | DPP_STATUS_OK = 0, | 
|  | 59 | DPP_STATUS_NOT_COMPATIBLE = 1, | 
|  | 60 | DPP_STATUS_AUTH_FAILURE = 2, | 
|  | 61 | DPP_STATUS_UNWRAP_FAILURE = 3, | 
|  | 62 | DPP_STATUS_BAD_GROUP = 4, | 
|  | 63 | DPP_STATUS_CONFIGURE_FAILURE = 5, | 
|  | 64 | DPP_STATUS_RESPONSE_PENDING = 6, | 
|  | 65 | }; | 
|  | 66 |  | 
|  | 67 | #define DPP_CAPAB_ENROLLEE BIT(0) | 
|  | 68 | #define DPP_CAPAB_CONFIGURATOR BIT(1) | 
|  | 69 | #define DPP_CAPAB_ROLE_MASK (BIT(0) | BIT(1)) | 
|  | 70 |  | 
|  | 71 | #define DPP_BOOTSTRAP_MAX_FREQ 30 | 
|  | 72 | #define DPP_MAX_NONCE_LEN 32 | 
|  | 73 | #define DPP_MAX_HASH_LEN 64 | 
|  | 74 | #define DPP_MAX_SHARED_SECRET_LEN 66 | 
|  | 75 |  | 
|  | 76 | struct dpp_curve_params { | 
|  | 77 | const char *name; | 
|  | 78 | size_t hash_len; | 
|  | 79 | size_t aes_siv_key_len; | 
|  | 80 | size_t nonce_len; | 
|  | 81 | size_t prime_len; | 
|  | 82 | const char *jwk_crv; | 
|  | 83 | u16 ike_group; | 
|  | 84 | const char *jws_alg; | 
|  | 85 | }; | 
|  | 86 |  | 
|  | 87 | enum dpp_bootstrap_type { | 
|  | 88 | DPP_BOOTSTRAP_QR_CODE, | 
|  | 89 | DPP_BOOTSTRAP_PKEX, | 
|  | 90 | }; | 
|  | 91 |  | 
|  | 92 | struct dpp_bootstrap_info { | 
|  | 93 | struct dl_list list; | 
|  | 94 | unsigned int id; | 
|  | 95 | enum dpp_bootstrap_type type; | 
|  | 96 | char *uri; | 
|  | 97 | u8 mac_addr[ETH_ALEN]; | 
|  | 98 | char *info; | 
|  | 99 | unsigned int freq[DPP_BOOTSTRAP_MAX_FREQ]; | 
|  | 100 | unsigned int num_freq; | 
|  | 101 | int own; | 
|  | 102 | EVP_PKEY *pubkey; | 
|  | 103 | u8 pubkey_hash[SHA256_MAC_LEN]; | 
|  | 104 | const struct dpp_curve_params *curve; | 
|  | 105 | }; | 
|  | 106 |  | 
|  | 107 | struct dpp_pkex { | 
|  | 108 | unsigned int initiator:1; | 
|  | 109 | unsigned int exchange_done:1; | 
|  | 110 | struct dpp_bootstrap_info *own_bi; | 
|  | 111 | u8 own_mac[ETH_ALEN]; | 
|  | 112 | u8 peer_mac[ETH_ALEN]; | 
|  | 113 | char *identifier; | 
|  | 114 | char *code; | 
|  | 115 | EVP_PKEY *x; | 
|  | 116 | EVP_PKEY *y; | 
|  | 117 | u8 Mx[DPP_MAX_SHARED_SECRET_LEN]; | 
|  | 118 | u8 Nx[DPP_MAX_SHARED_SECRET_LEN]; | 
|  | 119 | u8 z[DPP_MAX_HASH_LEN]; | 
|  | 120 | EVP_PKEY *peer_bootstrap_key; | 
|  | 121 | struct wpabuf *exchange_req; | 
|  | 122 | struct wpabuf *exchange_resp; | 
|  | 123 | }; | 
|  | 124 |  | 
|  | 125 | struct dpp_configuration { | 
|  | 126 | u8 ssid[32]; | 
|  | 127 | size_t ssid_len; | 
|  | 128 | int dpp; /* whether to use DPP or legacy configuration */ | 
|  | 129 |  | 
|  | 130 | /* For DPP configuration (connector) */ | 
|  | 131 | os_time_t netaccesskey_expiry; | 
|  | 132 |  | 
|  | 133 | /* TODO: groups */ | 
|  | 134 |  | 
|  | 135 | /* For legacy configuration */ | 
|  | 136 | char *passphrase; | 
|  | 137 | u8 psk[32]; | 
|  | 138 | }; | 
|  | 139 |  | 
|  | 140 | struct dpp_authentication { | 
|  | 141 | void *msg_ctx; | 
|  | 142 | const struct dpp_curve_params *curve; | 
|  | 143 | struct dpp_bootstrap_info *peer_bi; | 
|  | 144 | struct dpp_bootstrap_info *own_bi; | 
|  | 145 | u8 waiting_pubkey_hash[SHA256_MAC_LEN]; | 
|  | 146 | int response_pending; | 
|  | 147 | enum dpp_status_error auth_resp_status; | 
|  | 148 | u8 peer_mac_addr[ETH_ALEN]; | 
|  | 149 | u8 i_nonce[DPP_MAX_NONCE_LEN]; | 
|  | 150 | u8 r_nonce[DPP_MAX_NONCE_LEN]; | 
|  | 151 | u8 e_nonce[DPP_MAX_NONCE_LEN]; | 
|  | 152 | u8 i_capab; | 
|  | 153 | u8 r_capab; | 
|  | 154 | EVP_PKEY *own_protocol_key; | 
|  | 155 | EVP_PKEY *peer_protocol_key; | 
|  | 156 | struct wpabuf *req_msg; | 
|  | 157 | struct wpabuf *resp_msg; | 
|  | 158 | unsigned int curr_freq; | 
|  | 159 | size_t secret_len; | 
|  | 160 | u8 Mx[DPP_MAX_SHARED_SECRET_LEN]; | 
|  | 161 | u8 Nx[DPP_MAX_SHARED_SECRET_LEN]; | 
|  | 162 | u8 Lx[DPP_MAX_SHARED_SECRET_LEN]; | 
|  | 163 | u8 k1[DPP_MAX_HASH_LEN]; | 
|  | 164 | u8 k2[DPP_MAX_HASH_LEN]; | 
|  | 165 | u8 ke[DPP_MAX_HASH_LEN]; | 
|  | 166 | int initiator; | 
|  | 167 | int configurator; | 
|  | 168 | int remove_on_tx_status; | 
|  | 169 | int auth_success; | 
|  | 170 | struct wpabuf *conf_req; | 
|  | 171 | struct dpp_configuration *conf_ap; | 
|  | 172 | struct dpp_configuration *conf_sta; | 
|  | 173 | struct dpp_configurator *conf; | 
|  | 174 | char *connector; /* received signedConnector */ | 
|  | 175 | u8 ssid[SSID_MAX_LEN]; | 
|  | 176 | u8 ssid_len; | 
|  | 177 | char passphrase[64]; | 
|  | 178 | u8 psk[PMK_LEN]; | 
|  | 179 | int psk_set; | 
|  | 180 | struct wpabuf *net_access_key; | 
|  | 181 | os_time_t net_access_key_expiry; | 
|  | 182 | struct wpabuf *c_sign_key; | 
|  | 183 | #ifdef CONFIG_TESTING_OPTIONS | 
|  | 184 | char *config_obj_override; | 
|  | 185 | char *discovery_override; | 
|  | 186 | char *groups_override; | 
|  | 187 | unsigned int ignore_netaccesskey_mismatch:1; | 
|  | 188 | #endif /* CONFIG_TESTING_OPTIONS */ | 
|  | 189 | }; | 
|  | 190 |  | 
|  | 191 | struct dpp_configurator { | 
|  | 192 | struct dl_list list; | 
|  | 193 | unsigned int id; | 
|  | 194 | int own; | 
|  | 195 | EVP_PKEY *csign; | 
|  | 196 | char *kid; | 
|  | 197 | const struct dpp_curve_params *curve; | 
|  | 198 | }; | 
|  | 199 |  | 
|  | 200 | struct dpp_introduction { | 
|  | 201 | u8 pmkid[PMKID_LEN]; | 
|  | 202 | u8 pmk[PMK_LEN_MAX]; | 
|  | 203 | size_t pmk_len; | 
|  | 204 | }; | 
|  | 205 |  | 
|  | 206 | void dpp_bootstrap_info_free(struct dpp_bootstrap_info *info); | 
|  | 207 | const char * dpp_bootstrap_type_txt(enum dpp_bootstrap_type type); | 
|  | 208 | int dpp_bootstrap_key_hash(struct dpp_bootstrap_info *bi); | 
|  | 209 | int dpp_parse_uri_chan_list(struct dpp_bootstrap_info *bi, | 
|  | 210 | const char *chan_list); | 
|  | 211 | int dpp_parse_uri_mac(struct dpp_bootstrap_info *bi, const char *mac); | 
|  | 212 | int dpp_parse_uri_info(struct dpp_bootstrap_info *bi, const char *info); | 
|  | 213 | struct dpp_bootstrap_info * dpp_parse_qr_code(const char *uri); | 
|  | 214 | char * dpp_keygen(struct dpp_bootstrap_info *bi, const char *curve, | 
|  | 215 | const u8 *privkey, size_t privkey_len); | 
|  | 216 | struct dpp_authentication * dpp_auth_init(void *msg_ctx, | 
|  | 217 | struct dpp_bootstrap_info *peer_bi, | 
|  | 218 | struct dpp_bootstrap_info *own_bi, | 
|  | 219 | int configurator); | 
|  | 220 | struct dpp_authentication * | 
|  | 221 | dpp_auth_req_rx(void *msg_ctx, u8 dpp_allowed_roles, int qr_mutual, | 
|  | 222 | struct dpp_bootstrap_info *peer_bi, | 
|  | 223 | struct dpp_bootstrap_info *own_bi, | 
|  | 224 | unsigned int freq, const u8 *hdr, const u8 *attr_start, | 
|  | 225 | const u8 *wrapped_data, u16 wrapped_data_len); | 
|  | 226 | struct wpabuf * | 
|  | 227 | dpp_auth_resp_rx(struct dpp_authentication *auth, const u8 *hdr, | 
|  | 228 | const u8 *attr_start, size_t attr_len); | 
|  | 229 | struct wpabuf * dpp_build_conf_req(struct dpp_authentication *auth, | 
|  | 230 | const char *json); | 
|  | 231 | int dpp_auth_conf_rx(struct dpp_authentication *auth, const u8 *hdr, | 
|  | 232 | const u8 *attr_start, size_t attr_len); | 
|  | 233 | int dpp_notify_new_qr_code(struct dpp_authentication *auth, | 
|  | 234 | struct dpp_bootstrap_info *peer_bi); | 
|  | 235 | void dpp_configuration_free(struct dpp_configuration *conf); | 
|  | 236 | void dpp_auth_deinit(struct dpp_authentication *auth); | 
|  | 237 | struct wpabuf * | 
|  | 238 | dpp_conf_req_rx(struct dpp_authentication *auth, const u8 *attr_start, | 
|  | 239 | size_t attr_len); | 
|  | 240 | int dpp_conf_resp_rx(struct dpp_authentication *auth, | 
|  | 241 | const struct wpabuf *resp); | 
|  | 242 | struct wpabuf * dpp_alloc_msg(enum dpp_public_action_frame_type type, | 
|  | 243 | size_t len); | 
|  | 244 | const u8 * dpp_get_attr(const u8 *buf, size_t len, u16 req_id, u16 *ret_len); | 
|  | 245 | int dpp_check_attrs(const u8 *buf, size_t len); | 
|  | 246 | int dpp_key_expired(const char *timestamp, os_time_t *expiry); | 
|  | 247 | void dpp_configurator_free(struct dpp_configurator *conf); | 
|  | 248 | struct dpp_configurator * | 
|  | 249 | dpp_keygen_configurator(const char *curve, const u8 *privkey, | 
|  | 250 | size_t privkey_len); | 
|  | 251 | int dpp_configurator_own_config(struct dpp_authentication *auth, | 
|  | 252 | const char *curve); | 
|  | 253 | int dpp_peer_intro(struct dpp_introduction *intro, const char *own_connector, | 
|  | 254 | const u8 *net_access_key, size_t net_access_key_len, | 
|  | 255 | const u8 *csign_key, size_t csign_key_len, | 
|  | 256 | const u8 *peer_connector, size_t peer_connector_len, | 
|  | 257 | os_time_t *expiry); | 
|  | 258 | struct dpp_pkex * dpp_pkex_init(struct dpp_bootstrap_info *bi, | 
|  | 259 | const u8 *own_mac, | 
|  | 260 | const char *identifier, | 
|  | 261 | const char *code); | 
|  | 262 | struct dpp_pkex * dpp_pkex_rx_exchange_req(struct dpp_bootstrap_info *bi, | 
|  | 263 | const u8 *own_mac, | 
|  | 264 | const u8 *peer_mac, | 
|  | 265 | const char *identifier, | 
|  | 266 | const char *code, | 
|  | 267 | const u8 *buf, size_t len); | 
|  | 268 | struct wpabuf * dpp_pkex_rx_exchange_resp(struct dpp_pkex *pkex, | 
|  | 269 | const u8 *buf, size_t len); | 
|  | 270 | struct wpabuf * dpp_pkex_rx_commit_reveal_req(struct dpp_pkex *pkex, | 
|  | 271 | const u8 *hdr, | 
|  | 272 | const u8 *buf, size_t len); | 
|  | 273 | int dpp_pkex_rx_commit_reveal_resp(struct dpp_pkex *pkex, const u8 *hdr, | 
|  | 274 | const u8 *buf, size_t len); | 
|  | 275 | void dpp_pkex_free(struct dpp_pkex *pkex); | 
|  | 276 |  | 
|  | 277 | #endif /* DPP_H */ |