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.
Phase 2 is where network traffic encryption/authentication parameters are actually negotiated and the security associations to do so are setup. There is only one mode in which Phase 2 operates known as Quick Mode.
Quick mode cannot stand alone, it is innately bound to an IKEv1 Phase 1 negotiation. It depends on the secure channel setup by Phase 1 to protect the exchanges that occur which negotiate the SAs for network traffic encryption/authentication. Nonces are exchanged between peers in Quick Mode for replay protection. The keying material is normally derived from the secret keying material used for Phase 1, but there is an option to perform another completely unrelated Diffie-Hellman-Merkel exchange and generate secrets that are not derivative of any other keys. This separate Diffie-Hellman-Merkel exchange is known as Perfect Forward Secrecy (PFS) and makes it much more difficult for an eavesdropper to guess (brute-force or otherwise) the secret keys used to encrypt and authenticate the protected traffic.
For the setup, we are going to shift things a bit and look at the Phase 2 exchange between a Juniper SRX and a Linux box using strongSwan. The reason for this is so we can do some more analysis of the packet captures. As Phase 2 is completely protected by the work done in Phase 1, all of the raw packet captures are fairly boring and just show a bunch of encrypted data contained within. strongSwan can be run at debug levels that will log all of the encryption keys used, whereas the SRX keeps those types of things out of the logs. I thought I saw one of the SRXes log the Diffie-Hellman-Merkel secret g^xy, but a careful search of the logs of several exchanges didn't reveal anything sensitive. Having one of the peers run strongSwan will allow us to use a recent version of Wireshark to decrypt all of the packet contents.
The IKE exchange we will be probing will be between SRX-13 and the Server as shown in the diagram.
Network setup for IKEv1 Phase 2, Quick Mode
SRX-13 has a tunnel setup to the Server. This isn't really meant to be a working tunnel at this point, just enough to complete an IKEv1 exchange all of the way through Phase 1 and Phase 2. For Phase 1, we will be using main mode. The Linux Server running strongSwan will be acting as the initiator, and SRX-13 will be acting as the responder. We will be capturing packets on the network link between SRX-13 and the Server for analysis.
The relevant configuration on SRX-13 for the test, and the Server are shown below.
SRX-13 configuration for Quick Mode
interfaces { ge-0/0/3 { description "Connection to Server"; unit 0 { family inet { address 10.80.80.13/24 ; } } } ge-0/0/6 { unit 0 { family inet { address 172.18.3.13/24; } family iso; } } lo0 { unit 0 { family inet { address 192.168.13.13/32; } family iso { address 49.0000.0000.0000.0013.00; } } } st0 { unit 80 { family inet { address 172.19.80.13/24; } } } } protocols { isis { level 2 disable; interface ge-0/0/3.0 { passive; } interface ge-0/0/6.0; interface lo0.0 { passive; } } } security { ike { traceoptions { file IKEv1-quick.log size 10m; } proposal IKE-PROPOSAL { authentication-method pre-shared-keys; dh-group group2; authentication-algorithm md5; encryption-algorithm 3des-cbc; lifetime-seconds 86400; } policy IKE-POLICY { mode main; proposals IKE-PROPOSAL; pre-shared-key ascii-text "$9$spgaUqmT/CujHCuO1yrYgoJjH.P5F69"; } gateway SERVER-BOX { ike-policy IKE-POLICY; address 10.80.80.80; local-identity inet 10.80.80.13; remote-identity inet 10.80.80.80; external-interface ge-0/0/3.0; version v1-only; } } ipsec { proposal IPSEC-PROPOSAL { protocol esp; authentication-algorithm hmac-sha1-96; encryption-algorithm aes-128-cbc; lifetime-seconds 1200; } policy IPSEC-POLICY { proposals IPSEC-PROPOSAL; } vpn SERVER-BOX { bind-interface st0.80; ike { gateway SERVER-BOX; ipsec-policy IPSEC-POLICY; } establish-tunnels on-traffic; } } forwarding-options { family { iso { mode packet-based; } } } policies { default-policy { permit-all; } } zones { security-zone TRUST { host-inbound-traffic { system-services { ping; traceroute; ike; } } interfaces { ge-0/0/3.0; st0.80; } } } }
strongSwan ipsec.conf file on Server
# ipsec.conf - strongSwan IPsec configuration file config setup plutodebug=all plutostderrlog = /var/log/pluto.log plutostart=yes # VPN connection to SRX-13 conn srx-13 auto=add keyexchange=ikev1 ikelifetime=24h ike=3des-md5-modp1024 authby=psk keyingtries=1 left=10.80.80.80 leftid=10.80.80.80 leftsubnet=0.0.0.0/0 right=10.80.80.13 rightid=10.80.80.13 rightsubnet=0.0.0.0/0 esp=aes128-sha1 pfs=no
strongSwan ipsec.secrets file on Server
# This file holds shared secrets or RSA private keys for inter-Pluto # authentication. See ipsec_pluto(8) manpage, and HTML documentation. 10.80.80.80 10.80.80.13 : PSK "juniper123"
We initiate the IKE exchange on the server with the following command: ipsec up srx-13
. Afterwhich, we have the following security associations
on the server and on SRX-13.
Security Associations on server
root@server:~# ipsec status 000 "srx-13": 0.0.0.0/0===10.80.80.80[10.80.80.80]...10.80.80.13[10.80.80.13]===0.0.0.0/0; erouted; eroute owner: #2 000 "srx-13": newest ISAKMP SA: #1; newest IPsec SA: #2; 000 000 #2: "srx-13" STATE_QUICK_I2 (sent QI2, IPsec SA established); EVENT_SA_REPLACE in 2835s; newest IPSEC; eroute owner 000 #2: "srx-13" esp.5ef52687@10.80.80.13 (0 bytes) esp.c786011d@10.80.80.80 (0 bytes); tunnel 000 #1: "srx-13" STATE_MAIN_I4 (ISAKMP SA established); EVENT_SA_REPLACE in 85394s; newest ISAKMP 000 Security Associations: none root@server:~#
Security Associations on SRX-13
juniper@SRX-13> show security ike security-associations detail IKE peer 10.80.80.80, Index 2719962, Gateway Name: SERVER-BOX Role: Responder, State: UP Initiator cookie: a305bbc510fd3640, Responder cookie: d16dd2ce1e0390ec Exchange type: Main, Authentication method: Pre-shared-keys Local: 10.80.80.13:500, Remote: 10.80.80.80:500 Lifetime: Expires in 86378 seconds Peer ike-id: 10.80.80.80 Xauth assigned IP: 0.0.0.0 Algorithms: Authentication : hmac-md5-96 Encryption : 3des-cbc Pseudo random function: hmac-md5 Diffie-Hellman group : DH-group-2 Traffic statistics: Input bytes : 584 Output bytes : 696 Input packets: 5 Output packets: 4 Flags: IKE SA is created IPSec security associations: 1 created, 0 deleted Phase 2 negotiations in progress: 0 Negotiation type: Quick mode, Role: Responder, 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> show security ipsec security-associations detail ID: 131073 Virtual-system: root, VPN Name: SERVER-BOX Local Gateway: 10.80.80.13, Remote Gateway: 10.80.80.80 Local Identity: ipv4_subnet(any:0,[0..7]=0.0.0.0/0) Remote Identity: ipv4_subnet(any:0,[0..7]=0.0.0.0/0) Version: IKEv1 DF-bit: clear Bind-interface: st0.80 Port: 500, Nego#: 5, Fail#: 0, Def-Del#: 0 Flag: 0x600a29 Last Tunnel Down Reason: Delete payload received Direction: inbound, SPI: 5ef52687, AUX-SPI: 0 , VPN Monitoring: - Hard lifetime: Expires in 1175 seconds Lifesize Remaining: Unlimited Soft lifetime: Expires in 972 seconds Mode: Tunnel(0 0), Type: dynamic, State: installed Protocol: ESP, Authentication: hmac-sha1-96, Encryption: aes-cbc (128 bits) Anti-replay service: counter-based enabled, Replay window size: 64 Direction: outbound, SPI: c786011d, AUX-SPI: 0 , VPN Monitoring: - Hard lifetime: Expires in 1175 seconds Lifesize Remaining: Unlimited Soft lifetime: Expires in 972 seconds Mode: Tunnel(0 0), Type: dynamic, State: installed Protocol: ESP, Authentication: hmac-sha1-96, Encryption: aes-cbc (128 bits) Anti-replay service: counter-based enabled, Replay window size: 64 juniper@SRX-13>
As we go through this example, we're going to dig through a packet capture of the entire exchange, and crawl through the logs line by line.
You can download the entire IKEv1 main mode exchange with pre-shared keys, the
IKE logs from the responder SRX-13 and the IKE logs from the pluto daemon in order to parse through at
your leisure. The pluto daemon handles IKEv1 exchanges in strongSwan. The plutodebug=all
line in the ipsec.conf
file on the
server is necessary to log the encryption keys that will be used for the IKEv1 secure channel.
If we view the packet capture in Wireshark, or run it through tcpdump all we see as far as payloads for the ISAKMP quick mode packets are "Encrypted Data" or "Encrypted Hash".
Wireshark showing encrypted data for ISAKMP Quick Mode Payload
To decrypt this data, we need to find the Initiator's cookie and encryption keys that were logged into the pluto.log file during the exchange. These values need to be entered into a table in the ISAKMP protocol dissector in Wireshark in order to decrypt it without any whitespace.
Finding the Initiator's cookie in the pluto.log file
juniper@server:~$ grep ICOOKIE /var/log/pluto.log | uniq | sed s/" "/""/g |ICOOKIE:a305bbc510fd3640 juniper@server:~$
The encryption key is in the log file listed as "enc key", but it normally covers two lines, starting a line 542. We'll use a couple of sed expressions to remove the vertical bars, newline and spaces.
Finding the Initiator's encryption key in the pluto.log file
juniper@server:~$ grep -n "enc key" /var/log/pluto.log 542:| enc key: 82 0f df 71 dc 10 7c 21 87 52 b4 b9 f6 37 47 0e juniper@server:~$ head -n 543 /var/log/pluto.log | tail -n 2 | sed s/^\|/""/ | sed s/" "/""/g | sed ':a;N;$!ba;s/\n//g' enckey:820fdf71dc107c218752b4b9f637470ed285def53864f409 juniper@server:~$
To plug these values into Wireshark, you need to have a fairly recent version (I used one pulled from the latest git repositories). Go to Edit->Preferences and open up the dialog box. Navigate to ISAKMP under Protocols in the Preferences dialog box.
Finding ISAKMP protocol under Preferences
Next, open up the "IKEv1 Decryption Table" and add a "New" entry. Plug in the values for the Initiator's Cookie, and the Encryption Key from the Initiator. In this case the Cookie is a305bbc510fd3640 and the encryption key is 820fdf71dc107c218752b4b9f637470ed285def53864f409.
Adding a new IKEv1 Decryption Table Entry
After this is applied, you should have an entry in the main IKEv1 Decryption Table.
Populated IKEv1 Decryption Table
After this is applied, the packets in the capture should be able to be decrypted. However, there seems to be a slight but in at least a couple of versions of the dissector where it shows one or more of the Quick Mode packets are corrupt. If this happens, close the capture file and reopen it. After that everything should be able to be displayed properly.
Decrypted Quick Mode Packet
The start of Phase 2,Quick Mode, begins immediately after the initiator receives the last packet of the Phase 1 exchange an authenticates the responder.
We can see the initiator begin processing quick mode from the pluto.log file with the message:
"srx-13" #2: initiating Quick Mode PSK+ENCRYPT+TUNNEL+UP {using isakmp#1}
.
In Quick Mode, except for the ISAKMP header, all of the payloads are encrypted with the parameters negotiated in Phase 1. We can see the initiator constructing the Quick Mode ISAKMP header with the following lines from the log file:
Initiator constructing ISAKMP header for Quick Mode
| **emit ISAKMP Message: | initiator cookie: | a3 05 bb c5 10 fd 36 40 | responder cookie: | d1 6d d2 ce 1e 03 90 ec | next payload type: ISAKMP_NEXT_HASH | ISAKMP version: ISAKMP Version 1.0 | exchange type: ISAKMP_XCHG_QUICK | flags: ISAKMP_FLAG_ENCRYPTION | message ID: 3e 8e f9 3e
Directly after the ISAKMP header, Quick Mode is required to send an authentication hash to authenticate the message and provide proof of liveliness. As seen above, following RFC 2409 Section 5.5, the next header called out is an authentication hash.
Initiator calculating authentication hash
| ***emit ISAKMP Hash Payload: | next payload type: ISAKMP_NEXT_SA | emitting 16 zero bytes of HASH into ISAKMP Hash Payload | emitting length of ISAKMP Hash Payload: 20
Next the initiator begins to assemble it's proposal for the traffic protection profile which consists of the procotol to use (AH or ESP) and a Security Parameter Index (SPI). The SPI is a unique value that helps the operating system discern between different traffic flows between a pair of hosts. The SPI may be the same as the values for the cookies that were used during Phase 1. To demonstrate the need for the SPI, if there were two different IPSEC flows between two peers, each using a different secret key, the SPI would allow each peer to determine which key to use on each packet. The SPI, together with the destination IP address and the protocol (AH or ESP) is what makes up a Security Association (SA). Two or more SPIs are seen quite a bit when keying material is getting ready to expire, and a new SA is established between the IPSEC peers in order to allow for a smooth cutover of traffic once the old SA expires.
A few other flags are set in the proposal, the ISAKMP Domain of Interpretation (DOI), and the IPSEC Situation Definition. The DOI specifies the context the following payloads are supposed to be evaluated under. There are currently three listed in the IANA IKE Attributes listing: ISAKMP, IPSEC and GDOI. Unless using a Group VPN, which is worth an entire writeup by itself, this is set IPSEC for Quick Mode. The IPSEC Situation Definition provide information that the responder can use in order how to process the incoming SA request. This is a masked field that indicates if it can support SAs identified by the identities negotiated in Phase 1, or if it can support integrity and secrecy labels for use in Multi-Level-Security (MLS) environments. This will normally just be set to a value of SIT_IDENITY_ONLY. Identity only must be supported by all IPSEC implementations, the others are optional.
Initiator setting the DOI and IPSEC Situation Definition
| ***emit ISAKMP Security Association Payload: | next payload type: ISAKMP_NEXT_VID | DOI: ISAKMP_DOI_IPSEC | ****emit IPsec DOI SIT: | IPsec DOI SIT: SIT_IDENTITY_ONLY
Next the initiator adds some sub payloads to the proposal payload that specified groupings of encryption and authentication parameters that the initiator will support. These are sets of the encryption alogrithm, authentication algorithm, key lifetimes and lifetime type, Diffie-Hellman-Merkel groups, and the encapsulation mode. The encapsulation mode is either tunnel or transport mode; additinally UDP can be used in either mode if NAT-T is in use and is specified here as well. There can be mutiple sets, or transforms in a proposal for the responder to select from.
Initiator constructing a transformation for the proposal
|| esp proposal: AES_CBC_128/HMAC_SHA1, | ****emit ISAKMP Proposal Payload: | next payload type: ISAKMP_NEXT_NONE | proposal number: 0 | protocol ID: PROTO_IPSEC_ESP | SPI size: 4 | number of transforms: 1 | getting SPI for reqid {16384} | got SPI c786011d for reqid {16384} | emitting 4 raw bytes of SPI into ISAKMP Proposal Payload | SPI c7 86 01 1d | *****emit ISAKMP Transform Payload (ESP): | next payload type: ISAKMP_NEXT_NONE | transform number: 0 | transform ID: AES_CBC | ******emit ISAKMP IPsec DOI attribute: | af+type: ENCAPSULATION_MODE | length/value: 1 | [1 is ENCAPSULATION_MODE_TUNNEL] | ******emit ISAKMP IPsec DOI attribute: | af+type: SA_LIFE_TYPE | length/value: 1 | [1 is SA_LIFE_TYPE_SECONDS] | ******emit ISAKMP IPsec DOI attribute: | af+type: SA_LIFE_DURATION | length/value: 3600 | ******emit ISAKMP IPsec DOI attribute: | af+type: AUTH_ALGORITHM | length/value: 2 | [2 is HMAC_SHA1] | ******emit ISAKMP IPsec DOI attribute: | af+type: KEY_LENGTH | length/value: 128 | emitting length of ISAKMP Transform Payload (ESP): 28 | emitting length of ISAKMP Proposal Payload: 40
Next the initiator picks a new nonce to guard against replay attacks for the protected traffic.
Initiator selects a nonce
| ***emit ISAKMP Nonce Payload: | next payload type: ISAKMP_NEXT_ID | emitting 16 raw bytes of Ni into ISAKMP Nonce Payload | Ni 5d 91 31 68 cd 6d ee d7 6e b1 ad 1a c8 db 45 5c | emitting length of ISAKMP Nonce Payload: 20
Next the initiator sends more identities. The identities are used to identify and direct traffic to the appropriate tunnel in cases where multiple tunnels exist between two peers, and to allow for unique and shared SAs with different parameters to coexist. These identities are also known as Proxy Identities, or Proxy IDs and are in the format of an IP address and a netmask. For lack of a better term, I will be referring to these as Proxy IDs from this point on. The Proxy IDs signify what traffic the IPSEC speaker will be encrypting - or acting as a proxy for other network clients. One Proxy ID is sent as the local traffic to be matched by the SA, and the other as the remote traffic that will be matched by the SA in the form of IP addresses and subnet masks. In this example, they are being set to 0.0.0.0/0 for both the local and remote, specified by the leftsubnet and rightsubnet directives in the ipsec.conf file for strongSwan, and are always 0.0.0.0/0 for an SRX device using a routed IPSEC VPN. The Proxy-IDs need to match for Quick Mode to continue.
| ***emit ISAKMP Identification Payload (IPsec DOI): | next payload type: ISAKMP_NEXT_ID | ID type: ID_IPV4_ADDR_SUBNET | Protocol ID: 0 | port: 0 | emitting 4 raw bytes of client network into ISAKMP Identification Payload (IPsec DOI) | client network 00 00 00 00 | emitting 4 raw bytes of client mask into ISAKMP Identification Payload (IPsec DOI) | client mask 00 00 00 00 | emitting length of ISAKMP Identification Payload (IPsec DOI): 16 | ***emit ISAKMP Identification Payload (IPsec DOI): | next payload type: ISAKMP_NEXT_NONE | ID type: ID_IPV4_ADDR_SUBNET | Protocol ID: 0 | port: 0 | emitting 4 raw bytes of client network into ISAKMP Identification Payload (IPsec DOI) | client network 00 00 00 00 | emitting 4 raw bytes of client mask into ISAKMP Identification Payload (IPsec DOI) | client mask 00 00 00 00 | emitting length of ISAKMP Identification Payload (IPsec DOI): 16
If Perfect-Forward-Secrecy (PFS) is in use in the exchange (which isn't in use here) there would be another Diffie-Hellman-Merkel key exchange payload.
Next, the payloads are packaged up and encrypted with the keying material setup during the Phase 1 negotiation.
Initiator enrcypts outgoing payloads.
HASH(1) computed: | 92 ee 26 eb 83 d2 4e 6b 78 d4 d5 c0 72 9a 13 a8 | last Phase 1 IV: 8d 5e 85 f3 38 26 5e 4d | computed Phase 2 IV: | 48 60 07 20 58 de 69 ca c4 a5 3f 5f 6e 7e 36 e6 | encrypting: | 01 00 00 14 92 ee 26 eb 83 d2 4e 6b 78 d4 d5 c0 | 72 9a 13 a8 0a 00 00 34 00 00 00 01 00 00 00 01 | 00 00 00 28 00 03 04 01 c7 86 01 1d 00 00 00 1c | 00 0c 00 00 80 04 00 01 80 01 00 01 80 02 0e 10 | 80 05 00 02 80 06 00 80 05 00 00 14 5d 91 31 68 | cd 6d ee d7 6e b1 ad 1a c8 db 45 5c 05 00 00 10 | 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 10 | 04 00 00 00 00 00 00 00 00 00 00 00 | emitting 4 zero bytes of encryption padding into ISAKMP Message | encrypting using 3DES_CBC
To summarize these actions with a Finite State Machine, we have the following actions being performed by the initiator.
Initiator Starts Quick Mode.
And the initiator sends out the first packet in the Quick Mode Exchange.
Initiator sends Quick Mode packet #1 to Responder
The responder begins Quick Mode upon the receipt of the first Phase 2 packet from the Initiator. The SRX looks up the cookies, and finds that it belongs to an existing SA.
Responder recieves first packet for Quick Mode
[Feb 14 20:52:10][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 [Feb 14 20:52:10][10.80.80.13 <-> 10.80.80.80] ikev2_packet_st_input_start: [8c2d000/0] Processing received [Feb 14 20:52:10][10.80.80.13 <-> 10.80.80.80] ike_sa_find: Start, SA = { a305bbc5 10fd3640 - d16dd2ce 1e0390ec } [Feb 14 20:52:10][10.80.80.13 <-> 10.80.80.80] ike_sa_find: Found SA = { a305bbc5 10fd3640 - d16dd2ce 1e0390ec } [Feb 14 20:52:10][10.80.80.13 <-> 10.80.80.80] Found IKEv1 SA
As it parses through the ISAKMP header, it discovers that this packet is to setup an SA for traffic protection in Quick Mode.
Responder starts Quick Mode processing
[Feb 14 20:52:10][10.80.80.13 <-> 10.80.80.80] ike_udp_callback_common: New quick mode negotiation message_id = 3e8ef93e initialized, using slot 0 [Feb 14 20:52:10][10.80.80.13 <-> 10.80.80.80] ike_init_qm_negotiation: Start, initiator = 0, message_id = 3e8ef93e [Feb 14 20:52:10][10.80.80.13 <-> 10.80.80.80] Taking reference to P1 SA 2719962 to ref count 2 [Feb 14 20:52:10][10.80.80.13 <-> 10.80.80.80] ikev2_fb_new_connection_phase_qm: Accepting new Quick-Mode negotiation: local=:500, remote=10.80.80.80:500 (neg 8c7a800) [Feb 14 20:52:10][10.80.80.13 <-> 10.80.80.80] ssh_set_thread_debug_info: ikev2_fb_new_connection_phase_qm: set thread debug info - local 10.80.80.13 remote 10.80.80.80 neg 0x8c7a800 neg->ike_sa 0x8c76400 ike_sa 0x0 [Feb 14 20:52:10][10.80.80.13 <-> 10.80.80.80] ssh_set_debug_gw_info: ssh_set_debug_gw_info: set gw debug info - local 10.80.80.13 remote 10.80.80.80
The responding SRX decrypts the packet, and parses through the contents finding five different payloads. Referencing RFC2408 section 3.1 we find that contained within is a Hash, SA, nonce, two Identifications (ID) and an empty payload (type 0).
Responder processes payloads.
[Feb 14 20:52:10][10.80.80.13 <-> 10.80.80.80] ike_decode_packet: Start [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_decode_packet: Start, SA = { a305bbc5 10fd3640 - d16dd2ce 1e0390ec} / 3e8ef93e, nego = 0 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_decode_packet: first_payload_type:8. [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_decode_packet: Decrypting packet [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_decode_packet: next_payload_type:1. [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_decode_packet: next_payload_type:10. [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_decode_packet: next_payload_type:5. [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_decode_packet: next_payload_type:5. [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_decode_packet: next_payload_type:0.
The SRX first parses the proposal. Inside the proposal, there is a single transformation contained within. Cross referencing IANA "Magic Numbers" for ISAKMP Protocol, IPSEC Security Association Attributes we find that the proposal uses tunnel mode encapsulation, units of seconds for the SA life type, a life time of 3600 seconds, HMAC-SHA2-256 for authentication and a key length of 128 bits. the proposal calls for ,
Responder parses proposals for SA
[Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_decode_payload_sa: Start [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_decode_payload_sa: Found 1 proposals [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_decode_payload_t: Start, # trans = 1 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ssh_ike_decode_data_attribute_size: decode_size B: type = 4 (0x0004), value = 1 (0x0001), size = 4 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ssh_ike_decode_data_attribute_size: decode_size B: type = 1 (0x0001), value = 1 (0x0001), size = 4 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ssh_ike_decode_data_attribute_size: decode_size B: type = 2 (0x0002), value = 3600 (0x0e10), size = 4 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ssh_ike_decode_data_attribute_size: decode_size B: type = 5 (0x0005), value = 2 (0x0002), size = 4 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ssh_ike_decode_data_attribute_size: decode_size B: type = 6 (0x0006), value = 128 (0x0080), size = 4 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ssh_ike_decode_data_attribute: decode B: type = 4 (0x0004), value = 1 (0x0001), len = 2, used_bytes = 4 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ssh_ike_decode_data_attribute: decode B: type = 1 (0x0001), value = 1 (0x0001), len = 2, used_bytes = 4 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ssh_ike_decode_data_attribute: decode B: type = 2 (0x0002), value = 3600 (0x0e10), len = 2, used_bytes = 4 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ssh_ike_decode_data_attribute: decode B: type = 5 (0x0005), value = 2 (0x0002), len = 2, used_bytes = 4 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ssh_ike_decode_data_attribute: decode B: type = 6 (0x0006), value = 128 (0x0080), len = 2, used_bytes = 4
The responding SRX continues processing by checking that the packet was properly decrypted, and checks the authentication hash.
Responder authenticates Initiator
[Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_st_i_encrypt: Check that packet was encrypted succeeded [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_state_step: Calling input function[1] = ike_st_i_qm_hash_1 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_st_i_qm_hash_1: Start, hash[0..16] = 92ee26eb 83d24e6b ...
The responder processes the initiators Phase 2 nonce, and looks for the Proxy IDs, a new Diffie-Hellman-Merkel public value if PFS is in use, and the proposals.
Responder processess initiator's nonce, new Diffie-Hellman-Merkel public value and proposals.
[Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_state_step: Calling input function[2] = ike_st_i_qm_nonce [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_st_i_qm_nonce: Nonce[0..16] = 5d913168 cd6deed7 ... [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_state_step: Calling input function[3] = ike_st_i_qm_ids [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_state_step: Calling input function[4] = ike_st_i_qm_ke [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_state_step: Calling input function[5] = ike_st_i_qm_sa_proposals [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_st_i_qm_sa_proposals: Start
The responder than allocates a new SPI for inbound traffic, 5ef52687.
Responder allocates new inbound SPI
[Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ikev2_fb_ipsec_spi_allocate_cb: New IPSec SPI 5ef52687 allocated successfully (neg 8c7a800) [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ikev2_fb_st_select_qm_sa_alloc_spi: FB; Calling v2 policy function ipsec_spi_allocate [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] iked_pm_ipsec_spi_allocate: local:10.80.80.13, remote:10.80.80.80 IKEv1 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] Allocated SPI [9af45c68]. proto 0 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] Added (spi=0x685cf49a, protocol=0) entry to the spi table [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] Parsing notification payload for local:10.80.80.13, remote:10.80.80.80 IKEv1 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ikev2_fb_ipsec_spi_allocate_cb: New IPSec SPI 685cf49a allocated successfully (neg 8c7a800)
In processing the new SA, the SRX parses through the Proxy IDs, and compares the ones received from the peer to it's own along with the IPSEC endpoints in order to find a matching configuration session. Junos 12.1X46 uses the IKEv2 library to do everything, and translates most IKEv1 parameters into the IKEv2 equivalents for processing with the same library routines. The traffic selector is IKEv2 for "Proxy ID". This is where it becomes apparent why the Proxy-IDs have to match in Junos, they are part of the parameters used to match the SA being setup to the appropriate configuration section and thus ensure that the traffic that matches the SA is processed properly. Here we see that the SRX sucessfully matches the ongoing negotiations in this sequence to the "SERVER-BOX" configuration section.
Reponder uses Proxy-IDs to match configuration for peer
[Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] Peer's proposed traffic selectors is his local: ipv4(0.0.0.0-255.255.255.255) his remote: ipv4(0.0.0.0-255.255.255.255) [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] Configured traffic selectors is local: ipv4(0.0.0.0-255.255.255.255) Remote: ipv4(0.0.0.0-255.255.255.255) [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] Found SA-CFG SERVER-BOX by ip address for local:10.80.80.13, remote:10.80.80.80 IKEv1 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] Found SA-CFG SERVER-BOX for phase 2 for local:10.80.80.13, remote:10.80.80.80 IKEv1
Having found the configuration it should be using, the responding SRX checks it's own configured proposals and transforms to make sure that the two agree on the parameters. The SRX comes to the conclusion that the proposals match.
Reponder compares proposals
[Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ssh_ikev2_sav1_select: Comparing 1 input proposals against 1 policy proposals [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ssh_ikev2_sav1_select: Comparing input proposal #0 against policy proposal #1 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ikev2_choose_v1_proposal: Comparing 1 protocol(s) [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ikev2_choose_v1_proposal: Comparing transforms of protocol 3 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ikev2_choose_v1_transform: Comparing 1 input transforms against 1 policy transforms [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ikev2_choose_v1_transform: Comparing input transform #0 against policy transform #0 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ikev2_choose_v1_transform: Transform id 12 matches, comparing attributes [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ikev2_ikev1_attribute_check: Comparing 5 input attributes against 5 policy attributes [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ikev2_ikev1_attribute_check: Comparing input attribute 0 against policy attribute 0 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ikev2_ikev1_attribute_check: Comparing input attribute 0 against policy attribute 1 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ikev2_ikev1_attribute_check: Comparing input attribute 0 against policy attribute 2 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ikev2_ikev1_attribute_check: Comparing input attribute 0 against policy attribute 3 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ikev2_ikev1_attribute_check: Comparing input attribute 0 against policy attribute 4 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ikev2_ikev1_attribute_check: Input attribute 1 is life type/duration, ignoring [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ikev2_ikev1_attribute_check: Input attribute 2 is life type/duration, ignoring [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ikev2_ikev1_attribute_check: Comparing input attribute 3 against policy attribute 0 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ikev2_ikev1_attribute_check: Comparing input attribute 3 against policy attribute 1 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ikev2_ikev1_attribute_check: Input and policy attributes of type 5 match [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ikev2_ikev1_attribute_check: Comparing input attribute 4 against policy attribute 0 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ikev2_ikev1_attribute_check: Input and policy attributes of type 6 match [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ikev2_ikev1_attribute_check: Attributes matched successfully [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ikev2_ikev1_attribute_check: Setting life in seconds to 1200 from policy [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ikev2_choose_v1_transform: Attributes match; selected input transform 0 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ikev2_choose_v1_proposal: Protocols match [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ikev2_choose_v1_proposal: Selected proposal number 0 and transforms for 1 protocols [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ikev2_choose_v1_proposal: Selected transform id 12 for protocol 3 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ssh_ikev2_sav1_select: Proposals match
The responding SRX begins to formulate a reply to the initiator. First it computes it's own authentication hash to verify the packet.
Responder creates authentication hash
[Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_st_o_qm_hash_2: Start
Then it assembles information for the SA payload. It is going to echo back the SA and selected transformation to the initiator. If there is only one transformation that was listed, it is still echoed back as confirmation that the two are in agreement.
Responder prepares SA payload.
[Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_st_o_qm_sa_values: Start [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ssh_ike_get_data_attribute_int: get_int: type = 4 (0x0004), value = 1 (0x00000001), len = 2 (0x0002) [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ssh_ike_get_data_attribute_int: get_int: type = 1 (0x0001), value = 1 (0x00000001), len = 2 (0x0002) [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ssh_ike_get_data_attribute_int: get_int: type = 2 (0x0002), value = 3600 (0x00000e10), len = 2 (0x0002) [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ssh_ike_get_data_attribute_int: get_int: type = 5 (0x0005), value = 2 (0x00000002), len = 2 (0x0002) [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ssh_ike_get_data_attribute_int: get_int: type = 6 (0x0006), value = 128 (0x00000080), len = 2 (0x0002)
The responding SRX creates it's own Phase 2 nonce.
Responder creates a nonce for protected traffic
[Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_st_o_qm_nonce: Start [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ikev2_fb_qm_nonce_data_len: Entered [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_policy_reply_qm_nonce_data_len: Start
It checks to see if PFS in in use, and if so send a new Diffie-Hellman-Merkel public value. In this case PFS is not in use, so another KE payload isn't added.
Responder calculates new Diffie-Hellman-Merkel public value (if needed for PFS)
[Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_st_o_qm_optional_ke: Start
The responding SRX adds in the local and remote Proxy IDs.
Responder adds Proxy-IDs
[Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_st_o_qm_optional_ids: Start [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ikev2_fb_qm_local_id: Using ipv4_subnet(any:0,[0..7]=0.0.0.0/0) as local QM identity [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_policy_reply_qm_local_id: Start [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ikev2_fb_qm_remote_id: Using ipv4_subnet(any:0,[0..7]=0.0.0.0/0) as remote QM identity
Since the SRX is configured to use a routed IPSEC tunnel, it checks to see if the peer is another Juniper device that supports automatically creating next-hop tunnel binding entries for multipoint tunnels (NHTB). Since the peer isn't, it skips this step. Note that this will be sent over as a private payload and is vendor specific; not a required step in Quick Mode.
Responding SRX checks to see if it needs to send some private payloads
[Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] Construction NHTB payload for local:10.80.80.13, remote:10.80.80.80 IKEv1 P1 SA index 2719962 sa-cfg SERVER-BOX [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] Peer router vendor is not Juniper. Not sending NHTB payload for sa-cfg SERVER-BOX, p1_sa=2719962
Next the SRX assembles the payloads and encrypts them with the keying material that was setup from Phase 1.
Reponder prepares outgoing packet
[Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_encode_packet: Start, SA = { 0xa305bbc5 10fd3640 - d16dd2ce 1e0390ec } / 3e8ef93e, nego = 0 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_encode_packet: Payload length = 20 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ssh_ike_encode_data_attribute: encode B: type = 4 (0x0004), len = 2, value = 0001 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ssh_ike_encode_data_attribute: encode B: type = 1 (0x0001), len = 2, value = 0001 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ssh_ike_encode_data_attribute: encode B: type = 2 (0x0002), len = 2, value = 0e10 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ssh_ike_encode_data_attribute: encode B: type = 5 (0x0005), len = 2, value = 0002 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ssh_ike_encode_data_attribute: encode B: type = 6 (0x0006), len = 2, value = 0080 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_encode_packet: Payload length = 52 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_encode_packet: Payload length = 20 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_encode_packet: Payload length = 16 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_encode_packet: Payload length = 16 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_encode_packet: Payload length = 28 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_encode_packet: Packet length = 180 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_encode_packet: Calling finalizing function for payload[0].type = 8 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_encode_packet: Encrypting packet [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_encode_packet: Final length = 180
To summarize the actions at this step in a FSM:
Responder's first action in quick mode.
And finally the responder sends Packet #2 in the quick mode exchange back to the initiator.
Responder sends first reply for Quick Mode
[Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_send_packet: Start, send SA = { a305bbc5 10fd3640 - d16dd2ce 1e0390ec}, nego = 0, dst = 10.80.80.80:500, routing table id = 0
Packet #2: Quick mode packet sent to initiator.
Once the initiator receives the responders first Quick Mode reply it really starts to work.
Initiator receives first Quick Mode reply
| *received 180 bytes from 10.80.80.13:500 on eth1
The initiator parses the ISAKMP header to match it up with an existing SA and finds an entry that is in progress.
Initiator parses ISAKMP header
| **parse ISAKMP Message: | initiator cookie: | a3 05 bb c5 10 fd 36 40 | responder cookie: | d1 6d d2 ce 1e 03 90 ec | next payload type: ISAKMP_NEXT_HASH | ISAKMP version: ISAKMP Version 1.0 | exchange type: ISAKMP_XCHG_QUICK | flags: ISAKMP_FLAG_ENCRYPTION | message ID: 3e 8e f9 3e | length: 180 | ICOOKIE: a3 05 bb c5 10 fd 36 40 | RCOOKIE: d1 6d d2 ce 1e 03 90 ec | peer: 0a 50 50 0d | state hash entry 3 | state object #2 found, in STATE_QUICK_I1
It decrypts the contents of the packet.
Initiator decrypts packet.
| received encrypted packet from 10.80.80.13:500 | decrypting 152 bytes using algorithm 3DES_CBC | decrypted:
It parses the received payloads once they are decrypted.
Initiator parses decrypted payloads
| ***parse ISAKMP Hash Payload: | next payload type: ISAKMP_NEXT_SA | length: 20 | ***parse ISAKMP Security Association Payload: | next payload type: ISAKMP_NEXT_NONCE | length: 52 | DOI: ISAKMP_DOI_IPSEC | ***parse ISAKMP Nonce Payload: | next payload type: ISAKMP_NEXT_ID | length: 20 | ***parse ISAKMP Identification Payload (IPsec DOI): | next payload type: ISAKMP_NEXT_ID | length: 16 | ID type: ID_IPV4_ADDR_SUBNET | Protocol ID: 0 | port: 0 | ***parse ISAKMP Identification Payload (IPsec DOI): | next payload type: ISAKMP_NEXT_N | length: 16 | ID type: ID_IPV4_ADDR_SUBNET | Protocol ID: 0 | port: 0 | ***parse ISAKMP Notification Payload: | next payload type: ISAKMP_NEXT_NONE | length: 28 | DOI: ISAKMP_DOI_IPSEC | protocol ID: 3 | SPI size: 4 | Notify Message Type: IPSEC_RESPONDER_LIFETIME "srx-13" #2: ignoring informational payload, type IPSEC_RESPONDER_LIFETIME
It checks the authentication hash to make sure the message is isn't a clever forgery.
Initiator checks responders hash payload
| HASH(2) computed: | 64 90 7f 85 a0 ca ef a7 74 d1 15 36 ec 5c 7c fc
Since our packet is indeed authentic, the initiator can if the proposal, and which transform was selected to be used. This includes matching up the Proxy IDs sent by the responder.
Initiator parses the accepted proposal and transform.
****parse ISAKMP Proposal Payload: | next payload type: ISAKMP_NEXT_NONE | length: 40 | proposal number: 0 | protocol ID: PROTO_IPSEC_ESP | SPI size: 4 | number of transforms: 1 | parsing 4 raw bytes of ISAKMP Proposal Payload into SPI | SPI 5e f5 26 87 | *****parse ISAKMP Transform Payload (ESP): | next payload type: ISAKMP_NEXT_NONE | length: 28 | transform number: 0 | transform ID: AES_CBC | ******parse ISAKMP IPsec DOI attribute: | af+type: ENCAPSULATION_MODE | length/value: 1 | [1 is ENCAPSULATION_MODE_TUNNEL] | ******parse ISAKMP IPsec DOI attribute: | af+type: SA_LIFE_TYPE | length/value: 1 | [1 is SA_LIFE_TYPE_SECONDS] | ******parse ISAKMP IPsec DOI attribute: | af+type: SA_LIFE_DURATION | length/value: 3600 | ******parse ISAKMP IPsec DOI attribute: | af+type: AUTH_ALGORITHM | length/value: 2 | [2 is HMAC_SHA1] | ******parse ISAKMP IPsec DOI attribute: | af+type: KEY_LENGTH | length/value: 128 | kernel_alg_esp_enc_ok(12,128): alg_id=12, alg_ivlen=8, alg_minbits=128, alg_maxbits=256, res=0, ret=1 | our client is subnet 0.0.0.0/0 | our client protocol/port is 0/0 | peer client is subnet 0.0.0.0/0 | peer client protocol/port is 0/0
Now that the encryption, authentication, modes and lifetimes have all been agreed upon, the initiator will send back a ISAKMP reply back to the responder with a single hash payload as a feedback mechanism. This lets the responder know that the initiator has is in agreement and has installed the appropriate SAs for traffic protection. The hash is computed, to be inserted as the reply.
Initiator constructs a new hash
| ***emit ISAKMP Hash Payload: | next payload type: ISAKMP_NEXT_NONE | emitting 16 zero bytes of HASH into ISAKMP Hash Payload | emitting length of ISAKMP Hash Payload: 20 | HASH(3) computed: 04 82 0a 74 03 e8 17 74 b5 4d 1f f4 ec ed c9 6d
Now that the initiator knows which parameters have been agreed on, it can compute the secret keying material for both inbound and outbound traffic.
Initator computes secret keys for Phase 2
| kernel_alg_esp_enc_keylen(): alg_id=12, keylen=16 | kernel_alg_esp_auth_keylen(auth=2, sadb_aalg=3): a_keylen=20 | KEYMAT computed: | f4 4d 2a 05 83 7d 88 dc c8 01 be 84 d8 83 15 c8 | 1e 55 b1 eb c7 e3 75 27 0f d1 ad 71 68 19 55 c6 | 79 e0 b6 c7 | Peer KEYMAT computed: | e5 80 80 0e 5c 19 81 01 83 e6 a8 1b 85 af 45 0a | 21 4b bf 81 68 5b 7f de 1d 46 03 e4 30 55 97 3e | c3 e0 1f e5
With the keying material inhand, now entries can be inserted into the Security Association Database (SAD). On Linux, the traffic protection mechanisms for IPSEC have been integrated in the kernel. The SAD is a kernel database that lists all of the established SAs. An SA is created for both the outbound traffic that will be encrypted, and the inbound traffic that will be decrypted.
Initiator activates inbound SA
| install_ipsec_sa() for #2: inbound and outbound | route owner of "srx-13" unrouted: NULL; eroute owner: NULL | kernel_alg_esp_info():transid=12, auth=2, ei=0x7f76e6a2b5e0, enckeylen=32, authkeylen=20, encryptalg=12, authalg=3 | adding SAD entry with SPI c786011d and reqid {16384} | using encryption algorithm AES_CBC with key size 128 | using integrity algorithm HMAC_SHA1_96 with key size 160
Initiator activates outbound SA
| kernel_alg_esp_info():transid=12, auth=2, ei=0x7f76e6a2b5e0, enckeylen=32, authkeylen=20, encryptalg=12, authalg=3 | adding SAD entry with SPI 5ef52687 and reqid {16384} | using encryption algorithm AES_CBC with key size 128 | using integrity algorithm HMAC_SHA1_96 with key size 160
The Linux box updates all of it's routing tables to reflect the SAs that have just been installed.
Initiator updates local routing tables
| sr for #2: unrouted | route owner of "srx-13" unrouted: NULL; eroute owner: NULL | route_and_eroute with c: srx-13 (next: none) ero:null esr:{(nil)} ro:null rosr:{(nil)} and state: 2 | eroute_connection add eroute 0.0.0.0/0:0 -> 0.0.0.0/0:0 => tun.0@10.80.80.80:0 | adding policy 0.0.0.0/0 === 0.0.0.0/0 in | eroute_connection add eroute 0.0.0.0/0:0 -> 0.0.0.0/0:0 => tun.0@10.80.80.13:0 | adding policy 0.0.0.0/0 === 0.0.0.0/0 out
The Initiator finally declares itself finished with quick mode as it updates it's Security Policy Database (SPD).
Initiator declares Phase 2 SA's completed
| executing up-client: 2>&1 PLUTO_VERSION='1.1' PLUTO_VERB='up-client' PLUTO_CONNECTION='srx-13' PLUTO_NEXT_HOP='10.80.80.13' PLUTO_INTERFACE='eth1' PLUTO_REQID='16384' PLUTO_ME='10.80.80.80' PLUTO_MY_ID='10.80.80.80' PLUTO_MY_CLIENT='0.0.0.0/0' PLUTO_MY_CLIENT_NET='0.0.0.0' PLUTO_MY_CLIENT_MASK='0.0.0.0' PLUTO_MY_PORT='0' PLUTO_MY_PROTOCOL='0' PLUTO_PEER='10.80.80.13' PLUTO_PEER_ID='10.80.80.13' PLUTO_PEER_CLIENT='0.0.0.0/0' PLUTO_PEER_CLIENT_NET='0.0.0.0' PLUTO_PEER_CLIENT_MASK='0.0.0.0' PLUTO_PEER_PORT='0' PLUTO_PEER_PROTOCOL='0' PLUTO_PEER_CA='' ipsec _updown | route_and_eroute: firewall_notified: true | executing prepare-client: 2>&1 PLUTO_VERSION='1.1' PLUTO_VERB='prepare-client' PLUTO_CONNECTION='srx-13' PLUTO_NEXT_HOP='10.80.80.13' PLUTO_INTERFACE='eth1' PLUTO_REQID='16384' PLUTO_ME='10.80.80.80' PLUTO_MY_ID='10.80.80.80' PLUTO_MY_CLIENT='0.0.0.0/0' PLUTO_MY_CLIENT_NET='0.0.0.0' PLUTO_MY_CLIENT_MASK='0.0.0.0' PLUTO_MY_PORT='0' PLUTO_MY_PROTOCOL='0' PLUTO_PEER='10.80.80.13' PLUTO_PEER_ID='10.80.80.13' PLUTO_PEER_CLIENT='0.0.0.0/0' PLUTO_PEER_CLIENT_NET='0.0.0.0' PLUTO_PEER_CLIENT_MASK='0.0.0.0' PLUTO_PEER_PORT='0' PLUTO_PEER_PROTOCOL='0' PLUTO_PEER_CA='' ipsec _updown | executing route-client: 2>&1 PLUTO_VERSION='1.1' PLUTO_VERB='route-client' PLUTO_CONNECTION='srx-13' PLUTO_NEXT_HOP='10.80.80.13' PLUTO_INTERFACE='eth1' PLUTO_REQID='16384' PLUTO_ME='10.80.80.80' PLUTO_MY_ID='10.80.80.80' PLUTO_MY_CLIENT='0.0.0.0/0' PLUTO_MY_CLIENT_NET='0.0.0.0' PLUTO_MY_CLIENT_MASK='0.0.0.0' PLUTO_MY_PORT='0' PLUTO_MY_PROTOCOL='0' PLUTO_PEER='10.80.80.13' PLUTO_PEER_ID='10.80.80.13' PLUTO_PEER_CLIENT='0.0.0.0/0' PLUTO_PEER_CLIENT_NET='0.0.0.0' PLUTO_PEER_CLIENT_MASK='0.0.0.0' PLUTO_PEER_PORT='0' PLUTO_PEER_PROTOCOL='0' PLUTO_PEER_CA='' ipsec _updown | route_and_eroute: instance "srx-13", setting eroute_owner {spd=0x7f76e78e0b78,sr=0x7f76e78e0b78} to #2 (was #0) (newest_ipsec_sa=#0)
To close the feedback loop with the responder, the initiator enrypts it's the final ISAKMP packet in the Quick Mode exchange with the keying material negotiated during Phase 1.
| encrypting: | 00 00 00 14 04 82 0a 74 03 e8 17 74 b5 4d 1f f4 | ec ed c9 6d | emitting 4 zero bytes of encryption padding into ISAKMP Message | encrypting using 3DES_CBC | next IV: 20 5e c9 03 73 3d 3f 36 | emitting length of ISAKMP Message: 52
The Quick Mode Finite state machine summarized the initiators actions at this point.
Initiator blah .
And finally, the responder sends the last packet of the Quick Mode portion of the exchange.
Initiator sends authentication hash back to responder.
| sending 52 bytes for STATE_QUICK_I1 through eth1 to 10.80.80.13:500:
Quick Mode Packet #3: ISAKMP packet sent to responder.
The responder, SRX-13, receives the last Quick Mode packet. After it receives the packet, it parses the header and matches it up with the ongoing Phase 2 SA that is being setup.
Responder recieves last Quick Mode packet
[Feb 14 20:52:11][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 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ikev2_packet_st_input_start: [8c2d400/0] Processing received [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_sa_find: Start, SA = { a305bbc5 10fd3640 - d16dd2ce 1e0390ec } [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_sa_find: Found SA = { a305bbc5 10fd3640 - d16dd2ce 1e0390ec } [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] Found IKEv1 SA [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ikev2_packet_st_input_v1_get_sa: [8c2d400/deadbeee] Packet to existing v1 SA [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ikev2_packet_v1_start: Passing IKE v1.0 packet to IKEv1 library [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_udp_callback_common: Packet from 10.80.80.80:500, use_natt=0 data[0..52] = a305bbc5 10fd3640 d16dd2ce 1e0390ec ... [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_get_sa: Start, SA = { a305bbc5 10fd3640 - d16dd2ce 1e0390ec } / 3e8ef93e, remote = 10.80.80.80:500 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_sa_find: Start, SA = { a305bbc5 10fd3640 - d16dd2ce 1e0390ec } [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_sa_find: Found SA = { a305bbc5 10fd3640 - d16dd2ce 1e0390ec } [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_udp_callback_common: Finding negotiation for 3e8ef93e, [0].message-id = 3e8ef93e [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_udp_callback_common: Old negotiation message_id = 3e8ef93e, slot 0
It decrypts the packet and parses the payloads, a hash and a null payload.
Responder finds lone authentication hash payload
[Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_decode_packet: Start [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_decode_packet: Start, SA = { a305bbc5 10fd3640 - d16dd2ce 1e0390ec} / 3e8ef93e, nego = 0 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_decode_packet: first_payload_type:8. [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_decode_packet: Decrypting packet [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_decode_packet: next_payload_type:0.
The responder checks the packet and the authentication hash to make sure their valid.
[Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_state_step: Calling input function[0] = ike_st_i_encrypt [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_st_i_encrypt: Check that packet was encrypted succeeded [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_state_step: Calling input function[1] = ike_st_i_qm_hash_3 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_st_i_qm_hash_3: Start, hash[0..16] = 04820a74 03e81774 ...
Since the authentication hash has succeeded, the responder internally declares that Phase 2 has succeeded!
The responder declares Quick Mode negotiations a success!
[Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80]:500 (Responder) <-> 10.80.80.80:500 { a305bbc5 10fd3640 - d16dd2ce 1e0390ec [0] / 0x3e8ef93e } QM; MESSAGE: Phase 2 connection succeeded, No PFS, group = 0 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_qm_call_callback: MESSAGE: Phase 2 connection succeeded, No PFS, group = 0 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] :500 (Responder) <-> 10.80.80.80:500 { a305bbc5 10fd3640 - d16dd2ce 1e0390ec [0] / 0x3e8ef93e } QM; MESSAGE: SA[0][0] = ESP aes, life = 0 kB/3600 sec, group = 0, tunnel, hmac-sha1-96, Ex [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ike_qm_call_callback: MESSAGE: SA[0][0] = ESP aes, life = 0 kB/3600 sec, group = 0, tunnel, hmac-sha1-96, Extended seq not used, key len = 128, key rounds = 0 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ikev2_fb_sa_handler: SA handler entered, IKE SA 8c76400 (neg 8c7a800) [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ikev2_fb_sa_handler: Outbound SPI c786011d
However, despite all of the celebrations about the end of Quick Mode packet passing, the responder still needs to generate the secret keys for Phase 2 and complete the SAs for Phase 2.
Reponder generates inbound and outbound secret keys
[Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ikev2_fb_fill_keymat: Generate keys for inbound ESP transform, SPI 5ef52687, key length 36 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ikev2_fb_fill_keymat: Inbound ESP key: [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] 00000000: e580 800e 5c19 8101 83e6 a81b 85af 450a ....\.........E. [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] 00000010: 214b bf81 685b 7fde 1d46 03e4 3055 973e !K..h[...F..0U.> [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] 00000020: c3e0 1fe5 .... [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ikev2_fb_fill_keymat: Generate keys for outbound ESP transform, SPI c786011d, key length 36 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ikev2_fb_fill_keymat: Outbound ESP key: [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] 00000000: f44d 2a05 837d 88dc c801 be84 d883 15c8 .M*..}.......... [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] 00000010: 1e55 b1eb c7e3 7527 0fd1 ad71 6819 55c6 .U....u'...qh.U. [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] 00000020: 79e0 b6c7 y... [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ikev2_fb_fill_keymat: Keymat, length 72 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] 00000000: e580 800e 5c19 8101 83e6 a81b 85af 450a ....\.........E. [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] 00000010: 214b bf81 685b 7fde 1d46 03e4 3055 973e !K..h[...F..0U.> [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] 00000020: c3e0 1fe5 f44d 2a05 837d 88dc c801 be84 .....M*..}...... [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] 00000030: d883 15c8 1e55 b1eb c7e3 7527 0fd1 ad71 .....U....u'...q [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] 00000040: 6819 55c6 79e0 b6c7 h.U.y...
Next the responder installs the SAs for inbound and outbound traffic.
Responder updates Phase 2 SAs (SAD)
[Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] Creating a SA spi=0x5ef52687, proto=ESP pair_index = 1 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] Added (spi=0x5ef52687, protocol=ESP dst=10.80.80.13) entry to the peer hash table [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] Creating a SA spi=0xc786011d, proto=ESP pair_index = 1 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] Added (spi=0xc786011d, protocol=ESP dst=10.80.80.80) entry to the peer hash table
And finally the SRX logs a large message summarizing the state of the Phase 1 and Phase 2 SAs, and logs a celebratory complettion message.
[Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ----------------Voyager ipsec SA BUNDLE------------------- [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] SA pair update request for: Tunnel index: 131073 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] Local Gateway address: 10.80.80.13 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] Primary remote Gateway address: 10.80.80.80 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] Backup remote Gateway State: Active [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] Anti replay: counter-based enabled [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] Window_size: 64 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] Server Time: 0 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] Peer : Static [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] Mode : Tunnel [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] VPN Type : route-based [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] Tunnel mtu: 0 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] DF bit: 0 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] local-if ifl idx: 1224736768 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] tunnel-if ifl idx: 1157627904 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] Tunnel mtu: 0 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] DPD interval: 0 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] policy id: 0 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] NATT enabled: 0 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] NATT version: 0 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] NAT position: 0 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] SA Idle time: 0 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] SA Outbound install delay time: 1 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] IKED ID: 0 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] DIST ID: 0 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] Keepalive interval: 0 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] VPN monitoring interval: 0 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] VPN monitoring optimized: 0 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] Respond-bad-SPI: 0 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] seq_out: 0 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] Local port: 0 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] Remote port: 500 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] SA CFG name: SERVER-BOX [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] Dial-up IKE ID: [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] RG ID: 0 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] Group template tunnel ID: 0 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ----------------Incoming SA ------------------- [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] SPI: 0x5ef52687 Protocol: 2 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] Algorithm: 130 Auth key. length: 20 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] Encr key. length; 16 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] ----------------Outgoing SA ------------------- [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] SPI: 0xc786011d Protocol: 2 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] Algorithm: 130 Auth key. length: 20 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] Encr key. length; 16 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] In iked_ipsec_sa_pair_add Adding GENCFG msg with key; Tunnel = 131073;SPI-In = 0x5ef52687 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] Added dependency on SA config blob with tunnelid = 131073 [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] Successfully added ipsec SA PAIR [Feb 14 20:52:11][10.80.80.13 <-> 10.80.80.80] IPSec negotiation done successfully for SA-CFG SERVER-BOX for local:10.80.80.13, remote:10.80.80.80 IKEv1
The Quick Mode Finite State Machine shows the final actions that the responder takes to bring up the SAs.
The responder's final actions..
Quick mode is a success, and traffic can now be protected with the parameters negotiated in Phase 2. Quick mode will occur again when the key lifetimes expire and new SAs need to be brought up with fresh keys.