xref: /openbsd-src/sbin/iked/ikev2_msg.c (revision 42ac1f71ddfc8f2b1ea1555399aa1e1ffc2faced)
1 /*	$OpenBSD: ikev2_msg.c,v 1.85 2022/03/14 12:58:55 tobhe Exp $	*/
2 
3 /*
4  * Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de>
5  * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include <sys/types.h>
21 #include <sys/queue.h>
22 #include <sys/socket.h>
23 #include <sys/uio.h>
24 
25 #include <netinet/in.h>
26 #include <arpa/inet.h>
27 
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <syslog.h>
31 #include <unistd.h>
32 #include <string.h>
33 #include <signal.h>
34 #include <errno.h>
35 #include <err.h>
36 #include <event.h>
37 
38 #include <openssl/sha.h>
39 #include <openssl/evp.h>
40 
41 #include "iked.h"
42 #include "ikev2.h"
43 #include "eap.h"
44 #include "dh.h"
45 
46 void	 ikev1_recv(struct iked *, struct iked_message *);
47 void	 ikev2_msg_response_timeout(struct iked *, void *);
48 void	 ikev2_msg_retransmit_timeout(struct iked *, void *);
49 int	 ikev2_check_frag_oversize(struct iked_sa *, struct ibuf *);
50 int	 ikev2_send_encrypted_fragments(struct iked *, struct iked_sa *,
51 	    struct ibuf *, uint8_t, uint8_t, int);
52 int	 ikev2_msg_encrypt_prepare(struct iked_sa *, struct ikev2_payload *,
53 	    struct ibuf*, struct ibuf *, struct ike_header *, uint8_t, int);
54 
55 void
56 ikev2_msg_cb(int fd, short event, void *arg)
57 {
58 	struct iked_socket	*sock = arg;
59 	struct iked		*env = sock->sock_env;
60 	struct iked_message	 msg;
61 	struct ike_header	 hdr;
62 	uint32_t		 natt = 0x00000000;
63 	uint8_t			 buf[IKED_MSGBUF_MAX];
64 	ssize_t			 len;
65 	off_t			 off;
66 
67 	bzero(&msg, sizeof(msg));
68 	bzero(buf, sizeof(buf));
69 
70 	msg.msg_peerlen = sizeof(msg.msg_peer);
71 	msg.msg_locallen = sizeof(msg.msg_local);
72 	msg.msg_parent = &msg;
73 	memcpy(&msg.msg_local, &sock->sock_addr, sizeof(sock->sock_addr));
74 
75 	if ((len = recvfromto(fd, buf, sizeof(buf), 0,
76 	    (struct sockaddr *)&msg.msg_peer, &msg.msg_peerlen,
77 	    (struct sockaddr *)&msg.msg_local, &msg.msg_locallen)) <
78 	    (ssize_t)sizeof(natt))
79 		return;
80 
81 	if (socket_getport((struct sockaddr *)&msg.msg_local) ==
82 	    env->sc_nattport) {
83 		if (memcmp(&natt, buf, sizeof(natt)) != 0)
84 			return;
85 		msg.msg_natt = 1;
86 		off = sizeof(natt);
87 	} else
88 		off = 0;
89 
90 	if ((size_t)(len - off) <= sizeof(hdr))
91 		return;
92 	memcpy(&hdr, buf + off, sizeof(hdr));
93 
94 	if ((msg.msg_data = ibuf_new(buf + off, len - off)) == NULL)
95 		return;
96 
97 	TAILQ_INIT(&msg.msg_proposals);
98 	SIMPLEQ_INIT(&msg.msg_certreqs);
99 	msg.msg_fd = fd;
100 
101 	if (hdr.ike_version == IKEV1_VERSION)
102 		ikev1_recv(env, &msg);
103 	else
104 		ikev2_recv(env, &msg);
105 
106 	ikev2_msg_cleanup(env, &msg);
107 }
108 
109 void
110 ikev1_recv(struct iked *env, struct iked_message *msg)
111 {
112 	struct ike_header	*hdr;
113 
114 	if (ibuf_size(msg->msg_data) <= sizeof(*hdr)) {
115 		log_debug("%s: short message", __func__);
116 		return;
117 	}
118 
119 	hdr = (struct ike_header *)ibuf_data(msg->msg_data);
120 
121 	log_debug("%s: header ispi %s rspi %s"
122 	    " nextpayload %u version 0x%02x exchange %u flags 0x%02x"
123 	    " msgid %u length %u", __func__,
124 	    print_spi(betoh64(hdr->ike_ispi), 8),
125 	    print_spi(betoh64(hdr->ike_rspi), 8),
126 	    hdr->ike_nextpayload,
127 	    hdr->ike_version,
128 	    hdr->ike_exchange,
129 	    hdr->ike_flags,
130 	    betoh32(hdr->ike_msgid),
131 	    betoh32(hdr->ike_length));
132 
133 	log_debug("%s: IKEv1 not supported", __func__);
134 }
135 
136 struct ibuf *
137 ikev2_msg_init(struct iked *env, struct iked_message *msg,
138     struct sockaddr_storage *peer, socklen_t peerlen,
139     struct sockaddr_storage *local, socklen_t locallen, int response)
140 {
141 	bzero(msg, sizeof(*msg));
142 	memcpy(&msg->msg_peer, peer, peerlen);
143 	msg->msg_peerlen = peerlen;
144 	memcpy(&msg->msg_local, local, locallen);
145 	msg->msg_locallen = locallen;
146 	msg->msg_response = response ? 1 : 0;
147 	msg->msg_fd = -1;
148 	msg->msg_data = ibuf_static();
149 	msg->msg_e = 0;
150 	msg->msg_parent = msg;	/* has to be set */
151 	TAILQ_INIT(&msg->msg_proposals);
152 
153 	return (msg->msg_data);
154 }
155 
156 struct iked_message *
157 ikev2_msg_copy(struct iked *env, struct iked_message *msg)
158 {
159 	struct iked_message		*m = NULL;
160 	struct ibuf			*buf;
161 	size_t				 len;
162 	void				*ptr;
163 
164 	if (ibuf_size(msg->msg_data) < msg->msg_offset)
165 		return (NULL);
166 	len = ibuf_size(msg->msg_data) - msg->msg_offset;
167 
168 	if ((m = malloc(sizeof(*m))) == NULL)
169 		return (NULL);
170 
171 	if ((ptr = ibuf_seek(msg->msg_data, msg->msg_offset, len)) == NULL ||
172 	    (buf = ikev2_msg_init(env, m, &msg->msg_peer, msg->msg_peerlen,
173 	     &msg->msg_local, msg->msg_locallen, msg->msg_response)) == NULL ||
174 	    ibuf_add(buf, ptr, len)) {
175 		free(m);
176 		return (NULL);
177 	}
178 
179 	m->msg_fd = msg->msg_fd;
180 	m->msg_msgid = msg->msg_msgid;
181 	m->msg_offset = msg->msg_offset;
182 	m->msg_sa = msg->msg_sa;
183 
184 	return (m);
185 }
186 
187 void
188 ikev2_msg_cleanup(struct iked *env, struct iked_message *msg)
189 {
190 	struct iked_certreq	*cr;
191 
192 	if (msg == msg->msg_parent) {
193 		ibuf_release(msg->msg_nonce);
194 		ibuf_release(msg->msg_ke);
195 		ibuf_release(msg->msg_auth.id_buf);
196 		ibuf_release(msg->msg_peerid.id_buf);
197 		ibuf_release(msg->msg_localid.id_buf);
198 		ibuf_release(msg->msg_cert.id_buf);
199 		ibuf_release(msg->msg_cookie);
200 		ibuf_release(msg->msg_cookie2);
201 		ibuf_release(msg->msg_del_buf);
202 		free(msg->msg_eap.eam_user);
203 		free(msg->msg_cp_addr);
204 		free(msg->msg_cp_addr6);
205 		free(msg->msg_cp_dns);
206 
207 		msg->msg_nonce = NULL;
208 		msg->msg_ke = NULL;
209 		msg->msg_auth.id_buf = NULL;
210 		msg->msg_peerid.id_buf = NULL;
211 		msg->msg_localid.id_buf = NULL;
212 		msg->msg_cert.id_buf = NULL;
213 		msg->msg_cookie = NULL;
214 		msg->msg_cookie2 = NULL;
215 		msg->msg_del_buf = NULL;
216 		msg->msg_eap.eam_user = NULL;
217 		msg->msg_cp_addr = NULL;
218 		msg->msg_cp_addr6 = NULL;
219 		msg->msg_cp_dns = NULL;
220 
221 		config_free_proposals(&msg->msg_proposals, 0);
222 		while ((cr = SIMPLEQ_FIRST(&msg->msg_certreqs))) {
223 			ibuf_release(cr->cr_data);
224 			SIMPLEQ_REMOVE_HEAD(&msg->msg_certreqs, cr_entry);
225 			free(cr);
226 		}
227 	}
228 
229 	if (msg->msg_data != NULL) {
230 		ibuf_release(msg->msg_data);
231 		msg->msg_data = NULL;
232 	}
233 }
234 
235 int
236 ikev2_msg_valid_ike_sa(struct iked *env, struct ike_header *oldhdr,
237     struct iked_message *msg)
238 {
239 	if (msg->msg_sa != NULL && msg->msg_policy != NULL) {
240 		if (msg->msg_sa->sa_state == IKEV2_STATE_CLOSED)
241 			return (-1);
242 		/*
243 		 * Only permit informational requests from initiator
244 		 * on closing SAs (for DELETE).
245 		 */
246 		if (msg->msg_sa->sa_state == IKEV2_STATE_CLOSING) {
247 			if (((oldhdr->ike_flags &
248 			    (IKEV2_FLAG_INITIATOR|IKEV2_FLAG_RESPONSE)) ==
249 			    IKEV2_FLAG_INITIATOR) &&
250 			    (oldhdr->ike_exchange ==
251 			    IKEV2_EXCHANGE_INFORMATIONAL))
252 				return (0);
253 			return (-1);
254 		}
255 		return (0);
256 	}
257 
258 	/* Always fail */
259 	return (-1);
260 }
261 
262 int
263 ikev2_msg_send(struct iked *env, struct iked_message *msg)
264 {
265 	struct iked_sa		*sa = msg->msg_sa;
266 	struct ibuf		*buf = msg->msg_data;
267 	uint32_t		 natt = 0x00000000;
268 	int			 isnatt = 0;
269 	uint8_t			 exchange, flags;
270 	struct ike_header	*hdr;
271 	struct iked_message	*m;
272 
273 	if (buf == NULL || (hdr = ibuf_seek(msg->msg_data,
274 	    msg->msg_offset, sizeof(*hdr))) == NULL)
275 		return (-1);
276 
277 	isnatt = (msg->msg_natt || (sa && sa->sa_natt));
278 
279 	exchange = hdr->ike_exchange;
280 	flags = hdr->ike_flags;
281 	logit(exchange == IKEV2_EXCHANGE_INFORMATIONAL ?  LOG_DEBUG : LOG_INFO,
282 	    "%ssend %s %s %u peer %s local %s, %ld bytes%s",
283 	    SPI_IH(hdr),
284 	    print_map(exchange, ikev2_exchange_map),
285 	    (flags & IKEV2_FLAG_RESPONSE) ? "res" : "req",
286 	    betoh32(hdr->ike_msgid),
287 	    print_host((struct sockaddr *)&msg->msg_peer, NULL, 0),
288 	    print_host((struct sockaddr *)&msg->msg_local, NULL, 0),
289 	    ibuf_length(buf), isnatt ? ", NAT-T" : "");
290 
291 	if (isnatt) {
292 		if (ibuf_prepend(buf, &natt, sizeof(natt)) == -1) {
293 			log_debug("%s: failed to set NAT-T", __func__);
294 			return (-1);
295 		}
296 	}
297 
298 	if (sendtofrom(msg->msg_fd, ibuf_data(buf), ibuf_size(buf), 0,
299 	    (struct sockaddr *)&msg->msg_peer, msg->msg_peerlen,
300 	    (struct sockaddr *)&msg->msg_local, msg->msg_locallen) == -1) {
301 		log_warn("%s: sendtofrom", __func__);
302 		if (sa != NULL && errno == EADDRNOTAVAIL) {
303 			sa_state(env, sa, IKEV2_STATE_CLOSING);
304 			timer_del(env, &sa->sa_timer);
305 			timer_set(env, &sa->sa_timer,
306 			    ikev2_ike_sa_timeout, sa);
307 			timer_add(env, &sa->sa_timer,
308 			    IKED_IKE_SA_DELETE_TIMEOUT);
309 		}
310 	}
311 
312 	if (sa == NULL)
313 		return (0);
314 
315 	if ((m = ikev2_msg_copy(env, msg)) == NULL) {
316 		log_debug("%s: failed to copy a message", __func__);
317 		return (-1);
318 	}
319 	m->msg_exchange = exchange;
320 
321 	if (flags & IKEV2_FLAG_RESPONSE) {
322 		if (ikev2_msg_enqueue(env, &sa->sa_responses, m,
323 		    IKED_RESPONSE_TIMEOUT) != 0) {
324 			ikev2_msg_cleanup(env, m);
325 			free(m);
326 			return (-1);
327 		}
328 	} else {
329 		if (ikev2_msg_enqueue(env, &sa->sa_requests, m,
330 		    IKED_RETRANSMIT_TIMEOUT) != 0) {
331 			ikev2_msg_cleanup(env, m);
332 			free(m);
333 			return (-1);
334 		}
335 	}
336 
337 	return (0);
338 }
339 
340 uint32_t
341 ikev2_msg_id(struct iked *env, struct iked_sa *sa)
342 {
343 	uint32_t		id = sa->sa_reqid;
344 
345 	if (++sa->sa_reqid == UINT32_MAX) {
346 		/* XXX we should close and renegotiate the connection now */
347 		log_debug("%s: IKEv2 message sequence overflow", __func__);
348 	}
349 	return (id);
350 }
351 
352 /*
353  * Calculate the final sizes of the IKEv2 header and the encrypted payload
354  * header.  This must be done before encryption to make sure the correct
355  * headers are authenticated.
356  */
357 int
358 ikev2_msg_encrypt_prepare(struct iked_sa *sa, struct ikev2_payload *pld,
359     struct ibuf *buf, struct ibuf *e, struct ike_header *hdr,
360     uint8_t firstpayload, int fragmentation)
361 {
362 	size_t	 len, ivlen, encrlen, integrlen, blocklen, pldlen, outlen;
363 
364 	if (sa == NULL ||
365 	    sa->sa_encr == NULL ||
366 	    sa->sa_integr == NULL) {
367 		log_debug("%s: invalid SA", __func__);
368 		return (-1);
369 	}
370 
371 	len = ibuf_size(e);
372 	blocklen = cipher_length(sa->sa_encr);
373 	integrlen = hash_length(sa->sa_integr);
374 	ivlen = cipher_ivlength(sa->sa_encr);
375 	encrlen = roundup(len + 1, blocklen);
376 	outlen = cipher_outlength(sa->sa_encr, encrlen);
377 	pldlen = ivlen + outlen + integrlen;
378 
379 	if (ikev2_next_payload(pld,
380 	    pldlen + (fragmentation ? sizeof(struct ikev2_frag_payload) : 0),
381 	    firstpayload) == -1)
382 		return (-1);
383 	if (ikev2_set_header(hdr, ibuf_size(buf) + pldlen - sizeof(*hdr)) == -1)
384 		return (-1);
385 
386 	return (0);
387 }
388 
389 struct ibuf *
390 ikev2_msg_encrypt(struct iked *env, struct iked_sa *sa, struct ibuf *src,
391     struct ibuf *aad)
392 {
393 	size_t			 len, encrlen, integrlen, blocklen,
394 				    outlen;
395 	uint8_t			*buf, pad = 0, *ptr;
396 	struct ibuf		*encr, *dst = NULL, *out = NULL;
397 
398 	buf = ibuf_data(src);
399 	len = ibuf_size(src);
400 
401 	log_debug("%s: decrypted length %zu", __func__, len);
402 	print_hex(buf, 0, len);
403 
404 	if (sa == NULL ||
405 	    sa->sa_encr == NULL ||
406 	    sa->sa_integr == NULL) {
407 		log_debug("%s: invalid SA", __func__);
408 		goto done;
409 	}
410 
411 	if (sa->sa_hdr.sh_initiator)
412 		encr = sa->sa_key_iencr;
413 	else
414 		encr = sa->sa_key_rencr;
415 
416 	blocklen = cipher_length(sa->sa_encr);
417 	integrlen = hash_length(sa->sa_integr);
418 	encrlen = roundup(len + sizeof(pad), blocklen);
419 	pad = encrlen - (len + sizeof(pad));
420 
421 	/*
422 	 * Pad the payload and encrypt it
423 	 */
424 	if (pad) {
425 		if ((ptr = ibuf_advance(src, pad)) == NULL)
426 			goto done;
427 		arc4random_buf(ptr, pad);
428 	}
429 	if (ibuf_add(src, &pad, sizeof(pad)) != 0)
430 		goto done;
431 
432 	log_debug("%s: padded length %zu", __func__, ibuf_size(src));
433 	print_hex(ibuf_data(src), 0, ibuf_size(src));
434 
435 	cipher_setkey(sa->sa_encr, encr->buf, ibuf_length(encr));
436 	cipher_setiv(sa->sa_encr, NULL, 0);	/* XXX ivlen */
437 	if (cipher_init_encrypt(sa->sa_encr) == -1) {
438 		log_info("%s: error initiating cipher.", __func__);
439 		goto done;
440 	}
441 
442 	if ((dst = ibuf_dup(sa->sa_encr->encr_iv)) == NULL)
443 		goto done;
444 
445 	if ((out = ibuf_new(NULL,
446 	    cipher_outlength(sa->sa_encr, encrlen))) == NULL)
447 		goto done;
448 
449 	outlen = ibuf_size(out);
450 
451 	/* Add AAD for AEAD ciphers */
452 	if (sa->sa_integr->hash_isaead)
453 		cipher_aad(sa->sa_encr, ibuf_data(aad),
454 		    ibuf_length(aad), &outlen);
455 
456 	if (cipher_update(sa->sa_encr, ibuf_data(src), encrlen,
457 	    ibuf_data(out), &outlen) == -1) {
458 		log_info("%s: error updating cipher.", __func__);
459 		goto done;
460 	}
461 
462 	if (cipher_final(sa->sa_encr) == -1) {
463 		log_info("%s: encryption failed.", __func__);
464 		goto done;
465 	}
466 
467 	if (outlen && ibuf_add(dst, ibuf_data(out), outlen) != 0)
468 		goto done;
469 
470 	if ((ptr = ibuf_advance(dst, integrlen)) == NULL)
471 		goto done;
472 	explicit_bzero(ptr, integrlen);
473 
474 	log_debug("%s: length %zu, padding %d, output length %zu",
475 	    __func__, len + sizeof(pad), pad, ibuf_size(dst));
476 	print_hex(ibuf_data(dst), 0, ibuf_size(dst));
477 
478 	ibuf_release(src);
479 	ibuf_release(out);
480 	return (dst);
481  done:
482 	ibuf_release(src);
483 	ibuf_release(out);
484 	ibuf_release(dst);
485 	return (NULL);
486 }
487 
488 int
489 ikev2_msg_integr(struct iked *env, struct iked_sa *sa, struct ibuf *src)
490 {
491 	int			 ret = -1;
492 	size_t			 integrlen, tmplen;
493 	struct ibuf		*integr, *tmp = NULL;
494 	uint8_t			*ptr;
495 
496 	log_debug("%s: message length %zu", __func__, ibuf_size(src));
497 	print_hex(ibuf_data(src), 0, ibuf_size(src));
498 
499 	if (sa == NULL ||
500 	    sa->sa_encr == NULL ||
501 	    sa->sa_integr == NULL) {
502 		log_debug("%s: invalid SA", __func__);
503 		return (-1);
504 	}
505 
506 	integrlen = hash_length(sa->sa_integr);
507 	log_debug("%s: integrity checksum length %zu", __func__,
508 	    integrlen);
509 
510 	/*
511 	 * Validate packet checksum
512 	 */
513 	if ((tmp = ibuf_new(NULL, hash_keylength(sa->sa_integr))) == NULL)
514 		goto done;
515 
516 	if (!sa->sa_integr->hash_isaead) {
517 		if (sa->sa_hdr.sh_initiator)
518 			integr = sa->sa_key_iauth;
519 		else
520 			integr = sa->sa_key_rauth;
521 
522 		hash_setkey(sa->sa_integr, ibuf_data(integr),
523 		    ibuf_size(integr));
524 		hash_init(sa->sa_integr);
525 		hash_update(sa->sa_integr, ibuf_data(src),
526 		    ibuf_size(src) - integrlen);
527 		hash_final(sa->sa_integr, ibuf_data(tmp), &tmplen);
528 
529 		if (tmplen != integrlen) {
530 			log_debug("%s: hash failure", __func__);
531 			goto done;
532 		}
533 	} else {
534 		/* Append AEAD tag */
535 		if (cipher_gettag(sa->sa_encr, ibuf_data(tmp), ibuf_size(tmp)))
536 			goto done;
537 	}
538 
539 	if ((ptr = ibuf_seek(src,
540 	    ibuf_size(src) - integrlen, integrlen)) == NULL)
541 		goto done;
542 	memcpy(ptr, ibuf_data(tmp), integrlen);
543 
544 	print_hex(ibuf_data(tmp), 0, ibuf_size(tmp));
545 
546 	ret = 0;
547  done:
548 	ibuf_release(tmp);
549 
550 	return (ret);
551 }
552 
553 struct ibuf *
554 ikev2_msg_decrypt(struct iked *env, struct iked_sa *sa,
555     struct ibuf *msg, struct ibuf *src)
556 {
557 	ssize_t			 ivlen, encrlen, integrlen, blocklen,
558 				    outlen, tmplen;
559 	uint8_t			 pad = 0, *ptr, *integrdata;
560 	struct ibuf		*integr, *encr, *tmp = NULL, *out = NULL;
561 	off_t			 ivoff, encroff, integroff;
562 
563 	if (sa == NULL ||
564 	    sa->sa_encr == NULL ||
565 	    sa->sa_integr == NULL) {
566 		log_debug("%s: invalid SA", __func__);
567 		print_hex(ibuf_data(src), 0, ibuf_size(src));
568 		goto done;
569 	}
570 
571 	if (!sa->sa_hdr.sh_initiator) {
572 		encr = sa->sa_key_iencr;
573 		integr = sa->sa_key_iauth;
574 	} else {
575 		encr = sa->sa_key_rencr;
576 		integr = sa->sa_key_rauth;
577 	}
578 
579 	blocklen = cipher_length(sa->sa_encr);
580 	ivlen = cipher_ivlength(sa->sa_encr);
581 	ivoff = 0;
582 	integrlen = hash_length(sa->sa_integr);
583 	integroff = ibuf_size(src) - integrlen;
584 	encroff = ivlen;
585 	encrlen = ibuf_size(src) - integrlen - ivlen;
586 
587 	if (encrlen < 0 || integroff < 0) {
588 		log_debug("%s: invalid integrity value", __func__);
589 		goto done;
590 	}
591 
592 	log_debug("%s: IV length %zd", __func__, ivlen);
593 	print_hex(ibuf_data(src), 0, ivlen);
594 	log_debug("%s: encrypted payload length %zd", __func__, encrlen);
595 	print_hex(ibuf_data(src), encroff, encrlen);
596 	log_debug("%s: integrity checksum length %zd", __func__, integrlen);
597 	print_hex(ibuf_data(src), integroff, integrlen);
598 
599 	/*
600 	 * Validate packet checksum
601 	 */
602 	if (!sa->sa_integr->hash_isaead) {
603 		if ((tmp = ibuf_new(NULL, hash_keylength(sa->sa_integr))) == NULL)
604 			goto done;
605 
606 		hash_setkey(sa->sa_integr, integr->buf, ibuf_length(integr));
607 		hash_init(sa->sa_integr);
608 		hash_update(sa->sa_integr, ibuf_data(msg),
609 		    ibuf_size(msg) - integrlen);
610 		hash_final(sa->sa_integr, tmp->buf, &tmplen);
611 
612 		integrdata = ibuf_seek(src, integroff, integrlen);
613 		if (integrdata == NULL)
614 			goto done;
615 		if (memcmp(tmp->buf, integrdata, integrlen) != 0) {
616 			log_debug("%s: integrity check failed", __func__);
617 			goto done;
618 		}
619 
620 		log_debug("%s: integrity check succeeded", __func__);
621 		print_hex(tmp->buf, 0, tmplen);
622 
623 		ibuf_release(tmp);
624 		tmp = NULL;
625 	}
626 
627 	/*
628 	 * Decrypt the payload and strip any padding
629 	 */
630 	if ((encrlen % blocklen) != 0) {
631 		log_debug("%s: unaligned encrypted payload", __func__);
632 		goto done;
633 	}
634 
635 	cipher_setkey(sa->sa_encr, encr->buf, ibuf_length(encr));
636 	cipher_setiv(sa->sa_encr, ibuf_data(src) + ivoff, ivlen);
637 	if (cipher_init_decrypt(sa->sa_encr) == -1) {
638 		log_info("%s: error initiating cipher.", __func__);
639 		goto done;
640 	}
641 
642 	/* Set AEAD tag */
643 	if (sa->sa_integr->hash_isaead) {
644 		integrdata = ibuf_seek(src, integroff, integrlen);
645 		if (integrdata == NULL)
646 			goto done;
647 		if (cipher_settag(sa->sa_encr, integrdata, integrlen)) {
648 			log_info("%s: failed to set tag.", __func__);
649 			goto done;
650 		}
651 	}
652 
653 	if ((out = ibuf_new(NULL, cipher_outlength(sa->sa_encr,
654 	    encrlen))) == NULL)
655 		goto done;
656 
657 	/*
658 	 * Add additional authenticated data for AEAD ciphers
659 	 */
660 	if (sa->sa_integr->hash_isaead) {
661 		log_debug("%s: AAD length %zu", __func__, ibuf_length(msg) - ibuf_length(src));
662 		print_hex(ibuf_data(msg), 0, ibuf_length(msg) - ibuf_length(src));
663 		cipher_aad(sa->sa_encr, ibuf_data(msg),
664 		    ibuf_length(msg) - ibuf_length(src), &outlen);
665 	}
666 
667 	if ((outlen = ibuf_length(out)) != 0) {
668 		if (cipher_update(sa->sa_encr, ibuf_data(src) + encroff,
669 		    encrlen, ibuf_data(out), &outlen) == -1) {
670 			log_info("%s: error updating cipher.", __func__);
671 			goto done;
672 		}
673 
674 		ptr = ibuf_seek(out, outlen - 1, 1);
675 		pad = *ptr;
676 	}
677 
678 	if (cipher_final(sa->sa_encr) == -1) {
679 		log_info("%s: decryption failed.", __func__);
680 		goto done;
681 	}
682 
683 	log_debug("%s: decrypted payload length %zd/%zd padding %d",
684 	    __func__, outlen, encrlen, pad);
685 	print_hex(ibuf_data(out), 0, ibuf_size(out));
686 
687 	/* Strip padding and padding length */
688 	if (ibuf_setsize(out, outlen - pad - 1) != 0)
689 		goto done;
690 
691 	ibuf_release(src);
692 	return (out);
693  done:
694 	ibuf_release(tmp);
695 	ibuf_release(out);
696 	ibuf_release(src);
697 	return (NULL);
698 }
699 
700 int
701 ikev2_check_frag_oversize(struct iked_sa *sa, struct ibuf *buf) {
702 	size_t		len = ibuf_length(buf);
703 	sa_family_t	sa_fam;
704 	size_t		max;
705 	size_t		ivlen, integrlen, blocklen;
706 
707 	if (sa == NULL ||
708 	    sa->sa_encr == NULL ||
709 	    sa->sa_integr == NULL) {
710 		log_debug("%s: invalid SA", __func__);
711 		return (-1);
712 	}
713 
714 	sa_fam = ((struct sockaddr *)&sa->sa_local.addr)->sa_family;
715 
716 	max = sa_fam == AF_INET ? IKEV2_MAXLEN_IPV4_FRAG
717 	    : IKEV2_MAXLEN_IPV6_FRAG;
718 
719 	blocklen = cipher_length(sa->sa_encr);
720 	ivlen = cipher_ivlength(sa->sa_encr);
721 	integrlen = hash_length(sa->sa_integr);
722 
723 	/* Estimated maximum packet size (with 0 < padding < blocklen) */
724 	return ((len + ivlen + blocklen + integrlen) >= max) && sa->sa_frag;
725 }
726 
727 int
728 ikev2_msg_send_encrypt(struct iked *env, struct iked_sa *sa, struct ibuf **ep,
729     uint8_t exchange, uint8_t firstpayload, int response)
730 {
731 	struct iked_message		 resp;
732 	struct ike_header		*hdr;
733 	struct ikev2_payload		*pld;
734 	struct ibuf			*buf, *e = *ep;
735 	int				 ret = -1;
736 
737 	/* Check if msg needs to be fragmented */
738 	if (ikev2_check_frag_oversize(sa, e)) {
739 		return ikev2_send_encrypted_fragments(env, sa, e, exchange,
740 		    firstpayload, response);
741 	}
742 
743 	if ((buf = ikev2_msg_init(env, &resp, &sa->sa_peer.addr,
744 	    sa->sa_peer.addr.ss_len, &sa->sa_local.addr,
745 	    sa->sa_local.addr.ss_len, response)) == NULL)
746 		goto done;
747 
748 	resp.msg_msgid = response ? sa->sa_msgid_current : ikev2_msg_id(env, sa);
749 
750 	/* IKE header */
751 	if ((hdr = ikev2_add_header(buf, sa, resp.msg_msgid, IKEV2_PAYLOAD_SK,
752 	    exchange, response ? IKEV2_FLAG_RESPONSE : 0)) == NULL)
753 		goto done;
754 
755 	if ((pld = ikev2_add_payload(buf)) == NULL)
756 		goto done;
757 
758 	if (ikev2_msg_encrypt_prepare(sa, pld, buf, e, hdr, firstpayload, 0) == -1)
759 		goto done;
760 
761 	/* Encrypt message and add as an E payload */
762 	if ((e = ikev2_msg_encrypt(env, sa, e, buf)) == NULL) {
763 		log_debug("%s: encryption failed", __func__);
764 		goto done;
765 	}
766 	if (ibuf_cat(buf, e) != 0)
767 		goto done;
768 
769 	/* Add integrity checksum (HMAC) */
770 	if (ikev2_msg_integr(env, sa, buf) != 0) {
771 		log_debug("%s: integrity checksum failed", __func__);
772 		goto done;
773 	}
774 
775 	resp.msg_data = buf;
776 	resp.msg_sa = sa;
777 	resp.msg_fd = sa->sa_fd;
778 	TAILQ_INIT(&resp.msg_proposals);
779 
780 	(void)ikev2_pld_parse(env, hdr, &resp, 0);
781 
782 	ret = ikev2_msg_send(env, &resp);
783 
784  done:
785 	/* e is cleaned up by the calling function */
786 	*ep = e;
787 	ikev2_msg_cleanup(env, &resp);
788 
789 	return (ret);
790 }
791 
792 int
793 ikev2_send_encrypted_fragments(struct iked *env, struct iked_sa *sa,
794     struct ibuf *in, uint8_t exchange, uint8_t firstpayload, int response) {
795 	struct iked_message		 resp;
796 	struct ibuf			*buf, *e = NULL;
797 	struct ike_header		*hdr;
798 	struct ikev2_payload		*pld;
799 	struct ikev2_frag_payload	*frag;
800 	sa_family_t			 sa_fam;
801 	size_t				 ivlen, integrlen, blocklen;
802 	size_t				 max_len, left,  offset=0;
803 	size_t				 frag_num = 1, frag_total;
804 	uint8_t				*data;
805 	uint32_t			 msgid;
806 	int				 ret = -1;
807 
808 	if (sa == NULL ||
809 	    sa->sa_encr == NULL ||
810 	    sa->sa_integr == NULL) {
811 		log_debug("%s: invalid SA", __func__);
812 		goto done;
813 	}
814 
815 	sa_fam = ((struct sockaddr *)&sa->sa_local.addr)->sa_family;
816 
817 	left = ibuf_length(in);
818 
819 	/* Calculate max allowed size of a fragments payload */
820 	blocklen = cipher_length(sa->sa_encr);
821 	ivlen = cipher_ivlength(sa->sa_encr);
822 	integrlen = hash_length(sa->sa_integr);
823 	max_len = (sa_fam == AF_INET ? IKEV2_MAXLEN_IPV4_FRAG
824 	    : IKEV2_MAXLEN_IPV6_FRAG)
825 	    - ivlen - blocklen - integrlen;
826 
827 	/* Total number of fragments to send */
828 	frag_total = (left / max_len) + 1;
829 
830 	msgid = response ? sa->sa_msgid_current : ikev2_msg_id(env, sa);
831 
832 	while (frag_num <= frag_total) {
833 		if ((buf = ikev2_msg_init(env, &resp, &sa->sa_peer.addr,
834 		    sa->sa_peer.addr.ss_len, &sa->sa_local.addr,
835 		    sa->sa_local.addr.ss_len, response)) == NULL)
836 			goto done;
837 
838 		resp.msg_msgid = msgid;
839 
840 		/* IKE header */
841 		if ((hdr = ikev2_add_header(buf, sa, resp.msg_msgid,
842 		    IKEV2_PAYLOAD_SKF, exchange, response ? IKEV2_FLAG_RESPONSE
843 		    : 0)) == NULL)
844 			goto done;
845 
846 		/* Payload header */
847 		if ((pld = ikev2_add_payload(buf)) == NULL)
848 			goto done;
849 
850 		/* Fragment header */
851 		if ((frag = ibuf_advance(buf, sizeof(*frag))) == NULL) {
852 			log_debug("%s: failed to add SKF fragment header",
853 			    __func__);
854 			goto done;
855 		}
856 		frag->frag_num = htobe16(frag_num);
857 		frag->frag_total = htobe16(frag_total);
858 
859 		/* Encrypt message and add as an E payload */
860 		data = ibuf_seek(in, offset, 0);
861 		if ((e = ibuf_new(data, MINIMUM(left, max_len))) == NULL) {
862 			goto done;
863 		}
864 
865 		if (ikev2_msg_encrypt_prepare(sa, pld, buf, e, hdr,
866 		    firstpayload, 1) == -1)
867 			goto done;
868 
869 		if ((e = ikev2_msg_encrypt(env, sa, e, buf)) == NULL) {
870 			log_debug("%s: encryption failed", __func__);
871 			goto done;
872 		}
873 		if (ibuf_cat(buf, e) != 0)
874 			goto done;
875 
876 		/* Add integrity checksum (HMAC) */
877 		if (ikev2_msg_integr(env, sa, buf) != 0) {
878 			log_debug("%s: integrity checksum failed", __func__);
879 			goto done;
880 		}
881 
882 		log_debug("%s: Fragment %zu of %zu has size of %zu bytes.",
883 		    __func__, frag_num, frag_total,
884 		    ibuf_size(buf) - sizeof(*hdr));
885 		print_hex(ibuf_data(buf), 0,  ibuf_size(buf));
886 
887 		resp.msg_data = buf;
888 		resp.msg_sa = sa;
889 		resp.msg_fd = sa->sa_fd;
890 		TAILQ_INIT(&resp.msg_proposals);
891 
892 		if (ikev2_msg_send(env, &resp) == -1)
893 			goto done;
894 
895 		offset += MINIMUM(left, max_len);
896 		left -= MINIMUM(left, max_len);
897 		frag_num++;
898 
899 		/* MUST be zero after first fragment */
900 		firstpayload = 0;
901 
902 		ikev2_msg_cleanup(env, &resp);
903 		ibuf_release(e);
904 		e = NULL;
905 	}
906 
907 	return 0;
908 done:
909 	ikev2_msg_cleanup(env, &resp);
910 	ibuf_release(e);
911 	return ret;
912 }
913 
914 struct ibuf *
915 ikev2_msg_auth(struct iked *env, struct iked_sa *sa, int response)
916 {
917 	struct ibuf		*authmsg = NULL, *nonce, *prfkey, *buf;
918 	uint8_t			*ptr;
919 	struct iked_id		*id;
920 	size_t			 tmplen;
921 
922 	/*
923 	 * Create the payload to be signed/MAC'ed for AUTH
924 	 */
925 
926 	if (!response) {
927 		if ((nonce = sa->sa_rnonce) == NULL ||
928 		    (sa->sa_iid.id_type == 0) ||
929 		    (prfkey = sa->sa_key_iprf) == NULL ||
930 		    (buf = sa->sa_1stmsg) == NULL)
931 			return (NULL);
932 		id = &sa->sa_iid;
933 	} else {
934 		if ((nonce = sa->sa_inonce) == NULL ||
935 		    (sa->sa_rid.id_type == 0) ||
936 		    (prfkey = sa->sa_key_rprf) == NULL ||
937 		    (buf = sa->sa_2ndmsg) == NULL)
938 			return (NULL);
939 		id = &sa->sa_rid;
940 	}
941 
942 	if ((authmsg = ibuf_dup(buf)) == NULL)
943 		return (NULL);
944 	if (ibuf_cat(authmsg, nonce) != 0)
945 		goto fail;
946 
947 	if ((hash_setkey(sa->sa_prf, ibuf_data(prfkey),
948 	    ibuf_size(prfkey))) == NULL)
949 		goto fail;
950 
951 	/* require non-truncating hash */
952 	if (hash_keylength(sa->sa_prf) != hash_length(sa->sa_prf))
953 		goto fail;
954 
955 	if ((ptr = ibuf_advance(authmsg, hash_keylength(sa->sa_prf))) == NULL)
956 		goto fail;
957 
958 	hash_init(sa->sa_prf);
959 	hash_update(sa->sa_prf, ibuf_data(id->id_buf), ibuf_size(id->id_buf));
960 	hash_final(sa->sa_prf, ptr, &tmplen);
961 
962 	if (tmplen != hash_length(sa->sa_prf))
963 		goto fail;
964 
965 	log_debug("%s: %s auth data length %zu",
966 	    __func__, response ? "responder" : "initiator",
967 	    ibuf_size(authmsg));
968 	print_hex(ibuf_data(authmsg), 0, ibuf_size(authmsg));
969 
970 	return (authmsg);
971 
972  fail:
973 	ibuf_release(authmsg);
974 	return (NULL);
975 }
976 
977 int
978 ikev2_msg_authverify(struct iked *env, struct iked_sa *sa,
979     struct iked_auth *auth, uint8_t *buf, size_t len, struct ibuf *authmsg)
980 {
981 	uint8_t				*key, *psk = NULL;
982 	ssize_t				 keylen;
983 	struct iked_id			*id;
984 	struct iked_dsa			*dsa = NULL;
985 	int				 ret = -1;
986 	uint8_t				 keytype;
987 
988 	if (sa->sa_hdr.sh_initiator)
989 		id = &sa->sa_rcert;
990 	else
991 		id = &sa->sa_icert;
992 
993 	if ((dsa = dsa_verify_new(auth->auth_method, sa->sa_prf)) == NULL) {
994 		log_debug("%s: invalid auth method", __func__);
995 		return (-1);
996 	}
997 
998 	switch (auth->auth_method) {
999 	case IKEV2_AUTH_SHARED_KEY_MIC:
1000 		if (!auth->auth_length) {
1001 			log_debug("%s: no pre-shared key found", __func__);
1002 			goto done;
1003 		}
1004 		if ((keylen = ikev2_psk(sa, auth->auth_data,
1005 		    auth->auth_length, &psk)) == -1) {
1006 			log_debug("%s: failed to get PSK", __func__);
1007 			goto done;
1008 		}
1009 		key = psk;
1010 		keytype = 0;
1011 		break;
1012 	default:
1013 		if (!id->id_type || !ibuf_length(id->id_buf)) {
1014 			log_debug("%s: no cert found", __func__);
1015 			goto done;
1016 		}
1017 		key = ibuf_data(id->id_buf);
1018 		keylen = ibuf_size(id->id_buf);
1019 		keytype = id->id_type;
1020 		break;
1021 	}
1022 
1023 	log_debug("%s: method %s keylen %zd type %s", __func__,
1024 	    print_map(auth->auth_method, ikev2_auth_map), keylen,
1025 	    print_map(id->id_type, ikev2_cert_map));
1026 
1027 	if (dsa_setkey(dsa, key, keylen, keytype) == NULL ||
1028 	    dsa_init(dsa, buf, len) != 0 ||
1029 	    dsa_update(dsa, ibuf_data(authmsg), ibuf_size(authmsg))) {
1030 		log_debug("%s: failed to compute digital signature", __func__);
1031 		goto done;
1032 	}
1033 
1034 	if ((ret = dsa_verify_final(dsa, buf, len)) == 0) {
1035 		log_debug("%s: authentication successful", __func__);
1036 		sa_state(env, sa, IKEV2_STATE_AUTH_SUCCESS);
1037 		sa_stateflags(sa, IKED_REQ_AUTHVALID);
1038 	} else {
1039 		log_debug("%s: authentication failed", __func__);
1040 		sa_state(env, sa, IKEV2_STATE_AUTH_REQUEST);
1041 	}
1042 
1043  done:
1044 	free(psk);
1045 	dsa_free(dsa);
1046 
1047 	return (ret);
1048 }
1049 
1050 int
1051 ikev2_msg_authsign(struct iked *env, struct iked_sa *sa,
1052     struct iked_auth *auth, struct ibuf *authmsg)
1053 {
1054 	uint8_t				*key, *psk = NULL;
1055 	ssize_t				 keylen, siglen;
1056 	struct iked_hash		*prf = sa->sa_prf;
1057 	struct iked_id			*id;
1058 	struct iked_dsa			*dsa = NULL;
1059 	struct ibuf			*buf;
1060 	int				 ret = -1;
1061 	uint8_t			 keytype;
1062 
1063 	if (sa->sa_hdr.sh_initiator)
1064 		id = &sa->sa_icert;
1065 	else
1066 		id = &sa->sa_rcert;
1067 
1068 	if ((dsa = dsa_sign_new(auth->auth_method, prf)) == NULL) {
1069 		log_debug("%s: invalid auth method", __func__);
1070 		return (-1);
1071 	}
1072 
1073 	switch (auth->auth_method) {
1074 	case IKEV2_AUTH_SHARED_KEY_MIC:
1075 		if (!auth->auth_length) {
1076 			log_debug("%s: no pre-shared key found", __func__);
1077 			goto done;
1078 		}
1079 		if ((keylen = ikev2_psk(sa, auth->auth_data,
1080 		    auth->auth_length, &psk)) == -1) {
1081 			log_debug("%s: failed to get PSK", __func__);
1082 			goto done;
1083 		}
1084 		key = psk;
1085 		keytype = 0;
1086 		break;
1087 	default:
1088 		if (id == NULL) {
1089 			log_debug("%s: no cert found", __func__);
1090 			goto done;
1091 		}
1092 		key = ibuf_data(id->id_buf);
1093 		keylen = ibuf_size(id->id_buf);
1094 		keytype = id->id_type;
1095 		break;
1096 	}
1097 
1098 	if (dsa_setkey(dsa, key, keylen, keytype) == NULL ||
1099 	    dsa_init(dsa, NULL, 0) != 0 ||
1100 	    dsa_update(dsa, ibuf_data(authmsg), ibuf_size(authmsg))) {
1101 		log_debug("%s: failed to compute digital signature", __func__);
1102 		goto done;
1103 	}
1104 
1105 	ibuf_release(sa->sa_localauth.id_buf);
1106 	sa->sa_localauth.id_buf = NULL;
1107 
1108 	if ((buf = ibuf_new(NULL, dsa_length(dsa))) == NULL) {
1109 		log_debug("%s: failed to get auth buffer", __func__);
1110 		goto done;
1111 	}
1112 
1113 	if ((siglen = dsa_sign_final(dsa,
1114 	    ibuf_data(buf), ibuf_size(buf))) < 0) {
1115 		log_debug("%s: failed to create auth signature", __func__);
1116 		ibuf_release(buf);
1117 		goto done;
1118 	}
1119 
1120 	if (ibuf_setsize(buf, siglen) < 0) {
1121 		log_debug("%s: failed to set auth signature size to %zd",
1122 		    __func__, siglen);
1123 		ibuf_release(buf);
1124 		goto done;
1125 	}
1126 
1127 	sa->sa_localauth.id_type = auth->auth_method;
1128 	sa->sa_localauth.id_buf = buf;
1129 
1130 	ret = 0;
1131  done:
1132 	free(psk);
1133 	dsa_free(dsa);
1134 
1135 	return (ret);
1136 }
1137 
1138 int
1139 ikev2_msg_frompeer(struct iked_message *msg)
1140 {
1141 	struct iked_sa		*sa = msg->msg_sa;
1142 	struct ike_header	*hdr;
1143 
1144 	msg = msg->msg_parent;
1145 
1146 	if (sa == NULL ||
1147 	    (hdr = ibuf_seek(msg->msg_data, 0, sizeof(*hdr))) == NULL)
1148 		return (0);
1149 
1150 	if (!sa->sa_hdr.sh_initiator &&
1151 	    (hdr->ike_flags & IKEV2_FLAG_INITIATOR))
1152 		return (1);
1153 	else if (sa->sa_hdr.sh_initiator &&
1154 	    (hdr->ike_flags & IKEV2_FLAG_INITIATOR) == 0)
1155 		return (1);
1156 
1157 	return (0);
1158 }
1159 
1160 struct iked_socket *
1161 ikev2_msg_getsocket(struct iked *env, int af, int natt)
1162 {
1163 	switch (af) {
1164 	case AF_INET:
1165 		return (env->sc_sock4[natt ? 1 : 0]);
1166 	case AF_INET6:
1167 		return (env->sc_sock6[natt ? 1 : 0]);
1168 	}
1169 
1170 	log_debug("%s: af socket %d not available", __func__, af);
1171 	return (NULL);
1172 }
1173 
1174 int
1175 ikev2_msg_enqueue(struct iked *env, struct iked_msgqueue *queue,
1176     struct iked_message *msg, int timeout)
1177 {
1178 	struct iked_msg_retransmit *mr;
1179 
1180 	if ((mr = ikev2_msg_lookup(env, queue, msg, msg->msg_exchange)) ==
1181 	    NULL) {
1182 		if ((mr = calloc(1, sizeof(*mr))) == NULL)
1183 			return (-1);
1184 		TAILQ_INIT(&mr->mrt_frags);
1185 		mr->mrt_tries = 0;
1186 
1187 		timer_set(env, &mr->mrt_timer, msg->msg_response ?
1188 		    ikev2_msg_response_timeout : ikev2_msg_retransmit_timeout,
1189 		    mr);
1190 		timer_add(env, &mr->mrt_timer, timeout);
1191 
1192 		TAILQ_INSERT_TAIL(queue, mr, mrt_entry);
1193 	}
1194 
1195 	TAILQ_INSERT_TAIL(&mr->mrt_frags, msg, msg_entry);
1196 
1197 	return 0;
1198 }
1199 
1200 void
1201 ikev2_msg_prevail(struct iked *env, struct iked_msgqueue *queue,
1202     struct iked_message *msg)
1203 {
1204 	struct iked_msg_retransmit	*mr, *mrtmp;
1205 
1206 	TAILQ_FOREACH_SAFE(mr, queue, mrt_entry, mrtmp) {
1207 		if (TAILQ_FIRST(&mr->mrt_frags)->msg_msgid < msg->msg_msgid)
1208 			ikev2_msg_dispose(env, queue, mr);
1209 	}
1210 }
1211 
1212 void
1213 ikev2_msg_dispose(struct iked *env, struct iked_msgqueue *queue,
1214     struct iked_msg_retransmit *mr)
1215 {
1216 	struct iked_message	*m;
1217 
1218 	while ((m = TAILQ_FIRST(&mr->mrt_frags)) != NULL) {
1219 		TAILQ_REMOVE(&mr->mrt_frags, m, msg_entry);
1220 		ikev2_msg_cleanup(env, m);
1221 		free(m);
1222 	}
1223 
1224 	timer_del(env, &mr->mrt_timer);
1225 	TAILQ_REMOVE(queue, mr, mrt_entry);
1226 	free(mr);
1227 }
1228 
1229 void
1230 ikev2_msg_flushqueue(struct iked *env, struct iked_msgqueue *queue)
1231 {
1232 	struct iked_msg_retransmit	*mr = NULL;
1233 
1234 	while ((mr = TAILQ_FIRST(queue)) != NULL)
1235 		ikev2_msg_dispose(env, queue, mr);
1236 }
1237 
1238 struct iked_msg_retransmit *
1239 ikev2_msg_lookup(struct iked *env, struct iked_msgqueue *queue,
1240     struct iked_message *msg, uint8_t exchange)
1241 {
1242 	struct iked_msg_retransmit	*mr = NULL;
1243 
1244 	TAILQ_FOREACH(mr, queue, mrt_entry) {
1245 		if (TAILQ_FIRST(&mr->mrt_frags)->msg_msgid ==
1246 		    msg->msg_msgid &&
1247 		    TAILQ_FIRST(&mr->mrt_frags)->msg_exchange == exchange)
1248 			break;
1249 	}
1250 
1251 	return (mr);
1252 }
1253 
1254 int
1255 ikev2_msg_retransmit_response(struct iked *env, struct iked_sa *sa,
1256     struct iked_message *msg, uint8_t exchange)
1257 {
1258 	struct iked_msg_retransmit	*mr = NULL;
1259 	struct iked_message	*m = NULL;
1260 
1261 	if ((mr = ikev2_msg_lookup(env, &sa->sa_responses, msg, exchange))
1262 	    == NULL)
1263 		return (0);
1264 
1265 	TAILQ_FOREACH(m, &mr->mrt_frags, msg_entry) {
1266 		if (sendtofrom(m->msg_fd, ibuf_data(m->msg_data),
1267 		    ibuf_size(m->msg_data), 0,
1268 		    (struct sockaddr *)&m->msg_peer, m->msg_peerlen,
1269 		    (struct sockaddr *)&m->msg_local, m->msg_locallen) == -1) {
1270 			log_warn("%s: sendtofrom", __func__);
1271 			return (-1);
1272 		}
1273 		log_info("%sretransmit %s res %u local %s peer %s",
1274 		    SPI_SA(sa, NULL),
1275 		    print_map(exchange, ikev2_exchange_map),
1276 		    m->msg_msgid,
1277 		    print_host((struct sockaddr *)&m->msg_local, NULL, 0),
1278 		    print_host((struct sockaddr *)&m->msg_peer, NULL, 0));
1279 	}
1280 
1281 	timer_add(env, &mr->mrt_timer, IKED_RESPONSE_TIMEOUT);
1282 	return (0);
1283 }
1284 
1285 void
1286 ikev2_msg_response_timeout(struct iked *env, void *arg)
1287 {
1288 	struct iked_msg_retransmit	*mr = arg;
1289 	struct iked_sa		*sa;
1290 
1291 	sa = TAILQ_FIRST(&mr->mrt_frags)->msg_sa;
1292 	ikev2_msg_dispose(env, &sa->sa_responses, mr);
1293 }
1294 
1295 void
1296 ikev2_msg_retransmit_timeout(struct iked *env, void *arg)
1297 {
1298 	struct iked_msg_retransmit *mr = arg;
1299 	struct iked_message	*msg = TAILQ_FIRST(&mr->mrt_frags);
1300 	struct iked_sa		*sa = msg->msg_sa;
1301 
1302 	if (mr->mrt_tries < IKED_RETRANSMIT_TRIES) {
1303 		TAILQ_FOREACH(msg, &mr->mrt_frags, msg_entry) {
1304 			if (sendtofrom(msg->msg_fd, ibuf_data(msg->msg_data),
1305 			    ibuf_size(msg->msg_data), 0,
1306 			    (struct sockaddr *)&msg->msg_peer, msg->msg_peerlen,
1307 			    (struct sockaddr *)&msg->msg_local,
1308 			    msg->msg_locallen) == -1) {
1309 				log_warn("%s: sendtofrom", __func__);
1310 				ikev2_ike_sa_setreason(sa, "retransmit failed");
1311 				sa_free(env, sa);
1312 				return;
1313 			}
1314 			log_info("%sretransmit %d %s req %u peer %s "
1315 			    "local %s", SPI_SA(sa, NULL), mr->mrt_tries + 1,
1316 			    print_map(msg->msg_exchange, ikev2_exchange_map),
1317 			    msg->msg_msgid,
1318 			    print_host((struct sockaddr *)&msg->msg_peer, NULL, 0),
1319 			    print_host((struct sockaddr *)&msg->msg_local, NULL, 0));
1320 		}
1321 		/* Exponential timeout */
1322 		timer_add(env, &mr->mrt_timer,
1323 		    IKED_RETRANSMIT_TIMEOUT * (2 << (mr->mrt_tries++)));
1324 	} else {
1325 		log_debug("%s: retransmit limit reached for req %u",
1326 		    __func__, msg->msg_msgid);
1327 		ikev2_ike_sa_setreason(sa, "retransmit limit reached");
1328 		sa_free(env, sa);
1329 	}
1330 }
1331