00001
00016 #include "includes.h"
00017
00018 #include "common.h"
00019 #include "eap_i.h"
00020 #include "eap_tls_common.h"
00021 #include "config_ssid.h"
00022 #include "tls.h"
00023 #include "eap_tlv.h"
00024 #include "sha1.h"
00025 #include "config.h"
00026
00027
00028
00029
00030
00031
00032
00033 #define EAP_FAST_VERSION 1
00034 #define EAP_FAST_KEY_LEN 64
00035 #define EAP_FAST_PAC_KEY_LEN 32
00036 #define EAP_FAST_SIMCK_LEN 40
00037 #define EAP_FAST_SKS_LEN 40
00038
00039 #define TLS_EXT_PAC_OPAQUE 35
00040
00041 static const char *pac_file_hdr =
00042 "wpa_supplicant EAP-FAST PAC file - version 1";
00043
00044
00045 static void eap_fast_deinit(struct eap_sm *sm, void *priv);
00046
00047
00048 #define PAC_TYPE_PAC_KEY 1
00049 #define PAC_TYPE_PAC_OPAQUE 2
00050 #define PAC_TYPE_CRED_LIFETIME 3
00051 #define PAC_TYPE_A_ID 4
00052 #define PAC_TYPE_I_ID 5
00053 #define PAC_TYPE_SERVER_PROTECTED_DATA 6
00054 #define PAC_TYPE_A_ID_INFO 7
00055 #define PAC_TYPE_PAC_ACKNOWLEDGEMENT 8
00056 #define PAC_TYPE_PAC_INFO 9
00057
00058 struct pac_tlv_hdr {
00059 u16 type;
00060 u16 len;
00061 };
00062
00063
00064
00065
00066 struct eap_fast_key_block_provisioning {
00067
00068 u8 session_key_seed[EAP_FAST_SKS_LEN];
00069 u8 server_challenge[16];
00070 u8 client_challenge[16];
00071 };
00072
00073
00074 struct eap_fast_pac {
00075 struct eap_fast_pac *next;
00076
00077 u8 pac_key[EAP_FAST_PAC_KEY_LEN];
00078 u8 *pac_opaque;
00079 size_t pac_opaque_len;
00080 u8 *pac_info;
00081 size_t pac_info_len;
00082 u8 *a_id;
00083 size_t a_id_len;
00084 u8 *i_id;
00085 size_t i_id_len;
00086 u8 *a_id_info;
00087 size_t a_id_info_len;
00088 };
00089
00090
00091 struct eap_fast_data {
00092 struct eap_ssl_data ssl;
00093
00094 int fast_version;
00095
00096 const struct eap_method *phase2_method;
00097 void *phase2_priv;
00098 int phase2_success;
00099
00100 struct eap_method_type phase2_type;
00101 struct eap_method_type *phase2_types;
00102 size_t num_phase2_types;
00103 int resuming;
00104 struct eap_fast_key_block_provisioning *key_block_p;
00105 int provisioning_allowed;
00106 int provisioning;
00107
00108 u8 key_data[EAP_FAST_KEY_LEN];
00109 u8 emsk[EAP_EMSK_LEN];
00110 int success;
00111
00112 struct eap_fast_pac *pac;
00113 struct eap_fast_pac *current_pac;
00114
00115 int tls_master_secret_set;
00116
00117 u8 simck[EAP_FAST_SIMCK_LEN];
00118 int simck_idx;
00119 };
00120
00121
00122 static void eap_fast_free_pac(struct eap_fast_pac *pac)
00123 {
00124 os_free(pac->pac_opaque);
00125 os_free(pac->pac_info);
00126 os_free(pac->a_id);
00127 os_free(pac->i_id);
00128 os_free(pac->a_id_info);
00129 os_free(pac);
00130 }
00131
00132
00133 static struct eap_fast_pac * eap_fast_get_pac(struct eap_fast_data *data,
00134 const u8 *a_id, size_t a_id_len)
00135 {
00136 struct eap_fast_pac *pac = data->pac;
00137
00138 while (pac) {
00139 if (pac->a_id_len == a_id_len &&
00140 os_memcmp(pac->a_id, a_id, a_id_len) == 0) {
00141 return pac;
00142 }
00143 pac = pac->next;
00144 }
00145 return NULL;
00146 }
00147
00148
00149 static int eap_fast_add_pac(struct eap_fast_data *data,
00150 struct eap_fast_pac *entry)
00151 {
00152 struct eap_fast_pac *pac, *prev;
00153
00154 if (entry == NULL || entry->a_id == NULL)
00155 return -1;
00156
00157
00158 pac = data->pac;
00159 prev = NULL;
00160 while (pac) {
00161 if (pac->a_id_len == entry->a_id_len &&
00162 os_memcmp(pac->a_id, entry->a_id, pac->a_id_len) == 0) {
00163 if (prev == NULL) {
00164 data->pac = pac->next;
00165 } else {
00166 prev->next = pac->next;
00167 }
00168 if (data->current_pac == pac)
00169 data->current_pac = NULL;
00170 eap_fast_free_pac(pac);
00171 break;
00172 }
00173 prev = pac;
00174 pac = pac->next;
00175 }
00176
00177
00178 pac = os_zalloc(sizeof(*pac));
00179 if (pac == NULL)
00180 return -1;
00181
00182 os_memcpy(pac->pac_key, entry->pac_key, EAP_FAST_PAC_KEY_LEN);
00183 if (entry->pac_opaque) {
00184 pac->pac_opaque = os_malloc(entry->pac_opaque_len);
00185 if (pac->pac_opaque == NULL) {
00186 eap_fast_free_pac(pac);
00187 return -1;
00188 }
00189 os_memcpy(pac->pac_opaque, entry->pac_opaque,
00190 entry->pac_opaque_len);
00191 pac->pac_opaque_len = entry->pac_opaque_len;
00192 }
00193 if (entry->pac_info) {
00194 pac->pac_info = os_malloc(entry->pac_info_len);
00195 if (pac->pac_info == NULL) {
00196 eap_fast_free_pac(pac);
00197 return -1;
00198 }
00199 os_memcpy(pac->pac_info, entry->pac_info,
00200 entry->pac_info_len);
00201 pac->pac_info_len = entry->pac_info_len;
00202 }
00203 if (entry->a_id) {
00204 pac->a_id = os_malloc(entry->a_id_len);
00205 if (pac->a_id == NULL) {
00206 eap_fast_free_pac(pac);
00207 return -1;
00208 }
00209 os_memcpy(pac->a_id, entry->a_id,
00210 entry->a_id_len);
00211 pac->a_id_len = entry->a_id_len;
00212 }
00213 if (entry->i_id) {
00214 pac->i_id = os_malloc(entry->i_id_len);
00215 if (pac->i_id == NULL) {
00216 eap_fast_free_pac(pac);
00217 return -1;
00218 }
00219 os_memcpy(pac->i_id, entry->i_id,
00220 entry->i_id_len);
00221 pac->i_id_len = entry->i_id_len;
00222 }
00223 if (entry->a_id_info) {
00224 pac->a_id_info = os_malloc(entry->a_id_info_len);
00225 if (pac->a_id_info == NULL) {
00226 eap_fast_free_pac(pac);
00227 return -1;
00228 }
00229 os_memcpy(pac->a_id_info, entry->a_id_info,
00230 entry->a_id_info_len);
00231 pac->a_id_info_len = entry->a_id_info_len;
00232 }
00233 pac->next = data->pac;
00234 data->pac = pac;
00235 return 0;
00236 }
00237
00238
00239 struct eap_fast_read_ctx {
00240 FILE *f;
00241 const char *pos;
00242 const char *end;
00243 };
00244
00245 static int eap_fast_read_line(struct eap_fast_read_ctx *rc, char *buf,
00246 size_t buf_len)
00247 {
00248 char *pos;
00249
00250 if (rc->f) {
00251 if (fgets(buf, buf_len, rc->f) == NULL)
00252 return -1;
00253 } else {
00254 const char *l_end;
00255 size_t len;
00256 if (rc->pos >= rc->end)
00257 return -1;
00258 l_end = rc->pos;
00259 while (l_end < rc->end && *l_end != '\n')
00260 l_end++;
00261 len = l_end - rc->pos;
00262 if (len >= buf_len)
00263 len = buf_len - 1;
00264 os_memcpy(buf, rc->pos, len);
00265 buf[len] = '\0';
00266 rc->pos = l_end + 1;
00267 }
00268
00269 buf[buf_len - 1] = '\0';
00270 pos = buf;
00271 while (*pos != '\0') {
00272 if (*pos == '\n' || *pos == '\r') {
00273 *pos = '\0';
00274 break;
00275 }
00276 pos++;
00277 }
00278
00279 return 0;
00280 }
00281
00282
00283 static u8 * eap_fast_parse_hex(const char *value, size_t *len)
00284 {
00285 int hlen;
00286 u8 *buf;
00287
00288 if (value == NULL)
00289 return NULL;
00290 hlen = os_strlen(value);
00291 if (hlen & 1)
00292 return NULL;
00293 *len = hlen / 2;
00294 buf = os_malloc(*len);
00295 if (buf == NULL)
00296 return NULL;
00297 if (hexstr2bin(value, buf, *len)) {
00298 os_free(buf);
00299 return NULL;
00300 }
00301 return buf;
00302 }
00303
00304
00305 static int eap_fast_load_pac(struct eap_sm *sm, struct eap_fast_data *data,
00306 const char *pac_file)
00307 {
00308 struct eap_fast_read_ctx rc;
00309 struct eap_fast_pac *pac = NULL;
00310 int count = 0;
00311 char *buf, *pos;
00312 const int buf_len = 2048;
00313 int ret = 0, line = 0;
00314
00315 if (pac_file == NULL)
00316 return -1;
00317
00318 os_memset(&rc, 0, sizeof(rc));
00319
00320 if (os_strncmp(pac_file, "blob://", 7) == 0) {
00321 const struct wpa_config_blob *blob;
00322 blob = eap_get_config_blob(sm, pac_file + 7);
00323 if (blob == NULL) {
00324 wpa_printf(MSG_INFO, "EAP-FAST: No PAC blob '%s' - "
00325 "assume no PAC entries have been "
00326 "provisioned", pac_file + 7);
00327 return 0;
00328 }
00329 rc.pos = (char *) blob->data;
00330 rc.end = (char *) blob->data + blob->len;
00331 } else {
00332 rc.f = fopen(pac_file, "r");
00333 if (rc.f == NULL) {
00334 wpa_printf(MSG_INFO, "EAP-FAST: No PAC file '%s' - "
00335 "assume no PAC entries have been "
00336 "provisioned", pac_file);
00337 return 0;
00338 }
00339 }
00340
00341 buf = os_malloc(buf_len);
00342 if (buf == NULL) {
00343 return -1;
00344 }
00345
00346 line++;
00347 if (eap_fast_read_line(&rc, buf, buf_len) < 0 ||
00348 os_strcmp(pac_file_hdr, buf) != 0) {
00349 wpa_printf(MSG_INFO, "EAP-FAST: Unrecognized header line in "
00350 "PAC file '%s'", pac_file);
00351 os_free(buf);
00352 if (rc.f)
00353 fclose(rc.f);
00354 return -1;
00355 }
00356
00357 while (eap_fast_read_line(&rc, buf, buf_len) == 0) {
00358 line++;
00359 pos = os_strchr(buf, '=');
00360 if (pos) {
00361 *pos++ = '\0';
00362 }
00363
00364 if (os_strcmp(buf, "START") == 0) {
00365 if (pac) {
00366 wpa_printf(MSG_INFO, "EAP-FAST: START line "
00367 "without END in '%s:%d'",
00368 pac_file, line);
00369 ret = -1;
00370 break;
00371 }
00372 pac = os_zalloc(sizeof(*pac));
00373 if (pac == NULL) {
00374 wpa_printf(MSG_INFO, "EAP-FAST: No memory for "
00375 "PAC entry");
00376 ret = -1;
00377 break;
00378 }
00379 } else if (os_strcmp(buf, "END") == 0) {
00380 if (pac == NULL) {
00381 wpa_printf(MSG_INFO, "EAP-FAST: END line "
00382 "without START in '%s:%d'",
00383 pac_file, line);
00384 ret = -1;
00385 break;
00386 }
00387 pac->next = data->pac;
00388 data->pac = pac;
00389 pac = NULL;
00390 count++;
00391 } else if (pac && os_strcmp(buf, "PAC-Key") == 0) {
00392 u8 *key;
00393 size_t key_len;
00394 key = eap_fast_parse_hex(pos, &key_len);
00395 if (key == NULL || key_len != EAP_FAST_PAC_KEY_LEN) {
00396 wpa_printf(MSG_INFO, "EAP-FAST: Invalid "
00397 "PAC-Key '%s:%d'", pac_file, line);
00398 ret = -1;
00399 os_free(key);
00400 break;
00401 }
00402
00403 os_memcpy(pac->pac_key, key, EAP_FAST_PAC_KEY_LEN);
00404 os_free(key);
00405 } else if (pac && os_strcmp(buf, "PAC-Opaque") == 0) {
00406 os_free(pac->pac_opaque);
00407 pac->pac_opaque =
00408 eap_fast_parse_hex(pos, &pac->pac_opaque_len);
00409 if (pac->pac_opaque == NULL) {
00410 wpa_printf(MSG_INFO, "EAP-FAST: Invalid "
00411 "PAC-Opaque '%s:%d'",
00412 pac_file, line);
00413 ret = -1;
00414 break;
00415 }
00416 } else if (pac && os_strcmp(buf, "A-ID") == 0) {
00417 os_free(pac->a_id);
00418 pac->a_id = eap_fast_parse_hex(pos, &pac->a_id_len);
00419 if (pac->a_id == NULL) {
00420 wpa_printf(MSG_INFO, "EAP-FAST: Invalid "
00421 "A-ID '%s:%d'", pac_file, line);
00422 ret = -1;
00423 break;
00424 }
00425 } else if (pac && os_strcmp(buf, "I-ID") == 0) {
00426 os_free(pac->i_id);
00427 pac->i_id = eap_fast_parse_hex(pos, &pac->i_id_len);
00428 if (pac->i_id == NULL) {
00429 wpa_printf(MSG_INFO, "EAP-FAST: Invalid "
00430 "I-ID '%s:%d'", pac_file, line);
00431 ret = -1;
00432 break;
00433 }
00434 } else if (pac && os_strcmp(buf, "A-ID-Info") == 0) {
00435 os_free(pac->a_id_info);
00436 pac->a_id_info =
00437 eap_fast_parse_hex(pos, &pac->a_id_info_len);
00438 if (pac->a_id_info == NULL) {
00439 wpa_printf(MSG_INFO, "EAP-FAST: Invalid "
00440 "A-ID-Info '%s:%d'",
00441 pac_file, line);
00442 ret = -1;
00443 break;
00444 }
00445 }
00446 }
00447
00448 if (pac) {
00449 wpa_printf(MSG_INFO, "EAP-FAST: PAC block not terminated with "
00450 "END in '%s'", pac_file);
00451 eap_fast_free_pac(pac);
00452 ret = -1;
00453 }
00454
00455 os_free(buf);
00456 if (rc.f)
00457 fclose(rc.f);
00458
00459 if (ret == 0) {
00460 wpa_printf(MSG_DEBUG, "EAP-FAST: read %d PAC entries from "
00461 "'%s'", count, pac_file);
00462 }
00463
00464 return ret;
00465 }
00466
00467
00468 static void eap_fast_write(char **buf, char **pos, size_t *buf_len,
00469 const char *field, const u8 *data,
00470 size_t len, int txt)
00471 {
00472 size_t i, need;
00473 int ret;
00474
00475 if (data == NULL || *buf == NULL)
00476 return;
00477
00478 need = os_strlen(field) + len * 2 + 30;
00479 if (txt)
00480 need += os_strlen(field) + len + 20;
00481
00482 if (*pos - *buf + need > *buf_len) {
00483 char *nbuf = os_realloc(*buf, *buf_len + need);
00484 if (nbuf == NULL) {
00485 os_free(*buf);
00486 *buf = NULL;
00487 return;
00488 }
00489 *buf = nbuf;
00490 *buf_len += need;
00491 }
00492
00493 ret = os_snprintf(*pos, *buf + *buf_len - *pos, "%s=", field);
00494 if (ret < 0 || ret >= *buf + *buf_len - *pos)
00495 return;
00496 *pos += ret;
00497 *pos += wpa_snprintf_hex(*pos, *buf + *buf_len - *pos, data, len);
00498 ret = os_snprintf(*pos, *buf + *buf_len - *pos, "\n");
00499 if (ret < 0 || ret >= *buf + *buf_len - *pos)
00500 return;
00501 *pos += ret;
00502
00503 if (txt) {
00504 ret = os_snprintf(*pos, *buf + *buf_len - *pos,
00505 "%s-txt=", field);
00506 if (ret < 0 || ret >= *buf + *buf_len - *pos)
00507 return;
00508 *pos += ret;
00509 for (i = 0; i < len; i++) {
00510 ret = os_snprintf(*pos, *buf + *buf_len - *pos,
00511 "%c", data[i]);
00512 if (ret < 0 || ret >= *buf + *buf_len - *pos)
00513 return;
00514 *pos += ret;
00515 }
00516 ret = os_snprintf(*pos, *buf + *buf_len - *pos, "\n");
00517 if (ret < 0 || ret >= *buf + *buf_len - *pos)
00518 return;
00519 *pos += ret;
00520 }
00521 }
00522
00523
00524 static int eap_fast_save_pac(struct eap_sm *sm, struct eap_fast_data *data,
00525 const char *pac_file)
00526 {
00527 FILE *f;
00528 struct eap_fast_pac *pac;
00529 int count = 0, ret;
00530 char *buf, *pos;
00531 size_t buf_len;
00532
00533 if (pac_file == NULL)
00534 return -1;
00535
00536 buf_len = 1024;
00537 pos = buf = os_malloc(buf_len);
00538 if (buf == NULL)
00539 return -1;
00540
00541 ret = os_snprintf(pos, buf + buf_len - pos, "%s\n", pac_file_hdr);
00542 if (ret < 0 || ret >= buf + buf_len - pos) {
00543 os_free(buf);
00544 return -1;
00545 }
00546 pos += ret;
00547
00548 pac = data->pac;
00549 while (pac) {
00550 ret = os_snprintf(pos, buf + buf_len - pos, "START\n");
00551 if (ret < 0 || ret >= buf + buf_len - pos) {
00552 os_free(buf);
00553 return -1;
00554 }
00555 pos += ret;
00556 eap_fast_write(&buf, &pos, &buf_len, "PAC-Key", pac->pac_key,
00557 EAP_FAST_PAC_KEY_LEN, 0);
00558 eap_fast_write(&buf, &pos, &buf_len, "PAC-Opaque",
00559 pac->pac_opaque, pac->pac_opaque_len, 0);
00560 eap_fast_write(&buf, &pos, &buf_len, "PAC-Info", pac->pac_info,
00561 pac->pac_info_len, 0);
00562 eap_fast_write(&buf, &pos, &buf_len, "A-ID", pac->a_id,
00563 pac->a_id_len, 0);
00564 eap_fast_write(&buf, &pos, &buf_len, "I-ID", pac->i_id,
00565 pac->i_id_len, 1);
00566 eap_fast_write(&buf, &pos, &buf_len, "A-ID-Info",
00567 pac->a_id_info, pac->a_id_info_len, 1);
00568 if (buf == NULL) {
00569 wpa_printf(MSG_DEBUG, "EAP-FAST: No memory for PAC "
00570 "data");
00571 return -1;
00572 }
00573 ret = os_snprintf(pos, buf + buf_len - pos, "END\n");
00574 if (ret < 0 || ret >= buf + buf_len - pos) {
00575 os_free(buf);
00576 return -1;
00577 }
00578 pos += ret;
00579 count++;
00580 pac = pac->next;
00581 }
00582
00583 if (os_strncmp(pac_file, "blob://", 7) == 0) {
00584 struct wpa_config_blob *blob;
00585 blob = os_zalloc(sizeof(*blob));
00586 if (blob == NULL) {
00587 os_free(buf);
00588 return -1;
00589 }
00590 blob->data = (u8 *) buf;
00591 blob->len = pos - buf;
00592 buf = NULL;
00593 blob->name = os_strdup(pac_file + 7);
00594 if (blob->name == NULL) {
00595 os_free(blob->data);
00596 os_free(blob);
00597 return -1;
00598 }
00599 eap_set_config_blob(sm, blob);
00600 } else {
00601 f = fopen(pac_file, "w");
00602 if (f == NULL) {
00603 wpa_printf(MSG_INFO, "EAP-FAST: Failed to open PAC "
00604 "file '%s' for writing", pac_file);
00605 os_free(buf);
00606 return -1;
00607 }
00608 fprintf(f, "%s", buf);
00609 os_free(buf);
00610 fclose(f);
00611 }
00612
00613 wpa_printf(MSG_DEBUG, "EAP-FAST: wrote %d PAC entries into '%s'",
00614 count, pac_file);
00615
00616 return 0;
00617 }
00618
00619
00620 static void * eap_fast_init(struct eap_sm *sm)
00621 {
00622 struct eap_fast_data *data;
00623 struct wpa_ssid *config = eap_get_config(sm);
00624
00625 data = os_zalloc(sizeof(*data));
00626 if (data == NULL)
00627 return NULL;
00628 data->fast_version = EAP_FAST_VERSION;
00629
00630 if (config && config->phase1) {
00631 if (os_strstr(config->phase1, "fast_provisioning=1")) {
00632 data->provisioning_allowed = 1;
00633 wpa_printf(MSG_DEBUG, "EAP-FAST: Automatic PAC "
00634 "provisioning is allowed");
00635 }
00636 }
00637
00638 if (config && config->phase2) {
00639 char *start, *pos, *buf;
00640 struct eap_method_type *methods = NULL, *_methods;
00641 u8 method;
00642 size_t num_methods = 0;
00643 start = buf = os_strdup(config->phase2);
00644 if (buf == NULL) {
00645 eap_fast_deinit(sm, data);
00646 return NULL;
00647 }
00648 while (start && *start != '\0') {
00649 int vendor;
00650 pos = os_strstr(start, "auth=");
00651 if (pos == NULL)
00652 break;
00653 if (start != pos && *(pos - 1) != ' ') {
00654 start = pos + 5;
00655 continue;
00656 }
00657
00658 start = pos + 5;
00659 pos = os_strchr(start, ' ');
00660 if (pos)
00661 *pos++ = '\0';
00662 method = eap_get_phase2_type(start, &vendor);
00663 if (vendor == EAP_VENDOR_IETF &&
00664 method == EAP_TYPE_NONE) {
00665 wpa_printf(MSG_ERROR, "EAP-FAST: Unsupported "
00666 "Phase2 method '%s'", start);
00667 } else {
00668 num_methods++;
00669 _methods = os_realloc(
00670 methods,
00671 num_methods * sizeof(*methods));
00672 if (_methods == NULL) {
00673 os_free(methods);
00674 os_free(buf);
00675 eap_fast_deinit(sm, data);
00676 return NULL;
00677 }
00678 methods = _methods;
00679 methods[num_methods - 1].vendor = vendor;
00680 methods[num_methods - 1].method = method;
00681 }
00682
00683 start = pos;
00684 }
00685 os_free(buf);
00686 data->phase2_types = methods;
00687 data->num_phase2_types = num_methods;
00688 }
00689 if (data->phase2_types == NULL) {
00690 data->phase2_types =
00691 eap_get_phase2_types(config, &data->num_phase2_types);
00692 }
00693 if (data->phase2_types == NULL) {
00694 wpa_printf(MSG_ERROR, "EAP-FAST: No Phase2 method available");
00695 eap_fast_deinit(sm, data);
00696 return NULL;
00697 }
00698 wpa_hexdump(MSG_DEBUG, "EAP-FAST: Phase2 EAP types",
00699 (u8 *) data->phase2_types,
00700 data->num_phase2_types * sizeof(struct eap_method_type));
00701 data->phase2_type.vendor = EAP_VENDOR_IETF;
00702 data->phase2_type.method = EAP_TYPE_NONE;
00703
00704 if (eap_tls_ssl_init(sm, &data->ssl, config)) {
00705 wpa_printf(MSG_INFO, "EAP-FAST: Failed to initialize SSL.");
00706 eap_fast_deinit(sm, data);
00707 return NULL;
00708 }
00709
00710
00711
00712
00713 tls_connection_enable_workaround(sm->ssl_ctx, data->ssl.conn);
00714
00715 if (eap_fast_load_pac(sm, data, config->pac_file) < 0) {
00716 eap_fast_deinit(sm, data);
00717 return NULL;
00718 }
00719
00720 if (data->pac == NULL && !data->provisioning_allowed) {
00721 wpa_printf(MSG_INFO, "EAP-FAST: No PAC configured and "
00722 "provisioning disabled");
00723 eap_fast_deinit(sm, data);
00724 return NULL;
00725 }
00726
00727 return data;
00728 }
00729
00730
00731 static void eap_fast_deinit(struct eap_sm *sm, void *priv)
00732 {
00733 struct eap_fast_data *data = priv;
00734 struct eap_fast_pac *pac, *prev;
00735
00736 if (data == NULL)
00737 return;
00738 if (data->phase2_priv && data->phase2_method)
00739 data->phase2_method->deinit(sm, data->phase2_priv);
00740 os_free(data->phase2_types);
00741 os_free(data->key_block_p);
00742 eap_tls_ssl_deinit(sm, &data->ssl);
00743
00744 pac = data->pac;
00745 prev = NULL;
00746 while (pac) {
00747 prev = pac;
00748 pac = pac->next;
00749 eap_fast_free_pac(prev);
00750 }
00751 os_free(data);
00752 }
00753
00754
00755 static int eap_fast_encrypt(struct eap_sm *sm, struct eap_fast_data *data,
00756 int id, const u8 *plain, size_t plain_len,
00757 u8 **out_data, size_t *out_len)
00758 {
00759 int res;
00760 u8 *pos;
00761 struct eap_hdr *resp;
00762
00763
00764
00765 resp = os_malloc(sizeof(struct eap_hdr) + 2 + data->ssl.tls_out_limit);
00766 if (resp == NULL)
00767 return 0;
00768
00769 resp->code = EAP_CODE_RESPONSE;
00770 resp->identifier = id;
00771
00772 pos = (u8 *) (resp + 1);
00773 *pos++ = EAP_TYPE_FAST;
00774 *pos++ = data->fast_version;
00775
00776 res = tls_connection_encrypt(sm->ssl_ctx, data->ssl.conn,
00777 plain, plain_len,
00778 pos, data->ssl.tls_out_limit);
00779 if (res < 0) {
00780 wpa_printf(MSG_INFO, "EAP-FAST: Failed to encrypt Phase 2 "
00781 "data");
00782 os_free(resp);
00783 return 0;
00784 }
00785
00786 *out_len = sizeof(struct eap_hdr) + 2 + res;
00787 resp->length = host_to_be16(*out_len);
00788 *out_data = (u8 *) resp;
00789 return 0;
00790 }
00791
00792
00793 static int eap_fast_phase2_nak(struct eap_fast_data *data,
00794 struct eap_hdr *hdr,
00795 u8 **resp, size_t *resp_len)
00796 {
00797 struct eap_hdr *resp_hdr;
00798 u8 *pos = (u8 *) (hdr + 1);
00799 size_t i;
00800
00801
00802 wpa_printf(MSG_DEBUG, "EAP-FAST: Phase 2 Request: Nak type=%d", *pos);
00803 wpa_hexdump(MSG_DEBUG, "EAP-FAST: Allowed Phase2 EAP types",
00804 (u8 *) data->phase2_types,
00805 data->num_phase2_types * sizeof(struct eap_method_type));
00806 *resp_len = sizeof(struct eap_hdr) + 1;
00807 *resp = os_malloc(*resp_len + data->num_phase2_types);
00808 if (*resp == NULL)
00809 return -1;
00810
00811 resp_hdr = (struct eap_hdr *) (*resp);
00812 resp_hdr->code = EAP_CODE_RESPONSE;
00813 resp_hdr->identifier = hdr->identifier;
00814 pos = (u8 *) (resp_hdr + 1);
00815 *pos++ = EAP_TYPE_NAK;
00816 for (i = 0; i < data->num_phase2_types; i++) {
00817 if (data->phase2_types[i].vendor == EAP_VENDOR_IETF &&
00818 data->phase2_types[i].method < 256) {
00819 (*resp_len)++;
00820 *pos++ = data->phase2_types[i].method;
00821 }
00822 }
00823 resp_hdr->length = host_to_be16(*resp_len);
00824
00825 return 0;
00826 }
00827
00828
00829 static int eap_fast_derive_msk(struct eap_fast_data *data)
00830 {
00831
00832 sha1_t_prf(data->simck, EAP_FAST_SIMCK_LEN,
00833 "Session Key Generating Function", (u8 *) "", 0,
00834 data->key_data, EAP_FAST_KEY_LEN);
00835 wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: Derived key (MSK)",
00836 data->key_data, EAP_FAST_KEY_LEN);
00837
00838 sha1_t_prf(data->simck, EAP_FAST_SIMCK_LEN,
00839 "Extended Session Key Generating Function",
00840 (u8 *) "", 0, data->emsk, EAP_EMSK_LEN);
00841 wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: Derived key (EMSK)",
00842 data->emsk, EAP_EMSK_LEN);
00843
00844 data->success = 1;
00845
00846 return 0;
00847 }
00848
00849
00850 static int eap_fast_set_tls_master_secret(struct eap_sm *sm,
00851 struct eap_fast_data *data,
00852 const u8 *tls, size_t tls_len)
00853 {
00854 struct tls_keys keys;
00855 u8 master_secret[48], *seed;
00856 const u8 *server_random;
00857 size_t seed_len, server_random_len;
00858
00859 if (data->tls_master_secret_set || !data->current_pac ||
00860 tls_connection_get_keys(sm->ssl_ctx, data->ssl.conn, &keys) ||
00861 keys.client_random == NULL) {
00862 return 0;
00863 }
00864
00865 wpa_hexdump(MSG_DEBUG, "EAP-FAST: client_random",
00866 keys.client_random, keys.client_random_len);
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883 if (tls_len < 43 || tls[0] != 0x16 ||
00884 tls[1] != 0x03 || tls[2] != 0x01 ||
00885 tls[5] != 0x02 || tls[9] != 0x03 || tls[10] != 0x01) {
00886 wpa_hexdump(MSG_DEBUG, "EAP-FAST: unrecognized TLS "
00887 "ServerHello", tls, tls_len);
00888 return -1;
00889 }
00890 server_random = tls + 11;
00891 server_random_len = 32;
00892 wpa_hexdump(MSG_DEBUG, "EAP-FAST: server_random",
00893 server_random, server_random_len);
00894
00895 seed_len = keys.client_random_len + server_random_len;
00896 seed = os_malloc(seed_len);
00897 if (seed == NULL)
00898 return -1;
00899 os_memcpy(seed, server_random, server_random_len);
00900 os_memcpy(seed + server_random_len,
00901 keys.client_random, keys.client_random_len);
00902
00903 wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: T-PRF seed", seed, seed_len);
00904 wpa_hexdump_key(MSG_MSGDUMP, "EAP-FAST: PAC-Key",
00905 data->current_pac->pac_key, EAP_FAST_PAC_KEY_LEN);
00906
00907
00908 sha1_t_prf(data->current_pac->pac_key, EAP_FAST_PAC_KEY_LEN,
00909 "PAC to master secret label hash",
00910 seed, seed_len, master_secret, sizeof(master_secret));
00911 os_free(seed);
00912 wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: TLS pre-master-secret",
00913 master_secret, sizeof(master_secret));
00914
00915 data->tls_master_secret_set = 1;
00916
00917 return tls_connection_set_master_key(sm->ssl_ctx, data->ssl.conn,
00918 master_secret,
00919 sizeof(master_secret));
00920 }
00921
00922
00923 static u8 * eap_fast_derive_key(struct eap_sm *sm, struct eap_ssl_data *data,
00924 char *label, size_t len)
00925 {
00926 struct tls_keys keys;
00927 u8 *rnd = NULL, *out;
00928 int block_size;
00929
00930 block_size = tls_connection_get_keyblock_size(sm->ssl_ctx, data->conn);
00931 if (block_size < 0)
00932 return NULL;
00933
00934 out = os_malloc(block_size + len);
00935 if (out == NULL)
00936 return NULL;
00937
00938 if (tls_connection_prf(sm->ssl_ctx, data->conn, label, 1, out,
00939 block_size + len) == 0) {
00940 os_memmove(out, out + block_size, len);
00941 return out;
00942 }
00943
00944 if (tls_connection_get_keys(sm->ssl_ctx, data->conn, &keys))
00945 goto fail;
00946
00947 rnd = os_malloc(keys.client_random_len + keys.server_random_len);
00948 if (rnd == NULL)
00949 goto fail;
00950
00951 os_memcpy(rnd, keys.server_random, keys.server_random_len);
00952 os_memcpy(rnd + keys.server_random_len, keys.client_random,
00953 keys.client_random_len);
00954
00955 wpa_hexdump_key(MSG_MSGDUMP, "EAP-FAST: master_secret for key "
00956 "expansion", keys.master_key, keys.master_key_len);
00957 if (tls_prf(keys.master_key, keys.master_key_len,
00958 label, rnd, keys.client_random_len +
00959 keys.server_random_len, out, block_size + len))
00960 goto fail;
00961 os_free(rnd);
00962 os_memmove(out, out + block_size, len);
00963 return out;
00964
00965 fail:
00966 os_free(rnd);
00967 os_free(out);
00968 return NULL;
00969 }
00970
00971
00972 static void eap_fast_derive_key_auth(struct eap_sm *sm,
00973 struct eap_fast_data *data)
00974 {
00975 u8 *sks;
00976
00977
00978
00979
00980
00981
00982 sks = eap_fast_derive_key(sm, &data->ssl, "key expansion",
00983 EAP_FAST_SKS_LEN);
00984 if (sks == NULL) {
00985 wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to derive "
00986 "session_key_seed");
00987 return;
00988 }
00989
00990
00991
00992
00993
00994 wpa_hexdump_key(MSG_DEBUG,
00995 "EAP-FAST: session_key_seed (SKS = S-IMCK[0])",
00996 sks, EAP_FAST_SKS_LEN);
00997 data->simck_idx = 0;
00998 os_memcpy(data->simck, sks, EAP_FAST_SIMCK_LEN);
00999 os_free(sks);
01000 }
01001
01002
01003 static void eap_fast_derive_key_provisioning(struct eap_sm *sm,
01004 struct eap_fast_data *data)
01005 {
01006 os_free(data->key_block_p);
01007 data->key_block_p = (struct eap_fast_key_block_provisioning *)
01008 eap_fast_derive_key(sm, &data->ssl, "key expansion",
01009 sizeof(*data->key_block_p));
01010 if (data->key_block_p == NULL) {
01011 wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to derive key block");
01012 return;
01013 }
01014
01015
01016
01017
01018 wpa_hexdump_key(MSG_DEBUG,
01019 "EAP-FAST: session_key_seed (SKS = S-IMCK[0])",
01020 data->key_block_p->session_key_seed,
01021 sizeof(data->key_block_p->session_key_seed));
01022 data->simck_idx = 0;
01023 os_memcpy(data->simck, data->key_block_p->session_key_seed,
01024 EAP_FAST_SIMCK_LEN);
01025 wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: server_challenge",
01026 data->key_block_p->server_challenge,
01027 sizeof(data->key_block_p->server_challenge));
01028 wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: client_challenge",
01029 data->key_block_p->client_challenge,
01030 sizeof(data->key_block_p->client_challenge));
01031 }
01032
01033
01034 static void eap_fast_derive_keys(struct eap_sm *sm, struct eap_fast_data *data)
01035 {
01036 if (data->current_pac) {
01037 eap_fast_derive_key_auth(sm, data);
01038 } else {
01039 eap_fast_derive_key_provisioning(sm, data);
01040 }
01041 }
01042
01043
01044 static int eap_fast_phase2_request(struct eap_sm *sm,
01045 struct eap_fast_data *data,
01046 struct eap_method_ret *ret,
01047 struct eap_hdr *hdr,
01048 u8 **resp, size_t *resp_len)
01049 {
01050 size_t len = be_to_host16(hdr->length);
01051 u8 *pos;
01052 struct eap_method_ret iret;
01053
01054 if (len <= sizeof(struct eap_hdr)) {
01055 wpa_printf(MSG_INFO, "EAP-FAST: too short "
01056 "Phase 2 request (len=%lu)", (unsigned long) len);
01057 return -1;
01058 }
01059 pos = (u8 *) (hdr + 1);
01060 wpa_printf(MSG_DEBUG, "EAP-FAST: Phase 2 Request: type=%d", *pos);
01061 switch (*pos) {
01062 case EAP_TYPE_IDENTITY:
01063 *resp = eap_sm_buildIdentity(sm, hdr->identifier, resp_len, 1);
01064 break;
01065 default:
01066 if (data->phase2_type.vendor == EAP_VENDOR_IETF &&
01067 data->phase2_type.method == EAP_TYPE_NONE) {
01068 size_t i;
01069 for (i = 0; i < data->num_phase2_types; i++) {
01070 if (data->phase2_types[i].vendor !=
01071 EAP_VENDOR_IETF ||
01072 data->phase2_types[i].method != *pos)
01073 continue;
01074
01075 data->phase2_type.vendor =
01076 data->phase2_types[i].vendor;
01077 data->phase2_type.method =
01078 data->phase2_types[i].method;
01079 wpa_printf(MSG_DEBUG, "EAP-FAST: Selected "
01080 "Phase 2 EAP vendor %d method %d",
01081 data->phase2_type.vendor,
01082 data->phase2_type.method);
01083 break;
01084 }
01085 }
01086 if (*pos != data->phase2_type.method ||
01087 *pos == EAP_TYPE_NONE) {
01088 if (eap_fast_phase2_nak(data, hdr, resp, resp_len))
01089 return -1;
01090 return 0;
01091 }
01092
01093 if (data->phase2_priv == NULL) {
01094 data->phase2_method = eap_sm_get_eap_methods(
01095 data->phase2_type.vendor,
01096 data->phase2_type.method);
01097 if (data->phase2_method) {
01098 if (data->key_block_p) {
01099 sm->auth_challenge =
01100 data->key_block_p->
01101 server_challenge;
01102 sm->peer_challenge =
01103 data->key_block_p->
01104 client_challenge;
01105 }
01106 sm->init_phase2 = 1;
01107 sm->mschapv2_full_key = 1;
01108 data->phase2_priv =
01109 data->phase2_method->init(sm);
01110 sm->init_phase2 = 0;
01111 sm->mschapv2_full_key = 0;
01112 sm->auth_challenge = NULL;
01113 sm->peer_challenge = NULL;
01114 }
01115 }
01116 if (data->phase2_priv == NULL || data->phase2_method == NULL) {
01117 wpa_printf(MSG_INFO, "EAP-FAST: failed to initialize "
01118 "Phase 2 EAP method %d", *pos);
01119 ret->methodState = METHOD_DONE;
01120 ret->decision = DECISION_FAIL;
01121 return -1;
01122 }
01123 os_memset(&iret, 0, sizeof(iret));
01124 *resp = data->phase2_method->process(sm, data->phase2_priv,
01125 &iret, (u8 *) hdr, len,
01126 resp_len);
01127 if (*resp == NULL ||
01128 (iret.methodState == METHOD_DONE &&
01129 iret.decision == DECISION_FAIL)) {
01130 ret->methodState = METHOD_DONE;
01131 ret->decision = DECISION_FAIL;
01132 } else if ((iret.methodState == METHOD_DONE ||
01133 iret.methodState == METHOD_MAY_CONT) &&
01134 (iret.decision == DECISION_UNCOND_SUCC ||
01135 iret.decision == DECISION_COND_SUCC)) {
01136 data->phase2_success = 1;
01137 }
01138 if (*resp == NULL)
01139 return -1;
01140 break;
01141 }
01142 return 0;
01143 }
01144
01145
01146 static u8 * eap_fast_tlv_nak(int vendor_id, int tlv_type, size_t *len)
01147 {
01148 struct eap_tlv_nak_tlv *nak;
01149 *len = sizeof(*nak);
01150 nak = os_malloc(*len);
01151 if (nak == NULL)
01152 return NULL;
01153 nak->tlv_type = host_to_be16(EAP_TLV_TYPE_MANDATORY | EAP_TLV_NAK_TLV);
01154 nak->length = host_to_be16(6);
01155 nak->vendor_id = host_to_be32(vendor_id);
01156 nak->nak_type = host_to_be16(tlv_type);
01157 return (u8 *) nak;
01158 }
01159
01160
01161 static u8 * eap_fast_tlv_result(int status, int intermediate, size_t *len)
01162 {
01163 struct eap_tlv_intermediate_result_tlv *result;
01164 *len = sizeof(*result);
01165 result = os_malloc(*len);
01166 if (result == NULL)
01167 return NULL;
01168 result->tlv_type = host_to_be16(EAP_TLV_TYPE_MANDATORY |
01169 (intermediate ?
01170 EAP_TLV_INTERMEDIATE_RESULT_TLV :
01171 EAP_TLV_RESULT_TLV));
01172 result->length = host_to_be16(2);
01173 result->status = host_to_be16(status);
01174 return (u8 *) result;
01175 }
01176
01177
01178 static u8 * eap_fast_tlv_pac_ack(size_t *len)
01179 {
01180 struct eap_tlv_result_tlv *res;
01181 struct eap_tlv_pac_ack_tlv *ack;
01182
01183 *len = sizeof(*res) + sizeof(*ack);
01184 res = os_zalloc(*len);
01185 if (res == NULL)
01186 return NULL;
01187
01188 res->tlv_type = host_to_be16(EAP_TLV_RESULT_TLV |
01189 EAP_TLV_TYPE_MANDATORY);
01190 res->length = host_to_be16(sizeof(*res) - sizeof(struct eap_tlv_hdr));
01191 res->status = host_to_be16(EAP_TLV_RESULT_SUCCESS);
01192
01193 ack = (struct eap_tlv_pac_ack_tlv *) (res + 1);
01194 ack->tlv_type = host_to_be16(EAP_TLV_PAC_TLV |
01195 EAP_TLV_TYPE_MANDATORY);
01196 ack->length = host_to_be16(sizeof(*ack) - sizeof(struct eap_tlv_hdr));
01197 ack->pac_type = host_to_be16(PAC_TYPE_PAC_ACKNOWLEDGEMENT);
01198 ack->pac_len = host_to_be16(2);
01199 ack->result = host_to_be16(EAP_TLV_RESULT_SUCCESS);
01200
01201 return (u8 *) res;
01202 }
01203
01204
01205 static u8 * eap_fast_tlv_eap_payload(u8 *buf, size_t *len)
01206 {
01207 struct eap_tlv_hdr *tlv;
01208
01209
01210 tlv = os_malloc(sizeof(*tlv) + *len);
01211 if (tlv == NULL) {
01212 wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to "
01213 "allocate memory for TLV "
01214 "encapsulation");
01215 os_free(buf);
01216 return NULL;
01217 }
01218 tlv->tlv_type = host_to_be16(EAP_TLV_TYPE_MANDATORY |
01219 EAP_TLV_EAP_PAYLOAD_TLV);
01220 tlv->length = host_to_be16(*len);
01221 os_memcpy(tlv + 1, buf, *len);
01222 os_free(buf);
01223 *len += sizeof(*tlv);
01224 return (u8 *) tlv;
01225 }
01226
01227
01228 static u8 * eap_fast_process_crypto_binding(
01229 struct eap_sm *sm, struct eap_fast_data *data,
01230 struct eap_method_ret *ret,
01231 struct eap_tlv_crypto_binding__tlv *_bind, size_t bind_len,
01232 size_t *resp_len, int final)
01233 {
01234 u8 *resp;
01235 struct eap_tlv_intermediate_result_tlv *rresult;
01236 struct eap_tlv_crypto_binding__tlv *rbind;
01237 u8 isk[32], imck[60], *cmk, cmac[20], *key;
01238 size_t key_len;
01239 int res;
01240
01241 wpa_printf(MSG_DEBUG, "EAP-FAST: Crypto-Binding TLV: Version %d "
01242 "Received Version %d SubType %d",
01243 _bind->version, _bind->received_version, _bind->subtype);
01244 wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: NONCE",
01245 _bind->nonce, sizeof(_bind->nonce));
01246 wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Compound MAC",
01247 _bind->compound_mac, sizeof(_bind->compound_mac));
01248
01249 if (_bind->version != EAP_FAST_VERSION ||
01250 _bind->received_version != EAP_FAST_VERSION ||
01251 _bind->subtype != EAP_TLV_CRYPTO_BINDING_SUBTYPE_REQUEST) {
01252 wpa_printf(MSG_INFO, "EAP-FAST: Invalid version/subtype in "
01253 "Crypto-Binding TLV: Version %d "
01254 "Received Version %d SubType %d",
01255 _bind->version, _bind->received_version,
01256 _bind->subtype);
01257 resp = eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 1,
01258 resp_len);
01259 return resp;
01260 }
01261
01262 wpa_printf(MSG_DEBUG, "EAP-FAST: Determining CMK[%d] for Compound MIC "
01263 "calculation", data->simck_idx + 1);
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273 os_memset(isk, 0, sizeof(isk));
01274 if (data->phase2_method == NULL || data->phase2_priv == NULL) {
01275 wpa_printf(MSG_DEBUG, "EAP-FAST: Phase 2 method not "
01276 "available");
01277 return NULL;
01278 }
01279 if (data->phase2_method->isKeyAvailable && data->phase2_method->getKey)
01280 {
01281 if (!data->phase2_method->isKeyAvailable(sm, data->phase2_priv)
01282 ||
01283 (key = data->phase2_method->getKey(sm, data->phase2_priv,
01284 &key_len)) == NULL) {
01285 wpa_printf(MSG_DEBUG, "EAP-FAST: Could not get key "
01286 "material from Phase 2");
01287 return NULL;
01288 }
01289 if (key_len > sizeof(isk))
01290 key_len = sizeof(isk);
01291 os_memcpy(isk, key, key_len);
01292 os_free(key);
01293 }
01294 wpa_hexdump_key(MSG_MSGDUMP, "EAP-FAST: ISK[j]", isk, sizeof(isk));
01295 sha1_t_prf(data->simck, EAP_FAST_SIMCK_LEN,
01296 "Inner Methods Compound Keys",
01297 isk, sizeof(isk), imck, sizeof(imck));
01298 data->simck_idx++;
01299 os_memcpy(data->simck, imck, EAP_FAST_SIMCK_LEN);
01300 wpa_hexdump_key(MSG_MSGDUMP, "EAP-FAST: S-IMCK[j]",
01301 data->simck, EAP_FAST_SIMCK_LEN);
01302 cmk = imck + EAP_FAST_SIMCK_LEN;
01303 wpa_hexdump_key(MSG_MSGDUMP, "EAP-FAST: CMK[j]", cmk, 20);
01304
01305 os_memcpy(cmac, _bind->compound_mac, sizeof(cmac));
01306 os_memset(_bind->compound_mac, 0, sizeof(cmac));
01307 wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Crypto-Binding TLV for Compound "
01308 "MAC calculation", (u8 *) _bind, bind_len);
01309 hmac_sha1(cmk, 20, (u8 *) _bind, bind_len, _bind->compound_mac);
01310 res = os_memcmp(cmac, _bind->compound_mac, sizeof(cmac));
01311 wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Received Compound MAC",
01312 cmac, sizeof(cmac));
01313 wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Calculated Compound MAC",
01314 _bind->compound_mac, sizeof(cmac));
01315 if (res != 0) {
01316 wpa_printf(MSG_INFO, "EAP-FAST: Compound MAC did not match");
01317 resp = eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 1,
01318 resp_len);
01319 os_memcpy(_bind->compound_mac, cmac, sizeof(cmac));
01320 return resp;
01321 }
01322
01323 *resp_len = sizeof(*rresult) + sizeof(*rbind);
01324 resp = os_zalloc(*resp_len);
01325 if (resp == NULL)
01326 return NULL;
01327
01328
01329
01330 rresult = (struct eap_tlv_intermediate_result_tlv *) resp;
01331 rresult->tlv_type = host_to_be16(EAP_TLV_TYPE_MANDATORY |
01332 (final ? EAP_TLV_RESULT_TLV :
01333 EAP_TLV_INTERMEDIATE_RESULT_TLV));
01334 rresult->length = host_to_be16(2);
01335 rresult->status = host_to_be16(EAP_TLV_RESULT_SUCCESS);
01336
01337 if (!data->provisioning && data->phase2_success &&
01338 eap_fast_derive_msk(data) < 0) {
01339 wpa_printf(MSG_INFO, "EAP-FAST: Failed to generate MSK");
01340 ret->methodState = METHOD_DONE;
01341 ret->decision = DECISION_FAIL;
01342 rresult->status = host_to_be16(EAP_TLV_RESULT_FAILURE);
01343 data->phase2_success = 0;
01344 }
01345
01346 rbind = (struct eap_tlv_crypto_binding__tlv *) (rresult + 1);
01347 rbind->tlv_type = host_to_be16(EAP_TLV_TYPE_MANDATORY |
01348 EAP_TLV_CRYPTO_BINDING_TLV_);
01349 rbind->length = host_to_be16(sizeof(*rbind) -
01350 sizeof(struct eap_tlv_hdr));
01351 rbind->version = EAP_FAST_VERSION;
01352 rbind->received_version = _bind->version;
01353 rbind->subtype = EAP_TLV_CRYPTO_BINDING_SUBTYPE_RESPONSE;
01354 os_memcpy(rbind->nonce, _bind->nonce, sizeof(_bind->nonce));
01355 inc_byte_array(rbind->nonce, sizeof(rbind->nonce));
01356 hmac_sha1(cmk, 20, (u8 *) rbind, sizeof(*rbind), rbind->compound_mac);
01357
01358 wpa_printf(MSG_DEBUG, "EAP-FAST: Reply Crypto-Binding TLV: Version %d "
01359 "Received Version %d SubType %d",
01360 rbind->version, rbind->received_version, rbind->subtype);
01361 wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: NONCE",
01362 rbind->nonce, sizeof(rbind->nonce));
01363 wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Compound MAC",
01364 rbind->compound_mac, sizeof(rbind->compound_mac));
01365
01366 if (final && data->phase2_success) {
01367 wpa_printf(MSG_DEBUG, "EAP-FAST: Authentication completed "
01368 "successfully.");
01369 ret->methodState = METHOD_DONE;
01370 ret->decision = DECISION_UNCOND_SUCC;
01371 }
01372
01373 return resp;
01374 }
01375
01376
01377 static u8 * eap_fast_process_pac(struct eap_sm *sm, struct eap_fast_data *data,
01378 struct eap_method_ret *ret,
01379 u8 *pac, size_t pac_len, size_t *resp_len)
01380 {
01381 struct wpa_ssid *config = eap_get_config(sm);
01382 struct pac_tlv_hdr *hdr;
01383 u8 *pos;
01384 size_t left, len;
01385 int type, pac_key_found = 0;
01386 struct eap_fast_pac entry;
01387
01388 os_memset(&entry, 0, sizeof(entry));
01389 pos = pac;
01390 left = pac_len;
01391 while (left > sizeof(*hdr)) {
01392 hdr = (struct pac_tlv_hdr *) pos;
01393 type = be_to_host16(hdr->type);
01394 len = be_to_host16(hdr->len);
01395 pos += sizeof(*hdr);
01396 left -= sizeof(*hdr);
01397 if (len > left) {
01398 wpa_printf(MSG_DEBUG, "EAP-FAST: PAC TLV overrun "
01399 "(type=%d len=%lu left=%lu)",
01400 type, (unsigned long) len,
01401 (unsigned long) left);
01402 return eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 0,
01403 resp_len);
01404 }
01405 switch (type) {
01406 case PAC_TYPE_PAC_KEY:
01407 wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: PAC-Key",
01408 pos, len);
01409 if (len != EAP_FAST_PAC_KEY_LEN) {
01410 wpa_printf(MSG_DEBUG, "EAP-FAST: Invalid "
01411 "PAC-Key length %lu",
01412 (unsigned long) len);
01413 break;
01414 }
01415 pac_key_found = 1;
01416 os_memcpy(entry.pac_key, pos, len);
01417 break;
01418 case PAC_TYPE_PAC_OPAQUE:
01419 wpa_hexdump(MSG_DEBUG, "EAP-FAST: PAC-Opaque",
01420 pos, len);
01421 entry.pac_opaque = pos;
01422 entry.pac_opaque_len = len;
01423 break;
01424 case PAC_TYPE_PAC_INFO:
01425 wpa_hexdump(MSG_DEBUG, "EAP-FAST: PAC-Info",
01426 pos, len);
01427 entry.pac_info = pos;
01428 entry.pac_info_len = len;
01429 break;
01430 default:
01431 wpa_printf(MSG_DEBUG, "EAP-FAST: Ignored unknown PAC "
01432 "type %d", type);
01433 break;
01434 }
01435
01436 pos += len;
01437 left -= len;
01438 }
01439
01440 if (!pac_key_found || !entry.pac_opaque || !entry.pac_info) {
01441 wpa_printf(MSG_DEBUG, "EAP-FAST: PAC TLV does not include "
01442 "all the required fields");
01443 return eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 0,
01444 resp_len);
01445 }
01446
01447 pos = entry.pac_info;
01448 left = entry.pac_info_len;
01449 while (left > sizeof(*hdr)) {
01450 hdr = (struct pac_tlv_hdr *) pos;
01451 type = be_to_host16(hdr->type);
01452 len = be_to_host16(hdr->len);
01453 pos += sizeof(*hdr);
01454 left -= sizeof(*hdr);
01455 if (len > left) {
01456 wpa_printf(MSG_DEBUG, "EAP-FAST: PAC-Info overrun "
01457 "(type=%d len=%lu left=%lu)",
01458 type, (unsigned long) len,
01459 (unsigned long) left);
01460 return eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 0,
01461 resp_len);
01462 }
01463 switch (type) {
01464 case PAC_TYPE_A_ID:
01465 wpa_hexdump_ascii(MSG_DEBUG, "EAP-FAST: PAC-Info - "
01466 "A-ID", pos, len);
01467 entry.a_id = pos;
01468 entry.a_id_len = len;
01469 break;
01470 case PAC_TYPE_I_ID:
01471 wpa_hexdump_ascii(MSG_DEBUG, "EAP-FAST: PAC-Info - "
01472 "I-ID", pos, len);
01473 entry.i_id = pos;
01474 entry.i_id_len = len;
01475 break;
01476 case PAC_TYPE_A_ID_INFO:
01477 wpa_hexdump_ascii(MSG_DEBUG, "EAP-FAST: PAC-Info - "
01478 "A-ID-Info", pos, len);
01479 entry.a_id_info = pos;
01480 entry.a_id_info_len = len;
01481 break;
01482 default:
01483 wpa_printf(MSG_DEBUG, "EAP-FAST: Ignored unknown "
01484 "PAC-Info type %d", type);
01485 break;
01486 }
01487
01488 pos += len;
01489 left -= len;
01490 }
01491
01492 if (entry.a_id == NULL || entry.a_id_info == NULL) {
01493 wpa_printf(MSG_DEBUG, "EAP-FAST: PAC-Info does not include "
01494 "all the required fields");
01495 return eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 0,
01496 resp_len);
01497 }
01498
01499 eap_fast_add_pac(data, &entry);
01500 eap_fast_save_pac(sm, data, config->pac_file);
01501
01502 if (data->provisioning) {
01503
01504
01505
01506 data->success = 0;
01507 ret->decision = DECISION_FAIL;
01508 wpa_printf(MSG_DEBUG, "EAP-FAST: Send PAC-Acknowledgement TLV "
01509 "- Provisioning completed successfully");
01510 } else {
01511
01512
01513 wpa_printf(MSG_DEBUG, "EAP-FAST: Send PAC-Acknowledgement TLV "
01514 "- PAC refreshing completed successfully");
01515 ret->decision = DECISION_UNCOND_SUCC;
01516 }
01517 ret->methodState = METHOD_DONE;
01518 return eap_fast_tlv_pac_ack(resp_len);
01519 }
01520
01521
01522 static int eap_fast_decrypt(struct eap_sm *sm, struct eap_fast_data *data,
01523 struct eap_method_ret *ret,
01524 const struct eap_hdr *req,
01525 const u8 *in_data, size_t in_len,
01526 u8 **out_data, size_t *out_len)
01527 {
01528 u8 *in_decrypted, *pos, *end;
01529 int len_decrypted, len;
01530 struct eap_hdr *hdr;
01531 u8 *resp = NULL;
01532 size_t buf_len, resp_len;
01533 int mandatory, tlv_type;
01534 u8 *eap_payload_tlv = NULL, *pac = NULL;
01535 size_t eap_payload_tlv_len = 0, pac_len = 0;
01536 int iresult = 0, result = 0;
01537 struct eap_tlv_crypto_binding__tlv *crypto_binding = NULL;
01538 size_t crypto_binding_len = 0;
01539 const u8 *msg;
01540 size_t msg_len;
01541 int need_more_input, stop;
01542
01543 wpa_printf(MSG_DEBUG, "EAP-FAST: received %lu bytes encrypted data for"
01544 " Phase 2", (unsigned long) in_len);
01545
01546 msg = eap_tls_data_reassemble(sm, &data->ssl, in_data, in_len,
01547 &msg_len, &need_more_input);
01548 if (msg == NULL)
01549 return need_more_input ? 1 : -1;
01550
01551 buf_len = in_len;
01552 if (data->ssl.tls_in_total > buf_len)
01553 buf_len = data->ssl.tls_in_total;
01554 in_decrypted = os_malloc(buf_len);
01555 if (in_decrypted == NULL) {
01556 os_free(data->ssl.tls_in);
01557 data->ssl.tls_in = NULL;
01558 data->ssl.tls_in_len = 0;
01559 wpa_printf(MSG_WARNING, "EAP-FAST: failed to allocate memory "
01560 "for decryption");
01561 return -1;
01562 }
01563
01564 len_decrypted = tls_connection_decrypt(sm->ssl_ctx, data->ssl.conn,
01565 msg, msg_len,
01566 in_decrypted, buf_len);
01567 os_free(data->ssl.tls_in);
01568 data->ssl.tls_in = NULL;
01569 data->ssl.tls_in_len = 0;
01570 if (len_decrypted < 0) {
01571 wpa_printf(MSG_INFO, "EAP-FAST: Failed to decrypt Phase 2 "
01572 "data");
01573 os_free(in_decrypted);
01574 return -1;
01575 }
01576
01577 wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Decrypted Phase 2 TLV(s)",
01578 in_decrypted, len_decrypted);
01579
01580 if (len_decrypted < 4) {
01581 os_free(in_decrypted);
01582 wpa_printf(MSG_INFO, "EAP-FAST: Too short Phase 2 "
01583 "TLV frame (len=%d)", len_decrypted);
01584 return -1;
01585 }
01586
01587 pos = in_decrypted;
01588 end = in_decrypted + len_decrypted;
01589 stop = 0;
01590 while (pos + 4 < end && !stop) {
01591 mandatory = pos[0] & 0x80;
01592 tlv_type = WPA_GET_BE16(pos) & 0x3fff;
01593 pos += 2;
01594 len = WPA_GET_BE16(pos);
01595 pos += 2;
01596 if (pos + len > end) {
01597 os_free(in_decrypted);
01598 wpa_printf(MSG_INFO, "EAP-FAST: TLV overflow");
01599 return 0;
01600 }
01601 wpa_printf(MSG_DEBUG, "EAP-FAST: received Phase 2: "
01602 "TLV type %d length %d%s",
01603 tlv_type, len, mandatory ? " (mandatory)" : "");
01604
01605 switch (tlv_type) {
01606 case EAP_TLV_EAP_PAYLOAD_TLV:
01607 wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: EAP Payload TLV",
01608 pos, len);
01609 eap_payload_tlv = pos;
01610 eap_payload_tlv_len = len;
01611 break;
01612 case EAP_TLV_RESULT_TLV:
01613 wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Result TLV",
01614 pos, len);
01615 if (len < 2) {
01616 wpa_printf(MSG_DEBUG, "EAP-FAST: Too short "
01617 "Result TLV");
01618 result = EAP_TLV_RESULT_FAILURE;
01619 break;
01620 }
01621 result = WPA_GET_BE16(pos);
01622 if (result != EAP_TLV_RESULT_SUCCESS &&
01623 result != EAP_TLV_RESULT_FAILURE) {
01624 wpa_printf(MSG_DEBUG, "EAP-FAST: Unknown "
01625 "Result %d", result);
01626 result = EAP_TLV_RESULT_FAILURE;
01627 }
01628 wpa_printf(MSG_DEBUG, "EAP-FAST: Result: %s",
01629 result == EAP_TLV_RESULT_SUCCESS ?
01630 "Success" : "Failure");
01631 break;
01632 case EAP_TLV_INTERMEDIATE_RESULT_TLV:
01633 wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Intermediate "
01634 "Result TLV", pos, len);
01635 if (len < 2) {
01636 wpa_printf(MSG_DEBUG, "EAP-FAST: Too short "
01637 "Intermediate Result TLV");
01638 iresult = EAP_TLV_RESULT_FAILURE;
01639 break;
01640 }
01641 iresult = WPA_GET_BE16(pos);
01642 if (iresult != EAP_TLV_RESULT_SUCCESS &&
01643 iresult != EAP_TLV_RESULT_FAILURE) {
01644 wpa_printf(MSG_DEBUG, "EAP-FAST: Unknown "
01645 "Intermediate Result %d", iresult);
01646 iresult = EAP_TLV_RESULT_FAILURE;
01647 }
01648 wpa_printf(MSG_DEBUG,
01649 "EAP-FAST: Intermediate Result: %s",
01650 iresult == EAP_TLV_RESULT_SUCCESS ?
01651 "Success" : "Failure");
01652 break;
01653 case EAP_TLV_CRYPTO_BINDING_TLV_:
01654 wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Crypto-Binding "
01655 "TLV", pos, len);
01656 crypto_binding_len = sizeof(struct eap_tlv_hdr) + len;
01657 if (crypto_binding_len < sizeof(*crypto_binding)) {
01658 wpa_printf(MSG_DEBUG, "EAP-FAST: Too short "
01659 "Crypto-Binding TLV");
01660 iresult = EAP_TLV_RESULT_FAILURE;
01661 pos = end;
01662 break;
01663 }
01664 crypto_binding =
01665 (struct eap_tlv_crypto_binding__tlv *)
01666 (pos - sizeof(struct eap_tlv_hdr));
01667 break;
01668 case EAP_TLV_PAC_TLV:
01669 wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: PAC TLV",
01670 pos, len);
01671 pac = pos;
01672 pac_len = len;
01673 break;
01674 default:
01675 if (mandatory) {
01676 wpa_printf(MSG_DEBUG, "EAP-FAST: Nak unknown "
01677 "mandatory TLV type %d", tlv_type);
01678 resp = eap_fast_tlv_nak(0, tlv_type,
01679 &resp_len);
01680 stop = 1;
01681 } else {
01682 wpa_printf(MSG_DEBUG, "EAP-FAST: ignored "
01683 "unknown optional TLV type %d",
01684 tlv_type);
01685 }
01686 break;
01687 }
01688
01689 pos += len;
01690 }
01691
01692 if (!resp && result == EAP_TLV_RESULT_FAILURE) {
01693 resp = eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 0,
01694 &resp_len);
01695 if (!resp) {
01696 os_free(in_decrypted);
01697 return 0;
01698 }
01699 }
01700
01701 if (!resp && iresult == EAP_TLV_RESULT_FAILURE) {
01702 resp = eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 1,
01703 &resp_len);
01704 if (!resp) {
01705 os_free(in_decrypted);
01706 return 0;
01707 }
01708 }
01709
01710 if (!resp && eap_payload_tlv) {
01711 if (eap_payload_tlv_len < sizeof(*hdr)) {
01712 wpa_printf(MSG_DEBUG, "EAP-FAST: too short EAP "
01713 "Payload TLV (len=%lu)",
01714 (unsigned long) eap_payload_tlv_len);
01715 os_free(in_decrypted);
01716 return 0;
01717 }
01718 hdr = (struct eap_hdr *) eap_payload_tlv;
01719 if (be_to_host16(hdr->length) > eap_payload_tlv_len) {
01720 wpa_printf(MSG_DEBUG, "EAP-FAST: EAP packet overflow "
01721 "in EAP Payload TLV");
01722 os_free(in_decrypted);
01723 return 0;
01724 }
01725 if (hdr->code == EAP_CODE_REQUEST) {
01726 if (eap_fast_phase2_request(sm, data, ret, hdr,
01727 &resp, &resp_len)) {
01728 os_free(in_decrypted);
01729 wpa_printf(MSG_INFO, "EAP-FAST: Phase2 "
01730 "Request processing failed");
01731 return 0;
01732 }
01733 resp = eap_fast_tlv_eap_payload(resp, &resp_len);
01734 if (resp == NULL) {
01735 os_free(in_decrypted);
01736 return 0;
01737 }
01738 } else {
01739 wpa_printf(MSG_INFO, "EAP-FAST: Unexpected code=%d in "
01740 "Phase 2 EAP header", hdr->code);
01741 os_free(in_decrypted);
01742 return 0;
01743 }
01744 }
01745
01746 if (!resp && crypto_binding) {
01747 int final = result == EAP_TLV_RESULT_SUCCESS;
01748 resp = eap_fast_process_crypto_binding(sm, data, ret,
01749 crypto_binding,
01750 crypto_binding_len,
01751 &resp_len, final);
01752 if (!resp) {
01753 os_free(in_decrypted);
01754 return 0;
01755 }
01756 }
01757
01758 if (!resp && pac && result != EAP_TLV_RESULT_SUCCESS) {
01759 wpa_printf(MSG_DEBUG, "EAP-FAST: PAC TLV without Result TLV "
01760 "acknowledging success");
01761 resp = eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 0,
01762 &resp_len);
01763 if (!resp) {
01764 os_free(in_decrypted);
01765 return 0;
01766 }
01767 }
01768
01769 if (!resp && pac && result == EAP_TLV_RESULT_SUCCESS) {
01770 resp = eap_fast_process_pac(sm, data, ret, pac, pac_len,
01771 &resp_len);
01772 if (!resp) {
01773 os_free(in_decrypted);
01774 return 0;
01775 }
01776 }
01777
01778 os_free(in_decrypted);
01779
01780 if (resp == NULL) {
01781 wpa_printf(MSG_DEBUG, "EAP-FAST: No recognized TLVs - send "
01782 "empty response packet");
01783 resp = os_malloc(1);
01784 if (resp == NULL)
01785 return 0;
01786 resp_len = 0;
01787 }
01788
01789 wpa_hexdump(MSG_DEBUG, "EAP-FAST: Encrypting Phase 2 data",
01790 resp, resp_len);
01791 if (eap_fast_encrypt(sm, data, req->identifier, resp, resp_len,
01792 out_data, out_len)) {
01793 wpa_printf(MSG_INFO, "EAP-FAST: Failed to encrypt a Phase 2 "
01794 "frame");
01795 }
01796 os_free(resp);
01797
01798 return 0;
01799 }
01800
01801
01802 static u8 * eap_fast_process(struct eap_sm *sm, void *priv,
01803 struct eap_method_ret *ret,
01804 const u8 *reqData, size_t reqDataLen,
01805 size_t *respDataLen)
01806 {
01807 const struct eap_hdr *req;
01808 size_t left;
01809 int res;
01810 u8 flags, *resp, id;
01811 const u8 *pos;
01812 struct eap_fast_data *data = priv;
01813
01814 pos = eap_tls_process_init(sm, &data->ssl, EAP_TYPE_FAST, ret,
01815 reqData, reqDataLen, &left, &flags);
01816 if (pos == NULL)
01817 return NULL;
01818 req = (const struct eap_hdr *) reqData;
01819 id = req->identifier;
01820
01821 if (flags & EAP_TLS_FLAGS_START) {
01822 const u8 *a_id;
01823 size_t a_id_len;
01824 struct pac_tlv_hdr *hdr;
01825
01826 wpa_printf(MSG_DEBUG, "EAP-FAST: Start (server ver=%d, own "
01827 "ver=%d)", flags & EAP_PEAP_VERSION_MASK,
01828 data->fast_version);
01829 if ((flags & EAP_PEAP_VERSION_MASK) < data->fast_version)
01830 data->fast_version = flags & EAP_PEAP_VERSION_MASK;
01831 wpa_printf(MSG_DEBUG, "EAP-FAST: Using FAST version %d",
01832 data->fast_version);
01833
01834 a_id = pos;
01835 a_id_len = left;
01836 if (left > sizeof(*hdr)) {
01837 int tlen;
01838 hdr = (struct pac_tlv_hdr *) pos;
01839 tlen = be_to_host16(hdr->len);
01840 if (be_to_host16(hdr->type) == PAC_TYPE_A_ID &&
01841 sizeof(*hdr) + tlen <= left) {
01842 a_id = (u8 *) (hdr + 1);
01843 a_id_len = tlen;
01844 }
01845 }
01846 wpa_hexdump_ascii(MSG_DEBUG, "EAP-FAST: A-ID", a_id, a_id_len);
01847
01848 data->current_pac = eap_fast_get_pac(data, a_id, a_id_len);
01849 if (data->current_pac) {
01850 wpa_printf(MSG_DEBUG, "EAP-FAST: PAC found for this "
01851 "A-ID");
01852 wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-FAST: A-ID-Info",
01853 data->current_pac->a_id_info,
01854 data->current_pac->a_id_info_len);
01855 }
01856
01857 if (data->resuming && data->current_pac) {
01858 wpa_printf(MSG_DEBUG, "EAP-FAST: Trying to resume "
01859 "session - do not add PAC-Opaque to TLS "
01860 "ClientHello");
01861 if (tls_connection_client_hello_ext(
01862 sm->ssl_ctx, data->ssl.conn,
01863 TLS_EXT_PAC_OPAQUE, NULL, 0) < 0) {
01864 wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to "
01865 "remove PAC-Opaque TLS extension");
01866 return NULL;
01867 }
01868
01869 } else if (data->current_pac) {
01870 u8 *tlv;
01871 size_t tlv_len, olen;
01872 struct eap_tlv_hdr *ehdr;
01873 olen = data->current_pac->pac_opaque_len;
01874 tlv_len = sizeof(*ehdr) + olen;
01875 tlv = os_malloc(tlv_len);
01876 if (tlv) {
01877 ehdr = (struct eap_tlv_hdr *) tlv;
01878 ehdr->tlv_type =
01879 host_to_be16(PAC_TYPE_PAC_OPAQUE);
01880 ehdr->length = host_to_be16(olen);
01881 os_memcpy(ehdr + 1,
01882 data->current_pac->pac_opaque, olen);
01883 }
01884 if (tlv == NULL ||
01885 tls_connection_client_hello_ext(
01886 sm->ssl_ctx, data->ssl.conn,
01887 TLS_EXT_PAC_OPAQUE, tlv, tlv_len) < 0) {
01888 wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to "
01889 "add PAC-Opaque TLS extension");
01890 os_free(tlv);
01891 return NULL;
01892 }
01893 os_free(tlv);
01894 } else {
01895 u8 ciphers[2];
01896 if (!data->provisioning_allowed) {
01897 wpa_printf(MSG_DEBUG, "EAP-FAST: No PAC found "
01898 "and provisioning disabled");
01899 return NULL;
01900 }
01901 wpa_printf(MSG_DEBUG, "EAP-FAST: No PAC found - "
01902 "starting provisioning");
01903 ciphers[0] = TLS_CIPHER_ANON_DH_AES128_SHA;
01904 ciphers[1] = TLS_CIPHER_NONE;
01905 if (tls_connection_set_cipher_list(sm->ssl_ctx,
01906 data->ssl.conn,
01907 ciphers)) {
01908 wpa_printf(MSG_INFO, "EAP-FAST: Could not "
01909 "configure anonymous DH for TLS "
01910 "connection");
01911 return NULL;
01912 }
01913 if (tls_connection_client_hello_ext(
01914 sm->ssl_ctx, data->ssl.conn,
01915 TLS_EXT_PAC_OPAQUE, NULL, 0) < 0) {
01916 wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to "
01917 "remove PAC-Opaque TLS extension");
01918 return NULL;
01919 }
01920 data->provisioning = 1;
01921 }
01922
01923 left = 0;
01924 }
01925
01926 resp = NULL;
01927 if (tls_connection_established(sm->ssl_ctx, data->ssl.conn) &&
01928 !data->resuming) {
01929 res = eap_fast_decrypt(sm, data, ret, req, pos, left,
01930 &resp, respDataLen);
01931 if (res < 0) {
01932 ret->methodState = METHOD_DONE;
01933 ret->decision = DECISION_FAIL;
01934
01935
01936 res = 1;
01937 }
01938 } else {
01939 if (eap_fast_set_tls_master_secret(sm, data, pos, left) < 0) {
01940 wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to configure "
01941 "TLS master secret");
01942 ret->methodState = METHOD_DONE;
01943 ret->decision = DECISION_FAIL;
01944 return NULL;
01945 }
01946
01947 res = eap_tls_process_helper(sm, &data->ssl, EAP_TYPE_FAST,
01948 data->fast_version, id, pos, left,
01949 &resp, respDataLen);
01950
01951 if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
01952 wpa_printf(MSG_DEBUG,
01953 "EAP-FAST: TLS done, proceed to Phase 2");
01954 data->resuming = 0;
01955 eap_fast_derive_keys(sm, data);
01956 }
01957 }
01958
01959 if (res == 1)
01960 return eap_tls_build_ack(&data->ssl, respDataLen, id,
01961 EAP_TYPE_FAST, data->fast_version);
01962 return resp;
01963 }
01964
01965
01966 #if 0
01967 static Boolean eap_fast_has_reauth_data(struct eap_sm *sm, void *priv)
01968 {
01969 struct eap_fast_data *data = priv;
01970 return tls_connection_established(sm->ssl_ctx, data->ssl.conn);
01971 }
01972
01973
01974 static void eap_fast_deinit_for_reauth(struct eap_sm *sm, void *priv)
01975 {
01976 struct eap_fast_data *data = priv;
01977 os_free(data->key_block_p);
01978 data->key_block_p = NULL;
01979 }
01980
01981
01982 static void * eap_fast_init_for_reauth(struct eap_sm *sm, void *priv)
01983 {
01984 struct eap_fast_data *data = priv;
01985 if (eap_tls_reauth_init(sm, &data->ssl)) {
01986 os_free(data);
01987 return NULL;
01988 }
01989 if (data->phase2_priv && data->phase2_method &&
01990 data->phase2_method->init_for_reauth)
01991 data->phase2_method->init_for_reauth(sm, data->phase2_priv);
01992 data->phase2_success = 0;
01993 data->resuming = 1;
01994 data->provisioning = 0;
01995 data->simck_idx = 0;
01996 return priv;
01997 }
01998 #endif
01999
02000
02001 static int eap_fast_get_status(struct eap_sm *sm, void *priv, char *buf,
02002 size_t buflen, int verbose)
02003 {
02004 struct eap_fast_data *data = priv;
02005 int len, ret;
02006
02007 len = eap_tls_status(sm, &data->ssl, buf, buflen, verbose);
02008 if (data->phase2_method) {
02009 ret = os_snprintf(buf + len, buflen - len,
02010 "EAP-FAST Phase2 method=%s\n",
02011 data->phase2_method->name);
02012 if (ret < 0 || (size_t) ret >= buflen - len)
02013 return len;
02014 len += ret;
02015 }
02016 return len;
02017 }
02018
02019
02020 static Boolean eap_fast_isKeyAvailable(struct eap_sm *sm, void *priv)
02021 {
02022 struct eap_fast_data *data = priv;
02023 return data->success;
02024 }
02025
02026
02027 static u8 * eap_fast_getKey(struct eap_sm *sm, void *priv, size_t *len)
02028 {
02029 struct eap_fast_data *data = priv;
02030 u8 *key;
02031
02032 if (!data->success)
02033 return NULL;
02034
02035 key = os_malloc(EAP_FAST_KEY_LEN);
02036 if (key == NULL)
02037 return NULL;
02038
02039 *len = EAP_FAST_KEY_LEN;
02040 os_memcpy(key, data->key_data, EAP_FAST_KEY_LEN);
02041
02042 return key;
02043 }
02044
02045
02046 static u8 * eap_fast_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
02047 {
02048 struct eap_fast_data *data = priv;
02049 u8 *key;
02050
02051 if (!data->success)
02052 return NULL;
02053
02054 key = os_malloc(EAP_EMSK_LEN);
02055 if (key == NULL)
02056 return NULL;
02057
02058 *len = EAP_EMSK_LEN;
02059 os_memcpy(key, data->emsk, EAP_EMSK_LEN);
02060
02061 return key;
02062 }
02063
02064
02065 int eap_peer_fast_register(void)
02066 {
02067 struct eap_method *eap;
02068 int ret;
02069
02070 eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
02071 EAP_VENDOR_IETF, EAP_TYPE_FAST, "FAST");
02072 if (eap == NULL)
02073 return -1;
02074
02075 eap->init = eap_fast_init;
02076 eap->deinit = eap_fast_deinit;
02077 eap->process = eap_fast_process;
02078 eap->isKeyAvailable = eap_fast_isKeyAvailable;
02079 eap->getKey = eap_fast_getKey;
02080 eap->get_status = eap_fast_get_status;
02081 #if 0
02082 eap->has_reauth_data = eap_fast_has_reauth_data;
02083 eap->deinit_for_reauth = eap_fast_deinit_for_reauth;
02084 eap->init_for_reauth = eap_fast_init_for_reauth;
02085 #endif
02086 eap->get_emsk = eap_fast_get_emsk;
02087
02088 ret = eap_peer_method_register(eap);
02089 if (ret)
02090 eap_peer_method_free(eap);
02091 return ret;
02092 }
02093