blob: f0fd20553794a6bb4dd1c97009bf23da3ec6d6e1 [file] [log] [blame]
Filip Tehlar12b517b2020-04-26 18:05:05 +00001import os
Filip Tehlar2008e312020-11-09 13:23:24 +00002import time
Filip Tehlarec112e52020-10-07 23:52:37 +00003from socket import inet_pton
Filip Tehlarbfeae8c2020-06-23 20:35:58 +00004from cryptography import x509
Filip Tehlar12b517b2020-04-26 18:05:05 +00005from cryptography.hazmat.backends import default_backend
6from cryptography.hazmat.primitives import hashes, hmac
Filip Tehlarbfeae8c2020-06-23 20:35:58 +00007from cryptography.hazmat.primitives.asymmetric import dh, padding
8from cryptography.hazmat.primitives.serialization import load_pem_private_key
Filip Tehlar12b517b2020-04-26 18:05:05 +00009from cryptography.hazmat.primitives.ciphers import (
10 Cipher,
11 algorithms,
12 modes,
13)
Filip Tehlar84962d12020-09-08 06:08:05 +000014from ipaddress import IPv4Address, IPv6Address, ip_address
Paul Vinciguerrae061dad2020-12-04 14:57:51 -050015import unittest
Klement Sekerab23ffd72021-05-31 16:08:53 +020016from config import config
Filip Tehlarbfeae8c2020-06-23 20:35:58 +000017from scapy.layers.ipsec import ESP
Filip Tehlar12b517b2020-04-26 18:05:05 +000018from scapy.layers.inet import IP, UDP, Ether
Filip Tehlar84962d12020-09-08 06:08:05 +000019from scapy.layers.inet6 import IPv6
Filip Tehlar12b517b2020-04-26 18:05:05 +000020from scapy.packet import raw, Raw
21from scapy.utils import long_converter
Dave Wallace670724c2022-09-20 21:52:18 -040022from framework import tag_fixme_vpp_workers, tag_fixme_ubuntu2204, tag_fixme_debian11
23from framework import is_distro_ubuntu2204, is_distro_debian11
Filip Tehlar12b517b2020-04-26 18:05:05 +000024from framework import VppTestCase, VppTestRunner
Filip Tehlarbfeae8c2020-06-23 20:35:58 +000025from vpp_ikev2 import Profile, IDType, AuthMethod
Filip Tehlar4f42a712020-07-01 08:56:59 +000026from vpp_papi import VppEnum
Filip Tehlar12b517b2020-04-26 18:05:05 +000027
Filip Tehlar84962d12020-09-08 06:08:05 +000028try:
29 text_type = unicode
30except NameError:
31 text_type = str
Filip Tehlar12b517b2020-04-26 18:05:05 +000032
33KEY_PAD = b"Key Pad for IKEv2"
Filip Tehlara7b963d2020-07-08 13:25:34 +000034SALT_SIZE = 4
35GCM_ICV_SIZE = 16
36GCM_IV_SIZE = 8
Filip Tehlar12b517b2020-04-26 18:05:05 +000037
38
39# defined in rfc3526
40# tuple structure is (p, g, key_len)
41DH = {
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020042 "2048MODPgr": (
43 long_converter(
44 """
Filip Tehlar12b517b2020-04-26 18:05:05 +000045 FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1
46 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD
47 EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245
48 E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED
49 EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D
50 C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F
51 83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D
52 670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B
53 E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9
54 DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020055 15728E5A 8AACAA68 FFFFFFFF FFFFFFFF"""
56 ),
57 2,
58 256,
59 ),
60 "3072MODPgr": (
61 long_converter(
62 """
Filip Tehlar4f42a712020-07-01 08:56:59 +000063 FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1
64 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD
65 EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245
66 E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED
67 EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D
68 C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F
69 83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D
70 670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B
71 E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9
72 DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510
73 15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64
74 ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7
75 ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B
76 F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C
77 BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020078 43DB5BFC E0FD108E 4B82D120 A93AD2CA FFFFFFFF FFFFFFFF"""
79 ),
80 2,
81 384,
82 ),
Filip Tehlar12b517b2020-04-26 18:05:05 +000083}
84
85
86class CryptoAlgo(object):
87 def __init__(self, name, cipher, mode):
88 self.name = name
89 self.cipher = cipher
90 self.mode = mode
91 if self.cipher is not None:
92 self.bs = self.cipher.block_size // 8
93
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020094 if self.name == "AES-GCM-16ICV":
Filip Tehlara7b963d2020-07-08 13:25:34 +000095 self.iv_len = GCM_IV_SIZE
96 else:
97 self.iv_len = self.bs
Filip Tehlar12b517b2020-04-26 18:05:05 +000098
Filip Tehlara7b963d2020-07-08 13:25:34 +000099 def encrypt(self, data, key, aad=None):
100 iv = os.urandom(self.iv_len)
101 if aad is None:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200102 encryptor = Cipher(
103 self.cipher(key), self.mode(iv), default_backend()
104 ).encryptor()
Filip Tehlara7b963d2020-07-08 13:25:34 +0000105 return iv + encryptor.update(data) + encryptor.finalize()
106 else:
107 salt = key[-SALT_SIZE:]
108 nonce = salt + iv
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200109 encryptor = Cipher(
110 self.cipher(key[:-SALT_SIZE]), self.mode(nonce), default_backend()
111 ).encryptor()
Filip Tehlara7b963d2020-07-08 13:25:34 +0000112 encryptor.authenticate_additional_data(aad)
113 data = encryptor.update(data) + encryptor.finalize()
114 data += encryptor.tag[:GCM_ICV_SIZE]
115 return iv + data
116
117 def decrypt(self, data, key, aad=None, icv=None):
118 if aad is None:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200119 iv = data[: self.iv_len]
120 ct = data[self.iv_len :]
121 decryptor = Cipher(
122 algorithms.AES(key), self.mode(iv), default_backend()
123 ).decryptor()
Filip Tehlara7b963d2020-07-08 13:25:34 +0000124 return decryptor.update(ct) + decryptor.finalize()
125 else:
126 salt = key[-SALT_SIZE:]
127 nonce = salt + data[:GCM_IV_SIZE]
128 ct = data[GCM_IV_SIZE:]
129 key = key[:-SALT_SIZE]
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200130 decryptor = Cipher(
131 algorithms.AES(key), self.mode(nonce, icv, len(icv)), default_backend()
132 ).decryptor()
Filip Tehlara7b963d2020-07-08 13:25:34 +0000133 decryptor.authenticate_additional_data(aad)
Filip Tehlaredf29002020-10-10 04:39:11 +0000134 return decryptor.update(ct) + decryptor.finalize()
Filip Tehlar12b517b2020-04-26 18:05:05 +0000135
136 def pad(self, data):
137 pad_len = (len(data) // self.bs + 1) * self.bs - len(data)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200138 data = data + b"\x00" * (pad_len - 1)
Filip Tehlar558607d2020-07-16 07:25:56 +0000139 return data + bytes([pad_len - 1])
Filip Tehlar12b517b2020-04-26 18:05:05 +0000140
141
142class AuthAlgo(object):
143 def __init__(self, name, mac, mod, key_len, trunc_len=None):
144 self.name = name
145 self.mac = mac
146 self.mod = mod
147 self.key_len = key_len
148 self.trunc_len = trunc_len or key_len
149
150
151CRYPTO_ALGOS = {
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200152 "NULL": CryptoAlgo("NULL", cipher=None, mode=None),
153 "AES-CBC": CryptoAlgo("AES-CBC", cipher=algorithms.AES, mode=modes.CBC),
154 "AES-GCM-16ICV": CryptoAlgo("AES-GCM-16ICV", cipher=algorithms.AES, mode=modes.GCM),
Filip Tehlar12b517b2020-04-26 18:05:05 +0000155}
156
157AUTH_ALGOS = {
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200158 "NULL": AuthAlgo("NULL", mac=None, mod=None, key_len=0, trunc_len=0),
159 "HMAC-SHA1-96": AuthAlgo("HMAC-SHA1-96", hmac.HMAC, hashes.SHA1, 20, 12),
160 "SHA2-256-128": AuthAlgo("SHA2-256-128", hmac.HMAC, hashes.SHA256, 32, 16),
161 "SHA2-384-192": AuthAlgo("SHA2-384-192", hmac.HMAC, hashes.SHA256, 48, 24),
162 "SHA2-512-256": AuthAlgo("SHA2-512-256", hmac.HMAC, hashes.SHA256, 64, 32),
Filip Tehlar12b517b2020-04-26 18:05:05 +0000163}
164
165PRF_ALGOS = {
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200166 "NULL": AuthAlgo("NULL", mac=None, mod=None, key_len=0, trunc_len=0),
167 "PRF_HMAC_SHA2_256": AuthAlgo("PRF_HMAC_SHA2_256", hmac.HMAC, hashes.SHA256, 32),
Filip Tehlar12b517b2020-04-26 18:05:05 +0000168}
169
Filip Tehlar68ad6252020-10-30 05:28:11 +0000170CRYPTO_IDS = {
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200171 12: "AES-CBC",
172 20: "AES-GCM-16ICV",
Filip Tehlar68ad6252020-10-30 05:28:11 +0000173}
174
175INTEG_IDS = {
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200176 2: "HMAC-SHA1-96",
177 12: "SHA2-256-128",
178 13: "SHA2-384-192",
179 14: "SHA2-512-256",
Filip Tehlar68ad6252020-10-30 05:28:11 +0000180}
181
Filip Tehlar12b517b2020-04-26 18:05:05 +0000182
183class IKEv2ChildSA(object):
Filip Tehlar68ad6252020-10-30 05:28:11 +0000184 def __init__(self, local_ts, remote_ts, is_initiator):
185 spi = os.urandom(4)
186 if is_initiator:
187 self.ispi = spi
188 self.rspi = None
189 else:
190 self.rspi = spi
191 self.ispi = None
Filip Tehlar12b517b2020-04-26 18:05:05 +0000192 self.local_ts = local_ts
193 self.remote_ts = remote_ts
194
195
196class IKEv2SA(object):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200197 def __init__(
198 self,
199 test,
200 is_initiator=True,
201 i_id=None,
202 r_id=None,
203 spi=b"\x01\x02\x03\x04\x05\x06\x07\x08",
204 id_type="fqdn",
205 nonce=None,
206 auth_data=None,
207 local_ts=None,
208 remote_ts=None,
209 auth_method="shared-key",
210 priv_key=None,
211 i_natt=False,
212 r_natt=False,
213 udp_encap=False,
214 ):
Filip Tehlar67b8a7f2020-11-06 11:00:42 +0000215 self.udp_encap = udp_encap
Filip Tehlar027d8132020-12-04 17:38:11 +0000216 self.i_natt = i_natt
217 self.r_natt = r_natt
218 if i_natt or r_natt:
Filip Tehlarbfeae8c2020-06-23 20:35:58 +0000219 self.sport = 4500
220 self.dport = 4500
221 else:
222 self.sport = 500
223 self.dport = 500
Filip Tehlar558607d2020-07-16 07:25:56 +0000224 self.msg_id = 0
Filip Tehlar12b517b2020-04-26 18:05:05 +0000225 self.dh_params = None
226 self.test = test
Filip Tehlarbfeae8c2020-06-23 20:35:58 +0000227 self.priv_key = priv_key
Filip Tehlar12b517b2020-04-26 18:05:05 +0000228 self.is_initiator = is_initiator
229 nonce = nonce or os.urandom(32)
230 self.auth_data = auth_data
Filip Tehlar4128c7b2020-05-10 05:18:37 +0000231 self.i_id = i_id
232 self.r_id = r_id
Filip Tehlar12b517b2020-04-26 18:05:05 +0000233 if isinstance(id_type, str):
234 self.id_type = IDType.value(id_type)
235 else:
236 self.id_type = id_type
237 self.auth_method = auth_method
238 if self.is_initiator:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200239 self.rspi = 8 * b"\x00"
Filip Tehlar12b517b2020-04-26 18:05:05 +0000240 self.ispi = spi
Filip Tehlar12b517b2020-04-26 18:05:05 +0000241 self.i_nonce = nonce
242 else:
243 self.rspi = spi
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200244 self.ispi = 8 * b"\x00"
Filip Tehlare7c83962020-09-23 11:20:12 +0000245 self.r_nonce = nonce
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200246 self.child_sas = [IKEv2ChildSA(local_ts, remote_ts, self.is_initiator)]
Filip Tehlar12b517b2020-04-26 18:05:05 +0000247
Filip Tehlar558607d2020-07-16 07:25:56 +0000248 def new_msg_id(self):
249 self.msg_id += 1
250 return self.msg_id
251
Filip Tehlare7c83962020-09-23 11:20:12 +0000252 @property
253 def my_dh_pub_key(self):
254 if self.is_initiator:
255 return self.i_dh_data
256 return self.r_dh_data
257
258 @property
259 def peer_dh_pub_key(self):
260 if self.is_initiator:
261 return self.r_dh_data
Filip Tehlar12b517b2020-04-26 18:05:05 +0000262 return self.i_dh_data
263
Filip Tehlar027d8132020-12-04 17:38:11 +0000264 @property
265 def natt(self):
266 return self.i_natt or self.r_natt
267
Filip Tehlar12b517b2020-04-26 18:05:05 +0000268 def compute_secret(self):
269 priv = self.dh_private_key
Filip Tehlare7c83962020-09-23 11:20:12 +0000270 peer = self.peer_dh_pub_key
Filip Tehlar12b517b2020-04-26 18:05:05 +0000271 p, g, l = self.ike_group
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200272 return pow(
273 int.from_bytes(peer, "big"), int.from_bytes(priv, "big"), p
274 ).to_bytes(l, "big")
Filip Tehlar12b517b2020-04-26 18:05:05 +0000275
276 def generate_dh_data(self):
277 # generate DH keys
Filip Tehlare7c83962020-09-23 11:20:12 +0000278 if self.ike_dh not in DH:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200279 raise NotImplementedError("%s not in DH group" % self.ike_dh)
Filip Tehlare7c83962020-09-23 11:20:12 +0000280
281 if self.dh_params is None:
282 dhg = DH[self.ike_dh]
283 pn = dh.DHParameterNumbers(dhg[0], dhg[1])
284 self.dh_params = pn.parameters(default_backend())
285
286 priv = self.dh_params.generate_private_key()
287 pub = priv.public_key()
288 x = priv.private_numbers().x
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200289 self.dh_private_key = x.to_bytes(priv.key_size // 8, "big")
Filip Tehlare7c83962020-09-23 11:20:12 +0000290 y = pub.public_numbers().y
291
Filip Tehlar12b517b2020-04-26 18:05:05 +0000292 if self.is_initiator:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200293 self.i_dh_data = y.to_bytes(pub.key_size // 8, "big")
Filip Tehlare7c83962020-09-23 11:20:12 +0000294 else:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200295 self.r_dh_data = y.to_bytes(pub.key_size // 8, "big")
Filip Tehlar12b517b2020-04-26 18:05:05 +0000296
297 def complete_dh_data(self):
298 self.dh_shared_secret = self.compute_secret()
299
Atzm Watanabec65921f2022-08-12 14:29:31 +0900300 def calc_child_keys(self, kex=False):
Filip Tehlar12b517b2020-04-26 18:05:05 +0000301 prf = self.ike_prf_alg.mod()
302 s = self.i_nonce + self.r_nonce
Atzm Watanabec65921f2022-08-12 14:29:31 +0900303 if kex:
304 s = self.dh_shared_secret + s
Filip Tehlar12b517b2020-04-26 18:05:05 +0000305 c = self.child_sas[0]
306
307 encr_key_len = self.esp_crypto_key_len
Filip Tehlar4f42a712020-07-01 08:56:59 +0000308 integ_key_len = self.esp_integ_alg.key_len
309 salt_len = 0 if integ_key_len else 4
310
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200311 l = integ_key_len * 2 + encr_key_len * 2 + salt_len * 2
Filip Tehlar12b517b2020-04-26 18:05:05 +0000312 keymat = self.calc_prfplus(prf, self.sk_d, s, l)
313
314 pos = 0
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200315 c.sk_ei = keymat[pos : pos + encr_key_len]
Filip Tehlar12b517b2020-04-26 18:05:05 +0000316 pos += encr_key_len
317
Filip Tehlar4f42a712020-07-01 08:56:59 +0000318 if integ_key_len:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200319 c.sk_ai = keymat[pos : pos + integ_key_len]
Filip Tehlar4f42a712020-07-01 08:56:59 +0000320 pos += integ_key_len
321 else:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200322 c.salt_ei = keymat[pos : pos + salt_len]
Filip Tehlar4f42a712020-07-01 08:56:59 +0000323 pos += salt_len
Filip Tehlar12b517b2020-04-26 18:05:05 +0000324
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200325 c.sk_er = keymat[pos : pos + encr_key_len]
Filip Tehlar12b517b2020-04-26 18:05:05 +0000326 pos += encr_key_len
327
Filip Tehlar4f42a712020-07-01 08:56:59 +0000328 if integ_key_len:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200329 c.sk_ar = keymat[pos : pos + integ_key_len]
Filip Tehlar4f42a712020-07-01 08:56:59 +0000330 pos += integ_key_len
331 else:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200332 c.salt_er = keymat[pos : pos + salt_len]
Filip Tehlar4f42a712020-07-01 08:56:59 +0000333 pos += salt_len
Filip Tehlar12b517b2020-04-26 18:05:05 +0000334
335 def calc_prfplus(self, prf, key, seed, length):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200336 r = b""
Filip Tehlar12b517b2020-04-26 18:05:05 +0000337 t = None
338 x = 1
339 while len(r) < length and x < 255:
340 if t is not None:
341 s = t
342 else:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200343 s = b""
Filip Tehlar12b517b2020-04-26 18:05:05 +0000344 s = s + seed + bytes([x])
345 t = self.calc_prf(prf, key, s)
346 r = r + t
347 x = x + 1
348
349 if x == 255:
350 return None
351 return r
352
353 def calc_prf(self, prf, key, data):
Filip Tehlara7b963d2020-07-08 13:25:34 +0000354 h = self.ike_prf_alg.mac(key, prf, backend=default_backend())
Filip Tehlar12b517b2020-04-26 18:05:05 +0000355 h.update(data)
356 return h.finalize()
357
358 def calc_keys(self):
359 prf = self.ike_prf_alg.mod()
360 # SKEYSEED = prf(Ni | Nr, g^ir)
361 s = self.i_nonce + self.r_nonce
362 self.skeyseed = self.calc_prf(prf, s, self.dh_shared_secret)
363
364 # calculate S = Ni | Nr | SPIi SPIr
365 s = s + self.ispi + self.rspi
366
367 prf_key_trunc = self.ike_prf_alg.trunc_len
368 encr_key_len = self.ike_crypto_key_len
369 tr_prf_key_len = self.ike_prf_alg.key_len
370 integ_key_len = self.ike_integ_alg.key_len
Filip Tehlara7b963d2020-07-08 13:25:34 +0000371 if integ_key_len == 0:
372 salt_size = 4
373 else:
374 salt_size = 0
375
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200376 l = (
377 prf_key_trunc
378 + integ_key_len * 2
379 + encr_key_len * 2
380 + tr_prf_key_len * 2
381 + salt_size * 2
382 )
Filip Tehlar12b517b2020-04-26 18:05:05 +0000383 keymat = self.calc_prfplus(prf, self.skeyseed, s, l)
384
385 pos = 0
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200386 self.sk_d = keymat[: pos + prf_key_trunc]
Filip Tehlar12b517b2020-04-26 18:05:05 +0000387 pos += prf_key_trunc
388
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200389 self.sk_ai = keymat[pos : pos + integ_key_len]
Filip Tehlar12b517b2020-04-26 18:05:05 +0000390 pos += integ_key_len
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200391 self.sk_ar = keymat[pos : pos + integ_key_len]
Filip Tehlar12b517b2020-04-26 18:05:05 +0000392 pos += integ_key_len
393
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200394 self.sk_ei = keymat[pos : pos + encr_key_len + salt_size]
Filip Tehlara7b963d2020-07-08 13:25:34 +0000395 pos += encr_key_len + salt_size
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200396 self.sk_er = keymat[pos : pos + encr_key_len + salt_size]
Filip Tehlara7b963d2020-07-08 13:25:34 +0000397 pos += encr_key_len + salt_size
Filip Tehlar12b517b2020-04-26 18:05:05 +0000398
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200399 self.sk_pi = keymat[pos : pos + tr_prf_key_len]
Filip Tehlar12b517b2020-04-26 18:05:05 +0000400 pos += tr_prf_key_len
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200401 self.sk_pr = keymat[pos : pos + tr_prf_key_len]
Filip Tehlar12b517b2020-04-26 18:05:05 +0000402
403 def generate_authmsg(self, prf, packet):
404 if self.is_initiator:
405 id = self.i_id
406 nonce = self.r_nonce
407 key = self.sk_pi
Filip Tehlare7c83962020-09-23 11:20:12 +0000408 else:
409 id = self.r_id
410 nonce = self.i_nonce
411 key = self.sk_pr
Filip Tehlar12b517b2020-04-26 18:05:05 +0000412 data = bytes([self.id_type, 0, 0, 0]) + id
413 id_hash = self.calc_prf(prf, key, data)
414 return packet + nonce + id_hash
415
416 def auth_init(self):
417 prf = self.ike_prf_alg.mod()
Filip Tehlare7c83962020-09-23 11:20:12 +0000418 if self.is_initiator:
419 packet = self.init_req_packet
420 else:
421 packet = self.init_resp_packet
422 authmsg = self.generate_authmsg(prf, raw(packet))
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200423 if self.auth_method == "shared-key":
Filip Tehlarbfeae8c2020-06-23 20:35:58 +0000424 psk = self.calc_prf(prf, self.auth_data, KEY_PAD)
425 self.auth_data = self.calc_prf(prf, psk, authmsg)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200426 elif self.auth_method == "rsa-sig":
427 self.auth_data = self.priv_key.sign(
428 authmsg, padding.PKCS1v15(), hashes.SHA1()
429 )
Filip Tehlarbfeae8c2020-06-23 20:35:58 +0000430 else:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200431 raise TypeError("unknown auth method type!")
Filip Tehlar12b517b2020-04-26 18:05:05 +0000432
Filip Tehlara7b963d2020-07-08 13:25:34 +0000433 def encrypt(self, data, aad=None):
Filip Tehlar12b517b2020-04-26 18:05:05 +0000434 data = self.ike_crypto_alg.pad(data)
Filip Tehlara7b963d2020-07-08 13:25:34 +0000435 return self.ike_crypto_alg.encrypt(data, self.my_cryptokey, aad)
Filip Tehlar12b517b2020-04-26 18:05:05 +0000436
437 @property
438 def peer_authkey(self):
439 if self.is_initiator:
440 return self.sk_ar
441 return self.sk_ai
442
443 @property
444 def my_authkey(self):
445 if self.is_initiator:
446 return self.sk_ai
447 return self.sk_ar
448
449 @property
450 def my_cryptokey(self):
451 if self.is_initiator:
452 return self.sk_ei
453 return self.sk_er
454
455 @property
456 def peer_cryptokey(self):
457 if self.is_initiator:
458 return self.sk_er
459 return self.sk_ei
460
Filip Tehlar4f42a712020-07-01 08:56:59 +0000461 def concat(self, alg, key_len):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200462 return alg + "-" + str(key_len * 8)
Filip Tehlar4f42a712020-07-01 08:56:59 +0000463
464 @property
465 def vpp_ike_cypto_alg(self):
466 return self.concat(self.ike_crypto, self.ike_crypto_key_len)
467
468 @property
469 def vpp_esp_cypto_alg(self):
470 return self.concat(self.esp_crypto, self.esp_crypto_key_len)
471
Filip Tehlar12b517b2020-04-26 18:05:05 +0000472 def verify_hmac(self, ikemsg):
473 integ_trunc = self.ike_integ_alg.trunc_len
474 exp_hmac = ikemsg[-integ_trunc:]
475 data = ikemsg[:-integ_trunc]
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200476 computed_hmac = self.compute_hmac(
477 self.ike_integ_alg.mod(), self.peer_authkey, data
478 )
Filip Tehlar12b517b2020-04-26 18:05:05 +0000479 self.test.assertEqual(computed_hmac[:integ_trunc], exp_hmac)
480
481 def compute_hmac(self, integ, key, data):
482 h = self.ike_integ_alg.mac(key, integ, backend=default_backend())
483 h.update(data)
484 return h.finalize()
485
Filip Tehlara7b963d2020-07-08 13:25:34 +0000486 def decrypt(self, data, aad=None, icv=None):
487 return self.ike_crypto_alg.decrypt(data, self.peer_cryptokey, aad, icv)
Filip Tehlar12b517b2020-04-26 18:05:05 +0000488
489 def hmac_and_decrypt(self, ike):
490 ep = ike[ikev2.IKEv2_payload_Encrypted]
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200491 if self.ike_crypto == "AES-GCM-16ICV":
Filip Tehlara7b963d2020-07-08 13:25:34 +0000492 aad_len = len(ikev2.IKEv2_payload_Encrypted()) + len(ikev2.IKEv2())
493 ct = ep.load[:-GCM_ICV_SIZE]
494 tag = ep.load[-GCM_ICV_SIZE:]
Filip Tehlaredf29002020-10-10 04:39:11 +0000495 plain = self.decrypt(ct, raw(ike)[:aad_len], tag)
Filip Tehlara7b963d2020-07-08 13:25:34 +0000496 else:
497 self.verify_hmac(raw(ike))
498 integ_trunc = self.ike_integ_alg.trunc_len
Filip Tehlar12b517b2020-04-26 18:05:05 +0000499
Filip Tehlara7b963d2020-07-08 13:25:34 +0000500 # remove ICV and decrypt payload
501 ct = ep.load[:-integ_trunc]
Filip Tehlaredf29002020-10-10 04:39:11 +0000502 plain = self.decrypt(ct)
503 # remove padding
504 pad_len = plain[-1]
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200505 return plain[: -pad_len - 1]
Filip Tehlar12b517b2020-04-26 18:05:05 +0000506
Filip Tehlar84962d12020-09-08 06:08:05 +0000507 def build_ts_addr(self, ts, version):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200508 return {
509 "starting_address_v" + version: ts["start_addr"],
510 "ending_address_v" + version: ts["end_addr"],
511 }
Filip Tehlar84962d12020-09-08 06:08:05 +0000512
513 def generate_ts(self, is_ip4):
Filip Tehlar12b517b2020-04-26 18:05:05 +0000514 c = self.child_sas[0]
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200515 ts_data = {"IP_protocol_ID": 0, "start_port": 0, "end_port": 0xFFFF}
Filip Tehlar84962d12020-09-08 06:08:05 +0000516 if is_ip4:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200517 ts_data.update(self.build_ts_addr(c.local_ts, "4"))
Filip Tehlar84962d12020-09-08 06:08:05 +0000518 ts1 = ikev2.IPv4TrafficSelector(**ts_data)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200519 ts_data.update(self.build_ts_addr(c.remote_ts, "4"))
Filip Tehlar84962d12020-09-08 06:08:05 +0000520 ts2 = ikev2.IPv4TrafficSelector(**ts_data)
521 else:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200522 ts_data.update(self.build_ts_addr(c.local_ts, "6"))
Filip Tehlar84962d12020-09-08 06:08:05 +0000523 ts1 = ikev2.IPv6TrafficSelector(**ts_data)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200524 ts_data.update(self.build_ts_addr(c.remote_ts, "6"))
Filip Tehlar84962d12020-09-08 06:08:05 +0000525 ts2 = ikev2.IPv6TrafficSelector(**ts_data)
Filip Tehlare7c83962020-09-23 11:20:12 +0000526
527 if self.is_initiator:
528 return ([ts1], [ts2])
529 return ([ts2], [ts1])
Filip Tehlar12b517b2020-04-26 18:05:05 +0000530
531 def set_ike_props(self, crypto, crypto_key_len, integ, prf, dh):
532 if crypto not in CRYPTO_ALGOS:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200533 raise TypeError("unsupported encryption algo %r" % crypto)
Filip Tehlar12b517b2020-04-26 18:05:05 +0000534 self.ike_crypto = crypto
535 self.ike_crypto_alg = CRYPTO_ALGOS[crypto]
536 self.ike_crypto_key_len = crypto_key_len
537
538 if integ not in AUTH_ALGOS:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200539 raise TypeError("unsupported auth algo %r" % integ)
540 self.ike_integ = None if integ == "NULL" else integ
Filip Tehlar12b517b2020-04-26 18:05:05 +0000541 self.ike_integ_alg = AUTH_ALGOS[integ]
542
543 if prf not in PRF_ALGOS:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200544 raise TypeError("unsupported prf algo %r" % prf)
Filip Tehlar12b517b2020-04-26 18:05:05 +0000545 self.ike_prf = prf
546 self.ike_prf_alg = PRF_ALGOS[prf]
547 self.ike_dh = dh
548 self.ike_group = DH[self.ike_dh]
549
550 def set_esp_props(self, crypto, crypto_key_len, integ):
551 self.esp_crypto_key_len = crypto_key_len
552 if crypto not in CRYPTO_ALGOS:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200553 raise TypeError("unsupported encryption algo %r" % crypto)
Filip Tehlar12b517b2020-04-26 18:05:05 +0000554 self.esp_crypto = crypto
555 self.esp_crypto_alg = CRYPTO_ALGOS[crypto]
556
557 if integ not in AUTH_ALGOS:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200558 raise TypeError("unsupported auth algo %r" % integ)
559 self.esp_integ = None if integ == "NULL" else integ
Filip Tehlar12b517b2020-04-26 18:05:05 +0000560 self.esp_integ_alg = AUTH_ALGOS[integ]
561
562 def crypto_attr(self, key_len):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200563 if self.ike_crypto in ["AES-CBC", "AES-GCM-16ICV"]:
564 return (0x800E << 16 | key_len << 3, 12)
Filip Tehlar12b517b2020-04-26 18:05:05 +0000565 else:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200566 raise Exception("unsupported attribute type")
Filip Tehlar12b517b2020-04-26 18:05:05 +0000567
568 def ike_crypto_attr(self):
569 return self.crypto_attr(self.ike_crypto_key_len)
570
571 def esp_crypto_attr(self):
572 return self.crypto_attr(self.esp_crypto_key_len)
573
Filip Tehlarec112e52020-10-07 23:52:37 +0000574 def compute_nat_sha1(self, ip, port, rspi=None):
575 if rspi is None:
576 rspi = self.rspi
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200577 data = self.ispi + rspi + ip + (port).to_bytes(2, "big")
Filip Tehlarbfeae8c2020-06-23 20:35:58 +0000578 digest = hashes.Hash(hashes.SHA1(), backend=default_backend())
579 digest.update(data)
580 return digest.finalize()
Filip Tehlar12b517b2020-04-26 18:05:05 +0000581
Filip Tehlarbfeae8c2020-06-23 20:35:58 +0000582
Filip Tehlare7c83962020-09-23 11:20:12 +0000583class IkePeer(VppTestCase):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200584 """common class for initiator and responder"""
Filip Tehlar12b517b2020-04-26 18:05:05 +0000585
586 @classmethod
587 def setUpClass(cls):
588 import scapy.contrib.ikev2 as _ikev2
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200589
590 globals()["ikev2"] = _ikev2
Filip Tehlare7c83962020-09-23 11:20:12 +0000591 super(IkePeer, cls).setUpClass()
Filip Tehlar12b517b2020-04-26 18:05:05 +0000592 cls.create_pg_interfaces(range(2))
593 for i in cls.pg_interfaces:
594 i.admin_up()
595 i.config_ip4()
596 i.resolve_arp()
Filip Tehlar84962d12020-09-08 06:08:05 +0000597 i.config_ip6()
598 i.resolve_ndp()
Filip Tehlar12b517b2020-04-26 18:05:05 +0000599
600 @classmethod
601 def tearDownClass(cls):
Filip Tehlare7c83962020-09-23 11:20:12 +0000602 super(IkePeer, cls).tearDownClass()
Filip Tehlar12b517b2020-04-26 18:05:05 +0000603
Filip Tehlaredf29002020-10-10 04:39:11 +0000604 def tearDown(self):
605 super(IkePeer, self).tearDown()
606 if self.del_sa_from_responder:
607 self.initiate_del_sa_from_responder()
608 else:
609 self.initiate_del_sa_from_initiator()
610 r = self.vapi.ikev2_sa_dump()
611 self.assertEqual(len(r), 0)
612 sas = self.vapi.ipsec_sa_dump()
613 self.assertEqual(len(sas), 0)
614 self.p.remove_vpp_config()
615 self.assertIsNone(self.p.query_vpp_config())
616
Filip Tehlar12b517b2020-04-26 18:05:05 +0000617 def setUp(self):
Filip Tehlare7c83962020-09-23 11:20:12 +0000618 super(IkePeer, self).setUp()
Filip Tehlar12b517b2020-04-26 18:05:05 +0000619 self.config_tc()
Filip Tehlar12b517b2020-04-26 18:05:05 +0000620 self.p.add_vpp_config()
Filip Tehlar459d17b2020-07-06 15:40:08 +0000621 self.assertIsNotNone(self.p.query_vpp_config())
Filip Tehlar68ad6252020-10-30 05:28:11 +0000622 if self.sa.is_initiator:
623 self.sa.generate_dh_data()
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200624 self.vapi.cli("ikev2 set logging level 4")
625 self.vapi.cli("event-lo clear")
Filip Tehlar12b517b2020-04-26 18:05:05 +0000626
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200627 def assert_counter(self, count, name, version="ip4"):
628 node_name = "/err/ikev2-%s/" % version + name
Filip Tehlarfab5e7f2021-01-14 13:32:01 +0000629 self.assertEqual(count, self.statistics.get_err_counter(node_name))
630
Atzm Watanabec65921f2022-08-12 14:29:31 +0900631 def create_rekey_request(self, kex=False):
632 sa, first_payload = self.generate_auth_payload(is_rekey=True, kex=kex)
Filip Tehlar38340fa2020-11-19 21:34:48 +0000633 header = ikev2.IKEv2(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200634 init_SPI=self.sa.ispi,
635 resp_SPI=self.sa.rspi,
636 id=self.sa.new_msg_id(),
637 flags="Initiator",
638 exch_type="CREATE_CHILD_SA",
639 )
Filip Tehlar38340fa2020-11-19 21:34:48 +0000640
641 ike_msg = self.encrypt_ike_msg(header, sa, first_payload)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200642 return self.create_packet(
643 self.pg0, ike_msg, self.sa.sport, self.sa.dport, self.sa.natt, self.ip6
644 )
Filip Tehlar38340fa2020-11-19 21:34:48 +0000645
646 def create_empty_request(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200647 header = ikev2.IKEv2(
648 init_SPI=self.sa.ispi,
649 resp_SPI=self.sa.rspi,
650 id=self.sa.new_msg_id(),
651 flags="Initiator",
652 exch_type="INFORMATIONAL",
653 next_payload="Encrypted",
654 )
Filip Tehlar38340fa2020-11-19 21:34:48 +0000655
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200656 msg = self.encrypt_ike_msg(header, b"", None)
657 return self.create_packet(
658 self.pg0, msg, self.sa.sport, self.sa.dport, self.sa.natt, self.ip6
659 )
Filip Tehlar38340fa2020-11-19 21:34:48 +0000660
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200661 def create_packet(
662 self, src_if, msg, sport=500, dport=500, natt=False, use_ip6=False
663 ):
Filip Tehlar84962d12020-09-08 06:08:05 +0000664 if use_ip6:
665 src_ip = src_if.remote_ip6
666 dst_ip = src_if.local_ip6
667 ip_layer = IPv6
668 else:
669 src_ip = src_if.remote_ip4
670 dst_ip = src_if.local_ip4
671 ip_layer = IP
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200672 res = (
673 Ether(dst=src_if.local_mac, src=src_if.remote_mac)
674 / ip_layer(src=src_ip, dst=dst_ip)
675 / UDP(sport=sport, dport=dport)
676 )
Filip Tehlarbfeae8c2020-06-23 20:35:58 +0000677 if natt:
678 # insert non ESP marker
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200679 res = res / Raw(b"\x00" * 4)
Filip Tehlarbfeae8c2020-06-23 20:35:58 +0000680 return res / msg
Filip Tehlar12b517b2020-04-26 18:05:05 +0000681
Filip Tehlare7c83962020-09-23 11:20:12 +0000682 def verify_udp(self, udp):
683 self.assertEqual(udp.sport, self.sa.sport)
684 self.assertEqual(udp.dport, self.sa.dport)
Filip Tehlar12b517b2020-04-26 18:05:05 +0000685
Filip Tehlare7c83962020-09-23 11:20:12 +0000686 def get_ike_header(self, packet):
687 try:
688 ih = packet[ikev2.IKEv2]
Filip Tehlar18107c92020-12-01 14:51:09 +0000689 ih = self.verify_and_remove_non_esp_marker(ih)
Filip Tehlare7c83962020-09-23 11:20:12 +0000690 except IndexError as e:
691 # this is a workaround for getting IKEv2 layer as both ikev2 and
692 # ipsec register for port 4500
693 esp = packet[ESP]
694 ih = self.verify_and_remove_non_esp_marker(esp)
695 self.assertEqual(ih.version, 0x20)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200696 self.assertNotIn("Version", ih.flags)
Filip Tehlare7c83962020-09-23 11:20:12 +0000697 return ih
Filip Tehlar12b517b2020-04-26 18:05:05 +0000698
Filip Tehlare7c83962020-09-23 11:20:12 +0000699 def verify_and_remove_non_esp_marker(self, packet):
700 if self.sa.natt:
701 # if we are in nat traversal mode check for non esp marker
702 # and remove it
703 data = raw(packet)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200704 self.assertEqual(data[:4], b"\x00" * 4)
Filip Tehlare7c83962020-09-23 11:20:12 +0000705 return ikev2.IKEv2(data[4:])
Filip Tehlarbfeae8c2020-06-23 20:35:58 +0000706 else:
Filip Tehlare7c83962020-09-23 11:20:12 +0000707 return packet
Filip Tehlar12b517b2020-04-26 18:05:05 +0000708
Filip Tehlar558607d2020-07-16 07:25:56 +0000709 def encrypt_ike_msg(self, header, plain, first_payload):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200710 if self.sa.ike_crypto == "AES-GCM-16ICV":
Filip Tehlar558607d2020-07-16 07:25:56 +0000711 data = self.sa.ike_crypto_alg.pad(raw(plain))
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200712 plen = (
713 len(data)
714 + GCM_IV_SIZE
715 + GCM_ICV_SIZE
716 + len(ikev2.IKEv2_payload_Encrypted())
717 )
Filip Tehlar558607d2020-07-16 07:25:56 +0000718 tlen = plen + len(ikev2.IKEv2())
719
720 # prepare aad data
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200721 sk_p = ikev2.IKEv2_payload_Encrypted(
722 next_payload=first_payload, length=plen
723 )
Filip Tehlar558607d2020-07-16 07:25:56 +0000724 header.length = tlen
725 res = header / sk_p
726 encr = self.sa.encrypt(raw(plain), raw(res))
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200727 sk_p = ikev2.IKEv2_payload_Encrypted(
728 next_payload=first_payload, length=plen, load=encr
729 )
Filip Tehlar558607d2020-07-16 07:25:56 +0000730 res = header / sk_p
731 else:
732 encr = self.sa.encrypt(raw(plain))
733 trunc_len = self.sa.ike_integ_alg.trunc_len
734 plen = len(encr) + len(ikev2.IKEv2_payload_Encrypted()) + trunc_len
735 tlen = plen + len(ikev2.IKEv2())
736
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200737 sk_p = ikev2.IKEv2_payload_Encrypted(
738 next_payload=first_payload, length=plen, load=encr
739 )
Filip Tehlar558607d2020-07-16 07:25:56 +0000740 header.length = tlen
741 res = header / sk_p
742
743 integ_data = raw(res)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200744 hmac_data = self.sa.compute_hmac(
745 self.sa.ike_integ_alg.mod(), self.sa.my_authkey, integ_data
746 )
Filip Tehlar558607d2020-07-16 07:25:56 +0000747 res = res / Raw(hmac_data[:trunc_len])
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200748 assert len(res) == tlen
Filip Tehlar558607d2020-07-16 07:25:56 +0000749 return res
750
Filip Tehlar67b8a7f2020-11-06 11:00:42 +0000751 def verify_udp_encap(self, ipsec_sa):
752 e = VppEnum.vl_api_ipsec_sad_flags_t
753 if self.sa.udp_encap or self.sa.natt:
754 self.assertIn(e.IPSEC_API_SAD_FLAG_UDP_ENCAP, ipsec_sa.flags)
755 else:
756 self.assertNotIn(e.IPSEC_API_SAD_FLAG_UDP_ENCAP, ipsec_sa.flags)
757
Atzm Watanabe7e6ffba2022-08-09 14:00:03 +0900758 def verify_ipsec_sas(self, is_rekey=False, sa_count=None):
Filip Tehlar12b517b2020-04-26 18:05:05 +0000759 sas = self.vapi.ipsec_sa_dump()
Atzm Watanabe7e6ffba2022-08-09 14:00:03 +0900760 if sa_count is None:
761 if is_rekey:
762 # after rekey there is a short period of time in which old
763 # inbound SA is still present
764 sa_count = 3
765 else:
766 sa_count = 2
Filip Tehlar68ad6252020-10-30 05:28:11 +0000767 self.assertEqual(len(sas), sa_count)
Filip Tehlare7c83962020-09-23 11:20:12 +0000768 if self.sa.is_initiator:
Filip Tehlar68ad6252020-10-30 05:28:11 +0000769 if is_rekey:
770 sa0 = sas[0].entry
771 sa1 = sas[2].entry
772 else:
773 sa0 = sas[0].entry
774 sa1 = sas[1].entry
Filip Tehlare7c83962020-09-23 11:20:12 +0000775 else:
Filip Tehlar68ad6252020-10-30 05:28:11 +0000776 if is_rekey:
777 sa0 = sas[2].entry
778 sa1 = sas[0].entry
779 else:
780 sa1 = sas[0].entry
781 sa0 = sas[1].entry
Filip Tehlare7c83962020-09-23 11:20:12 +0000782
Filip Tehlar12b517b2020-04-26 18:05:05 +0000783 c = self.sa.child_sas[0]
784
Filip Tehlar67b8a7f2020-11-06 11:00:42 +0000785 self.verify_udp_encap(sa0)
786 self.verify_udp_encap(sa1)
Filip Tehlar4f42a712020-07-01 08:56:59 +0000787 vpp_crypto_alg = self.vpp_enums[self.sa.vpp_esp_cypto_alg]
788 self.assertEqual(sa0.crypto_algorithm, vpp_crypto_alg)
789 self.assertEqual(sa1.crypto_algorithm, vpp_crypto_alg)
790
791 if self.sa.esp_integ is None:
792 vpp_integ_alg = 0
793 else:
794 vpp_integ_alg = self.vpp_enums[self.sa.esp_integ]
795 self.assertEqual(sa0.integrity_algorithm, vpp_integ_alg)
796 self.assertEqual(sa1.integrity_algorithm, vpp_integ_alg)
797
Filip Tehlar12b517b2020-04-26 18:05:05 +0000798 # verify crypto keys
799 self.assertEqual(sa0.crypto_key.length, len(c.sk_er))
800 self.assertEqual(sa1.crypto_key.length, len(c.sk_ei))
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200801 self.assertEqual(sa0.crypto_key.data[: len(c.sk_er)], c.sk_er)
802 self.assertEqual(sa1.crypto_key.data[: len(c.sk_ei)], c.sk_ei)
Filip Tehlar12b517b2020-04-26 18:05:05 +0000803
804 # verify integ keys
Filip Tehlar4f42a712020-07-01 08:56:59 +0000805 if vpp_integ_alg:
806 self.assertEqual(sa0.integrity_key.length, len(c.sk_ar))
807 self.assertEqual(sa1.integrity_key.length, len(c.sk_ai))
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200808 self.assertEqual(sa0.integrity_key.data[: len(c.sk_ar)], c.sk_ar)
809 self.assertEqual(sa1.integrity_key.data[: len(c.sk_ai)], c.sk_ai)
Filip Tehlar4f42a712020-07-01 08:56:59 +0000810 else:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200811 self.assertEqual(sa0.salt.to_bytes(4, "little"), c.salt_er)
812 self.assertEqual(sa1.salt.to_bytes(4, "little"), c.salt_ei)
Filip Tehlar12b517b2020-04-26 18:05:05 +0000813
jan_cavojskya340fe12020-07-08 09:24:12 +0200814 def verify_keymat(self, api_keys, keys, name):
815 km = getattr(keys, name)
816 api_km = getattr(api_keys, name)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200817 api_km_len = getattr(api_keys, name + "_len")
jan_cavojskya340fe12020-07-08 09:24:12 +0200818 self.assertEqual(len(km), api_km_len)
819 self.assertEqual(km, api_km[:api_km_len])
820
821 def verify_id(self, api_id, exp_id):
822 self.assertEqual(api_id.type, IDType.value(exp_id.type))
823 self.assertEqual(api_id.data_len, exp_id.data_len)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200824 self.assertEqual(bytes(api_id.data, "ascii"), exp_id.type)
jan_cavojskya340fe12020-07-08 09:24:12 +0200825
826 def verify_ike_sas(self):
827 r = self.vapi.ikev2_sa_dump()
828 self.assertEqual(len(r), 1)
829 sa = r[0].sa
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200830 self.assertEqual(self.sa.ispi, (sa.ispi).to_bytes(8, "big"))
831 self.assertEqual(self.sa.rspi, (sa.rspi).to_bytes(8, "big"))
Filip Tehlar84962d12020-09-08 06:08:05 +0000832 if self.ip6:
Filip Tehlare7c83962020-09-23 11:20:12 +0000833 if self.sa.is_initiator:
834 self.assertEqual(sa.iaddr, IPv6Address(self.pg0.remote_ip6))
835 self.assertEqual(sa.raddr, IPv6Address(self.pg0.local_ip6))
836 else:
837 self.assertEqual(sa.iaddr, IPv6Address(self.pg0.local_ip6))
838 self.assertEqual(sa.raddr, IPv6Address(self.pg0.remote_ip6))
Filip Tehlar84962d12020-09-08 06:08:05 +0000839 else:
Filip Tehlare7c83962020-09-23 11:20:12 +0000840 if self.sa.is_initiator:
841 self.assertEqual(sa.iaddr, IPv4Address(self.pg0.remote_ip4))
842 self.assertEqual(sa.raddr, IPv4Address(self.pg0.local_ip4))
843 else:
844 self.assertEqual(sa.iaddr, IPv4Address(self.pg0.local_ip4))
845 self.assertEqual(sa.raddr, IPv4Address(self.pg0.remote_ip4))
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200846 self.verify_keymat(sa.keys, self.sa, "sk_d")
847 self.verify_keymat(sa.keys, self.sa, "sk_ai")
848 self.verify_keymat(sa.keys, self.sa, "sk_ar")
849 self.verify_keymat(sa.keys, self.sa, "sk_ei")
850 self.verify_keymat(sa.keys, self.sa, "sk_er")
851 self.verify_keymat(sa.keys, self.sa, "sk_pi")
852 self.verify_keymat(sa.keys, self.sa, "sk_pr")
jan_cavojskya340fe12020-07-08 09:24:12 +0200853
854 self.assertEqual(sa.i_id.type, self.sa.id_type)
855 self.assertEqual(sa.r_id.type, self.sa.id_type)
856 self.assertEqual(sa.i_id.data_len, len(self.sa.i_id))
Benoît Gannec7cceee2021-09-28 11:19:37 +0200857 self.assertEqual(sa.r_id.data_len, len(self.idr))
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200858 self.assertEqual(bytes(sa.i_id.data, "ascii"), self.sa.i_id)
859 self.assertEqual(bytes(sa.r_id.data, "ascii"), self.idr)
jan_cavojskya340fe12020-07-08 09:24:12 +0200860
861 r = self.vapi.ikev2_child_sa_dump(sa_index=sa.sa_index)
862 self.assertEqual(len(r), 1)
863 csa = r[0].child_sa
864 self.assertEqual(csa.sa_index, sa.sa_index)
865 c = self.sa.child_sas[0]
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200866 if hasattr(c, "sk_ai"):
867 self.verify_keymat(csa.keys, c, "sk_ai")
868 self.verify_keymat(csa.keys, c, "sk_ar")
869 self.verify_keymat(csa.keys, c, "sk_ei")
870 self.verify_keymat(csa.keys, c, "sk_er")
871 self.assertEqual(csa.i_spi.to_bytes(4, "big"), c.ispi)
872 self.assertEqual(csa.r_spi.to_bytes(4, "big"), c.rspi)
jan_cavojskya340fe12020-07-08 09:24:12 +0200873
Filip Tehlar84962d12020-09-08 06:08:05 +0000874 tsi, tsr = self.sa.generate_ts(self.p.ts_is_ip4)
jan_cavojskya340fe12020-07-08 09:24:12 +0200875 tsi = tsi[0]
876 tsr = tsr[0]
877 r = self.vapi.ikev2_traffic_selector_dump(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200878 is_initiator=True, sa_index=sa.sa_index, child_sa_index=csa.child_sa_index
879 )
jan_cavojskya340fe12020-07-08 09:24:12 +0200880 self.assertEqual(len(r), 1)
881 ts = r[0].ts
882 self.verify_ts(r[0].ts, tsi[0], True)
883
884 r = self.vapi.ikev2_traffic_selector_dump(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200885 is_initiator=False, sa_index=sa.sa_index, child_sa_index=csa.child_sa_index
886 )
jan_cavojskya340fe12020-07-08 09:24:12 +0200887 self.assertEqual(len(r), 1)
888 self.verify_ts(r[0].ts, tsr[0], False)
889
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200890 n = self.vapi.ikev2_nonce_get(is_initiator=True, sa_index=sa.sa_index)
jan_cavojskya340fe12020-07-08 09:24:12 +0200891 self.verify_nonce(n, self.sa.i_nonce)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200892 n = self.vapi.ikev2_nonce_get(is_initiator=False, sa_index=sa.sa_index)
jan_cavojskya340fe12020-07-08 09:24:12 +0200893 self.verify_nonce(n, self.sa.r_nonce)
894
895 def verify_nonce(self, api_nonce, nonce):
896 self.assertEqual(api_nonce.data_len, len(nonce))
897 self.assertEqual(api_nonce.nonce, nonce)
898
899 def verify_ts(self, api_ts, ts, is_initiator):
900 if is_initiator:
901 self.assertTrue(api_ts.is_local)
902 else:
903 self.assertFalse(api_ts.is_local)
Filip Tehlar84962d12020-09-08 06:08:05 +0000904
905 if self.p.ts_is_ip4:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200906 self.assertEqual(api_ts.start_addr, IPv4Address(ts.starting_address_v4))
907 self.assertEqual(api_ts.end_addr, IPv4Address(ts.ending_address_v4))
Filip Tehlar84962d12020-09-08 06:08:05 +0000908 else:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200909 self.assertEqual(api_ts.start_addr, IPv6Address(ts.starting_address_v6))
910 self.assertEqual(api_ts.end_addr, IPv6Address(ts.ending_address_v6))
jan_cavojskya340fe12020-07-08 09:24:12 +0200911 self.assertEqual(api_ts.start_port, ts.start_port)
912 self.assertEqual(api_ts.end_port, ts.end_port)
913 self.assertEqual(api_ts.protocol_id, ts.IP_protocol_ID)
914
Filip Tehlare7c83962020-09-23 11:20:12 +0000915
916class TemplateInitiator(IkePeer):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200917 """initiator test template"""
Filip Tehlare7c83962020-09-23 11:20:12 +0000918
Filip Tehlaredf29002020-10-10 04:39:11 +0000919 def initiate_del_sa_from_initiator(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200920 ispi = int.from_bytes(self.sa.ispi, "little")
Filip Tehlaredf29002020-10-10 04:39:11 +0000921 self.pg0.enable_capture()
922 self.pg_start()
923 self.vapi.ikev2_initiate_del_ike_sa(ispi=ispi)
924 capture = self.pg0.get_capture(1)
925 ih = self.get_ike_header(capture[0])
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200926 self.assertNotIn("Response", ih.flags)
927 self.assertIn("Initiator", ih.flags)
Filip Tehlaredf29002020-10-10 04:39:11 +0000928 self.assertEqual(ih.init_SPI, self.sa.ispi)
929 self.assertEqual(ih.resp_SPI, self.sa.rspi)
930 plain = self.sa.hmac_and_decrypt(ih)
931 d = ikev2.IKEv2_payload_Delete(plain)
932 self.assertEqual(d.proto, 1) # proto=IKEv2
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200933 header = ikev2.IKEv2(
934 init_SPI=self.sa.ispi,
935 resp_SPI=self.sa.rspi,
936 flags="Response",
937 exch_type="INFORMATIONAL",
938 id=ih.id,
939 next_payload="Encrypted",
940 )
941 resp = self.encrypt_ike_msg(header, b"", None)
Filip Tehlaredf29002020-10-10 04:39:11 +0000942 self.send_and_assert_no_replies(self.pg0, resp)
943
944 def verify_del_sa(self, packet):
945 ih = self.get_ike_header(packet)
946 self.assertEqual(ih.id, self.sa.msg_id)
947 self.assertEqual(ih.exch_type, 37) # exchange informational
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200948 self.assertIn("Response", ih.flags)
949 self.assertIn("Initiator", ih.flags)
Filip Tehlaredf29002020-10-10 04:39:11 +0000950 plain = self.sa.hmac_and_decrypt(ih)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200951 self.assertEqual(plain, b"")
Filip Tehlaredf29002020-10-10 04:39:11 +0000952
953 def initiate_del_sa_from_responder(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200954 header = ikev2.IKEv2(
955 init_SPI=self.sa.ispi,
956 resp_SPI=self.sa.rspi,
957 exch_type="INFORMATIONAL",
958 id=self.sa.new_msg_id(),
959 )
960 del_sa = ikev2.IKEv2_payload_Delete(proto="IKEv2")
961 ike_msg = self.encrypt_ike_msg(header, del_sa, "Delete")
962 packet = self.create_packet(
963 self.pg0, ike_msg, self.sa.sport, self.sa.dport, self.sa.natt, self.ip6
964 )
Filip Tehlaredf29002020-10-10 04:39:11 +0000965 self.pg0.add_stream(packet)
966 self.pg0.enable_capture()
967 self.pg_start()
968 capture = self.pg0.get_capture(1)
969 self.verify_del_sa(capture[0])
Filip Tehlare7c83962020-09-23 11:20:12 +0000970
Filip Tehlarec112e52020-10-07 23:52:37 +0000971 @staticmethod
972 def find_notify_payload(packet, notify_type):
973 n = packet[ikev2.IKEv2_payload_Notify]
974 while n is not None:
975 if n.type == notify_type:
976 return n
977 n = n.payload
978 return None
979
980 def verify_nat_detection(self, packet):
981 if self.ip6:
982 iph = packet[IPv6]
983 else:
984 iph = packet[IP]
985 udp = packet[UDP]
986
987 # NAT_DETECTION_SOURCE_IP
988 s = self.find_notify_payload(packet, 16388)
989 self.assertIsNotNone(s)
990 src_sha = self.sa.compute_nat_sha1(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200991 inet_pton(socket.AF_INET, iph.src), udp.sport, b"\x00" * 8
992 )
Filip Tehlarec112e52020-10-07 23:52:37 +0000993 self.assertEqual(s.load, src_sha)
994
995 # NAT_DETECTION_DESTINATION_IP
996 s = self.find_notify_payload(packet, 16389)
997 self.assertIsNotNone(s)
998 dst_sha = self.sa.compute_nat_sha1(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200999 inet_pton(socket.AF_INET, iph.dst), udp.dport, b"\x00" * 8
1000 )
Filip Tehlarec112e52020-10-07 23:52:37 +00001001 self.assertEqual(s.load, dst_sha)
1002
Filip Tehlare7c83962020-09-23 11:20:12 +00001003 def verify_sa_init_request(self, packet):
Filip Tehlar18107c92020-12-01 14:51:09 +00001004 udp = packet[UDP]
1005 self.sa.dport = udp.sport
Filip Tehlare7c83962020-09-23 11:20:12 +00001006 ih = packet[ikev2.IKEv2]
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001007 self.assertNotEqual(ih.init_SPI, 8 * b"\x00")
Filip Tehlare7c83962020-09-23 11:20:12 +00001008 self.assertEqual(ih.exch_type, 34) # SA_INIT
1009 self.sa.ispi = ih.init_SPI
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001010 self.assertEqual(ih.resp_SPI, 8 * b"\x00")
1011 self.assertIn("Initiator", ih.flags)
1012 self.assertNotIn("Response", ih.flags)
Filip Tehlare7c83962020-09-23 11:20:12 +00001013 self.sa.i_nonce = ih[ikev2.IKEv2_payload_Nonce].load
1014 self.sa.i_dh_data = ih[ikev2.IKEv2_payload_KE].load
1015
1016 prop = packet[ikev2.IKEv2_payload_Proposal]
1017 self.assertEqual(prop.proto, 1) # proto = ikev2
1018 self.assertEqual(prop.proposal, 1)
1019 self.assertEqual(prop.trans[0].transform_type, 1) # encryption
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001020 self.assertEqual(
1021 prop.trans[0].transform_id, self.p.ike_transforms["crypto_alg"]
1022 )
Filip Tehlare7c83962020-09-23 11:20:12 +00001023 self.assertEqual(prop.trans[1].transform_type, 2) # prf
1024 self.assertEqual(prop.trans[1].transform_id, 5) # "hmac-sha2-256"
1025 self.assertEqual(prop.trans[2].transform_type, 4) # dh
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001026 self.assertEqual(prop.trans[2].transform_id, self.p.ike_transforms["dh_group"])
Filip Tehlare7c83962020-09-23 11:20:12 +00001027
Filip Tehlarec112e52020-10-07 23:52:37 +00001028 self.verify_nat_detection(packet)
Filip Tehlar68ad6252020-10-30 05:28:11 +00001029 self.sa.set_ike_props(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001030 crypto="AES-GCM-16ICV",
1031 crypto_key_len=32,
1032 integ="NULL",
1033 prf="PRF_HMAC_SHA2_256",
1034 dh="3072MODPgr",
1035 )
1036 self.sa.set_esp_props(crypto="AES-CBC", crypto_key_len=32, integ="SHA2-256-128")
Filip Tehlar68ad6252020-10-30 05:28:11 +00001037 self.sa.generate_dh_data()
Filip Tehlare7c83962020-09-23 11:20:12 +00001038 self.sa.complete_dh_data()
1039 self.sa.calc_keys()
1040
Filip Tehlar68ad6252020-10-30 05:28:11 +00001041 def update_esp_transforms(self, trans, sa):
1042 while trans:
1043 if trans.transform_type == 1: # ecryption
1044 sa.esp_crypto = CRYPTO_IDS[trans.transform_id]
1045 elif trans.transform_type == 3: # integrity
1046 sa.esp_integ = INTEG_IDS[trans.transform_id]
1047 trans = trans.payload
1048
Filip Tehlare7c83962020-09-23 11:20:12 +00001049 def verify_sa_auth_req(self, packet):
Filip Tehlar18107c92020-12-01 14:51:09 +00001050 udp = packet[UDP]
1051 self.sa.dport = udp.sport
Filip Tehlare7c83962020-09-23 11:20:12 +00001052 ih = self.get_ike_header(packet)
1053 self.assertEqual(ih.resp_SPI, self.sa.rspi)
1054 self.assertEqual(ih.init_SPI, self.sa.ispi)
1055 self.assertEqual(ih.exch_type, 35) # IKE_AUTH
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001056 self.assertIn("Initiator", ih.flags)
1057 self.assertNotIn("Response", ih.flags)
Filip Tehlare7c83962020-09-23 11:20:12 +00001058
1059 udp = packet[UDP]
1060 self.verify_udp(udp)
1061 self.assertEqual(ih.id, self.sa.msg_id + 1)
1062 self.sa.msg_id += 1
1063 plain = self.sa.hmac_and_decrypt(ih)
1064 idi = ikev2.IKEv2_payload_IDi(plain)
Filip Tehlare7c83962020-09-23 11:20:12 +00001065 self.assertEqual(idi.load, self.sa.i_id)
Benoît Gannec7cceee2021-09-28 11:19:37 +02001066 if self.no_idr_auth:
1067 self.assertEqual(idi.next_payload, 39) # AUTH
1068 else:
1069 idr = ikev2.IKEv2_payload_IDr(idi.payload)
1070 self.assertEqual(idr.load, self.sa.r_id)
Filip Tehlar68ad6252020-10-30 05:28:11 +00001071 prop = idi[ikev2.IKEv2_payload_Proposal]
1072 c = self.sa.child_sas[0]
1073 c.ispi = prop.SPI
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001074 self.update_esp_transforms(prop[ikev2.IKEv2_payload_Transform], self.sa)
Filip Tehlare7c83962020-09-23 11:20:12 +00001075
1076 def send_init_response(self):
1077 tr_attr = self.sa.ike_crypto_attr()
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001078 trans = (
1079 ikev2.IKEv2_payload_Transform(
1080 transform_type="Encryption",
1081 transform_id=self.sa.ike_crypto,
1082 length=tr_attr[1],
1083 key_length=tr_attr[0],
1084 )
1085 / ikev2.IKEv2_payload_Transform(
1086 transform_type="Integrity", transform_id=self.sa.ike_integ
1087 )
1088 / ikev2.IKEv2_payload_Transform(
1089 transform_type="PRF", transform_id=self.sa.ike_prf_alg.name
1090 )
1091 / ikev2.IKEv2_payload_Transform(
1092 transform_type="GroupDesc", transform_id=self.sa.ike_dh
1093 )
1094 )
1095 props = ikev2.IKEv2_payload_Proposal(
1096 proposal=1, proto="IKEv2", trans_nb=4, trans=trans
1097 )
Filip Tehlar18107c92020-12-01 14:51:09 +00001098
1099 src_address = inet_pton(socket.AF_INET, self.pg0.remote_ip4)
1100 if self.sa.natt:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001101 dst_address = b"\x0a\x0a\x0a\x0a"
Filip Tehlar18107c92020-12-01 14:51:09 +00001102 else:
1103 dst_address = inet_pton(socket.AF_INET, self.pg0.local_ip4)
1104 src_nat = self.sa.compute_nat_sha1(src_address, self.sa.sport)
1105 dst_nat = self.sa.compute_nat_sha1(dst_address, self.sa.dport)
1106
Filip Tehlare7c83962020-09-23 11:20:12 +00001107 self.sa.init_resp_packet = (
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001108 ikev2.IKEv2(
1109 init_SPI=self.sa.ispi,
1110 resp_SPI=self.sa.rspi,
1111 exch_type="IKE_SA_INIT",
1112 flags="Response",
1113 )
1114 / ikev2.IKEv2_payload_SA(next_payload="KE", prop=props)
1115 / ikev2.IKEv2_payload_KE(
1116 next_payload="Nonce", group=self.sa.ike_dh, load=self.sa.my_dh_pub_key
1117 )
1118 / ikev2.IKEv2_payload_Nonce(load=self.sa.r_nonce, next_payload="Notify")
1119 / ikev2.IKEv2_payload_Notify(
1120 type="NAT_DETECTION_SOURCE_IP", load=src_nat, next_payload="Notify"
1121 )
1122 / ikev2.IKEv2_payload_Notify(
1123 type="NAT_DETECTION_DESTINATION_IP", load=dst_nat
1124 )
1125 )
Filip Tehlare7c83962020-09-23 11:20:12 +00001126
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001127 ike_msg = self.create_packet(
1128 self.pg0,
1129 self.sa.init_resp_packet,
1130 self.sa.sport,
1131 self.sa.dport,
1132 False,
1133 self.ip6,
1134 )
Filip Tehlare7c83962020-09-23 11:20:12 +00001135 self.pg_send(self.pg0, ike_msg)
1136 capture = self.pg0.get_capture(1)
1137 self.verify_sa_auth_req(capture[0])
1138
1139 def initiate_sa_init(self):
1140 self.pg0.enable_capture()
1141 self.pg_start()
1142 self.vapi.ikev2_initiate_sa_init(name=self.p.profile_name)
1143
1144 capture = self.pg0.get_capture(1)
1145 self.verify_sa_init_request(capture[0])
1146 self.send_init_response()
1147
1148 def send_auth_response(self):
1149 tr_attr = self.sa.esp_crypto_attr()
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001150 trans = (
1151 ikev2.IKEv2_payload_Transform(
1152 transform_type="Encryption",
1153 transform_id=self.sa.esp_crypto,
1154 length=tr_attr[1],
1155 key_length=tr_attr[0],
1156 )
1157 / ikev2.IKEv2_payload_Transform(
1158 transform_type="Integrity", transform_id=self.sa.esp_integ
1159 )
1160 / ikev2.IKEv2_payload_Transform(
1161 transform_type="Extended Sequence Number", transform_id="No ESN"
1162 )
1163 / ikev2.IKEv2_payload_Transform(
1164 transform_type="Extended Sequence Number", transform_id="ESN"
1165 )
1166 )
Filip Tehlare7c83962020-09-23 11:20:12 +00001167
Filip Tehlar68ad6252020-10-30 05:28:11 +00001168 c = self.sa.child_sas[0]
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001169 props = ikev2.IKEv2_payload_Proposal(
1170 proposal=1, proto="ESP", SPIsize=4, SPI=c.rspi, trans_nb=4, trans=trans
1171 )
Filip Tehlare7c83962020-09-23 11:20:12 +00001172
1173 tsi, tsr = self.sa.generate_ts(self.p.ts_is_ip4)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001174 plain = (
1175 ikev2.IKEv2_payload_IDi(
1176 next_payload="IDr", IDtype=self.sa.id_type, load=self.sa.i_id
1177 )
1178 / ikev2.IKEv2_payload_IDr(
1179 next_payload="AUTH", IDtype=self.sa.id_type, load=self.sa.r_id
1180 )
1181 / ikev2.IKEv2_payload_AUTH(
1182 next_payload="SA",
1183 auth_type=AuthMethod.value(self.sa.auth_method),
1184 load=self.sa.auth_data,
1185 )
1186 / ikev2.IKEv2_payload_SA(next_payload="TSi", prop=props)
1187 / ikev2.IKEv2_payload_TSi(
1188 next_payload="TSr", number_of_TSs=len(tsi), traffic_selector=tsi
1189 )
1190 / ikev2.IKEv2_payload_TSr(
1191 next_payload="Notify", number_of_TSs=len(tsr), traffic_selector=tsr
1192 )
1193 / ikev2.IKEv2_payload_Notify(type="INITIAL_CONTACT")
1194 )
Filip Tehlare7c83962020-09-23 11:20:12 +00001195
1196 header = ikev2.IKEv2(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001197 init_SPI=self.sa.ispi,
1198 resp_SPI=self.sa.rspi,
1199 id=self.sa.new_msg_id(),
1200 flags="Response",
1201 exch_type="IKE_AUTH",
1202 )
Filip Tehlare7c83962020-09-23 11:20:12 +00001203
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001204 ike_msg = self.encrypt_ike_msg(header, plain, "IDi")
1205 packet = self.create_packet(
1206 self.pg0, ike_msg, self.sa.sport, self.sa.dport, self.sa.natt, self.ip6
1207 )
Filip Tehlare7c83962020-09-23 11:20:12 +00001208 self.pg_send(self.pg0, packet)
1209
1210 def test_initiator(self):
1211 self.initiate_sa_init()
1212 self.sa.auth_init()
1213 self.sa.calc_child_keys()
1214 self.send_auth_response()
1215 self.verify_ike_sas()
1216
1217
1218class TemplateResponder(IkePeer):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001219 """responder test template"""
Filip Tehlare7c83962020-09-23 11:20:12 +00001220
Filip Tehlaredf29002020-10-10 04:39:11 +00001221 def initiate_del_sa_from_responder(self):
1222 self.pg0.enable_capture()
1223 self.pg_start()
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001224 self.vapi.ikev2_initiate_del_ike_sa(ispi=int.from_bytes(self.sa.ispi, "little"))
Filip Tehlaredf29002020-10-10 04:39:11 +00001225 capture = self.pg0.get_capture(1)
1226 ih = self.get_ike_header(capture[0])
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001227 self.assertNotIn("Response", ih.flags)
1228 self.assertNotIn("Initiator", ih.flags)
Filip Tehlaredf29002020-10-10 04:39:11 +00001229 self.assertEqual(ih.exch_type, 37) # INFORMATIONAL
1230 plain = self.sa.hmac_and_decrypt(ih)
1231 d = ikev2.IKEv2_payload_Delete(plain)
1232 self.assertEqual(d.proto, 1) # proto=IKEv2
1233 self.assertEqual(ih.init_SPI, self.sa.ispi)
1234 self.assertEqual(ih.resp_SPI, self.sa.rspi)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001235 header = ikev2.IKEv2(
1236 init_SPI=self.sa.ispi,
1237 resp_SPI=self.sa.rspi,
1238 flags="Initiator+Response",
1239 exch_type="INFORMATIONAL",
1240 id=ih.id,
1241 next_payload="Encrypted",
1242 )
1243 resp = self.encrypt_ike_msg(header, b"", None)
Filip Tehlaredf29002020-10-10 04:39:11 +00001244 self.send_and_assert_no_replies(self.pg0, resp)
Filip Tehlare7c83962020-09-23 11:20:12 +00001245
1246 def verify_del_sa(self, packet):
1247 ih = self.get_ike_header(packet)
1248 self.assertEqual(ih.id, self.sa.msg_id)
1249 self.assertEqual(ih.exch_type, 37) # exchange informational
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001250 self.assertIn("Response", ih.flags)
1251 self.assertNotIn("Initiator", ih.flags)
Filip Tehlaredf29002020-10-10 04:39:11 +00001252 self.assertEqual(ih.next_payload, 46) # Encrypted
1253 self.assertEqual(ih.init_SPI, self.sa.ispi)
1254 self.assertEqual(ih.resp_SPI, self.sa.rspi)
1255 plain = self.sa.hmac_and_decrypt(ih)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001256 self.assertEqual(plain, b"")
Filip Tehlare7c83962020-09-23 11:20:12 +00001257
Filip Tehlaredf29002020-10-10 04:39:11 +00001258 def initiate_del_sa_from_initiator(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001259 header = ikev2.IKEv2(
1260 init_SPI=self.sa.ispi,
1261 resp_SPI=self.sa.rspi,
1262 flags="Initiator",
1263 exch_type="INFORMATIONAL",
1264 id=self.sa.new_msg_id(),
1265 )
1266 del_sa = ikev2.IKEv2_payload_Delete(proto="IKEv2")
1267 ike_msg = self.encrypt_ike_msg(header, del_sa, "Delete")
1268 packet = self.create_packet(
1269 self.pg0, ike_msg, self.sa.sport, self.sa.dport, self.sa.natt, self.ip6
1270 )
Filip Tehlare7c83962020-09-23 11:20:12 +00001271 self.pg0.add_stream(packet)
1272 self.pg0.enable_capture()
1273 self.pg_start()
1274 capture = self.pg0.get_capture(1)
1275 self.verify_del_sa(capture[0])
1276
Filip Tehlar027d8132020-12-04 17:38:11 +00001277 def send_sa_init_req(self):
Filip Tehlare7c83962020-09-23 11:20:12 +00001278 tr_attr = self.sa.ike_crypto_attr()
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001279 trans = (
1280 ikev2.IKEv2_payload_Transform(
1281 transform_type="Encryption",
1282 transform_id=self.sa.ike_crypto,
1283 length=tr_attr[1],
1284 key_length=tr_attr[0],
1285 )
1286 / ikev2.IKEv2_payload_Transform(
1287 transform_type="Integrity", transform_id=self.sa.ike_integ
1288 )
1289 / ikev2.IKEv2_payload_Transform(
1290 transform_type="PRF", transform_id=self.sa.ike_prf_alg.name
1291 )
1292 / ikev2.IKEv2_payload_Transform(
1293 transform_type="GroupDesc", transform_id=self.sa.ike_dh
1294 )
1295 )
Filip Tehlare7c83962020-09-23 11:20:12 +00001296
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001297 props = ikev2.IKEv2_payload_Proposal(
1298 proposal=1, proto="IKEv2", trans_nb=4, trans=trans
1299 )
Filip Tehlare7c83962020-09-23 11:20:12 +00001300
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001301 next_payload = None if self.ip6 else "Notify"
Filip Tehlar027d8132020-12-04 17:38:11 +00001302
Filip Tehlare7c83962020-09-23 11:20:12 +00001303 self.sa.init_req_packet = (
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001304 ikev2.IKEv2(
1305 init_SPI=self.sa.ispi, flags="Initiator", exch_type="IKE_SA_INIT"
1306 )
1307 / ikev2.IKEv2_payload_SA(next_payload="KE", prop=props)
1308 / ikev2.IKEv2_payload_KE(
1309 next_payload="Nonce", group=self.sa.ike_dh, load=self.sa.my_dh_pub_key
1310 )
1311 / ikev2.IKEv2_payload_Nonce(next_payload=next_payload, load=self.sa.i_nonce)
1312 )
Filip Tehlare7c83962020-09-23 11:20:12 +00001313
Filip Tehlar027d8132020-12-04 17:38:11 +00001314 if not self.ip6:
1315 if self.sa.i_natt:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001316 src_address = b"\x0a\x0a\x0a\x01"
Filip Tehlar027d8132020-12-04 17:38:11 +00001317 else:
1318 src_address = inet_pton(socket.AF_INET, self.pg0.remote_ip4)
Filip Tehlare7c83962020-09-23 11:20:12 +00001319
Filip Tehlar027d8132020-12-04 17:38:11 +00001320 if self.sa.r_natt:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001321 dst_address = b"\x0a\x0a\x0a\x0a"
Filip Tehlar027d8132020-12-04 17:38:11 +00001322 else:
1323 dst_address = inet_pton(socket.AF_INET, self.pg0.local_ip4)
1324
1325 src_nat = self.sa.compute_nat_sha1(src_address, self.sa.sport)
1326 dst_nat = self.sa.compute_nat_sha1(dst_address, self.sa.dport)
1327 nat_src_detection = ikev2.IKEv2_payload_Notify(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001328 type="NAT_DETECTION_SOURCE_IP", load=src_nat, next_payload="Notify"
1329 )
Filip Tehlar027d8132020-12-04 17:38:11 +00001330 nat_dst_detection = ikev2.IKEv2_payload_Notify(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001331 type="NAT_DETECTION_DESTINATION_IP", load=dst_nat
1332 )
1333 self.sa.init_req_packet = (
1334 self.sa.init_req_packet / nat_src_detection / nat_dst_detection
1335 )
Filip Tehlare7c83962020-09-23 11:20:12 +00001336
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001337 ike_msg = self.create_packet(
1338 self.pg0,
1339 self.sa.init_req_packet,
1340 self.sa.sport,
1341 self.sa.dport,
1342 self.sa.natt,
1343 self.ip6,
1344 )
Filip Tehlare7c83962020-09-23 11:20:12 +00001345 self.pg0.add_stream(ike_msg)
1346 self.pg0.enable_capture()
1347 self.pg_start()
1348 capture = self.pg0.get_capture(1)
1349 self.verify_sa_init(capture[0])
1350
Atzm Watanabec65921f2022-08-12 14:29:31 +09001351 def generate_auth_payload(self, last_payload=None, is_rekey=False, kex=False):
Filip Tehlare7c83962020-09-23 11:20:12 +00001352 tr_attr = self.sa.esp_crypto_attr()
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001353 last_payload = last_payload or "Notify"
Atzm Watanabec65921f2022-08-12 14:29:31 +09001354 trans_nb = 4
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001355 trans = (
1356 ikev2.IKEv2_payload_Transform(
1357 transform_type="Encryption",
1358 transform_id=self.sa.esp_crypto,
1359 length=tr_attr[1],
1360 key_length=tr_attr[0],
1361 )
1362 / ikev2.IKEv2_payload_Transform(
1363 transform_type="Integrity", transform_id=self.sa.esp_integ
1364 )
1365 / ikev2.IKEv2_payload_Transform(
1366 transform_type="Extended Sequence Number", transform_id="No ESN"
1367 )
1368 / ikev2.IKEv2_payload_Transform(
1369 transform_type="Extended Sequence Number", transform_id="ESN"
1370 )
1371 )
Filip Tehlare7c83962020-09-23 11:20:12 +00001372
Atzm Watanabec65921f2022-08-12 14:29:31 +09001373 if kex:
1374 trans_nb += 1
1375 trans /= ikev2.IKEv2_payload_Transform(
1376 transform_type="GroupDesc", transform_id=self.sa.ike_dh
1377 )
1378
Filip Tehlar68ad6252020-10-30 05:28:11 +00001379 c = self.sa.child_sas[0]
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001380 props = ikev2.IKEv2_payload_Proposal(
Atzm Watanabec65921f2022-08-12 14:29:31 +09001381 proposal=1,
1382 proto="ESP",
1383 SPIsize=4,
1384 SPI=c.ispi,
1385 trans_nb=trans_nb,
1386 trans=trans,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001387 )
Filip Tehlare7c83962020-09-23 11:20:12 +00001388
1389 tsi, tsr = self.sa.generate_ts(self.p.ts_is_ip4)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001390 plain = (
1391 ikev2.IKEv2_payload_AUTH(
1392 next_payload="SA",
1393 auth_type=AuthMethod.value(self.sa.auth_method),
1394 load=self.sa.auth_data,
1395 )
1396 / ikev2.IKEv2_payload_SA(next_payload="TSi", prop=props)
1397 / ikev2.IKEv2_payload_TSi(
1398 next_payload="TSr", number_of_TSs=len(tsi), traffic_selector=tsi
1399 )
1400 / ikev2.IKEv2_payload_TSr(
1401 next_payload=last_payload, number_of_TSs=len(tsr), traffic_selector=tsr
1402 )
1403 )
Filip Tehlare7c83962020-09-23 11:20:12 +00001404
Filip Tehlar68ad6252020-10-30 05:28:11 +00001405 if is_rekey:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001406 first_payload = "Nonce"
Atzm Watanabec65921f2022-08-12 14:29:31 +09001407 if kex:
1408 head = ikev2.IKEv2_payload_Nonce(
1409 load=self.sa.i_nonce, next_payload="KE"
1410 ) / ikev2.IKEv2_payload_KE(
1411 group=self.sa.ike_dh, load=self.sa.my_dh_pub_key, next_payload="SA"
1412 )
1413 else:
1414 head = ikev2.IKEv2_payload_Nonce(
1415 load=self.sa.i_nonce, next_payload="SA"
1416 )
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001417 plain = (
Atzm Watanabec65921f2022-08-12 14:29:31 +09001418 head
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001419 / plain
Atzm Watanabe03aae962022-08-08 15:45:36 +09001420 / ikev2.IKEv2_payload_Notify(
1421 type="REKEY_SA",
1422 proto="ESP",
1423 SPI=c.ispi,
1424 length=8 + len(c.ispi),
1425 next_payload="Notify",
1426 )
1427 / ikev2.IKEv2_payload_Notify(type="ESP_TFC_PADDING_NOT_SUPPORTED")
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001428 )
Filip Tehlar68ad6252020-10-30 05:28:11 +00001429 else:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001430 first_payload = "IDi"
Benoît Gannec7cceee2021-09-28 11:19:37 +02001431 if self.no_idr_auth:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001432 ids = ikev2.IKEv2_payload_IDi(
1433 next_payload="AUTH", IDtype=self.sa.id_type, load=self.sa.i_id
1434 )
Benoît Gannec7cceee2021-09-28 11:19:37 +02001435 else:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001436 ids = ikev2.IKEv2_payload_IDi(
1437 next_payload="IDr", IDtype=self.sa.id_type, load=self.sa.i_id
1438 ) / ikev2.IKEv2_payload_IDr(
1439 next_payload="AUTH", IDtype=self.sa.id_type, load=self.sa.r_id
1440 )
Filip Tehlar68ad6252020-10-30 05:28:11 +00001441 plain = ids / plain
1442 return plain, first_payload
1443
1444 def send_sa_auth(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001445 plain, first_payload = self.generate_auth_payload(last_payload="Notify")
1446 plain = plain / ikev2.IKEv2_payload_Notify(type="INITIAL_CONTACT")
Filip Tehlare7c83962020-09-23 11:20:12 +00001447 header = ikev2.IKEv2(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001448 init_SPI=self.sa.ispi,
1449 resp_SPI=self.sa.rspi,
1450 id=self.sa.new_msg_id(),
1451 flags="Initiator",
1452 exch_type="IKE_AUTH",
1453 )
Filip Tehlare7c83962020-09-23 11:20:12 +00001454
Filip Tehlar68ad6252020-10-30 05:28:11 +00001455 ike_msg = self.encrypt_ike_msg(header, plain, first_payload)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001456 packet = self.create_packet(
1457 self.pg0, ike_msg, self.sa.sport, self.sa.dport, self.sa.natt, self.ip6
1458 )
Filip Tehlare7c83962020-09-23 11:20:12 +00001459 self.pg0.add_stream(packet)
1460 self.pg0.enable_capture()
1461 self.pg_start()
1462 capture = self.pg0.get_capture(1)
1463 self.verify_sa_auth_resp(capture[0])
1464
1465 def verify_sa_init(self, packet):
1466 ih = self.get_ike_header(packet)
1467
1468 self.assertEqual(ih.id, self.sa.msg_id)
1469 self.assertEqual(ih.exch_type, 34)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001470 self.assertIn("Response", ih.flags)
Filip Tehlare7c83962020-09-23 11:20:12 +00001471 self.assertEqual(ih.init_SPI, self.sa.ispi)
1472 self.assertNotEqual(ih.resp_SPI, 0)
1473 self.sa.rspi = ih.resp_SPI
1474 try:
1475 sa = ih[ikev2.IKEv2_payload_SA]
1476 self.sa.r_nonce = ih[ikev2.IKEv2_payload_Nonce].load
1477 self.sa.r_dh_data = ih[ikev2.IKEv2_payload_KE].load
1478 except IndexError as e:
1479 self.logger.error("unexpected reply: SA/Nonce/KE payload found!")
1480 self.logger.error(ih.show())
1481 raise
1482 self.sa.complete_dh_data()
1483 self.sa.calc_keys()
1484 self.sa.auth_init()
1485
1486 def verify_sa_auth_resp(self, packet):
1487 ike = self.get_ike_header(packet)
1488 udp = packet[UDP]
1489 self.verify_udp(udp)
1490 self.assertEqual(ike.id, self.sa.msg_id)
1491 plain = self.sa.hmac_and_decrypt(ike)
Filip Tehlar68ad6252020-10-30 05:28:11 +00001492 idr = ikev2.IKEv2_payload_IDr(plain)
1493 prop = idr[ikev2.IKEv2_payload_Proposal]
1494 self.assertEqual(prop.SPIsize, 4)
1495 self.sa.child_sas[0].rspi = prop.SPI
Filip Tehlare7c83962020-09-23 11:20:12 +00001496 self.sa.calc_child_keys()
1497
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001498 IKE_NODE_SUFFIX = "ip4"
Filip Tehlarfab5e7f2021-01-14 13:32:01 +00001499
1500 def verify_counters(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001501 self.assert_counter(2, "processed", self.IKE_NODE_SUFFIX)
1502 self.assert_counter(1, "init_sa_req", self.IKE_NODE_SUFFIX)
1503 self.assert_counter(1, "ike_auth_req", self.IKE_NODE_SUFFIX)
Filip Tehlarfab5e7f2021-01-14 13:32:01 +00001504
Filip Tehlar68d27532021-01-25 10:09:27 +00001505 r = self.vapi.ikev2_sa_dump()
1506 s = r[0].sa.stats
1507 self.assertEqual(1, s.n_sa_auth_req)
1508 self.assertEqual(1, s.n_sa_init_req)
1509
Filip Tehlar12b517b2020-04-26 18:05:05 +00001510 def test_responder(self):
Filip Tehlar027d8132020-12-04 17:38:11 +00001511 self.send_sa_init_req()
Filip Tehlar12b517b2020-04-26 18:05:05 +00001512 self.send_sa_auth()
jan_cavojskya340fe12020-07-08 09:24:12 +02001513 self.verify_ipsec_sas()
1514 self.verify_ike_sas()
Filip Tehlarfab5e7f2021-01-14 13:32:01 +00001515 self.verify_counters()
Filip Tehlar12b517b2020-04-26 18:05:05 +00001516
1517
Filip Tehlarbfeae8c2020-06-23 20:35:58 +00001518class Ikev2Params(object):
1519 def config_params(self, params={}):
Filip Tehlar4f42a712020-07-01 08:56:59 +00001520 ec = VppEnum.vl_api_ipsec_crypto_alg_t
1521 ei = VppEnum.vl_api_ipsec_integ_alg_t
1522 self.vpp_enums = {
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001523 "AES-CBC-128": ec.IPSEC_API_CRYPTO_ALG_AES_CBC_128,
1524 "AES-CBC-192": ec.IPSEC_API_CRYPTO_ALG_AES_CBC_192,
1525 "AES-CBC-256": ec.IPSEC_API_CRYPTO_ALG_AES_CBC_256,
1526 "AES-GCM-16ICV-128": ec.IPSEC_API_CRYPTO_ALG_AES_GCM_128,
1527 "AES-GCM-16ICV-192": ec.IPSEC_API_CRYPTO_ALG_AES_GCM_192,
1528 "AES-GCM-16ICV-256": ec.IPSEC_API_CRYPTO_ALG_AES_GCM_256,
1529 "HMAC-SHA1-96": ei.IPSEC_API_INTEG_ALG_SHA1_96,
1530 "SHA2-256-128": ei.IPSEC_API_INTEG_ALG_SHA_256_128,
1531 "SHA2-384-192": ei.IPSEC_API_INTEG_ALG_SHA_384_192,
1532 "SHA2-512-256": ei.IPSEC_API_INTEG_ALG_SHA_512_256,
1533 }
Filip Tehlar4f42a712020-07-01 08:56:59 +00001534
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001535 dpd_disabled = True if "dpd_disabled" not in params else params["dpd_disabled"]
Filip Tehlar2008e312020-11-09 13:23:24 +00001536 if dpd_disabled:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001537 self.vapi.cli("ikev2 dpd disable")
1538 self.del_sa_from_responder = (
1539 False
1540 if "del_sa_from_responder" not in params
1541 else params["del_sa_from_responder"]
1542 )
1543 i_natt = False if "i_natt" not in params else params["i_natt"]
1544 r_natt = False if "r_natt" not in params else params["r_natt"]
1545 self.p = Profile(self, "pr1")
1546 self.ip6 = False if "ip6" not in params else params["ip6"]
Filip Tehlarbfeae8c2020-06-23 20:35:58 +00001547
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001548 if "auth" in params and params["auth"] == "rsa-sig":
1549 auth_method = "rsa-sig"
Klement Sekerab23ffd72021-05-31 16:08:53 +02001550 work_dir = f"{config.vpp_ws_dir}/src/plugins/ikev2/test/certs/"
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001551 self.vapi.ikev2_set_local_key(key_file=work_dir + params["server-key"])
Filip Tehlarbfeae8c2020-06-23 20:35:58 +00001552
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001553 client_file = work_dir + params["client-cert"]
1554 server_pem = open(work_dir + params["server-cert"]).read()
1555 client_priv = open(work_dir + params["client-key"]).read()
1556 client_priv = load_pem_private_key(
1557 str.encode(client_priv), None, default_backend()
1558 )
Filip Tehlarbfeae8c2020-06-23 20:35:58 +00001559 self.peer_cert = x509.load_pem_x509_certificate(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001560 str.encode(server_pem), default_backend()
1561 )
1562 self.p.add_auth(method="rsa-sig", data=str.encode(client_file))
Filip Tehlarbfeae8c2020-06-23 20:35:58 +00001563 auth_data = None
1564 else:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001565 auth_data = b"$3cr3tpa$$w0rd"
1566 self.p.add_auth(method="shared-key", data=auth_data)
1567 auth_method = "shared-key"
Filip Tehlarbfeae8c2020-06-23 20:35:58 +00001568 client_priv = None
1569
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001570 is_init = True if "is_initiator" not in params else params["is_initiator"]
1571 self.no_idr_auth = params.get("no_idr_in_auth", False)
Filip Tehlare7c83962020-09-23 11:20:12 +00001572
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001573 idr = {"id_type": "fqdn", "data": b"vpp.home"}
1574 idi = {"id_type": "fqdn", "data": b"roadwarrior.example.com"}
1575 r_id = self.idr = idr["data"]
1576 i_id = self.idi = idi["data"]
Filip Tehlare7c83962020-09-23 11:20:12 +00001577 if is_init:
Benoît Gannec7cceee2021-09-28 11:19:37 +02001578 # scapy is initiator, VPP is responder
Filip Tehlare7c83962020-09-23 11:20:12 +00001579 self.p.add_local_id(**idr)
1580 self.p.add_remote_id(**idi)
Benoît Gannec7cceee2021-09-28 11:19:37 +02001581 if self.no_idr_auth:
1582 r_id = None
Filip Tehlare7c83962020-09-23 11:20:12 +00001583 else:
Benoît Gannec7cceee2021-09-28 11:19:37 +02001584 # VPP is initiator, scapy is responder
Filip Tehlare7c83962020-09-23 11:20:12 +00001585 self.p.add_local_id(**idi)
Benoît Gannec7cceee2021-09-28 11:19:37 +02001586 if not self.no_idr_auth:
1587 self.p.add_remote_id(**idr)
Filip Tehlare7c83962020-09-23 11:20:12 +00001588
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001589 loc_ts = (
1590 {"start_addr": "10.10.10.0", "end_addr": "10.10.10.255"}
1591 if "loc_ts" not in params
1592 else params["loc_ts"]
1593 )
1594 rem_ts = (
1595 {"start_addr": "10.0.0.0", "end_addr": "10.0.0.255"}
1596 if "rem_ts" not in params
1597 else params["rem_ts"]
1598 )
Filip Tehlar84962d12020-09-08 06:08:05 +00001599 self.p.add_local_ts(**loc_ts)
1600 self.p.add_remote_ts(**rem_ts)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001601 if "responder" in params:
1602 self.p.add_responder(params["responder"])
1603 if "ike_transforms" in params:
1604 self.p.add_ike_transforms(params["ike_transforms"])
1605 if "esp_transforms" in params:
1606 self.p.add_esp_transforms(params["esp_transforms"])
Filip Tehlarbfeae8c2020-06-23 20:35:58 +00001607
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001608 udp_encap = False if "udp_encap" not in params else params["udp_encap"]
Filip Tehlar67b8a7f2020-11-06 11:00:42 +00001609 if udp_encap:
1610 self.p.set_udp_encap(True)
1611
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001612 if "responder_hostname" in params:
1613 hn = params["responder_hostname"]
Filip Tehlaraf2cc642021-02-22 16:15:51 +00001614 self.p.add_responder_hostname(hn)
1615
1616 # configure static dns record
1617 self.vapi.dns_name_server_add_del(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001618 is_ip6=0, is_add=1, server_address=IPv4Address("8.8.8.8").packed
1619 )
Filip Tehlaraf2cc642021-02-22 16:15:51 +00001620 self.vapi.dns_enable_disable(enable=1)
1621
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001622 cmd = "dns cache add {} {}".format(hn["hostname"], self.pg0.remote_ip4)
Filip Tehlaraf2cc642021-02-22 16:15:51 +00001623 self.vapi.cli(cmd)
1624
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001625 self.sa = IKEv2SA(
1626 self,
1627 i_id=i_id,
1628 r_id=r_id,
1629 is_initiator=is_init,
1630 id_type=self.p.local_id["id_type"],
1631 i_natt=i_natt,
1632 r_natt=r_natt,
1633 priv_key=client_priv,
1634 auth_method=auth_method,
1635 nonce=params.get("nonce"),
1636 auth_data=auth_data,
1637 udp_encap=udp_encap,
1638 local_ts=self.p.remote_ts,
1639 remote_ts=self.p.local_ts,
1640 )
Benoît Gannec7cceee2021-09-28 11:19:37 +02001641
Filip Tehlar68ad6252020-10-30 05:28:11 +00001642 if is_init:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001643 ike_crypto = (
1644 ("AES-CBC", 32) if "ike-crypto" not in params else params["ike-crypto"]
1645 )
1646 ike_integ = (
1647 "HMAC-SHA1-96" if "ike-integ" not in params else params["ike-integ"]
1648 )
1649 ike_dh = "2048MODPgr" if "ike-dh" not in params else params["ike-dh"]
Filip Tehlar4f42a712020-07-01 08:56:59 +00001650
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001651 esp_crypto = (
1652 ("AES-CBC", 32) if "esp-crypto" not in params else params["esp-crypto"]
1653 )
1654 esp_integ = (
1655 "HMAC-SHA1-96" if "esp-integ" not in params else params["esp-integ"]
1656 )
Filip Tehlar4f42a712020-07-01 08:56:59 +00001657
Filip Tehlar68ad6252020-10-30 05:28:11 +00001658 self.sa.set_ike_props(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001659 crypto=ike_crypto[0],
1660 crypto_key_len=ike_crypto[1],
1661 integ=ike_integ,
1662 prf="PRF_HMAC_SHA2_256",
1663 dh=ike_dh,
1664 )
Filip Tehlar68ad6252020-10-30 05:28:11 +00001665 self.sa.set_esp_props(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001666 crypto=esp_crypto[0], crypto_key_len=esp_crypto[1], integ=esp_integ
1667 )
Filip Tehlarbfeae8c2020-06-23 20:35:58 +00001668
1669
Filip Tehlar459d17b2020-07-06 15:40:08 +00001670class TestApi(VppTestCase):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001671 """Test IKEV2 API"""
1672
Filip Tehlar459d17b2020-07-06 15:40:08 +00001673 @classmethod
1674 def setUpClass(cls):
1675 super(TestApi, cls).setUpClass()
1676
1677 @classmethod
1678 def tearDownClass(cls):
1679 super(TestApi, cls).tearDownClass()
1680
1681 def tearDown(self):
1682 super(TestApi, self).tearDown()
1683 self.p1.remove_vpp_config()
1684 self.p2.remove_vpp_config()
1685 r = self.vapi.ikev2_profile_dump()
1686 self.assertEqual(len(r), 0)
1687
1688 def configure_profile(self, cfg):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001689 p = Profile(self, cfg["name"])
1690 p.add_local_id(id_type=cfg["loc_id"][0], data=cfg["loc_id"][1])
1691 p.add_remote_id(id_type=cfg["rem_id"][0], data=cfg["rem_id"][1])
1692 p.add_local_ts(**cfg["loc_ts"])
1693 p.add_remote_ts(**cfg["rem_ts"])
1694 p.add_responder(cfg["responder"])
1695 p.add_ike_transforms(cfg["ike_ts"])
1696 p.add_esp_transforms(cfg["esp_ts"])
1697 p.add_auth(**cfg["auth"])
1698 p.set_udp_encap(cfg["udp_encap"])
1699 p.set_ipsec_over_udp_port(cfg["ipsec_over_udp_port"])
1700 if "lifetime_data" in cfg:
1701 p.set_lifetime_data(cfg["lifetime_data"])
1702 if "tun_itf" in cfg:
1703 p.set_tunnel_interface(cfg["tun_itf"])
1704 if "natt_disabled" in cfg and cfg["natt_disabled"]:
Filip Tehlard7fc12f2020-10-30 04:47:44 +00001705 p.disable_natt()
Filip Tehlar459d17b2020-07-06 15:40:08 +00001706 p.add_vpp_config()
1707 return p
1708
1709 def test_profile_api(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001710 """test profile dump API"""
Filip Tehlar84962d12020-09-08 06:08:05 +00001711 loc_ts4 = {
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001712 "proto": 8,
1713 "start_port": 1,
1714 "end_port": 19,
1715 "start_addr": "3.3.3.2",
1716 "end_addr": "3.3.3.3",
1717 }
Filip Tehlar84962d12020-09-08 06:08:05 +00001718 rem_ts4 = {
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001719 "proto": 9,
1720 "start_port": 10,
1721 "end_port": 119,
1722 "start_addr": "4.5.76.80",
1723 "end_addr": "2.3.4.6",
1724 }
Filip Tehlar459d17b2020-07-06 15:40:08 +00001725
Filip Tehlar84962d12020-09-08 06:08:05 +00001726 loc_ts6 = {
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001727 "proto": 8,
1728 "start_port": 1,
1729 "end_port": 19,
1730 "start_addr": "ab::1",
1731 "end_addr": "ab::4",
1732 }
Filip Tehlar84962d12020-09-08 06:08:05 +00001733 rem_ts6 = {
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001734 "proto": 9,
1735 "start_port": 10,
1736 "end_port": 119,
1737 "start_addr": "cd::12",
1738 "end_addr": "cd::13",
1739 }
Filip Tehlar84962d12020-09-08 06:08:05 +00001740
Filip Tehlar459d17b2020-07-06 15:40:08 +00001741 conf = {
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001742 "p1": {
1743 "name": "p1",
1744 "natt_disabled": True,
1745 "loc_id": ("fqdn", b"vpp.home"),
1746 "rem_id": ("fqdn", b"roadwarrior.example.com"),
1747 "loc_ts": loc_ts4,
1748 "rem_ts": rem_ts4,
1749 "responder": {"sw_if_index": 0, "addr": "5.6.7.8"},
1750 "ike_ts": {
1751 "crypto_alg": 20,
1752 "crypto_key_size": 32,
1753 "integ_alg": 0,
1754 "dh_group": 1,
1755 },
1756 "esp_ts": {"crypto_alg": 13, "crypto_key_size": 24, "integ_alg": 2},
1757 "auth": {"method": "shared-key", "data": b"sharedkeydata"},
1758 "udp_encap": True,
1759 "ipsec_over_udp_port": 4501,
1760 "lifetime_data": {
1761 "lifetime": 123,
1762 "lifetime_maxdata": 20192,
1763 "lifetime_jitter": 9,
1764 "handover": 132,
1765 },
Filip Tehlar459d17b2020-07-06 15:40:08 +00001766 },
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001767 "p2": {
1768 "name": "p2",
1769 "loc_id": ("ip4-addr", b"192.168.2.1"),
1770 "rem_id": ("ip6-addr", b"abcd::1"),
1771 "loc_ts": loc_ts6,
1772 "rem_ts": rem_ts6,
1773 "responder": {"sw_if_index": 4, "addr": "def::10"},
1774 "ike_ts": {
1775 "crypto_alg": 12,
1776 "crypto_key_size": 16,
1777 "integ_alg": 3,
1778 "dh_group": 3,
1779 },
1780 "esp_ts": {"crypto_alg": 9, "crypto_key_size": 24, "integ_alg": 4},
1781 "auth": {"method": "shared-key", "data": b"sharedkeydata"},
1782 "udp_encap": False,
1783 "ipsec_over_udp_port": 4600,
1784 "tun_itf": 0,
1785 },
Filip Tehlar459d17b2020-07-06 15:40:08 +00001786 }
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001787 self.p1 = self.configure_profile(conf["p1"])
1788 self.p2 = self.configure_profile(conf["p2"])
Filip Tehlar459d17b2020-07-06 15:40:08 +00001789
1790 r = self.vapi.ikev2_profile_dump()
1791 self.assertEqual(len(r), 2)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001792 self.verify_profile(r[0].profile, conf["p1"])
1793 self.verify_profile(r[1].profile, conf["p2"])
Filip Tehlar459d17b2020-07-06 15:40:08 +00001794
1795 def verify_id(self, api_id, cfg_id):
1796 self.assertEqual(api_id.type, IDType.value(cfg_id[0]))
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001797 self.assertEqual(bytes(api_id.data, "ascii"), cfg_id[1])
Filip Tehlar459d17b2020-07-06 15:40:08 +00001798
1799 def verify_ts(self, api_ts, cfg_ts):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001800 self.assertEqual(api_ts.protocol_id, cfg_ts["proto"])
1801 self.assertEqual(api_ts.start_port, cfg_ts["start_port"])
1802 self.assertEqual(api_ts.end_port, cfg_ts["end_port"])
1803 self.assertEqual(api_ts.start_addr, ip_address(text_type(cfg_ts["start_addr"])))
1804 self.assertEqual(api_ts.end_addr, ip_address(text_type(cfg_ts["end_addr"])))
Filip Tehlar459d17b2020-07-06 15:40:08 +00001805
1806 def verify_responder(self, api_r, cfg_r):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001807 self.assertEqual(api_r.sw_if_index, cfg_r["sw_if_index"])
1808 self.assertEqual(api_r.addr, ip_address(cfg_r["addr"]))
Filip Tehlar459d17b2020-07-06 15:40:08 +00001809
1810 def verify_transforms(self, api_ts, cfg_ts):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001811 self.assertEqual(api_ts.crypto_alg, cfg_ts["crypto_alg"])
1812 self.assertEqual(api_ts.crypto_key_size, cfg_ts["crypto_key_size"])
1813 self.assertEqual(api_ts.integ_alg, cfg_ts["integ_alg"])
Filip Tehlar459d17b2020-07-06 15:40:08 +00001814
1815 def verify_ike_transforms(self, api_ts, cfg_ts):
1816 self.verify_transforms(api_ts, cfg_ts)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001817 self.assertEqual(api_ts.dh_group, cfg_ts["dh_group"])
Filip Tehlar459d17b2020-07-06 15:40:08 +00001818
1819 def verify_esp_transforms(self, api_ts, cfg_ts):
1820 self.verify_transforms(api_ts, cfg_ts)
1821
1822 def verify_auth(self, api_auth, cfg_auth):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001823 self.assertEqual(api_auth.method, AuthMethod.value(cfg_auth["method"]))
1824 self.assertEqual(api_auth.data, cfg_auth["data"])
1825 self.assertEqual(api_auth.data_len, len(cfg_auth["data"]))
Filip Tehlar459d17b2020-07-06 15:40:08 +00001826
1827 def verify_lifetime_data(self, p, ld):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001828 self.assertEqual(p.lifetime, ld["lifetime"])
1829 self.assertEqual(p.lifetime_maxdata, ld["lifetime_maxdata"])
1830 self.assertEqual(p.lifetime_jitter, ld["lifetime_jitter"])
1831 self.assertEqual(p.handover, ld["handover"])
Filip Tehlar459d17b2020-07-06 15:40:08 +00001832
1833 def verify_profile(self, ap, cp):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001834 self.assertEqual(ap.name, cp["name"])
1835 self.assertEqual(ap.udp_encap, cp["udp_encap"])
1836 self.verify_id(ap.loc_id, cp["loc_id"])
1837 self.verify_id(ap.rem_id, cp["rem_id"])
1838 self.verify_ts(ap.loc_ts, cp["loc_ts"])
1839 self.verify_ts(ap.rem_ts, cp["rem_ts"])
1840 self.verify_responder(ap.responder, cp["responder"])
1841 self.verify_ike_transforms(ap.ike_ts, cp["ike_ts"])
1842 self.verify_esp_transforms(ap.esp_ts, cp["esp_ts"])
1843 self.verify_auth(ap.auth, cp["auth"])
1844 natt_dis = False if "natt_disabled" not in cp else cp["natt_disabled"]
Filip Tehlard7fc12f2020-10-30 04:47:44 +00001845 self.assertTrue(natt_dis == ap.natt_disabled)
1846
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001847 if "lifetime_data" in cp:
1848 self.verify_lifetime_data(ap, cp["lifetime_data"])
1849 self.assertEqual(ap.ipsec_over_udp_port, cp["ipsec_over_udp_port"])
1850 if "tun_itf" in cp:
1851 self.assertEqual(ap.tun_itf, cp["tun_itf"])
Filip Tehlar459d17b2020-07-06 15:40:08 +00001852 else:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001853 self.assertEqual(ap.tun_itf, 0xFFFFFFFF)
Filip Tehlar459d17b2020-07-06 15:40:08 +00001854
1855
Andrew Yourtchenko8dc0d482021-01-29 13:17:19 +00001856@tag_fixme_vpp_workers
Filip Tehlar027d8132020-12-04 17:38:11 +00001857class TestResponderBehindNAT(TemplateResponder, Ikev2Params):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001858 """test responder - responder behind NAT"""
Filip Tehlar027d8132020-12-04 17:38:11 +00001859
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001860 IKE_NODE_SUFFIX = "ip4-natt"
Filip Tehlarfab5e7f2021-01-14 13:32:01 +00001861
Filip Tehlar027d8132020-12-04 17:38:11 +00001862 def config_tc(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001863 self.config_params({"r_natt": True})
Filip Tehlar027d8132020-12-04 17:38:11 +00001864
1865
Andrew Yourtchenko8dc0d482021-01-29 13:17:19 +00001866@tag_fixme_vpp_workers
Filip Tehlar18107c92020-12-01 14:51:09 +00001867class TestInitiatorNATT(TemplateInitiator, Ikev2Params):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001868 """test ikev2 initiator - NAT traversal (intitiator behind NAT)"""
Filip Tehlar18107c92020-12-01 14:51:09 +00001869
1870 def config_tc(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001871 self.config_params(
1872 {
1873 "i_natt": True,
1874 "is_initiator": False, # seen from test case perspective
1875 # thus vpp is initiator
1876 "responder": {
1877 "sw_if_index": self.pg0.sw_if_index,
1878 "addr": self.pg0.remote_ip4,
1879 },
1880 "ike-crypto": ("AES-GCM-16ICV", 32),
1881 "ike-integ": "NULL",
1882 "ike-dh": "3072MODPgr",
1883 "ike_transforms": {
1884 "crypto_alg": 20, # "aes-gcm-16"
1885 "crypto_key_size": 256,
1886 "dh_group": 15, # "modp-3072"
1887 },
1888 "esp_transforms": {
1889 "crypto_alg": 12, # "aes-cbc"
1890 "crypto_key_size": 256,
1891 # "hmac-sha2-256-128"
1892 "integ_alg": 12,
1893 },
1894 }
1895 )
Filip Tehlar18107c92020-12-01 14:51:09 +00001896
1897
Andrew Yourtchenko8dc0d482021-01-29 13:17:19 +00001898@tag_fixme_vpp_workers
Filip Tehlare7c83962020-09-23 11:20:12 +00001899class TestInitiatorPsk(TemplateInitiator, Ikev2Params):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001900 """test ikev2 initiator - pre shared key auth"""
Filip Tehlaredf29002020-10-10 04:39:11 +00001901
Filip Tehlare7c83962020-09-23 11:20:12 +00001902 def config_tc(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001903 self.config_params(
1904 {
1905 "is_initiator": False, # seen from test case perspective
1906 # thus vpp is initiator
1907 "ike-crypto": ("AES-GCM-16ICV", 32),
1908 "ike-integ": "NULL",
1909 "ike-dh": "3072MODPgr",
1910 "ike_transforms": {
1911 "crypto_alg": 20, # "aes-gcm-16"
1912 "crypto_key_size": 256,
1913 "dh_group": 15, # "modp-3072"
1914 },
1915 "esp_transforms": {
1916 "crypto_alg": 12, # "aes-cbc"
1917 "crypto_key_size": 256,
1918 # "hmac-sha2-256-128"
1919 "integ_alg": 12,
1920 },
1921 "responder_hostname": {
1922 "hostname": "vpp.responder.org",
1923 "sw_if_index": self.pg0.sw_if_index,
1924 },
1925 }
1926 )
Filip Tehlare7c83962020-09-23 11:20:12 +00001927
1928
Andrew Yourtchenko8dc0d482021-01-29 13:17:19 +00001929@tag_fixme_vpp_workers
Filip Tehlar38340fa2020-11-19 21:34:48 +00001930class TestInitiatorRequestWindowSize(TestInitiatorPsk):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001931 """test initiator - request window size (1)"""
Filip Tehlar38340fa2020-11-19 21:34:48 +00001932
1933 def rekey_respond(self, req, update_child_sa_data):
1934 ih = self.get_ike_header(req)
1935 plain = self.sa.hmac_and_decrypt(ih)
1936 sa = ikev2.IKEv2_payload_SA(plain)
1937 if update_child_sa_data:
1938 prop = sa[ikev2.IKEv2_payload_Proposal]
1939 self.sa.i_nonce = sa[ikev2.IKEv2_payload_Nonce].load
1940 self.sa.r_nonce = self.sa.i_nonce
1941 self.sa.child_sas[0].ispi = prop.SPI
1942 self.sa.child_sas[0].rspi = prop.SPI
1943 self.sa.calc_child_keys()
1944
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001945 header = ikev2.IKEv2(
1946 init_SPI=self.sa.ispi,
1947 resp_SPI=self.sa.rspi,
1948 flags="Response",
1949 exch_type=36,
1950 id=ih.id,
1951 next_payload="Encrypted",
1952 )
1953 resp = self.encrypt_ike_msg(header, sa, "SA")
1954 packet = self.create_packet(
1955 self.pg0, resp, self.sa.sport, self.sa.dport, self.sa.natt, self.ip6
1956 )
Filip Tehlar38340fa2020-11-19 21:34:48 +00001957 self.send_and_assert_no_replies(self.pg0, packet)
1958
1959 def test_initiator(self):
1960 super(TestInitiatorRequestWindowSize, self).test_initiator()
1961 self.pg0.enable_capture()
1962 self.pg_start()
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001963 ispi = int.from_bytes(self.sa.child_sas[0].ispi, "little")
Filip Tehlar38340fa2020-11-19 21:34:48 +00001964 self.vapi.ikev2_initiate_rekey_child_sa(ispi=ispi)
1965 self.vapi.ikev2_initiate_rekey_child_sa(ispi=ispi)
1966 capture = self.pg0.get_capture(2)
1967
1968 # reply in reverse order
1969 self.rekey_respond(capture[1], True)
1970 self.rekey_respond(capture[0], False)
1971
1972 # verify that only the second request was accepted
1973 self.verify_ike_sas()
1974 self.verify_ipsec_sas(is_rekey=True)
1975
1976
Andrew Yourtchenko8dc0d482021-01-29 13:17:19 +00001977@tag_fixme_vpp_workers
Filip Tehlar68ad6252020-10-30 05:28:11 +00001978class TestInitiatorRekey(TestInitiatorPsk):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001979 """test ikev2 initiator - rekey"""
Filip Tehlar68ad6252020-10-30 05:28:11 +00001980
1981 def rekey_from_initiator(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001982 ispi = int.from_bytes(self.sa.child_sas[0].ispi, "little")
Filip Tehlar68ad6252020-10-30 05:28:11 +00001983 self.pg0.enable_capture()
1984 self.pg_start()
1985 self.vapi.ikev2_initiate_rekey_child_sa(ispi=ispi)
1986 capture = self.pg0.get_capture(1)
1987 ih = self.get_ike_header(capture[0])
1988 self.assertEqual(ih.exch_type, 36) # CHILD_SA
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001989 self.assertNotIn("Response", ih.flags)
1990 self.assertIn("Initiator", ih.flags)
Filip Tehlar68ad6252020-10-30 05:28:11 +00001991 plain = self.sa.hmac_and_decrypt(ih)
1992 sa = ikev2.IKEv2_payload_SA(plain)
1993 prop = sa[ikev2.IKEv2_payload_Proposal]
Filip Tehlar68ad6252020-10-30 05:28:11 +00001994 self.sa.i_nonce = sa[ikev2.IKEv2_payload_Nonce].load
1995 self.sa.r_nonce = self.sa.i_nonce
1996 # update new responder SPI
1997 self.sa.child_sas[0].ispi = prop.SPI
1998 self.sa.child_sas[0].rspi = prop.SPI
1999 self.sa.calc_child_keys()
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002000 header = ikev2.IKEv2(
2001 init_SPI=self.sa.ispi,
2002 resp_SPI=self.sa.rspi,
2003 flags="Response",
2004 exch_type=36,
2005 id=ih.id,
2006 next_payload="Encrypted",
2007 )
2008 resp = self.encrypt_ike_msg(header, sa, "SA")
2009 packet = self.create_packet(
2010 self.pg0, resp, self.sa.sport, self.sa.dport, self.sa.natt, self.ip6
2011 )
Filip Tehlar68ad6252020-10-30 05:28:11 +00002012 self.send_and_assert_no_replies(self.pg0, packet)
2013
2014 def test_initiator(self):
2015 super(TestInitiatorRekey, self).test_initiator()
2016 self.rekey_from_initiator()
2017 self.verify_ike_sas()
2018 self.verify_ipsec_sas(is_rekey=True)
2019
2020
Andrew Yourtchenko8dc0d482021-01-29 13:17:19 +00002021@tag_fixme_vpp_workers
Filip Tehlaredf29002020-10-10 04:39:11 +00002022class TestInitiatorDelSAFromResponder(TemplateInitiator, Ikev2Params):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002023 """test ikev2 initiator - delete IKE SA from responder"""
Filip Tehlaredf29002020-10-10 04:39:11 +00002024
2025 def config_tc(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002026 self.config_params(
2027 {
2028 "del_sa_from_responder": True,
2029 "is_initiator": False, # seen from test case perspective
2030 # thus vpp is initiator
2031 "responder": {
2032 "sw_if_index": self.pg0.sw_if_index,
2033 "addr": self.pg0.remote_ip4,
2034 },
2035 "ike-crypto": ("AES-GCM-16ICV", 32),
2036 "ike-integ": "NULL",
2037 "ike-dh": "3072MODPgr",
2038 "ike_transforms": {
2039 "crypto_alg": 20, # "aes-gcm-16"
2040 "crypto_key_size": 256,
2041 "dh_group": 15, # "modp-3072"
2042 },
2043 "esp_transforms": {
2044 "crypto_alg": 12, # "aes-cbc"
2045 "crypto_key_size": 256,
2046 # "hmac-sha2-256-128"
2047 "integ_alg": 12,
2048 },
2049 "no_idr_in_auth": True,
2050 }
2051 )
Filip Tehlaredf29002020-10-10 04:39:11 +00002052
2053
Andrew Yourtchenko8dc0d482021-01-29 13:17:19 +00002054@tag_fixme_vpp_workers
Filip Tehlar027d8132020-12-04 17:38:11 +00002055class TestResponderInitBehindNATT(TemplateResponder, Ikev2Params):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002056 """test ikev2 responder - initiator behind NAT"""
Filip Tehlarfab5e7f2021-01-14 13:32:01 +00002057
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002058 IKE_NODE_SUFFIX = "ip4-natt"
Filip Tehlarfab5e7f2021-01-14 13:32:01 +00002059
Filip Tehlarbfeae8c2020-06-23 20:35:58 +00002060 def config_tc(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002061 self.config_params({"i_natt": True})
Filip Tehlarbfeae8c2020-06-23 20:35:58 +00002062
2063
Andrew Yourtchenko8dc0d482021-01-29 13:17:19 +00002064@tag_fixme_vpp_workers
Filip Tehlarbfeae8c2020-06-23 20:35:58 +00002065class TestResponderPsk(TemplateResponder, Ikev2Params):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002066 """test ikev2 responder - pre shared key auth"""
2067
Filip Tehlarbfeae8c2020-06-23 20:35:58 +00002068 def config_tc(self):
2069 self.config_params()
2070
2071
Andrew Yourtchenko8dc0d482021-01-29 13:17:19 +00002072@tag_fixme_vpp_workers
Filip Tehlar2008e312020-11-09 13:23:24 +00002073class TestResponderDpd(TestResponderPsk):
2074 """
2075 Dead peer detection test
2076 """
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002077
Filip Tehlar2008e312020-11-09 13:23:24 +00002078 def config_tc(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002079 self.config_params({"dpd_disabled": False})
Filip Tehlar2008e312020-11-09 13:23:24 +00002080
2081 def tearDown(self):
2082 pass
2083
2084 def test_responder(self):
2085 self.vapi.ikev2_profile_set_liveness(period=2, max_retries=1)
2086 super(TestResponderDpd, self).test_responder()
2087 self.pg0.enable_capture()
2088 self.pg_start()
2089 # capture empty request but don't reply
2090 capture = self.pg0.get_capture(expected_count=1, timeout=5)
2091 ih = self.get_ike_header(capture[0])
2092 self.assertEqual(ih.exch_type, 37) # INFORMATIONAL
2093 plain = self.sa.hmac_and_decrypt(ih)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002094 self.assertEqual(plain, b"")
Filip Tehlar2008e312020-11-09 13:23:24 +00002095 # wait for SA expiration
2096 time.sleep(3)
2097 ike_sas = self.vapi.ikev2_sa_dump()
2098 self.assertEqual(len(ike_sas), 0)
2099 ipsec_sas = self.vapi.ipsec_sa_dump()
2100 self.assertEqual(len(ipsec_sas), 0)
2101
2102
Andrew Yourtchenko8dc0d482021-01-29 13:17:19 +00002103@tag_fixme_vpp_workers
Filip Tehlar68ad6252020-10-30 05:28:11 +00002104class TestResponderRekey(TestResponderPsk):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002105 """test ikev2 responder - rekey"""
Filip Tehlar68ad6252020-10-30 05:28:11 +00002106
Atzm Watanabec65921f2022-08-12 14:29:31 +09002107 WITH_KEX = False
2108
Atzm Watanabe7e6ffba2022-08-09 14:00:03 +09002109 def send_rekey_from_initiator(self):
Atzm Watanabec65921f2022-08-12 14:29:31 +09002110 if self.WITH_KEX:
2111 self.sa.generate_dh_data()
2112 packet = self.create_rekey_request(kex=self.WITH_KEX)
Filip Tehlar68ad6252020-10-30 05:28:11 +00002113 self.pg0.add_stream(packet)
2114 self.pg0.enable_capture()
2115 self.pg_start()
2116 capture = self.pg0.get_capture(1)
Atzm Watanabe7e6ffba2022-08-09 14:00:03 +09002117 return capture
2118
2119 def process_rekey_response(self, capture):
Filip Tehlar68ad6252020-10-30 05:28:11 +00002120 ih = self.get_ike_header(capture[0])
2121 plain = self.sa.hmac_and_decrypt(ih)
2122 sa = ikev2.IKEv2_payload_SA(plain)
2123 prop = sa[ikev2.IKEv2_payload_Proposal]
Filip Tehlar68ad6252020-10-30 05:28:11 +00002124 self.sa.r_nonce = sa[ikev2.IKEv2_payload_Nonce].load
2125 # update new responder SPI
2126 self.sa.child_sas[0].rspi = prop.SPI
Atzm Watanabec65921f2022-08-12 14:29:31 +09002127 if self.WITH_KEX:
2128 self.sa.r_dh_data = sa[ikev2.IKEv2_payload_KE].load
2129 self.sa.complete_dh_data()
2130 self.sa.calc_child_keys(kex=self.WITH_KEX)
Filip Tehlar68ad6252020-10-30 05:28:11 +00002131
2132 def test_responder(self):
2133 super(TestResponderRekey, self).test_responder()
Atzm Watanabe7e6ffba2022-08-09 14:00:03 +09002134 self.process_rekey_response(self.send_rekey_from_initiator())
Filip Tehlar68ad6252020-10-30 05:28:11 +00002135 self.verify_ike_sas()
2136 self.verify_ipsec_sas(is_rekey=True)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002137 self.assert_counter(1, "rekey_req", "ip4")
Filip Tehlar68d27532021-01-25 10:09:27 +00002138 r = self.vapi.ikev2_sa_dump()
2139 self.assertEqual(r[0].sa.stats.n_rekey_req, 1)
Filip Tehlar68ad6252020-10-30 05:28:11 +00002140
2141
Atzm Watanabe7e6ffba2022-08-09 14:00:03 +09002142@tag_fixme_vpp_workers
2143class TestResponderRekeyRepeat(TestResponderRekey):
2144 """test ikev2 responder - rekey repeat"""
2145
2146 def test_responder(self):
2147 super(TestResponderRekeyRepeat, self).test_responder()
2148 # rekey request is not accepted until old IPsec SA is expired
2149 capture = self.send_rekey_from_initiator()
2150 ih = self.get_ike_header(capture[0])
2151 plain = self.sa.hmac_and_decrypt(ih)
2152 notify = ikev2.IKEv2_payload_Notify(plain)
2153 self.assertEqual(notify.type, 43)
2154 self.assertEqual(len(self.vapi.ipsec_sa_dump()), 3)
2155 # rekey request is accepted after old IPsec SA was expired
2156 for _ in range(50):
2157 if len(self.vapi.ipsec_sa_dump()) != 3:
2158 break
2159 time.sleep(0.2)
2160 else:
2161 self.fail("old IPsec SA not expired")
2162 self.process_rekey_response(self.send_rekey_from_initiator())
Atzm Watanabe7e6ffba2022-08-09 14:00:03 +09002163 self.verify_ike_sas()
2164 self.verify_ipsec_sas(sa_count=3)
2165
2166
Atzm Watanabec65921f2022-08-12 14:29:31 +09002167@tag_fixme_vpp_workers
2168class TestResponderRekeyKEX(TestResponderRekey):
2169 """test ikev2 responder - rekey with key exchange"""
2170
2171 WITH_KEX = True
2172
2173
2174@tag_fixme_vpp_workers
2175class TestResponderRekeyRepeatKEX(TestResponderRekeyRepeat):
2176 """test ikev2 responder - rekey repeat with key exchange"""
2177
2178 WITH_KEX = True
2179
2180
Dave Wallace670724c2022-09-20 21:52:18 -04002181@tag_fixme_ubuntu2204
2182@tag_fixme_debian11
Filip Tehlard28196f2021-01-27 18:08:21 +00002183class TestResponderVrf(TestResponderPsk, Ikev2Params):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002184 """test ikev2 responder - non-default table id"""
Filip Tehlard28196f2021-01-27 18:08:21 +00002185
2186 @classmethod
2187 def setUpClass(cls):
2188 import scapy.contrib.ikev2 as _ikev2
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002189
2190 globals()["ikev2"] = _ikev2
Filip Tehlard28196f2021-01-27 18:08:21 +00002191 super(IkePeer, cls).setUpClass()
Dave Wallace670724c2022-09-20 21:52:18 -04002192 if (is_distro_ubuntu2204 == True or is_distro_debian11 == True) and not hasattr(
2193 cls, "vpp"
2194 ):
2195 return
Filip Tehlard28196f2021-01-27 18:08:21 +00002196 cls.create_pg_interfaces(range(1))
2197 cls.vapi.cli("ip table add 1")
2198 cls.vapi.cli("set interface ip table pg0 1")
2199 for i in cls.pg_interfaces:
2200 i.admin_up()
2201 i.config_ip4()
2202 i.resolve_arp()
2203 i.config_ip6()
2204 i.resolve_ndp()
2205
2206 def config_tc(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002207 self.config_params({"dpd_disabled": False})
Filip Tehlard28196f2021-01-27 18:08:21 +00002208
2209 def test_responder(self):
2210 self.vapi.ikev2_profile_set_liveness(period=2, max_retries=1)
2211 super(TestResponderVrf, self).test_responder()
2212 self.pg0.enable_capture()
2213 self.pg_start()
2214 capture = self.pg0.get_capture(expected_count=1, timeout=5)
2215 ih = self.get_ike_header(capture[0])
2216 self.assertEqual(ih.exch_type, 37) # INFORMATIONAL
2217 plain = self.sa.hmac_and_decrypt(ih)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002218 self.assertEqual(plain, b"")
Filip Tehlard28196f2021-01-27 18:08:21 +00002219
2220
Andrew Yourtchenko8dc0d482021-01-29 13:17:19 +00002221@tag_fixme_vpp_workers
Filip Tehlarbfeae8c2020-06-23 20:35:58 +00002222class TestResponderRsaSign(TemplateResponder, Ikev2Params):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002223 """test ikev2 responder - cert based auth"""
2224
Filip Tehlarbfeae8c2020-06-23 20:35:58 +00002225 def config_tc(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002226 self.config_params(
2227 {
2228 "udp_encap": True,
2229 "auth": "rsa-sig",
2230 "server-key": "server-key.pem",
2231 "client-key": "client-key.pem",
2232 "client-cert": "client-cert.pem",
2233 "server-cert": "server-cert.pem",
2234 }
2235 )
Filip Tehlarbfeae8c2020-06-23 20:35:58 +00002236
Filip Tehlar4f42a712020-07-01 08:56:59 +00002237
Andrew Yourtchenko8dc0d482021-01-29 13:17:19 +00002238@tag_fixme_vpp_workers
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002239class Test_IKE_AES_CBC_128_SHA256_128_MODP2048_ESP_AES_CBC_192_SHA_384_192(
2240 TemplateResponder, Ikev2Params
2241):
Filip Tehlar4f42a712020-07-01 08:56:59 +00002242 """
2243 IKE:AES_CBC_128_SHA256_128,DH=modp2048 ESP:AES_CBC_192_SHA_384_192
2244 """
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002245
Filip Tehlar4f42a712020-07-01 08:56:59 +00002246 def config_tc(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002247 self.config_params(
2248 {
2249 "ike-crypto": ("AES-CBC", 16),
2250 "ike-integ": "SHA2-256-128",
2251 "esp-crypto": ("AES-CBC", 24),
2252 "esp-integ": "SHA2-384-192",
2253 "ike-dh": "2048MODPgr",
2254 "nonce": os.urandom(256),
2255 "no_idr_in_auth": True,
2256 }
2257 )
Filip Tehlar4f42a712020-07-01 08:56:59 +00002258
2259
Andrew Yourtchenko8dc0d482021-01-29 13:17:19 +00002260@tag_fixme_vpp_workers
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002261class TestAES_CBC_128_SHA256_128_MODP3072_ESP_AES_GCM_16(
2262 TemplateResponder, Ikev2Params
2263):
Filip Tehlarfab5e7f2021-01-14 13:32:01 +00002264
Filip Tehlar4f42a712020-07-01 08:56:59 +00002265 """
2266 IKE:AES_CBC_128_SHA256_128,DH=modp3072 ESP:AES_GCM_16
2267 """
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002268
Filip Tehlar4f42a712020-07-01 08:56:59 +00002269 def config_tc(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002270 self.config_params(
2271 {
2272 "ike-crypto": ("AES-CBC", 32),
2273 "ike-integ": "SHA2-256-128",
2274 "esp-crypto": ("AES-GCM-16ICV", 32),
2275 "esp-integ": "NULL",
2276 "ike-dh": "3072MODPgr",
2277 }
2278 )
Filip Tehlar4f42a712020-07-01 08:56:59 +00002279
2280
Andrew Yourtchenko8dc0d482021-01-29 13:17:19 +00002281@tag_fixme_vpp_workers
Filip Tehlara7b963d2020-07-08 13:25:34 +00002282class Test_IKE_AES_GCM_16_256(TemplateResponder, Ikev2Params):
2283 """
2284 IKE:AES_GCM_16_256
2285 """
Filip Tehlarfab5e7f2021-01-14 13:32:01 +00002286
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002287 IKE_NODE_SUFFIX = "ip6"
Filip Tehlarfab5e7f2021-01-14 13:32:01 +00002288
Filip Tehlara7b963d2020-07-08 13:25:34 +00002289 def config_tc(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002290 self.config_params(
2291 {
2292 "del_sa_from_responder": True,
2293 "ip6": True,
2294 "natt": True,
2295 "ike-crypto": ("AES-GCM-16ICV", 32),
2296 "ike-integ": "NULL",
2297 "ike-dh": "2048MODPgr",
2298 "loc_ts": {"start_addr": "ab:cd::0", "end_addr": "ab:cd::10"},
2299 "rem_ts": {"start_addr": "11::0", "end_addr": "11::100"},
2300 }
2301 )
Filip Tehlara7b963d2020-07-08 13:25:34 +00002302
2303
Andrew Yourtchenko8dc0d482021-01-29 13:17:19 +00002304@tag_fixme_vpp_workers
Filip Tehlar2008e312020-11-09 13:23:24 +00002305class TestInitiatorKeepaliveMsg(TestInitiatorPsk):
2306 """
2307 Test for keep alive messages
2308 """
2309
2310 def send_empty_req_from_responder(self):
Filip Tehlar38340fa2020-11-19 21:34:48 +00002311 packet = self.create_empty_request()
Filip Tehlar2008e312020-11-09 13:23:24 +00002312 self.pg0.add_stream(packet)
2313 self.pg0.enable_capture()
2314 self.pg_start()
2315 capture = self.pg0.get_capture(1)
2316 ih = self.get_ike_header(capture[0])
2317 self.assertEqual(ih.id, self.sa.msg_id)
2318 plain = self.sa.hmac_and_decrypt(ih)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002319 self.assertEqual(plain, b"")
2320 self.assert_counter(1, "keepalive", "ip4")
Filip Tehlar68d27532021-01-25 10:09:27 +00002321 r = self.vapi.ikev2_sa_dump()
2322 self.assertEqual(1, r[0].sa.stats.n_keepalives)
Filip Tehlar2008e312020-11-09 13:23:24 +00002323
2324 def test_initiator(self):
2325 super(TestInitiatorKeepaliveMsg, self).test_initiator()
2326 self.send_empty_req_from_responder()
2327
2328
Filip Tehlar558607d2020-07-16 07:25:56 +00002329class TestMalformedMessages(TemplateResponder, Ikev2Params):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002330 """malformed packet test"""
Filip Tehlar558607d2020-07-16 07:25:56 +00002331
2332 def tearDown(self):
2333 pass
2334
2335 def config_tc(self):
2336 self.config_params()
2337
Filip Tehlar558607d2020-07-16 07:25:56 +00002338 def create_ike_init_msg(self, length=None, payload=None):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002339 msg = ikev2.IKEv2(
2340 length=length,
2341 init_SPI="\x11" * 8,
2342 flags="Initiator",
2343 exch_type="IKE_SA_INIT",
2344 )
Filip Tehlar558607d2020-07-16 07:25:56 +00002345 if payload is not None:
2346 msg /= payload
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002347 return self.create_packet(self.pg0, msg, self.sa.sport, self.sa.dport)
Filip Tehlar558607d2020-07-16 07:25:56 +00002348
2349 def verify_bad_packet_length(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002350 ike_msg = self.create_ike_init_msg(length=0xDEAD)
Filip Tehlar558607d2020-07-16 07:25:56 +00002351 self.send_and_assert_no_replies(self.pg0, ike_msg * self.pkt_count)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002352 self.assert_counter(self.pkt_count, "bad_length")
Filip Tehlar558607d2020-07-16 07:25:56 +00002353
2354 def verify_bad_sa_payload_length(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002355 p = ikev2.IKEv2_payload_SA(length=0xDEAD)
Filip Tehlar558607d2020-07-16 07:25:56 +00002356 ike_msg = self.create_ike_init_msg(payload=p)
2357 self.send_and_assert_no_replies(self.pg0, ike_msg * self.pkt_count)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002358 self.assert_counter(self.pkt_count, "malformed_packet")
Filip Tehlar558607d2020-07-16 07:25:56 +00002359
2360 def test_responder(self):
2361 self.pkt_count = 254
2362 self.verify_bad_packet_length()
2363 self.verify_bad_sa_payload_length()
2364
2365
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02002366if __name__ == "__main__":
Filip Tehlar12b517b2020-04-26 18:05:05 +00002367 unittest.main(testRunner=VppTestRunner)