tests: changes for scapy 2.4.3 migration
[vpp.git] / test / patches / scapy-2.4.3 / ipsec.patch
1 diff --git a/scapy/layers/ipsec.py b/scapy/layers/ipsec.py
2 index f8c601fa..f566d288 100644
3 --- a/scapy/layers/ipsec.py
4 +++ b/scapy/layers/ipsec.py
5 @@ -359,11 +359,8 @@ class CryptAlgo(object):
6              encryptor = cipher.encryptor()
7  
8              if self.is_aead:
9 -                if esn_en:
10 -                    aad = struct.pack('!LLL', esp.spi, esn, esp.seq)
11 -                else:
12 -                    aad = struct.pack('!LL', esp.spi, esp.seq)
13 -                encryptor.authenticate_additional_data(aad)
14 +                encryptor.authenticate_additional_data(sa.build_aead(esp))
15 +
16                  data = encryptor.update(data) + encryptor.finalize()
17                  data += encryptor.tag[:self.icv_size]
18              else:
19 @@ -401,12 +398,7 @@ class CryptAlgo(object):
20  
21              if self.is_aead:
22                  # Tag value check is done during the finalize method
23 -                if esn_en:
24 -                    decryptor.authenticate_additional_data(
25 -                        struct.pack('!LLL', esp.spi, esn, esp.seq))
26 -                else:
27 -                    decryptor.authenticate_additional_data(
28 -                        struct.pack('!LL', esp.spi, esp.seq))
29 +                decryptor.authenticate_additional_data(sa.build_aead(esp))
30              try:
31                  data = decryptor.update(data) + decryptor.finalize()
32              except InvalidTag as err:
33 @@ -545,7 +537,7 @@ class AuthAlgo(object):
34          else:
35              return self.mac(key, self.digestmod(), default_backend())
36  
37 -    def sign(self, pkt, key):
38 +    def sign(self, pkt, key, trailer=None):
39          """
40          Sign an IPsec (ESP or AH) packet with this algo.
41  
42 @@ -561,16 +553,20 @@ class AuthAlgo(object):
43  
44          if pkt.haslayer(ESP):
45              mac.update(raw(pkt[ESP]))
46 +            if trailer:
47 +                mac.update(trailer)
48              pkt[ESP].data += mac.finalize()[:self.icv_size]
49  
50          elif pkt.haslayer(AH):
51              clone = zero_mutable_fields(pkt.copy(), sending=True)
52              mac.update(raw(clone))
53 +            if trailer:
54 +                mac.update(trailer)
55              pkt[AH].icv = mac.finalize()[:self.icv_size]
56  
57          return pkt
58  
59 -    def verify(self, pkt, key):
60 +    def verify(self, pkt, key, trailer):
61          """
62          Check that the integrity check value (icv) of a packet is valid.
63  
64 @@ -602,6 +598,8 @@ class AuthAlgo(object):
65              clone = zero_mutable_fields(pkt.copy(), sending=False)
66  
67          mac.update(raw(clone))
68 +        if trailer:
69 +            mac.update(trailer) # bytearray(4)) #raw(trailer))
70          computed_icv = mac.finalize()[:self.icv_size]
71  
72          # XXX: Cannot use mac.verify because the ICV can be truncated
73 @@ -864,6 +862,23 @@ class SecurityAssociation(object):
74                  raise TypeError('nat_t_header must be %s' % UDP.name)
75          self.nat_t_header = nat_t_header
76  
77 +    def build_aead(self, esp):
78 +        if self.esn_en:
79 +            return (struct.pack('!LLL', esp.spi, self.seq_num >> 32, esp.seq))
80 +        else:
81 +            return (struct.pack('!LL', esp.spi, esp.seq))
82 +
83 +    def build_seq_num(self, num):
84 +        # only lower order bits are  transmitted
85 +        # higher order bits are used in the ICV
86 +        lower = num & 0xffffffff
87 +        upper = num >> 32
88 +
89 +        if self.esn_en:
90 +            return lower, struct.pack("!I", upper)
91 +        else:
92 +            return lower, None
93 +
94      def check_spi(self, pkt):
95          if pkt.spi != self.spi:
96              raise TypeError('packet spi=0x%x does not match the SA spi=0x%x' %
97 @@ -877,7 +892,8 @@ class SecurityAssociation(object):
98              if len(iv) != self.crypt_algo.iv_size:
99                  raise TypeError('iv length must be %s' % self.crypt_algo.iv_size)  # noqa: E501
100  
101 -        esp = _ESPPlain(spi=self.spi, seq=seq_num or self.seq_num, iv=iv)
102 +        low_seq_num, high_seq_num = self.build_seq_num(seq_num or self.seq_num)
103 +        esp = _ESPPlain(spi=self.spi, seq=low_seq_num, iv=iv)
104  
105          if self.tunnel_header:
106              tunnel = self.tunnel_header.copy()
107 @@ -901,7 +917,7 @@ class SecurityAssociation(object):
108                                        esn_en=esn_en or self.esn_en,
109                                        esn=esn or self.esn)
110  
111 -        self.auth_algo.sign(esp, self.auth_key)
112 +        self.auth_algo.sign(esp, self.auth_key, high_seq_num)
113  
114          if self.nat_t_header:
115              nat_t_header = self.nat_t_header.copy()
116 @@ -928,7 +944,8 @@ class SecurityAssociation(object):
117  
118      def _encrypt_ah(self, pkt, seq_num=None):
119  
120 -        ah = AH(spi=self.spi, seq=seq_num or self.seq_num,
121 +        low_seq_num, high_seq_num = self.build_seq_num(seq_num or self.seq_num)
122 +        ah = AH(spi=self.spi, seq=low_seq_num,
123                  icv=b"\x00" * self.auth_algo.icv_size)
124  
125          if self.tunnel_header:
126 @@ -968,7 +985,8 @@ class SecurityAssociation(object):
127          else:
128              ip_header.plen = len(ip_header.payload) + len(ah) + len(payload)
129  
130 -        signed_pkt = self.auth_algo.sign(ip_header / ah / payload, self.auth_key)  # noqa: E501
131 +        signed_pkt = self.auth_algo.sign(ip_header / ah / payload,
132 +                                         self.auth_key, high_seq_num)  # noqa: E501
133  
134          # sequence number must always change, unless specified by the user
135          if seq_num is None:
136 @@ -1005,11 +1023,12 @@ class SecurityAssociation(object):
137  
138      def _decrypt_esp(self, pkt, verify=True, esn_en=None, esn=None):
139  
140 +        low_seq_num, high_seq_num = self.build_seq_num(self.seq_num)
141          encrypted = pkt[ESP]
142  
143          if verify:
144              self.check_spi(pkt)
145 -            self.auth_algo.verify(encrypted, self.auth_key)
146 +            self.auth_algo.verify(encrypted, self.auth_key, high_seq_num)
147  
148          esp = self.crypt_algo.decrypt(self, encrypted, self.crypt_key,
149                                        self.crypt_algo.icv_size or
150 @@ -1050,9 +1069,10 @@ class SecurityAssociation(object):
151  
152      def _decrypt_ah(self, pkt, verify=True):
153  
154 +        low_seq_num, high_seq_num = self.build_seq_num(self.seq_num)
155          if verify:
156              self.check_spi(pkt)
157 -            self.auth_algo.verify(pkt, self.auth_key)
158 +            self.auth_algo.verify(pkt, self.auth_key, high_seq_num)
159  
160          ah = pkt[AH]
161          payload = ah.payload
162