Line data Source code
1 : /*
2 : * IKEv2 responder (RFC 4306) for EAP-IKEV2
3 : * Copyright (c) 2007, Jouni Malinen <j@w1.fi>
4 : *
5 : * This software may be distributed under the terms of the BSD license.
6 : * See README for more details.
7 : */
8 :
9 : #include "includes.h"
10 :
11 : #include "common.h"
12 : #include "crypto/dh_groups.h"
13 : #include "crypto/random.h"
14 : #include "ikev2.h"
15 :
16 :
17 116 : void ikev2_responder_deinit(struct ikev2_responder_data *data)
18 : {
19 116 : ikev2_free_keys(&data->keys);
20 116 : wpabuf_free(data->i_dh_public);
21 116 : wpabuf_free(data->r_dh_private);
22 116 : os_free(data->IDi);
23 116 : os_free(data->IDr);
24 116 : os_free(data->shared_secret);
25 116 : wpabuf_free(data->i_sign_msg);
26 116 : wpabuf_free(data->r_sign_msg);
27 116 : os_free(data->key_pad);
28 116 : }
29 :
30 :
31 56 : static int ikev2_derive_keys(struct ikev2_responder_data *data)
32 : {
33 : u8 *buf, *pos, *pad, skeyseed[IKEV2_MAX_HASH_LEN];
34 : size_t buf_len, pad_len;
35 : struct wpabuf *shared;
36 : const struct ikev2_integ_alg *integ;
37 : const struct ikev2_prf_alg *prf;
38 : const struct ikev2_encr_alg *encr;
39 : int ret;
40 : const u8 *addr[2];
41 : size_t len[2];
42 :
43 : /* RFC 4306, Sect. 2.14 */
44 :
45 56 : integ = ikev2_get_integ(data->proposal.integ);
46 56 : prf = ikev2_get_prf(data->proposal.prf);
47 56 : encr = ikev2_get_encr(data->proposal.encr);
48 56 : if (integ == NULL || prf == NULL || encr == NULL) {
49 0 : wpa_printf(MSG_INFO, "IKEV2: Unsupported proposal");
50 0 : return -1;
51 : }
52 :
53 56 : shared = dh_derive_shared(data->i_dh_public, data->r_dh_private,
54 : data->dh);
55 56 : if (shared == NULL)
56 2 : return -1;
57 :
58 : /* Construct Ni | Nr | SPIi | SPIr */
59 :
60 54 : buf_len = data->i_nonce_len + data->r_nonce_len + 2 * IKEV2_SPI_LEN;
61 54 : buf = os_malloc(buf_len);
62 54 : if (buf == NULL) {
63 1 : wpabuf_free(shared);
64 1 : return -1;
65 : }
66 :
67 53 : pos = buf;
68 53 : os_memcpy(pos, data->i_nonce, data->i_nonce_len);
69 53 : pos += data->i_nonce_len;
70 53 : os_memcpy(pos, data->r_nonce, data->r_nonce_len);
71 53 : pos += data->r_nonce_len;
72 53 : os_memcpy(pos, data->i_spi, IKEV2_SPI_LEN);
73 53 : pos += IKEV2_SPI_LEN;
74 53 : os_memcpy(pos, data->r_spi, IKEV2_SPI_LEN);
75 :
76 : /* SKEYSEED = prf(Ni | Nr, g^ir) */
77 : /* Use zero-padding per RFC 4306, Sect. 2.14 */
78 53 : pad_len = data->dh->prime_len - wpabuf_len(shared);
79 53 : pad = os_zalloc(pad_len ? pad_len : 1);
80 53 : if (pad == NULL) {
81 1 : wpabuf_free(shared);
82 1 : os_free(buf);
83 1 : return -1;
84 : }
85 :
86 52 : addr[0] = pad;
87 52 : len[0] = pad_len;
88 52 : addr[1] = wpabuf_head(shared);
89 52 : len[1] = wpabuf_len(shared);
90 52 : if (ikev2_prf_hash(prf->id, buf, data->i_nonce_len + data->r_nonce_len,
91 : 2, addr, len, skeyseed) < 0) {
92 1 : wpabuf_free(shared);
93 1 : os_free(buf);
94 1 : os_free(pad);
95 1 : return -1;
96 : }
97 51 : os_free(pad);
98 51 : wpabuf_free(shared);
99 :
100 : /* DH parameters are not needed anymore, so free them */
101 51 : wpabuf_free(data->i_dh_public);
102 51 : data->i_dh_public = NULL;
103 51 : wpabuf_free(data->r_dh_private);
104 51 : data->r_dh_private = NULL;
105 :
106 51 : wpa_hexdump_key(MSG_DEBUG, "IKEV2: SKEYSEED",
107 : skeyseed, prf->hash_len);
108 :
109 51 : ret = ikev2_derive_sk_keys(prf, integ, encr, skeyseed, buf, buf_len,
110 : &data->keys);
111 51 : os_free(buf);
112 51 : return ret;
113 : }
114 :
115 :
116 307 : static int ikev2_parse_transform(struct ikev2_proposal_data *prop,
117 : const u8 *pos, const u8 *end)
118 : {
119 : int transform_len;
120 : const struct ikev2_transform *t;
121 : u16 transform_id;
122 : const u8 *tend;
123 :
124 307 : if (end - pos < (int) sizeof(*t)) {
125 1 : wpa_printf(MSG_INFO, "IKEV2: Too short transform");
126 1 : return -1;
127 : }
128 :
129 306 : t = (const struct ikev2_transform *) pos;
130 306 : transform_len = WPA_GET_BE16(t->transform_length);
131 306 : if (transform_len < (int) sizeof(*t) || transform_len > end - pos) {
132 2 : wpa_printf(MSG_INFO, "IKEV2: Invalid transform length %d",
133 : transform_len);
134 2 : return -1;
135 : }
136 304 : tend = pos + transform_len;
137 :
138 304 : transform_id = WPA_GET_BE16(t->transform_id);
139 :
140 304 : wpa_printf(MSG_DEBUG, "IKEV2: Transform:");
141 912 : wpa_printf(MSG_DEBUG, "IKEV2: Type: %d Transform Length: %d "
142 : "Transform Type: %d Transform ID: %d",
143 608 : t->type, transform_len, t->transform_type, transform_id);
144 :
145 304 : if (t->type != 0 && t->type != 3) {
146 1 : wpa_printf(MSG_INFO, "IKEV2: Unexpected Transform type");
147 1 : return -1;
148 : }
149 :
150 303 : pos = (const u8 *) (t + 1);
151 303 : if (pos < tend) {
152 64 : wpa_hexdump(MSG_DEBUG, "IKEV2: Transform Attributes",
153 64 : pos, tend - pos);
154 : }
155 :
156 303 : switch (t->transform_type) {
157 : case IKEV2_TRANSFORM_ENCR:
158 75 : if (ikev2_get_encr(transform_id)) {
159 75 : if (transform_id == ENCR_AES_CBC) {
160 64 : if (tend - pos != 4) {
161 1 : wpa_printf(MSG_DEBUG, "IKEV2: No "
162 : "Transform Attr for AES");
163 1 : break;
164 : }
165 63 : if (WPA_GET_BE16(pos) != 0x800e) {
166 1 : wpa_printf(MSG_DEBUG, "IKEV2: Not a "
167 : "Key Size attribute for "
168 : "AES");
169 1 : break;
170 : }
171 62 : if (WPA_GET_BE16(pos + 2) != 128) {
172 1 : wpa_printf(MSG_DEBUG, "IKEV2: "
173 : "Unsupported AES key size "
174 : "%d bits",
175 1 : WPA_GET_BE16(pos + 2));
176 1 : break;
177 : }
178 : }
179 72 : prop->encr = transform_id;
180 : }
181 72 : break;
182 : case IKEV2_TRANSFORM_PRF:
183 72 : if (ikev2_get_prf(transform_id))
184 72 : prop->prf = transform_id;
185 72 : break;
186 : case IKEV2_TRANSFORM_INTEG:
187 72 : if (ikev2_get_integ(transform_id))
188 72 : prop->integ = transform_id;
189 72 : break;
190 : case IKEV2_TRANSFORM_DH:
191 72 : if (dh_groups_get(transform_id))
192 72 : prop->dh = transform_id;
193 72 : break;
194 : }
195 :
196 303 : return transform_len;
197 : }
198 :
199 :
200 87 : static int ikev2_parse_proposal(struct ikev2_proposal_data *prop,
201 : const u8 *pos, const u8 *end)
202 : {
203 : const u8 *pend, *ppos;
204 : int proposal_len, i;
205 : const struct ikev2_proposal *p;
206 :
207 87 : if (end - pos < (int) sizeof(*p)) {
208 1 : wpa_printf(MSG_INFO, "IKEV2: Too short proposal");
209 1 : return -1;
210 : }
211 :
212 : /* FIX: AND processing if multiple proposals use the same # */
213 :
214 86 : p = (const struct ikev2_proposal *) pos;
215 86 : proposal_len = WPA_GET_BE16(p->proposal_length);
216 86 : if (proposal_len < (int) sizeof(*p) || proposal_len > end - pos) {
217 2 : wpa_printf(MSG_INFO, "IKEV2: Invalid proposal length %d",
218 : proposal_len);
219 2 : return -1;
220 : }
221 84 : wpa_printf(MSG_DEBUG, "IKEV2: SAi1 Proposal # %d",
222 84 : p->proposal_num);
223 168 : wpa_printf(MSG_DEBUG, "IKEV2: Type: %d Proposal Length: %d "
224 : " Protocol ID: %d",
225 168 : p->type, proposal_len, p->protocol_id);
226 168 : wpa_printf(MSG_DEBUG, "IKEV2: SPI Size: %d Transforms: %d",
227 168 : p->spi_size, p->num_transforms);
228 :
229 84 : if (p->type != 0 && p->type != 2) {
230 1 : wpa_printf(MSG_INFO, "IKEV2: Unexpected Proposal type");
231 1 : return -1;
232 : }
233 :
234 83 : if (p->protocol_id != IKEV2_PROTOCOL_IKE) {
235 1 : wpa_printf(MSG_DEBUG, "IKEV2: Unexpected Protocol ID "
236 : "(only IKE allowed for EAP-IKEv2)");
237 1 : return -1;
238 : }
239 :
240 82 : if (p->proposal_num != prop->proposal_num) {
241 1 : if (p->proposal_num == prop->proposal_num + 1)
242 0 : prop->proposal_num = p->proposal_num;
243 : else {
244 1 : wpa_printf(MSG_INFO, "IKEV2: Unexpected Proposal #");
245 1 : return -1;
246 : }
247 : }
248 :
249 81 : ppos = (const u8 *) (p + 1);
250 81 : pend = pos + proposal_len;
251 81 : if (p->spi_size > pend - ppos) {
252 1 : wpa_printf(MSG_INFO, "IKEV2: Not enough room for SPI "
253 : "in proposal");
254 1 : return -1;
255 : }
256 80 : if (p->spi_size) {
257 1 : wpa_hexdump(MSG_DEBUG, "IKEV2: SPI",
258 1 : ppos, p->spi_size);
259 1 : ppos += p->spi_size;
260 : }
261 :
262 : /*
263 : * For initial IKE_SA negotiation, SPI Size MUST be zero; for
264 : * subsequent negotiations, it must be 8 for IKE. We only support
265 : * initial case for now.
266 : */
267 80 : if (p->spi_size != 0) {
268 1 : wpa_printf(MSG_INFO, "IKEV2: Unexpected SPI Size");
269 1 : return -1;
270 : }
271 :
272 79 : if (p->num_transforms == 0) {
273 1 : wpa_printf(MSG_INFO, "IKEV2: At least one transform required");
274 1 : return -1;
275 : }
276 :
277 381 : for (i = 0; i < (int) p->num_transforms; i++) {
278 307 : int tlen = ikev2_parse_transform(prop, ppos, pend);
279 307 : if (tlen < 0)
280 4 : return -1;
281 303 : ppos += tlen;
282 : }
283 :
284 74 : if (ppos != pend) {
285 1 : wpa_printf(MSG_INFO, "IKEV2: Unexpected data after "
286 : "transforms");
287 1 : return -1;
288 : }
289 :
290 73 : return proposal_len;
291 : }
292 :
293 :
294 89 : static int ikev2_process_sai1(struct ikev2_responder_data *data,
295 : const u8 *sai1, size_t sai1_len)
296 : {
297 : struct ikev2_proposal_data prop;
298 : const u8 *pos, *end;
299 89 : int found = 0;
300 :
301 : /* Security Association Payloads: <Proposals> */
302 :
303 89 : if (sai1 == NULL) {
304 1 : wpa_printf(MSG_INFO, "IKEV2: SAi1 not received");
305 1 : return -1;
306 : }
307 :
308 88 : os_memset(&prop, 0, sizeof(prop));
309 88 : prop.proposal_num = 1;
310 :
311 88 : pos = sai1;
312 88 : end = sai1 + sai1_len;
313 :
314 249 : while (pos < end) {
315 : int plen;
316 :
317 87 : prop.integ = -1;
318 87 : prop.prf = -1;
319 87 : prop.encr = -1;
320 87 : prop.dh = -1;
321 87 : plen = ikev2_parse_proposal(&prop, pos, end);
322 87 : if (plen < 0)
323 14 : return -1;
324 :
325 145 : if (!found && prop.integ != -1 && prop.prf != -1 &&
326 144 : prop.encr != -1 && prop.dh != -1) {
327 72 : os_memcpy(&data->proposal, &prop, sizeof(prop));
328 72 : data->dh = dh_groups_get(prop.dh);
329 72 : found = 1;
330 : }
331 :
332 73 : pos += plen;
333 : }
334 :
335 74 : if (pos != end) {
336 0 : wpa_printf(MSG_INFO, "IKEV2: Unexpected data after proposals");
337 0 : return -1;
338 : }
339 :
340 74 : if (!found) {
341 2 : wpa_printf(MSG_INFO, "IKEV2: No acceptable proposal found");
342 2 : return -1;
343 : }
344 :
345 144 : wpa_printf(MSG_DEBUG, "IKEV2: Accepted proposal #%d: ENCR:%d PRF:%d "
346 72 : "INTEG:%d D-H:%d", data->proposal.proposal_num,
347 : data->proposal.encr, data->proposal.prf,
348 : data->proposal.integ, data->proposal.dh);
349 :
350 72 : return 0;
351 : }
352 :
353 :
354 72 : static int ikev2_process_kei(struct ikev2_responder_data *data,
355 : const u8 *kei, size_t kei_len)
356 : {
357 : u16 group;
358 :
359 : /*
360 : * Key Exchange Payload:
361 : * DH Group # (16 bits)
362 : * RESERVED (16 bits)
363 : * Key Exchange Data (Diffie-Hellman public value)
364 : */
365 :
366 72 : if (kei == NULL) {
367 1 : wpa_printf(MSG_INFO, "IKEV2: KEi not received");
368 1 : return -1;
369 : }
370 :
371 71 : if (kei_len < 4 + 96) {
372 1 : wpa_printf(MSG_INFO, "IKEV2: Too short Key Exchange Payload");
373 1 : return -1;
374 : }
375 :
376 70 : group = WPA_GET_BE16(kei);
377 70 : wpa_printf(MSG_DEBUG, "IKEV2: KEi DH Group #%u", group);
378 :
379 70 : if (group != data->proposal.dh) {
380 1 : wpa_printf(MSG_DEBUG, "IKEV2: KEi DH Group #%u does not match "
381 : "with the selected proposal (%u)",
382 : group, data->proposal.dh);
383 : /* Reject message with Notify payload of type
384 : * INVALID_KE_PAYLOAD (RFC 4306, Sect. 3.4) */
385 1 : data->error_type = INVALID_KE_PAYLOAD;
386 1 : data->state = NOTIFY;
387 1 : return -1;
388 : }
389 :
390 69 : if (data->dh == NULL) {
391 0 : wpa_printf(MSG_INFO, "IKEV2: Unsupported DH group");
392 0 : return -1;
393 : }
394 :
395 : /* RFC 4306, Section 3.4:
396 : * The length of DH public value MUST be equal to the length of the
397 : * prime modulus.
398 : */
399 69 : if (kei_len - 4 != data->dh->prime_len) {
400 2 : wpa_printf(MSG_INFO, "IKEV2: Invalid DH public value length "
401 : "%ld (expected %ld)",
402 2 : (long) (kei_len - 4), (long) data->dh->prime_len);
403 1 : return -1;
404 : }
405 :
406 68 : wpabuf_free(data->i_dh_public);
407 68 : data->i_dh_public = wpabuf_alloc(kei_len - 4);
408 68 : if (data->i_dh_public == NULL)
409 1 : return -1;
410 67 : wpabuf_put_data(data->i_dh_public, kei + 4, kei_len - 4);
411 :
412 67 : wpa_hexdump_buf(MSG_DEBUG, "IKEV2: KEi Diffie-Hellman Public Value",
413 67 : data->i_dh_public);
414 :
415 67 : return 0;
416 : }
417 :
418 :
419 67 : static int ikev2_process_ni(struct ikev2_responder_data *data,
420 : const u8 *ni, size_t ni_len)
421 : {
422 67 : if (ni == NULL) {
423 1 : wpa_printf(MSG_INFO, "IKEV2: Ni not received");
424 1 : return -1;
425 : }
426 :
427 66 : if (ni_len < IKEV2_NONCE_MIN_LEN || ni_len > IKEV2_NONCE_MAX_LEN) {
428 2 : wpa_printf(MSG_INFO, "IKEV2: Invalid Ni length %ld",
429 : (long) ni_len);
430 2 : return -1;
431 : }
432 :
433 64 : data->i_nonce_len = ni_len;
434 64 : os_memcpy(data->i_nonce, ni, ni_len);
435 128 : wpa_hexdump(MSG_MSGDUMP, "IKEV2: Ni",
436 64 : data->i_nonce, data->i_nonce_len);
437 :
438 64 : return 0;
439 : }
440 :
441 :
442 89 : static int ikev2_process_sa_init(struct ikev2_responder_data *data,
443 : const struct ikev2_hdr *hdr,
444 : struct ikev2_payloads *pl)
445 : {
446 161 : if (ikev2_process_sai1(data, pl->sa, pl->sa_len) < 0 ||
447 139 : ikev2_process_kei(data, pl->ke, pl->ke_len) < 0 ||
448 67 : ikev2_process_ni(data, pl->nonce, pl->nonce_len) < 0)
449 25 : return -1;
450 :
451 64 : os_memcpy(data->i_spi, hdr->i_spi, IKEV2_SPI_LEN);
452 :
453 64 : return 0;
454 : }
455 :
456 :
457 26 : static int ikev2_process_idi(struct ikev2_responder_data *data,
458 : const u8 *idi, size_t idi_len)
459 : {
460 : u8 id_type;
461 :
462 26 : if (idi == NULL) {
463 0 : wpa_printf(MSG_INFO, "IKEV2: No IDi received");
464 0 : return -1;
465 : }
466 :
467 26 : if (idi_len < 4) {
468 0 : wpa_printf(MSG_INFO, "IKEV2: Too short IDi payload");
469 0 : return -1;
470 : }
471 :
472 26 : id_type = idi[0];
473 26 : idi += 4;
474 26 : idi_len -= 4;
475 :
476 26 : wpa_printf(MSG_DEBUG, "IKEV2: IDi ID Type %d", id_type);
477 26 : wpa_hexdump_ascii(MSG_DEBUG, "IKEV2: IDi", idi, idi_len);
478 26 : os_free(data->IDi);
479 26 : data->IDi = os_malloc(idi_len);
480 26 : if (data->IDi == NULL)
481 1 : return -1;
482 25 : os_memcpy(data->IDi, idi, idi_len);
483 25 : data->IDi_len = idi_len;
484 25 : data->IDi_type = id_type;
485 :
486 25 : return 0;
487 : }
488 :
489 :
490 25 : static int ikev2_process_cert(struct ikev2_responder_data *data,
491 : const u8 *cert, size_t cert_len)
492 : {
493 : u8 cert_encoding;
494 :
495 25 : if (cert == NULL) {
496 25 : if (data->peer_auth == PEER_AUTH_CERT) {
497 0 : wpa_printf(MSG_INFO, "IKEV2: No Certificate received");
498 0 : return -1;
499 : }
500 25 : return 0;
501 : }
502 :
503 0 : if (cert_len < 1) {
504 0 : wpa_printf(MSG_INFO, "IKEV2: No Cert Encoding field");
505 0 : return -1;
506 : }
507 :
508 0 : cert_encoding = cert[0];
509 0 : cert++;
510 0 : cert_len--;
511 :
512 0 : wpa_printf(MSG_DEBUG, "IKEV2: Cert Encoding %d", cert_encoding);
513 0 : wpa_hexdump(MSG_MSGDUMP, "IKEV2: Certificate Data", cert, cert_len);
514 :
515 : /* TODO: validate certificate */
516 :
517 0 : return 0;
518 : }
519 :
520 :
521 0 : static int ikev2_process_auth_cert(struct ikev2_responder_data *data,
522 : u8 method, const u8 *auth, size_t auth_len)
523 : {
524 0 : if (method != AUTH_RSA_SIGN) {
525 0 : wpa_printf(MSG_INFO, "IKEV2: Unsupported authentication "
526 : "method %d", method);
527 0 : return -1;
528 : }
529 :
530 : /* TODO: validate AUTH */
531 0 : return 0;
532 : }
533 :
534 :
535 25 : static int ikev2_process_auth_secret(struct ikev2_responder_data *data,
536 : u8 method, const u8 *auth,
537 : size_t auth_len)
538 : {
539 : u8 auth_data[IKEV2_MAX_HASH_LEN];
540 : const struct ikev2_prf_alg *prf;
541 :
542 25 : if (method != AUTH_SHARED_KEY_MIC) {
543 0 : wpa_printf(MSG_INFO, "IKEV2: Unsupported authentication "
544 : "method %d", method);
545 0 : return -1;
546 : }
547 :
548 : /* msg | Nr | prf(SK_pi,IDi') */
549 150 : if (ikev2_derive_auth_data(data->proposal.prf, data->i_sign_msg,
550 50 : data->IDi, data->IDi_len, data->IDi_type,
551 25 : &data->keys, 1, data->shared_secret,
552 : data->shared_secret_len,
553 25 : data->r_nonce, data->r_nonce_len,
554 25 : data->key_pad, data->key_pad_len,
555 : auth_data) < 0) {
556 5 : wpa_printf(MSG_INFO, "IKEV2: Could not derive AUTH data");
557 5 : return -1;
558 : }
559 :
560 20 : wpabuf_free(data->i_sign_msg);
561 20 : data->i_sign_msg = NULL;
562 :
563 20 : prf = ikev2_get_prf(data->proposal.prf);
564 20 : if (prf == NULL)
565 0 : return -1;
566 :
567 40 : if (auth_len != prf->hash_len ||
568 20 : os_memcmp_const(auth, auth_data, auth_len) != 0) {
569 4 : wpa_printf(MSG_INFO, "IKEV2: Invalid Authentication Data");
570 4 : wpa_hexdump(MSG_DEBUG, "IKEV2: Received Authentication Data",
571 : auth, auth_len);
572 4 : wpa_hexdump(MSG_DEBUG, "IKEV2: Expected Authentication Data",
573 : auth_data, prf->hash_len);
574 4 : data->error_type = AUTHENTICATION_FAILED;
575 4 : data->state = NOTIFY;
576 4 : return -1;
577 : }
578 :
579 16 : wpa_printf(MSG_DEBUG, "IKEV2: Server authenticated successfully "
580 : "using shared keys");
581 :
582 16 : return 0;
583 : }
584 :
585 :
586 25 : static int ikev2_process_auth(struct ikev2_responder_data *data,
587 : const u8 *auth, size_t auth_len)
588 : {
589 : u8 auth_method;
590 :
591 25 : if (auth == NULL) {
592 0 : wpa_printf(MSG_INFO, "IKEV2: No Authentication Payload");
593 0 : return -1;
594 : }
595 :
596 25 : if (auth_len < 4) {
597 0 : wpa_printf(MSG_INFO, "IKEV2: Too short Authentication "
598 : "Payload");
599 0 : return -1;
600 : }
601 :
602 25 : auth_method = auth[0];
603 25 : auth += 4;
604 25 : auth_len -= 4;
605 :
606 25 : wpa_printf(MSG_DEBUG, "IKEV2: Auth Method %d", auth_method);
607 25 : wpa_hexdump(MSG_MSGDUMP, "IKEV2: Authentication Data", auth, auth_len);
608 :
609 25 : switch (data->peer_auth) {
610 : case PEER_AUTH_CERT:
611 0 : return ikev2_process_auth_cert(data, auth_method, auth,
612 : auth_len);
613 : case PEER_AUTH_SECRET:
614 25 : return ikev2_process_auth_secret(data, auth_method, auth,
615 : auth_len);
616 : }
617 :
618 0 : return -1;
619 : }
620 :
621 :
622 26 : static int ikev2_process_sa_auth_decrypted(struct ikev2_responder_data *data,
623 : u8 next_payload,
624 : u8 *payload, size_t payload_len)
625 : {
626 : struct ikev2_payloads pl;
627 :
628 26 : wpa_printf(MSG_DEBUG, "IKEV2: Processing decrypted payloads");
629 :
630 26 : if (ikev2_parse_payloads(&pl, next_payload, payload, payload +
631 : payload_len) < 0) {
632 0 : wpa_printf(MSG_INFO, "IKEV2: Failed to parse decrypted "
633 : "payloads");
634 0 : return -1;
635 : }
636 :
637 51 : if (ikev2_process_idi(data, pl.idi, pl.idi_len) < 0 ||
638 50 : ikev2_process_cert(data, pl.cert, pl.cert_len) < 0 ||
639 25 : ikev2_process_auth(data, pl.auth, pl.auth_len) < 0)
640 10 : return -1;
641 :
642 16 : return 0;
643 : }
644 :
645 :
646 30 : static int ikev2_process_sa_auth(struct ikev2_responder_data *data,
647 : const struct ikev2_hdr *hdr,
648 : struct ikev2_payloads *pl)
649 : {
650 : u8 *decrypted;
651 : size_t decrypted_len;
652 : int ret;
653 :
654 30 : decrypted = ikev2_decrypt_payload(data->proposal.encr,
655 : data->proposal.integ,
656 : &data->keys, 1, hdr, pl->encrypted,
657 : pl->encrypted_len, &decrypted_len);
658 30 : if (decrypted == NULL)
659 4 : return -1;
660 :
661 26 : ret = ikev2_process_sa_auth_decrypted(data, pl->encr_next_payload,
662 : decrypted, decrypted_len);
663 26 : os_free(decrypted);
664 :
665 26 : return ret;
666 : }
667 :
668 :
669 128 : static int ikev2_validate_rx_state(struct ikev2_responder_data *data,
670 : u8 exchange_type, u32 message_id)
671 : {
672 128 : switch (data->state) {
673 : case SA_INIT:
674 : /* Expect to receive IKE_SA_INIT: HDR, SAi1, KEi, Ni */
675 98 : if (exchange_type != IKE_SA_INIT) {
676 1 : wpa_printf(MSG_INFO, "IKEV2: Unexpected Exchange Type "
677 : "%u in SA_INIT state", exchange_type);
678 1 : return -1;
679 : }
680 97 : if (message_id != 0) {
681 1 : wpa_printf(MSG_INFO, "IKEV2: Unexpected Message ID %u "
682 : "in SA_INIT state", message_id);
683 1 : return -1;
684 : }
685 96 : break;
686 : case SA_AUTH:
687 : /* Expect to receive IKE_SA_AUTH:
688 : * HDR, SK {IDi, [CERT,] [CERTREQ,] [IDr,]
689 : * AUTH, SAi2, TSi, TSr}
690 : */
691 30 : if (exchange_type != IKE_SA_AUTH) {
692 0 : wpa_printf(MSG_INFO, "IKEV2: Unexpected Exchange Type "
693 : "%u in SA_AUTH state", exchange_type);
694 0 : return -1;
695 : }
696 30 : if (message_id != 1) {
697 0 : wpa_printf(MSG_INFO, "IKEV2: Unexpected Message ID %u "
698 : "in SA_AUTH state", message_id);
699 0 : return -1;
700 : }
701 30 : break;
702 : case CHILD_SA:
703 0 : if (exchange_type != CREATE_CHILD_SA) {
704 0 : wpa_printf(MSG_INFO, "IKEV2: Unexpected Exchange Type "
705 : "%u in CHILD_SA state", exchange_type);
706 0 : return -1;
707 : }
708 0 : if (message_id != 2) {
709 0 : wpa_printf(MSG_INFO, "IKEV2: Unexpected Message ID %u "
710 : "in CHILD_SA state", message_id);
711 0 : return -1;
712 : }
713 0 : break;
714 : case NOTIFY:
715 : case IKEV2_DONE:
716 : case IKEV2_FAILED:
717 0 : return -1;
718 : }
719 :
720 126 : return 0;
721 : }
722 :
723 :
724 134 : int ikev2_responder_process(struct ikev2_responder_data *data,
725 : const struct wpabuf *buf)
726 : {
727 : const struct ikev2_hdr *hdr;
728 : u32 length, message_id;
729 : const u8 *pos, *end;
730 : struct ikev2_payloads pl;
731 :
732 134 : wpa_printf(MSG_MSGDUMP, "IKEV2: Received message (len %lu)",
733 : (unsigned long) wpabuf_len(buf));
734 :
735 134 : if (wpabuf_len(buf) < sizeof(*hdr)) {
736 4 : wpa_printf(MSG_INFO, "IKEV2: Too short frame to include HDR");
737 4 : return -1;
738 : }
739 :
740 130 : data->error_type = 0;
741 130 : hdr = (const struct ikev2_hdr *) wpabuf_head(buf);
742 130 : end = wpabuf_head_u8(buf) + wpabuf_len(buf);
743 130 : message_id = WPA_GET_BE32(hdr->message_id);
744 130 : length = WPA_GET_BE32(hdr->length);
745 :
746 130 : wpa_hexdump(MSG_DEBUG, "IKEV2: IKE_SA Initiator's SPI",
747 130 : hdr->i_spi, IKEV2_SPI_LEN);
748 130 : wpa_hexdump(MSG_DEBUG, "IKEV2: IKE_SA Responder's SPI",
749 130 : hdr->r_spi, IKEV2_SPI_LEN);
750 390 : wpa_printf(MSG_DEBUG, "IKEV2: Next Payload: %u Version: 0x%x "
751 : "Exchange Type: %u",
752 390 : hdr->next_payload, hdr->version, hdr->exchange_type);
753 130 : wpa_printf(MSG_DEBUG, "IKEV2: Message ID: %u Length: %u",
754 : message_id, length);
755 :
756 130 : if (hdr->version != IKEV2_VERSION) {
757 1 : wpa_printf(MSG_INFO, "IKEV2: Unsupported HDR version 0x%x "
758 1 : "(expected 0x%x)", hdr->version, IKEV2_VERSION);
759 1 : return -1;
760 : }
761 :
762 129 : if (length != wpabuf_len(buf)) {
763 1 : wpa_printf(MSG_INFO, "IKEV2: Invalid length (HDR: %lu != "
764 : "RX: %lu)", (unsigned long) length,
765 : (unsigned long) wpabuf_len(buf));
766 1 : return -1;
767 : }
768 :
769 128 : if (ikev2_validate_rx_state(data, hdr->exchange_type, message_id) < 0)
770 2 : return -1;
771 :
772 126 : if ((hdr->flags & (IKEV2_HDR_INITIATOR | IKEV2_HDR_RESPONSE)) !=
773 : IKEV2_HDR_INITIATOR) {
774 2 : wpa_printf(MSG_INFO, "IKEV2: Unexpected Flags value 0x%x",
775 2 : hdr->flags);
776 2 : return -1;
777 : }
778 :
779 124 : if (data->state != SA_INIT) {
780 30 : if (os_memcmp(data->i_spi, hdr->i_spi, IKEV2_SPI_LEN) != 0) {
781 0 : wpa_printf(MSG_INFO, "IKEV2: Unexpected IKE_SA "
782 : "Initiator's SPI");
783 0 : return -1;
784 : }
785 30 : if (os_memcmp(data->r_spi, hdr->r_spi, IKEV2_SPI_LEN) != 0) {
786 0 : wpa_printf(MSG_INFO, "IKEV2: Unexpected IKE_SA "
787 : "Responder's SPI");
788 0 : return -1;
789 : }
790 : }
791 :
792 124 : pos = (const u8 *) (hdr + 1);
793 124 : if (ikev2_parse_payloads(&pl, hdr->next_payload, pos, end) < 0)
794 5 : return -1;
795 :
796 119 : if (data->state == SA_INIT) {
797 89 : data->last_msg = LAST_MSG_SA_INIT;
798 89 : if (ikev2_process_sa_init(data, hdr, &pl) < 0) {
799 25 : if (data->state == NOTIFY)
800 1 : return 0;
801 24 : return -1;
802 : }
803 64 : wpabuf_free(data->i_sign_msg);
804 64 : data->i_sign_msg = wpabuf_dup(buf);
805 : }
806 :
807 94 : if (data->state == SA_AUTH) {
808 30 : data->last_msg = LAST_MSG_SA_AUTH;
809 30 : if (ikev2_process_sa_auth(data, hdr, &pl) < 0) {
810 14 : if (data->state == NOTIFY)
811 4 : return 0;
812 10 : return -1;
813 : }
814 : }
815 :
816 80 : return 0;
817 : }
818 :
819 :
820 79 : static void ikev2_build_hdr(struct ikev2_responder_data *data,
821 : struct wpabuf *msg, u8 exchange_type,
822 : u8 next_payload, u32 message_id)
823 : {
824 : struct ikev2_hdr *hdr;
825 :
826 79 : wpa_printf(MSG_DEBUG, "IKEV2: Adding HDR");
827 :
828 : /* HDR - RFC 4306, Sect. 3.1 */
829 79 : hdr = wpabuf_put(msg, sizeof(*hdr));
830 79 : os_memcpy(hdr->i_spi, data->i_spi, IKEV2_SPI_LEN);
831 79 : os_memcpy(hdr->r_spi, data->r_spi, IKEV2_SPI_LEN);
832 79 : hdr->next_payload = next_payload;
833 79 : hdr->version = IKEV2_VERSION;
834 79 : hdr->exchange_type = exchange_type;
835 79 : hdr->flags = IKEV2_HDR_RESPONSE;
836 79 : WPA_PUT_BE32(hdr->message_id, message_id);
837 79 : }
838 :
839 :
840 61 : static int ikev2_build_sar1(struct ikev2_responder_data *data,
841 : struct wpabuf *msg, u8 next_payload)
842 : {
843 : struct ikev2_payload_hdr *phdr;
844 : size_t plen;
845 : struct ikev2_proposal *p;
846 : struct ikev2_transform *t;
847 :
848 61 : wpa_printf(MSG_DEBUG, "IKEV2: Adding SAr1 payload");
849 :
850 : /* SAr1 - RFC 4306, Sect. 2.7 and 3.3 */
851 61 : phdr = wpabuf_put(msg, sizeof(*phdr));
852 61 : phdr->next_payload = next_payload;
853 61 : phdr->flags = 0;
854 :
855 61 : p = wpabuf_put(msg, sizeof(*p));
856 61 : p->proposal_num = data->proposal.proposal_num;
857 61 : p->protocol_id = IKEV2_PROTOCOL_IKE;
858 61 : p->num_transforms = 4;
859 :
860 61 : t = wpabuf_put(msg, sizeof(*t));
861 61 : t->type = 3;
862 61 : t->transform_type = IKEV2_TRANSFORM_ENCR;
863 61 : WPA_PUT_BE16(t->transform_id, data->proposal.encr);
864 61 : if (data->proposal.encr == ENCR_AES_CBC) {
865 : /* Transform Attribute: Key Len = 128 bits */
866 57 : wpabuf_put_be16(msg, 0x800e); /* AF=1, AttrType=14 */
867 57 : wpabuf_put_be16(msg, 128); /* 128-bit key */
868 : }
869 61 : plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) t;
870 61 : WPA_PUT_BE16(t->transform_length, plen);
871 :
872 61 : t = wpabuf_put(msg, sizeof(*t));
873 61 : t->type = 3;
874 61 : WPA_PUT_BE16(t->transform_length, sizeof(*t));
875 61 : t->transform_type = IKEV2_TRANSFORM_PRF;
876 61 : WPA_PUT_BE16(t->transform_id, data->proposal.prf);
877 :
878 61 : t = wpabuf_put(msg, sizeof(*t));
879 61 : t->type = 3;
880 61 : WPA_PUT_BE16(t->transform_length, sizeof(*t));
881 61 : t->transform_type = IKEV2_TRANSFORM_INTEG;
882 61 : WPA_PUT_BE16(t->transform_id, data->proposal.integ);
883 :
884 61 : t = wpabuf_put(msg, sizeof(*t));
885 61 : WPA_PUT_BE16(t->transform_length, sizeof(*t));
886 61 : t->transform_type = IKEV2_TRANSFORM_DH;
887 61 : WPA_PUT_BE16(t->transform_id, data->proposal.dh);
888 :
889 61 : plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) p;
890 61 : WPA_PUT_BE16(p->proposal_length, plen);
891 :
892 61 : plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) phdr;
893 61 : WPA_PUT_BE16(phdr->payload_length, plen);
894 :
895 61 : return 0;
896 : }
897 :
898 :
899 61 : static int ikev2_build_ker(struct ikev2_responder_data *data,
900 : struct wpabuf *msg, u8 next_payload)
901 : {
902 : struct ikev2_payload_hdr *phdr;
903 : size_t plen;
904 : struct wpabuf *pv;
905 :
906 61 : wpa_printf(MSG_DEBUG, "IKEV2: Adding KEr payload");
907 :
908 61 : pv = dh_init(data->dh, &data->r_dh_private);
909 61 : if (pv == NULL) {
910 5 : wpa_printf(MSG_DEBUG, "IKEV2: Failed to initialize DH");
911 5 : return -1;
912 : }
913 :
914 : /* KEr - RFC 4306, Sect. 3.4 */
915 56 : phdr = wpabuf_put(msg, sizeof(*phdr));
916 56 : phdr->next_payload = next_payload;
917 56 : phdr->flags = 0;
918 :
919 56 : wpabuf_put_be16(msg, data->proposal.dh); /* DH Group # */
920 56 : wpabuf_put(msg, 2); /* RESERVED */
921 : /*
922 : * RFC 4306, Sect. 3.4: possible zero padding for public value to
923 : * match the length of the prime.
924 : */
925 56 : wpabuf_put(msg, data->dh->prime_len - wpabuf_len(pv));
926 56 : wpabuf_put_buf(msg, pv);
927 56 : wpabuf_free(pv);
928 :
929 56 : plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) phdr;
930 56 : WPA_PUT_BE16(phdr->payload_length, plen);
931 56 : return 0;
932 : }
933 :
934 :
935 56 : static int ikev2_build_nr(struct ikev2_responder_data *data,
936 : struct wpabuf *msg, u8 next_payload)
937 : {
938 : struct ikev2_payload_hdr *phdr;
939 : size_t plen;
940 :
941 56 : wpa_printf(MSG_DEBUG, "IKEV2: Adding Nr payload");
942 :
943 : /* Nr - RFC 4306, Sect. 3.9 */
944 56 : phdr = wpabuf_put(msg, sizeof(*phdr));
945 56 : phdr->next_payload = next_payload;
946 56 : phdr->flags = 0;
947 56 : wpabuf_put_data(msg, data->r_nonce, data->r_nonce_len);
948 56 : plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) phdr;
949 56 : WPA_PUT_BE16(phdr->payload_length, plen);
950 56 : return 0;
951 : }
952 :
953 :
954 55 : static int ikev2_build_idr(struct ikev2_responder_data *data,
955 : struct wpabuf *msg, u8 next_payload)
956 : {
957 : struct ikev2_payload_hdr *phdr;
958 : size_t plen;
959 :
960 55 : wpa_printf(MSG_DEBUG, "IKEV2: Adding IDr payload");
961 :
962 55 : if (data->IDr == NULL) {
963 0 : wpa_printf(MSG_INFO, "IKEV2: No IDr available");
964 0 : return -1;
965 : }
966 :
967 : /* IDr - RFC 4306, Sect. 3.5 */
968 55 : phdr = wpabuf_put(msg, sizeof(*phdr));
969 55 : phdr->next_payload = next_payload;
970 55 : phdr->flags = 0;
971 55 : wpabuf_put_u8(msg, ID_KEY_ID);
972 55 : wpabuf_put(msg, 3); /* RESERVED */
973 55 : wpabuf_put_data(msg, data->IDr, data->IDr_len);
974 55 : plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) phdr;
975 55 : WPA_PUT_BE16(phdr->payload_length, plen);
976 55 : return 0;
977 : }
978 :
979 :
980 14 : static int ikev2_build_auth(struct ikev2_responder_data *data,
981 : struct wpabuf *msg, u8 next_payload)
982 : {
983 : struct ikev2_payload_hdr *phdr;
984 : size_t plen;
985 : const struct ikev2_prf_alg *prf;
986 :
987 14 : wpa_printf(MSG_DEBUG, "IKEV2: Adding AUTH payload");
988 :
989 14 : prf = ikev2_get_prf(data->proposal.prf);
990 14 : if (prf == NULL)
991 0 : return -1;
992 :
993 : /* Authentication - RFC 4306, Sect. 3.8 */
994 14 : phdr = wpabuf_put(msg, sizeof(*phdr));
995 14 : phdr->next_payload = next_payload;
996 14 : phdr->flags = 0;
997 14 : wpabuf_put_u8(msg, AUTH_SHARED_KEY_MIC);
998 14 : wpabuf_put(msg, 3); /* RESERVED */
999 :
1000 : /* msg | Ni | prf(SK_pr,IDr') */
1001 70 : if (ikev2_derive_auth_data(data->proposal.prf, data->r_sign_msg,
1002 14 : data->IDr, data->IDr_len, ID_KEY_ID,
1003 14 : &data->keys, 0, data->shared_secret,
1004 : data->shared_secret_len,
1005 14 : data->i_nonce, data->i_nonce_len,
1006 14 : data->key_pad, data->key_pad_len,
1007 14 : wpabuf_put(msg, prf->hash_len)) < 0) {
1008 2 : wpa_printf(MSG_INFO, "IKEV2: Could not derive AUTH data");
1009 2 : return -1;
1010 : }
1011 12 : wpabuf_free(data->r_sign_msg);
1012 12 : data->r_sign_msg = NULL;
1013 :
1014 12 : plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) phdr;
1015 12 : WPA_PUT_BE16(phdr->payload_length, plen);
1016 12 : return 0;
1017 : }
1018 :
1019 :
1020 3 : static int ikev2_build_notification(struct ikev2_responder_data *data,
1021 : struct wpabuf *msg, u8 next_payload)
1022 : {
1023 : struct ikev2_payload_hdr *phdr;
1024 : size_t plen;
1025 :
1026 3 : wpa_printf(MSG_DEBUG, "IKEV2: Adding Notification payload");
1027 :
1028 3 : if (data->error_type == 0) {
1029 0 : wpa_printf(MSG_INFO, "IKEV2: No Notify Message Type "
1030 : "available");
1031 0 : return -1;
1032 : }
1033 :
1034 : /* Notify - RFC 4306, Sect. 3.10 */
1035 3 : phdr = wpabuf_put(msg, sizeof(*phdr));
1036 3 : phdr->next_payload = next_payload;
1037 3 : phdr->flags = 0;
1038 3 : wpabuf_put_u8(msg, 0); /* Protocol ID: no existing SA */
1039 3 : wpabuf_put_u8(msg, 0); /* SPI Size */
1040 3 : wpabuf_put_be16(msg, data->error_type);
1041 :
1042 3 : switch (data->error_type) {
1043 : case INVALID_KE_PAYLOAD:
1044 1 : if (data->proposal.dh == -1) {
1045 0 : wpa_printf(MSG_INFO, "IKEV2: No DH Group selected for "
1046 : "INVALID_KE_PAYLOAD notifications");
1047 0 : return -1;
1048 : }
1049 1 : wpabuf_put_be16(msg, data->proposal.dh);
1050 1 : wpa_printf(MSG_DEBUG, "IKEV2: INVALID_KE_PAYLOAD - request "
1051 : "DH Group #%d", data->proposal.dh);
1052 1 : break;
1053 : case AUTHENTICATION_FAILED:
1054 : /* no associated data */
1055 2 : break;
1056 : default:
1057 0 : wpa_printf(MSG_INFO, "IKEV2: Unsupported Notify Message Type "
1058 0 : "%d", data->error_type);
1059 0 : return -1;
1060 : }
1061 :
1062 3 : plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) phdr;
1063 3 : WPA_PUT_BE16(phdr->payload_length, plen);
1064 3 : return 0;
1065 : }
1066 :
1067 :
1068 64 : static struct wpabuf * ikev2_build_sa_init(struct ikev2_responder_data *data)
1069 : {
1070 : struct wpabuf *msg;
1071 :
1072 : /* build IKE_SA_INIT: HDR, SAr1, KEr, Nr, [CERTREQ], [SK{IDr}] */
1073 :
1074 64 : if (os_get_random(data->r_spi, IKEV2_SPI_LEN))
1075 1 : return NULL;
1076 63 : wpa_hexdump(MSG_DEBUG, "IKEV2: IKE_SA Responder's SPI",
1077 63 : data->r_spi, IKEV2_SPI_LEN);
1078 :
1079 63 : data->r_nonce_len = IKEV2_NONCE_MIN_LEN;
1080 63 : if (random_get_bytes(data->r_nonce, data->r_nonce_len))
1081 1 : return NULL;
1082 62 : wpa_hexdump(MSG_DEBUG, "IKEV2: Nr", data->r_nonce, data->r_nonce_len);
1083 :
1084 62 : msg = wpabuf_alloc(sizeof(struct ikev2_hdr) + data->IDr_len + 1500);
1085 62 : if (msg == NULL)
1086 1 : return NULL;
1087 :
1088 61 : ikev2_build_hdr(data, msg, IKE_SA_INIT, IKEV2_PAYLOAD_SA, 0);
1089 122 : if (ikev2_build_sar1(data, msg, IKEV2_PAYLOAD_KEY_EXCHANGE) ||
1090 117 : ikev2_build_ker(data, msg, IKEV2_PAYLOAD_NONCE) ||
1091 56 : ikev2_build_nr(data, msg, data->peer_auth == PEER_AUTH_SECRET ?
1092 : IKEV2_PAYLOAD_ENCRYPTED :
1093 : IKEV2_PAYLOAD_NO_NEXT_PAYLOAD)) {
1094 5 : wpabuf_free(msg);
1095 5 : return NULL;
1096 : }
1097 :
1098 56 : if (ikev2_derive_keys(data)) {
1099 14 : wpabuf_free(msg);
1100 14 : return NULL;
1101 : }
1102 :
1103 42 : if (data->peer_auth == PEER_AUTH_CERT) {
1104 : /* TODO: CERTREQ with SHA-1 hashes of Subject Public Key Info
1105 : * for trust agents */
1106 : }
1107 :
1108 42 : if (data->peer_auth == PEER_AUTH_SECRET) {
1109 42 : struct wpabuf *plain = wpabuf_alloc(data->IDr_len + 1000);
1110 42 : if (plain == NULL) {
1111 1 : wpabuf_free(msg);
1112 1 : return NULL;
1113 : }
1114 41 : if (ikev2_build_idr(data, plain,
1115 41 : IKEV2_PAYLOAD_NO_NEXT_PAYLOAD) ||
1116 41 : ikev2_build_encrypted(data->proposal.encr,
1117 : data->proposal.integ,
1118 : &data->keys, 0, msg, plain,
1119 : IKEV2_PAYLOAD_IDr)) {
1120 4 : wpabuf_free(plain);
1121 4 : wpabuf_free(msg);
1122 4 : return NULL;
1123 : }
1124 37 : wpabuf_free(plain);
1125 : }
1126 :
1127 37 : ikev2_update_hdr(msg);
1128 :
1129 37 : wpa_hexdump_buf(MSG_MSGDUMP, "IKEV2: Sending message (SA_INIT)", msg);
1130 :
1131 37 : data->state = SA_AUTH;
1132 :
1133 37 : wpabuf_free(data->r_sign_msg);
1134 37 : data->r_sign_msg = wpabuf_dup(msg);
1135 :
1136 37 : return msg;
1137 : }
1138 :
1139 :
1140 16 : static struct wpabuf * ikev2_build_sa_auth(struct ikev2_responder_data *data)
1141 : {
1142 : struct wpabuf *msg, *plain;
1143 :
1144 : /* build IKE_SA_AUTH: HDR, SK {IDr, [CERT,] AUTH} */
1145 :
1146 16 : msg = wpabuf_alloc(sizeof(struct ikev2_hdr) + data->IDr_len + 1000);
1147 16 : if (msg == NULL)
1148 1 : return NULL;
1149 15 : ikev2_build_hdr(data, msg, IKE_SA_AUTH, IKEV2_PAYLOAD_ENCRYPTED, 1);
1150 :
1151 15 : plain = wpabuf_alloc(data->IDr_len + 1000);
1152 15 : if (plain == NULL) {
1153 1 : wpabuf_free(msg);
1154 1 : return NULL;
1155 : }
1156 :
1157 28 : if (ikev2_build_idr(data, plain, IKEV2_PAYLOAD_AUTHENTICATION) ||
1158 26 : ikev2_build_auth(data, plain, IKEV2_PAYLOAD_NO_NEXT_PAYLOAD) ||
1159 12 : ikev2_build_encrypted(data->proposal.encr, data->proposal.integ,
1160 : &data->keys, 0, msg, plain,
1161 : IKEV2_PAYLOAD_IDr)) {
1162 2 : wpabuf_free(plain);
1163 2 : wpabuf_free(msg);
1164 2 : return NULL;
1165 : }
1166 12 : wpabuf_free(plain);
1167 :
1168 12 : wpa_hexdump_buf(MSG_MSGDUMP, "IKEV2: Sending message (SA_AUTH)", msg);
1169 :
1170 12 : data->state = IKEV2_DONE;
1171 :
1172 12 : return msg;
1173 : }
1174 :
1175 :
1176 5 : static struct wpabuf * ikev2_build_notify(struct ikev2_responder_data *data)
1177 : {
1178 : struct wpabuf *msg;
1179 :
1180 5 : msg = wpabuf_alloc(sizeof(struct ikev2_hdr) + 1000);
1181 5 : if (msg == NULL)
1182 1 : return NULL;
1183 4 : if (data->last_msg == LAST_MSG_SA_AUTH) {
1184 : /* HDR, SK{N} */
1185 3 : struct wpabuf *plain = wpabuf_alloc(100);
1186 3 : if (plain == NULL) {
1187 1 : wpabuf_free(msg);
1188 1 : return NULL;
1189 : }
1190 2 : ikev2_build_hdr(data, msg, IKE_SA_AUTH,
1191 : IKEV2_PAYLOAD_ENCRYPTED, 1);
1192 2 : if (ikev2_build_notification(data, plain,
1193 2 : IKEV2_PAYLOAD_NO_NEXT_PAYLOAD) ||
1194 2 : ikev2_build_encrypted(data->proposal.encr,
1195 : data->proposal.integ,
1196 : &data->keys, 0, msg, plain,
1197 : IKEV2_PAYLOAD_NOTIFICATION)) {
1198 1 : wpabuf_free(plain);
1199 1 : wpabuf_free(msg);
1200 1 : return NULL;
1201 : }
1202 1 : wpabuf_free(plain);
1203 1 : data->state = IKEV2_FAILED;
1204 : } else {
1205 : /* HDR, N */
1206 1 : ikev2_build_hdr(data, msg, IKE_SA_INIT,
1207 : IKEV2_PAYLOAD_NOTIFICATION, 0);
1208 1 : if (ikev2_build_notification(data, msg,
1209 : IKEV2_PAYLOAD_NO_NEXT_PAYLOAD)) {
1210 0 : wpabuf_free(msg);
1211 0 : return NULL;
1212 : }
1213 1 : data->state = SA_INIT;
1214 : }
1215 :
1216 2 : ikev2_update_hdr(msg);
1217 :
1218 2 : wpa_hexdump_buf(MSG_MSGDUMP, "IKEV2: Sending message (Notification)",
1219 : msg);
1220 :
1221 2 : return msg;
1222 : }
1223 :
1224 :
1225 85 : struct wpabuf * ikev2_responder_build(struct ikev2_responder_data *data)
1226 : {
1227 85 : switch (data->state) {
1228 : case SA_INIT:
1229 64 : return ikev2_build_sa_init(data);
1230 : case SA_AUTH:
1231 16 : return ikev2_build_sa_auth(data);
1232 : case CHILD_SA:
1233 0 : return NULL;
1234 : case NOTIFY:
1235 5 : return ikev2_build_notify(data);
1236 : case IKEV2_DONE:
1237 : case IKEV2_FAILED:
1238 0 : return NULL;
1239 : }
1240 0 : return NULL;
1241 : }
|