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