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 "crypto/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
);