+class IpsecTcpTests(IpsecTcp):
+ def test_tcp_checksum(self):
+ """ verify checksum correctness for vpp generated packets """
+ self.verify_tcp_checksum()
+
+
+class IpsecTra4(object):
+ """ verify methods for Transport v4 """
+ def verify_tra_anti_replay(self, count=1):
+ p = self.params[socket.AF_INET]
+ use_esn = p.vpp_tra_sa.use_esn
+
+ # fire in a packet with seq number 1
+ pkt = (Ether(src=self.tra_if.remote_mac,
+ dst=self.tra_if.local_mac) /
+ p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
+ dst=self.tra_if.local_ip4) /
+ ICMP(),
+ seq_num=1))
+ recv_pkts = self.send_and_expect(self.tra_if, [pkt], self.tra_if)
+
+ # now move the window over to 235
+ pkt = (Ether(src=self.tra_if.remote_mac,
+ dst=self.tra_if.local_mac) /
+ p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
+ dst=self.tra_if.local_ip4) /
+ ICMP(),
+ seq_num=235))
+ recv_pkts = self.send_and_expect(self.tra_if, [pkt], self.tra_if)
+
+ # replayed packets are dropped
+ self.send_and_assert_no_replies(self.tra_if, pkt * 3)
+ self.assert_error_counter_equal(
+ '/err/%s/SA replayed packet' % self.tra4_decrypt_node_name, 3)
+
+ # the window size is 64 packets
+ # in window are still accepted
+ pkt = (Ether(src=self.tra_if.remote_mac,
+ dst=self.tra_if.local_mac) /
+ p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
+ dst=self.tra_if.local_ip4) /
+ ICMP(),
+ seq_num=172))
+ recv_pkts = self.send_and_expect(self.tra_if, [pkt], self.tra_if)
+
+ # a packet that does not decrypt does not move the window forward
+ bogus_sa = SecurityAssociation(self.encryption_type,
+ p.vpp_tra_spi,
+ crypt_algo=p.crypt_algo,
+ crypt_key=p.crypt_key[::-1],
+ auth_algo=p.auth_algo,
+ auth_key=p.auth_key[::-1])
+ pkt = (Ether(src=self.tra_if.remote_mac,
+ dst=self.tra_if.local_mac) /
+ bogus_sa.encrypt(IP(src=self.tra_if.remote_ip4,
+ dst=self.tra_if.local_ip4) /
+ ICMP(),
+ seq_num=350))
+ self.send_and_assert_no_replies(self.tra_if, pkt * 17)
+
+ self.assert_error_counter_equal(
+ '/err/%s/Integrity check failed' % self.tra4_decrypt_node_name, 17)
+
+ # a malformed 'runt' packet
+ # created by a mis-constructed SA
+ if (ESP == self.encryption_type):
+ bogus_sa = SecurityAssociation(self.encryption_type,
+ p.vpp_tra_spi)
+ pkt = (Ether(src=self.tra_if.remote_mac,
+ dst=self.tra_if.local_mac) /
+ bogus_sa.encrypt(IP(src=self.tra_if.remote_ip4,
+ dst=self.tra_if.local_ip4) /
+ ICMP(),
+ seq_num=350))
+ self.send_and_assert_no_replies(self.tra_if, pkt * 17)
+
+ self.assert_error_counter_equal(
+ '/err/%s/undersized packet' % self.tra4_decrypt_node_name, 17)
+
+ # which we can determine since this packet is still in the window
+ pkt = (Ether(src=self.tra_if.remote_mac,
+ dst=self.tra_if.local_mac) /
+ p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
+ dst=self.tra_if.local_ip4) /
+ ICMP(),
+ seq_num=234))
+ self.send_and_expect(self.tra_if, [pkt], self.tra_if)
+
+ # out of window are dropped
+ pkt = (Ether(src=self.tra_if.remote_mac,
+ dst=self.tra_if.local_mac) /
+ p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
+ dst=self.tra_if.local_ip4) /
+ ICMP(),
+ seq_num=17))
+ self.send_and_assert_no_replies(self.tra_if, pkt * 17)
+
+ if use_esn:
+ # an out of window error with ESN looks like a high sequence
+ # wrap. but since it isn't then the verify will fail.
+ self.assert_error_counter_equal(
+ '/err/%s/Integrity check failed' %
+ self.tra4_decrypt_node_name, 34)
+
+ else:
+ self.assert_error_counter_equal(
+ '/err/%s/SA replayed packet' %
+ self.tra4_decrypt_node_name, 20)
+
+ # valid packet moves the window over to 236
+ pkt = (Ether(src=self.tra_if.remote_mac,
+ dst=self.tra_if.local_mac) /
+ p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
+ dst=self.tra_if.local_ip4) /
+ ICMP(),
+ seq_num=236))
+ rx = self.send_and_expect(self.tra_if, [pkt], self.tra_if)
+ decrypted = p.vpp_tra_sa.decrypt(rx[0][IP])
+
+ # move VPP's SA to just before the seq-number wrap
+ self.vapi.cli("test ipsec sa %d seq 0xffffffff" % p.scapy_tra_sa_id)
+
+ # then fire in a packet that VPP should drop because it causes the
+ # seq number to wrap unless we're using extended.
+ pkt = (Ether(src=self.tra_if.remote_mac,
+ dst=self.tra_if.local_mac) /
+ p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
+ dst=self.tra_if.local_ip4) /
+ ICMP(),
+ seq_num=237))
+
+ if use_esn:
+ rx = self.send_and_expect(self.tra_if, [pkt], self.tra_if)
+ # in order to decrpyt the high order number needs to wrap
+ p.vpp_tra_sa.seq_num = 0x100000000
+ decrypted = p.vpp_tra_sa.decrypt(rx[0][IP])
+
+ # send packets with high bits set
+ p.scapy_tra_sa.seq_num = 0x100000005
+ pkt = (Ether(src=self.tra_if.remote_mac,
+ dst=self.tra_if.local_mac) /
+ p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
+ dst=self.tra_if.local_ip4) /
+ ICMP(),
+ seq_num=0x100000005))
+ rx = self.send_and_expect(self.tra_if, [pkt], self.tra_if)
+ # in order to decrpyt the high order number needs to wrap
+ decrypted = p.vpp_tra_sa.decrypt(rx[0][IP])
+ else:
+ self.send_and_assert_no_replies(self.tra_if, [pkt])
+ self.assert_error_counter_equal(
+ '/err/%s/sequence number cycled' %
+ self.tra4_encrypt_node_name, 1)
+
+ # move the security-associations seq number on to the last we used
+ self.vapi.cli("test ipsec sa %d seq 0x15f" % p.scapy_tra_sa_id)
+ p.scapy_tra_sa.seq_num = 351
+ p.vpp_tra_sa.seq_num = 351
+
+ def verify_tra_basic4(self, count=1):