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