ipsec: Tunnel SA DSCP behaviour
[vpp.git] / test / test_ipsec_esp.py
1 import socket
2 import unittest
3 from scapy.layers.ipsec import ESP
4 from scapy.layers.inet import IP, ICMP, UDP
5 from scapy.layers.inet6 import IPv6
6 from scapy.layers.l2 import Ether
7 from scapy.packet import Raw
8
9 from parameterized import parameterized
10 from framework import VppTestRunner
11 from template_ipsec import IpsecTra46Tests, IpsecTun46Tests, TemplateIpsec, \
12     IpsecTcpTests, IpsecTun4Tests, IpsecTra4Tests, config_tra_params, \
13     config_tun_params, IPsecIPv4Params, IPsecIPv6Params, \
14     IpsecTra4, IpsecTun4, IpsecTra6, IpsecTun6, \
15     IpsecTun6HandoffTests, IpsecTun4HandoffTests, \
16     IpsecTra6ExtTests
17 from vpp_ipsec import VppIpsecSpd, VppIpsecSpdEntry, VppIpsecSA,\
18     VppIpsecSpdItfBinding
19 from vpp_ip_route import VppIpRoute, VppRoutePath
20 from vpp_ip import DpoProto
21 from vpp_papi import VppEnum
22
23 NUM_PKTS = 67
24 engines_supporting_chain_bufs = ["openssl"]
25
26
27 class ConfigIpsecESP(TemplateIpsec):
28     encryption_type = ESP
29     tra4_encrypt_node_name = "esp4-encrypt"
30     tra4_decrypt_node_name = "esp4-decrypt"
31     tra6_encrypt_node_name = "esp6-encrypt"
32     tra6_decrypt_node_name = "esp6-decrypt"
33     tun4_encrypt_node_name = "esp4-encrypt"
34     tun4_decrypt_node_name = "esp4-decrypt"
35     tun6_encrypt_node_name = "esp6-encrypt"
36     tun6_decrypt_node_name = "esp6-decrypt"
37
38     @classmethod
39     def setUpClass(cls):
40         super(ConfigIpsecESP, cls).setUpClass()
41
42     @classmethod
43     def tearDownClass(cls):
44         super(ConfigIpsecESP, cls).tearDownClass()
45
46     def setUp(self):
47         super(ConfigIpsecESP, self).setUp()
48
49     def tearDown(self):
50         super(ConfigIpsecESP, self).tearDown()
51
52     def config_network(self, params):
53         self.net_objs = []
54         self.tun_if = self.pg0
55         self.tra_if = self.pg2
56         self.logger.info(self.vapi.ppcli("show int addr"))
57
58         self.tra_spd = VppIpsecSpd(self, self.tra_spd_id)
59         self.tra_spd.add_vpp_config()
60         self.net_objs.append(self.tra_spd)
61         self.tun_spd = VppIpsecSpd(self, self.tun_spd_id)
62         self.tun_spd.add_vpp_config()
63         self.net_objs.append(self.tun_spd)
64
65         b = VppIpsecSpdItfBinding(self, self.tun_spd,
66                                   self.tun_if)
67         b.add_vpp_config()
68         self.net_objs.append(b)
69
70         b = VppIpsecSpdItfBinding(self, self.tra_spd,
71                                   self.tra_if)
72         b.add_vpp_config()
73         self.net_objs.append(b)
74
75         for p in params:
76             self.config_esp_tra(p)
77             config_tra_params(p, self.encryption_type)
78         for p in params:
79             self.config_esp_tun(p)
80             config_tun_params(p, self.encryption_type, self.tun_if)
81
82         for p in params:
83             d = DpoProto.DPO_PROTO_IP6 if p.is_ipv6 else DpoProto.DPO_PROTO_IP4
84             r = VppIpRoute(self,  p.remote_tun_if_host, p.addr_len,
85                            [VppRoutePath(self.tun_if.remote_addr[p.addr_type],
86                                          0xffffffff,
87                                          proto=d)])
88             r.add_vpp_config()
89             self.net_objs.append(r)
90
91         self.logger.info(self.vapi.ppcli("show ipsec all"))
92
93     def unconfig_network(self):
94         for o in reversed(self.net_objs):
95             o.remove_vpp_config()
96         self.net_objs = []
97
98     def config_esp_tun(self, params):
99         addr_type = params.addr_type
100         scapy_tun_sa_id = params.scapy_tun_sa_id
101         scapy_tun_spi = params.scapy_tun_spi
102         vpp_tun_sa_id = params.vpp_tun_sa_id
103         vpp_tun_spi = params.vpp_tun_spi
104         auth_algo_vpp_id = params.auth_algo_vpp_id
105         auth_key = params.auth_key
106         crypt_algo_vpp_id = params.crypt_algo_vpp_id
107         crypt_key = params.crypt_key
108         remote_tun_if_host = params.remote_tun_if_host
109         addr_any = params.addr_any
110         addr_bcast = params.addr_bcast
111         e = VppEnum.vl_api_ipsec_spd_action_t
112         flags = params.flags
113         tun_flags = params.tun_flags
114         salt = params.salt
115         objs = []
116
117         params.tun_sa_in = VppIpsecSA(self, scapy_tun_sa_id, scapy_tun_spi,
118                                       auth_algo_vpp_id, auth_key,
119                                       crypt_algo_vpp_id, crypt_key,
120                                       self.vpp_esp_protocol,
121                                       self.tun_if.local_addr[addr_type],
122                                       self.tun_if.remote_addr[addr_type],
123                                       tun_flags=tun_flags,
124                                       dscp=params.dscp,
125                                       flags=flags,
126                                       salt=salt)
127         params.tun_sa_out = VppIpsecSA(self, vpp_tun_sa_id, vpp_tun_spi,
128                                        auth_algo_vpp_id, auth_key,
129                                        crypt_algo_vpp_id, crypt_key,
130                                        self.vpp_esp_protocol,
131                                        self.tun_if.remote_addr[addr_type],
132                                        self.tun_if.local_addr[addr_type],
133                                        tun_flags=tun_flags,
134                                        dscp=params.dscp,
135                                        flags=flags,
136                                        salt=salt)
137         objs.append(params.tun_sa_in)
138         objs.append(params.tun_sa_out)
139
140         params.spd_policy_in_any = VppIpsecSpdEntry(self, self.tun_spd,
141                                                     scapy_tun_sa_id,
142                                                     addr_any, addr_bcast,
143                                                     addr_any, addr_bcast,
144                                                     socket.IPPROTO_ESP)
145         params.spd_policy_out_any = VppIpsecSpdEntry(self, self.tun_spd,
146                                                      scapy_tun_sa_id,
147                                                      addr_any, addr_bcast,
148                                                      addr_any, addr_bcast,
149                                                      socket.IPPROTO_ESP,
150                                                      is_outbound=0)
151         objs.append(params.spd_policy_out_any)
152         objs.append(params.spd_policy_in_any)
153
154         objs.append(VppIpsecSpdEntry(self, self.tun_spd, vpp_tun_sa_id,
155                                      remote_tun_if_host, remote_tun_if_host,
156                                      self.pg1.remote_addr[addr_type],
157                                      self.pg1.remote_addr[addr_type],
158                                      0,
159                                      priority=10,
160                                      policy=e.IPSEC_API_SPD_ACTION_PROTECT,
161                                      is_outbound=0))
162         objs.append(VppIpsecSpdEntry(self, self.tun_spd, scapy_tun_sa_id,
163                                      self.pg1.remote_addr[addr_type],
164                                      self.pg1.remote_addr[addr_type],
165                                      remote_tun_if_host, remote_tun_if_host,
166                                      0,
167                                      policy=e.IPSEC_API_SPD_ACTION_PROTECT,
168                                      priority=10))
169         objs.append(VppIpsecSpdEntry(self, self.tun_spd, vpp_tun_sa_id,
170                                      remote_tun_if_host, remote_tun_if_host,
171                                      self.pg0.local_addr[addr_type],
172                                      self.pg0.local_addr[addr_type],
173                                      0,
174                                      priority=20,
175                                      policy=e.IPSEC_API_SPD_ACTION_PROTECT,
176                                      is_outbound=0))
177         objs.append(VppIpsecSpdEntry(self, self.tun_spd, scapy_tun_sa_id,
178                                      self.pg0.local_addr[addr_type],
179                                      self.pg0.local_addr[addr_type],
180                                      remote_tun_if_host, remote_tun_if_host,
181                                      0,
182                                      policy=e.IPSEC_API_SPD_ACTION_PROTECT,
183                                      priority=20))
184         for o in objs:
185             o.add_vpp_config()
186         self.net_objs = self.net_objs + objs
187
188     def config_esp_tra(self, params):
189         addr_type = params.addr_type
190         scapy_tra_sa_id = params.scapy_tra_sa_id
191         scapy_tra_spi = params.scapy_tra_spi
192         vpp_tra_sa_id = params.vpp_tra_sa_id
193         vpp_tra_spi = params.vpp_tra_spi
194         auth_algo_vpp_id = params.auth_algo_vpp_id
195         auth_key = params.auth_key
196         crypt_algo_vpp_id = params.crypt_algo_vpp_id
197         crypt_key = params.crypt_key
198         addr_any = params.addr_any
199         addr_bcast = params.addr_bcast
200         flags = (VppEnum.vl_api_ipsec_sad_flags_t.
201                  IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY)
202         e = VppEnum.vl_api_ipsec_spd_action_t
203         flags = params.flags | flags
204         salt = params.salt
205         objs = []
206
207         params.tra_sa_in = VppIpsecSA(self, scapy_tra_sa_id, scapy_tra_spi,
208                                       auth_algo_vpp_id, auth_key,
209                                       crypt_algo_vpp_id, crypt_key,
210                                       self.vpp_esp_protocol,
211                                       flags=flags,
212                                       salt=salt)
213         params.tra_sa_out = VppIpsecSA(self, vpp_tra_sa_id, vpp_tra_spi,
214                                        auth_algo_vpp_id, auth_key,
215                                        crypt_algo_vpp_id, crypt_key,
216                                        self.vpp_esp_protocol,
217                                        flags=flags,
218                                        salt=salt)
219         objs.append(params.tra_sa_in)
220         objs.append(params.tra_sa_out)
221
222         objs.append(VppIpsecSpdEntry(self, self.tra_spd, vpp_tra_sa_id,
223                                      addr_any, addr_bcast,
224                                      addr_any, addr_bcast,
225                                      socket.IPPROTO_ESP))
226         objs.append(VppIpsecSpdEntry(self, self.tra_spd, vpp_tra_sa_id,
227                                      addr_any, addr_bcast,
228                                      addr_any, addr_bcast,
229                                      socket.IPPROTO_ESP,
230                                      is_outbound=0))
231         objs.append(VppIpsecSpdEntry(self, self.tra_spd, vpp_tra_sa_id,
232                                      self.tra_if.local_addr[addr_type],
233                                      self.tra_if.local_addr[addr_type],
234                                      self.tra_if.remote_addr[addr_type],
235                                      self.tra_if.remote_addr[addr_type],
236                                      0, priority=10,
237                                      policy=e.IPSEC_API_SPD_ACTION_PROTECT,
238                                      is_outbound=0))
239         objs.append(VppIpsecSpdEntry(self, self.tra_spd, scapy_tra_sa_id,
240                                      self.tra_if.local_addr[addr_type],
241                                      self.tra_if.local_addr[addr_type],
242                                      self.tra_if.remote_addr[addr_type],
243                                      self.tra_if.remote_addr[addr_type],
244                                      0, policy=e.IPSEC_API_SPD_ACTION_PROTECT,
245                                      priority=10))
246         for o in objs:
247             o.add_vpp_config()
248         self.net_objs = self.net_objs + objs
249
250
251 class TemplateIpsecEsp(ConfigIpsecESP):
252     """
253     Basic test for ipsec esp sanity - tunnel and transport modes.
254
255     Below 4 cases are covered as part of this test
256     1) ipsec esp v4 transport basic test  - IPv4 Transport mode
257         scenario using HMAC-SHA1-96 integrity algo
258     2) ipsec esp v4 transport burst test
259         Above test for 257 pkts
260     3) ipsec esp 4o4 tunnel basic test    - IPv4 Tunnel mode
261         scenario using HMAC-SHA1-96 integrity algo
262     4) ipsec esp 4o4 tunnel burst test
263         Above test for 257 pkts
264
265     TRANSPORT MODE:
266
267      ---   encrypt   ---
268     |pg2| <-------> |VPP|
269      ---   decrypt   ---
270
271     TUNNEL MODE:
272
273      ---   encrypt   ---   plain   ---
274     |pg0| <-------  |VPP| <------ |pg1|
275      ---             ---           ---
276
277      ---   decrypt   ---   plain   ---
278     |pg0| ------->  |VPP| ------> |pg1|
279      ---             ---           ---
280     """
281
282     @classmethod
283     def setUpClass(cls):
284         super(TemplateIpsecEsp, cls).setUpClass()
285
286     @classmethod
287     def tearDownClass(cls):
288         super(TemplateIpsecEsp, cls).tearDownClass()
289
290     def setUp(self):
291         super(TemplateIpsecEsp, self).setUp()
292         self.config_network(self.params.values())
293
294     def tearDown(self):
295         self.unconfig_network()
296         super(TemplateIpsecEsp, self).tearDown()
297
298
299 class TestIpsecEsp1(TemplateIpsecEsp, IpsecTra46Tests,
300                     IpsecTun46Tests, IpsecTra6ExtTests):
301     """ Ipsec ESP - TUN & TRA tests """
302
303     @classmethod
304     def setUpClass(cls):
305         super(TestIpsecEsp1, cls).setUpClass()
306
307     @classmethod
308     def tearDownClass(cls):
309         super(TestIpsecEsp1, cls).tearDownClass()
310
311     def setUp(self):
312         super(TestIpsecEsp1, self).setUp()
313
314     def tearDown(self):
315         super(TestIpsecEsp1, self).tearDown()
316
317     def test_tun_46(self):
318         """ ipsec 4o6 tunnel """
319         # add an SPD entry to direct 2.2.2.2 to the v6 tunnel SA
320         p6 = self.ipv6_params
321         p4 = self.ipv4_params
322
323         p6.remote_tun_if_host4 = "2.2.2.2"
324         e = VppEnum.vl_api_ipsec_spd_action_t
325
326         VppIpsecSpdEntry(self,
327                          self.tun_spd,
328                          p6.scapy_tun_sa_id,
329                          self.pg1.remote_addr[p4.addr_type],
330                          self.pg1.remote_addr[p4.addr_type],
331                          p6.remote_tun_if_host4,
332                          p6.remote_tun_if_host4,
333                          0,
334                          priority=10,
335                          policy=e.IPSEC_API_SPD_ACTION_PROTECT,
336                          is_outbound=1).add_vpp_config()
337         VppIpRoute(self,  p6.remote_tun_if_host4, p4.addr_len,
338                    [VppRoutePath(self.tun_if.remote_addr[p4.addr_type],
339                                  0xffffffff)]).add_vpp_config()
340
341         old_name = self.tun6_encrypt_node_name
342         self.tun6_encrypt_node_name = "esp4-encrypt"
343
344         self.verify_tun_46(p6, count=63)
345         self.tun6_encrypt_node_name = old_name
346
347     def test_tun_64(self):
348         """ ipsec 6o4 tunnel """
349         # add an SPD entry to direct 4444::4 to the v4 tunnel SA
350         p6 = self.ipv6_params
351         p4 = self.ipv4_params
352
353         p4.remote_tun_if_host6 = "4444::4"
354         e = VppEnum.vl_api_ipsec_spd_action_t
355
356         VppIpsecSpdEntry(self,
357                          self.tun_spd,
358                          p4.scapy_tun_sa_id,
359                          self.pg1.remote_addr[p6.addr_type],
360                          self.pg1.remote_addr[p6.addr_type],
361                          p4.remote_tun_if_host6,
362                          p4.remote_tun_if_host6,
363                          0,
364                          priority=10,
365                          policy=e.IPSEC_API_SPD_ACTION_PROTECT,
366                          is_outbound=1).add_vpp_config()
367         d = DpoProto.DPO_PROTO_IP6
368         VppIpRoute(self,  p4.remote_tun_if_host6, p6.addr_len,
369                    [VppRoutePath(self.tun_if.remote_addr[p6.addr_type],
370                                  0xffffffff,
371                                  proto=d)]).add_vpp_config()
372
373         old_name = self.tun4_encrypt_node_name
374         self.tun4_encrypt_node_name = "esp6-encrypt"
375         self.verify_tun_64(p4, count=63)
376         self.tun4_encrypt_node_name = old_name
377
378
379 class TestIpsecEspTun(TemplateIpsecEsp, IpsecTun46Tests):
380     """ Ipsec ESP - TUN encap tests """
381
382     def setUp(self):
383         self.ipv4_params = IPsecIPv4Params()
384         self.ipv6_params = IPsecIPv6Params()
385
386         c = (VppEnum.vl_api_tunnel_encap_decap_flags_t.
387              TUNNEL_API_ENCAP_DECAP_FLAG_ENCAP_COPY_DSCP)
388         c1 = c | (VppEnum.vl_api_tunnel_encap_decap_flags_t.
389                   TUNNEL_API_ENCAP_DECAP_FLAG_ENCAP_COPY_ECN)
390
391         self.ipv4_params.tun_flags = c
392         self.ipv6_params.tun_flags = c1
393
394         super(TestIpsecEspTun, self).setUp()
395
396     def gen_pkts(self, sw_intf, src, dst, count=1, payload_size=54):
397         # set the DSCP + ECN - flags are set to copy only DSCP
398         return [Ether(src=sw_intf.remote_mac, dst=sw_intf.local_mac) /
399                 IP(src=src, dst=dst, tos=5) /
400                 UDP(sport=4444, dport=4444) /
401                 Raw(b'X' * payload_size)
402                 for i in range(count)]
403
404     def gen_pkts6(self, sw_intf, src, dst, count=1, payload_size=54):
405         # set the DSCP + ECN - flags are set to copy both
406         return [Ether(src=sw_intf.remote_mac, dst=sw_intf.local_mac) /
407                 IPv6(src=src, dst=dst, tc=5) /
408                 UDP(sport=4444, dport=4444) /
409                 Raw(b'X' * payload_size)
410                 for i in range(count)]
411
412     def verify_encrypted(self, p, sa, rxs):
413         # just check that only the DSCP is copied
414         for rx in rxs:
415             self.assertEqual(rx[IP].tos, 4)
416
417     def verify_encrypted6(self, p, sa, rxs):
418         # just check that the DSCP & ECN are copied
419         for rx in rxs:
420             self.assertEqual(rx[IPv6].tc, 5)
421
422
423 class TestIpsecEspTun2(TemplateIpsecEsp, IpsecTun46Tests):
424     """ Ipsec ESP - TUN DSCP tests """
425
426     def setUp(self):
427         self.ipv4_params = IPsecIPv4Params()
428         self.ipv6_params = IPsecIPv6Params()
429
430         self.ipv4_params.dscp = VppEnum.vl_api_ip_dscp_t.IP_API_DSCP_EF
431         self.ipv6_params.dscp = VppEnum.vl_api_ip_dscp_t.IP_API_DSCP_AF11
432
433         super(TestIpsecEspTun2, self).setUp()
434
435     def gen_pkts(self, sw_intf, src, dst, count=1, payload_size=54):
436         # set the DSCP + ECN - flags are set to copy only DSCP
437         return [Ether(src=sw_intf.remote_mac, dst=sw_intf.local_mac) /
438                 IP(src=src, dst=dst) /
439                 UDP(sport=4444, dport=4444) /
440                 Raw(b'X' * payload_size)
441                 for i in range(count)]
442
443     def gen_pkts6(self, sw_intf, src, dst, count=1, payload_size=54):
444         # set the DSCP + ECN - flags are set to copy both
445         return [Ether(src=sw_intf.remote_mac, dst=sw_intf.local_mac) /
446                 IPv6(src=src, dst=dst) /
447                 UDP(sport=4444, dport=4444) /
448                 Raw(b'X' * payload_size)
449                 for i in range(count)]
450
451     def verify_encrypted(self, p, sa, rxs):
452         # just check that only the DSCP is copied
453         for rx in rxs:
454             self.assertEqual(rx[IP].tos,
455                              VppEnum.vl_api_ip_dscp_t.IP_API_DSCP_EF << 2)
456
457     def verify_encrypted6(self, p, sa, rxs):
458         # just check that the DSCP & ECN are copied
459         for rx in rxs:
460             self.assertEqual(rx[IPv6].tc,
461                              VppEnum.vl_api_ip_dscp_t.IP_API_DSCP_AF11 << 2)
462
463
464 class TestIpsecEsp2(TemplateIpsecEsp, IpsecTcpTests):
465     """ Ipsec ESP - TCP tests """
466     pass
467
468
469 class TestIpsecEspHandoff(TemplateIpsecEsp,
470                           IpsecTun6HandoffTests,
471                           IpsecTun4HandoffTests):
472     """ Ipsec ESP - handoff tests """
473     pass
474
475
476 class TemplateIpsecEspUdp(ConfigIpsecESP):
477     """
478     UDP encapped ESP
479     """
480
481     @classmethod
482     def setUpClass(cls):
483         super(TemplateIpsecEspUdp, cls).setUpClass()
484
485     @classmethod
486     def tearDownClass(cls):
487         super(TemplateIpsecEspUdp, cls).tearDownClass()
488
489     def setUp(self):
490         super(TemplateIpsecEspUdp, self).setUp()
491         self.net_objs = []
492         self.tun_if = self.pg0
493         self.tra_if = self.pg2
494         self.logger.info(self.vapi.ppcli("show int addr"))
495
496         p = self.ipv4_params
497         p.flags = (VppEnum.vl_api_ipsec_sad_flags_t.
498                    IPSEC_API_SAD_FLAG_UDP_ENCAP)
499         p.nat_header = UDP(sport=5454, dport=4500)
500
501         self.tra_spd = VppIpsecSpd(self, self.tra_spd_id)
502         self.tra_spd.add_vpp_config()
503         VppIpsecSpdItfBinding(self, self.tra_spd,
504                               self.tra_if).add_vpp_config()
505
506         self.config_esp_tra(p)
507         config_tra_params(p, self.encryption_type)
508
509         self.tun_spd = VppIpsecSpd(self, self.tun_spd_id)
510         self.tun_spd.add_vpp_config()
511         VppIpsecSpdItfBinding(self, self.tun_spd,
512                               self.tun_if).add_vpp_config()
513
514         self.config_esp_tun(p)
515         self.logger.info(self.vapi.ppcli("show ipsec all"))
516
517         d = DpoProto.DPO_PROTO_IP4
518         VppIpRoute(self,  p.remote_tun_if_host, p.addr_len,
519                    [VppRoutePath(self.tun_if.remote_addr[p.addr_type],
520                                  0xffffffff,
521                                  proto=d)]).add_vpp_config()
522
523     def tearDown(self):
524         super(TemplateIpsecEspUdp, self).tearDown()
525
526     def show_commands_at_teardown(self):
527         self.logger.info(self.vapi.cli("show hardware"))
528
529
530 class TestIpsecEspUdp(TemplateIpsecEspUdp, IpsecTra4Tests):
531     """ Ipsec NAT-T ESP UDP tests """
532     pass
533
534
535 class MyParameters():
536     def __init__(self):
537         self.engines = ["ia32", "ipsecmb", "openssl"]
538         flag_esn = VppEnum.vl_api_ipsec_sad_flags_t.IPSEC_API_SAD_FLAG_USE_ESN
539         self.flags = [0, flag_esn]
540         # foreach crypto algorithm
541         self.algos = {
542             'AES-GCM-128/NONE': {
543                   'vpp-crypto': (VppEnum.vl_api_ipsec_crypto_alg_t.
544                                  IPSEC_API_CRYPTO_ALG_AES_GCM_128),
545                   'vpp-integ': (VppEnum.vl_api_ipsec_integ_alg_t.
546                                 IPSEC_API_INTEG_ALG_NONE),
547                   'scapy-crypto': "AES-GCM",
548                   'scapy-integ': "NULL",
549                   'key': b"JPjyOWBeVEQiMe7h",
550                   'salt': 0},
551             'AES-GCM-192/NONE': {
552                   'vpp-crypto': (VppEnum.vl_api_ipsec_crypto_alg_t.
553                                  IPSEC_API_CRYPTO_ALG_AES_GCM_192),
554                   'vpp-integ': (VppEnum.vl_api_ipsec_integ_alg_t.
555                                 IPSEC_API_INTEG_ALG_NONE),
556                   'scapy-crypto': "AES-GCM",
557                   'scapy-integ': "NULL",
558                   'key': b"JPjyOWBeVEQiMe7h01234567",
559                   'salt': 1010},
560             'AES-GCM-256/NONE': {
561                   'vpp-crypto': (VppEnum.vl_api_ipsec_crypto_alg_t.
562                                  IPSEC_API_CRYPTO_ALG_AES_GCM_256),
563                   'vpp-integ': (VppEnum.vl_api_ipsec_integ_alg_t.
564                                 IPSEC_API_INTEG_ALG_NONE),
565                   'scapy-crypto': "AES-GCM",
566                   'scapy-integ': "NULL",
567                   'key': b"JPjyOWBeVEQiMe7h0123456787654321",
568                   'salt': 2020},
569             'AES-CBC-128/MD5-96': {
570                   'vpp-crypto': (VppEnum.vl_api_ipsec_crypto_alg_t.
571                                  IPSEC_API_CRYPTO_ALG_AES_CBC_128),
572                   'vpp-integ': (VppEnum.vl_api_ipsec_integ_alg_t.
573                                 IPSEC_API_INTEG_ALG_MD5_96),
574                   'scapy-crypto': "AES-CBC",
575                   'scapy-integ': "HMAC-MD5-96",
576                   'salt': 0,
577                   'key': b"JPjyOWBeVEQiMe7h"},
578             'AES-CBC-192/SHA1-96': {
579                   'vpp-crypto': (VppEnum.vl_api_ipsec_crypto_alg_t.
580                                  IPSEC_API_CRYPTO_ALG_AES_CBC_192),
581                   'vpp-integ': (VppEnum.vl_api_ipsec_integ_alg_t.
582                                 IPSEC_API_INTEG_ALG_SHA1_96),
583                   'scapy-crypto': "AES-CBC",
584                   'scapy-integ': "HMAC-SHA1-96",
585                   'salt': 0,
586                   'key': b"JPjyOWBeVEQiMe7hJPjyOWBe"},
587             'AES-CBC-256/SHA1-96': {
588                   'vpp-crypto': (VppEnum.vl_api_ipsec_crypto_alg_t.
589                                  IPSEC_API_CRYPTO_ALG_AES_CBC_256),
590                   'vpp-integ': (VppEnum.vl_api_ipsec_integ_alg_t.
591                                 IPSEC_API_INTEG_ALG_SHA1_96),
592                   'scapy-crypto': "AES-CBC",
593                   'scapy-integ': "HMAC-SHA1-96",
594                   'salt': 0,
595                   'key': b"JPjyOWBeVEQiMe7hJPjyOWBeVEQiMe7h"},
596             '3DES-CBC/SHA1-96': {
597                   'vpp-crypto': (VppEnum.vl_api_ipsec_crypto_alg_t.
598                                  IPSEC_API_CRYPTO_ALG_3DES_CBC),
599                   'vpp-integ': (VppEnum.vl_api_ipsec_integ_alg_t.
600                                 IPSEC_API_INTEG_ALG_SHA1_96),
601                   'scapy-crypto': "3DES",
602                   'scapy-integ': "HMAC-SHA1-96",
603                   'salt': 0,
604                   'key': b"JPjyOWBeVEQiMe7h00112233"},
605             'NONE/SHA1-96': {
606                   'vpp-crypto': (VppEnum.vl_api_ipsec_crypto_alg_t.
607                                  IPSEC_API_CRYPTO_ALG_NONE),
608                   'vpp-integ': (VppEnum.vl_api_ipsec_integ_alg_t.
609                                 IPSEC_API_INTEG_ALG_SHA1_96),
610                   'scapy-crypto': "NULL",
611                   'scapy-integ': "HMAC-SHA1-96",
612                   'salt': 0,
613                   'key': b"JPjyOWBeVEQiMe7h00112233"}}
614
615
616 class RunTestIpsecEspAll(ConfigIpsecESP,
617                          IpsecTra4, IpsecTra6,
618                          IpsecTun4, IpsecTun6):
619     """ Ipsec ESP all Algos """
620
621     def setUp(self):
622         super(RunTestIpsecEspAll, self).setUp()
623         test_args = str.split(self.__doc__, " ")
624
625         params = MyParameters()
626         self.engine = test_args[0]
627         self.flag = params.flags[0]
628         if test_args[1] == 'ESN':
629             self.flag = params.flags[1]
630
631         self.algo = params.algos[test_args[2]]
632
633     def tearDown(self):
634         super(RunTestIpsecEspAll, self).tearDown()
635
636     def run_test(self):
637         self.run_a_test(self.engine, self.flag, self.algo)
638
639     def run_a_test(self, engine, flag, algo, payload_size=None):
640         if engine == "ia32":
641             engine = "native"
642         self.vapi.cli("set crypto handler all %s" % engine)
643
644         self.ipv4_params = IPsecIPv4Params()
645         self.ipv6_params = IPsecIPv6Params()
646
647         self.params = {self.ipv4_params.addr_type:
648                        self.ipv4_params,
649                        self.ipv6_params.addr_type:
650                        self.ipv6_params}
651
652         for _, p in self.params.items():
653             p.auth_algo_vpp_id = algo['vpp-integ']
654             p.crypt_algo_vpp_id = algo['vpp-crypto']
655             p.crypt_algo = algo['scapy-crypto']
656             p.auth_algo = algo['scapy-integ']
657             p.crypt_key = algo['key']
658             p.salt = algo['salt']
659             p.flags = p.flags | flag
660
661         self.reporter.send_keep_alive(self)
662
663         #
664         # configure the SPDs. SAs, etc
665         #
666         self.config_network(self.params.values())
667
668         #
669         # run some traffic.
670         #  An exhautsive 4o6, 6o4 is not necessary
671         #  for each algo
672         #
673         self.verify_tra_basic6(count=NUM_PKTS)
674         self.verify_tra_basic4(count=NUM_PKTS)
675         self.verify_tun_66(self.params[socket.AF_INET6],
676                            count=NUM_PKTS)
677         #
678         # Use an odd-byte payload size to check for correct padding.
679         #
680         # 49 + 2 == 51 which should pad +1 to 52 for 4 byte alignment, +5
681         # to 56 for 8 byte alignment, and +13 to 64 for 64 byte alignment.
682         # This should catch bugs where the code is incorrectly over-padding
683         # for algorithms that don't require it
684         psz = 49 - len(IP()/ICMP()) if payload_size is None else payload_size
685         self.verify_tun_44(self.params[socket.AF_INET],
686                            count=NUM_PKTS, payload_size=psz)
687
688         LARGE_PKT_SZ = [
689             1970,  # results in 2 chained buffers entering decrypt node
690                    # but leaving as simple buffer due to ICV removal (tra4)
691             2004,  # footer+ICV will be added to 2nd buffer (tun4)
692             4010,  # ICV ends up splitted accross 2 buffers in esp_decrypt
693                    # for transport4; transport6 takes normal path
694             4020,  # same as above but tra4 and tra6 are switched
695         ]
696         if self.engine in engines_supporting_chain_bufs:
697             for sz in LARGE_PKT_SZ:
698                 self.verify_tra_basic4(count=NUM_PKTS, payload_size=sz)
699                 self.verify_tra_basic6(count=NUM_PKTS, payload_size=sz)
700                 self.verify_tun_66(self.params[socket.AF_INET6],
701                                    count=NUM_PKTS, payload_size=sz)
702                 self.verify_tun_44(self.params[socket.AF_INET],
703                                    count=NUM_PKTS, payload_size=sz)
704
705         #
706         # remove the SPDs, SAs, etc
707         #
708         self.unconfig_network()
709
710         #
711         # reconfigure the network and SA to run the
712         # anti replay tests
713         #
714         self.config_network(self.params.values())
715         self.verify_tra_anti_replay()
716         self.unconfig_network()
717
718 #
719 # To generate test classes, do:
720 #   grep '# GEN' test_ipsec_esp.py | sed -e 's/# GEN //g' | bash
721 #
722 # GEN for ENG in ia32 ipsecmb openssl; do \
723 # GEN   for FLG in noESN ESN; do for ALG in AES-GCM-128/NONE \
724 # GEN     AES-GCM-192/NONE AES-GCM-256/NONE AES-CBC-128/MD5-96 \
725 # GEN     AES-CBC-192/SHA1-96 AES-CBC-256/SHA1-96 \
726 # GEN     3DES-CBC/SHA1-96 NONE/SHA1-96; do \
727 # GEN      [[ ${FLG} == "ESN" &&  ${ALG} == *"NONE" ]] && continue
728 # GEN      echo -e "\n\nclass Test_${ENG}_${FLG}_${ALG}(RunTestIpsecEspAll):" |
729 # GEN             sed -e 's/-/_/g' -e 's#/#_#g' ; \
730 # GEN      echo '    """'$ENG $FLG $ALG IPSec test'"""' ;
731 # GEN      echo "    def test_ipsec(self):";
732 # GEN      echo "        self.run_test()";
733 # GEN done; done; done
734
735
736 class Test_ia32_noESN_AES_GCM_128_NONE(RunTestIpsecEspAll):
737     """ia32 noESN AES-GCM-128/NONE IPSec test"""
738     def test_ipsec(self):
739         self.run_test()
740
741
742 class Test_ia32_noESN_AES_GCM_192_NONE(RunTestIpsecEspAll):
743     """ia32 noESN AES-GCM-192/NONE IPSec test"""
744     def test_ipsec(self):
745         self.run_test()
746
747
748 class Test_ia32_noESN_AES_GCM_256_NONE(RunTestIpsecEspAll):
749     """ia32 noESN AES-GCM-256/NONE IPSec test"""
750     def test_ipsec(self):
751         self.run_test()
752
753
754 class Test_ia32_noESN_AES_CBC_128_MD5_96(RunTestIpsecEspAll):
755     """ia32 noESN AES-CBC-128/MD5-96 IPSec test"""
756     def test_ipsec(self):
757         self.run_test()
758
759
760 class Test_ia32_noESN_AES_CBC_192_SHA1_96(RunTestIpsecEspAll):
761     """ia32 noESN AES-CBC-192/SHA1-96 IPSec test"""
762     def test_ipsec(self):
763         self.run_test()
764
765
766 class Test_ia32_noESN_AES_CBC_256_SHA1_96(RunTestIpsecEspAll):
767     """ia32 noESN AES-CBC-256/SHA1-96 IPSec test"""
768     def test_ipsec(self):
769         self.run_test()
770
771
772 class Test_ia32_noESN_3DES_CBC_SHA1_96(RunTestIpsecEspAll):
773     """ia32 noESN 3DES-CBC/SHA1-96 IPSec test"""
774     def test_ipsec(self):
775         self.run_test()
776
777
778 class Test_ia32_noESN_NONE_SHA1_96(RunTestIpsecEspAll):
779     """ia32 noESN NONE/SHA1-96 IPSec test"""
780     def test_ipsec(self):
781         self.run_test()
782
783
784 class Test_ia32_ESN_AES_CBC_128_MD5_96(RunTestIpsecEspAll):
785     """ia32 ESN AES-CBC-128/MD5-96 IPSec test"""
786     def test_ipsec(self):
787         self.run_test()
788
789
790 class Test_ia32_ESN_AES_CBC_192_SHA1_96(RunTestIpsecEspAll):
791     """ia32 ESN AES-CBC-192/SHA1-96 IPSec test"""
792     def test_ipsec(self):
793         self.run_test()
794
795
796 class Test_ia32_ESN_AES_CBC_256_SHA1_96(RunTestIpsecEspAll):
797     """ia32 ESN AES-CBC-256/SHA1-96 IPSec test"""
798     def test_ipsec(self):
799         self.run_test()
800
801
802 class Test_ia32_ESN_3DES_CBC_SHA1_96(RunTestIpsecEspAll):
803     """ia32 ESN 3DES-CBC/SHA1-96 IPSec test"""
804     def test_ipsec(self):
805         self.run_test()
806
807
808 class Test_ia32_ESN_NONE_SHA1_96(RunTestIpsecEspAll):
809     """ia32 ESN NONE/SHA1-96 IPSec test"""
810     def test_ipsec(self):
811         self.run_test()
812
813
814 class Test_ipsecmb_noESN_AES_GCM_128_NONE(RunTestIpsecEspAll):
815     """ipsecmb noESN AES-GCM-128/NONE IPSec test"""
816     def test_ipsec(self):
817         self.run_test()
818
819
820 class Test_ipsecmb_noESN_AES_GCM_192_NONE(RunTestIpsecEspAll):
821     """ipsecmb noESN AES-GCM-192/NONE IPSec test"""
822     def test_ipsec(self):
823         self.run_test()
824
825
826 class Test_ipsecmb_noESN_AES_GCM_256_NONE(RunTestIpsecEspAll):
827     """ipsecmb noESN AES-GCM-256/NONE IPSec test"""
828     def test_ipsec(self):
829         self.run_test()
830
831
832 class Test_ipsecmb_noESN_AES_CBC_128_MD5_96(RunTestIpsecEspAll):
833     """ipsecmb noESN AES-CBC-128/MD5-96 IPSec test"""
834     def test_ipsec(self):
835         self.run_test()
836
837
838 class Test_ipsecmb_noESN_AES_CBC_192_SHA1_96(RunTestIpsecEspAll):
839     """ipsecmb noESN AES-CBC-192/SHA1-96 IPSec test"""
840     def test_ipsec(self):
841         self.run_test()
842
843
844 class Test_ipsecmb_noESN_AES_CBC_256_SHA1_96(RunTestIpsecEspAll):
845     """ipsecmb noESN AES-CBC-256/SHA1-96 IPSec test"""
846     def test_ipsec(self):
847         self.run_test()
848
849
850 class Test_ipsecmb_noESN_3DES_CBC_SHA1_96(RunTestIpsecEspAll):
851     """ipsecmb noESN 3DES-CBC/SHA1-96 IPSec test"""
852     def test_ipsec(self):
853         self.run_test()
854
855
856 class Test_ipsecmb_noESN_NONE_SHA1_96(RunTestIpsecEspAll):
857     """ipsecmb noESN NONE/SHA1-96 IPSec test"""
858     def test_ipsec(self):
859         self.run_test()
860
861
862 class Test_ipsecmb_ESN_AES_CBC_128_MD5_96(RunTestIpsecEspAll):
863     """ipsecmb ESN AES-CBC-128/MD5-96 IPSec test"""
864     def test_ipsec(self):
865         self.run_test()
866
867
868 class Test_ipsecmb_ESN_AES_CBC_192_SHA1_96(RunTestIpsecEspAll):
869     """ipsecmb ESN AES-CBC-192/SHA1-96 IPSec test"""
870     def test_ipsec(self):
871         self.run_test()
872
873
874 class Test_ipsecmb_ESN_AES_CBC_256_SHA1_96(RunTestIpsecEspAll):
875     """ipsecmb ESN AES-CBC-256/SHA1-96 IPSec test"""
876     def test_ipsec(self):
877         self.run_test()
878
879
880 class Test_ipsecmb_ESN_3DES_CBC_SHA1_96(RunTestIpsecEspAll):
881     """ipsecmb ESN 3DES-CBC/SHA1-96 IPSec test"""
882     def test_ipsec(self):
883         self.run_test()
884
885
886 class Test_ipsecmb_ESN_NONE_SHA1_96(RunTestIpsecEspAll):
887     """ipsecmb ESN NONE/SHA1-96 IPSec test"""
888     def test_ipsec(self):
889         self.run_test()
890
891
892 class Test_openssl_noESN_AES_GCM_128_NONE(RunTestIpsecEspAll):
893     """openssl noESN AES-GCM-128/NONE IPSec test"""
894     def test_ipsec(self):
895         self.run_test()
896
897
898 class Test_openssl_noESN_AES_GCM_192_NONE(RunTestIpsecEspAll):
899     """openssl noESN AES-GCM-192/NONE IPSec test"""
900     def test_ipsec(self):
901         self.run_test()
902
903
904 class Test_openssl_noESN_AES_GCM_256_NONE(RunTestIpsecEspAll):
905     """openssl noESN AES-GCM-256/NONE IPSec test"""
906     def test_ipsec(self):
907         self.run_test()
908
909
910 class Test_openssl_noESN_AES_CBC_128_MD5_96(RunTestIpsecEspAll):
911     """openssl noESN AES-CBC-128/MD5-96 IPSec test"""
912     def test_ipsec(self):
913         self.run_test()
914
915
916 class Test_openssl_noESN_AES_CBC_192_SHA1_96(RunTestIpsecEspAll):
917     """openssl noESN AES-CBC-192/SHA1-96 IPSec test"""
918     def test_ipsec(self):
919         self.run_test()
920
921
922 class Test_openssl_noESN_AES_CBC_256_SHA1_96(RunTestIpsecEspAll):
923     """openssl noESN AES-CBC-256/SHA1-96 IPSec test"""
924     def test_ipsec(self):
925         self.run_test()
926
927
928 class Test_openssl_noESN_3DES_CBC_SHA1_96(RunTestIpsecEspAll):
929     """openssl noESN 3DES-CBC/SHA1-96 IPSec test"""
930     def test_ipsec(self):
931         self.run_test()
932
933
934 class Test_openssl_noESN_NONE_SHA1_96(RunTestIpsecEspAll):
935     """openssl noESN NONE/SHA1-96 IPSec test"""
936     def test_ipsec(self):
937         self.run_test()
938
939
940 class Test_openssl_ESN_AES_CBC_128_MD5_96(RunTestIpsecEspAll):
941     """openssl ESN AES-CBC-128/MD5-96 IPSec test"""
942     def test_ipsec(self):
943         self.run_test()
944
945
946 class Test_openssl_ESN_AES_CBC_192_SHA1_96(RunTestIpsecEspAll):
947     """openssl ESN AES-CBC-192/SHA1-96 IPSec test"""
948     def test_ipsec(self):
949         self.run_test()
950
951
952 class Test_openssl_ESN_AES_CBC_256_SHA1_96(RunTestIpsecEspAll):
953     """openssl ESN AES-CBC-256/SHA1-96 IPSec test"""
954     def test_ipsec(self):
955         self.run_test()
956
957
958 class Test_openssl_ESN_3DES_CBC_SHA1_96(RunTestIpsecEspAll):
959     """openssl ESN 3DES-CBC/SHA1-96 IPSec test"""
960     def test_ipsec(self):
961         self.run_test()
962
963
964 class Test_openssl_ESN_NONE_SHA1_96(RunTestIpsecEspAll):
965     """openssl ESN NONE/SHA1-96 IPSec test"""
966     def test_ipsec(self):
967         self.run_test()
968
969
970 if __name__ == '__main__':
971     unittest.main(testRunner=VppTestRunner)