00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "includes.h"
00016
00017 #include "common.h"
00018 #include "crypto/sha256.h"
00019 #include "wps_i.h"
00020
00021
00022 int wps_process_authenticator(struct wps_data *wps, const u8 *authenticator,
00023 const struct wpabuf *msg)
00024 {
00025 u8 hash[SHA256_MAC_LEN];
00026 const u8 *addr[2];
00027 size_t len[2];
00028
00029 if (authenticator == NULL) {
00030 wpa_printf(MSG_DEBUG, "WPS: No Authenticator attribute "
00031 "included");
00032 return -1;
00033 }
00034
00035 if (wps->last_msg == NULL) {
00036 wpa_printf(MSG_DEBUG, "WPS: Last message not available for "
00037 "validating authenticator");
00038 return -1;
00039 }
00040
00041
00042
00043
00044 addr[0] = wpabuf_head(wps->last_msg);
00045 len[0] = wpabuf_len(wps->last_msg);
00046 addr[1] = wpabuf_head(msg);
00047 len[1] = wpabuf_len(msg) - 4 - WPS_AUTHENTICATOR_LEN;
00048 hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 2, addr, len, hash);
00049
00050 if (os_memcmp(hash, authenticator, WPS_AUTHENTICATOR_LEN) != 0) {
00051 wpa_printf(MSG_DEBUG, "WPS: Incorrect Authenticator");
00052 return -1;
00053 }
00054
00055 return 0;
00056 }
00057
00058
00059 int wps_process_key_wrap_auth(struct wps_data *wps, struct wpabuf *msg,
00060 const u8 *key_wrap_auth)
00061 {
00062 u8 hash[SHA256_MAC_LEN];
00063 const u8 *head;
00064 size_t len;
00065
00066 if (key_wrap_auth == NULL) {
00067 wpa_printf(MSG_DEBUG, "WPS: No KWA in decrypted attribute");
00068 return -1;
00069 }
00070
00071 head = wpabuf_head(msg);
00072 len = wpabuf_len(msg) - 4 - WPS_KWA_LEN;
00073 if (head + len != key_wrap_auth - 4) {
00074 wpa_printf(MSG_DEBUG, "WPS: KWA not in the end of the "
00075 "decrypted attribute");
00076 return -1;
00077 }
00078
00079 hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, head, len, hash);
00080 if (os_memcmp(hash, key_wrap_auth, WPS_KWA_LEN) != 0) {
00081 wpa_printf(MSG_DEBUG, "WPS: Invalid KWA");
00082 return -1;
00083 }
00084
00085 return 0;
00086 }
00087
00088
00089 static int wps_process_cred_network_idx(struct wps_credential *cred,
00090 const u8 *idx)
00091 {
00092 if (idx == NULL) {
00093 wpa_printf(MSG_DEBUG, "WPS: Credential did not include "
00094 "Network Index");
00095 return -1;
00096 }
00097
00098 wpa_printf(MSG_DEBUG, "WPS: Network Index: %d", *idx);
00099
00100 return 0;
00101 }
00102
00103
00104 static int wps_process_cred_ssid(struct wps_credential *cred, const u8 *ssid,
00105 size_t ssid_len)
00106 {
00107 if (ssid == NULL) {
00108 wpa_printf(MSG_DEBUG, "WPS: Credential did not include SSID");
00109 return -1;
00110 }
00111
00112
00113
00114 while (ssid_len > 0 && ssid[ssid_len - 1] == 0)
00115 ssid_len--;
00116
00117 wpa_hexdump_ascii(MSG_DEBUG, "WPS: SSID", ssid, ssid_len);
00118 if (ssid_len <= sizeof(cred->ssid)) {
00119 os_memcpy(cred->ssid, ssid, ssid_len);
00120 cred->ssid_len = ssid_len;
00121 }
00122
00123 return 0;
00124 }
00125
00126
00127 static int wps_process_cred_auth_type(struct wps_credential *cred,
00128 const u8 *auth_type)
00129 {
00130 if (auth_type == NULL) {
00131 wpa_printf(MSG_DEBUG, "WPS: Credential did not include "
00132 "Authentication Type");
00133 return -1;
00134 }
00135
00136 cred->auth_type = WPA_GET_BE16(auth_type);
00137 wpa_printf(MSG_DEBUG, "WPS: Authentication Type: 0x%x",
00138 cred->auth_type);
00139
00140 return 0;
00141 }
00142
00143
00144 static int wps_process_cred_encr_type(struct wps_credential *cred,
00145 const u8 *encr_type)
00146 {
00147 if (encr_type == NULL) {
00148 wpa_printf(MSG_DEBUG, "WPS: Credential did not include "
00149 "Encryption Type");
00150 return -1;
00151 }
00152
00153 cred->encr_type = WPA_GET_BE16(encr_type);
00154 wpa_printf(MSG_DEBUG, "WPS: Encryption Type: 0x%x",
00155 cred->encr_type);
00156
00157 return 0;
00158 }
00159
00160
00161 static int wps_process_cred_network_key_idx(struct wps_credential *cred,
00162 const u8 *key_idx)
00163 {
00164 if (key_idx == NULL)
00165 return 0;
00166
00167 wpa_printf(MSG_DEBUG, "WPS: Network Key Index: %d", *key_idx);
00168 cred->key_idx = *key_idx;
00169
00170 return 0;
00171 }
00172
00173
00174 static int wps_process_cred_network_key(struct wps_credential *cred,
00175 const u8 *key, size_t key_len)
00176 {
00177 if (key == NULL) {
00178 wpa_printf(MSG_DEBUG, "WPS: Credential did not include "
00179 "Network Key");
00180 return -1;
00181 }
00182
00183 wpa_hexdump_key(MSG_DEBUG, "WPS: Network Key", key, key_len);
00184 if (key_len <= sizeof(cred->key)) {
00185 os_memcpy(cred->key, key, key_len);
00186 cred->key_len = key_len;
00187 }
00188
00189 return 0;
00190 }
00191
00192
00193 static int wps_process_cred_mac_addr(struct wps_credential *cred,
00194 const u8 *mac_addr)
00195 {
00196 if (mac_addr == NULL) {
00197 wpa_printf(MSG_DEBUG, "WPS: Credential did not include "
00198 "MAC Address");
00199 return -1;
00200 }
00201
00202 wpa_printf(MSG_DEBUG, "WPS: MAC Address " MACSTR, MAC2STR(mac_addr));
00203 os_memcpy(cred->mac_addr, mac_addr, ETH_ALEN);
00204
00205 return 0;
00206 }
00207
00208
00209 static int wps_process_cred_eap_type(struct wps_credential *cred,
00210 const u8 *eap_type, size_t eap_type_len)
00211 {
00212 if (eap_type == NULL)
00213 return 0;
00214
00215 wpa_hexdump(MSG_DEBUG, "WPS: EAP Type", eap_type, eap_type_len);
00216
00217 return 0;
00218 }
00219
00220
00221 static int wps_process_cred_eap_identity(struct wps_credential *cred,
00222 const u8 *identity,
00223 size_t identity_len)
00224 {
00225 if (identity == NULL)
00226 return 0;
00227
00228 wpa_hexdump_ascii(MSG_DEBUG, "WPS: EAP Identity",
00229 identity, identity_len);
00230
00231 return 0;
00232 }
00233
00234
00235 static int wps_process_cred_key_prov_auto(struct wps_credential *cred,
00236 const u8 *key_prov_auto)
00237 {
00238 if (key_prov_auto == NULL)
00239 return 0;
00240
00241 wpa_printf(MSG_DEBUG, "WPS: Key Provided Automatically: %d",
00242 *key_prov_auto);
00243
00244 return 0;
00245 }
00246
00247
00248 static int wps_process_cred_802_1x_enabled(struct wps_credential *cred,
00249 const u8 *dot1x_enabled)
00250 {
00251 if (dot1x_enabled == NULL)
00252 return 0;
00253
00254 wpa_printf(MSG_DEBUG, "WPS: 802.1X Enabled: %d", *dot1x_enabled);
00255
00256 return 0;
00257 }
00258
00259
00260 static void wps_workaround_cred_key(struct wps_credential *cred)
00261 {
00262 if (cred->auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK) &&
00263 cred->key_len > 8 && cred->key_len < 64 &&
00264 cred->key[cred->key_len - 1] == 0) {
00265
00266
00267
00268
00269
00270 wpa_printf(MSG_DEBUG, "WPS: Workaround - remove NULL "
00271 "termination from ASCII passphrase");
00272 cred->key_len--;
00273 }
00274 }
00275
00276
00277 int wps_process_cred(struct wps_parse_attr *attr,
00278 struct wps_credential *cred)
00279 {
00280 wpa_printf(MSG_DEBUG, "WPS: Process Credential");
00281
00282
00283 if (wps_process_cred_network_idx(cred, attr->network_idx) ||
00284 wps_process_cred_ssid(cred, attr->ssid, attr->ssid_len) ||
00285 wps_process_cred_auth_type(cred, attr->auth_type) ||
00286 wps_process_cred_encr_type(cred, attr->encr_type) ||
00287 wps_process_cred_network_key_idx(cred, attr->network_key_idx) ||
00288 wps_process_cred_network_key(cred, attr->network_key,
00289 attr->network_key_len) ||
00290 wps_process_cred_mac_addr(cred, attr->mac_addr) ||
00291 wps_process_cred_eap_type(cred, attr->eap_type,
00292 attr->eap_type_len) ||
00293 wps_process_cred_eap_identity(cred, attr->eap_identity,
00294 attr->eap_identity_len) ||
00295 wps_process_cred_key_prov_auto(cred, attr->key_prov_auto) ||
00296 wps_process_cred_802_1x_enabled(cred, attr->dot1x_enabled))
00297 return -1;
00298
00299 wps_workaround_cred_key(cred);
00300
00301 return 0;
00302 }
00303
00304
00305 int wps_process_ap_settings(struct wps_parse_attr *attr,
00306 struct wps_credential *cred)
00307 {
00308 wpa_printf(MSG_DEBUG, "WPS: Processing AP Settings");
00309 os_memset(cred, 0, sizeof(*cred));
00310
00311 if (wps_process_cred_ssid(cred, attr->ssid, attr->ssid_len) ||
00312 wps_process_cred_auth_type(cred, attr->auth_type) ||
00313 wps_process_cred_encr_type(cred, attr->encr_type) ||
00314 wps_process_cred_network_key_idx(cred, attr->network_key_idx) ||
00315 wps_process_cred_network_key(cred, attr->network_key,
00316 attr->network_key_len) ||
00317 wps_process_cred_mac_addr(cred, attr->mac_addr))
00318 return -1;
00319
00320 wps_workaround_cred_key(cred);
00321
00322 return 0;
00323 }