Ejemplo n.º 1
0
    def test_tra_anti_replay(self, count=1):
        """ ipsec v4 transport anti-reply test """
        p = self.params[socket.AF_INET]

        # 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)

        # 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)

        # 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)

        err = self.statistics.get_counter('/err/%s/SA replayed packet' %
                                          self.tra4_decrypt_node_name)
        self.assertEqual(err, 17)

        # a packet that does not decrypt does not move the window forward
        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)

        err = self.statistics.get_counter('/err/%s/Integrity check failed' %
                                          self.tra4_decrypt_node_name)
        self.assertEqual(err, 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))
        recv_pkts = self.send_and_expect(self.tra_if, [pkt], self.tra_if)

        # move the security-associations seq number on to the last we used
        p.scapy_tra_sa.seq_num = 351
        p.vpp_tra_sa.seq_num = 351
Ejemplo n.º 2
0
    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_packet_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_packet_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_packet_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_packet_counter_equal(
                '/err/%s/Integrity check failed' % self.tra4_decrypt_node_name,
                34)

        else:
            self.assert_packet_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_packet_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
Ejemplo n.º 3
0
    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_packet_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_packet_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_packet_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_packet_counter_equal(
                '/err/%s/Integrity check failed' %
                self.tra4_decrypt_node_name, 34)

        else:
            self.assert_packet_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_packet_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
Ejemplo n.º 4
0
    def verify_tra_anti_replay(self):
        p = self.params[socket.AF_INET]
        use_esn = p.vpp_tra_sa.use_esn

        seq_cycle_node_name = ('/err/%s/sequence number cycled' %
                               self.tra4_encrypt_node_name)
        replay_node_name = ('/err/%s/SA replayed packet' %
                            self.tra4_decrypt_node_name)
        if ESP == self.encryption_type and p.crypt_algo == "AES-GCM":
            hash_failed_node_name = ('/err/%s/ESP decryption failed' %
                                     self.tra4_decrypt_node_name)
        else:
            hash_failed_node_name = ('/err/%s/Integrity check failed' %
                                     self.tra4_decrypt_node_name)
        replay_count = self.statistics.get_err_counter(replay_node_name)
        hash_failed_count = self.statistics.get_err_counter(
            hash_failed_node_name)
        seq_cycle_count = self.statistics.get_err_counter(seq_cycle_node_name)

        if ESP == self.encryption_type:
            undersize_node_name = ('/err/%s/undersized packet' %
                                   self.tra4_decrypt_node_name)
            undersize_count = self.statistics.get_err_counter(
                undersize_node_name)

        #
        # send packets with seq numbers 1->34
        # this means the window size is still in Case B (see RFC4303
        # Appendix A)
        #
        # for reasons i haven't investigated Scapy won't create a packet with
        # seq_num=0
        #
        pkts = [(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=seq)) for seq in range(1, 34)]
        recv_pkts = self.send_and_expect(self.tra_if, pkts, self.tra_if)

        # replayed packets are dropped
        self.send_and_assert_no_replies(self.tra_if, pkts)
        replay_count += len(pkts)
        self.assert_error_counter_equal(replay_node_name, replay_count)

        #
        # now send a batch of packets all with the same sequence number
        # the first packet in the batch is legitimate, the rest bogus
        #
        pkts = (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=35))
        recv_pkts = self.send_and_expect(self.tra_if,
                                         pkts * 8,
                                         self.tra_if,
                                         n_rx=1)
        replay_count += 7
        self.assert_error_counter_equal(replay_node_name, replay_count)

        #
        # now move the window over to 257 (more than one byte) and into Case A
        #
        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=257))
        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)
        replay_count += 3
        self.assert_error_counter_equal(replay_node_name, replay_count)

        # 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=200))
        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=mk_scapy_crpyt_key(p)[::-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)

        hash_failed_count += 17
        self.assert_error_counter_equal(hash_failed_node_name,
                                        hash_failed_count)

        # a malformed 'runt' packet
        #  created by a mis-constructed SA
        if (ESP == self.encryption_type and p.crypt_algo != "NULL"):
            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)

            undersize_count += 17
            self.assert_error_counter_equal(undersize_node_name,
                                            undersize_count)

        # 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
        #  this is Case B. So VPP will consider this to be a high seq num wrap
        #  and so the decrypt attempt will fail
        #
        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.
            hash_failed_count += 17
            self.assert_error_counter_equal(hash_failed_node_name,
                                            hash_failed_count)

        else:
            replay_count += 17
            self.assert_error_counter_equal(replay_node_name, replay_count)

        # valid packet moves the window over to 258
        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=258))
        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 TX seq-num to just before the seq-number wrap.
        # then fire in a packet that VPP should drop on TX because it
        # causes the TX seq number to wrap; unless we're using extened sequence
        # numbers.
        #
        self.vapi.cli("test ipsec sa %d seq 0xffffffff" % p.scapy_tra_sa_id)
        self.logger.info(self.vapi.ppcli("show ipsec sa 0"))
        self.logger.info(self.vapi.ppcli("show ipsec sa 1"))

        pkts = [(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=seq))
                for seq in range(259, 280)]

        if use_esn:
            rxs = self.send_and_expect(self.tra_if, pkts, self.tra_if)

            #
            # in order for scapy to decrypt its SA's high order number needs
            # to wrap
            #
            p.vpp_tra_sa.seq_num = 0x100000000
            for rx in rxs:
                decrypted = p.vpp_tra_sa.decrypt(rx[0][IP])

            #
            # wrap scapy's TX high sequence number. VPP is in case B, so it
            # will consider this a high seq wrap also.
            # The low seq num we set it to will place VPP's RX window in Case A
            #
            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)
            decrypted = p.vpp_tra_sa.decrypt(rx[0][IP])

            #
            # A packet that has seq num between (2^32-64) and 5 is within
            # the window
            #
            p.scapy_tra_sa.seq_num = 0xfffffffd
            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=0xfffffffd))
            rx = self.send_and_expect(self.tra_if, [pkt], self.tra_if)
            decrypted = p.vpp_tra_sa.decrypt(rx[0][IP])

            #
            # While in case A we cannot wrap the high sequence number again
            # becuase VPP will consider this packet to be one that moves the
            # window forward
            #
            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=0x200000999))
            self.send_and_assert_no_replies(self.tra_if, [pkt], self.tra_if)

            hash_failed_count += 1
            self.assert_error_counter_equal(hash_failed_node_name,
                                            hash_failed_count)

            #
            # but if we move the wondow forward to case B, then we can wrap
            # again
            #
            p.scapy_tra_sa.seq_num = 0x100000555
            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=0x100000555))
            rx = self.send_and_expect(self.tra_if, [pkt], self.tra_if)
            decrypted = p.vpp_tra_sa.decrypt(rx[0][IP])

            p.scapy_tra_sa.seq_num = 0x200000444
            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=0x200000444))
            rx = self.send_and_expect(self.tra_if, [pkt], self.tra_if)
            decrypted = p.vpp_tra_sa.decrypt(rx[0][IP])

        else:
            #
            # without ESN TX sequence numbers can't wrap and packets are
            # dropped from here on out.
            #
            self.send_and_assert_no_replies(self.tra_if, pkts)
            seq_cycle_count += len(pkts)
            self.assert_error_counter_equal(seq_cycle_node_name,
                                            seq_cycle_count)

        # 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
Ejemplo n.º 5
0
def main():
    """Send and receive IPsec packet."""
    args = TrafficScriptArg([
        'src_mac', 'dst_mac', 'src_ip', 'dst_ip', 'crypto_alg', 'crypto_key',
        'integ_alg', 'integ_key', 'l_spi', 'r_spi'
    ], ['src_tun', 'dst_tun'])

    rxq = RxQueue(args.get_arg('rx_if'))
    txq = TxQueue(args.get_arg('tx_if'))

    src_mac = args.get_arg('src_mac')
    dst_mac = args.get_arg('dst_mac')
    src_ip = args.get_arg('src_ip')
    dst_ip = args.get_arg('dst_ip')
    crypto_alg = args.get_arg('crypto_alg')
    crypto_key = args.get_arg('crypto_key')
    integ_alg = args.get_arg('integ_alg')
    integ_key = args.get_arg('integ_key')
    l_spi = int(args.get_arg('l_spi'))
    r_spi = int(args.get_arg('r_spi'))
    src_tun = args.get_arg('src_tun')
    dst_tun = args.get_arg('dst_tun')

    is_ipv4 = True
    if 6 == ip_address(unicode(src_ip)).version:
        is_ipv4 = False

    tunnel_out = None
    tunnel_in = None

    if src_tun and dst_tun:
        if is_ipv4:
            tunnel_out = IP(src=src_tun, dst=dst_tun)
            tunnel_in = IP(src=dst_tun, dst=src_tun)
        else:
            tunnel_out = IPv6(src=src_tun, dst=dst_tun)
            tunnel_in = IPv6(src=dst_tun, dst=src_tun)
    else:
        src_tun = src_ip
        dst_tun = dst_ip

    sa_in = SecurityAssociation(ESP,
                                spi=r_spi,
                                crypt_algo=crypto_alg,
                                crypt_key=crypto_key,
                                auth_algo=integ_alg,
                                auth_key=integ_key,
                                tunnel_header=tunnel_in)

    sa_out = SecurityAssociation(ESP,
                                 spi=l_spi,
                                 crypt_algo=crypto_alg,
                                 crypt_key=crypto_key,
                                 auth_algo=integ_alg,
                                 auth_key=integ_key,
                                 tunnel_header=tunnel_out)

    sent_packets = []

    if is_ipv4:
        ip_pkt = IP(src=src_ip, dst=dst_ip) / \
                 ICMP()
        ip_pkt = IP(str(ip_pkt))
    else:
        ip_pkt = IPv6(src=src_ip, dst=dst_ip) / \
                 ICMPv6EchoRequest()
        ip_pkt = IPv6(str(ip_pkt))

    e_pkt = sa_out.encrypt(ip_pkt)
    pkt_send = Ether(src=src_mac, dst=dst_mac) / \
               e_pkt

    sent_packets.append(pkt_send)
    txq.send(pkt_send)

    pkt_recv = rxq.recv(2, sent_packets)

    if pkt_recv is None:
        raise RuntimeError('ESP packet Rx timeout')

    if is_ipv4:
        check_ipv4(pkt_recv, src_tun, dst_ip, src_ip, sa_in)
    else:
        check_ipv6(pkt_recv, src_tun, dst_ip, src_ip, sa_in)

    sys.exit(0)
Ejemplo n.º 6
0
def main():
    """Send and receive IPsec packet."""

    args = TrafficScriptArg([
        u"tx_src_mac", u"tx_dst_mac", u"rx_src_mac", u"rx_dst_mac", u"src_ip",
        u"dst_ip", u"crypto_alg", u"crypto_key", u"integ_alg", u"integ_key",
        u"l_spi", u"r_spi"
    ], [u"src_tun", u"dst_tun"])

    tx_txq = TxQueue(args.get_arg(u"tx_if"))
    tx_rxq = RxQueue(args.get_arg(u"tx_if"))
    rx_txq = TxQueue(args.get_arg(u"rx_if"))
    rx_rxq = RxQueue(args.get_arg(u"rx_if"))

    tx_src_mac = args.get_arg(u"tx_src_mac")
    tx_dst_mac = args.get_arg(u"tx_dst_mac")
    rx_src_mac = args.get_arg(u"rx_src_mac")
    rx_dst_mac = args.get_arg(u"rx_dst_mac")
    src_ip = args.get_arg(u"src_ip")
    dst_ip = args.get_arg(u"dst_ip")
    crypto_alg = args.get_arg(u"crypto_alg")
    crypto_key = args.get_arg(u"crypto_key")
    integ_alg = args.get_arg(u"integ_alg")
    integ_key = args.get_arg(u"integ_key")
    l_spi = int(args.get_arg(u"l_spi"))
    r_spi = int(args.get_arg(u"r_spi"))
    src_tun = args.get_arg(u"src_tun")
    dst_tun = args.get_arg(u"dst_tun")

    ip_layer = IP if ip_address(src_ip).version == 4 else IPv6

    tunnel_out = ip_layer(src=src_tun, dst=dst_tun) if src_tun and dst_tun \
        else None
    tunnel_in = ip_layer(src=dst_tun, dst=src_tun) if src_tun and dst_tun \
        else None

    if not (src_tun and dst_tun):
        src_tun = src_ip

    sa_in = SecurityAssociation(ESP,
                                spi=r_spi,
                                crypt_algo=crypto_alg,
                                crypt_key=crypto_key.encode(encoding=u"utf-8"),
                                auth_algo=integ_alg,
                                auth_key=integ_key.encode(encoding=u"utf-8"),
                                tunnel_header=tunnel_in)

    sa_out = SecurityAssociation(
        ESP,
        spi=l_spi,
        crypt_algo=crypto_alg,
        crypt_key=crypto_key.encode(encoding=u"utf-8"),
        auth_algo=integ_alg,
        auth_key=integ_key.encode(encoding=u"utf-8"),
        tunnel_header=tunnel_out)

    ip_pkt = ip_layer(src=src_ip, dst=dst_ip, proto=61) if ip_layer == IP \
        else ip_layer(src=src_ip, dst=dst_ip)
    ip_pkt = ip_layer(ip_pkt)

    e_pkt = sa_out.encrypt(ip_pkt)
    tx_pkt_send = (Ether(src=tx_src_mac, dst=tx_dst_mac) / e_pkt)

    sent_packets = list()
    tx_pkt_send /= Raw()
    sent_packets.append(tx_pkt_send)
    tx_txq.send(tx_pkt_send)

    while True:
        rx_pkt_recv = rx_rxq.recv(2)

        if rx_pkt_recv is None:
            raise RuntimeError(f"{ip_layer.name} packet Rx timeout")

        if rx_pkt_recv.haslayer(ICMPv6ND_NS):
            # read another packet in the queue if the current one is ICMPv6ND_NS
            continue
        else:
            # otherwise process the current packet
            break

    check_ip(rx_pkt_recv, ip_layer, src_ip, dst_ip)

    rx_ip_pkt = ip_layer(src=dst_ip, dst=src_ip, proto=61) if ip_layer == IP \
        else ip_layer(src=dst_ip, dst=src_ip)
    rx_pkt_send = (Ether(src=rx_dst_mac, dst=rx_src_mac) / rx_ip_pkt)

    rx_pkt_send /= Raw()
    rx_txq.send(rx_pkt_send)

    while True:
        tx_pkt_recv = tx_rxq.recv(2, sent_packets)

        if tx_pkt_recv is None:
            raise RuntimeError(u"ESP packet Rx timeout")

        if tx_pkt_recv.haslayer(ICMPv6ND_NS):
            # read another packet in the queue if the current one is ICMPv6ND_NS
            continue
        else:
            # otherwise process the current packet
            break

    check_ipsec(tx_pkt_recv, ip_layer, src_tun, dst_ip, src_ip, sa_in)

    sys.exit(0)
Ejemplo n.º 7
0
    def test_tra_anti_replay(self, count=1):
        """ ipsec v4 transport anti-reply test """
        p = self.params[socket.AF_INET]

        # 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)

        # 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)

        # 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)

        self.assert_packet_counter_equal(
            '/err/%s/SA replayed packet' % self.tra4_decrypt_node_name, 17)

        # a packet that does not decrypt does not move the window forward
        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_packet_counter_equal(
            '/err/%s/Integrity check failed' % 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)

        # 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 becuase it causes the
        # seq number to wrap
        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))
        self.send_and_assert_no_replies(self.tra_if, [pkt])
        self.assert_packet_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
Ejemplo n.º 8
0
def main():
    """Send and receive IPsec packet."""

    args = TrafficScriptArg(
        [
            u"tx_src_mac", u"tx_dst_mac", u"rx_src_mac", u"rx_dst_mac",
            u"src_ip", u"dst_ip", u"src_tun", u"dst_tun", u"crypto_alg",
            u"crypto_key", u"integ_alg", u"integ_key", u"l_spi", u"r_spi"
        ]
    )

    tx_txq = TxQueue(args.get_arg(u"tx_if"))
    tx_rxq = RxQueue(args.get_arg(u"tx_if"))
    rx_txq = TxQueue(args.get_arg(u"rx_if"))
    rx_rxq = RxQueue(args.get_arg(u"rx_if"))

    tx_src_mac = args.get_arg(u"tx_src_mac")
    tx_dst_mac = args.get_arg(u"tx_dst_mac")
    rx_src_mac = args.get_arg(u"rx_src_mac")
    rx_dst_mac = args.get_arg(u"rx_dst_mac")
    src_ip = args.get_arg(u"src_ip")
    dst_ip = args.get_arg(u"dst_ip")
    src_tun = args.get_arg(u"src_tun")
    dst_tun = args.get_arg(u"dst_tun")
    crypto_alg = args.get_arg(u"crypto_alg")
    crypto_key = args.get_arg(u"crypto_key")
    integ_alg = args.get_arg(u"integ_alg")
    integ_key = args.get_arg(u"integ_key")
    l_spi = int(args.get_arg(u"l_spi"))
    r_spi = int(args.get_arg(u"r_spi"))

    ip_layer = IP if ip_address(src_ip).version == 4 else IPv6
    ip_pkt = ip_layer(src=src_ip, dst=dst_ip, proto=61) if ip_layer == IP \
        else ip_layer(src=src_ip, dst=dst_ip)

    tunnel_in = ip_layer(src=src_tun, dst=dst_tun)
    tunnel_out = ip_layer(src=dst_tun, dst=src_tun)

    sa_in = SecurityAssociation(
        ESP, spi=l_spi, crypt_algo=crypto_alg,
        crypt_key=crypto_key.encode(encoding=u"utf-8"), auth_algo=integ_alg,
        auth_key=integ_key.encode(encoding=u"utf-8"),
        tunnel_header=tunnel_in
    )

    sa_out = SecurityAssociation(
        ESP, spi=r_spi, crypt_algo=crypto_alg,
        crypt_key=crypto_key.encode(encoding=u"utf-8"), auth_algo=integ_alg,
        auth_key=integ_key.encode(encoding=u"utf-8"),
        tunnel_header=tunnel_out
    )

    sent_packets = list()
    tx_pkt_send = (Ether(src=tx_src_mac, dst=tx_dst_mac) / ip_pkt)
    tx_pkt_send /= Raw()
    size_limit = 78 if ip_layer == IPv6 else 64
    if len(tx_pkt_send) < size_limit:
        tx_pkt_send[Raw].load += (b"\0" * (size_limit - len(tx_pkt_send)))
    sent_packets.append(tx_pkt_send)
    tx_txq.send(tx_pkt_send)

    while True:
        rx_pkt_recv = rx_rxq.recv(2)

        if rx_pkt_recv is None:
            raise RuntimeError(f"{ip_layer.__name__} packet Rx timeout")

        if rx_pkt_recv.haslayer(ICMPv6ND_NS):
            # read another packet in the queue if the current one is ICMPv6ND_NS
            continue
        elif rx_pkt_recv.haslayer(ICMPv6MLReport2):
            # read another packet in the queue if the current one is
            # ICMPv6MLReport2
            continue
        elif rx_pkt_recv.haslayer(ICMPv6ND_RA):
            # read another packet in the queue if the current one is
            # ICMPv6ND_RA
            continue

        # otherwise process the current packet
        break

    check_ipsec(
        rx_pkt_recv, ip_layer, rx_src_mac, rx_dst_mac, src_tun, dst_tun, src_ip,
        dst_ip, sa_in
    )

    ip_pkt = ip_layer(src=dst_ip, dst=src_ip, proto=61) if ip_layer == IP \
        else ip_layer(src=dst_ip, dst=src_ip)
    ip_pkt /= Raw()
    if len(ip_pkt) < (size_limit - 14):
        ip_pkt[Raw].load += (b"\0" * (size_limit - 14 - len(ip_pkt)))
    e_pkt = sa_out.encrypt(ip_pkt)
    rx_pkt_send = (Ether(src=rx_dst_mac, dst=rx_src_mac) /
                   e_pkt)
    rx_txq.send(rx_pkt_send)

    while True:
        tx_pkt_recv = tx_rxq.recv(2, ignore=sent_packets)

        if tx_pkt_recv is None:
            raise RuntimeError(f"{ip_layer.__name__} packet Rx timeout")

        if tx_pkt_recv.haslayer(ICMPv6ND_NS):
            # read another packet in the queue if the current one is ICMPv6ND_NS
            continue
        elif tx_pkt_recv.haslayer(ICMPv6MLReport2):
            # read another packet in the queue if the current one is
            # ICMPv6MLReport2
            continue
        elif tx_pkt_recv.haslayer(ICMPv6MLReport2):
            # read another packet in the queue if the current one is
            # ICMPv6MLReport2
            continue
        elif tx_pkt_recv.haslayer(ICMPv6ND_RA):
            # read another packet in the queue if the current one is
            # ICMPv6ND_RA
            continue

        # otherwise process the current packet
        break

    check_ip(tx_pkt_recv, ip_layer, tx_dst_mac, tx_src_mac, dst_ip, src_ip)

    sys.exit(0)
Ejemplo n.º 9
0
    def test_tra_anti_replay(self, count=1):
        """ ipsec v4 transport anti-reply test """
        p = self.params[socket.AF_INET]

        # 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)

        # 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)

        # 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)

        self.assert_packet_counter_equal(
            '/err/%s/SA replayed packet' % self.tra4_decrypt_node_name, 17)

        # a packet that does not decrypt does not move the window forward
        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_packet_counter_equal(
            '/err/%s/Integrity check failed' % 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)

        # 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 becuase it causes the
        # seq number to wrap
        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))
        self.send_and_assert_no_replies(self.tra_if, [pkt])
        self.assert_packet_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