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 60 : void ikev2_responder_deinit(struct ikev2_responder_data *data)
18 : {
19 60 : ikev2_free_keys(&data->keys);
20 60 : wpabuf_free(data->i_dh_public);
21 60 : wpabuf_free(data->r_dh_private);
22 60 : os_free(data->IDi);
23 60 : os_free(data->IDr);
24 60 : os_free(data->shared_secret);
25 60 : wpabuf_free(data->i_sign_msg);
26 60 : wpabuf_free(data->r_sign_msg);
27 60 : os_free(data->key_pad);
28 60 : }
29 :
30 :
31 12 : 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 12 : integ = ikev2_get_integ(data->proposal.integ);
46 12 : prf = ikev2_get_prf(data->proposal.prf);
47 12 : encr = ikev2_get_encr(data->proposal.encr);
48 12 : if (integ == NULL || prf == NULL || encr == NULL) {
49 0 : wpa_printf(MSG_INFO, "IKEV2: Unsupported proposal");
50 0 : return -1;
51 : }
52 :
53 12 : shared = dh_derive_shared(data->i_dh_public, data->r_dh_private,
54 : data->dh);
55 12 : if (shared == NULL)
56 1 : return -1;
57 :
58 : /* Construct Ni | Nr | SPIi | SPIr */
59 :
60 11 : buf_len = data->i_nonce_len + data->r_nonce_len + 2 * IKEV2_SPI_LEN;
61 11 : buf = os_malloc(buf_len);
62 11 : if (buf == NULL) {
63 0 : wpabuf_free(shared);
64 0 : return -1;
65 : }
66 :
67 11 : pos = buf;
68 11 : os_memcpy(pos, data->i_nonce, data->i_nonce_len);
69 11 : pos += data->i_nonce_len;
70 11 : os_memcpy(pos, data->r_nonce, data->r_nonce_len);
71 11 : pos += data->r_nonce_len;
72 11 : os_memcpy(pos, data->i_spi, IKEV2_SPI_LEN);
73 11 : pos += IKEV2_SPI_LEN;
74 11 : 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 11 : pad_len = data->dh->prime_len - wpabuf_len(shared);
79 11 : pad = os_zalloc(pad_len ? pad_len : 1);
80 11 : if (pad == NULL) {
81 0 : wpabuf_free(shared);
82 0 : os_free(buf);
83 0 : return -1;
84 : }
85 :
86 11 : addr[0] = pad;
87 11 : len[0] = pad_len;
88 11 : addr[1] = wpabuf_head(shared);
89 11 : len[1] = wpabuf_len(shared);
90 11 : if (ikev2_prf_hash(prf->id, buf, data->i_nonce_len + data->r_nonce_len,
91 : 2, addr, len, skeyseed) < 0) {
92 0 : wpabuf_free(shared);
93 0 : os_free(buf);
94 0 : os_free(pad);
95 0 : return -1;
96 : }
97 11 : os_free(pad);
98 11 : wpabuf_free(shared);
99 :
100 : /* DH parameters are not needed anymore, so free them */
101 11 : wpabuf_free(data->i_dh_public);
102 11 : data->i_dh_public = NULL;
103 11 : wpabuf_free(data->r_dh_private);
104 11 : data->r_dh_private = NULL;
105 :
106 11 : wpa_hexdump_key(MSG_DEBUG, "IKEV2: SKEYSEED",
107 : skeyseed, prf->hash_len);
108 :
109 11 : ret = ikev2_derive_sk_keys(prf, integ, encr, skeyseed, buf, buf_len,
110 : &data->keys);
111 11 : os_free(buf);
112 11 : return ret;
113 : }
114 :
115 :
116 107 : 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 107 : if (end - pos < (int) sizeof(*t)) {
125 1 : wpa_printf(MSG_INFO, "IKEV2: Too short transform");
126 1 : return -1;
127 : }
128 :
129 106 : t = (const struct ikev2_transform *) pos;
130 106 : transform_len = WPA_GET_BE16(t->transform_length);
131 106 : if (transform_len < (int) sizeof(*t) || pos + transform_len > end) {
132 2 : wpa_printf(MSG_INFO, "IKEV2: Invalid transform length %d",
133 : transform_len);
134 2 : return -1;
135 : }
136 104 : tend = pos + transform_len;
137 :
138 104 : transform_id = WPA_GET_BE16(t->transform_id);
139 :
140 104 : wpa_printf(MSG_DEBUG, "IKEV2: Transform:");
141 312 : wpa_printf(MSG_DEBUG, "IKEV2: Type: %d Transform Length: %d "
142 : "Transform Type: %d Transform ID: %d",
143 208 : t->type, transform_len, t->transform_type, transform_id);
144 :
145 104 : if (t->type != 0 && t->type != 3) {
146 1 : wpa_printf(MSG_INFO, "IKEV2: Unexpected Transform type");
147 1 : return -1;
148 : }
149 :
150 103 : pos = (const u8 *) (t + 1);
151 103 : if (pos < tend) {
152 14 : wpa_hexdump(MSG_DEBUG, "IKEV2: Transform Attributes",
153 14 : pos, tend - pos);
154 : }
155 :
156 103 : switch (t->transform_type) {
157 : case IKEV2_TRANSFORM_ENCR:
158 25 : if (ikev2_get_encr(transform_id)) {
159 25 : if (transform_id == ENCR_AES_CBC) {
160 14 : if (tend - pos != 4) {
161 1 : wpa_printf(MSG_DEBUG, "IKEV2: No "
162 : "Transform Attr for AES");
163 1 : break;
164 : }
165 13 : 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 12 : 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 22 : prop->encr = transform_id;
180 : }
181 22 : break;
182 : case IKEV2_TRANSFORM_PRF:
183 22 : if (ikev2_get_prf(transform_id))
184 22 : prop->prf = transform_id;
185 22 : break;
186 : case IKEV2_TRANSFORM_INTEG:
187 22 : if (ikev2_get_integ(transform_id))
188 22 : prop->integ = transform_id;
189 22 : break;
190 : case IKEV2_TRANSFORM_DH:
191 22 : if (dh_groups_get(transform_id))
192 22 : prop->dh = transform_id;
193 22 : break;
194 : }
195 :
196 103 : return transform_len;
197 : }
198 :
199 :
200 37 : 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 37 : 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 36 : p = (const struct ikev2_proposal *) pos;
215 36 : proposal_len = WPA_GET_BE16(p->proposal_length);
216 36 : 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 34 : wpa_printf(MSG_DEBUG, "IKEV2: SAi1 Proposal # %d",
222 34 : p->proposal_num);
223 68 : wpa_printf(MSG_DEBUG, "IKEV2: Type: %d Proposal Length: %d "
224 : " Protocol ID: %d",
225 68 : p->type, proposal_len, p->protocol_id);
226 68 : wpa_printf(MSG_DEBUG, "IKEV2: SPI Size: %d Transforms: %d",
227 68 : p->spi_size, p->num_transforms);
228 :
229 34 : if (p->type != 0 && p->type != 2) {
230 1 : wpa_printf(MSG_INFO, "IKEV2: Unexpected Proposal type");
231 1 : return -1;
232 : }
233 :
234 33 : 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 32 : 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 31 : ppos = (const u8 *) (p + 1);
250 31 : pend = pos + proposal_len;
251 31 : if (ppos + p->spi_size > pend) {
252 1 : wpa_printf(MSG_INFO, "IKEV2: Not enough room for SPI "
253 : "in proposal");
254 1 : return -1;
255 : }
256 30 : 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 30 : if (p->spi_size != 0) {
268 1 : wpa_printf(MSG_INFO, "IKEV2: Unexpected SPI Size");
269 1 : return -1;
270 : }
271 :
272 29 : if (p->num_transforms == 0) {
273 1 : wpa_printf(MSG_INFO, "IKEV2: At least one transform required");
274 1 : return -1;
275 : }
276 :
277 131 : for (i = 0; i < (int) p->num_transforms; i++) {
278 107 : int tlen = ikev2_parse_transform(prop, ppos, pend);
279 107 : if (tlen < 0)
280 4 : return -1;
281 103 : ppos += tlen;
282 : }
283 :
284 24 : if (ppos != pend) {
285 1 : wpa_printf(MSG_INFO, "IKEV2: Unexpected data after "
286 : "transforms");
287 1 : return -1;
288 : }
289 :
290 23 : return proposal_len;
291 : }
292 :
293 :
294 39 : 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 39 : int found = 0;
300 :
301 : /* Security Association Payloads: <Proposals> */
302 :
303 39 : if (sai1 == NULL) {
304 1 : wpa_printf(MSG_INFO, "IKEV2: SAi1 not received");
305 1 : return -1;
306 : }
307 :
308 38 : os_memset(&prop, 0, sizeof(prop));
309 38 : prop.proposal_num = 1;
310 :
311 38 : pos = sai1;
312 38 : end = sai1 + sai1_len;
313 :
314 99 : while (pos < end) {
315 : int plen;
316 :
317 37 : prop.integ = -1;
318 37 : prop.prf = -1;
319 37 : prop.encr = -1;
320 37 : prop.dh = -1;
321 37 : plen = ikev2_parse_proposal(&prop, pos, end);
322 37 : if (plen < 0)
323 14 : return -1;
324 :
325 45 : if (!found && prop.integ != -1 && prop.prf != -1 &&
326 44 : prop.encr != -1 && prop.dh != -1) {
327 22 : os_memcpy(&data->proposal, &prop, sizeof(prop));
328 22 : data->dh = dh_groups_get(prop.dh);
329 22 : found = 1;
330 : }
331 :
332 23 : pos += plen;
333 : }
334 :
335 24 : if (pos != end) {
336 0 : wpa_printf(MSG_INFO, "IKEV2: Unexpected data after proposals");
337 0 : return -1;
338 : }
339 :
340 24 : if (!found) {
341 2 : wpa_printf(MSG_INFO, "IKEV2: No acceptable proposal found");
342 2 : return -1;
343 : }
344 :
345 44 : wpa_printf(MSG_DEBUG, "IKEV2: Accepted proposal #%d: ENCR:%d PRF:%d "
346 22 : "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 22 : return 0;
351 : }
352 :
353 :
354 22 : 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 22 : if (kei == NULL) {
367 1 : wpa_printf(MSG_INFO, "IKEV2: KEi not received");
368 1 : return -1;
369 : }
370 :
371 21 : if (kei_len < 4 + 96) {
372 1 : wpa_printf(MSG_INFO, "IKEV2: Too short Key Exchange Payload");
373 1 : return -1;
374 : }
375 :
376 20 : group = WPA_GET_BE16(kei);
377 20 : wpa_printf(MSG_DEBUG, "IKEV2: KEi DH Group #%u", group);
378 :
379 20 : 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 19 : 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 19 : 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 18 : wpabuf_free(data->i_dh_public);
407 18 : data->i_dh_public = wpabuf_alloc(kei_len - 4);
408 18 : if (data->i_dh_public == NULL)
409 0 : return -1;
410 18 : wpabuf_put_data(data->i_dh_public, kei + 4, kei_len - 4);
411 :
412 18 : wpa_hexdump_buf(MSG_DEBUG, "IKEV2: KEi Diffie-Hellman Public Value",
413 18 : data->i_dh_public);
414 :
415 18 : return 0;
416 : }
417 :
418 :
419 18 : static int ikev2_process_ni(struct ikev2_responder_data *data,
420 : const u8 *ni, size_t ni_len)
421 : {
422 18 : if (ni == NULL) {
423 1 : wpa_printf(MSG_INFO, "IKEV2: Ni not received");
424 1 : return -1;
425 : }
426 :
427 17 : 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 15 : data->i_nonce_len = ni_len;
434 15 : os_memcpy(data->i_nonce, ni, ni_len);
435 30 : wpa_hexdump(MSG_MSGDUMP, "IKEV2: Ni",
436 15 : data->i_nonce, data->i_nonce_len);
437 :
438 15 : return 0;
439 : }
440 :
441 :
442 39 : static int ikev2_process_sa_init(struct ikev2_responder_data *data,
443 : const struct ikev2_hdr *hdr,
444 : struct ikev2_payloads *pl)
445 : {
446 61 : if (ikev2_process_sai1(data, pl->sa, pl->sa_len) < 0 ||
447 40 : ikev2_process_kei(data, pl->ke, pl->ke_len) < 0 ||
448 18 : ikev2_process_ni(data, pl->nonce, pl->nonce_len) < 0)
449 24 : return -1;
450 :
451 15 : os_memcpy(data->i_spi, hdr->i_spi, IKEV2_SPI_LEN);
452 :
453 15 : return 0;
454 : }
455 :
456 :
457 7 : 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 7 : if (idi == NULL) {
463 0 : wpa_printf(MSG_INFO, "IKEV2: No IDi received");
464 0 : return -1;
465 : }
466 :
467 7 : if (idi_len < 4) {
468 0 : wpa_printf(MSG_INFO, "IKEV2: Too short IDi payload");
469 0 : return -1;
470 : }
471 :
472 7 : id_type = idi[0];
473 7 : idi += 4;
474 7 : idi_len -= 4;
475 :
476 7 : wpa_printf(MSG_DEBUG, "IKEV2: IDi ID Type %d", id_type);
477 7 : wpa_hexdump_ascii(MSG_DEBUG, "IKEV2: IDi", idi, idi_len);
478 7 : os_free(data->IDi);
479 7 : data->IDi = os_malloc(idi_len);
480 7 : if (data->IDi == NULL)
481 0 : return -1;
482 7 : os_memcpy(data->IDi, idi, idi_len);
483 7 : data->IDi_len = idi_len;
484 7 : data->IDi_type = id_type;
485 :
486 7 : return 0;
487 : }
488 :
489 :
490 7 : 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 7 : if (cert == NULL) {
496 7 : if (data->peer_auth == PEER_AUTH_CERT) {
497 0 : wpa_printf(MSG_INFO, "IKEV2: No Certificate received");
498 0 : return -1;
499 : }
500 7 : 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 7 : 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 7 : 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 42 : if (ikev2_derive_auth_data(data->proposal.prf, data->i_sign_msg,
550 14 : data->IDi, data->IDi_len, data->IDi_type,
551 7 : &data->keys, 1, data->shared_secret,
552 : data->shared_secret_len,
553 7 : data->r_nonce, data->r_nonce_len,
554 7 : data->key_pad, data->key_pad_len,
555 : auth_data) < 0) {
556 0 : wpa_printf(MSG_INFO, "IKEV2: Could not derive AUTH data");
557 0 : return -1;
558 : }
559 :
560 7 : wpabuf_free(data->i_sign_msg);
561 7 : data->i_sign_msg = NULL;
562 :
563 7 : prf = ikev2_get_prf(data->proposal.prf);
564 7 : if (prf == NULL)
565 0 : return -1;
566 :
567 14 : if (auth_len != prf->hash_len ||
568 7 : os_memcmp_const(auth, auth_data, auth_len) != 0) {
569 1 : wpa_printf(MSG_INFO, "IKEV2: Invalid Authentication Data");
570 1 : wpa_hexdump(MSG_DEBUG, "IKEV2: Received Authentication Data",
571 : auth, auth_len);
572 1 : wpa_hexdump(MSG_DEBUG, "IKEV2: Expected Authentication Data",
573 : auth_data, prf->hash_len);
574 1 : data->error_type = AUTHENTICATION_FAILED;
575 1 : data->state = NOTIFY;
576 1 : return -1;
577 : }
578 :
579 6 : wpa_printf(MSG_DEBUG, "IKEV2: Server authenticated successfully "
580 : "using shared keys");
581 :
582 6 : return 0;
583 : }
584 :
585 :
586 7 : 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 7 : if (auth == NULL) {
592 0 : wpa_printf(MSG_INFO, "IKEV2: No Authentication Payload");
593 0 : return -1;
594 : }
595 :
596 7 : if (auth_len < 4) {
597 0 : wpa_printf(MSG_INFO, "IKEV2: Too short Authentication "
598 : "Payload");
599 0 : return -1;
600 : }
601 :
602 7 : auth_method = auth[0];
603 7 : auth += 4;
604 7 : auth_len -= 4;
605 :
606 7 : wpa_printf(MSG_DEBUG, "IKEV2: Auth Method %d", auth_method);
607 7 : wpa_hexdump(MSG_MSGDUMP, "IKEV2: Authentication Data", auth, auth_len);
608 :
609 7 : 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 7 : return ikev2_process_auth_secret(data, auth_method, auth,
615 : auth_len);
616 : }
617 :
618 0 : return -1;
619 : }
620 :
621 :
622 7 : 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 7 : wpa_printf(MSG_DEBUG, "IKEV2: Processing decrypted payloads");
629 :
630 7 : 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 14 : if (ikev2_process_idi(data, pl.idi, pl.idi_len) < 0 ||
638 14 : ikev2_process_cert(data, pl.cert, pl.cert_len) < 0 ||
639 7 : ikev2_process_auth(data, pl.auth, pl.auth_len) < 0)
640 1 : return -1;
641 :
642 6 : return 0;
643 : }
644 :
645 :
646 7 : 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 7 : 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 7 : if (decrypted == NULL)
659 0 : return -1;
660 :
661 7 : ret = ikev2_process_sa_auth_decrypted(data, pl->encr_next_payload,
662 : decrypted, decrypted_len);
663 7 : os_free(decrypted);
664 :
665 7 : return ret;
666 : }
667 :
668 :
669 55 : static int ikev2_validate_rx_state(struct ikev2_responder_data *data,
670 : u8 exchange_type, u32 message_id)
671 : {
672 55 : switch (data->state) {
673 : case SA_INIT:
674 : /* Expect to receive IKE_SA_INIT: HDR, SAi1, KEi, Ni */
675 48 : 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 47 : 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 46 : 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 7 : 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 7 : 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 7 : 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 53 : return 0;
721 : }
722 :
723 :
724 60 : 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 60 : wpa_printf(MSG_MSGDUMP, "IKEV2: Received message (len %lu)",
733 : (unsigned long) wpabuf_len(buf));
734 :
735 60 : if (wpabuf_len(buf) < sizeof(*hdr)) {
736 3 : wpa_printf(MSG_INFO, "IKEV2: Too short frame to include HDR");
737 3 : return -1;
738 : }
739 :
740 57 : data->error_type = 0;
741 57 : hdr = (const struct ikev2_hdr *) wpabuf_head(buf);
742 57 : end = wpabuf_head_u8(buf) + wpabuf_len(buf);
743 57 : message_id = WPA_GET_BE32(hdr->message_id);
744 57 : length = WPA_GET_BE32(hdr->length);
745 :
746 57 : wpa_hexdump(MSG_DEBUG, "IKEV2: IKE_SA Initiator's SPI",
747 57 : hdr->i_spi, IKEV2_SPI_LEN);
748 57 : wpa_hexdump(MSG_DEBUG, "IKEV2: IKE_SA Responder's SPI",
749 57 : hdr->r_spi, IKEV2_SPI_LEN);
750 171 : wpa_printf(MSG_DEBUG, "IKEV2: Next Payload: %u Version: 0x%x "
751 : "Exchange Type: %u",
752 171 : hdr->next_payload, hdr->version, hdr->exchange_type);
753 57 : wpa_printf(MSG_DEBUG, "IKEV2: Message ID: %u Length: %u",
754 : message_id, length);
755 :
756 57 : 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 56 : 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 55 : if (ikev2_validate_rx_state(data, hdr->exchange_type, message_id) < 0)
770 2 : return -1;
771 :
772 53 : 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 51 : if (data->state != SA_INIT) {
780 7 : 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 7 : 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 51 : pos = (const u8 *) (hdr + 1);
793 51 : if (ikev2_parse_payloads(&pl, hdr->next_payload, pos, end) < 0)
794 5 : return -1;
795 :
796 46 : if (data->state == SA_INIT) {
797 39 : data->last_msg = LAST_MSG_SA_INIT;
798 39 : if (ikev2_process_sa_init(data, hdr, &pl) < 0) {
799 24 : if (data->state == NOTIFY)
800 1 : return 0;
801 23 : return -1;
802 : }
803 15 : wpabuf_free(data->i_sign_msg);
804 15 : data->i_sign_msg = wpabuf_dup(buf);
805 : }
806 :
807 22 : if (data->state == SA_AUTH) {
808 7 : data->last_msg = LAST_MSG_SA_AUTH;
809 7 : if (ikev2_process_sa_auth(data, hdr, &pl) < 0) {
810 1 : if (data->state == NOTIFY)
811 1 : return 0;
812 0 : return -1;
813 : }
814 : }
815 :
816 21 : return 0;
817 : }
818 :
819 :
820 23 : 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 23 : wpa_printf(MSG_DEBUG, "IKEV2: Adding HDR");
827 :
828 : /* HDR - RFC 4306, Sect. 3.1 */
829 23 : hdr = wpabuf_put(msg, sizeof(*hdr));
830 23 : os_memcpy(hdr->i_spi, data->i_spi, IKEV2_SPI_LEN);
831 23 : os_memcpy(hdr->r_spi, data->r_spi, IKEV2_SPI_LEN);
832 23 : hdr->next_payload = next_payload;
833 23 : hdr->version = IKEV2_VERSION;
834 23 : hdr->exchange_type = exchange_type;
835 23 : hdr->flags = IKEV2_HDR_RESPONSE;
836 23 : WPA_PUT_BE32(hdr->message_id, message_id);
837 23 : }
838 :
839 :
840 15 : 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 15 : wpa_printf(MSG_DEBUG, "IKEV2: Adding SAr1 payload");
849 :
850 : /* SAr1 - RFC 4306, Sect. 2.7 and 3.3 */
851 15 : phdr = wpabuf_put(msg, sizeof(*phdr));
852 15 : phdr->next_payload = next_payload;
853 15 : phdr->flags = 0;
854 :
855 15 : p = wpabuf_put(msg, sizeof(*p));
856 15 : p->proposal_num = data->proposal.proposal_num;
857 15 : p->protocol_id = IKEV2_PROTOCOL_IKE;
858 15 : p->num_transforms = 4;
859 :
860 15 : t = wpabuf_put(msg, sizeof(*t));
861 15 : t->type = 3;
862 15 : t->transform_type = IKEV2_TRANSFORM_ENCR;
863 15 : WPA_PUT_BE16(t->transform_id, data->proposal.encr);
864 15 : if (data->proposal.encr == ENCR_AES_CBC) {
865 : /* Transform Attribute: Key Len = 128 bits */
866 11 : wpabuf_put_be16(msg, 0x800e); /* AF=1, AttrType=14 */
867 11 : wpabuf_put_be16(msg, 128); /* 128-bit key */
868 : }
869 15 : plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) t;
870 15 : WPA_PUT_BE16(t->transform_length, plen);
871 :
872 15 : t = wpabuf_put(msg, sizeof(*t));
873 15 : t->type = 3;
874 15 : WPA_PUT_BE16(t->transform_length, sizeof(*t));
875 15 : t->transform_type = IKEV2_TRANSFORM_PRF;
876 15 : WPA_PUT_BE16(t->transform_id, data->proposal.prf);
877 :
878 15 : t = wpabuf_put(msg, sizeof(*t));
879 15 : t->type = 3;
880 15 : WPA_PUT_BE16(t->transform_length, sizeof(*t));
881 15 : t->transform_type = IKEV2_TRANSFORM_INTEG;
882 15 : WPA_PUT_BE16(t->transform_id, data->proposal.integ);
883 :
884 15 : t = wpabuf_put(msg, sizeof(*t));
885 15 : WPA_PUT_BE16(t->transform_length, sizeof(*t));
886 15 : t->transform_type = IKEV2_TRANSFORM_DH;
887 15 : WPA_PUT_BE16(t->transform_id, data->proposal.dh);
888 :
889 15 : plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) p;
890 15 : WPA_PUT_BE16(p->proposal_length, plen);
891 :
892 15 : plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) phdr;
893 15 : WPA_PUT_BE16(phdr->payload_length, plen);
894 :
895 15 : return 0;
896 : }
897 :
898 :
899 15 : 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 15 : wpa_printf(MSG_DEBUG, "IKEV2: Adding KEr payload");
907 :
908 15 : pv = dh_init(data->dh, &data->r_dh_private);
909 15 : if (pv == NULL) {
910 3 : wpa_printf(MSG_DEBUG, "IKEV2: Failed to initialize DH");
911 3 : return -1;
912 : }
913 :
914 : /* KEr - RFC 4306, Sect. 3.4 */
915 12 : phdr = wpabuf_put(msg, sizeof(*phdr));
916 12 : phdr->next_payload = next_payload;
917 12 : phdr->flags = 0;
918 :
919 12 : wpabuf_put_be16(msg, data->proposal.dh); /* DH Group # */
920 12 : 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 12 : wpabuf_put(msg, data->dh->prime_len - wpabuf_len(pv));
926 12 : wpabuf_put_buf(msg, pv);
927 12 : wpabuf_free(pv);
928 :
929 12 : plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) phdr;
930 12 : WPA_PUT_BE16(phdr->payload_length, plen);
931 12 : return 0;
932 : }
933 :
934 :
935 12 : 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 12 : wpa_printf(MSG_DEBUG, "IKEV2: Adding Nr payload");
942 :
943 : /* Nr - RFC 4306, Sect. 3.9 */
944 12 : phdr = wpabuf_put(msg, sizeof(*phdr));
945 12 : phdr->next_payload = next_payload;
946 12 : phdr->flags = 0;
947 12 : wpabuf_put_data(msg, data->r_nonce, data->r_nonce_len);
948 12 : plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) phdr;
949 12 : WPA_PUT_BE16(phdr->payload_length, plen);
950 12 : return 0;
951 : }
952 :
953 :
954 17 : 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 17 : wpa_printf(MSG_DEBUG, "IKEV2: Adding IDr payload");
961 :
962 17 : 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 17 : phdr = wpabuf_put(msg, sizeof(*phdr));
969 17 : phdr->next_payload = next_payload;
970 17 : phdr->flags = 0;
971 17 : wpabuf_put_u8(msg, ID_KEY_ID);
972 17 : wpabuf_put(msg, 3); /* RESERVED */
973 17 : wpabuf_put_data(msg, data->IDr, data->IDr_len);
974 17 : plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) phdr;
975 17 : WPA_PUT_BE16(phdr->payload_length, plen);
976 17 : return 0;
977 : }
978 :
979 :
980 6 : 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 6 : wpa_printf(MSG_DEBUG, "IKEV2: Adding AUTH payload");
988 :
989 6 : prf = ikev2_get_prf(data->proposal.prf);
990 6 : if (prf == NULL)
991 0 : return -1;
992 :
993 : /* Authentication - RFC 4306, Sect. 3.8 */
994 6 : phdr = wpabuf_put(msg, sizeof(*phdr));
995 6 : phdr->next_payload = next_payload;
996 6 : phdr->flags = 0;
997 6 : wpabuf_put_u8(msg, AUTH_SHARED_KEY_MIC);
998 6 : wpabuf_put(msg, 3); /* RESERVED */
999 :
1000 : /* msg | Ni | prf(SK_pr,IDr') */
1001 30 : if (ikev2_derive_auth_data(data->proposal.prf, data->r_sign_msg,
1002 6 : data->IDr, data->IDr_len, ID_KEY_ID,
1003 6 : &data->keys, 0, data->shared_secret,
1004 : data->shared_secret_len,
1005 6 : data->i_nonce, data->i_nonce_len,
1006 6 : data->key_pad, data->key_pad_len,
1007 6 : wpabuf_put(msg, prf->hash_len)) < 0) {
1008 0 : wpa_printf(MSG_INFO, "IKEV2: Could not derive AUTH data");
1009 0 : return -1;
1010 : }
1011 6 : wpabuf_free(data->r_sign_msg);
1012 6 : data->r_sign_msg = NULL;
1013 :
1014 6 : plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) phdr;
1015 6 : WPA_PUT_BE16(phdr->payload_length, plen);
1016 6 : return 0;
1017 : }
1018 :
1019 :
1020 2 : 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 2 : wpa_printf(MSG_DEBUG, "IKEV2: Adding Notification payload");
1027 :
1028 2 : 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 2 : phdr = wpabuf_put(msg, sizeof(*phdr));
1036 2 : phdr->next_payload = next_payload;
1037 2 : phdr->flags = 0;
1038 2 : wpabuf_put_u8(msg, 0); /* Protocol ID: no existing SA */
1039 2 : wpabuf_put_u8(msg, 0); /* SPI Size */
1040 2 : wpabuf_put_be16(msg, data->error_type);
1041 :
1042 2 : 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 1 : 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 2 : plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) phdr;
1063 2 : WPA_PUT_BE16(phdr->payload_length, plen);
1064 2 : return 0;
1065 : }
1066 :
1067 :
1068 15 : 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 15 : if (os_get_random(data->r_spi, IKEV2_SPI_LEN))
1075 0 : return NULL;
1076 15 : wpa_hexdump(MSG_DEBUG, "IKEV2: IKE_SA Responder's SPI",
1077 15 : data->r_spi, IKEV2_SPI_LEN);
1078 :
1079 15 : data->r_nonce_len = IKEV2_NONCE_MIN_LEN;
1080 15 : if (random_get_bytes(data->r_nonce, data->r_nonce_len))
1081 0 : return NULL;
1082 15 : wpa_hexdump(MSG_DEBUG, "IKEV2: Nr", data->r_nonce, data->r_nonce_len);
1083 :
1084 15 : msg = wpabuf_alloc(sizeof(struct ikev2_hdr) + data->IDr_len + 1500);
1085 15 : if (msg == NULL)
1086 0 : return NULL;
1087 :
1088 15 : ikev2_build_hdr(data, msg, IKE_SA_INIT, IKEV2_PAYLOAD_SA, 0);
1089 30 : if (ikev2_build_sar1(data, msg, IKEV2_PAYLOAD_KEY_EXCHANGE) ||
1090 27 : ikev2_build_ker(data, msg, IKEV2_PAYLOAD_NONCE) ||
1091 12 : ikev2_build_nr(data, msg, data->peer_auth == PEER_AUTH_SECRET ?
1092 : IKEV2_PAYLOAD_ENCRYPTED :
1093 : IKEV2_PAYLOAD_NO_NEXT_PAYLOAD)) {
1094 3 : wpabuf_free(msg);
1095 3 : return NULL;
1096 : }
1097 :
1098 12 : if (ikev2_derive_keys(data)) {
1099 1 : wpabuf_free(msg);
1100 1 : return NULL;
1101 : }
1102 :
1103 11 : 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 11 : if (data->peer_auth == PEER_AUTH_SECRET) {
1109 11 : struct wpabuf *plain = wpabuf_alloc(data->IDr_len + 1000);
1110 11 : if (plain == NULL) {
1111 0 : wpabuf_free(msg);
1112 0 : return NULL;
1113 : }
1114 11 : if (ikev2_build_idr(data, plain,
1115 11 : IKEV2_PAYLOAD_NO_NEXT_PAYLOAD) ||
1116 11 : ikev2_build_encrypted(data->proposal.encr,
1117 : data->proposal.integ,
1118 : &data->keys, 0, msg, plain,
1119 : IKEV2_PAYLOAD_IDr)) {
1120 0 : wpabuf_free(plain);
1121 0 : wpabuf_free(msg);
1122 0 : return NULL;
1123 : }
1124 11 : wpabuf_free(plain);
1125 : }
1126 :
1127 11 : ikev2_update_hdr(msg);
1128 :
1129 11 : wpa_hexdump_buf(MSG_MSGDUMP, "IKEV2: Sending message (SA_INIT)", msg);
1130 :
1131 11 : data->state = SA_AUTH;
1132 :
1133 11 : wpabuf_free(data->r_sign_msg);
1134 11 : data->r_sign_msg = wpabuf_dup(msg);
1135 :
1136 11 : return msg;
1137 : }
1138 :
1139 :
1140 6 : 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 6 : msg = wpabuf_alloc(sizeof(struct ikev2_hdr) + data->IDr_len + 1000);
1147 6 : if (msg == NULL)
1148 0 : return NULL;
1149 6 : ikev2_build_hdr(data, msg, IKE_SA_AUTH, IKEV2_PAYLOAD_ENCRYPTED, 1);
1150 :
1151 6 : plain = wpabuf_alloc(data->IDr_len + 1000);
1152 6 : if (plain == NULL) {
1153 0 : wpabuf_free(msg);
1154 0 : return NULL;
1155 : }
1156 :
1157 12 : if (ikev2_build_idr(data, plain, IKEV2_PAYLOAD_AUTHENTICATION) ||
1158 12 : ikev2_build_auth(data, plain, IKEV2_PAYLOAD_NO_NEXT_PAYLOAD) ||
1159 6 : ikev2_build_encrypted(data->proposal.encr, data->proposal.integ,
1160 : &data->keys, 0, msg, plain,
1161 : IKEV2_PAYLOAD_IDr)) {
1162 0 : wpabuf_free(plain);
1163 0 : wpabuf_free(msg);
1164 0 : return NULL;
1165 : }
1166 6 : wpabuf_free(plain);
1167 :
1168 6 : wpa_hexdump_buf(MSG_MSGDUMP, "IKEV2: Sending message (SA_AUTH)", msg);
1169 :
1170 6 : data->state = IKEV2_DONE;
1171 :
1172 6 : return msg;
1173 : }
1174 :
1175 :
1176 2 : static struct wpabuf * ikev2_build_notify(struct ikev2_responder_data *data)
1177 : {
1178 : struct wpabuf *msg;
1179 :
1180 2 : msg = wpabuf_alloc(sizeof(struct ikev2_hdr) + 1000);
1181 2 : if (msg == NULL)
1182 0 : return NULL;
1183 2 : if (data->last_msg == LAST_MSG_SA_AUTH) {
1184 : /* HDR, SK{N} */
1185 1 : struct wpabuf *plain = wpabuf_alloc(100);
1186 1 : if (plain == NULL) {
1187 0 : wpabuf_free(msg);
1188 0 : return NULL;
1189 : }
1190 1 : ikev2_build_hdr(data, msg, IKE_SA_AUTH,
1191 : IKEV2_PAYLOAD_ENCRYPTED, 1);
1192 1 : if (ikev2_build_notification(data, plain,
1193 1 : IKEV2_PAYLOAD_NO_NEXT_PAYLOAD) ||
1194 1 : ikev2_build_encrypted(data->proposal.encr,
1195 : data->proposal.integ,
1196 : &data->keys, 0, msg, plain,
1197 : IKEV2_PAYLOAD_NOTIFICATION)) {
1198 0 : wpabuf_free(plain);
1199 0 : wpabuf_free(msg);
1200 0 : 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 23 : struct wpabuf * ikev2_responder_build(struct ikev2_responder_data *data)
1226 : {
1227 23 : switch (data->state) {
1228 : case SA_INIT:
1229 15 : return ikev2_build_sa_init(data);
1230 : case SA_AUTH:
1231 6 : return ikev2_build_sa_auth(data);
1232 : case CHILD_SA:
1233 0 : return NULL;
1234 : case NOTIFY:
1235 2 : return ikev2_build_notify(data);
1236 : case IKEV2_DONE:
1237 : case IKEV2_FAILED:
1238 0 : return NULL;
1239 : }
1240 0 : return NULL;
1241 : }
|