An exploration of the Internet Key Exchange (IKE) version 1, IKE version 2, and the different modes in which it operates, aggressive, main and quick.
Now we'll step through the operation of the initial exchange. It consists of two separate sub-exchanges, the INIT_SA and the IKE_AUTH exchange. The INIT_SA exchange is where the peers exchange and agree on cryptographic parameters, and the IKE_AUTH portion is where they each prove who they are. We'll step through an entire initial exchange of IKEv2 using pre-shared keys by going through an actual example; the establishment of an IKEv2 security association between SRX-13 and the Linux server box. The server box runs strongSwan for key negotiation and security association setup. Both boxes will be using their addresses on the 10.80.80.0/24 subnet for the IPSEC session, 10.80.80.13 and 10.80.80.80 respectively.
We're using a strongSwan client as one side of the IKE session as we can get it to log all of the encryption and authentication keys, while Junos won't. We can use the sensitive data coughed up by strongSwan with the logging levels maxed out to use with Wireshark to decrypt any encrypted packets that are part of the IKE exchange.
We use the following IKE configuration snippets from the SRX and Linux box to bring up our SA. The only real difference
configuration-wise on the SRX is
that we've deleted the mode
statement from the IKE policy, and we're forcing the SA to use IKEv2 with the
version v2-only
statement under the gateway. In truth, on the SRX if the version statement is left
out the peers will try to negotiate an IKEv2 SA (with a fallback to IKEv1), and will simply ignore the mode statement
if IKEv2 is used.
SRX-13 IKEv2 Config Snippet
security { ike { proposal IKE-PROPOSAL { authentication-method pre-shared-keys; dh-group group2; authentication-algorithm sha1; encryption-algorithm aes-128-cbc; lifetime-seconds 86400; } policy IKE-POLICY { proposals IKE-PROPOSAL; pre-shared-key ascii-text "$9$spgaUqmT/CujHCuO1yrYgoJjH.P5F69"; } gateway SERVER-BOX { ike-policy IKE-POLICY; address 10.80.80.80; external-interface ge-0/0/3.0; version v2-only; } } ipsec { proposal IPSEC-PROPOSAL { protocol esp; authentication-algorithm hmac-sha1-96; encryption-algorithm aes-128-cbc; lifetime-seconds 1200; } policy IPSEC-POLICY { perfect-forward-secrecy { keys group2; } proposals IPSEC-PROPOSAL; } vpn SERVER-BOX { bind-interface st0.80; ike { gateway SERVER-BOX; ipsec-policy IPSEC-POLICY; } establish-tunnels on-traffic; } } }
Server-Box stronSwan IPSec ipsec.conf configuration file
# ipsec.conf - strongSwan IPsec configuration file config setup charonstart=yes conn srx-13 auto=add keyexchange=ikev2 ikelifetime=24h authby=secret keyingtries=1 left=10.80.80.80 leftid=10.80.80.80 leftsubnet=1.0.0.0/8 right=10.80.80.13 rightid=10.80.80.13 rightsubnet=2.0.0.0/8 pfs=no include /var/lib/strongswan/ipsec.conf.inc
As we go through this example, we're going to dig through a packet capture of the exchange, and crawl through the logs line by line. You can download the entire IKEv2 exchange with pre-shared keys, the IKE logs from the initiator SRX-13 and the IKE logs from the responding stongSwan Linux server in order to follow along.
After a quick ping, the IPSEC SA comes up between both boxes.
Initial SA on SRX-13
juniper@SRX-13> show security ike security-associations detail | no-more IKE peer 10.80.80.80, Index 3283989, Gateway Name: SERVER-BOX Role: Initiator, State: UP Initiator cookie: 4444ab122717716d, Responder cookie: 4980326cef722580 Exchange type: IKEv2, Authentication method: Pre-shared-keys Local: 10.80.80.13:500, Remote: 10.80.80.80:500 Lifetime: Expires in 86382 seconds Peer ike-id: 10.80.80.80 Xauth assigned IP: 0.0.0.0 Algorithms: Authentication : hmac-sha1-96 Encryption : aes128-cbc Pseudo random function: hmac-sha1 Diffie-Hellman group : DH-group-2 Traffic statistics: Input bytes : 552 Output bytes : 572 Input packets: 2 Output packets: 2 Flags: IKE SA is created IPSec security associations: 2 created, 0 deleted Phase 2 negotiations in progress: 0 Negotiation type: Quick mode, Role: Initiator, Message ID: 0 Local: 10.80.80.13:500, Remote: 10.80.80.80:500 Local identity: 10.80.80.13 Remote identity: 10.80.80.80 Flags: IKE SA is created juniper@SRX-13>
Initial SA on strongSwan Linux box
root@server:/etc# ipsec status Security Associations: srx-13[1]: ESTABLISHED 3 seconds ago, 10.80.80.80[10.80.80.80]...10.80.80.13[10.80.80.13] srx-13{1}: INSTALLED, TUNNEL, ESP SPIs: c9c54fcc_i 81cb7deb_o srx-13{1}: 1.0.0.0/8 === 2.0.0.0/8 root@server:/etc#
The process starts exactly like IKEv1 with one of the peers, the initiator, deciding that it wants to establish and IKE security association with it's peer -- the responder. In this example, SRX-13 using it loopback address of 192.168.11.11, initiates the session to SRX-13's loopback address of 192.168.13.13.
[Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Received IKE Trigger message with local_gw_addr = 13.80.80.10 remote_gw_addr = 80.80.80.10 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Triggering the IKE negotiation .... [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Triggering negotiation for SERVER-BOX config block [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Initiating new P1 SA for gateway SERVER-BOX
The initiator creates a local SA.
[Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Allocated IKE SA index 3283989, ref cnt 0 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] P1 SA 3283989 start timer. timer duration 30, reason 1. [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_ike_sa_alloc_cb: Allocated IKE SA 8c9f400 I4444ab12 2717716d (10.80.80.80;500/4500)
The SRX allocated an index of 3283989 to keep track of the SA internally, and assigned a IKE SPI of 4444ab122717716d. IKEv2 tries to shed the cookie nomenclature a bit, calling the values that identify an IKE session Security Parameter Indexes (SPI) rather than cookies. However, when you look at the use of the IKE SPI, it is just like with IKEv1 and the cookies. IKEv2 refers to the individual values when taken out of the SPI context as a cookie.
Once the SPI has been created to identify the SA, it begins to fill in all of the values.
The SRX starts by creating a security association (SA) payload with all of the initiators proposals for the protection of the secure channel that is in the progress of being established: encryption and authentication algorithms, Diffie-Hellman group and pseudo-random function (PRF)to use. The PRF is used for generation of all keying material. Below, we see that SRX-13 is proposing to use AES in CBC mode with 128 bit keys for encryption, SHA1 for hash based message authentication with a length 96 bits for integrity checking, 1024 bit Diffie-Hellman keys, and to use SHA1 for keying material generation. All of this corresponds to the proposal that was configured.
[Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ssh_ikev2_ipsec_send: Creating IKE and IPsec SA 10.80.80.80;500 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_state_init_initiator_out_fill_sa: Calling fill_ike_sa [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] IKE SA fill called for negotiation of local:10.80.80.13, remote:10.80.80.80 IKEv2 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Initiator's proposing IKE SA payload SA([0](id = 1) protocol = IKE (1), AES CBC key len = 128, HMAC-SHA1-96, 1024 bit MODP, HMAC-SHA1 PRF; ) [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_reply_cb_init_initiator_fill_ike_sa: [8c38800/8c9f400] IKE SA filled successfully [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_state_init_initiator_out_sa: [8c38800/8c9f400] Adding SAi1 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_encode_sa: [8c38800/8c9f400] SA([0](id = 1) protocol = IKE (1), AES CBC key len = 128, HMAC-SHA1-96, 1024 bit MODP, HMAC-SHA1 PRF; )
Next, the SRX creates a Diffie-Hellman key pair according to the proposal above.
[Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_state_init_initiator_out_dh_setup: [8c38800/8c9f400] Starting Diffie-Hellman using group = 2 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Using software for dh_gen operation [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Inside kmd_sw_dh_gen... [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_state_init_i_out_dh_setup_cb: [8c38800/8c9f400] Diffie-Hellman done using group = 2 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_state_init_i_out_dh_setup_cb: [8c38800/8c9f400] Adding KEi [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_encode_ke: [8c38800/8c9f400] KE(group = 1024 bit MODP (2), len = 128, data = 2320c8e2 5d3ca6ab 3118c863 d6e53e5d a42f6748 c55d012a 4dc55e96 b8635f58 6347331c 5a0de1c8 27a57178 8a8f7f29 4
And then it creates a nonce, used for protection against replay attacks.
[Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_create_nonce_and_add: [8c38800/8c9f400] Adding NONCE [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_encode_nonce: [8c38800/8c9f400] NONCE(len = 32, data = 906155fd c6dca621 e591151e ab8478e1 42ace2a0 974ebbcb 0e6b2c13 7b8cbdff)
The next payload to be assembled is a Notification payload for NAT traversal discovery and negotiation. Unlike IKEv1, where NAT-T is an add on RFC (RFC3947), NAT-T is specified within the IKEv2 RFC. NAT-T is broken down into two separate payloads, one to detect source NAT, and one to detect any destination NAT.
[Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_add_nat_discovery_notify: Calling get_local_address_list [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_add_nat_discovery_notify_cb: [8c38800/8c9f400] Got 1 addresses [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_calc_nat_detection: Calculating NAT hash, ip = 10.80.80.13, port = 500, spi_i = 4444ab122717716d, spi_r = 0000000000000000 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_calc_nat_detection: NAT hash = 3a8a0e17 c67e0448 30f8f31d e879ebcf 6f29fa00 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_add_nat_discovery_notify_cb: [8c38800/8c9f400] Adding N [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_encode_notify: [8c38800/8c9f400] N(type = NAT detection source IP (16388), protocol = None (0), spi_len = 0, spi = , data_len = 20 data = 3a8a0e17 c67e0448 30f8f31d e879ebcf 6f29fa00) [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_calc_nat_detection: Calculating NAT hash, ip = 10.80.80.80, port = 500, spi_i = 4444ab122717716d, spi_r = 0000000000000000 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_calc_nat_detection: NAT hash = ad1d99c3 3f50c600 83c7c9f2 edf8daeb d2653944 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_add_nat_discovery_notify_cb: [8c38800/8c9f400] Adding N [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_encode_notify: [8c38800/8c9f400] N(type = NAT detection destination IP (16389), protocol = None (0), spi_len = 0, spi = , data_len = 20 data = ad1d99c3 3f50c600 83c7c9f2 edf8daeb d265394 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_add_notify: Calling notify_request [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Parsing notification payload for local:10.80.80.13, remote:10.80.80.80 IKEv2
The last payload the SRX adds is the vendor id.
[Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_add_vid: Calling vendor_id_request [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_reply_cb_vid_request: [8c38800/8c9f400] Got VID [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_reply_cb_vid_request: [8c38800/8c9f400] Adding VID [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_encode_vendor_id: [8c38800/8c9f400] VID(len = 28, data = 69936922 8741c6d4 ca094c93 e242c9de 19e7b7c6 00000005 00000500) [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] iked_pm_ike_request_vendor_id: Sending VID NetScreen Technologies [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_reply_cb_vid_request: [8c38800/8c9f400] No more VIDs [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_add_private_payload: Calling private_payload_request [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_reply_cb_private_payload_request: [8c38800/8c9f400] No more private payloads
At this point initiators actions are finished. To summarize what has happed in a FSM-like box:
Initiator Formulates Initial Request.
And the initial packet is sent on it's way to 10.80.80.80.
[Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_state_send: [8c38800/8c9f400] Sending packet [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_packet_st_send_request_address: [8c38800/8c9f400] Sending packet/request address pair [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_packet_st_send: [8c38800/8c9f400] Sending packet/Do [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_packet_st_send: Sending packet 0:500 to 10.80.80.80:500 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_udp_send_packet: [8c38800/8c9f400] Sending packet using VR id 0
Packet #1: Initial ISAKMP packet sent to responder.Click on the packet to download it. View it with tcpdump, Wireshark or Cloudshark.
The responder receives it's first packet from the initiator. The initiator parses the header of the ISAKMP packet and realizes it's received a request to establish a new SA.
Mar 7 19:43:54 10[ENC] parsing header of message Mar 7 19:43:54 10[ENC] parsing HEADER payload, 336 bytes left Mar 7 19:43:54 10[ENC] parsing payload from => 336 bytes @ 0x7fc228000d60 Mar 7 19:43:54 10[ENC] parsing rule 0 IKE_SPI Mar 7 19:43:54 10[ENC] => => 8 bytes @ 0x7fc2280011c0 Mar 7 19:43:54 10[ENC] 0: 44 44 AB 12 27 17 71 6D DD..'.qm Mar 7 19:43:54 10[ENC] parsing rule 1 IKE_SPI Mar 7 19:43:54 10[ENC] => => 8 bytes @ 0x7fc2280011c8 Mar 7 19:43:54 10[ENC] 0: 00 00 00 00 00 00 00 00 ........ Mar 7 19:43:54 10[ENC] parsing rule 2 U_INT_8 Mar 7 19:43:54 10[ENC] => 33 Mar 7 19:43:54 10[ENC] parsing rule 3 U_INT_4 Mar 7 19:43:54 10[ENC] => 2 Mar 7 19:43:54 10[ENC] parsing rule 4 U_INT_4 Mar 7 19:43:54 10[ENC] => 0 Mar 7 19:43:54 10[ENC] parsing rule 5 U_INT_8 Mar 7 19:43:54 10[ENC] => 34 Mar 7 19:43:54 10[ENC] parsing rule 6 RESERVED_BIT Mar 7 19:43:54 10[ENC] => 0 Mar 7 19:43:54 10[ENC] parsing rule 7 RESERVED_BIT Mar 7 19:43:54 10[ENC] => 0 Mar 7 19:43:54 10[ENC] parsing rule 8 FLAG Mar 7 19:43:54 10[ENC] => 0 Mar 7 19:43:54 10[ENC] parsing rule 9 FLAG Mar 7 19:43:54 10[ENC] => 0 Mar 7 19:43:54 10[ENC] parsing rule 10 FLAG Mar 7 19:43:54 10[ENC] => 1 Mar 7 19:43:54 10[ENC] parsing rule 11 RESERVED_BIT Mar 7 19:43:54 10[ENC] => 0 Mar 7 19:43:54 10[ENC] parsing rule 12 RESERVED_BIT Mar 7 19:43:54 10[ENC] => 0 Mar 7 19:43:54 10[ENC] parsing rule 13 RESERVED_BIT Mar 7 19:43:54 10[ENC] => 0 Mar 7 19:43:54 10[ENC] parsing rule 14 U_INT_32 Mar 7 19:43:54 10[ENC] => 0 Mar 7 19:43:54 10[ENC] parsing rule 15 HEADER_LENGTH Mar 7 19:43:54 10[ENC] => 336 Mar 7 19:43:54 10[ENC] parsing HEADER payload finished Mar 7 19:43:54 10[ENC] parsed a IKE_SA_INIT request Mar 7 19:43:54 15[NET] received packet: from 10.80.80.13[500] to 10.80.80.80[500]
The responder then goes through all of the payloads, starting with the security association payload.
Mar 7 19:43:54 15[ENC] parsing body of message, first payload is SECURITY_ASSOCIATION Mar 7 19:43:54 15[ENC] starting parsing a SECURITY_ASSOCIATION payload Mar 7 19:43:54 15[ENC] parsing SECURITY_ASSOCIATION payload, 308 bytes left Mar 7 19:43:54 15[ENC] parsing payload from => 308 bytes @ 0x7fc228000d7c Mar 7 19:43:54 15[ENC] parsing rule 0 U_INT_8 Mar 7 19:43:54 15[ENC] parsing rule 1 FLAG Mar 7 19:43:54 15[ENC] parsing rule 2 RESERVED_BIT Mar 7 19:43:54 15[ENC] parsing rule 3 RESERVED_BIT Mar 7 19:43:54 15[ENC] parsing rule 4 RESERVED_BIT Mar 7 19:43:54 15[ENC] parsing rule 5 RESERVED_BIT Mar 7 19:43:54 15[ENC] parsing rule 6 RESERVED_BIT Mar 7 19:43:54 15[ENC] parsing rule 7 RESERVED_BIT Mar 7 19:43:54 15[ENC] parsing rule 8 RESERVED_BIT Mar 7 19:43:54 15[ENC] parsing rule 9 PAYLOAD_LENGTH
It finds a proposal for the encryption and authentication parameters. This is basically a listing of how many transforms are in the proposal, where they are. Reference RFC2408 Section 3.5
Mar 7 19:43:54 15[ENC] parsing PROPOSAL_SUBSTRUCTURE payload, 304 bytes left Mar 7 19:43:54 15[ENC] parsing payload from => 304 bytes @ 0x7fc228000d80 Mar 7 19:43:54 15[ENC] parsing rule 0 U_INT_8 Mar 7 19:43:54 15[ENC] => 0 Mar 7 19:43:54 15[ENC] parsing rule 1 RESERVED_BYTE Mar 7 19:43:54 15[ENC] => 0 Mar 7 19:43:54 15[ENC] parsing rule 2 PAYLOAD_LENGTH Mar 7 19:43:54 15[ENC] => 44 Mar 7 19:43:54 15[ENC] parsing rule 3 U_INT_8 Mar 7 19:43:54 15[ENC] => 1 Mar 7 19:43:54 15[ENC] parsing rule 4 U_INT_8 Mar 7 19:43:54 15[ENC] => 1 Mar 7 19:43:54 15[ENC] parsing rule 5 SPI_SIZE Mar 7 19:43:54 15[ENC] => 0 Mar 7 19:43:54 15[ENC] parsing rule 6 U_INT_8 Mar 7 19:43:54 15[ENC] => 4 Mar 7 19:43:54 15[ENC] parsing rule 7 SPI Mar 7 19:43:54 15[ENC] => => 0 bytes @ (nil)
Next, it goes through the transforms one by one. To decode this we use RFC2408 Section 3.6 and we find that rule 3, corresponds to the transform number, and rule 5 is the transform id with a value of 12. Cross-referencing this with Internet Key Exchange Version 2 (IKEv2) Parameters listing at IANA, we find that a transform type of 1 is an Encryption Algorithm Transform ID, and value 12 corresponds to ENCR_AES_CBC. The transform attribues can be decoded by the same IANA listing, the transform attribute type of 14 is a key length, and it's value is 128.
Mar 7 19:43:54 15[ENC] 36 bytes left, parsing recursively TRANSFORM_SUBSTRUCTURE Mar 7 19:43:54 15[ENC] parsing TRANSFORM_SUBSTRUCTURE payload, 296 bytes left Mar 7 19:43:54 15[ENC] parsing payload from => 296 bytes @ 0x7fc228000d88 Mar 7 19:43:54 15[ENC] parsing rule 0 U_INT_8 Mar 7 19:43:54 15[ENC] => 3 Mar 7 19:43:54 15[ENC] parsing rule 1 RESERVED_BYTE Mar 7 19:43:54 15[ENC] => 0 Mar 7 19:43:54 15[ENC] parsing rule 2 PAYLOAD_LENGTH Mar 7 19:43:54 15[ENC] => 12 Mar 7 19:43:54 15[ENC] parsing rule 3 U_INT_8 Mar 7 19:43:54 15[ENC] => 1 Mar 7 19:43:54 15[ENC] parsing rule 4 RESERVED_BYTE Mar 7 19:43:54 15[ENC] => 0 Mar 7 19:43:54 15[ENC] parsing rule 5 U_INT_16 Mar 7 19:43:54 15[ENC] => 12 Mar 7 19:43:54 15[ENC] parsing rule 6 TRANSFORM_ATTRIBUTES Mar 7 19:43:54 15[ENC] 4 bytes left, parsing recursively TRANSFORM_ATTRIBUTE Mar 7 19:43:54 15[ENC] parsing TRANSFORM_ATTRIBUTE payload, 288 bytes left Mar 7 19:43:54 15[ENC] parsing payload from => 288 bytes @ 0x7fc228000d90 Mar 7 19:43:54 15[ENC] parsing rule 0 ATTRIBUTE_FORMAT Mar 7 19:43:54 15[ENC] => 1 Mar 7 19:43:54 15[ENC] parsing rule 1 ATTRIBUTE_TYPE Mar 7 19:43:54 15[ENC] => 14 Mar 7 19:43:54 15[ENC] parsing rule 2 ATTRIBUTE_LENGTH_OR_VALUE Mar 7 19:43:54 15[ENC] => 128 Mar 7 19:43:54 15[ENC] parsing rule 3 ATTRIBUTE_VALUE Mar 7 19:43:54 15[ENC] parsing TRANSFORM_ATTRIBUTE payload finished Mar 7 19:43:54 15[ENC] parsing TRANSFORM_SUBSTRUCTURE payload finished Mar 7 19:43:54 15[ENC] 24 bytes left, parsing recursively TRANSFORM_SUBSTRUCTURE
We continue with the next transform, and following the same process we find that this one is a transfrom type 3, which specifies the Integrity Algorithm Transform. The value of 2 in rule 5 corresponds to AUTH_HMAC_SHA1_96.
Mar 7 19:43:54 15[ENC] 24 bytes left, parsing recursively TRANSFORM_SUBSTRUCTURE Mar 7 19:43:54 15[ENC] parsing TRANSFORM_SUBSTRUCTURE payload, 284 bytes left Mar 7 19:43:54 15[ENC] parsing payload from => 284 bytes @ 0x7fc228000d94 Mar 7 19:43:54 15[ENC] parsing rule 0 U_INT_8 Mar 7 19:43:54 15[ENC] => 3 Mar 7 19:43:54 15[ENC] parsing rule 1 RESERVED_BYTE Mar 7 19:43:54 15[ENC] => 0 Mar 7 19:43:54 15[ENC] parsing rule 2 PAYLOAD_LENGTH Mar 7 19:43:54 15[ENC] => 8 Mar 7 19:43:54 15[ENC] parsing rule 3 U_INT_8 Mar 7 19:43:54 15[ENC] => 3 Mar 7 19:43:54 15[ENC] parsing rule 4 RESERVED_BYTE Mar 7 19:43:54 15[ENC] => 0 Mar 7 19:43:54 15[ENC] parsing rule 5 U_INT_16 Mar 7 19:43:54 15[ENC] => 2 Mar 7 19:43:54 15[ENC] parsing rule 6 TRANSFORM_ATTRIBUTES Mar 7 19:43:54 15[ENC] parsing TRANSFORM_SUBSTRUCTURE payload finished Mar 7 19:43:54 15[ENC] 16 bytes left, parsing recursively TRANSFORM_SUBSTRUCTURE
The next transform is type 4, the Diffie-Hellman Group ID. A value of 2 convienently stands for Diffie Hellman Group 2, which is uses 1024-bit MODP.
Mar 7 19:43:54 15[ENC] parsing TRANSFORM_SUBSTRUCTURE payload, 276 bytes left Mar 7 19:43:54 15[ENC] parsing payload from => 276 bytes @ 0x7fc228000d9c Mar 7 19:43:54 15[ENC] parsing rule 0 U_INT_8 Mar 7 19:43:54 15[ENC] => 3 Mar 7 19:43:54 15[ENC] parsing rule 1 RESERVED_BYTE Mar 7 19:43:54 15[ENC] => 0 Mar 7 19:43:54 15[ENC] parsing rule 2 PAYLOAD_LENGTH Mar 7 19:43:54 15[ENC] => 8 Mar 7 19:43:54 15[ENC] parsing rule 3 U_INT_8 Mar 7 19:43:54 15[ENC] => 4 Mar 7 19:43:54 15[ENC] parsing rule 4 RESERVED_BYTE Mar 7 19:43:54 15[ENC] => 0 Mar 7 19:43:54 15[ENC] parsing rule 5 U_INT_16 Mar 7 19:43:54 15[ENC] => 2 Mar 7 19:43:54 15[ENC] parsing rule 6 TRANSFORM_ATTRIBUTES Mar 7 19:43:54 15[ENC] parsing TRANSFORM_SUBSTRUCTURE payload finished Mar 7 19:43:54 15[ENC] 8 bytes left, parsing recursively TRANSFORM_SUBSTRUCTURE
Finally, we have a type 2, which specifies the PRF to be used. A value of 2 is PRF_HMAC_SHA1.
Mar 7 19:43:54 15[ENC] parsing TRANSFORM_SUBSTRUCTURE payload, 268 bytes left Mar 7 19:43:54 15[ENC] parsing payload from => 268 bytes @ 0x7fc228000da4 Mar 7 19:43:54 15[ENC] parsing rule 0 U_INT_8 Mar 7 19:43:54 15[ENC] => 0 Mar 7 19:43:54 15[ENC] parsing rule 1 RESERVED_BYTE Mar 7 19:43:54 15[ENC] => 0 Mar 7 19:43:54 15[ENC] parsing rule 2 PAYLOAD_LENGTH Mar 7 19:43:54 15[ENC] => 8 Mar 7 19:43:54 15[ENC] parsing rule 3 U_INT_8 Mar 7 19:43:54 15[ENC] => 2 Mar 7 19:43:54 15[ENC] parsing rule 4 RESERVED_BYTE Mar 7 19:43:54 15[ENC] => 0 Mar 7 19:43:54 15[ENC] parsing rule 5 U_INT_16 Mar 7 19:43:54 15[ENC] => 2 Mar 7 19:43:54 15[ENC] parsing rule 6 TRANSFORM_ATTRIBUTES Mar 7 19:43:54 15[ENC] parsing TRANSFORM_SUBSTRUCTURE payload finished
And the responder logs a couple of messages indicating that it's succesfully parsed in all of the transforms, the proposal that they were a part of and the entire SA request.
Mar 7 19:43:54 15[ENC] parsing TRANSFORM_SUBSTRUCTURE payload finished Mar 7 19:43:54 15[ENC] parsing PROPOSAL_SUBSTRUCTURE payload finished Mar 7 19:43:54 15[ENC] parsing SECURITY_ASSOCIATION payload finished Mar 7 19:43:54 15[ENC] verifying payload of type SECURITY_ASSOCIATION Mar 7 19:43:54 15[ENC] SECURITY_ASSOCIATION payload verified. Adding to payload list
The responder then moves onto reading in the Diffie-Hellman key exchange parameters from the key exchange payload. RFC2408 Section 3.7 has the break down of the key exchange payload. Essentially the entire key exchange data interpreteted based on the Domain of Intrpretation, which in our case is the Diffie-Hellman-Merkel public value.
Mar 7 19:43:54 15[ENC] starting parsing a KEY_EXCHANGE payload Mar 7 19:43:54 15[ENC] parsing KEY_EXCHANGE payload, 260 bytes left Mar 7 19:43:54 15[ENC] parsing payload from => 260 bytes @ 0x7fc228000dac Mar 7 19:43:54 15[ENC] parsing rule 0 U_INT_8 Mar 7 19:43:54 15[ENC] => 40 Mar 7 19:43:54 15[ENC] parsing rule 1 FLAG Mar 7 19:43:54 15[ENC] => 0 Mar 7 19:43:54 15[ENC] parsing rule 2 RESERVED_BIT Mar 7 19:43:54 15[ENC] => 0 Mar 7 19:43:54 15[ENC] parsing rule 3 RESERVED_BIT Mar 7 19:43:54 15[ENC] => 0 Mar 7 19:43:54 15[ENC] parsing rule 4 RESERVED_BIT Mar 7 19:43:54 15[ENC] => 0 Mar 7 19:43:54 15[ENC] parsing rule 5 RESERVED_BIT Mar 7 19:43:54 15[ENC] => 0 Mar 7 19:43:54 15[ENC] parsing rule 6 RESERVED_BIT Mar 7 19:43:54 15[ENC] => 0 Mar 7 19:43:54 15[ENC] parsing rule 7 RESERVED_BIT Mar 7 19:43:54 15[ENC] => 0 Mar 7 19:43:54 15[ENC] parsing rule 8 RESERVED_BIT Mar 7 19:43:54 15[ENC] => 0 Mar 7 19:43:54 15[ENC] parsing rule 9 PAYLOAD_LENGTH Mar 7 19:43:54 15[ENC] => 136 Mar 7 19:43:54 15[ENC] parsing rule 10 U_INT_16 Mar 7 19:43:54 15[ENC] => 2 Mar 7 19:43:54 15[ENC] parsing rule 11 RESERVED_BYTE Mar 7 19:43:54 15[ENC] => 0 Mar 7 19:43:54 15[ENC] parsing rule 12 RESERVED_BYTE Mar 7 19:43:54 15[ENC] => 0 Mar 7 19:43:54 15[ENC] parsing rule 13 KEY_EXCHANGE_DATA Mar 7 19:43:54 15[ENC] => => 128 bytes @ 0x7fc230002700 Mar 7 19:43:54 15[ENC] parsing KEY_EXCHANGE payload finished Mar 7 19:43:54 15[ENC] verifying payload of type KEY_EXCHANGE Mar 7 19:43:54 15[ENC] KEY_EXCHANGE payload verified. Adding to payload list
Next in line in a nonce payload which is defined in RFC2408 Section 3.13. Essentially, it's just the hopefully random bits that make up the nonce.
Mar 7 19:43:54 15[ENC] starting parsing a NONCE payload Mar 7 19:43:54 15[ENC] parsing NONCE payload, 124 bytes left Mar 7 19:43:54 15[ENC] parsing payload from => 124 bytes @ 0x7fc228000e34 Mar 7 19:43:54 15[ENC] parsing rule 0 U_INT_8 Mar 7 19:43:54 15[ENC] => 41 Mar 7 19:43:54 15[ENC] parsing rule 1 FLAG Mar 7 19:43:54 15[ENC] => 0 Mar 7 19:43:54 15[ENC] parsing rule 2 RESERVED_BIT Mar 7 19:43:54 15[ENC] => 0 Mar 7 19:43:54 15[ENC] parsing rule 3 RESERVED_BIT Mar 7 19:43:54 15[ENC] => 0 Mar 7 19:43:54 15[ENC] parsing rule 4 RESERVED_BIT Mar 7 19:43:54 15[ENC] => 0 Mar 7 19:43:54 15[ENC] parsing rule 5 RESERVED_BIT Mar 7 19:43:54 15[ENC] => 0 Mar 7 19:43:54 15[ENC] parsing rule 6 RESERVED_BIT Mar 7 19:43:54 15[ENC] => 0 Mar 7 19:43:54 15[ENC] parsing rule 7 RESERVED_BIT Mar 7 19:43:54 15[ENC] => 0 Mar 7 19:43:54 15[ENC] parsing rule 8 RESERVED_BIT Mar 7 19:43:54 15[ENC] => 0 Mar 7 19:43:54 15[ENC] parsing rule 9 PAYLOAD_LENGTH Mar 7 19:43:54 15[ENC] => 36 Mar 7 19:43:54 15[ENC] parsing rule 10 NONCE_DATA Mar 7 19:43:54 15[ENC] => => 32 bytes @ 0x7fc2300025d0 Mar 7 19:43:54 15[ENC] 0: 90 61 55 FD C6 DC A6 21 E5 91 15 1E AB 84 78 E1 .aU....!......x. Mar 7 19:43:54 15[ENC] 16: 42 AC E2 A0 97 4E BB CB 0E 6B 2C 13 7B 8C BD FF B....N...k,.{... Mar 7 19:43:54 15[ENC] parsing NONCE payload finished Mar 7 19:43:54 15[ENC] verifying payload of type NONCE Mar 7 19:43:54 15[ENC] NONCE payload verified. Adding to payload list
Next, the responder parses through the notifications, which in this case are used for NAT detection.
Mar 7 19:43:54 15[ENC] starting parsing a NOTIFY payload Mar 7 19:43:54 15[ENC] parsing NOTIFY payload, 88 bytes left Mar 7 19:43:54 15[ENC] parsing payload from => 88 bytes @ 0x7fc228000e58 Mar 7 19:43:54 15[ENC] parsing NOTIFY payload finished Mar 7 19:43:54 15[ENC] verifying payload of type NOTIFY Mar 7 19:43:54 15[ENC] NOTIFY payload verified. Adding to payload list Mar 7 19:43:54 15[ENC] starting parsing a NOTIFY payload Mar 7 19:43:54 15[ENC] parsing NOTIFY payload, 60 bytes left Mar 7 19:43:54 15[ENC] parsing payload from => 60 bytes @ 0x7fc228000e74 Mar 7 19:43:54 15[ENC] parsing NOTIFY payload finished Mar 7 19:43:54 15[ENC] verifying payload of type NOTIFY Mar 7 19:43:54 15[ENC] NOTIFY payload verified. Adding to payload list
And the last part of our first packet has the vendor id payload.
Mar 7 19:43:54 15[ENC] parsing VENDOR_ID payload, 32 bytes left Mar 7 19:43:54 15[ENC] parsing payload from => 32 bytes @ 0x7fc228000e90 Mar 7 19:43:54 15[ENC] parsing VENDOR_ID payload finished Mar 7 19:43:54 15[ENC] verifying payload of type VENDOR_ID Mar 7 19:43:54 15[ENC] VENDOR_ID payload verified. Adding to payload list
Now that all of the payloads have been verified and loaded into memory, the responder starts to actually process the contents.
Mar 7 19:43:54 15[ENC] process payload of type SECURITY_ASSOCIATION Mar 7 19:43:54 15[ENC] process payload of type KEY_EXCHANGE Mar 7 19:43:54 15[ENC] process payload of type NONCE Mar 7 19:43:54 15[ENC] process payload of type NOTIFY Mar 7 19:43:54 15[ENC] process payload of type NOTIFY Mar 7 19:43:54 15[ENC] process payload of type VENDOR_ID Mar 7 19:43:54 15[ENC] verifying message structure Mar 7 19:43:54 15[ENC] found payload of type NOTIFY Mar 7 19:43:54 15[ENC] found payload of type NOTIFY Mar 7 19:43:54 15[ENC] found payload of type SECURITY_ASSOCIATION Mar 7 19:43:54 15[ENC] found payload of type KEY_EXCHANGE Mar 7 19:43:54 15[ENC] found payload of type NONCE Mar 7 19:43:54 15[ENC] found payload of type VENDOR_ID Mar 7 19:43:54 15[ENC] parsed IKE_SA_INIT request 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) V ] Mar 7 19:43:54 15[ENC] received unknown vendor id: 69:93:69:22:87:41:c6:d4:ca:09:4c:93:e2:42:c9:de:19:e7:b7:c6:00:00:00:05:00:00:05:00
The responder realises now that the intiator is trying to establish a SA.
Mar 7 19:43:54 15[IKE] 10.80.80.13 is initiating an IKE_SA Mar 7 19:43:54 15[IKE] IKE_SA (unnamed)[1] state change: CREATED => CONNECTING
The responder can now begin the work of assembling a the response. strongSwan first gets the easy things out of the way, formulating the NAT-T replies and creating a vendor id payload.
Mar 7 19:43:54 15[IKE] natd_chunk => 22 bytes @ 0x7fc230003c30 Mar 7 19:43:54 15[IKE] received src_hash => 20 bytes @ 0x7fc230002910 Mar 7 19:43:54 15[IKE] received dst_hash => 20 bytes @ 0x7fc230002a10 Mar 7 19:43:54 15[ENC] added payload of type VENDOR_ID to message
Next the responder picks it's own Diffie-Hellman-Merkle public and private value. As soon as it does this, it has enough information to figure out what the Diffie-Hellman-Merkle secret value is for the exchange.
Mar 7 19:43:54 15[IKE] shared Diffie Hellman secret => 128 bytes @ 0x7fc230005000
With IKEv2, the responder has enough information to figure out what all of the keys that will be used for all of the encryption and authentication after the arrival of the first packet.
strongSwan with the debugging levels turned all the way up will log all of the keys that are generated and all of the sensitive values that are normally kept as hidden as possible. We will be able to use the values below with Wireshark to decrypt the remaining parts of the exchange that are encrypted.
Briefly, from , RFC4306. SKEYSEED is calculated from the nonces and Diffie-Hellman secret value, and is used to seed all of the other keys that will be used. These keys Sk_ai and Sk_ar are used for authentication by the initiator and responder respectively. Sk_ei and Sk_r are secret keys used for encryption. SK_pi and SK_pr are used to generate the AUTH payload that is used to identify the initator and responder later in the exchange. Sk_d is used to derive any later keying material for any additional child SAs that may be setup at a later time.
Mar 7 19:43:54 15[IKE] SKEYSEED => 20 bytes @ 0x7fc2300052f0 Mar 7 19:43:54 15[IKE] 0: E5 54 85 5C 9B 6C 15 39 3D 19 F2 46 B0 05 70 56 .T.\.l.9=..F..pV Mar 7 19:43:54 15[IKE] 16: E6 50 B5 5D .P.] Mar 7 19:43:54 15[IKE] Sk_d secret => 20 bytes @ 0x7fc2300052f0 Mar 7 19:43:54 15[IKE] 0: 6E D9 FD 4F 4D 1E 73 48 09 BC 1E D2 A6 99 70 F8 n..OM.sH......p. Mar 7 19:43:54 15[IKE] 16: A9 B3 CF 1E .... Mar 7 19:43:54 15[IKE] Sk_ai secret => 20 bytes @ 0x7fc230005660 Mar 7 19:43:54 15[IKE] 0: E5 1F 5F BE F6 7E DF 09 C1 72 49 6B 3D 6A 82 28 .._..~...rIk=j.( Mar 7 19:43:54 15[IKE] 16: CB D8 41 AB ..A. Mar 7 19:43:54 15[IKE] Sk_ar secret => 20 bytes @ 0x7fc230005660 Mar 7 19:43:54 15[IKE] 0: AF 63 6D F4 D1 37 84 FA 4E DD 88 BB EF 93 35 91 .cm..7..N.....5. Mar 7 19:43:54 15[IKE] 16: 70 5D 6D A0 p]m. Mar 7 19:43:54 15[IKE] Sk_ei secret => 16 bytes @ 0x7fc230005090 Mar 7 19:43:54 15[IKE] 0: 58 92 B4 C6 5D 17 FF 4A D5 E9 BA 25 29 99 DD AD X...]..J...%)... Mar 7 19:43:54 15[IKE] Sk_er secret => 16 bytes @ 0x7fc230005000 Mar 7 19:43:54 15[IKE] 0: C4 18 B3 69 BC BF DC 47 6B 18 1D 87 BA 33 41 B7 ...i...Gk....3A. Mar 7 19:43:54 15[IKE] Sk_pi secret => 20 bytes @ 0x7fc230005000 Mar 7 19:43:54 15[IKE] 0: 08 0B 57 0B 5C 77 F5 6B 36 D2 1E 5B 74 EF 18 DC ..W.\w.k6..[t... Mar 7 19:43:54 15[IKE] 16: 07 89 B1 40 ...@ Mar 7 19:43:54 15[IKE] Sk_pr secret => 20 bytes @ 0x7fc230005020 Mar 7 19:43:54 15[IKE] 0: E1 F6 E1 B3 DB B7 84 D5 99 3D 00 C2 D6 21 D3 06 .........=...!.. Mar 7 19:43:54 15[IKE] 16: 5B E6 19 AC [...
Next the responder begins to pack the response payloads for the initiator. It notes that it needs to respond back with a security association, it Diffie-Hellman-Merkle public value, a nonce, the NAT-T stuff and it's going to add it's vendor ID as well. It also notes that the payloads will all be sent in the clear. It still has to send an unencrypted reply back to the initiator as it's doesn't have everything it needs to decrypt and check anything - the nonce and the Diffie-Hellman-Merkel value that will be sent.
Mar 7 19:43:54 15[ENC] generating IKE_SA_INIT response 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) N(MULT_AUTH) V ] Mar 7 19:43:54 15[ENC] not encrypting payloads
It makes the header, and adds in it's own SPI (cookie), which is 0x4980326CEF722580.
Mar 7 19:43:54 15[ENC] generating payload of type HEADER Mar 7 19:43:54 15[ENC] generating rule 0 IKE_SPI Mar 7 19:43:54 15[ENC] => => 8 bytes @ 0x7fc230003e20 Mar 7 19:43:54 15[ENC] 0: 44 44 AB 12 27 17 71 6D DD..'.qm Mar 7 19:43:54 15[ENC] generating rule 1 IKE_SPI Mar 7 19:43:54 15[ENC] => => 8 bytes @ 0x7fc230003e28 Mar 7 19:43:54 15[ENC] 0: 49 80 32 6C EF 72 25 80 I.2l.r%
The responder creates a security association payload that consists of the proposal it has selected for the session. If no proposal was acceptable, the reponder would send pack an informational packet notifying the initiator that there weren't any proposals that were worth anything to the responder. In our case with just a single proposal in the initiators request, the responder just echo's back the same transforms and parameters.
Mar 7 19:43:54 15[ENC] generating payload of type SECURITY_ASSOCIATION Mar 7 19:43:54 15[ENC] generating payload of type PROPOSAL_SUBSTRUCTURE Mar 7 19:43:54 15[ENC] generating payload of type TRANSFORM_SUBSTRUCTURE Mar 7 19:43:54 15[ENC] generating payload of type TRANSFORM_ATTRIBUTE Mar 7 19:43:54 15[ENC] generating TRANSFORM_SUBSTRUCTURE payload finished Mar 7 19:43:54 15[ENC] generating TRANSFORM_SUBSTRUCTURE payload finished Mar 7 19:43:54 15[ENC] generating TRANSFORM_SUBSTRUCTURE payload finished Mar 7 19:43:54 15[ENC] generating TRANSFORM_SUBSTRUCTURE payload finished Mar 7 19:43:54 15[ENC] generating PROPOSAL_SUBSTRUCTURE payload finished Mar 7 19:43:54 15[ENC] generating SECURITY_ASSOCIATION payload finished
Next, the responder sends it's own Diffie-Hellman-Merkel public value.
Mar 7 19:43:54 15[ENC] generating payload of type KEY_EXCHANGE Mar 7 19:43:54 15[ENC] generating KEY_EXCHANGE payload finished
Followed by a nonce.
Mar 7 19:43:54 15[ENC] generating payload of type NONCE Mar 7 19:43:54 15[ENC] generating NONCE payload finished
Then a set of notifications for NAT-T.
Mar 7 19:43:54 15[ENC] generating payload of type NOTIFY Mar 7 19:43:54 15[ENC] generating NOTIFY payload finished Mar 7 19:43:54 15[ENC] generating NOTIFY payload finished Mar 7 19:43:54 15[ENC] generating NOTIFY payload finished
And a vendor id to seal the IKEv2 response with a bit of flavor.
Mar 7 19:43:54 15[ENC] generating payload of type VENDOR_ID Mar 7 19:43:54 15[ENC] generating VENDOR_ID payload finished
At this point the responder has nearly finished the last step in the Initial SA portion of the IKEv2 exchange. We model the actions up to this point with another box in the finite state machine.
Responder's initial actions.
And the responder sends off it's packet to the initiator in reply.
Mar 7 19:43:54 15[NET] sending packet: from 10.80.80.80[500] to 10.80.80.13[500]
Packet #2: IKEv2 packet sent to initiator. Except for the responders SPI being completed, this packet looks almost like the first packet the initiator sent.
The initiator recieves the reply from the responder, and identifies it as belonging to the IKEv2 SA that is being formed.
[Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] *** Processing received packet from 10.80.80.80:500 to 10.80.80.13:0 VR 0 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_packet_st_input_start: [8c38c00/0] Processing received [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Found IKEv2 P1 SA 3283989
The initiator parses through the packet and finds all of the payloads: the security association, a Diffie-Hellman-Merkel public value, a nonce, a couple of notifications for NAT-T, and the vendor id of the responder.
[Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_decode_packet: [8c38c00/8c9f400] Decoding packet [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_decode_packet: [8c38c00/8c9f400] We have old context [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_decode_sa: [8c38c00/8c9f400] SA([0](id = 1) protocol = IKE (1), AES CBC key len = 128, HMAC-SHA1-96, HMAC-SHA1 PRF, 1024 bit MODP; ) [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_decode_ke: [8c38c00/8c9f400] KE(group = 1024 bit MODP (2), len = 128, data = 174f7bcf 89d1b0a9 f3b5082c a47284bd f1e633df b27b9ce7 a5ddce19 ef5fd95f c0c87dad 88ec8544 dd6dfb1a 72ca743b 6 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_decode_nonce: [8c38c00/8c9f400] NONCE(len = 32, data = e7bdfd9d dd4535a5 ee0ad6bc 436e44be eaf70461 ca5d631c 3f3ccfe0 492a31d3) [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_decode_notify: Calling notify_received [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] iked_pm_ike_spd_notify_received: Received Unauthenticated notification payload NAT detection source IP from local:10.80.80.13 remote:10.80.80.80 IKEv2 for P1 SA 3283989 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Ignoring unauthenticated message, notify_message_type is 16388 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_decode_notify: [8c38c00/8c9f400] N(type = NAT detection source IP (16388), protocol = None (0), spi_len = 0, spi = , data_len = 20 data = f15746d5 941ec68f 52578165 e52af16c d1e3677b) [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_decode_notify: Calling notify_received [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] iked_pm_ike_spd_notify_received: Received Unauthenticated notification payload NAT detection destination IP from local:10.80.80.13 remote:10.80.80.80 IKEv2 for P1 SA 3283989 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Ignoring unauthenticated message, notify_message_type is 16389 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_decode_notify: [8c38c00/8c9f400] N(type = NAT detection destination IP (16389), protocol = None (0), spi_len = 0, spi = , data_len = 20 data = 9b30bdb6 f69d8121 a6ca82d3 2c5f4e27 6defb9d [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_decode_notify: Calling notify_received [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] iked_pm_ike_spd_notify_received: Received Unauthenticated notification payload Multiple auth supported from local:10.80.80.13 remote:10.80.80.80 IKEv2 for P1 SA 3283989 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Ignoring unauthenticated message, notify_message_type is 16404 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_decode_notify: [8c38c00/8c9f400] N(type = Multiple auth supported (16404), protocol = None (0), spi_len = 0, spi = , data_len = 0 data = ) [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_decode_vendor_id: Calling vendor_id [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_decode_vendor_id: [8c38c00/8c9f400] VID(len = 16, data = 882fe56d 6fd20dbc 2251613b 2ebe5beb)
The initiator updates the SPI with the responder's cookie value of 0x4980326cef722580.
[Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_decode_packet: [8c38c00/8c9f400] Updating responder IKE SPI to IKE SA 8c9f400 I 4444ab12 2717716d R 4980326c ef722580
The initiator makes note that the SA was accepted, it has a public value for the Diffie-Hellman-Merkel exchange
[Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_state_init_initiator_in_sa: [8c38c00/8c9f400] Verify SAr1 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_state_init_initiator_in_sa: [8c38c00/8c9f400] SAr1 was ok [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_state_init_initiator_in_ke: [8c38c00/8c9f400] KE was ok
The initiator finishes off the NAT checks in the notification payloads.
[Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_check_nat_detection: Calling get_local_address_list [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_check_nat_detection_cb: [8c38c00/8c9f400] Got 1 addresses [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_calc_nat_detection: Calculating NAT hash, ip = 10.80.80.13, port = 500, spi_i = 4444ab122717716d, spi_r = 4980326cef722580 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_calc_nat_detection: NAT hash = 9b30bdb6 f69d8121 a6ca82d3 2c5f4e27 6defb9d2 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_compute_nat_detection: [8c38c00/8c9f400] We are not behind NAT [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_calc_nat_detection: Calculating NAT hash, ip = 10.80.80.80, port = 500, spi_i = 4444ab122717716d, spi_r = 4980326cef722580 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_calc_nat_detection: NAT hash = f15746d5 941ec68f 52578165 e52af16c d1e3677b [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_compute_nat_detection: [8c38c00/8c9f400] Remote end is not behind NAT
At this point the SRX starts to construct it's next reply to the responder. Everything has been agreed upon so far, and the initiator now has enough information to encrypt the rest of the exchange. The next step in the initial exchange is for the initiator to provide his identity, and prove through some authentication means that it is who it claims to be either with a pre-shared key, a certificate or even Extensible Authentication Protocol (EAP). This portion of the initial exchange is referred to as the IKE_AUTH exchange.
[Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_reply_packet_allocate: [8c38c00/8c9f400] Allocating reply packet [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_packet_allocate: [8c39000/0] Allocating [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_reply_packet_allocate: [8c38c00/0] Allocated reply packet [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_state_init_initiator_in_end: [8c38c00/0] Move to the IKE_AUTH exchange
The SRX now starts to calculate all of the keying material for the remaining exchanges, starting with the SKEYSEED seed. Note that before it can complete the value of SKEYSEED, it has to calculate the Diffie-Hellman-Merkel secret.
[Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_state_auth_initiator_out: [8c39000/8c9f400] Making sure that the SKEYSEED is calculated [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_skeyseed: Starting SKEYSEED calculation for SA 8c9f400 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Using software for dh_comp operation [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Inside kmd_sw_dh_comp... [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_restart_packet: [8c39000/8c9f400] Restarting packet [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_skeyseed_agree: SKEYSEED calculation done
The initiator then creates an identity payload, to let the responder know who it is. From the logs below, we can see that per our configuration, SRX-13 is asserting it's idenity as an IPv4 address of 10.80.80.13.
[Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_reply_cb_id: [8c39000/8c9f400] Adding IDi [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_encode_id: [8c39000/8c9f400] ID(type = ipv4 (1), len = 4, value = 10.80.80.13) [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_add_certs: Calling get_certificates [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_reply_cb_get_certs: [8c39000/8c9f400] No private keys [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_reply_cb_get_certs: [8c39000/8c9f400] Got 0 certificates [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_add_certreq: Calling get_cas [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_reply_cb_get_cas: [8c39000/8c9f400] Got 0 CAs [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_add_id: Calling id
The initiator also has the option to insert a payload that has the identity of the responder. This will let the responder know which of the responder's identities the initiator want's to talk to. The SRX goes ahead and takes this option, creating an identity payload for the responder of an IPv4 address of 10.80.80.80.
[Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_reply_cb_id: [8c39000/8c9f400] Adding IDr [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_encode_id: [8c39000/8c9f400] ID(type = ipv4 (1), len = 4, value = 10.80.80.80)
Next the SRX creates an authentication payload, to prove that it is who it claims to be. Here we an find the SRX is using a pre-shared key for this step. For a pre-shared key, the value of the authentication data uses the PRF that was agreed upon to hash a hash of the pre-shared key and and a 17 byte ASCII pad. The value is hashed twice so the software implementation doesn't have to keep the pre-shared in memory for longer than it needs to create the first hash value.
[Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_auth_data: [8c39000/8c9f400] Using local packet [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_auth_data: [8c39000/8c9f400] Using responder nonce [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_auth_data: [8c39000/8c9f400] Using IDi and sk_pi [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_state_auth_initiator_out_auth_shared_key: [8c39000/8c9f400] Try to use shared key [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_add_auth_shared_key: Calling shared_key [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] iked_pm_ike_pre_shared_key Start... [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] iked_pm_id_validate NO remote ID, skip validation. [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_reply_cb_shared_key_local: [8c39000/8c9f400] Shared key found [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_add_auth: [8c39000/8c9f400] Adding AUTH [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_encode_auth: [8c39000/8c9f400] AUTH(method = Shared key (2), len = 20, data = 554d0341 6e2dfcbf 4fdaa3a6 ebefb691 7f5780d2) [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_state_auth_initiator_out_auth_done: [8c39000/8c9f400] No EAP
Next we see some of the efficiencies that are built into IKEv2. As part of the initial exchange, the first CHILD_SA (for traffic protection) is setup and negotiated. Unlike IKEv1, where there is a distinct separation between the negotiation and setup of a secure channel, and the negotiation and setup of traffic protection parameters, IKEv2 mixes these together and gains some efficiencies in the process. The CHILD_SA is covered in more depth in the CHILD_SA section, so we'll just mention these items briefly.
[Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_state_auth_initiator_out_alloc_sa: Calling ipsec_spi_allocate [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_state_auth_initiator_out_sa: [8c39000/8c9f400] Adding SAi2 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_encode_sa: [8c39000/8c9f400] SA([0](id = 1) protocol = ESP (3), AES CBC key len = 128, HMAC-SHA1-96, No ESN; ) [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_encode_sa: IPsec SPI = 0x81cb7deb
Also part of the CHILD_SA, are the traffic selectors which are also carried as payloads. These have the same use as the proxy identity in IKEv1 and are also covered in more depth in the CHILD_SA section.
[Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_state_auth_initiator_out_ts: [8c39000/8c9f400] Adding TSi [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_encode_ts: [8c39000/8c9f400] TS(# ts = 1, [0] type = ipv4 range (7), protocol = 0, port = any, ip range = 0.0.0.0 - 255.255.255.255; ) [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_state_auth_initiator_out_ts: [8c39000/8c9f400] Adding TSr [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_encode_ts: [8c39000/8c9f400] TS(# ts = 1, [0] type = ipv4 range (7), protocol = 0, port = any, ip range = 0.0.0.0 - 255.255.255.255; )
The SRX also sends a couple of notifications as part of the CHILD_SA.
[Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] iked_pm_ike_spd_notify_request: Sending Initial contact [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Sending IKE window size notification for IKE SA of size 1
At this point, the initiator has finished what it needs to do. This processing done by the initiator was finishing off the seting up the secure channel, and alreay getting started on negotiating the traffic protection parameters. Summarizing these actions in our finite state machine boxes reveals the following.
The IKEv2 finite state machine at step three.
Initiator sets up secure channel and starts to negotiate traffic protection.
Finally, the initiator sends off the third packet, in the exchange -- however this is the first encrypted packet.
[Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_state_send: [8c39000/8c9f400] Sending packet [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_udp_send_packet: [8c39000/8c9f400] Sending packet using VR id 0
Packet #3: ISAKMP packet sent to responder.
If you loaded up packet number three in Wireshark or Cloudshark, you probably didn't see to much more than the headers and a bunch of garbage due to all of the nasty encryption. We'll take a short diversion with Wireshark and see how to decrypt all of the IKEv2 payloads.
Encrypted IKEv2 AUTH Payload
To decrypt the values in the IKE_AUTH packets, we'll use the values that strongSwan logged with all of the debug flags turned way up. Specifically, we
will need the SPIs, and values for Sk_a and Sk_e for both the initiator and responder. Parsing through the logs from the charon daemon, charon.log
,
and removing the unnecessary white-space we find the following values:
Parameters needed to decrypt the packet capture
Initiator Cookie 4444ab122717716d Responder Cookie 4980326cef722580 Mar 5 07:43:54 15[IKE] Sk_ai secret => 20 bytes @ 0x7fc230005660 E51F5FBEF67EDF09C172496B3D6A8228CBD841AB Mar 5 07:43:54 15[IKE] Sk_ar secret => 20 bytes @ 0x7fc230005660 AF636DF4D13784FA4EDD88BBEF933591705D6DA0 Mar 5 07:43:54 15[IKE] Sk_ei secret => 16 bytes @ 0x7fc230005090 5892B4C65D17FF4AD5E9BA252999DDAD Mar 5 07:43:54 15[IKE] Sk_er secret => 16 bytes @ 0x7fc230005000 C418B369BCBFDC476B181D87BA3341B7
We start in Wireshark by navigating to Edit -> Preferences, and selecting Protocols from the vertical pane on the left, and selecting the ISAKMP protocol. We then select the "Edit" button listed by the "IKEv2 Decryption Table" label.
Wireshark ISAKMP Protocol Preferences
We then select the "Edit" button listed by the "IKEv2 Decryption Table" label which brings up another dialog box that will allow us to input several sets of parameters to decrypt several different SAs.
Wireshark IKEv2 Decryption Table
Selecting "New" bring up another dialog box where we can input all of our secret keys and SPIs.
Wireshark IKEv2 Decryption Table Data Entry
Selecting, OK twice to apply the parameters and decrypt the packet contents.
Dencrypted IKEv2 AUTH Payload
The responder receives packet number three and reads in the clear-text portions of the packet which is basically the ISAKMP header identifying the IKE version, the SPIs and the type of request. From the SPIs, the responder is able to match up the packet to the ongoing IKEv2 negotiations.
Mar 7 19:43:54 10[ENC] parsing header of message Mar 7 19:43:54 10[ENC] parsing HEADER payload, 236 bytes left Mar 7 19:43:54 10[ENC] parsing payload from => 236 bytes @ 0x7fc228000d60 Mar 7 19:43:54 10[ENC] parsing rule 0 IKE_SPI Mar 7 19:43:54 10[ENC] => => 8 bytes @ 0x7fc2280011b0 Mar 7 19:43:54 10[ENC] 0: 44 44 AB 12 27 17 71 6D DD..'.qm Mar 7 19:43:54 10[ENC] parsing rule 1 IKE_SPI Mar 7 19:43:54 10[ENC] => => 8 bytes @ 0x7fc2280011b8 Mar 7 19:43:54 10[ENC] parsed a IKE_AUTH request Mar 7 19:43:54 16[NET] received packet: from 10.80.80.13[500] to 10.80.80.80[500]
The responder then gets to the encrypted portion of the packet, all of the payloads. Using RFC4306 Section 3.5 and IANA IKEv2 Payload Types we can verify that next payload is ID type 35 is IDi, the Identification of the Initiator.
Identification Payload Format from RFC4306
1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ! Next Payload !C! RESERVED ! Payload Length ! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ! ID Type ! RESERVED | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ! ! ~ Identification Data ~ ! ! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Mar 7 19:43:54 16[ENC] parsing body of message, first payload is ENCRYPTED Mar 7 19:43:54 16[ENC] starting parsing a ENCRYPTED payload Mar 7 19:43:54 16[ENC] parsing ENCRYPTED payload, 208 bytes left Mar 7 19:43:54 16[ENC] parsing payload from => 208 bytes @ 0x7fc228000d7c Mar 7 19:43:54 16[ENC] parsing rule 0 U_INT_8 Mar 7 19:43:54 16[ENC] => 35 Mar 7 19:43:54 16[ENC] parsing rule 1 U_INT_8 Mar 7 19:43:54 16[ENC] => 0 Mar 7 19:43:54 16[ENC] parsing rule 2 PAYLOAD_LENGTH Mar 7 19:43:54 16[ENC] => 208 Mar 7 19:43:54 16[ENC] parsing rule 3 ENCRYPTED_DATA Mar 7 19:43:54 16[ENC] => => 204 bytes @ 0x7fc23c000a20 Mar 7 19:43:54 16[ENC] parsing ENCRYPTED payload finished Mar 7 19:43:54 16[ENC] verifying payload of type ENCRYPTED Mar 7 19:43:54 16[ENC] ENCRYPTED payload verified. Adding to payload list Mar 7 19:43:54 16[ENC] ENCRYPTED payload found. Stop parsing Mar 7 19:43:54 16[ENC] process payload of type ENCRYPTED Mar 7 19:43:54 16[ENC] found an encryption payload
The responder uses Sk_ei to decrypt the rest of the packet, and Sk_ai to check that it hasn't been tampered with.
Mar 7 19:43:54 16[ENC] encryption payload decryption: Mar 7 19:43:54 16[ENC] IV => 16 bytes @ 0x7fc23c000a20 Mar 7 19:43:54 16[ENC] encrypted => 188 bytes @ 0x7fc23c000a30 Mar 7 19:43:54 16[ENC] ICV => 12 bytes @ 0x7fc23c000ae0 Mar 7 19:43:54 16[ENC] assoc => 32 bytes @ 0x7fc23c000ff0 Mar 7 19:43:54 16[ENC] plain => 164 bytes @ 0x7fc23c000a30 Mar 7 19:43:54 16[ENC] padding => 12 bytes @ 0x7fc23c000ad4 Mar 7 19:43:54 16[ENC] 0: 00 00 00 00 00 00 00 00 00 00 00 0B ............
After decryption, the first payload can be parsed out. We know that it is a IDi payload, and by cross referencing RFC4306 and the IANA IKEv2 listing again we can set that the next payload ID type 36 is IDr, the Identification of the Responder. None of the flags or reserved bits have been set, the length of the payload is 12 bytes, and a value of 1 for the ID type corresponds to an IPv4 address. The ID data contains 0x0A 50 50 0D, which when converted from hex to dotted quad notation is 10.80.80.13 .
Mar 7 19:43:54 16[ENC] parsing ID_INITIATOR payload, 164 bytes left Mar 7 19:43:54 16[ENC] parsing payload from => 164 bytes @ 0x7fc23c000a30 Mar 7 19:43:54 16[ENC] parsing rule 0 U_INT_8 Mar 7 19:43:54 16[ENC] => 36 Mar 7 19:43:54 16[ENC] parsing rule 1 FLAG Mar 7 19:43:54 16[ENC] => 0 Mar 7 19:43:54 16[ENC] parsing rule 2 RESERVED_BIT Mar 7 19:43:54 16[ENC] => 0 Mar 7 19:43:54 16[ENC] parsing rule 3 RESERVED_BIT Mar 7 19:43:54 16[ENC] => 0 Mar 7 19:43:54 16[ENC] parsing rule 4 RESERVED_BIT Mar 7 19:43:54 16[ENC] => 0 Mar 7 19:43:54 16[ENC] parsing rule 5 RESERVED_BIT Mar 7 19:43:54 16[ENC] => 0 Mar 7 19:43:54 16[ENC] parsing rule 6 RESERVED_BIT Mar 7 19:43:54 16[ENC] => 0 Mar 7 19:43:54 16[ENC] parsing rule 7 RESERVED_BIT Mar 7 19:43:54 16[ENC] => 0 Mar 7 19:43:54 16[ENC] parsing rule 8 RESERVED_BIT Mar 7 19:43:54 16[ENC] => 0 Mar 7 19:43:54 16[ENC] parsing rule 9 PAYLOAD_LENGTH Mar 7 19:43:54 16[ENC] => 12 Mar 7 19:43:54 16[ENC] parsing rule 10 U_INT_8 Mar 7 19:43:54 16[ENC] => 1 Mar 7 19:43:54 16[ENC] parsing rule 11 RESERVED_BYTE Mar 7 19:43:54 16[ENC] => 0 Mar 7 19:43:54 16[ENC] parsing rule 12 RESERVED_BYTE Mar 7 19:43:54 16[ENC] => 0 Mar 7 19:43:54 16[ENC] parsing rule 13 RESERVED_BYTE Mar 7 19:43:54 16[ENC] => 0 Mar 7 19:43:54 16[ENC] parsing rule 14 ID_DATA Mar 7 19:43:54 16[ENC] => => 4 bytes @ 0x7fc23c0049b0 Mar 7 19:43:54 16[ENC] 0: 0A 50 50 0D .PP. Mar 7 19:43:54 16[ENC] parsing ID_INITIATOR payload finished
Following the same procedure for the next payload, the IDr for the Responders Identity that the initiator is expecting to create an SA with, we find that it desires to talk to an IPv4 address of 0x 0A 50 50 50 (10.80.80.80). We also discover that the next payload is type 39, Authentication.
Mar 7 19:43:54 16[ENC] parsing ID_RESPONDER payload, 152 bytes left Mar 7 19:43:54 16[ENC] parsing payload from => 152 bytes @ 0x7fc23c000a3c Mar 7 19:43:54 16[ENC] parsing rule 0 U_INT_8 Mar 7 19:43:54 16[ENC] => 39 Mar 7 19:43:54 16[ENC] parsing rule 1 FLAG Mar 7 19:43:54 16[ENC] => 0 Mar 7 19:43:54 16[ENC] parsing rule 2 RESERVED_BIT Mar 7 19:43:54 16[ENC] => 0 Mar 7 19:43:54 16[ENC] parsing rule 3 RESERVED_BIT Mar 7 19:43:54 16[ENC] => 0 Mar 7 19:43:54 16[ENC] parsing rule 4 RESERVED_BIT Mar 7 19:43:54 16[ENC] => 0 Mar 7 19:43:54 16[ENC] parsing rule 5 RESERVED_BIT Mar 7 19:43:54 16[ENC] => 0 Mar 7 19:43:54 16[ENC] parsing rule 6 RESERVED_BIT Mar 7 19:43:54 16[ENC] => 0 Mar 7 19:43:54 16[ENC] parsing rule 7 RESERVED_BIT Mar 7 19:43:54 16[ENC] => 0 Mar 7 19:43:54 16[ENC] parsing rule 8 RESERVED_BIT Mar 7 19:43:54 16[ENC] => 0 Mar 7 19:43:54 16[ENC] parsing rule 9 PAYLOAD_LENGTH Mar 7 19:43:54 16[ENC] => 12 Mar 7 19:43:54 16[ENC] parsing rule 10 U_INT_8 Mar 7 19:43:54 16[ENC] => 1 Mar 7 19:43:54 16[ENC] parsing rule 11 RESERVED_BYTE Mar 7 19:43:54 16[ENC] => 0 Mar 7 19:43:54 16[ENC] parsing rule 12 RESERVED_BYTE Mar 7 19:43:54 16[ENC] => 0 Mar 7 19:43:54 16[ENC] parsing rule 13 RESERVED_BYTE Mar 7 19:43:54 16[ENC] => 0 Mar 7 19:43:54 16[ENC] parsing rule 14 ID_DATA Mar 7 19:43:54 16[ENC] => => 4 bytes @ 0x7fc23c004a70 Mar 7 19:43:54 16[ENC] 0: 0A 50 50 50 .PPP Mar 7 19:43:54 16[ENC] parsing ID_RESPONDER payload finished
Next the responder parses through the Authentication payload. Using RFC4306 Section 3.8 we find that the next payload to expect is type 33, an SA. We also find that the authentication type is 2, Shared Key Message Integrity Code, which is our pre-shared-key run through our PRF a couple of times.
Authentication Payload Format from RFC4306
1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ! Next Payload !C! RESERVED ! Payload Length ! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ! Auth Method ! RESERVED ! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ! ! ~ Authentication Data ~ ! ! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Mar 7 19:43:54 16[ENC] parsing AUTHENTICATION payload, 140 bytes left Mar 7 19:43:54 16[ENC] parsing payload from => 140 bytes @ 0x7fc23c000a48 Mar 7 19:43:54 16[ENC] parsing rule 0 U_INT_8 Mar 7 19:43:54 16[ENC] => 33 Mar 7 19:43:54 16[ENC] parsing rule 1 FLAG Mar 7 19:43:54 16[ENC] => 0 Mar 7 19:43:54 16[ENC] parsing rule 2 RESERVED_BIT Mar 7 19:43:54 16[ENC] => 0 Mar 7 19:43:54 16[ENC] parsing rule 3 RESERVED_BIT Mar 7 19:43:54 16[ENC] => 0 Mar 7 19:43:54 16[ENC] parsing rule 4 RESERVED_BIT Mar 7 19:43:54 16[ENC] => 0 Mar 7 19:43:54 16[ENC] parsing rule 5 RESERVED_BIT Mar 7 19:43:54 16[ENC] => 0 Mar 7 19:43:54 16[ENC] parsing rule 6 RESERVED_BIT Mar 7 19:43:54 16[ENC] => 0 Mar 7 19:43:54 16[ENC] parsing rule 7 RESERVED_BIT Mar 7 19:43:54 16[ENC] => 0 Mar 7 19:43:54 16[ENC] parsing rule 8 RESERVED_BIT Mar 7 19:43:54 16[ENC] => 0 Mar 7 19:43:54 16[ENC] parsing rule 9 PAYLOAD_LENGTH Mar 7 19:43:54 16[ENC] => 28 Mar 7 19:43:54 16[ENC] parsing rule 10 U_INT_8 Mar 7 19:43:54 16[ENC] => 2 Mar 7 19:43:54 16[ENC] parsing rule 11 RESERVED_BYTE Mar 7 19:43:54 16[ENC] => 0 Mar 7 19:43:54 16[ENC] parsing rule 12 RESERVED_BYTE Mar 7 19:43:54 16[ENC] => 0 Mar 7 19:43:54 16[ENC] parsing rule 13 RESERVED_BYTE Mar 7 19:43:54 16[ENC] => 0 Mar 7 19:43:54 16[ENC] parsing rule 14 AUTH_DATA Mar 7 19:43:54 16[ENC] => => 20 bytes @ 0x7fc23c004b50 Mar 7 19:43:54 16[ENC] 0: 55 4D 03 41 6E 2D FC BF 4F DA A3 A6 EB EF B6 91 UM.An-..O....... Mar 7 19:43:54 16[ENC] 16: 7F 57 80 D2 .W.. Mar 7 19:43:54 16[ENC] parsing AUTHENTICATION payload finished
Next the responder starts to read in the payloads that run into the CHILD_SA part of the exchange. The SA, the traffic selectors, and the two notifications.
Mar 7 19:43:54 16[ENC] parsing SECURITY_ASSOCIATION payload, 112 bytes left Mar 7 19:43:54 16[ENC] parsing TRAFFIC_SELECTOR_INITIATOR payload, 68 bytes left Mar 7 19:43:54 16[ENC] parsing TRAFFIC_SELECTOR_RESPONDER payload, 44 bytes left Mar 7 19:43:54 16[ENC] parsing NOTIFY payload, 20 bytes left Mar 7 19:43:54 16[ENC] parsing NOTIFY payload, 12 bytes left
At this point the responder has parsed all of the contents of the packet, and it's time to process them and check everything out.
Mar 7 19:43:54 16[ENC] process payload of type ID_INITIATOR Mar 7 19:43:54 16[ENC] process payload of type ID_RESPONDER Mar 7 19:43:54 16[ENC] process payload of type AUTHENTICATION Mar 7 19:43:54 16[ENC] process payload of type SECURITY_ASSOCIATION Mar 7 19:43:54 16[ENC] process payload of type TRAFFIC_SELECTOR_INITIATOR Mar 7 19:43:54 16[ENC] process payload of type TRAFFIC_SELECTOR_RESPONDER Mar 7 19:43:54 16[ENC] process payload of type NOTIFY Mar 7 19:43:54 16[ENC] process payload of type NOTIFY
It starts by checking the authentication payload. It runs through the process in RFC4306 section 2.15. It first finds the pre-shared key it has configured for the ID of IPv4 address 10.80.80.13 (0x0A80800D), which is "juniper123". It uses the the 17 byte ASCII pad "" with the pre-shared-key and the PRF that was negotiated ealier (HMAC-SHA1) to create the first hash. Who says the RFC writers have lost their sense of humor?
We can verify the value of prf(secret, keypad), which will be HMAC-SHA1(juniper123,"Key Pad for IKEv2") with openssl:
juniper@server:~$ echo -n "Key Pad for IKEv2" | openssl sha1 -hmac juniper123 (stdin)= 9f2c649be18879821b4f2027d1b0ea22c4735005
Confession: I tried to verify the value of AUTH with OpenSSL and the 388 bytes of the message but I couldn't get it to work. I'll take strongSwan's word for it.
Anyway, the responder successfully authenticated the initiator! That means that it can proceed with processing the rest of the payloads and formulate a reply without wasting any CPU cycles.
Mar 7 19:43:54 16[ENC] parsed IKE_AUTH request 1 [ IDi IDr AUTH SA TSi TSr N(INIT_CONTACT) N(SET_WINSIZE) ] Mar 7 19:43:54 16[CFG] looking for peer configs matching 10.80.80.80[10.80.80.80]...10.80.80.13[10.80.80.13] Mar 7 19:43:54 16[CFG] selected peer config 'srx-13' Mar 7 19:43:54 16[IKE] IDx' => 8 bytes @ 0x7fc24d6939c0 Mar 7 19:43:54 16[IKE] 0: 01 00 00 00 0A 50 50 0D .....PP. Mar 7 19:43:54 16[IKE] SK_p => 20 bytes @ 0x7fc230005000 Mar 7 19:43:54 16[IKE] 0: 08 0B 57 0B 5C 77 F5 6B 36 D2 1E 5B 74 EF 18 DC ..W.\w.k6..[t... Mar 7 19:43:54 16[IKE] 16: 07 89 B1 40 ...@ Mar 7 19:43:54 16[IKE] octets = message + nonce + prf(Sk_px, IDx') => 388 bytes @ 0x7fc23c005970 Mar 7 19:43:54 16[IKE] secret => 10 bytes @ 0x7fc26207ff70 Mar 7 19:43:54 16[IKE] 0: 6A 75 6E 69 70 65 72 31 32 33 juniper123 Mar 7 19:43:54 16[IKE] prf(secret, keypad) => 20 bytes @ 0x7fc23c005950 Mar 7 19:43:54 16[IKE] 0: 9F 2C 64 9B E1 88 79 82 1B 4F 20 27 D1 B0 EA 22 .,d...y..O '..." Mar 7 19:43:54 16[IKE] 16: C4 73 50 05 .sP. Mar 7 19:43:54 16[IKE] AUTH = prf(prf(secret, keypad), octets) => 20 bytes @ 0x7fc23c005b00 Mar 7 19:43:54 16[IKE] 0: 55 4D 03 41 6E 2D FC BF 4F DA A3 A6 EB EF B6 91 UM.An-..O....... Mar 7 19:43:54 16[IKE] 16: 7F 57 80 D2 .W.. Mar 7 19:43:54 16[IKE] authentication of '10.80.80.13' with pre-shared key successful
Next the responder creates it's own Authentication payload so the inititor can verify he's talking to the right peer and not some man-in-the-middle.
Mar 7 19:43:54 16[ENC] added payload of type ID_RESPONDER to message Mar 7 19:43:54 16[IKE] authentication of '10.80.80.80' (myself) with pre-shared key Mar 7 19:43:54 16[IKE] IDx' => 8 bytes @ 0x7fc24d6939f0 Mar 7 19:43:54 16[IKE] 0: 01 00 00 00 0A 50 50 50 .....PPP Mar 7 19:43:54 16[IKE] SK_p => 20 bytes @ 0x7fc230005020 Mar 7 19:43:54 16[IKE] 0: E1 F6 E1 B3 DB B7 84 D5 99 3D 00 C2 D6 21 D3 06 .........=...!.. Mar 7 19:43:54 16[IKE] 16: 5B E6 19 AC [... Mar 7 19:43:54 16[IKE] octets = message + nonce + prf(Sk_px, IDx') => 384 bytes @ 0x7fc23c006ad0 Mar 7 19:43:54 16[IKE] secret => 10 bytes @ 0x7fc26207ff70 Mar 7 19:43:54 16[IKE] 0: 6A 75 6E 69 70 65 72 31 32 33 juniper123 Mar 7 19:43:54 16[IKE] prf(secret, keypad) => 20 bytes @ 0x7fc23c000b30 Mar 7 19:43:54 16[IKE] 0: 9F 2C 64 9B E1 88 79 82 1B 4F 20 27 D1 B0 EA 22 .,d...y..O '..." Mar 7 19:43:54 16[IKE] 16: C4 73 50 05 .sP. Mar 7 19:43:54 16[IKE] AUTH = prf(prf(secret, keypad), octets) => 20 bytes @ 0x7fc23c006cd0 Mar 7 19:43:54 16[IKE] 0: 2B 97 00 08 66 30 C5 52 56 6A 46 9F DD 8E E5 E7 +...f0.RVjF..... Mar 7 19:43:54 16[IKE] 16: 07 A4 6F C5 ..o. Mar 7 19:43:54 16[IKE] successfully created shared key MAC Mar 7 19:43:54 16[ENC] added payload of type AUTHENTICATION to message
The responder at this point officialy declares that it's happy enough to declare the Initial SA established!
Mar 7 19:43:54 16[IKE] IKE_SA srx-13[1] established between 10.80.80.80[10.80.80.80]...10.80.80.13[10.80.80.13] Mar 7 19:43:54 16[IKE] IKE_SA srx-13[1] state change: CONNECTING => ESTABLISHED
At this point the strongSwan client also has enough information to declare it's CHILD_SA up. It sends some messages to the Linux kernel via system calls that it needs to setup some cryptographic transformations in the networking stack.
Mar 7 19:43:54 16[KNL] sending XFRM_MSG_ALLOCSPI: => 248 bytes @ 0x7fc24d693660
However, the responder still needs to send it's authentication message, and let it know that it's agreed upon the parameters in the CHILD_SA so it needs to send one more packet back to the initiator.
Mar 7 19:43:54 16[ENC] added payload of type SECURITY_ASSOCIATION to message Mar 7 19:43:54 16[ENC] added payload of type TRAFFIC_SELECTOR_INITIATOR to message Mar 7 19:43:54 16[ENC] added payload of type TRAFFIC_SELECTOR_RESPONDER to message Mar 7 19:43:54 16[IKE] CHILD_SA srx-13{1} established with SPIs c9c54fcc_i 81cb7deb_o and TS 1.0.0.0/8 === 2.0.0.0/8 Mar 7 19:43:54 16[ENC] added payload of type NOTIFY to message Mar 7 19:43:54 16[ENC] added payload of type ID_RESPONDER to message Mar 7 19:43:54 16[ENC] added payload of type AUTHENTICATION to message Mar 7 19:43:54 16[ENC] added payload of type SECURITY_ASSOCIATION to message Mar 7 19:43:54 16[ENC] added payload of type TRAFFIC_SELECTOR_INITIATOR to message Mar 7 19:43:54 16[ENC] added payload of type TRAFFIC_SELECTOR_RESPONDER to message Mar 7 19:43:54 16[ENC] added payload of type NOTIFY to message Mar 7 19:43:54 16[ENC] generating IKE_AUTH response 1 [ IDr AUTH SA TSi TSr N(AUTH_LFT) ] Mar 7 19:43:54 16[ENC] insert payload ID_RESPONDER to encryption payload Mar 7 19:43:54 16[ENC] insert payload AUTHENTICATION to encryption payload Mar 7 19:43:54 16[ENC] insert payload SECURITY_ASSOCIATION to encryption payload Mar 7 19:43:54 16[ENC] insert payload TRAFFIC_SELECTOR_INITIATOR to encryption payload Mar 7 19:43:54 16[ENC] insert payload TRAFFIC_SELECTOR_RESPONDER to encryption payload Mar 7 19:43:54 16[ENC] insert payload NOTIFY to encryption payload Mar 7 19:43:54 16[ENC] generating payload of type HEADER
It encrypts all of the payloads with Sk_er and adds an integrity check with SK_ar.
Mar 7 19:43:54 16[ENC] generated content in encryption payload Mar 7 19:43:54 16[ENC] encryption payload encryption: Mar 7 19:43:54 16[ENC] generating payload of type ENCRYPTED
The IKEv2 finite state machine actions at step 4.
Responder authenticates the Initiator, and sends back it's own proof of Identity.
And the responder sends off packet #4 back to the initiator. This is the last packet in the initial exchange, and also the last packet that completes the first CHILD_SA.
[Feb 11 20:39:53][192.168.13.13 <-> 192.168.11.11] ike_send_packet: Start, send SA = { 66d3e0d1 4604eb50 - 89829bbf 324bc708}, nego = -1, dst = 192.168.11.11:500, routing table id = 0
Packet #4: IKEv2 packet sent to initiator.
The initiator recieves the final packet of the IKEv2 initial exchange and matches it to the SA that is in progress.
[Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] *** Processing received packet from 10.80.80.80:500 to 10.80.80.13:0 VR 0 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_packet_st_input_start: [8c39400/0] Processing received [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Found IKEv2 P1 SA 3283989 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_packet_st_input_get_or_create_sa: [8c39400/8c9f400] Packet to existing v2 SA
As the packet is now encrypted, it has to be decoded and checked.
[Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_decode_packet: [8c39400/8c9f400] Decoding packet [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_decode_packet: [8c39400/8c9f400] Encrypted packet [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_decode_encr: Mac input [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_decode_encr: [8c39400/8c9f400] Packet decrypted successfully
Inside it finds a payload with the identity of the responder, IDr.
[Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_decode_id: [8c39400/8c9f400] IDr(type = ipv4 (1), len = 4, value = 10.80.80.80)
A payload filled with authentication data.
[Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_decode_auth: [8c39400/8c9f400] AUTH(method = Shared key (2), len = 20, data = 2b970008 6630c552 566a469f dd8ee5e7 07a46fc5)
And some payloads for the CHILD_SA that is being established, a security association payload, traffic selector payloads for the initiator side and the responder side, and a notification payload.
[Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_decode_sa: [8c39400/8c9f400] SA([0](id = 1) protocol = ESP (3), spi_len = 4, spi = 0xc9c54fcc, AES CBC key len = 128, HMAC-SHA1-96, No ESN; ) [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ssh_ikev2_ts_allocate: Allocated ts 0x8bf34c0, ref_cnt 1 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_decode_ts: [8c39400/8c9f400] TSi(# ts = 1, [0] type = ipv4 range (7), protocol = 0, port = any, ip range = 2.0.0.0 - 2.255.255.255; ) [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ssh_ikev2_ts_allocate: Allocated ts 0x8bf3e20, ref_cnt 1 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_decode_ts: [8c39400/8c9f400] TSr(# ts = 1, [0] type = ipv4 range (7), protocol = 0, port = any, ip range = 1.0.0.0 - 1.255.255.255; ) [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_decode_notify: Calling notify_received
The initiator now checks the authentication payload to make sure it's talking to the right responder, and finds that it checks out OK.
Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_auth_data: [8c39400/8c9f400] Using remote packet [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_auth_data: [8c39400/8c9f400] Using initiator nonce [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_auth_data: [8c39400/8c9f400] Using IDr and sk_pr [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_state_auth_initiator_in_shared_key: [8c39400/8c9f400] Verify shared key AUTH payload [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_check_auth_shared_key: Calling shared_key [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] iked_pm_ike_pre_shared_key Start... [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_fb_idv2_to_idv1: Converting the IKEv2 payload ID ID(type = ipv4 (1), len = 4, value = 10.80.80.80) to IKEv1 ID [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_fb_idv2_to_idv1: IKEv2 payload ID converted to IKEv1 payload ID ipv4(any:0,[0..3]=10.80.80.80) [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] iked_pm_id_validate called with id ipv4(any:0,[0..3]=10.80.80.80) [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] kmd_ipaddr2ikeid: ipaddr = 10.80.80.80 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] iked_pm_id_validate Use default id [ipv4(any:0,[0..3]=10.80.80.80)] [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] iked_pm_id_validate default id matched. [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_reply_cb_shared_key_auth_verify: [8c39400/8c9f400] Auth payload ok
At this time, the responder is happy! The initial portion of the SA is officially over, and the IKEv2 secure channel has been established.
The responder still has some work to do to finish off the first CHILD_SA to setup the traffic protection profiles.
[Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_state_auth_initiator_in_eap: [8c39400/8c9f400] State = AUTH_LAST [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_state_auth_initiator_in_eap: [8c39400/8c9f400] SAr2, TSi, or TSr, so this is final packet [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_state_auth_initiator_in_sa: [8c39400/8c9f400] Verify SAr2 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_state_auth_initiator_in_sa: [8c39400/8c9f400] SAr2 was ok [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_state_auth_initiator_in_ts: [8c39400/8c9f400] TSi and TSr were ok [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ikev2_state_auth_initiator_in_done: Calling ipsec_sa_install [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] iked_pm_ipsec_sa_install: local:10.80.80.13, remote:10.80.80.80 IKEv2 for SA-CFG SERVER-BOX [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] iked_update_sa_cfg_port sa_cfg(SERVER-BOX) local_port(0)and remote_port(500) [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Setting lifetime 1200 and lifesize 0 for IPSec SA [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] iked_pm_ipsec_sa_create: encr key len 16, auth key len: 20, salt len: 0 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Creating a SA spi=0x81cb7deb, proto=ESP pair_index = 1 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Added (spi=0x81cb7deb, protocol=ESP dst=10.80.80.13) entry to the peer hash table [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] iked_sa_cfg_update_sa_cfg_child_sa_count Parent not found for sa_cfg SERVER-BOX [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] iked_lookup_peer_entry: Peer entry 0x8c95200 FOUND for local 10.80.80.13:500 and remote 10.80.80.80:500 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Peer entry exist for local 10.80.80.13:500 and remote 10.80.80.80:500 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] iked_peer_insert_sa_cfg_entry: insert sa_cfg tunnel_id entry 131074 into peer entry 0x8c95200 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Creating a SA spi=0xc9c54fcc, proto=ESP pair_index = 1 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Added (spi=0xc9c54fcc, protocol=ESP dst=10.80.80.80) entry to the peer hash table [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] iked_sa_cfg_update_sa_cfg_child_sa_count Parent not found for sa_cfg SERVER-BOX [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] iked_nhtb_update_on_sa_create: Interface st0.80 is P2P for sa_cfg SERVER-BOX. Thus ignoring NHTB notification message [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] iked_pm_ipsec_sa_install: SA LIFE CREATED time 1394001833 with HARD LIFETIME SECONDS 1200 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Hardlife timer started for inbound SERVER-BOX with 1200 seconds/0 kilobytes [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Softlife timer started for inbound SERVER-BOX with 933 seconds/0 kilobytes
To summarize the last step of the IKEv2 initial exchanges, our finite state machine box takes on the following:
The final step of the IKEv2 finite state machine.
Initiator verifies responder's identity, installs CHILD_SA .
And the SRX that initiated the exchange displays a nice log message that it has completed the initial exchanges.
Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ----------------Voyager ipsec SA BUNDLE------------------- [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] SA pair update request for: Tunnel index: 131074 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Local Gateway address: 10.80.80.13 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Primary remote Gateway address: 10.80.80.80 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Backup remote Gateway State: Active [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Anti replay: counter-based enabled [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Window_size: 64 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Server Time: 0 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Peer : Static [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Mode : Tunnel [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] VPN Type : route-based [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Tunnel mtu: 0 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] DF bit: 0 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] local-if ifl idx: 1207959552 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] tunnel-if ifl idx: 1291845632 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Tunnel mtu: 0 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] DPD interval: 0 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] policy id: 0 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] NATT enabled: 0 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] NATT version: 0 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] NAT position: 0 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] SA Idle time: 0 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] SA Outbound install delay time: 1 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] IKED ID: 0 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] DIST ID: 0 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Keepalive interval: 0 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] VPN monitoring interval: 0 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] VPN monitoring optimized: 0 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Respond-bad-SPI: 0 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] seq_out: 0 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Local port: 0 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Remote port: 500 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] SA CFG name: SERVER-BOX [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Dial-up IKE ID: [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] RG ID: 0 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Group template tunnel ID: 0 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ----------------Incoming SA ------------------- [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] SPI: 0x81cb7deb Protocol: 2 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Algorithm: 130 Auth key. length: 20 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Encr key. length; 16 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] ----------------Outgoing SA ------------------- [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] SPI: 0xc9c54fcc Protocol: 2 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Algorithm: 130 Auth key. length: 20 [Mar 5 06:43:53][10.80.80.13 <-> 10.80.80.80] Encr key. length; 16