Ipsec: Always generate ikey 25/31325/7
authorVratko Polak <vrpolak@cisco.com>
Mon, 22 Feb 2021 13:43:46 +0000 (14:43 +0100)
committerVratko Polak <vrpolak@cisco.com>
Mon, 22 Feb 2021 18:56:38 +0000 (18:56 +0000)
Some tests use a crypto algorithm with no integrity algorithm.
Generate empty binary strings as fake integrity keys
to keep return values of low level methods consistent.

+ Add return_keys argument to avoid returning long lists.
+ Improve various docstrings.

Change-Id: Idae1877bdde32d194ce4e3bb3053c8dba39d377a
Signed-off-by: Vratko Polak <vrpolak@cisco.com>
resources/libraries/python/IPsecUtil.py
tests/vpp/device/crypto/eth2p-ethip4ipsec11tnlsw-ip4base-int-aes128cbc-hmac512sha-dev.robot
tests/vpp/device/crypto/eth2p-ethip4ipsec1tnlsw-ip4base-int-aes128cbc-hmac512sha-dev.robot

index 2bc10d3..a19ec62 100644 (file)
@@ -243,12 +243,14 @@ class IPsecUtil:
     def get_integ_alg_key_len(integ_alg):
         """Return integrity algorithm key length.
 
+        None argument is accepted, returning zero.
+
         :param integ_alg: Integrity algorithm.
-        :type integ_alg: IntegAlg
+        :type integ_alg: Optional[IntegAlg]
         :returns: Key length.
         :rtype: int
         """
-        return integ_alg.key_len
+        return 0 if integ_alg is None else integ_alg.key_len
 
     @staticmethod
     def get_integ_alg_scapy_name(integ_alg):
@@ -366,7 +368,7 @@ class IPsecUtil:
         :type spi: int
         :type crypto_alg: CryptoAlg
         :type crypto_key: str
-        :type integ_alg: IntegAlg
+        :type integ_alg: Optional[IntegAlg]
         :type integ_key: str
         :type tunnel_src: str
         :type tunnel_dst: str
@@ -450,7 +452,7 @@ class IPsecUtil:
         :type spi: int
         :type crypto_alg: CryptoAlg
         :type crypto_key: str
-        :type integ_alg: IntegAlg
+        :type integ_alg: Optional[IntegAlg]
         :type integ_key: str
         :type tunnel_src: str
         :type tunnel_dst: str
@@ -849,6 +851,8 @@ class IPsecUtil:
             raddr_ip2, addr_incr, spi_d, existing_tunnels=0):
         """Create multiple IPsec tunnel interfaces on DUT1 node using VAT.
 
+        Generate random keys and return them (so DUT2 or TG can decrypt).
+
         :param nodes: VPP nodes to create tunnel interfaces.
         :param tun_ips: Dictionary with VPP node 1 ipsec tunnel interface
             IPv4/IPv6 address (ip1) and VPP node 2 ipsec tunnel interface
@@ -871,11 +875,13 @@ class IPsecUtil:
         :type if2_key: str
         :type n_tunnels: int
         :type crypto_alg: CryptoAlg
-        :type integ_alg: IntegAlg
+        :type integ_alg: Optional[IntegAlg]
         :type raddr_ip2: IPv4Address or IPv6Address
         :type addr_incr: int
         :type spi_d: dict
         :type existing_tunnels: int
+        :returns: Generated ckeys and ikeys.
+        :rtype: List[bytes], List[bytes]
         """
         tmp_fn1 = u"/tmp/ipsec_create_tunnel_dut1.config"
         if1_n = Topology.get_interface_name(nodes[u"DUT1"], if1_key)
@@ -902,10 +908,10 @@ class IPsecUtil:
                 ckeys.append(
                     gen_key(IPsecUtil.get_crypto_alg_key_len(crypto_alg))
                 )
+                ikeys.append(
+                    gen_key(IPsecUtil.get_integ_alg_key_len(integ_alg))
+                )
                 if integ_alg:
-                    ikeys.append(
-                        gen_key(IPsecUtil.get_integ_alg_key_len(integ_alg))
-                    )
                     integ = f"integ-alg {integ_alg.alg_name} " \
                         f"integ-key {ikeys[i].hex()} "
                 else:
@@ -965,6 +971,9 @@ class IPsecUtil:
             ikeys, raddr_ip1, addr_incr, spi_d, existing_tunnels=0):
         """Create multiple IPsec tunnel interfaces on DUT2 node using VAT.
 
+        This method accesses keys generated by DUT1 method
+        and does not return anything.
+
         :param nodes: VPP nodes to create tunnel interfaces.
         :param tun_ips: Dictionary with VPP node 1 ipsec tunnel interface
             IPv4/IPv6 address (ip1) and VPP node 2 ipsec tunnel interface
@@ -985,9 +994,9 @@ class IPsecUtil:
         :type if2_key: str
         :type n_tunnels: int
         :type crypto_alg: CryptoAlg
-        :type ckeys: list
-        :type integ_alg: IntegAlg
-        :type ikeys: list
+        :type ckeys: Sequence[bytes]
+        :type integ_alg: Optional[IntegAlg]
+        :type ikeys: Sequence[bytes]
         :type addr_incr: int
         :type spi_d: dict
         :type existing_tunnels: int
@@ -1140,6 +1149,8 @@ class IPsecUtil:
             raddr_ip2, addr_incr, spi_d, existing_tunnels=0):
         """Create multiple IPsec tunnel interfaces on DUT1 node using PAPI.
 
+        Generate random keys and return them (so DUT2 or TG can decrypt).
+
         :param nodes: VPP nodes to create tunnel interfaces.
         :param tun_ips: Dictionary with VPP node 1 ipsec tunnel interface
             IPv4/IPv6 address (ip1) and VPP node 2 ipsec tunnel interface
@@ -1162,11 +1173,13 @@ class IPsecUtil:
         :type if2_key: str
         :type n_tunnels: int
         :type crypto_alg: CryptoAlg
-        :type integ_alg: IntegAlg
+        :type integ_alg: Optional[IntegAlg]
         :type raddr_ip2: IPv4Address or IPv6Address
         :type addr_incr: int
         :type spi_d: dict
         :type existing_tunnels: int
+        :returns: Generated ckeys and ikeys.
+        :rtype: List[bytes], List[bytes]
         """
         if not existing_tunnels:
             loop_sw_if_idx = IPsecUtil._ipsec_create_loopback_dut1_papi(
@@ -1269,10 +1282,9 @@ class IPsecUtil:
                 ckeys.append(
                     gen_key(IPsecUtil.get_crypto_alg_key_len(crypto_alg))
                 )
-                if integ_alg:
-                    ikeys.append(
-                        gen_key(IPsecUtil.get_integ_alg_key_len(integ_alg))
-                    )
+                ikeys.append(
+                    gen_key(IPsecUtil.get_integ_alg_key_len(integ_alg))
+                )
                 # SAD entry for outband / tx path
                 args[u"entry"][u"sad_id"] = i
                 args[u"entry"][u"spi"] = spi_d[u"spi_1"] + i
@@ -1388,6 +1400,9 @@ class IPsecUtil:
             ikeys, raddr_ip1, addr_incr, spi_d, existing_tunnels=0):
         """Create multiple IPsec tunnel interfaces on DUT2 node using PAPI.
 
+        This method accesses keys generated by DUT1 method
+        and does not return anything.
+
         :param nodes: VPP nodes to create tunnel interfaces.
         :param tun_ips: Dictionary with VPP node 1 ipsec tunnel interface
             IPv4/IPv6 address (ip1) and VPP node 2 ipsec tunnel interface
@@ -1408,9 +1423,9 @@ class IPsecUtil:
         :type if2_key: str
         :type n_tunnels: int
         :type crypto_alg: CryptoAlg
-        :type ckeys: list
-        :type integ_alg: IntegAlg
-        :type ikeys: list
+        :type ckeys: Sequence[bytes]
+        :type integ_alg: Optional[IntegAlg]
+        :type ikeys: Sequence[bytes]
         :type addr_incr: int
         :type spi_d: dict
         :type existing_tunnels: int
@@ -1509,10 +1524,9 @@ class IPsecUtil:
                 ckeys.append(
                     gen_key(IPsecUtil.get_crypto_alg_key_len(crypto_alg))
                 )
-                if integ_alg:
-                    ikeys.append(
-                        gen_key(IPsecUtil.get_integ_alg_key_len(integ_alg))
-                    )
+                ikeys.append(
+                    gen_key(IPsecUtil.get_integ_alg_key_len(integ_alg))
+                )
                 # SAD entry for outband / tx path
                 args[u"entry"][u"sad_id"] = 100000 + i
                 args[u"entry"][u"spi"] = spi_d[u"spi_2"] + i
@@ -1639,9 +1653,13 @@ class IPsecUtil:
     def vpp_ipsec_create_tunnel_interfaces(
             nodes, tun_if1_ip_addr, tun_if2_ip_addr, if1_key, if2_key,
             n_tunnels, crypto_alg, integ_alg, raddr_ip1, raddr_ip2, raddr_range,
-            existing_tunnels=0):
+            existing_tunnels=0, return_keys=False):
         """Create multiple IPsec tunnel interfaces between two VPP nodes.
 
+        Some deployments (e.g. devicetest) need to know the generated keys.
+        But other deployments (e.g. scale perf test) would get spammed
+        if we returned keys every time.
+
         :param nodes: VPP nodes to create tunnel interfaces.
         :param tun_if1_ip_addr: VPP node 1 ipsec tunnel interface IPv4/IPv6
             address.
@@ -1662,6 +1680,7 @@ class IPsecUtil:
             and to 128 in case of IPv6.
         :param existing_tunnels: Number of tunnel interfaces before creation.
             Useful mainly for reconf tests. Default 0.
+        :param return_keys: Whether generated keys should be returned.
         :type nodes: dict
         :type tun_if1_ip_addr: str
         :type tun_if2_ip_addr: str
@@ -1669,11 +1688,14 @@ class IPsecUtil:
         :type if2_key: str
         :type n_tunnels: int
         :type crypto_alg: CryptoAlg
-        :type integ_alg: IntegAlg
+        :type integ_alg: Optonal[IntegAlg]
         :type raddr_ip1: string
         :type raddr_ip2: string
         :type raddr_range: int
         :type existing_tunnels: int
+        :type return_keys: bool
+        :returns: Ckeys, ikeys, spi_1, spi_2.
+        :rtype: Optional[List[bytes], List[bytes], int, int]
         """
         n_tunnels = int(n_tunnels)
         existing_tunnels = int(existing_tunnels)
@@ -1695,25 +1717,27 @@ class IPsecUtil:
                 nodes, tun_ips, if1_key, if2_key, n_tunnels, crypto_alg,
                 integ_alg, raddr_ip2, addr_incr, spi_d, existing_tunnels
             )
-            if u"DUT2" not in nodes.keys():
-                return ckeys[0], ikeys[0], spi_d[u"spi_1"], spi_d[u"spi_2"]
-            IPsecUtil._ipsec_create_tunnel_interfaces_dut2_vat(
-                nodes, tun_ips, if2_key, n_tunnels, crypto_alg, ckeys,
-                integ_alg, ikeys, raddr_ip1, addr_incr, spi_d, existing_tunnels
-            )
+            if u"DUT2" in nodes.keys():
+                IPsecUtil._ipsec_create_tunnel_interfaces_dut2_vat(
+                    nodes, tun_ips, if2_key, n_tunnels, crypto_alg, ckeys,
+                    integ_alg, ikeys, raddr_ip1, addr_incr, spi_d,
+                    existing_tunnels
+                )
         else:
             ckeys, ikeys = IPsecUtil._ipsec_create_tunnel_interfaces_dut1_papi(
                 nodes, tun_ips, if1_key, if2_key, n_tunnels, crypto_alg,
                 integ_alg, raddr_ip2, addr_incr, spi_d, existing_tunnels
             )
-            if u"DUT2" not in nodes.keys():
-                return ckeys[0], ikeys[0], spi_d[u"spi_1"], spi_d[u"spi_2"]
-            IPsecUtil._ipsec_create_tunnel_interfaces_dut2_papi(
-                nodes, tun_ips, if2_key, n_tunnels, crypto_alg, ckeys,
-                integ_alg, ikeys, raddr_ip1, addr_incr, spi_d, existing_tunnels
-            )
+            if u"DUT2" in nodes.keys():
+                IPsecUtil._ipsec_create_tunnel_interfaces_dut2_papi(
+                    nodes, tun_ips, if2_key, n_tunnels, crypto_alg, ckeys,
+                    integ_alg, ikeys, raddr_ip1, addr_incr, spi_d,
+                    existing_tunnels
+                )
 
-        return None, None, None, None
+        if return_keys:
+            return ckeys, ikeys, spi_d[u"spi_1"], spi_d[u"spi_2"]
+        return None
 
     @staticmethod
     def _create_ipsec_script_files(dut, instances):
@@ -1778,7 +1802,7 @@ class IPsecUtil:
         :type if2_ip_addr: str
         :type n_tunnels: int
         :type crypto_alg: CryptoAlg
-        :type integ_alg: IntegAlg
+        :type integ_alg: Optional[IntegAlg]
         :type raddr_ip1: string
         :type raddr_ip2: string
         :type raddr_range: int
@@ -1811,10 +1835,10 @@ class IPsecUtil:
                 gen_key(IPsecUtil.get_crypto_alg_key_len(crypto_alg)), u"hex"
             )
             integ = u""
+            ikey = getattr(
+                gen_key(IPsecUtil.get_integ_alg_key_len(integ_alg)), u"hex"
+            )
             if integ_alg:
-                ikey = getattr(
-                    gen_key(IPsecUtil.get_integ_alg_key_len(integ_alg)), u"hex"
-                )
                 integ = (
                     f"integ-alg {integ_alg.alg_name} "
                     f"local-integ-key {ikey} "
@@ -1892,7 +1916,7 @@ class IPsecUtil:
         :type interface2: str or int
         :type n_tunnels: int
         :type crypto_alg: CryptoAlg
-        :type integ_alg: IntegAlg
+        :type integ_alg: Optional[IntegAlg]
         :type tunnel_ip1: str
         :type tunnel_ip2: str
         :type raddr_ip1: string
index 4338fa3..27451b1 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2020 Cisco and/or its affiliates.
+# Copyright (c) 2021 Cisco and/or its affiliates.
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at:
 | | When Initialize layer driver | ${nic_driver}
 | | And Initialize layer interface
 | | And Initialize IPSec in 2-node circular topology
-| | ${encr_key} | ${auth_key} | ${dut_spi} | ${tg_spi} =
+| | ${encr_keys} | ${auth_keys} | ${dut_spi} | ${tg_spi} =
 | | ... | And VPP IPsec Create Tunnel Interfaces
 | | ... | ${nodes} | ${tun_if1_ip4} | ${tun_if2_ip4} | ${DUT1_${int}2}[0]
 | | ... | ${TG_pf2}[0] | ${n_tunnels} | ${encr_alg} | ${auth_alg}
-| | ... | ${laddr_ip4} | ${raddr_ip4} | ${addr_range}
+| | ... | ${laddr_ip4} | ${raddr_ip4} | ${addr_range} | return_keys=${True}
 | | Then Send IP Packet and verify ESP encapsulation in received packet
 | | ... | ${tg} | ${TG_pf1}[0] | ${TG_pf2}[0] | ${DUT1_${int}1_mac}[0]
-| | ... | ${DUT1_${int}2_mac}[0] | ${encr_alg} | ${encr_key} | ${auth_alg}
-| | ... | ${auth_key} | ${dut_spi} | ${tg_spi} | ${laddr_ip4} | ${raddr_ip4}
+| | ... | ${DUT1_${int}2_mac}[0] | ${encr_alg} | ${encr_keys}[0] | ${auth_alg}
+| | ... | ${auth_keys}[0] | ${dut_spi} | ${tg_spi} | ${laddr_ip4} | ${raddr_ip4}
 | | ... | ${tun_if1_ip4} | ${tun_if2_ip4}
 
 *** Test Cases ***
index f8ab715..e5203ca 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2020 Cisco and/or its affiliates.
+# Copyright (c) 2021 Cisco and/or its affiliates.
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at:
 | | When Initialize layer driver | ${nic_driver}
 | | And Initialize layer interface
 | | And Initialize IPSec in 2-node circular topology
-| | ${encr_key} | ${auth_key} | ${dut_spi} | ${tg_spi} =
+| | ${encr_keys} | ${auth_keys} | ${dut_spi} | ${tg_spi} =
 | | ... | And VPP IPsec Create Tunnel Interfaces
 | | ... | ${nodes} | ${tun_if1_ip4} | ${tun_if2_ip4} | ${DUT1_${int}2}[0]
 | | ... | ${TG_pf2}[0] | ${n_tunnels} | ${encr_alg} | ${auth_alg}
-| | ... | ${laddr_ip4} | ${raddr_ip4} | ${addr_range}
+| | ... | ${laddr_ip4} | ${raddr_ip4} | ${addr_range} | return_keys=${True}
 | | Then Send IP Packet and verify ESP encapsulation in received packet
 | | ... | ${tg} | ${TG_pf1}[0] | ${TG_pf2}[0] | ${DUT1_${int}1_mac}[0]
-| | ... | ${DUT1_${int}2_mac}[0] | ${encr_alg} | ${encr_key} | ${auth_alg}
-| | ... | ${auth_key} | ${dut_spi} | ${tg_spi} | ${laddr_ip4} | ${raddr_ip4}
+| | ... | ${DUT1_${int}2_mac}[0] | ${encr_alg} | ${encr_keys}[0] | ${auth_alg}
+| | ... | ${auth_keys}[0] | ${dut_spi} | ${tg_spi} | ${laddr_ip4} | ${raddr_ip4}
 | | ... | ${tun_if1_ip4} | ${tun_if2_ip4}
 | | And Show Ipsec Security Association | ${dut1}