Skip to content

Commit 6a7a144

Browse files
Merge pull request #143 from gilles-peskine-arm/defragment-incremental-framework
Incremental TLS handshake defragmentation tests
2 parents 0a94d05 + 8d85112 commit 6a7a144

File tree

1 file changed

+59
-19
lines changed

1 file changed

+59
-19
lines changed

scripts/generate_tls_handshake_tests.py

Lines changed: 59 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414

1515
from mbedtls_framework import tls_test_case
1616
from mbedtls_framework import typing_util
17-
1817
from mbedtls_framework.tls_test_case import Side, Version
18+
import translate_ciphers
1919

2020

2121
# Assume that a TLS 1.2 ClientHello used in these tests will be at most
@@ -26,10 +26,14 @@
2626
TLS_HANDSHAKE_FRAGMENT_MIN_LENGTH = 4
2727

2828
def write_tls_handshake_defragmentation_test(
29+
#pylint: disable=too-many-arguments
2930
out: typing_util.Writable,
3031
side: Side,
3132
length: Optional[int],
32-
version: Optional[Version] = None
33+
version: Optional[Version] = None,
34+
cipher: Optional[str] = None,
35+
etm: Optional[bool] = None, #encrypt-then-mac (only relevant for CBC)
36+
variant: str = ''
3337
) -> None:
3438
"""Generate one TLS handshake defragmentation test.
3539
@@ -52,17 +56,6 @@ def write_tls_handshake_defragmentation_test(
5256
description = f'Handshake defragmentation on {side.name.lower()}: {description}'
5357
tc = tls_test_case.TestCase(description)
5458

55-
if version == Version.TLS12 and \
56-
length is not None and \
57-
length >= TLS_HANDSHAKE_FRAGMENT_MIN_LENGTH and \
58-
length < 16 and \
59-
side == side.CLIENT:
60-
# Skip test cases where the Finished message is fragmented in TLS 1.2.
61-
# This is currently buggy when the symmetric encryption used an
62-
# explicit IV (CBC, GCM or CCM; Chachapoly and null work, as does
63-
# TLS 1.3, because they use a purely implicit IV).
64-
tc.requirements.append('skip_next_test')
65-
6659
if version is not None:
6760
their_args += ' ' + version.openssl_option()
6861
# Emit a version requirement, because we're forcing the version via
@@ -80,7 +73,7 @@ def write_tls_handshake_defragmentation_test(
8073
# or at runtime), the TLS 1.2 ClientHello parser only sees
8174
# the first fragment of the ClientHello.
8275
tc.requirements.append('requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3')
83-
tc.description += ' TLS 1.3 ClientHello -> 1.2 Handshake'
76+
tc.description += ' with 1.3 support'
8477

8578
# To guarantee that the handhake messages are large enough and need to be
8679
# split into fragments, the tests require certificate authentication.
@@ -100,7 +93,6 @@ def write_tls_handshake_defragmentation_test(
10093

10194
if length is None:
10295
forbidden_patterns = [
103-
'reassembled record',
10496
'waiting for more fragments',
10597
]
10698
wanted_patterns = []
@@ -121,10 +113,38 @@ def write_tls_handshake_defragmentation_test(
121113
forbidden_patterns = []
122114
wanted_patterns = [
123115
'reassembled record',
124-
fr'handshake fragment: 0 \.\. {length} of [0-9]\+ msglen {length}',
125-
fr'waiting for more fragments ({length} of',
116+
fr'initial handshake fragment: {length}, 0\.\.{length} of [0-9]\+',
117+
fr'subsequent handshake fragment: [0-9]\+, {length}\.\.',
118+
fr'Prepare: waiting for more handshake fragments {length}/',
119+
fr'Consume: waiting for more handshake fragments {length}/',
120+
]
121+
122+
if cipher is not None:
123+
mbedtls_cipher = translate_ciphers.translate_mbedtls(cipher)
124+
if side == Side.CLIENT:
125+
our_args += ' force_ciphersuite=' + mbedtls_cipher
126+
if 'NULL' in cipher:
127+
their_args += ' -cipher ALL@SECLEVEL=0:COMPLEMENTOFALL@SECLEVEL=0'
128+
else:
129+
# For TLS 1.2, when Mbed TLS is the server, we must force the
130+
# cipher suite on the client side, because passing
131+
# force_ciphersuite to ssl_server2 would force a TLS-1.2-only
132+
# server, which does not support a fragmented ClientHello.
133+
tc.requirements.append('requires_ciphersuite_enabled ' + mbedtls_cipher)
134+
their_args += ' -cipher ' + translate_ciphers.translate_ossl(cipher)
135+
if 'NULL' in cipher:
136+
their_args += '@SECLEVEL=0'
137+
138+
if etm is not None:
139+
if etm:
140+
tc.requirements.append('requires_config_enabled MBEDTLS_SSL_ENCRYPT_THEN_MAC')
141+
our_args += ' etm=' + str(int(etm))
142+
(wanted_patterns if etm else forbidden_patterns)[0:0] = [
143+
'using encrypt then mac',
126144
]
127145

146+
tc.description += variant
147+
128148
if side == Side.CLIENT:
129149
tc.client = '$P_CLI debug_level=4' + our_args
130150
tc.server = '$O_NEXT_SRV' + their_args
@@ -139,13 +159,33 @@ def write_tls_handshake_defragmentation_test(
139159
tc.forbidden_server_patterns = forbidden_patterns
140160
tc.write(out)
141161

162+
163+
CIPHERS_FOR_TLS12_HANDSHAKE_DEFRAGMENTATION = [
164+
(None, 'default', None),
165+
('TLS_ECDHE_ECDSA_WITH_NULL_SHA', 'null', None),
166+
('TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256', 'ChachaPoly', None),
167+
('TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256', 'GCM', None),
168+
('TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256', 'CBC, etm=n', False),
169+
('TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256', 'CBC, etm=y', True),
170+
]
171+
142172
def write_tls_handshake_defragmentation_tests(out: typing_util.Writable) -> None:
143173
"""Generate TLS handshake defragmentation tests."""
144174
for side in Side.CLIENT, Side.SERVER:
145175
write_tls_handshake_defragmentation_test(out, side, None)
146176
for length in [512, 513, 256, 128, 64, 36, 32, 16, 13, 5, 4, 3]:
147-
write_tls_handshake_defragmentation_test(out, side, length, Version.TLS13)
148-
write_tls_handshake_defragmentation_test(out, side, length, Version.TLS12)
177+
write_tls_handshake_defragmentation_test(out, side, length,
178+
Version.TLS13)
179+
if length == 4:
180+
for (cipher_suite, nickname, etm) in \
181+
CIPHERS_FOR_TLS12_HANDSHAKE_DEFRAGMENTATION:
182+
write_tls_handshake_defragmentation_test(
183+
out, side, length, Version.TLS12,
184+
cipher=cipher_suite, etm=etm,
185+
variant=', '+nickname)
186+
else:
187+
write_tls_handshake_defragmentation_test(out, side, length,
188+
Version.TLS12)
149189

150190

151191
def write_handshake_tests(out: typing_util.Writable) -> None:

0 commit comments

Comments
 (0)