xref: /openbsd-src/sbin/isakmpd/ike_main_mode.c (revision 2f1aa25b0f696ec888d7fe80b22e760eed552d21)
1*2f1aa25bSmpi /* $OpenBSD: ike_main_mode.c,v 1.19 2018/01/15 09:54:48 mpi Exp $	 */
28fa9b809Sniklas /* $EOM: ike_main_mode.c,v 1.77 1999/04/25 22:12:34 niklas Exp $	 */
32040585eSniklas 
42040585eSniklas /*
53487e4e6Sniklas  * Copyright (c) 1998, 1999 Niklas Hallqvist.  All rights reserved.
62040585eSniklas  *
72040585eSniklas  * Redistribution and use in source and binary forms, with or without
82040585eSniklas  * modification, are permitted provided that the following conditions
92040585eSniklas  * are met:
102040585eSniklas  * 1. Redistributions of source code must retain the above copyright
112040585eSniklas  *    notice, this list of conditions and the following disclaimer.
122040585eSniklas  * 2. Redistributions in binary form must reproduce the above copyright
132040585eSniklas  *    notice, this list of conditions and the following disclaimer in the
142040585eSniklas  *    documentation and/or other materials provided with the distribution.
152040585eSniklas  *
162040585eSniklas  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
172040585eSniklas  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
182040585eSniklas  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
192040585eSniklas  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
202040585eSniklas  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
212040585eSniklas  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
222040585eSniklas  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
232040585eSniklas  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
242040585eSniklas  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
252040585eSniklas  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
262040585eSniklas  */
272040585eSniklas 
282040585eSniklas /*
292040585eSniklas  * This code was written under funding by Ericsson Radio Systems.
302040585eSniklas  */
312040585eSniklas 
322040585eSniklas #include <sys/types.h>
332040585eSniklas #include <netinet/in.h>
342040585eSniklas #include <stdlib.h>
352040585eSniklas #include <string.h>
362040585eSniklas 
372040585eSniklas #include "attribute.h"
382040585eSniklas #include "conf.h"
392040585eSniklas #include "constants.h"
402040585eSniklas #include "crypto.h"
412040585eSniklas #include "dh.h"
422040585eSniklas #include "doi.h"
432040585eSniklas #include "exchange.h"
442040585eSniklas #include "hash.h"
452040585eSniklas #include "ike_auth.h"
462040585eSniklas #include "ike_main_mode.h"
47b2cb08d0Sniklas #include "ike_phase_1.h"
482040585eSniklas #include "ipsec.h"
492040585eSniklas #include "ipsec_doi.h"
502040585eSniklas #include "isakmp.h"
512040585eSniklas #include "log.h"
522040585eSniklas #include "message.h"
532040585eSniklas #include "prf.h"
542040585eSniklas #include "sa.h"
552040585eSniklas #include "transport.h"
562040585eSniklas #include "util.h"
572040585eSniklas 
582040585eSniklas static int      initiator_send_ID_AUTH(struct message *);
598fa9b809Sniklas static int      responder_send_ID_AUTH(struct message *);
602040585eSniklas static int      responder_send_KE_NONCE(struct message *);
612040585eSniklas 
622040585eSniklas int (*ike_main_mode_initiator[]) (struct message *) = {
63b2cb08d0Sniklas 	ike_phase_1_initiator_send_SA,
64b2cb08d0Sniklas 	ike_phase_1_initiator_recv_SA,
65b2cb08d0Sniklas 	ike_phase_1_initiator_send_KE_NONCE,
66b2cb08d0Sniklas 	ike_phase_1_initiator_recv_KE_NONCE,
672040585eSniklas 	initiator_send_ID_AUTH,
68b2cb08d0Sniklas 	ike_phase_1_recv_ID_AUTH
692040585eSniklas };
702040585eSniklas 
712040585eSniklas int (*ike_main_mode_responder[]) (struct message *) = {
72b2cb08d0Sniklas 	ike_phase_1_responder_recv_SA,
73b2cb08d0Sniklas 	ike_phase_1_responder_send_SA,
74b2cb08d0Sniklas 	ike_phase_1_recv_KE_NONCE,
752040585eSniklas 	responder_send_KE_NONCE,
76b2cb08d0Sniklas 	ike_phase_1_recv_ID_AUTH,
778fa9b809Sniklas 	responder_send_ID_AUTH
782040585eSniklas };
792040585eSniklas 
802040585eSniklas static int
initiator_send_ID_AUTH(struct message * msg)812040585eSniklas initiator_send_ID_AUTH(struct message *msg)
822040585eSniklas {
832040585eSniklas 	msg->exchange->flags |= EXCHANGE_FLAG_ENCRYPT;
842040585eSniklas 
85b2cb08d0Sniklas 	if (ike_phase_1_send_ID(msg))
862040585eSniklas 		return -1;
872040585eSniklas 
888fa9b809Sniklas 	if (ike_phase_1_send_AUTH(msg))
898fa9b809Sniklas 		return -1;
908fa9b809Sniklas 
918fa9b809Sniklas 	return ipsec_initial_contact(msg);
922040585eSniklas }
932040585eSniklas 
942040585eSniklas /* Send our public DH value and a nonce to the initiator.  */
95b2cb08d0Sniklas int
responder_send_KE_NONCE(struct message * msg)962040585eSniklas responder_send_KE_NONCE(struct message *msg)
972040585eSniklas {
982040585eSniklas 	/* XXX Should we really just use the initiator's nonce size?  */
99b2cb08d0Sniklas 	if (ike_phase_1_send_KE_NONCE(msg, msg->exchange->nonce_i_len))
1002040585eSniklas 		return -1;
1012040585eSniklas 
1022040585eSniklas 	/*
10350eea14cSho 	 * Calculate DH values & key material in parallel with the message
10450eea14cSho 	 * going on a roundtrip over the wire.
1052040585eSniklas 	 */
1062040585eSniklas 	message_register_post_send(msg,
10712f43dabShshoexer 	    (void (*)(struct message *))ike_phase_1_post_exchange_KE_NONCE);
1082040585eSniklas 
1092040585eSniklas 	return 0;
1102040585eSniklas }
1118fa9b809Sniklas 
1128fa9b809Sniklas static int
responder_send_ID_AUTH(struct message * msg)1138fa9b809Sniklas responder_send_ID_AUTH(struct message *msg)
1148fa9b809Sniklas {
1158fa9b809Sniklas 	msg->exchange->flags |= EXCHANGE_FLAG_ENCRYPT;
1168fa9b809Sniklas 
1178fa9b809Sniklas 	if (ike_phase_1_responder_send_ID_AUTH(msg))
1188fa9b809Sniklas 		return -1;
1198fa9b809Sniklas 
1208fa9b809Sniklas 	return ipsec_initial_contact(msg);
1218fa9b809Sniklas }
122