2
* IKEv2 initiator (RFC 4306) for EAP-IKEV2
3
* Copyright (c) 2007, Jouni Malinen <j@w1.fi>
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License version 2 as
7
* published by the Free Software Foundation.
9
* Alternatively, this software may be distributed under the terms of BSD
12
* See README and COPYING for more details.
18
#include "dh_groups.h"
22
static int ikev2_process_idr(struct ikev2_initiator_data *data,
23
const u8 *idr, size_t idr_len);
26
void ikev2_initiator_deinit(struct ikev2_initiator_data *data)
28
ikev2_free_keys(&data->keys);
29
wpabuf_free(data->r_dh_public);
30
wpabuf_free(data->i_dh_private);
33
os_free(data->shared_secret);
34
wpabuf_free(data->i_sign_msg);
35
wpabuf_free(data->r_sign_msg);
36
os_free(data->key_pad);
40
static int ikev2_derive_keys(struct ikev2_initiator_data *data)
42
u8 *buf, *pos, *pad, skeyseed[IKEV2_MAX_HASH_LEN];
43
size_t buf_len, pad_len;
44
struct wpabuf *shared;
45
const struct ikev2_integ_alg *integ;
46
const struct ikev2_prf_alg *prf;
47
const struct ikev2_encr_alg *encr;
52
/* RFC 4306, Sect. 2.14 */
54
integ = ikev2_get_integ(data->proposal.integ);
55
prf = ikev2_get_prf(data->proposal.prf);
56
encr = ikev2_get_encr(data->proposal.encr);
57
if (integ == NULL || prf == NULL || encr == NULL) {
58
wpa_printf(MSG_INFO, "IKEV2: Unsupported proposal");
62
shared = dh_derive_shared(data->r_dh_public, data->i_dh_private,
67
/* Construct Ni | Nr | SPIi | SPIr */
69
buf_len = data->i_nonce_len + data->r_nonce_len + 2 * IKEV2_SPI_LEN;
70
buf = os_malloc(buf_len);
77
os_memcpy(pos, data->i_nonce, data->i_nonce_len);
78
pos += data->i_nonce_len;
79
os_memcpy(pos, data->r_nonce, data->r_nonce_len);
80
pos += data->r_nonce_len;
81
os_memcpy(pos, data->i_spi, IKEV2_SPI_LEN);
83
os_memcpy(pos, data->r_spi, IKEV2_SPI_LEN);
85
/* SKEYSEED = prf(Ni | Nr, g^ir) */
87
/* Use zero-padding per RFC 4306, Sect. 2.14 */
88
pad_len = data->dh->prime_len - wpabuf_len(shared);
89
pad = os_zalloc(pad_len ? pad_len : 1);
97
addr[1] = wpabuf_head(shared);
98
len[1] = wpabuf_len(shared);
99
if (ikev2_prf_hash(prf->id, buf, data->i_nonce_len + data->r_nonce_len,
100
2, addr, len, skeyseed) < 0) {
109
/* DH parameters are not needed anymore, so free them */
110
wpabuf_free(data->r_dh_public);
111
data->r_dh_public = NULL;
112
wpabuf_free(data->i_dh_private);
113
data->i_dh_private = NULL;
115
wpa_hexdump_key(MSG_DEBUG, "IKEV2: SKEYSEED",
116
skeyseed, prf->hash_len);
118
ret = ikev2_derive_sk_keys(prf, integ, encr, skeyseed, buf, buf_len,
125
static int ikev2_parse_transform(struct ikev2_initiator_data *data,
126
struct ikev2_proposal_data *prop,
127
const u8 *pos, const u8 *end)
130
const struct ikev2_transform *t;
134
if (end - pos < (int) sizeof(*t)) {
135
wpa_printf(MSG_INFO, "IKEV2: Too short transform");
139
t = (const struct ikev2_transform *) pos;
140
transform_len = WPA_GET_BE16(t->transform_length);
141
if (transform_len < (int) sizeof(*t) || pos + transform_len > end) {
142
wpa_printf(MSG_INFO, "IKEV2: Invalid transform length %d",
146
tend = pos + transform_len;
148
transform_id = WPA_GET_BE16(t->transform_id);
150
wpa_printf(MSG_DEBUG, "IKEV2: Transform:");
151
wpa_printf(MSG_DEBUG, "IKEV2: Type: %d Transform Length: %d "
152
"Transform Type: %d Transform ID: %d",
153
t->type, transform_len, t->transform_type, transform_id);
155
if (t->type != 0 && t->type != 3) {
156
wpa_printf(MSG_INFO, "IKEV2: Unexpected Transform type");
160
pos = (const u8 *) (t + 1);
162
wpa_hexdump(MSG_DEBUG, "IKEV2: Transform Attributes",
166
switch (t->transform_type) {
167
case IKEV2_TRANSFORM_ENCR:
168
if (ikev2_get_encr(transform_id) &&
169
transform_id == data->proposal.encr) {
170
if (transform_id == ENCR_AES_CBC) {
171
if (tend - pos != 4) {
172
wpa_printf(MSG_DEBUG, "IKEV2: No "
173
"Transform Attr for AES");
176
if (WPA_GET_BE16(pos) != 0x800e) {
177
wpa_printf(MSG_DEBUG, "IKEV2: Not a "
178
"Key Size attribute for "
182
if (WPA_GET_BE16(pos + 2) != 128) {
183
wpa_printf(MSG_DEBUG, "IKEV2: "
184
"Unsupported AES key size "
186
WPA_GET_BE16(pos + 2));
190
prop->encr = transform_id;
193
case IKEV2_TRANSFORM_PRF:
194
if (ikev2_get_prf(transform_id) &&
195
transform_id == data->proposal.prf)
196
prop->prf = transform_id;
198
case IKEV2_TRANSFORM_INTEG:
199
if (ikev2_get_integ(transform_id) &&
200
transform_id == data->proposal.integ)
201
prop->integ = transform_id;
203
case IKEV2_TRANSFORM_DH:
204
if (dh_groups_get(transform_id) &&
205
transform_id == data->proposal.dh)
206
prop->dh = transform_id;
210
return transform_len;
214
static int ikev2_parse_proposal(struct ikev2_initiator_data *data,
215
struct ikev2_proposal_data *prop,
216
const u8 *pos, const u8 *end)
218
const u8 *pend, *ppos;
220
const struct ikev2_proposal *p;
222
if (end - pos < (int) sizeof(*p)) {
223
wpa_printf(MSG_INFO, "IKEV2: Too short proposal");
227
p = (const struct ikev2_proposal *) pos;
228
proposal_len = WPA_GET_BE16(p->proposal_length);
229
if (proposal_len < (int) sizeof(*p) || pos + proposal_len > end) {
230
wpa_printf(MSG_INFO, "IKEV2: Invalid proposal length %d",
234
wpa_printf(MSG_DEBUG, "IKEV2: SAi1 Proposal # %d",
236
wpa_printf(MSG_DEBUG, "IKEV2: Type: %d Proposal Length: %d "
238
p->type, proposal_len, p->protocol_id);
239
wpa_printf(MSG_DEBUG, "IKEV2: SPI Size: %d Transforms: %d",
240
p->spi_size, p->num_transforms);
242
if (p->type != 0 && p->type != 2) {
243
wpa_printf(MSG_INFO, "IKEV2: Unexpected Proposal type");
247
if (p->protocol_id != IKEV2_PROTOCOL_IKE) {
248
wpa_printf(MSG_DEBUG, "IKEV2: Unexpected Protocol ID "
249
"(only IKE allowed for EAP-IKEv2)");
253
if (p->proposal_num != prop->proposal_num) {
254
if (p->proposal_num == prop->proposal_num + 1)
255
prop->proposal_num = p->proposal_num;
257
wpa_printf(MSG_INFO, "IKEV2: Unexpected Proposal #");
262
ppos = (const u8 *) (p + 1);
263
pend = pos + proposal_len;
264
if (ppos + p->spi_size > pend) {
265
wpa_printf(MSG_INFO, "IKEV2: Not enough room for SPI "
270
wpa_hexdump(MSG_DEBUG, "IKEV2: SPI",
276
* For initial IKE_SA negotiation, SPI Size MUST be zero; for
277
* subsequent negotiations, it must be 8 for IKE. We only support
278
* initial case for now.
280
if (p->spi_size != 0) {
281
wpa_printf(MSG_INFO, "IKEV2: Unexpected SPI Size");
285
if (p->num_transforms == 0) {
286
wpa_printf(MSG_INFO, "IKEV2: At least one transform required");
290
for (i = 0; i < (int) p->num_transforms; i++) {
291
int tlen = ikev2_parse_transform(data, prop, ppos, pend);
298
wpa_printf(MSG_INFO, "IKEV2: Unexpected data after "
307
static int ikev2_process_sar1(struct ikev2_initiator_data *data,
308
const u8 *sar1, size_t sar1_len)
310
struct ikev2_proposal_data prop;
314
/* Security Association Payloads: <Proposals> */
317
wpa_printf(MSG_INFO, "IKEV2: SAr1 not received");
321
os_memset(&prop, 0, sizeof(prop));
322
prop.proposal_num = 1;
325
end = sar1 + sar1_len;
334
plen = ikev2_parse_proposal(data, &prop, pos, end);
338
if (!found && prop.integ != -1 && prop.prf != -1 &&
339
prop.encr != -1 && prop.dh != -1) {
345
/* Only one proposal expected in SAr */
350
wpa_printf(MSG_INFO, "IKEV2: Unexpected data after proposal");
355
wpa_printf(MSG_INFO, "IKEV2: No acceptable proposal found");
359
wpa_printf(MSG_DEBUG, "IKEV2: Accepted proposal #%d: ENCR:%d PRF:%d "
360
"INTEG:%d D-H:%d", data->proposal.proposal_num,
361
data->proposal.encr, data->proposal.prf,
362
data->proposal.integ, data->proposal.dh);
368
static int ikev2_process_ker(struct ikev2_initiator_data *data,
369
const u8 *ker, size_t ker_len)
374
* Key Exchange Payload:
375
* DH Group # (16 bits)
377
* Key Exchange Data (Diffie-Hellman public value)
381
wpa_printf(MSG_INFO, "IKEV2: KEr not received");
385
if (ker_len < 4 + 96) {
386
wpa_printf(MSG_INFO, "IKEV2: Too show Key Exchange Payload");
390
group = WPA_GET_BE16(ker);
391
wpa_printf(MSG_DEBUG, "IKEV2: KEr DH Group #%u", group);
393
if (group != data->proposal.dh) {
394
wpa_printf(MSG_DEBUG, "IKEV2: KEr DH Group #%u does not match "
395
"with the selected proposal (%u)",
396
group, data->proposal.dh);
400
if (data->dh == NULL) {
401
wpa_printf(MSG_INFO, "IKEV2: Unsupported DH group");
405
/* RFC 4306, Section 3.4:
406
* The length of DH public value MUST be equal to the lenght of the
409
if (ker_len - 4 != data->dh->prime_len) {
410
wpa_printf(MSG_INFO, "IKEV2: Invalid DH public value length "
411
"%ld (expected %ld)",
412
(long) (ker_len - 4), (long) data->dh->prime_len);
416
wpabuf_free(data->r_dh_public);
417
data->r_dh_public = wpabuf_alloc_copy(ker + 4, ker_len - 4);
418
if (data->r_dh_public == NULL)
421
wpa_hexdump_buf(MSG_DEBUG, "IKEV2: KEr Diffie-Hellman Public Value",
428
static int ikev2_process_nr(struct ikev2_initiator_data *data,
429
const u8 *nr, size_t nr_len)
432
wpa_printf(MSG_INFO, "IKEV2: Nr not received");
436
if (nr_len < IKEV2_NONCE_MIN_LEN || nr_len > IKEV2_NONCE_MAX_LEN) {
437
wpa_printf(MSG_INFO, "IKEV2: Invalid Nr length %ld",
442
data->r_nonce_len = nr_len;
443
os_memcpy(data->r_nonce, nr, nr_len);
444
wpa_hexdump(MSG_MSGDUMP, "IKEV2: Nr",
445
data->r_nonce, data->r_nonce_len);
451
static int ikev2_process_sa_init_encr(struct ikev2_initiator_data *data,
452
const struct ikev2_hdr *hdr,
454
size_t encrypted_len, u8 next_payload)
457
size_t decrypted_len;
458
struct ikev2_payloads pl;
461
decrypted = ikev2_decrypt_payload(data->proposal.encr,
462
data->proposal.integ, &data->keys, 0,
463
hdr, encrypted, encrypted_len,
465
if (decrypted == NULL)
468
wpa_printf(MSG_DEBUG, "IKEV2: Processing decrypted payloads");
470
if (ikev2_parse_payloads(&pl, next_payload, decrypted,
471
decrypted + decrypted_len) < 0) {
472
wpa_printf(MSG_INFO, "IKEV2: Failed to parse decrypted "
478
ret = ikev2_process_idr(data, pl.idr, pl.idr_len);
486
static int ikev2_process_sa_init(struct ikev2_initiator_data *data,
487
const struct ikev2_hdr *hdr,
488
struct ikev2_payloads *pl)
490
if (ikev2_process_sar1(data, pl->sa, pl->sa_len) < 0 ||
491
ikev2_process_ker(data, pl->ke, pl->ke_len) < 0 ||
492
ikev2_process_nr(data, pl->nonce, pl->nonce_len) < 0)
495
os_memcpy(data->r_spi, hdr->r_spi, IKEV2_SPI_LEN);
497
if (ikev2_derive_keys(data) < 0)
501
wpa_printf(MSG_DEBUG, "IKEV2: Encrypted payload in SA_INIT - "
502
"try to get IDr from it");
503
if (ikev2_process_sa_init_encr(data, hdr, pl->encrypted,
505
pl->encr_next_payload) < 0) {
506
wpa_printf(MSG_INFO, "IKEV2: Failed to process "
507
"encrypted payload");
512
data->state = SA_AUTH;
518
static int ikev2_process_idr(struct ikev2_initiator_data *data,
519
const u8 *idr, size_t idr_len)
524
wpa_printf(MSG_INFO, "IKEV2: No IDr received");
529
wpa_printf(MSG_INFO, "IKEV2: Too short IDr payload");
537
wpa_printf(MSG_DEBUG, "IKEV2: IDr ID Type %d", id_type);
538
wpa_hexdump_ascii(MSG_DEBUG, "IKEV2: IDr", idr, idr_len);
540
if (id_type != data->IDr_type || idr_len != data->IDr_len ||
541
os_memcmp(idr, data->IDr, idr_len) != 0) {
542
wpa_printf(MSG_INFO, "IKEV2: IDr differs from the one "
544
wpa_printf(MSG_DEBUG, "IKEV2: Previous IDr ID Type %d",
546
wpa_hexdump_ascii(MSG_DEBUG, "Previous IKEV2: IDr",
547
data->IDr, data->IDr_len);
552
data->IDr = os_malloc(idr_len);
553
if (data->IDr == NULL)
555
os_memcpy(data->IDr, idr, idr_len);
556
data->IDr_len = idr_len;
557
data->IDr_type = id_type;
563
static int ikev2_process_cert(struct ikev2_initiator_data *data,
564
const u8 *cert, size_t cert_len)
569
if (data->peer_auth == PEER_AUTH_CERT) {
570
wpa_printf(MSG_INFO, "IKEV2: No Certificate received");
577
wpa_printf(MSG_INFO, "IKEV2: No Cert Encoding field");
581
cert_encoding = cert[0];
585
wpa_printf(MSG_DEBUG, "IKEV2: Cert Encoding %d", cert_encoding);
586
wpa_hexdump(MSG_MSGDUMP, "IKEV2: Certificate Data", cert, cert_len);
588
/* TODO: validate certificate */
594
static int ikev2_process_auth_cert(struct ikev2_initiator_data *data,
595
u8 method, const u8 *auth, size_t auth_len)
597
if (method != AUTH_RSA_SIGN) {
598
wpa_printf(MSG_INFO, "IKEV2: Unsupported authentication "
599
"method %d", method);
603
/* TODO: validate AUTH */
608
static int ikev2_process_auth_secret(struct ikev2_initiator_data *data,
609
u8 method, const u8 *auth,
612
u8 auth_data[IKEV2_MAX_HASH_LEN];
613
const struct ikev2_prf_alg *prf;
615
if (method != AUTH_SHARED_KEY_MIC) {
616
wpa_printf(MSG_INFO, "IKEV2: Unsupported authentication "
617
"method %d", method);
621
/* msg | Ni | prf(SK_pr,IDr') */
622
if (ikev2_derive_auth_data(data->proposal.prf, data->r_sign_msg,
623
data->IDr, data->IDr_len, data->IDr_type,
624
&data->keys, 0, data->shared_secret,
625
data->shared_secret_len,
626
data->i_nonce, data->i_nonce_len,
627
data->key_pad, data->key_pad_len,
629
wpa_printf(MSG_INFO, "IKEV2: Could not derive AUTH data");
633
wpabuf_free(data->r_sign_msg);
634
data->r_sign_msg = NULL;
636
prf = ikev2_get_prf(data->proposal.prf);
640
if (auth_len != prf->hash_len ||
641
os_memcmp(auth, auth_data, auth_len) != 0) {
642
wpa_printf(MSG_INFO, "IKEV2: Invalid Authentication Data");
643
wpa_hexdump(MSG_DEBUG, "IKEV2: Received Authentication Data",
645
wpa_hexdump(MSG_DEBUG, "IKEV2: Expected Authentication Data",
646
auth_data, prf->hash_len);
650
wpa_printf(MSG_DEBUG, "IKEV2: Peer authenticated successfully "
651
"using shared keys");
657
static int ikev2_process_auth(struct ikev2_initiator_data *data,
658
const u8 *auth, size_t auth_len)
663
wpa_printf(MSG_INFO, "IKEV2: No Authentication Payload");
668
wpa_printf(MSG_INFO, "IKEV2: Too short Authentication "
673
auth_method = auth[0];
677
wpa_printf(MSG_DEBUG, "IKEV2: Auth Method %d", auth_method);
678
wpa_hexdump(MSG_MSGDUMP, "IKEV2: Authentication Data", auth, auth_len);
680
switch (data->peer_auth) {
682
return ikev2_process_auth_cert(data, auth_method, auth,
684
case PEER_AUTH_SECRET:
685
return ikev2_process_auth_secret(data, auth_method, auth,
693
static int ikev2_process_sa_auth_decrypted(struct ikev2_initiator_data *data,
695
u8 *payload, size_t payload_len)
697
struct ikev2_payloads pl;
699
wpa_printf(MSG_DEBUG, "IKEV2: Processing decrypted payloads");
701
if (ikev2_parse_payloads(&pl, next_payload, payload, payload +
703
wpa_printf(MSG_INFO, "IKEV2: Failed to parse decrypted "
708
if (ikev2_process_idr(data, pl.idr, pl.idr_len) < 0 ||
709
ikev2_process_cert(data, pl.cert, pl.cert_len) < 0 ||
710
ikev2_process_auth(data, pl.auth, pl.auth_len) < 0)
717
static int ikev2_process_sa_auth(struct ikev2_initiator_data *data,
718
const struct ikev2_hdr *hdr,
719
struct ikev2_payloads *pl)
722
size_t decrypted_len;
725
decrypted = ikev2_decrypt_payload(data->proposal.encr,
726
data->proposal.integ,
727
&data->keys, 0, hdr, pl->encrypted,
728
pl->encrypted_len, &decrypted_len);
729
if (decrypted == NULL)
732
ret = ikev2_process_sa_auth_decrypted(data, pl->encr_next_payload,
733
decrypted, decrypted_len);
736
if (ret == 0 && !data->unknown_user) {
737
wpa_printf(MSG_DEBUG, "IKEV2: Authentication completed");
738
data->state = IKEV2_DONE;
745
static int ikev2_validate_rx_state(struct ikev2_initiator_data *data,
746
u8 exchange_type, u32 message_id)
748
switch (data->state) {
750
/* Expect to receive IKE_SA_INIT: HDR, SAr, KEr, Nr, [CERTREQ],
752
if (exchange_type != IKE_SA_INIT) {
753
wpa_printf(MSG_INFO, "IKEV2: Unexpected Exchange Type "
754
"%u in SA_INIT state", exchange_type);
757
if (message_id != 0) {
758
wpa_printf(MSG_INFO, "IKEV2: Unexpected Message ID %u "
759
"in SA_INIT state", message_id);
764
/* Expect to receive IKE_SA_AUTH:
765
* HDR, SK {IDr, [CERT,] [CERTREQ,] [NFID,] AUTH}
767
if (exchange_type != IKE_SA_AUTH) {
768
wpa_printf(MSG_INFO, "IKEV2: Unexpected Exchange Type "
769
"%u in SA_AUTH state", exchange_type);
772
if (message_id != 1) {
773
wpa_printf(MSG_INFO, "IKEV2: Unexpected Message ID %u "
774
"in SA_AUTH state", message_id);
779
if (exchange_type != CREATE_CHILD_SA) {
780
wpa_printf(MSG_INFO, "IKEV2: Unexpected Exchange Type "
781
"%u in CHILD_SA state", exchange_type);
784
if (message_id != 2) {
785
wpa_printf(MSG_INFO, "IKEV2: Unexpected Message ID %u "
786
"in CHILD_SA state", message_id);
798
int ikev2_initiator_process(struct ikev2_initiator_data *data,
799
const struct wpabuf *buf)
801
const struct ikev2_hdr *hdr;
802
u32 length, message_id;
804
struct ikev2_payloads pl;
806
wpa_printf(MSG_MSGDUMP, "IKEV2: Received message (len %lu)",
807
(unsigned long) wpabuf_len(buf));
809
if (wpabuf_len(buf) < sizeof(*hdr)) {
810
wpa_printf(MSG_INFO, "IKEV2: Too short frame to include HDR");
814
hdr = (const struct ikev2_hdr *) wpabuf_head(buf);
815
end = wpabuf_head_u8(buf) + wpabuf_len(buf);
816
message_id = WPA_GET_BE32(hdr->message_id);
817
length = WPA_GET_BE32(hdr->length);
819
wpa_hexdump(MSG_DEBUG, "IKEV2: IKE_SA Initiator's SPI",
820
hdr->i_spi, IKEV2_SPI_LEN);
821
wpa_hexdump(MSG_DEBUG, "IKEV2: IKE_SA Initiator's SPI",
822
hdr->r_spi, IKEV2_SPI_LEN);
823
wpa_printf(MSG_DEBUG, "IKEV2: Next Payload: %u Version: 0x%x "
825
hdr->next_payload, hdr->version, hdr->exchange_type);
826
wpa_printf(MSG_DEBUG, "IKEV2: Message ID: %u Length: %u",
829
if (hdr->version != IKEV2_VERSION) {
830
wpa_printf(MSG_INFO, "IKEV2: Unsupported HDR version 0x%x "
831
"(expected 0x%x)", hdr->version, IKEV2_VERSION);
835
if (length != wpabuf_len(buf)) {
836
wpa_printf(MSG_INFO, "IKEV2: Invalid length (HDR: %lu != "
837
"RX: %lu)", (unsigned long) length,
838
(unsigned long) wpabuf_len(buf));
842
if (ikev2_validate_rx_state(data, hdr->exchange_type, message_id) < 0)
845
if ((hdr->flags & (IKEV2_HDR_INITIATOR | IKEV2_HDR_RESPONSE)) !=
846
IKEV2_HDR_RESPONSE) {
847
wpa_printf(MSG_INFO, "IKEV2: Unexpected Flags value 0x%x",
852
if (data->state != SA_INIT) {
853
if (os_memcmp(data->i_spi, hdr->i_spi, IKEV2_SPI_LEN) != 0) {
854
wpa_printf(MSG_INFO, "IKEV2: Unexpected IKE_SA "
858
if (os_memcmp(data->r_spi, hdr->r_spi, IKEV2_SPI_LEN) != 0) {
859
wpa_printf(MSG_INFO, "IKEV2: Unexpected IKE_SA "
865
pos = (const u8 *) (hdr + 1);
866
if (ikev2_parse_payloads(&pl, hdr->next_payload, pos, end) < 0)
869
switch (data->state) {
871
if (ikev2_process_sa_init(data, hdr, &pl) < 0)
873
wpabuf_free(data->r_sign_msg);
874
data->r_sign_msg = wpabuf_dup(buf);
877
if (ikev2_process_sa_auth(data, hdr, &pl) < 0)
889
static void ikev2_build_hdr(struct ikev2_initiator_data *data,
890
struct wpabuf *msg, u8 exchange_type,
891
u8 next_payload, u32 message_id)
893
struct ikev2_hdr *hdr;
895
wpa_printf(MSG_DEBUG, "IKEV2: Adding HDR");
897
/* HDR - RFC 4306, Sect. 3.1 */
898
hdr = wpabuf_put(msg, sizeof(*hdr));
899
os_memcpy(hdr->i_spi, data->i_spi, IKEV2_SPI_LEN);
900
os_memcpy(hdr->r_spi, data->r_spi, IKEV2_SPI_LEN);
901
hdr->next_payload = next_payload;
902
hdr->version = IKEV2_VERSION;
903
hdr->exchange_type = exchange_type;
904
hdr->flags = IKEV2_HDR_INITIATOR;
905
WPA_PUT_BE32(hdr->message_id, message_id);
909
static int ikev2_build_sai(struct ikev2_initiator_data *data,
910
struct wpabuf *msg, u8 next_payload)
912
struct ikev2_payload_hdr *phdr;
914
struct ikev2_proposal *p;
915
struct ikev2_transform *t;
917
wpa_printf(MSG_DEBUG, "IKEV2: Adding SAi payload");
919
/* SAi1 - RFC 4306, Sect. 2.7 and 3.3 */
920
phdr = wpabuf_put(msg, sizeof(*phdr));
921
phdr->next_payload = next_payload;
924
/* TODO: support for multiple proposals */
925
p = wpabuf_put(msg, sizeof(*p));
926
p->proposal_num = data->proposal.proposal_num;
927
p->protocol_id = IKEV2_PROTOCOL_IKE;
928
p->num_transforms = 4;
930
t = wpabuf_put(msg, sizeof(*t));
932
t->transform_type = IKEV2_TRANSFORM_ENCR;
933
WPA_PUT_BE16(t->transform_id, data->proposal.encr);
934
if (data->proposal.encr == ENCR_AES_CBC) {
935
/* Transform Attribute: Key Len = 128 bits */
936
wpabuf_put_be16(msg, 0x800e); /* AF=1, AttrType=14 */
937
wpabuf_put_be16(msg, 128); /* 128-bit key */
939
plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) t;
940
WPA_PUT_BE16(t->transform_length, plen);
942
t = wpabuf_put(msg, sizeof(*t));
944
WPA_PUT_BE16(t->transform_length, sizeof(*t));
945
t->transform_type = IKEV2_TRANSFORM_PRF;
946
WPA_PUT_BE16(t->transform_id, data->proposal.prf);
948
t = wpabuf_put(msg, sizeof(*t));
950
WPA_PUT_BE16(t->transform_length, sizeof(*t));
951
t->transform_type = IKEV2_TRANSFORM_INTEG;
952
WPA_PUT_BE16(t->transform_id, data->proposal.integ);
954
t = wpabuf_put(msg, sizeof(*t));
955
WPA_PUT_BE16(t->transform_length, sizeof(*t));
956
t->transform_type = IKEV2_TRANSFORM_DH;
957
WPA_PUT_BE16(t->transform_id, data->proposal.dh);
959
plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) p;
960
WPA_PUT_BE16(p->proposal_length, plen);
962
plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) phdr;
963
WPA_PUT_BE16(phdr->payload_length, plen);
969
static int ikev2_build_kei(struct ikev2_initiator_data *data,
970
struct wpabuf *msg, u8 next_payload)
972
struct ikev2_payload_hdr *phdr;
976
wpa_printf(MSG_DEBUG, "IKEV2: Adding KEi payload");
978
data->dh = dh_groups_get(data->proposal.dh);
979
pv = dh_init(data->dh, &data->i_dh_private);
981
wpa_printf(MSG_DEBUG, "IKEV2: Failed to initialize DH");
985
/* KEi - RFC 4306, Sect. 3.4 */
986
phdr = wpabuf_put(msg, sizeof(*phdr));
987
phdr->next_payload = next_payload;
990
wpabuf_put_be16(msg, data->proposal.dh); /* DH Group # */
991
wpabuf_put(msg, 2); /* RESERVED */
993
* RFC 4306, Sect. 3.4: possible zero padding for public value to
994
* match the length of the prime.
996
wpabuf_put(msg, data->dh->prime_len - wpabuf_len(pv));
997
wpabuf_put_buf(msg, pv);
1000
plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) phdr;
1001
WPA_PUT_BE16(phdr->payload_length, plen);
1006
static int ikev2_build_ni(struct ikev2_initiator_data *data,
1007
struct wpabuf *msg, u8 next_payload)
1009
struct ikev2_payload_hdr *phdr;
1012
wpa_printf(MSG_DEBUG, "IKEV2: Adding Ni payload");
1014
/* Ni - RFC 4306, Sect. 3.9 */
1015
phdr = wpabuf_put(msg, sizeof(*phdr));
1016
phdr->next_payload = next_payload;
1018
wpabuf_put_data(msg, data->i_nonce, data->i_nonce_len);
1019
plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) phdr;
1020
WPA_PUT_BE16(phdr->payload_length, plen);
1025
static int ikev2_build_idi(struct ikev2_initiator_data *data,
1026
struct wpabuf *msg, u8 next_payload)
1028
struct ikev2_payload_hdr *phdr;
1031
wpa_printf(MSG_DEBUG, "IKEV2: Adding IDi payload");
1033
if (data->IDi == NULL) {
1034
wpa_printf(MSG_INFO, "IKEV2: No IDi available");
1038
/* IDi - RFC 4306, Sect. 3.5 */
1039
phdr = wpabuf_put(msg, sizeof(*phdr));
1040
phdr->next_payload = next_payload;
1042
wpabuf_put_u8(msg, ID_KEY_ID);
1043
wpabuf_put(msg, 3); /* RESERVED */
1044
wpabuf_put_data(msg, data->IDi, data->IDi_len);
1045
plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) phdr;
1046
WPA_PUT_BE16(phdr->payload_length, plen);
1051
static int ikev2_build_auth(struct ikev2_initiator_data *data,
1052
struct wpabuf *msg, u8 next_payload)
1054
struct ikev2_payload_hdr *phdr;
1056
const struct ikev2_prf_alg *prf;
1058
wpa_printf(MSG_DEBUG, "IKEV2: Adding AUTH payload");
1060
prf = ikev2_get_prf(data->proposal.prf);
1064
/* Authentication - RFC 4306, Sect. 3.8 */
1065
phdr = wpabuf_put(msg, sizeof(*phdr));
1066
phdr->next_payload = next_payload;
1068
wpabuf_put_u8(msg, AUTH_SHARED_KEY_MIC);
1069
wpabuf_put(msg, 3); /* RESERVED */
1071
/* msg | Nr | prf(SK_pi,IDi') */
1072
if (ikev2_derive_auth_data(data->proposal.prf, data->i_sign_msg,
1073
data->IDi, data->IDi_len, ID_KEY_ID,
1074
&data->keys, 1, data->shared_secret,
1075
data->shared_secret_len,
1076
data->r_nonce, data->r_nonce_len,
1077
data->key_pad, data->key_pad_len,
1078
wpabuf_put(msg, prf->hash_len)) < 0) {
1079
wpa_printf(MSG_INFO, "IKEV2: Could not derive AUTH data");
1082
wpabuf_free(data->i_sign_msg);
1083
data->i_sign_msg = NULL;
1085
plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) phdr;
1086
WPA_PUT_BE16(phdr->payload_length, plen);
1091
static struct wpabuf * ikev2_build_sa_init(struct ikev2_initiator_data *data)
1095
/* build IKE_SA_INIT: HDR, SAi, KEi, Ni */
1097
if (os_get_random(data->i_spi, IKEV2_SPI_LEN))
1099
wpa_hexdump(MSG_DEBUG, "IKEV2: IKE_SA Initiator's SPI",
1100
data->i_spi, IKEV2_SPI_LEN);
1102
data->i_nonce_len = IKEV2_NONCE_MIN_LEN;
1103
if (os_get_random(data->i_nonce, data->i_nonce_len))
1105
wpa_hexdump(MSG_DEBUG, "IKEV2: Ni", data->i_nonce, data->i_nonce_len);
1107
msg = wpabuf_alloc(sizeof(struct ikev2_hdr) + 1000);
1111
ikev2_build_hdr(data, msg, IKE_SA_INIT, IKEV2_PAYLOAD_SA, 0);
1112
if (ikev2_build_sai(data, msg, IKEV2_PAYLOAD_KEY_EXCHANGE) ||
1113
ikev2_build_kei(data, msg, IKEV2_PAYLOAD_NONCE) ||
1114
ikev2_build_ni(data, msg, IKEV2_PAYLOAD_NO_NEXT_PAYLOAD)) {
1119
ikev2_update_hdr(msg);
1121
wpa_hexdump_buf(MSG_MSGDUMP, "IKEV2: Sending message (SA_INIT)", msg);
1123
wpabuf_free(data->i_sign_msg);
1124
data->i_sign_msg = wpabuf_dup(msg);
1130
static struct wpabuf * ikev2_build_sa_auth(struct ikev2_initiator_data *data)
1132
struct wpabuf *msg, *plain;
1136
secret = data->get_shared_secret(data->cb_ctx, data->IDr,
1137
data->IDr_len, &secret_len);
1138
if (secret == NULL) {
1139
wpa_printf(MSG_INFO, "IKEV2: Could not get shared secret - "
1141
/* RFC 5106, Sect. 7:
1142
* Use a random key to fake AUTH generation in order to prevent
1143
* probing of user identities.
1145
data->unknown_user = 1;
1146
os_free(data->shared_secret);
1147
data->shared_secret = os_malloc(16);
1148
if (data->shared_secret == NULL)
1150
data->shared_secret_len = 16;
1151
if (os_get_random(data->shared_secret, 16))
1154
os_free(data->shared_secret);
1155
data->shared_secret = os_malloc(secret_len);
1156
if (data->shared_secret == NULL)
1158
os_memcpy(data->shared_secret, secret, secret_len);
1159
data->shared_secret_len = secret_len;
1162
/* build IKE_SA_AUTH: HDR, SK {IDi, [CERT,] [CERTREQ,] AUTH} */
1164
msg = wpabuf_alloc(sizeof(struct ikev2_hdr) + data->IDr_len + 1000);
1167
ikev2_build_hdr(data, msg, IKE_SA_AUTH, IKEV2_PAYLOAD_ENCRYPTED, 1);
1169
plain = wpabuf_alloc(data->IDr_len + 1000);
1170
if (plain == NULL) {
1175
if (ikev2_build_idi(data, plain, IKEV2_PAYLOAD_AUTHENTICATION) ||
1176
ikev2_build_auth(data, plain, IKEV2_PAYLOAD_NO_NEXT_PAYLOAD) ||
1177
ikev2_build_encrypted(data->proposal.encr, data->proposal.integ,
1178
&data->keys, 1, msg, plain,
1179
IKEV2_PAYLOAD_IDi)) {
1186
wpa_hexdump_buf(MSG_MSGDUMP, "IKEV2: Sending message (SA_AUTH)", msg);
1192
struct wpabuf * ikev2_initiator_build(struct ikev2_initiator_data *data)
1194
switch (data->state) {
1196
return ikev2_build_sa_init(data);
1198
return ikev2_build_sa_auth(data);