00001
00016 #include "includes.h"
00017
00018 #include "common.h"
00019 #include "dh_groups.h"
00020 #include "ikev2.h"
00021
00022
00023 static int ikev2_process_idr(struct ikev2_initiator_data *data,
00024 const u8 *idr, size_t idr_len);
00025
00026
00027 void ikev2_initiator_deinit(struct ikev2_initiator_data *data)
00028 {
00029 ikev2_free_keys(&data->keys);
00030 wpabuf_free(data->r_dh_public);
00031 wpabuf_free(data->i_dh_private);
00032 os_free(data->IDi);
00033 os_free(data->IDr);
00034 os_free(data->shared_secret);
00035 wpabuf_free(data->i_sign_msg);
00036 wpabuf_free(data->r_sign_msg);
00037 os_free(data->key_pad);
00038 }
00039
00040
00041 static int ikev2_derive_keys(struct ikev2_initiator_data *data)
00042 {
00043 u8 *buf, *pos, *pad, skeyseed[IKEV2_MAX_HASH_LEN];
00044 size_t buf_len, pad_len;
00045 struct wpabuf *shared;
00046 const struct ikev2_integ_alg *integ;
00047 const struct ikev2_prf_alg *prf;
00048 const struct ikev2_encr_alg *encr;
00049 int ret;
00050 const u8 *addr[2];
00051 size_t len[2];
00052
00053
00054
00055 integ = ikev2_get_integ(data->proposal.integ);
00056 prf = ikev2_get_prf(data->proposal.prf);
00057 encr = ikev2_get_encr(data->proposal.encr);
00058 if (integ == NULL || prf == NULL || encr == NULL) {
00059 wpa_printf(MSG_INFO, "IKEV2: Unsupported proposal");
00060 return -1;
00061 }
00062
00063 shared = dh_derive_shared(data->r_dh_public, data->i_dh_private,
00064 data->dh);
00065 if (shared == NULL)
00066 return -1;
00067
00068
00069
00070 buf_len = data->i_nonce_len + data->r_nonce_len + 2 * IKEV2_SPI_LEN;
00071 buf = os_malloc(buf_len);
00072 if (buf == NULL) {
00073 wpabuf_free(shared);
00074 return -1;
00075 }
00076
00077 pos = buf;
00078 os_memcpy(pos, data->i_nonce, data->i_nonce_len);
00079 pos += data->i_nonce_len;
00080 os_memcpy(pos, data->r_nonce, data->r_nonce_len);
00081 pos += data->r_nonce_len;
00082 os_memcpy(pos, data->i_spi, IKEV2_SPI_LEN);
00083 pos += IKEV2_SPI_LEN;
00084 os_memcpy(pos, data->r_spi, IKEV2_SPI_LEN);
00085
00086
00087
00088
00089 pad_len = data->dh->prime_len - wpabuf_len(shared);
00090 pad = os_zalloc(pad_len ? pad_len : 1);
00091 if (pad == NULL) {
00092 wpabuf_free(shared);
00093 os_free(buf);
00094 return -1;
00095 }
00096 addr[0] = pad;
00097 len[0] = pad_len;
00098 addr[1] = wpabuf_head(shared);
00099 len[1] = wpabuf_len(shared);
00100 if (ikev2_prf_hash(prf->id, buf, data->i_nonce_len + data->r_nonce_len,
00101 2, addr, len, skeyseed) < 0) {
00102 wpabuf_free(shared);
00103 os_free(buf);
00104 os_free(pad);
00105 return -1;
00106 }
00107 os_free(pad);
00108 wpabuf_free(shared);
00109
00110
00111 wpabuf_free(data->r_dh_public);
00112 data->r_dh_public = NULL;
00113 wpabuf_free(data->i_dh_private);
00114 data->i_dh_private = NULL;
00115
00116 wpa_hexdump_key(MSG_DEBUG, "IKEV2: SKEYSEED",
00117 skeyseed, prf->hash_len);
00118
00119 ret = ikev2_derive_sk_keys(prf, integ, encr, skeyseed, buf, buf_len,
00120 &data->keys);
00121 os_free(buf);
00122 return ret;
00123 }
00124
00125
00126 static int ikev2_parse_transform(struct ikev2_initiator_data *data,
00127 struct ikev2_proposal_data *prop,
00128 const u8 *pos, const u8 *end)
00129 {
00130 int transform_len;
00131 const struct ikev2_transform *t;
00132 u16 transform_id;
00133 const u8 *tend;
00134
00135 if (end - pos < (int) sizeof(*t)) {
00136 wpa_printf(MSG_INFO, "IKEV2: Too short transform");
00137 return -1;
00138 }
00139
00140 t = (const struct ikev2_transform *) pos;
00141 transform_len = WPA_GET_BE16(t->transform_length);
00142 if (transform_len < (int) sizeof(*t) || pos + transform_len > end) {
00143 wpa_printf(MSG_INFO, "IKEV2: Invalid transform length %d",
00144 transform_len);
00145 return -1;
00146 }
00147 tend = pos + transform_len;
00148
00149 transform_id = WPA_GET_BE16(t->transform_id);
00150
00151 wpa_printf(MSG_DEBUG, "IKEV2: Transform:");
00152 wpa_printf(MSG_DEBUG, "IKEV2: Type: %d Transform Length: %d "
00153 "Transform Type: %d Transform ID: %d",
00154 t->type, transform_len, t->transform_type, transform_id);
00155
00156 if (t->type != 0 && t->type != 3) {
00157 wpa_printf(MSG_INFO, "IKEV2: Unexpected Transform type");
00158 return -1;
00159 }
00160
00161 pos = (const u8 *) (t + 1);
00162 if (pos < tend) {
00163 wpa_hexdump(MSG_DEBUG, "IKEV2: Transform Attributes",
00164 pos, tend - pos);
00165 }
00166
00167 switch (t->transform_type) {
00168 case IKEV2_TRANSFORM_ENCR:
00169 if (ikev2_get_encr(transform_id) &&
00170 transform_id == data->proposal.encr) {
00171 if (transform_id == ENCR_AES_CBC) {
00172 if (tend - pos != 4) {
00173 wpa_printf(MSG_DEBUG, "IKEV2: No "
00174 "Transform Attr for AES");
00175 break;
00176 }
00177 if (WPA_GET_BE16(pos) != 0x800e) {
00178 wpa_printf(MSG_DEBUG, "IKEV2: Not a "
00179 "Key Size attribute for "
00180 "AES");
00181 break;
00182 }
00183 if (WPA_GET_BE16(pos + 2) != 128) {
00184 wpa_printf(MSG_DEBUG, "IKEV2: "
00185 "Unsupported AES key size "
00186 "%d bits",
00187 WPA_GET_BE16(pos + 2));
00188 break;
00189 }
00190 }
00191 prop->encr = transform_id;
00192 }
00193 break;
00194 case IKEV2_TRANSFORM_PRF:
00195 if (ikev2_get_prf(transform_id) &&
00196 transform_id == data->proposal.prf)
00197 prop->prf = transform_id;
00198 break;
00199 case IKEV2_TRANSFORM_INTEG:
00200 if (ikev2_get_integ(transform_id) &&
00201 transform_id == data->proposal.integ)
00202 prop->integ = transform_id;
00203 break;
00204 case IKEV2_TRANSFORM_DH:
00205 if (dh_groups_get(transform_id) &&
00206 transform_id == data->proposal.dh)
00207 prop->dh = transform_id;
00208 break;
00209 }
00210
00211 return transform_len;
00212 }
00213
00214
00215 static int ikev2_parse_proposal(struct ikev2_initiator_data *data,
00216 struct ikev2_proposal_data *prop,
00217 const u8 *pos, const u8 *end)
00218 {
00219 const u8 *pend, *ppos;
00220 int proposal_len, i;
00221 const struct ikev2_proposal *p;
00222
00223 if (end - pos < (int) sizeof(*p)) {
00224 wpa_printf(MSG_INFO, "IKEV2: Too short proposal");
00225 return -1;
00226 }
00227
00228 p = (const struct ikev2_proposal *) pos;
00229 proposal_len = WPA_GET_BE16(p->proposal_length);
00230 if (proposal_len < (int) sizeof(*p) || pos + proposal_len > end) {
00231 wpa_printf(MSG_INFO, "IKEV2: Invalid proposal length %d",
00232 proposal_len);
00233 return -1;
00234 }
00235 wpa_printf(MSG_DEBUG, "IKEV2: SAi1 Proposal # %d",
00236 p->proposal_num);
00237 wpa_printf(MSG_DEBUG, "IKEV2: Type: %d Proposal Length: %d "
00238 " Protocol ID: %d",
00239 p->type, proposal_len, p->protocol_id);
00240 wpa_printf(MSG_DEBUG, "IKEV2: SPI Size: %d Transforms: %d",
00241 p->spi_size, p->num_transforms);
00242
00243 if (p->type != 0 && p->type != 2) {
00244 wpa_printf(MSG_INFO, "IKEV2: Unexpected Proposal type");
00245 return -1;
00246 }
00247
00248 if (p->protocol_id != IKEV2_PROTOCOL_IKE) {
00249 wpa_printf(MSG_DEBUG, "IKEV2: Unexpected Protocol ID "
00250 "(only IKE allowed for EAP-IKEv2)");
00251 return -1;
00252 }
00253
00254 if (p->proposal_num != prop->proposal_num) {
00255 if (p->proposal_num == prop->proposal_num + 1)
00256 prop->proposal_num = p->proposal_num;
00257 else {
00258 wpa_printf(MSG_INFO, "IKEV2: Unexpected Proposal #");
00259 return -1;
00260 }
00261 }
00262
00263 ppos = (const u8 *) (p + 1);
00264 pend = pos + proposal_len;
00265 if (ppos + p->spi_size > pend) {
00266 wpa_printf(MSG_INFO, "IKEV2: Not enough room for SPI "
00267 "in proposal");
00268 return -1;
00269 }
00270 if (p->spi_size) {
00271 wpa_hexdump(MSG_DEBUG, "IKEV2: SPI",
00272 ppos, p->spi_size);
00273 ppos += p->spi_size;
00274 }
00275
00276
00277
00278
00279
00280
00281 if (p->spi_size != 0) {
00282 wpa_printf(MSG_INFO, "IKEV2: Unexpected SPI Size");
00283 return -1;
00284 }
00285
00286 if (p->num_transforms == 0) {
00287 wpa_printf(MSG_INFO, "IKEV2: At least one transform required");
00288 return -1;
00289 }
00290
00291 for (i = 0; i < (int) p->num_transforms; i++) {
00292 int tlen = ikev2_parse_transform(data, prop, ppos, pend);
00293 if (tlen < 0)
00294 return -1;
00295 ppos += tlen;
00296 }
00297
00298 if (ppos != pend) {
00299 wpa_printf(MSG_INFO, "IKEV2: Unexpected data after "
00300 "transforms");
00301 return -1;
00302 }
00303
00304 return proposal_len;
00305 }
00306
00307
00308 static int ikev2_process_sar1(struct ikev2_initiator_data *data,
00309 const u8 *sar1, size_t sar1_len)
00310 {
00311 struct ikev2_proposal_data prop;
00312 const u8 *pos, *end;
00313 int found = 0;
00314
00315
00316
00317 if (sar1 == NULL) {
00318 wpa_printf(MSG_INFO, "IKEV2: SAr1 not received");
00319 return -1;
00320 }
00321
00322 os_memset(&prop, 0, sizeof(prop));
00323 prop.proposal_num = 1;
00324
00325 pos = sar1;
00326 end = sar1 + sar1_len;
00327
00328 while (pos < end) {
00329 int plen;
00330
00331 prop.integ = -1;
00332 prop.prf = -1;
00333 prop.encr = -1;
00334 prop.dh = -1;
00335 plen = ikev2_parse_proposal(data, &prop, pos, end);
00336 if (plen < 0)
00337 return -1;
00338
00339 if (!found && prop.integ != -1 && prop.prf != -1 &&
00340 prop.encr != -1 && prop.dh != -1) {
00341 found = 1;
00342 }
00343
00344 pos += plen;
00345
00346
00347 break;
00348 }
00349
00350 if (pos != end) {
00351 wpa_printf(MSG_INFO, "IKEV2: Unexpected data after proposal");
00352 return -1;
00353 }
00354
00355 if (!found) {
00356 wpa_printf(MSG_INFO, "IKEV2: No acceptable proposal found");
00357 return -1;
00358 }
00359
00360 wpa_printf(MSG_DEBUG, "IKEV2: Accepted proposal #%d: ENCR:%d PRF:%d "
00361 "INTEG:%d D-H:%d", data->proposal.proposal_num,
00362 data->proposal.encr, data->proposal.prf,
00363 data->proposal.integ, data->proposal.dh);
00364
00365 return 0;
00366 }
00367
00368
00369 static int ikev2_process_ker(struct ikev2_initiator_data *data,
00370 const u8 *ker, size_t ker_len)
00371 {
00372 u16 group;
00373
00374
00375
00376
00377
00378
00379
00380
00381 if (ker == NULL) {
00382 wpa_printf(MSG_INFO, "IKEV2: KEr not received");
00383 return -1;
00384 }
00385
00386 if (ker_len < 4 + 96) {
00387 wpa_printf(MSG_INFO, "IKEV2: Too show Key Exchange Payload");
00388 return -1;
00389 }
00390
00391 group = WPA_GET_BE16(ker);
00392 wpa_printf(MSG_DEBUG, "IKEV2: KEr DH Group #%u", group);
00393
00394 if (group != data->proposal.dh) {
00395 wpa_printf(MSG_DEBUG, "IKEV2: KEr DH Group #%u does not match "
00396 "with the selected proposal (%u)",
00397 group, data->proposal.dh);
00398 return -1;
00399 }
00400
00401 if (data->dh == NULL) {
00402 wpa_printf(MSG_INFO, "IKEV2: Unsupported DH group");
00403 return -1;
00404 }
00405
00406
00407
00408
00409
00410 if (ker_len - 4 != data->dh->prime_len) {
00411 wpa_printf(MSG_INFO, "IKEV2: Invalid DH public value length "
00412 "%ld (expected %ld)",
00413 (long) (ker_len - 4), (long) data->dh->prime_len);
00414 return -1;
00415 }
00416
00417 wpabuf_free(data->r_dh_public);
00418 data->r_dh_public = wpabuf_alloc_copy(ker + 4, ker_len - 4);
00419 if (data->r_dh_public == NULL)
00420 return -1;
00421
00422 wpa_hexdump_buf(MSG_DEBUG, "IKEV2: KEr Diffie-Hellman Public Value",
00423 data->r_dh_public);
00424
00425 return 0;
00426 }
00427
00428
00429 static int ikev2_process_nr(struct ikev2_initiator_data *data,
00430 const u8 *nr, size_t nr_len)
00431 {
00432 if (nr == NULL) {
00433 wpa_printf(MSG_INFO, "IKEV2: Nr not received");
00434 return -1;
00435 }
00436
00437 if (nr_len < IKEV2_NONCE_MIN_LEN || nr_len > IKEV2_NONCE_MAX_LEN) {
00438 wpa_printf(MSG_INFO, "IKEV2: Invalid Nr length %ld",
00439 (long) nr_len);
00440 return -1;
00441 }
00442
00443 data->r_nonce_len = nr_len;
00444 os_memcpy(data->r_nonce, nr, nr_len);
00445 wpa_hexdump(MSG_MSGDUMP, "IKEV2: Nr",
00446 data->r_nonce, data->r_nonce_len);
00447
00448 return 0;
00449 }
00450
00451
00452 static int ikev2_process_sa_init_encr(struct ikev2_initiator_data *data,
00453 const struct ikev2_hdr *hdr,
00454 const u8 *encrypted,
00455 size_t encrypted_len, u8 next_payload)
00456 {
00457 u8 *decrypted;
00458 size_t decrypted_len;
00459 struct ikev2_payloads pl;
00460 int ret = 0;
00461
00462 decrypted = ikev2_decrypt_payload(data->proposal.encr,
00463 data->proposal.integ, &data->keys, 0,
00464 hdr, encrypted, encrypted_len,
00465 &decrypted_len);
00466 if (decrypted == NULL)
00467 return -1;
00468
00469 wpa_printf(MSG_DEBUG, "IKEV2: Processing decrypted payloads");
00470
00471 if (ikev2_parse_payloads(&pl, next_payload, decrypted,
00472 decrypted + decrypted_len) < 0) {
00473 wpa_printf(MSG_INFO, "IKEV2: Failed to parse decrypted "
00474 "payloads");
00475 return -1;
00476 }
00477
00478 if (pl.idr)
00479 ret = ikev2_process_idr(data, pl.idr, pl.idr_len);
00480
00481 os_free(decrypted);
00482
00483 return ret;
00484 }
00485
00486
00487 static int ikev2_process_sa_init(struct ikev2_initiator_data *data,
00488 const struct ikev2_hdr *hdr,
00489 struct ikev2_payloads *pl)
00490 {
00491 if (ikev2_process_sar1(data, pl->sa, pl->sa_len) < 0 ||
00492 ikev2_process_ker(data, pl->ke, pl->ke_len) < 0 ||
00493 ikev2_process_nr(data, pl->nonce, pl->nonce_len) < 0)
00494 return -1;
00495
00496 os_memcpy(data->r_spi, hdr->r_spi, IKEV2_SPI_LEN);
00497
00498 if (ikev2_derive_keys(data) < 0)
00499 return -1;
00500
00501 if (pl->encrypted) {
00502 wpa_printf(MSG_DEBUG, "IKEV2: Encrypted payload in SA_INIT - "
00503 "try to get IDr from it");
00504 if (ikev2_process_sa_init_encr(data, hdr, pl->encrypted,
00505 pl->encrypted_len,
00506 pl->encr_next_payload) < 0) {
00507 wpa_printf(MSG_INFO, "IKEV2: Failed to process "
00508 "encrypted payload");
00509 return -1;
00510 }
00511 }
00512
00513 data->state = SA_AUTH;
00514
00515 return 0;
00516 }
00517
00518
00519 static int ikev2_process_idr(struct ikev2_initiator_data *data,
00520 const u8 *idr, size_t idr_len)
00521 {
00522 u8 id_type;
00523
00524 if (idr == NULL) {
00525 wpa_printf(MSG_INFO, "IKEV2: No IDr received");
00526 return -1;
00527 }
00528
00529 if (idr_len < 4) {
00530 wpa_printf(MSG_INFO, "IKEV2: Too short IDr payload");
00531 return -1;
00532 }
00533
00534 id_type = idr[0];
00535 idr += 4;
00536 idr_len -= 4;
00537
00538 wpa_printf(MSG_DEBUG, "IKEV2: IDr ID Type %d", id_type);
00539 wpa_hexdump_ascii(MSG_DEBUG, "IKEV2: IDr", idr, idr_len);
00540 if (data->IDr) {
00541 if (id_type != data->IDr_type || idr_len != data->IDr_len ||
00542 os_memcmp(idr, data->IDr, idr_len) != 0) {
00543 wpa_printf(MSG_INFO, "IKEV2: IDr differs from the one "
00544 "received earlier");
00545 wpa_printf(MSG_DEBUG, "IKEV2: Previous IDr ID Type %d",
00546 id_type);
00547 wpa_hexdump_ascii(MSG_DEBUG, "Previous IKEV2: IDr",
00548 data->IDr, data->IDr_len);
00549 return -1;
00550 }
00551 os_free(data->IDr);
00552 }
00553 data->IDr = os_malloc(idr_len);
00554 if (data->IDr == NULL)
00555 return -1;
00556 os_memcpy(data->IDr, idr, idr_len);
00557 data->IDr_len = idr_len;
00558 data->IDr_type = id_type;
00559
00560 return 0;
00561 }
00562
00563
00564 static int ikev2_process_cert(struct ikev2_initiator_data *data,
00565 const u8 *cert, size_t cert_len)
00566 {
00567 u8 cert_encoding;
00568
00569 if (cert == NULL) {
00570 if (data->peer_auth == PEER_AUTH_CERT) {
00571 wpa_printf(MSG_INFO, "IKEV2: No Certificate received");
00572 return -1;
00573 }
00574 return 0;
00575 }
00576
00577 if (cert_len < 1) {
00578 wpa_printf(MSG_INFO, "IKEV2: No Cert Encoding field");
00579 return -1;
00580 }
00581
00582 cert_encoding = cert[0];
00583 cert++;
00584 cert_len--;
00585
00586 wpa_printf(MSG_DEBUG, "IKEV2: Cert Encoding %d", cert_encoding);
00587 wpa_hexdump(MSG_MSGDUMP, "IKEV2: Certificate Data", cert, cert_len);
00588
00589
00590
00591 return 0;
00592 }
00593
00594
00595 static int ikev2_process_auth_cert(struct ikev2_initiator_data *data,
00596 u8 method, const u8 *auth, size_t auth_len)
00597 {
00598 if (method != AUTH_RSA_SIGN) {
00599 wpa_printf(MSG_INFO, "IKEV2: Unsupported authentication "
00600 "method %d", method);
00601 return -1;
00602 }
00603
00604
00605 return 0;
00606 }
00607
00608
00609 static int ikev2_process_auth_secret(struct ikev2_initiator_data *data,
00610 u8 method, const u8 *auth,
00611 size_t auth_len)
00612 {
00613 u8 auth_data[IKEV2_MAX_HASH_LEN];
00614 const struct ikev2_prf_alg *prf;
00615
00616 if (method != AUTH_SHARED_KEY_MIC) {
00617 wpa_printf(MSG_INFO, "IKEV2: Unsupported authentication "
00618 "method %d", method);
00619 return -1;
00620 }
00621
00622
00623 if (ikev2_derive_auth_data(data->proposal.prf, data->r_sign_msg,
00624 data->IDr, data->IDr_len, data->IDr_type,
00625 &data->keys, 0, data->shared_secret,
00626 data->shared_secret_len,
00627 data->i_nonce, data->i_nonce_len,
00628 data->key_pad, data->key_pad_len,
00629 auth_data) < 0) {
00630 wpa_printf(MSG_INFO, "IKEV2: Could not derive AUTH data");
00631 return -1;
00632 }
00633
00634 wpabuf_free(data->r_sign_msg);
00635 data->r_sign_msg = NULL;
00636
00637 prf = ikev2_get_prf(data->proposal.prf);
00638 if (prf == NULL)
00639 return -1;
00640
00641 if (auth_len != prf->hash_len ||
00642 os_memcmp(auth, auth_data, auth_len) != 0) {
00643 wpa_printf(MSG_INFO, "IKEV2: Invalid Authentication Data");
00644 wpa_hexdump(MSG_DEBUG, "IKEV2: Received Authentication Data",
00645 auth, auth_len);
00646 wpa_hexdump(MSG_DEBUG, "IKEV2: Expected Authentication Data",
00647 auth_data, prf->hash_len);
00648 return -1;
00649 }
00650
00651 wpa_printf(MSG_DEBUG, "IKEV2: Peer authenticated successfully "
00652 "using shared keys");
00653
00654 return 0;
00655 }
00656
00657
00658 static int ikev2_process_auth(struct ikev2_initiator_data *data,
00659 const u8 *auth, size_t auth_len)
00660 {
00661 u8 auth_method;
00662
00663 if (auth == NULL) {
00664 wpa_printf(MSG_INFO, "IKEV2: No Authentication Payload");
00665 return -1;
00666 }
00667
00668 if (auth_len < 4) {
00669 wpa_printf(MSG_INFO, "IKEV2: Too short Authentication "
00670 "Payload");
00671 return -1;
00672 }
00673
00674 auth_method = auth[0];
00675 auth += 4;
00676 auth_len -= 4;
00677
00678 wpa_printf(MSG_DEBUG, "IKEV2: Auth Method %d", auth_method);
00679 wpa_hexdump(MSG_MSGDUMP, "IKEV2: Authentication Data", auth, auth_len);
00680
00681 switch (data->peer_auth) {
00682 case PEER_AUTH_CERT:
00683 return ikev2_process_auth_cert(data, auth_method, auth,
00684 auth_len);
00685 case PEER_AUTH_SECRET:
00686 return ikev2_process_auth_secret(data, auth_method, auth,
00687 auth_len);
00688 }
00689
00690 return -1;
00691 }
00692
00693
00694 static int ikev2_process_sa_auth_decrypted(struct ikev2_initiator_data *data,
00695 u8 next_payload,
00696 u8 *payload, size_t payload_len)
00697 {
00698 struct ikev2_payloads pl;
00699
00700 wpa_printf(MSG_DEBUG, "IKEV2: Processing decrypted payloads");
00701
00702 if (ikev2_parse_payloads(&pl, next_payload, payload, payload +
00703 payload_len) < 0) {
00704 wpa_printf(MSG_INFO, "IKEV2: Failed to parse decrypted "
00705 "payloads");
00706 return -1;
00707 }
00708
00709 if (ikev2_process_idr(data, pl.idr, pl.idr_len) < 0 ||
00710 ikev2_process_cert(data, pl.cert, pl.cert_len) < 0 ||
00711 ikev2_process_auth(data, pl.auth, pl.auth_len) < 0)
00712 return -1;
00713
00714 return 0;
00715 }
00716
00717
00718 static int ikev2_process_sa_auth(struct ikev2_initiator_data *data,
00719 const struct ikev2_hdr *hdr,
00720 struct ikev2_payloads *pl)
00721 {
00722 u8 *decrypted;
00723 size_t decrypted_len;
00724 int ret;
00725
00726 decrypted = ikev2_decrypt_payload(data->proposal.encr,
00727 data->proposal.integ,
00728 &data->keys, 0, hdr, pl->encrypted,
00729 pl->encrypted_len, &decrypted_len);
00730 if (decrypted == NULL)
00731 return -1;
00732
00733 ret = ikev2_process_sa_auth_decrypted(data, pl->encr_next_payload,
00734 decrypted, decrypted_len);
00735 os_free(decrypted);
00736
00737 if (ret == 0 && !data->unknown_user) {
00738 wpa_printf(MSG_DEBUG, "IKEV2: Authentication completed");
00739 data->state = IKEV2_DONE;
00740 }
00741
00742 return ret;
00743 }
00744
00745
00746 static int ikev2_validate_rx_state(struct ikev2_initiator_data *data,
00747 u8 exchange_type, u32 message_id)
00748 {
00749 switch (data->state) {
00750 case SA_INIT:
00751
00752
00753 if (exchange_type != IKE_SA_INIT) {
00754 wpa_printf(MSG_INFO, "IKEV2: Unexpected Exchange Type "
00755 "%u in SA_INIT state", exchange_type);
00756 return -1;
00757 }
00758 if (message_id != 0) {
00759 wpa_printf(MSG_INFO, "IKEV2: Unexpected Message ID %u "
00760 "in SA_INIT state", message_id);
00761 return -1;
00762 }
00763 break;
00764 case SA_AUTH:
00765
00766
00767
00768 if (exchange_type != IKE_SA_AUTH) {
00769 wpa_printf(MSG_INFO, "IKEV2: Unexpected Exchange Type "
00770 "%u in SA_AUTH state", exchange_type);
00771 return -1;
00772 }
00773 if (message_id != 1) {
00774 wpa_printf(MSG_INFO, "IKEV2: Unexpected Message ID %u "
00775 "in SA_AUTH state", message_id);
00776 return -1;
00777 }
00778 break;
00779 case CHILD_SA:
00780 if (exchange_type != CREATE_CHILD_SA) {
00781 wpa_printf(MSG_INFO, "IKEV2: Unexpected Exchange Type "
00782 "%u in CHILD_SA state", exchange_type);
00783 return -1;
00784 }
00785 if (message_id != 2) {
00786 wpa_printf(MSG_INFO, "IKEV2: Unexpected Message ID %u "
00787 "in CHILD_SA state", message_id);
00788 return -1;
00789 }
00790 break;
00791 case IKEV2_DONE:
00792 return -1;
00793 }
00794
00795 return 0;
00796 }
00797
00798
00799 int ikev2_initiator_process(struct ikev2_initiator_data *data,
00800 const struct wpabuf *buf)
00801 {
00802 const struct ikev2_hdr *hdr;
00803 u32 length, message_id;
00804 const u8 *pos, *end;
00805 struct ikev2_payloads pl;
00806
00807 wpa_printf(MSG_MSGDUMP, "IKEV2: Received message (len %lu)",
00808 (unsigned long) wpabuf_len(buf));
00809
00810 if (wpabuf_len(buf) < sizeof(*hdr)) {
00811 wpa_printf(MSG_INFO, "IKEV2: Too short frame to include HDR");
00812 return -1;
00813 }
00814
00815 hdr = (const struct ikev2_hdr *) wpabuf_head(buf);
00816 end = wpabuf_head_u8(buf) + wpabuf_len(buf);
00817 message_id = WPA_GET_BE32(hdr->message_id);
00818 length = WPA_GET_BE32(hdr->length);
00819
00820 wpa_hexdump(MSG_DEBUG, "IKEV2: IKE_SA Initiator's SPI",
00821 hdr->i_spi, IKEV2_SPI_LEN);
00822 wpa_hexdump(MSG_DEBUG, "IKEV2: IKE_SA Initiator's SPI",
00823 hdr->r_spi, IKEV2_SPI_LEN);
00824 wpa_printf(MSG_DEBUG, "IKEV2: Next Payload: %u Version: 0x%x "
00825 "Exchange Type: %u",
00826 hdr->next_payload, hdr->version, hdr->exchange_type);
00827 wpa_printf(MSG_DEBUG, "IKEV2: Message ID: %u Length: %u",
00828 message_id, length);
00829
00830 if (hdr->version != IKEV2_VERSION) {
00831 wpa_printf(MSG_INFO, "IKEV2: Unsupported HDR version 0x%x "
00832 "(expected 0x%x)", hdr->version, IKEV2_VERSION);
00833 return -1;
00834 }
00835
00836 if (length != wpabuf_len(buf)) {
00837 wpa_printf(MSG_INFO, "IKEV2: Invalid length (HDR: %lu != "
00838 "RX: %lu)", (unsigned long) length,
00839 (unsigned long) wpabuf_len(buf));
00840 return -1;
00841 }
00842
00843 if (ikev2_validate_rx_state(data, hdr->exchange_type, message_id) < 0)
00844 return -1;
00845
00846 if ((hdr->flags & (IKEV2_HDR_INITIATOR | IKEV2_HDR_RESPONSE)) !=
00847 IKEV2_HDR_RESPONSE) {
00848 wpa_printf(MSG_INFO, "IKEV2: Unexpected Flags value 0x%x",
00849 hdr->flags);
00850 return -1;
00851 }
00852
00853 if (data->state != SA_INIT) {
00854 if (os_memcmp(data->i_spi, hdr->i_spi, IKEV2_SPI_LEN) != 0) {
00855 wpa_printf(MSG_INFO, "IKEV2: Unexpected IKE_SA "
00856 "Initiator's SPI");
00857 return -1;
00858 }
00859 if (os_memcmp(data->r_spi, hdr->r_spi, IKEV2_SPI_LEN) != 0) {
00860 wpa_printf(MSG_INFO, "IKEV2: Unexpected IKE_SA "
00861 "Responder's SPI");
00862 return -1;
00863 }
00864 }
00865
00866 pos = (const u8 *) (hdr + 1);
00867 if (ikev2_parse_payloads(&pl, hdr->next_payload, pos, end) < 0)
00868 return -1;
00869
00870 switch (data->state) {
00871 case SA_INIT:
00872 if (ikev2_process_sa_init(data, hdr, &pl) < 0)
00873 return -1;
00874 wpabuf_free(data->r_sign_msg);
00875 data->r_sign_msg = wpabuf_dup(buf);
00876 break;
00877 case SA_AUTH:
00878 if (ikev2_process_sa_auth(data, hdr, &pl) < 0)
00879 return -1;
00880 break;
00881 case CHILD_SA:
00882 case IKEV2_DONE:
00883 break;
00884 }
00885
00886 return 0;
00887 }
00888
00889
00890 static void ikev2_build_hdr(struct ikev2_initiator_data *data,
00891 struct wpabuf *msg, u8 exchange_type,
00892 u8 next_payload, u32 message_id)
00893 {
00894 struct ikev2_hdr *hdr;
00895
00896 wpa_printf(MSG_DEBUG, "IKEV2: Adding HDR");
00897
00898
00899 hdr = wpabuf_put(msg, sizeof(*hdr));
00900 os_memcpy(hdr->i_spi, data->i_spi, IKEV2_SPI_LEN);
00901 os_memcpy(hdr->r_spi, data->r_spi, IKEV2_SPI_LEN);
00902 hdr->next_payload = next_payload;
00903 hdr->version = IKEV2_VERSION;
00904 hdr->exchange_type = exchange_type;
00905 hdr->flags = IKEV2_HDR_INITIATOR;
00906 WPA_PUT_BE32(hdr->message_id, message_id);
00907 }
00908
00909
00910 static int ikev2_build_sai(struct ikev2_initiator_data *data,
00911 struct wpabuf *msg, u8 next_payload)
00912 {
00913 struct ikev2_payload_hdr *phdr;
00914 size_t plen;
00915 struct ikev2_proposal *p;
00916 struct ikev2_transform *t;
00917
00918 wpa_printf(MSG_DEBUG, "IKEV2: Adding SAi payload");
00919
00920
00921 phdr = wpabuf_put(msg, sizeof(*phdr));
00922 phdr->next_payload = next_payload;
00923 phdr->flags = 0;
00924
00925
00926 p = wpabuf_put(msg, sizeof(*p));
00927 p->proposal_num = data->proposal.proposal_num;
00928 p->protocol_id = IKEV2_PROTOCOL_IKE;
00929 p->num_transforms = 4;
00930
00931 t = wpabuf_put(msg, sizeof(*t));
00932 t->type = 3;
00933 t->transform_type = IKEV2_TRANSFORM_ENCR;
00934 WPA_PUT_BE16(t->transform_id, data->proposal.encr);
00935 if (data->proposal.encr == ENCR_AES_CBC) {
00936
00937 wpabuf_put_be16(msg, 0x800e);
00938 wpabuf_put_be16(msg, 128);
00939 }
00940 plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) t;
00941 WPA_PUT_BE16(t->transform_length, plen);
00942
00943 t = wpabuf_put(msg, sizeof(*t));
00944 t->type = 3;
00945 WPA_PUT_BE16(t->transform_length, sizeof(*t));
00946 t->transform_type = IKEV2_TRANSFORM_PRF;
00947 WPA_PUT_BE16(t->transform_id, data->proposal.prf);
00948
00949 t = wpabuf_put(msg, sizeof(*t));
00950 t->type = 3;
00951 WPA_PUT_BE16(t->transform_length, sizeof(*t));
00952 t->transform_type = IKEV2_TRANSFORM_INTEG;
00953 WPA_PUT_BE16(t->transform_id, data->proposal.integ);
00954
00955 t = wpabuf_put(msg, sizeof(*t));
00956 WPA_PUT_BE16(t->transform_length, sizeof(*t));
00957 t->transform_type = IKEV2_TRANSFORM_DH;
00958 WPA_PUT_BE16(t->transform_id, data->proposal.dh);
00959
00960 plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) p;
00961 WPA_PUT_BE16(p->proposal_length, plen);
00962
00963 plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) phdr;
00964 WPA_PUT_BE16(phdr->payload_length, plen);
00965
00966 return 0;
00967 }
00968
00969
00970 static int ikev2_build_kei(struct ikev2_initiator_data *data,
00971 struct wpabuf *msg, u8 next_payload)
00972 {
00973 struct ikev2_payload_hdr *phdr;
00974 size_t plen;
00975 struct wpabuf *pv;
00976
00977 wpa_printf(MSG_DEBUG, "IKEV2: Adding KEi payload");
00978
00979 data->dh = dh_groups_get(data->proposal.dh);
00980 pv = dh_init(data->dh, &data->i_dh_private);
00981 if (pv == NULL) {
00982 wpa_printf(MSG_DEBUG, "IKEV2: Failed to initialize DH");
00983 return -1;
00984 }
00985
00986
00987 phdr = wpabuf_put(msg, sizeof(*phdr));
00988 phdr->next_payload = next_payload;
00989 phdr->flags = 0;
00990
00991 wpabuf_put_be16(msg, data->proposal.dh);
00992 wpabuf_put(msg, 2);
00993
00994
00995
00996
00997 wpabuf_put(msg, data->dh->prime_len - wpabuf_len(pv));
00998 wpabuf_put_buf(msg, pv);
00999 os_free(pv);
01000
01001 plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) phdr;
01002 WPA_PUT_BE16(phdr->payload_length, plen);
01003 return 0;
01004 }
01005
01006
01007 static int ikev2_build_ni(struct ikev2_initiator_data *data,
01008 struct wpabuf *msg, u8 next_payload)
01009 {
01010 struct ikev2_payload_hdr *phdr;
01011 size_t plen;
01012
01013 wpa_printf(MSG_DEBUG, "IKEV2: Adding Ni payload");
01014
01015
01016 phdr = wpabuf_put(msg, sizeof(*phdr));
01017 phdr->next_payload = next_payload;
01018 phdr->flags = 0;
01019 wpabuf_put_data(msg, data->i_nonce, data->i_nonce_len);
01020 plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) phdr;
01021 WPA_PUT_BE16(phdr->payload_length, plen);
01022 return 0;
01023 }
01024
01025
01026 static int ikev2_build_idi(struct ikev2_initiator_data *data,
01027 struct wpabuf *msg, u8 next_payload)
01028 {
01029 struct ikev2_payload_hdr *phdr;
01030 size_t plen;
01031
01032 wpa_printf(MSG_DEBUG, "IKEV2: Adding IDi payload");
01033
01034 if (data->IDi == NULL) {
01035 wpa_printf(MSG_INFO, "IKEV2: No IDi available");
01036 return -1;
01037 }
01038
01039
01040 phdr = wpabuf_put(msg, sizeof(*phdr));
01041 phdr->next_payload = next_payload;
01042 phdr->flags = 0;
01043 wpabuf_put_u8(msg, ID_KEY_ID);
01044 wpabuf_put(msg, 3);
01045 wpabuf_put_data(msg, data->IDi, data->IDi_len);
01046 plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) phdr;
01047 WPA_PUT_BE16(phdr->payload_length, plen);
01048 return 0;
01049 }
01050
01051
01052 static int ikev2_build_auth(struct ikev2_initiator_data *data,
01053 struct wpabuf *msg, u8 next_payload)
01054 {
01055 struct ikev2_payload_hdr *phdr;
01056 size_t plen;
01057 const struct ikev2_prf_alg *prf;
01058
01059 wpa_printf(MSG_DEBUG, "IKEV2: Adding AUTH payload");
01060
01061 prf = ikev2_get_prf(data->proposal.prf);
01062 if (prf == NULL)
01063 return -1;
01064
01065
01066 phdr = wpabuf_put(msg, sizeof(*phdr));
01067 phdr->next_payload = next_payload;
01068 phdr->flags = 0;
01069 wpabuf_put_u8(msg, AUTH_SHARED_KEY_MIC);
01070 wpabuf_put(msg, 3);
01071
01072
01073 if (ikev2_derive_auth_data(data->proposal.prf, data->i_sign_msg,
01074 data->IDi, data->IDi_len, ID_KEY_ID,
01075 &data->keys, 1, data->shared_secret,
01076 data->shared_secret_len,
01077 data->r_nonce, data->r_nonce_len,
01078 data->key_pad, data->key_pad_len,
01079 wpabuf_put(msg, prf->hash_len)) < 0) {
01080 wpa_printf(MSG_INFO, "IKEV2: Could not derive AUTH data");
01081 return -1;
01082 }
01083 wpabuf_free(data->i_sign_msg);
01084 data->i_sign_msg = NULL;
01085
01086 plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) phdr;
01087 WPA_PUT_BE16(phdr->payload_length, plen);
01088 return 0;
01089 }
01090
01091
01092 static struct wpabuf * ikev2_build_sa_init(struct ikev2_initiator_data *data)
01093 {
01094 struct wpabuf *msg;
01095
01096
01097
01098 if (os_get_random(data->i_spi, IKEV2_SPI_LEN))
01099 return NULL;
01100 wpa_hexdump(MSG_DEBUG, "IKEV2: IKE_SA Initiator's SPI",
01101 data->i_spi, IKEV2_SPI_LEN);
01102
01103 data->i_nonce_len = IKEV2_NONCE_MIN_LEN;
01104 if (os_get_random(data->i_nonce, data->i_nonce_len))
01105 return NULL;
01106 wpa_hexdump(MSG_DEBUG, "IKEV2: Ni", data->i_nonce, data->i_nonce_len);
01107
01108 msg = wpabuf_alloc(sizeof(struct ikev2_hdr) + 1000);
01109 if (msg == NULL)
01110 return NULL;
01111
01112 ikev2_build_hdr(data, msg, IKE_SA_INIT, IKEV2_PAYLOAD_SA, 0);
01113 if (ikev2_build_sai(data, msg, IKEV2_PAYLOAD_KEY_EXCHANGE) ||
01114 ikev2_build_kei(data, msg, IKEV2_PAYLOAD_NONCE) ||
01115 ikev2_build_ni(data, msg, IKEV2_PAYLOAD_NO_NEXT_PAYLOAD)) {
01116 wpabuf_free(msg);
01117 return NULL;
01118 }
01119
01120 ikev2_update_hdr(msg);
01121
01122 wpa_hexdump_buf(MSG_MSGDUMP, "IKEV2: Sending message (SA_INIT)", msg);
01123
01124 wpabuf_free(data->i_sign_msg);
01125 data->i_sign_msg = wpabuf_dup(msg);
01126
01127 return msg;
01128 }
01129
01130
01131 static struct wpabuf * ikev2_build_sa_auth(struct ikev2_initiator_data *data)
01132 {
01133 struct wpabuf *msg, *plain;
01134 const u8 *secret;
01135 size_t secret_len;
01136
01137 secret = data->get_shared_secret(data->cb_ctx, data->IDr,
01138 data->IDr_len, &secret_len);
01139 if (secret == NULL) {
01140 wpa_printf(MSG_INFO, "IKEV2: Could not get shared secret - "
01141 "use fake value");
01142
01143
01144
01145
01146 data->unknown_user = 1;
01147 os_free(data->shared_secret);
01148 data->shared_secret = os_malloc(16);
01149 if (data->shared_secret == NULL)
01150 return NULL;
01151 data->shared_secret_len = 16;
01152 if (os_get_random(data->shared_secret, 16))
01153 return NULL;
01154 } else {
01155 os_free(data->shared_secret);
01156 data->shared_secret = os_malloc(secret_len);
01157 if (data->shared_secret == NULL)
01158 return NULL;
01159 os_memcpy(data->shared_secret, secret, secret_len);
01160 data->shared_secret_len = secret_len;
01161 }
01162
01163
01164
01165 msg = wpabuf_alloc(sizeof(struct ikev2_hdr) + data->IDr_len + 1000);
01166 if (msg == NULL)
01167 return NULL;
01168 ikev2_build_hdr(data, msg, IKE_SA_AUTH, IKEV2_PAYLOAD_ENCRYPTED, 1);
01169
01170 plain = wpabuf_alloc(data->IDr_len + 1000);
01171 if (plain == NULL) {
01172 wpabuf_free(msg);
01173 return NULL;
01174 }
01175
01176 if (ikev2_build_idi(data, plain, IKEV2_PAYLOAD_AUTHENTICATION) ||
01177 ikev2_build_auth(data, plain, IKEV2_PAYLOAD_NO_NEXT_PAYLOAD) ||
01178 ikev2_build_encrypted(data->proposal.encr, data->proposal.integ,
01179 &data->keys, 1, msg, plain,
01180 IKEV2_PAYLOAD_IDi)) {
01181 wpabuf_free(plain);
01182 wpabuf_free(msg);
01183 return NULL;
01184 }
01185 wpabuf_free(plain);
01186
01187 wpa_hexdump_buf(MSG_MSGDUMP, "IKEV2: Sending message (SA_AUTH)", msg);
01188
01189 return msg;
01190 }
01191
01192
01193 struct wpabuf * ikev2_initiator_build(struct ikev2_initiator_data *data)
01194 {
01195 switch (data->state) {
01196 case SA_INIT:
01197 return ikev2_build_sa_init(data);
01198 case SA_AUTH:
01199 return ikev2_build_sa_auth(data);
01200 case CHILD_SA:
01201 return NULL;
01202 case IKEV2_DONE:
01203 return NULL;
01204 }
01205 return NULL;
01206 }
01207