00001
00016 #include "includes.h"
00017
00018 #include "common.h"
00019 #include "eloop.h"
00020 #include "sha1.h"
00021 #include "sha256.h"
00022 #include "wpa.h"
00023 #include "defs.h"
00024 #include "wpa_auth_i.h"
00025 #include "wpa_auth_ie.h"
00026
00027 #ifdef CONFIG_PEERKEY
00028
00029 static void wpa_stsl_step(void *eloop_ctx, void *timeout_ctx)
00030 {
00031 #if 0
00032 struct wpa_authenticator *wpa_auth = eloop_ctx;
00033 struct wpa_stsl_negotiation *neg = timeout_ctx;
00034 #endif
00035
00036
00037 }
00038
00039
00040 struct wpa_stsl_search {
00041 const u8 *addr;
00042 struct wpa_state_machine *sm;
00043 };
00044
00045
00046 static int wpa_stsl_select_sta(struct wpa_state_machine *sm, void *ctx)
00047 {
00048 struct wpa_stsl_search *search = ctx;
00049 if (os_memcmp(search->addr, sm->addr, ETH_ALEN) == 0) {
00050 search->sm = sm;
00051 return 1;
00052 }
00053 return 0;
00054 }
00055
00056
00057 static void wpa_smk_send_error(struct wpa_authenticator *wpa_auth,
00058 struct wpa_state_machine *sm, const u8 *peer,
00059 u16 mui, u16 error_type)
00060 {
00061 u8 kde[2 + RSN_SELECTOR_LEN + ETH_ALEN +
00062 2 + RSN_SELECTOR_LEN + sizeof(struct rsn_error_kde)];
00063 u8 *pos;
00064 struct rsn_error_kde error;
00065
00066 wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG,
00067 "Sending SMK Error");
00068
00069 pos = kde;
00070
00071 if (peer) {
00072 pos = wpa_add_kde(pos, RSN_KEY_DATA_MAC_ADDR, peer, ETH_ALEN,
00073 NULL, 0);
00074 }
00075
00076 error.mui = host_to_be16(mui);
00077 error.error_type = host_to_be16(error_type);
00078 pos = wpa_add_kde(pos, RSN_KEY_DATA_ERROR,
00079 (u8 *) &error, sizeof(error), NULL, 0);
00080
00081 __wpa_send_eapol(wpa_auth, sm,
00082 WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC |
00083 WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_ERROR,
00084 NULL, NULL, kde, pos - kde, 0, 0, 0);
00085 }
00086
00087
00088 void wpa_smk_m1(struct wpa_authenticator *wpa_auth,
00089 struct wpa_state_machine *sm, struct wpa_eapol_key *key)
00090 {
00091 struct wpa_eapol_ie_parse kde;
00092 struct wpa_stsl_search search;
00093 u8 *buf, *pos;
00094 size_t buf_len;
00095
00096 if (wpa_parse_kde_ies((const u8 *) (key + 1),
00097 WPA_GET_BE16(key->key_data_length), &kde) < 0) {
00098 wpa_printf(MSG_INFO, "RSN: Failed to parse KDEs in SMK M1");
00099 return;
00100 }
00101
00102 if (kde.rsn_ie == NULL || kde.mac_addr == NULL ||
00103 kde.mac_addr_len < ETH_ALEN) {
00104 wpa_printf(MSG_INFO, "RSN: No RSN IE or MAC address KDE in "
00105 "SMK M1");
00106 return;
00107 }
00108
00109
00110
00111 search.addr = kde.mac_addr;
00112 search.sm = NULL;
00113 if (wpa_auth_for_each_sta(wpa_auth, wpa_stsl_select_sta, &search) ==
00114 0 || search.sm == NULL) {
00115 wpa_printf(MSG_DEBUG, "RSN: SMK handshake with " MACSTR
00116 " aborted - STA not associated anymore",
00117 MAC2STR(kde.mac_addr));
00118 wpa_smk_send_error(wpa_auth, sm, kde.mac_addr, STK_MUI_SMK,
00119 STK_ERR_STA_NR);
00120
00121 return;
00122 }
00123
00124 buf_len = kde.rsn_ie_len + 2 + RSN_SELECTOR_LEN + ETH_ALEN;
00125 buf = os_malloc(buf_len);
00126 if (buf == NULL)
00127 return;
00128
00129 os_memcpy(buf, kde.rsn_ie, kde.rsn_ie_len);
00130 pos = buf + kde.rsn_ie_len;
00131
00132 pos = wpa_add_kde(pos, RSN_KEY_DATA_MAC_ADDR, sm->addr, ETH_ALEN,
00133 NULL, 0);
00134
00135
00136
00137
00138
00139
00140 wpa_auth_logger(wpa_auth, search.sm->addr, LOGGER_DEBUG,
00141 "Sending SMK M2");
00142
00143 __wpa_send_eapol(wpa_auth, search.sm,
00144 WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC |
00145 WPA_KEY_INFO_ACK | WPA_KEY_INFO_SMK_MESSAGE,
00146 NULL, key->key_nonce, buf, pos - buf, 0, 0, 0);
00147
00148 os_free(buf);
00149 }
00150
00151
00152 static void wpa_send_smk_m4(struct wpa_authenticator *wpa_auth,
00153 struct wpa_state_machine *sm,
00154 struct wpa_eapol_key *key,
00155 struct wpa_eapol_ie_parse *kde,
00156 const u8 *smk)
00157 {
00158 u8 *buf, *pos;
00159 size_t buf_len;
00160 u32 lifetime;
00161
00162
00163
00164
00165
00166
00167
00168 buf_len = 2 + RSN_SELECTOR_LEN + ETH_ALEN +
00169 2 + RSN_SELECTOR_LEN + WPA_NONCE_LEN +
00170 2 + RSN_SELECTOR_LEN + PMK_LEN + WPA_NONCE_LEN +
00171 2 + RSN_SELECTOR_LEN + sizeof(lifetime);
00172 pos = buf = os_malloc(buf_len);
00173 if (buf == NULL)
00174 return;
00175
00176
00177 pos = wpa_add_kde(pos, RSN_KEY_DATA_MAC_ADDR, kde->mac_addr, ETH_ALEN,
00178 NULL, 0);
00179
00180
00181 pos = wpa_add_kde(pos, RSN_KEY_DATA_NONCE, kde->nonce, WPA_NONCE_LEN,
00182 NULL, 0);
00183
00184
00185 pos = wpa_add_kde(pos, RSN_KEY_DATA_SMK, smk, PMK_LEN,
00186 key->key_nonce, WPA_NONCE_LEN);
00187
00188
00189 lifetime = htonl(43200);
00190 pos = wpa_add_kde(pos, RSN_KEY_DATA_LIFETIME,
00191 (u8 *) &lifetime, sizeof(lifetime), NULL, 0);
00192
00193 wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
00194 "Sending SMK M4");
00195
00196 __wpa_send_eapol(wpa_auth, sm,
00197 WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC |
00198 WPA_KEY_INFO_INSTALL | WPA_KEY_INFO_SMK_MESSAGE,
00199 NULL, key->key_nonce, buf, pos - buf, 0, 1, 0);
00200
00201 os_free(buf);
00202 }
00203
00204
00205 static void wpa_send_smk_m5(struct wpa_authenticator *wpa_auth,
00206 struct wpa_state_machine *sm,
00207 struct wpa_eapol_key *key,
00208 struct wpa_eapol_ie_parse *kde,
00209 const u8 *smk, const u8 *peer)
00210 {
00211 u8 *buf, *pos;
00212 size_t buf_len;
00213 u32 lifetime;
00214
00215
00216
00217
00218
00219
00220
00221 buf_len = kde->rsn_ie_len +
00222 2 + RSN_SELECTOR_LEN + ETH_ALEN +
00223 2 + RSN_SELECTOR_LEN + WPA_NONCE_LEN +
00224 2 + RSN_SELECTOR_LEN + PMK_LEN + WPA_NONCE_LEN +
00225 2 + RSN_SELECTOR_LEN + sizeof(lifetime);
00226 pos = buf = os_malloc(buf_len);
00227 if (buf == NULL)
00228 return;
00229
00230
00231 os_memcpy(buf, kde->rsn_ie, kde->rsn_ie_len);
00232 pos = buf + kde->rsn_ie_len;
00233
00234
00235 pos = wpa_add_kde(pos, RSN_KEY_DATA_MAC_ADDR, peer, ETH_ALEN, NULL, 0);
00236
00237
00238 pos = wpa_add_kde(pos, RSN_KEY_DATA_NONCE, key->key_nonce,
00239 WPA_NONCE_LEN, NULL, 0);
00240
00241
00242 pos = wpa_add_kde(pos, RSN_KEY_DATA_SMK, smk, PMK_LEN,
00243 kde->nonce, WPA_NONCE_LEN);
00244
00245
00246 lifetime = htonl(43200);
00247 pos = wpa_add_kde(pos, RSN_KEY_DATA_LIFETIME,
00248 (u8 *) &lifetime, sizeof(lifetime), NULL, 0);
00249
00250 wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
00251 "Sending SMK M5");
00252
00253 __wpa_send_eapol(wpa_auth, sm,
00254 WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC |
00255 WPA_KEY_INFO_SMK_MESSAGE,
00256 NULL, kde->nonce, buf, pos - buf, 0, 1, 0);
00257
00258 os_free(buf);
00259 }
00260
00261
00262 void wpa_smk_m3(struct wpa_authenticator *wpa_auth,
00263 struct wpa_state_machine *sm, struct wpa_eapol_key *key)
00264 {
00265 struct wpa_eapol_ie_parse kde;
00266 struct wpa_stsl_search search;
00267 u8 smk[32], buf[ETH_ALEN + 8 + 2 * WPA_NONCE_LEN], *pos;
00268
00269 if (wpa_parse_kde_ies((const u8 *) (key + 1),
00270 WPA_GET_BE16(key->key_data_length), &kde) < 0) {
00271 wpa_printf(MSG_INFO, "RSN: Failed to parse KDEs in SMK M3");
00272 return;
00273 }
00274
00275 if (kde.rsn_ie == NULL ||
00276 kde.mac_addr == NULL || kde.mac_addr_len < ETH_ALEN ||
00277 kde.nonce == NULL || kde.nonce_len < WPA_NONCE_LEN) {
00278 wpa_printf(MSG_INFO, "RSN: No RSN IE, MAC address KDE, or "
00279 "Nonce KDE in SMK M3");
00280 return;
00281 }
00282
00283
00284
00285
00286 search.addr = kde.mac_addr;
00287 search.sm = NULL;
00288 if (wpa_auth_for_each_sta(wpa_auth, wpa_stsl_select_sta, &search) ==
00289 0 || search.sm == NULL) {
00290 wpa_printf(MSG_DEBUG, "RSN: SMK handshake with " MACSTR
00291 " aborted - STA not associated anymore",
00292 MAC2STR(kde.mac_addr));
00293 wpa_smk_send_error(wpa_auth, sm, kde.mac_addr, STK_MUI_SMK,
00294 STK_ERR_STA_NR);
00295
00296 return;
00297 }
00298
00299 if (os_get_random(smk, PMK_LEN)) {
00300 wpa_printf(MSG_DEBUG, "RSN: Failed to generate SMK");
00301 return;
00302 }
00303
00304
00305
00306
00307 os_memcpy(buf, wpa_auth->addr, ETH_ALEN);
00308 pos = buf + ETH_ALEN;
00309 wpa_get_ntp_timestamp(pos);
00310 pos += 8;
00311 os_memcpy(pos, kde.nonce, WPA_NONCE_LEN);
00312 pos += WPA_NONCE_LEN;
00313 os_memcpy(pos, key->key_nonce, WPA_NONCE_LEN);
00314 #ifdef CONFIG_IEEE80211W
00315 sha256_prf(smk, PMK_LEN, "SMK Derivation", buf, sizeof(buf),
00316 smk, PMK_LEN);
00317 #else
00318 sha1_prf(smk, PMK_LEN, "SMK Derivation", buf, sizeof(buf),
00319 smk, PMK_LEN);
00320 #endif
00321
00322 wpa_hexdump_key(MSG_DEBUG, "RSN: SMK", smk, PMK_LEN);
00323
00324 wpa_send_smk_m4(wpa_auth, sm, key, &kde, smk);
00325 wpa_send_smk_m5(wpa_auth, search.sm, key, &kde, smk, sm->addr);
00326
00327
00328
00329 os_memset(smk, 0, sizeof(*smk));
00330 }
00331
00332
00333 void wpa_smk_error(struct wpa_authenticator *wpa_auth,
00334 struct wpa_state_machine *sm, struct wpa_eapol_key *key)
00335 {
00336 struct wpa_eapol_ie_parse kde;
00337 struct wpa_stsl_search search;
00338 struct rsn_error_kde error;
00339 u16 mui, error_type;
00340
00341 if (wpa_parse_kde_ies((const u8 *) (key + 1),
00342 WPA_GET_BE16(key->key_data_length), &kde) < 0) {
00343 wpa_printf(MSG_INFO, "RSN: Failed to parse KDEs in SMK Error");
00344 return;
00345 }
00346
00347 if (kde.mac_addr == NULL || kde.mac_addr_len < ETH_ALEN ||
00348 kde.error == NULL || kde.error_len < sizeof(error)) {
00349 wpa_printf(MSG_INFO, "RSN: No MAC address or Error KDE in "
00350 "SMK Error");
00351 return;
00352 }
00353
00354 search.addr = kde.mac_addr;
00355 search.sm = NULL;
00356 if (wpa_auth_for_each_sta(wpa_auth, wpa_stsl_select_sta, &search) ==
00357 0 || search.sm == NULL) {
00358 wpa_printf(MSG_DEBUG, "RSN: Peer STA " MACSTR " not "
00359 "associated for SMK Error message from " MACSTR,
00360 MAC2STR(kde.mac_addr), MAC2STR(sm->addr));
00361 return;
00362 }
00363
00364 os_memcpy(&error, kde.error, sizeof(error));
00365 mui = be_to_host16(error.mui);
00366 error_type = be_to_host16(error.error_type);
00367 wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO,
00368 "STA reported SMK Error: Peer " MACSTR
00369 " MUI %d Error Type %d",
00370 MAC2STR(kde.mac_addr), mui, error_type);
00371
00372 wpa_smk_send_error(wpa_auth, search.sm, sm->addr, mui, error_type);
00373 }
00374
00375
00376 int wpa_stsl_remove(struct wpa_authenticator *wpa_auth,
00377 struct wpa_stsl_negotiation *neg)
00378 {
00379 struct wpa_stsl_negotiation *pos, *prev;
00380
00381 if (wpa_auth == NULL)
00382 return -1;
00383 pos = wpa_auth->stsl_negotiations;
00384 prev = NULL;
00385 while (pos) {
00386 if (pos == neg) {
00387 if (prev)
00388 prev->next = pos->next;
00389 else
00390 wpa_auth->stsl_negotiations = pos->next;
00391
00392 eloop_cancel_timeout(wpa_stsl_step, wpa_auth, pos);
00393 os_free(pos);
00394 return 0;
00395 }
00396 prev = pos;
00397 pos = pos->next;
00398 }
00399
00400 return -1;
00401 }
00402
00403 #endif
00404