• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1% Tests for RFC5925 TCP Authentication Option (TCP-AO)
2~ tcp tcpao
3# Some data from https://datatracker.ietf.org/doc/html/draft-touch-tcpm-ao-test-vectors-02
4
5+ Test Utilities
6= Test Utilities
7
8# Tolerate all whitespace like py37+ bytes.fromhex
9def fromhex(hex):
10    return bytes(bytearray.fromhex(hex.replace(" ", "").replace("\n", "")))
11
12+ TCP-AO Test Vectors
13= TCP-AO Test Vectors Utilities
14from scapy.contrib import tcpao
15master_key = b"testvector"
16client_keyid = 61
17server_keyid = 84
18
19def check(
20        packet_hex,
21        traffic_key_hex,
22        mac_hex,
23        src_isn,
24        dst_isn,
25        include_options=True,
26        alg_name="HMAC-SHA-1-96",
27        sne=0,
28    ):
29        packet_bytes = fromhex(packet_hex)
30        # sanity check for ip version
31        ipv = orb(packet_bytes[0]) >> 4
32        if ipv == 4:
33            p = IP(fromhex(packet_hex))
34            assert p[IP].proto == socket.IPPROTO_TCP
35        elif ipv == 6:
36            p = IPv6(fromhex(packet_hex))
37            assert p[IPv6].nh == socket.IPPROTO_TCP
38        else:
39            raise ValueError("bad ipv={}".format(ipv))
40        # sanity check for seq/ack in SYN/ACK packets
41        if p[TCP].flags.S and p[TCP].flags.A is False:
42            assert p[TCP].seq == src_isn
43            assert p[TCP].ack == 0
44        if p[TCP].flags.S and p[TCP].flags.A:
45            assert p[TCP].seq == src_isn
46            assert p[TCP].ack == dst_isn + 1
47        # check option bytes in header
48        opt = get_tcpao(p[TCP])
49        assert opt is not None
50        assert opt.keyid in [client_keyid, server_keyid]
51        assert opt.rnextkeyid in [client_keyid, server_keyid]
52        assert opt.mac == fromhex(mac_hex), "match parsed mac"
53        # check traffic key
54        alg = get_alg(alg_name)
55        context_bytes = tcpao.build_context_from_packet(p, src_isn, dst_isn)
56        traffic_key = alg.kdf(master_key, context_bytes)
57        assert traffic_key == fromhex(traffic_key_hex), "match traffic key"
58        # check mac
59        message_bytes = tcpao.build_message_from_packet(
60            p, include_options=include_options, sne=sne
61        )
62        mac = alg.mac(traffic_key, message_bytes)
63        assert mac == fromhex(mac_hex), "match computed mac"
64
65= TCP-AO Test Vector 4.1.1: SHA-1 Send Syn
66client_isn_41x = 0xFBFBAB5A
67server_isn_41x = 0x11C14261
68
69check(
70    """
71    45 e0 00 4c dd 0f 40 00 ff 06 bf 6b 0a 0b 0c 0d
72    ac 1b 1c 1d e9 d7 00 b3 fb fb ab 5a 00 00 00 00
73    e0 02 ff ff ca c4 00 00 02 04 05 b4 01 03 03 08
74    04 02 08 0a 00 15 5a b7 00 00 00 00 1d 10 3d 54
75    2e e4 37 c6 f8 ed e6 d7 c4 d6 02 e7
76    """,
77    "6d 63 ef 1b 02 fe 15 09 d4 b1 40 27 07 fd 7b 04 16 ab b7 4f",
78    "2e e4 37 c6 f8 ed e6 d7 c4 d6 02 e7",
79    client_isn_41x,
80    0,
81)
82
83= TCP-AO Test Vector 4.1.2 SHA-1 Recv Syn-Ack
84check(
85    """
86    45 e0 00 4c 65 06 40 00 ff 06 37 75 ac 1b 1c 1d
87    0a 0b 0c 0d 00 b3 e9 d7 11 c1 42 61 fb fb ab 5b
88    e0 12 ff ff 37 76 00 00 02 04 05 b4 01 03 03 08
89    04 02 08 0a 84 a5 0b eb 00 15 5a b7 1d 10 54 3d
90    ee ab 0f e2 4c 30 10 81 51 16 b3 be
91    """,
92    "d9 e2 17 e4 83 4a 80 ca 2f 3f d8 de 2e 41 b8 e6 79 7f ea 96",
93    "ee ab 0f e2 4c 30 10 81 51 16 b3 be",
94    server_isn_41x,
95    client_isn_41x,
96)
97
98= TCP-AO Test Vector 4.1.3 SHA-1 Send Other
99check(
100    """
101    45 e0 00 87 36 a1 40 00 ff 06 65 9f 0a 0b 0c 0d
102    ac 1b 1c 1d e9 d7 00 b3 fb fb ab 5b 11 c1 42 62
103    c0 18 01 04 a1 62 00 00 01 01 08 0a 00 15 5a c1
104    84 a5 0b eb 1d 10 3d 54 70 64 cf 99 8c c6 c3 15
105    c2 c2 e2 bf ff ff ff ff ff ff ff ff ff ff ff ff
106    ff ff ff ff 00 43 01 04 da bf 00 b4 0a 0b 0c 0d
107    26 02 06 01 04 00 01 00 01 02 02 80 00 02 02 02
108    00 02 02 42 00 02 06 41 04 00 00 da bf 02 08 40
109    06 00 64 00 01 01 00
110    """,
111    "d2 e5 9c 65 ff c7 b1 a3 93 47 65 64 63 b7 0e dc 24 a1 3d 71",
112    "70 64 cf 99 8c c6 c3 15 c2 c2 e2 bf",
113    client_isn_41x,
114    server_isn_41x,
115)
116
117= TCP-AO Test Vector 4.1.4 SHA-1 Recv Other
118check(
119    """
120    45 e0 00 87 1f a9 40 00 ff 06 7c 97 ac 1b 1c 1d
121    0a 0b 0c 0d 00 b3 e9 d7 11 c1 42 62 fb fb ab 9e
122    c0 18 01 00 40 0c 00 00 01 01 08 0a 84 a5 0b f5
123    00 15 5a c1 1d 10 54 3d a6 3f 0e cb bb 2e 63 5c
124    95 4d ea c7 ff ff ff ff ff ff ff ff ff ff ff ff
125    ff ff ff ff 00 43 01 04 da c0 00 b4 ac 1b 1c 1d
126    26 02 06 01 04 00 01 00 01 02 02 80 00 02 02 02
127    00 02 02 42 00 02 06 41 04 00 00 da c0 02 08 40
128    06 00 64 00 01 01 00
129    """,
130    "d9 e2 17 e4 83 4a 80 ca 2f 3f d8 de 2e 41 b8 e6 79 7f ea 96",
131    "a6 3f 0e cb bb 2e 63 5c 95 4d ea c7",
132    server_isn_41x,
133    client_isn_41x,
134)
135
136= TCP-AO Test Vector 4.2.1
137client_isn_42x = 0xCB0EFBEE
138server_isn_42x = 0xACD5B5E1
139check(
140    """
141    45 e0 00 4c 53 99 40 00 ff 06 48 e2 0a 0b 0c 0d
142    ac 1b 1c 1d ff 12 00 b3 cb 0e fb ee 00 00 00 00
143    e0 02 ff ff 54 1f 00 00 02 04 05 b4 01 03 03 08
144    04 02 08 0a 00 02 4c ce 00 00 00 00 1d 10 3d 54
145    80 af 3c fe b8 53 68 93 7b 8f 9e c2
146    """,
147    "30 ea a1 56 0c f0 be 57 da b5 c0 45 22 9f b1 0a 42 3c d7 ea",
148    "80 af 3c fe b8 53 68 93 7b 8f 9e c2",
149    client_isn_42x,
150    0,
151    include_options=False,
152)
153
154= TCP-AO Test Vector 4.2.2
155check(
156    """
157    45 e0 00 4c 32 84 40 00 ff 06 69 f7 ac 1b 1c 1d
158    0a 0b 0c 0d 00 b3 ff 12 ac d5 b5 e1 cb 0e fb ef
159    e0 12 ff ff 38 8e 00 00 02 04 05 b4 01 03 03 08
160    04 02 08 0a 57 67 72 f3 00 02 4c ce 1d 10 54 3d
161    09 30 6f 9a ce a6 3a 8c 68 cb 9a 70
162    """,
163    "b5 b2 89 6b b3 66 4e 81 76 b0 ed c6 e7 99 52 41 01 a8 30 7f",
164    "09 30 6f 9a ce a6 3a 8c 68 cb 9a 70",
165    server_isn_42x,
166    client_isn_42x,
167    include_options=False,
168)
169
170= TCP-AO Test Vector 4.2.3
171check(
172    """
173    45 e0 00 87 a8 f5 40 00 ff 06 f3 4a 0a 0b 0c 0d
174    ac 1b 1c 1d ff 12 00 b3 cb 0e fb ef ac d5 b5 e2
175    c0 18 01 04 6c 45 00 00 01 01 08 0a 00 02 4c ce
176    57 67 72 f3 1d 10 3d 54 71 06 08 cc 69 6c 03 a2
177    71 c9 3a a5 ff ff ff ff ff ff ff ff ff ff ff ff
178    ff ff ff ff 00 43 01 04 da bf 00 b4 0a 0b 0c 0d
179    26 02 06 01 04 00 01 00 01 02 02 80 00 02 02 02
180    00 02 02 42 00 02 06 41 04 00 00 da bf 02 08 40
181    06 00 64 00 01 01 00
182    """,
183    "f3 db 17 93 d7 91 0e cd 80 6c 34 f1 55 ea 1f 00 34 59 53 e3",
184    "71 06 08 cc 69 6c 03 a2 71 c9 3a a5",
185    client_isn_42x,
186    server_isn_42x,
187    include_options=False,
188)
189
190= TCP-AO Test Vector 4.2.4
191check(
192    """
193    45 e0 00 87 54 37 40 00 ff 06 48 09 ac 1b 1c 1d
194    0a 0b 0c 0d 00 b3 ff 12 ac d5 b5 e2 cb 0e fc 32
195    c0 18 01 00 46 b6 00 00 01 01 08 0a 57 67 72 f3
196    00 02 4c ce 1d 10 54 3d 97 76 6e 48 ac 26 2d e9
197    ae 61 b4 f9 ff ff ff ff ff ff ff ff ff ff ff ff
198    ff ff ff ff 00 43 01 04 da c0 00 b4 ac 1b 1c 1d
199    26 02 06 01 04 00 01 00 01 02 02 80 00 02 02 02
200    00 02 02 42 00 02 06 41 04 00 00 da c0 02 08 40
201    06 00 64 00 01 01 00
202    """,
203    "b5 b2 89 6b b3 66 4e 81 76 b0 ed c6 e7 99 52 41 01 a8 30 7f",
204    "97 76 6e 48 ac 26 2d e9 ae 61 b4 f9",
205    server_isn_42x,
206    client_isn_42x,
207    include_options=False,
208)
209
210= TCP-AO Test Vector 5.1.1
211check(
212    """
213    45 e0 00 4c 7b 9f 40 00 ff 06 20 dc 0a 0b 0c 0d
214    ac 1b 1c 1d c4 fa 00 b3 78 7a 1d df 00 00 00 00
215    e0 02 ff ff 5a 0f 00 00 02 04 05 b4 01 03 03 08
216    04 02 08 0a 00 01 7e d0 00 00 00 00 1d 10 3d 54
217    e4 77 e9 9c 80 40 76 54 98 e5 50 91
218    """,
219    "f5 b8 b3 d5 f3 4f db b6 eb 8d 4a b9 66 0e 60 e3",
220    "e4 77 e9 9c 80 40 76 54 98 e5 50 91",
221    0x787A1DDF,
222    0,
223    include_options=True,
224    alg_name="AES-128-CMAC-96",
225)
226
227= TCP-AO Test Vector 6.1.1
228client_isn_61x = 0x176A833F
229server_isn_61x = 0x3F51994B
230check(
231    """
232    6e 08 91 dc 00 38 06 40 fd 00 00 00 00 00 00 00
233    00 00 00 00 00 00 00 01 fd 00 00 00 00 00 00 00
234    00 00 00 00 00 00 00 02 f7 e4 00 b3 17 6a 83 3f
235    00 00 00 00 e0 02 ff ff 47 21 00 00 02 04 05 a0
236    01 03 03 08 04 02 08 0a 00 41 d0 87 00 00 00 00
237    1d 10 3d 54 90 33 ec 3d 73 34 b6 4c 5e dd 03 9f
238    """,
239    "62 5e c0 9d 57 58 36 ed c9 b6 42 84 18 bb f0 69 89 a3 61 bb",
240    "90 33 ec 3d 73 34 b6 4c 5e dd 03 9f",
241    client_isn_61x,
242    0,
243    include_options=True,
244)
245
246= TCP-AO Test Vector 6.1.2
247check(
248    """
249    6e 01 00 9e 00 38 06 40 fd 00 00 00 00 00 00 00
250    00 00 00 00 00 00 00 02 fd 00 00 00 00 00 00 00
251    00 00 00 00 00 00 00 01 00 b3 f7 e4 3f 51 99 4b
252    17 6a 83 40 e0 12 ff ff bf ec 00 00 02 04 05 a0
253    01 03 03 08 04 02 08 0a bd 33 12 9b 00 41 d0 87
254    1d 10 54 3d f1 cb a3 46 c3 52 61 63 f7 1f 1f 55
255    """,
256    "e4 a3 7a da 2a 0a fc a8 71 14 34 91 3f e1 38 c7 71 eb cb 4a",
257    "f1 cb a3 46 c3 52 61 63 f7 1f 1f 55",
258    server_isn_61x,
259    client_isn_61x,
260    include_options=True,
261)
262
263= TCP-AO Test Vector 6.2.2
264client_isn_62x = 0x020C1E69
265server_isn_62x = 0xEBA3734D
266check(
267    """
268    6e 0a 7e 1f 00 38 06 40 fd 00 00 00 00 00 00 00
269    00 00 00 00 00 00 00 02 fd 00 00 00 00 00 00 00
270    00 00 00 00 00 00 00 01 00 b3 c6 cd eb a3 73 4d
271    02 0c 1e 6a e0 12 ff ff 77 4d 00 00 02 04 05 a0
272    01 03 03 08 04 02 08 0a 5e c9 9b 70 00 9d b9 5b
273    1d 10 54 3d 3c 54 6b ad 97 43 f1 2d f8 b8 01 0d
274    """,
275    "40 51 08 94 7f 99 65 75 e7 bd bc 26 d4 02 16 a2 c7 fa 91 bd",
276    "3c 54 6b ad 97 43 f1 2d f8 b8 01 0d",
277    server_isn_62x,
278    client_isn_62x,
279    include_options=False,
280)
281
282= TCP-AO Test Vector 6.2.4
283check(
284    """
285    6e 0a 7e 1f 00 73 06 40 fd 00 00 00 00 00 00 00
286    00 00 00 00 00 00 00 02 fd 00 00 00 00 00 00 00
287    00 00 00 00 00 00 00 01 00 b3 c6 cd eb a3 73 4e
288    02 0c 1e ad c0 18 01 00 71 6a 00 00 01 01 08 0a
289    5e c9 9b 7a 00 9d b9 65 1d 10 54 3d 55 9a 81 94
290    45 b4 fd e9 8d 9e 13 17 ff ff ff ff ff ff ff ff
291    ff ff ff ff ff ff ff ff 00 43 01 04 fd e8 00 b4
292    01 01 01 7a 26 02 06 01 04 00 01 00 01 02 02 80
293    00 02 02 02 00 02 02 42 00 02 06 41 04 00 00 fd
294    e8 02 08 40 06 00 64 00 01 01 00
295    """,
296    "40 51 08 94 7f 99 65 75 e7 bd bc 26 d4 02 16 a2 c7 fa 91 bd",
297    "55 9a 81 94 45 b4 fd e9 8d 9e 13 17",
298    server_isn_62x,
299    client_isn_62x,
300    include_options=False,
301)
302
303= TCP-AO Test Vector 7.1.2
304server_isn_71x = 0xA6744ECB
305client_isn_71x = 0x193CCCEC
306check(
307    """
308    6e 06 15 20 00 38 06 40 fd 00 00 00 00 00 00 00
309    00 00 00 00 00 00 00 02 fd 00 00 00 00 00 00 00
310    00 00 00 00 00 00 00 01 00 b3 f8 5a a6 74 4e cb
311    19 3c cc ed e0 12 ff ff ea bb 00 00 02 04 05 a0
312    01 03 03 08 04 02 08 0a 71 da ab c8 13 e4 ab 99
313    1d 10 54 3d dc 28 43 a8 4e 78 a6 bc fd c5 ed 80
314    """,
315    "cf 1b 1e 22 5e 06 a6 36 16 76 4a 06 7b 46 f4 b1",
316    "dc 28 43 a8 4e 78 a6 bc fd c5 ed 80",
317    server_isn_71x,
318    client_isn_71x,
319    alg_name="AES-128-CMAC-96",
320    include_options=True,
321)
322
323= TCP-AO Test Vector 7.1.4
324check(
325    """
326    6e 06 15 20 00 73 06 40 fd 00 00 00 00 00 00 00
327    00 00 00 00 00 00 00 02 fd 00 00 00 00 00 00 00
328    00 00 00 00 00 00 00 01 00 b3 f8 5a a6 74 4e cc
329    19 3c cd 30 c0 18 01 00 52 f4 00 00 01 01 08 0a
330    71 da ab d3 13 e4 ab a3 1d 10 54 3d c1 06 9b 7d
331    fd 3d 69 3a 6d f3 f2 89 ff ff ff ff ff ff ff ff
332    ff ff ff ff ff ff ff ff 00 43 01 04 fd e8 00 b4
333    01 01 01 7a 26 02 06 01 04 00 01 00 01 02 02 80
334    00 02 02 02 00 02 02 42 00 02 06 41 04 00 00 fd
335    e8 02 08 40 06 00 64 00 01 01 00
336    """,
337    "cf 1b 1e 22 5e 06 a6 36 16 76 4a 06 7b 46 f4 b1",
338    "c1 06 9b 7d fd 3d 69 3a 6d f3 f2 89",
339    server_isn_71x,
340    client_isn_71x,
341    alg_name="AES-128-CMAC-96",
342    include_options=True,
343)
344
345+ TCP-AO Signature API
346= TCP-AO sign SYN packet build from scratch
347master_key = b"hello"
348alg = TCPAOAlg_HMAC_SHA1()
349keyid = 12
350rnextkeyid = 34
351
352p = IP() / TCP()
353p[TCP].flags == "S"
354sisn = p[TCP].seq
355disn = 0
356
357# sign
358traffic_key = calc_tcpao_traffic_key(p, alg, master_key, sisn, disn)
359sign_tcpao(p, alg, traffic_key, keyid, rnextkeyid)
360mac = calc_tcpao_mac(p, alg, traffic_key)
361
362# parse
363p2 = IP(raw(p))
364ao = get_tcpao(p2[TCP])
365ao is not None
366ao.keyid == keyid
367ao.rnextkeyid == rnextkeyid
368ao.mac == mac
369
370# calculate signature again on parsed packet
371traffic_key2 = calc_tcpao_traffic_key(p2, alg, master_key, p2[TCP].seq, 0)
372traffic_key == traffic_key2
373mac2 = calc_tcpao_mac(p2, alg, traffic_key2)
374mac == mac2
375