From 0d30d69d515130098eab5d21d8dd59c21400a433 Mon Sep 17 00:00:00 2001 From: Vratko Polak Date: Mon, 22 Feb 2021 14:43:46 +0100 Subject: [PATCH] Ipsec: Always generate ikey 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 --- resources/libraries/python/IPsecUtil.py | 110 +++++++++++++-------- ...nlsw-ip4base-int-aes128cbc-hmac512sha-dev.robot | 10 +- ...nlsw-ip4base-int-aes128cbc-hmac512sha-dev.robot | 10 +- 3 files changed, 77 insertions(+), 53 deletions(-) diff --git a/resources/libraries/python/IPsecUtil.py b/resources/libraries/python/IPsecUtil.py index 2bc10d3ac9..a19ec62402 100644 --- a/resources/libraries/python/IPsecUtil.py +++ b/resources/libraries/python/IPsecUtil.py @@ -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 diff --git a/tests/vpp/device/crypto/eth2p-ethip4ipsec11tnlsw-ip4base-int-aes128cbc-hmac512sha-dev.robot b/tests/vpp/device/crypto/eth2p-ethip4ipsec11tnlsw-ip4base-int-aes128cbc-hmac512sha-dev.robot index 4338fa35b5..27451b138e 100644 --- a/tests/vpp/device/crypto/eth2p-ethip4ipsec11tnlsw-ip4base-int-aes128cbc-hmac512sha-dev.robot +++ b/tests/vpp/device/crypto/eth2p-ethip4ipsec11tnlsw-ip4base-int-aes128cbc-hmac512sha-dev.robot @@ -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: @@ -84,15 +84,15 @@ | | 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 *** diff --git a/tests/vpp/device/crypto/eth2p-ethip4ipsec1tnlsw-ip4base-int-aes128cbc-hmac512sha-dev.robot b/tests/vpp/device/crypto/eth2p-ethip4ipsec1tnlsw-ip4base-int-aes128cbc-hmac512sha-dev.robot index f8ab71565b..e5203ca42b 100644 --- a/tests/vpp/device/crypto/eth2p-ethip4ipsec1tnlsw-ip4base-int-aes128cbc-hmac512sha-dev.robot +++ b/tests/vpp/device/crypto/eth2p-ethip4ipsec1tnlsw-ip4base-int-aes128cbc-hmac512sha-dev.robot @@ -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: @@ -84,15 +84,15 @@ | | 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} -- 2.16.6