aboutsummaryrefslogtreecommitdiffstats
path: root/test/test_ikev2.py
diff options
context:
space:
mode:
authorAtzm Watanabe <atzmism@gmail.com>2022-08-12 14:29:31 +0900
committerBeno�t Ganne <bganne@cisco.com>2022-08-18 08:03:13 +0000
commitc65921f7744a0da09ede876b6588628e3a188529 (patch)
treefb004fb74260e71a18d245d691c78cc81bb37889 /test/test_ikev2.py
parent138f65c5b7796c6401cde6ff92edc85f02c367a4 (diff)
ikev2: accept key exchange on CREATE_CHILD_SA
In RFC 7296, CREATE_CHILD_SA Exchange may contain the KE payload to enable stronger guarantees of forward secrecy. When the KEi payload is included in the CREATE_CHILD_SA request, responder should reply with the KEr payload and complete the key exchange, in accordance with the RFC. Type: improvement Signed-off-by: Atzm Watanabe <atzmism@gmail.com> Change-Id: I13cf6cf24359c11c3366757e585195bb7e999638
Diffstat (limited to 'test/test_ikev2.py')
-rw-r--r--test/test_ikev2.py62
1 files changed, 53 insertions, 9 deletions
diff --git a/test/test_ikev2.py b/test/test_ikev2.py
index 3c588719581..ffddc79dbcf 100644
--- a/test/test_ikev2.py
+++ b/test/test_ikev2.py
@@ -296,9 +296,11 @@ class IKEv2SA(object):
def complete_dh_data(self):
self.dh_shared_secret = self.compute_secret()
- def calc_child_keys(self):
+ def calc_child_keys(self, kex=False):
prf = self.ike_prf_alg.mod()
s = self.i_nonce + self.r_nonce
+ if kex:
+ s = self.dh_shared_secret + s
c = self.child_sas[0]
encr_key_len = self.esp_crypto_key_len
@@ -625,8 +627,8 @@ class IkePeer(VppTestCase):
node_name = "/err/ikev2-%s/" % version + name
self.assertEqual(count, self.statistics.get_err_counter(node_name))
- def create_rekey_request(self):
- sa, first_payload = self.generate_auth_payload(is_rekey=True)
+ def create_rekey_request(self, kex=False):
+ sa, first_payload = self.generate_auth_payload(is_rekey=True, kex=kex)
header = ikev2.IKEv2(
init_SPI=self.sa.ispi,
resp_SPI=self.sa.rspi,
@@ -1345,9 +1347,10 @@ class TemplateResponder(IkePeer):
capture = self.pg0.get_capture(1)
self.verify_sa_init(capture[0])
- def generate_auth_payload(self, last_payload=None, is_rekey=False):
+ def generate_auth_payload(self, last_payload=None, is_rekey=False, kex=False):
tr_attr = self.sa.esp_crypto_attr()
last_payload = last_payload or "Notify"
+ trans_nb = 4
trans = (
ikev2.IKEv2_payload_Transform(
transform_type="Encryption",
@@ -1366,9 +1369,20 @@ class TemplateResponder(IkePeer):
)
)
+ if kex:
+ trans_nb += 1
+ trans /= ikev2.IKEv2_payload_Transform(
+ transform_type="GroupDesc", transform_id=self.sa.ike_dh
+ )
+
c = self.sa.child_sas[0]
props = ikev2.IKEv2_payload_Proposal(
- proposal=1, proto="ESP", SPIsize=4, SPI=c.ispi, trans_nb=4, trans=trans
+ proposal=1,
+ proto="ESP",
+ SPIsize=4,
+ SPI=c.ispi,
+ trans_nb=trans_nb,
+ trans=trans,
)
tsi, tsr = self.sa.generate_ts(self.p.ts_is_ip4)
@@ -1389,8 +1403,18 @@ class TemplateResponder(IkePeer):
if is_rekey:
first_payload = "Nonce"
+ if kex:
+ head = ikev2.IKEv2_payload_Nonce(
+ load=self.sa.i_nonce, next_payload="KE"
+ ) / ikev2.IKEv2_payload_KE(
+ group=self.sa.ike_dh, load=self.sa.my_dh_pub_key, next_payload="SA"
+ )
+ else:
+ head = ikev2.IKEv2_payload_Nonce(
+ load=self.sa.i_nonce, next_payload="SA"
+ )
plain = (
- ikev2.IKEv2_payload_Nonce(load=self.sa.i_nonce, next_payload="SA")
+ head
/ plain
/ ikev2.IKEv2_payload_Notify(
type="REKEY_SA",
@@ -2079,8 +2103,12 @@ class TestResponderDpd(TestResponderPsk):
class TestResponderRekey(TestResponderPsk):
"""test ikev2 responder - rekey"""
+ WITH_KEX = False
+
def send_rekey_from_initiator(self):
- packet = self.create_rekey_request()
+ if self.WITH_KEX:
+ self.sa.generate_dh_data()
+ packet = self.create_rekey_request(kex=self.WITH_KEX)
self.pg0.add_stream(packet)
self.pg0.enable_capture()
self.pg_start()
@@ -2095,11 +2123,14 @@ class TestResponderRekey(TestResponderPsk):
self.sa.r_nonce = sa[ikev2.IKEv2_payload_Nonce].load
# update new responder SPI
self.sa.child_sas[0].rspi = prop.SPI
+ if self.WITH_KEX:
+ self.sa.r_dh_data = sa[ikev2.IKEv2_payload_KE].load
+ self.sa.complete_dh_data()
+ self.sa.calc_child_keys(kex=self.WITH_KEX)
def test_responder(self):
super(TestResponderRekey, self).test_responder()
self.process_rekey_response(self.send_rekey_from_initiator())
- self.sa.calc_child_keys()
self.verify_ike_sas()
self.verify_ipsec_sas(is_rekey=True)
self.assert_counter(1, "rekey_req", "ip4")
@@ -2128,11 +2159,24 @@ class TestResponderRekeyRepeat(TestResponderRekey):
else:
self.fail("old IPsec SA not expired")
self.process_rekey_response(self.send_rekey_from_initiator())
- self.sa.calc_child_keys()
self.verify_ike_sas()
self.verify_ipsec_sas(sa_count=3)
+@tag_fixme_vpp_workers
+class TestResponderRekeyKEX(TestResponderRekey):
+ """test ikev2 responder - rekey with key exchange"""
+
+ WITH_KEX = True
+
+
+@tag_fixme_vpp_workers
+class TestResponderRekeyRepeatKEX(TestResponderRekeyRepeat):
+ """test ikev2 responder - rekey repeat with key exchange"""
+
+ WITH_KEX = True
+
+
class TestResponderVrf(TestResponderPsk, Ikev2Params):
"""test ikev2 responder - non-default table id"""