Skip to content

Commit

Permalink
Migrate PQ Python code to TLS 1.3 (#4999)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexw91 authored Jan 10, 2025
1 parent 4746f70 commit 1f9f343
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 150 deletions.
12 changes: 0 additions & 12 deletions tests/integrationv2/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,18 +318,6 @@ class Ciphers(object):

KMS_TLS_1_0_2018_10 = Cipher(
"KMS-TLS-1-0-2018-10", Protocols.TLS10, False, False, s2n=True)
KMS_PQ_TLS_1_0_2019_06 = Cipher(
"KMS-PQ-TLS-1-0-2019-06", Protocols.TLS10, False, False, s2n=True, pq=True)
KMS_PQ_TLS_1_0_2020_02 = Cipher(
"KMS-PQ-TLS-1-0-2020-02", Protocols.TLS10, False, False, s2n=True, pq=True)
KMS_PQ_TLS_1_0_2020_07 = Cipher(
"KMS-PQ-TLS-1-0-2020-07", Protocols.TLS10, False, False, s2n=True, pq=True)
PQ_SIKE_TEST_TLS_1_0_2019_11 = Cipher(
"PQ-SIKE-TEST-TLS-1-0-2019-11", Protocols.TLS10, False, False, s2n=True, pq=True)
PQ_SIKE_TEST_TLS_1_0_2020_02 = Cipher(
"PQ-SIKE-TEST-TLS-1-0-2020-02", Protocols.TLS10, False, False, s2n=True, pq=True)
PQ_TLS_1_0_2020_12 = Cipher(
"PQ-TLS-1-0-2020-12", Protocols.TLS10, False, False, s2n=True, pq=True)
PQ_TLS_1_0_2023_01 = Cipher(
"PQ-TLS-1-0-2023-01-24", Protocols.TLS10, False, False, s2n=True, pq=True)
PQ_TLS_1_3_2023_06_01 = Cipher(
Expand Down
161 changes: 23 additions & 138 deletions tests/integrationv2/test_pq_handshake.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,7 @@

CIPHERS = [
None, # `None` will default to the appropriate `test_all` cipher preference in the S2N client provider
Ciphers.KMS_PQ_TLS_1_0_2019_06,
Ciphers.KMS_PQ_TLS_1_0_2020_02,
Ciphers.KMS_PQ_TLS_1_0_2020_07,
Ciphers.PQ_SIKE_TEST_TLS_1_0_2019_11,
Ciphers.PQ_SIKE_TEST_TLS_1_0_2020_02,
Ciphers.KMS_TLS_1_0_2018_10,
Ciphers.PQ_TLS_1_0_2020_12,
Ciphers.PQ_TLS_1_3_2023_06_01,
]

Expand All @@ -32,124 +26,35 @@
]

EXPECTED_RESULTS = {
# The tuple keys have the form (client_{cipher, kem_group}, server_{cipher, kem_group})
(Ciphers.KMS_PQ_TLS_1_0_2019_06, Ciphers.KMS_PQ_TLS_1_0_2019_06):
{"cipher": "ECDHE-RSA-AES256-GCM-SHA384",
"kem": None, "kem_group": None},
(Ciphers.KMS_PQ_TLS_1_0_2019_06, Ciphers.KMS_PQ_TLS_1_0_2020_02):
{"cipher": "ECDHE-RSA-AES256-GCM-SHA384",
"kem": None, "kem_group": None},
(Ciphers.KMS_PQ_TLS_1_0_2019_06, Ciphers.KMS_PQ_TLS_1_0_2020_07):
{"cipher": "ECDHE-RSA-AES256-GCM-SHA384",
"kem": None, "kem_group": None},

(Ciphers.KMS_PQ_TLS_1_0_2020_02, Ciphers.KMS_PQ_TLS_1_0_2019_06):
{"cipher": "ECDHE-RSA-AES256-GCM-SHA384",
"kem": None, "kem_group": None},
(Ciphers.KMS_PQ_TLS_1_0_2020_02, Ciphers.KMS_PQ_TLS_1_0_2020_02):
{"cipher": "ECDHE-RSA-AES256-GCM-SHA384",
"kem": None, "kem_group": None},
(Ciphers.KMS_PQ_TLS_1_0_2020_02, Ciphers.KMS_PQ_TLS_1_0_2020_07):
{"cipher": "ECDHE-RSA-AES256-GCM-SHA384",
"kem": None, "kem_group": None},

(Ciphers.KMS_PQ_TLS_1_0_2020_07, Ciphers.KMS_PQ_TLS_1_0_2019_06):
{"cipher": "ECDHE-RSA-AES256-GCM-SHA384",
"kem": None, "kem_group": None},
(Ciphers.KMS_PQ_TLS_1_0_2020_07, Ciphers.KMS_PQ_TLS_1_0_2020_02):
{"cipher": "ECDHE-RSA-AES256-GCM-SHA384",
"kem": None, "kem_group": None},
(Ciphers.KMS_PQ_TLS_1_0_2020_07, Ciphers.KMS_PQ_TLS_1_0_2020_07):
{"cipher": "ECDHE-KYBER-RSA-AES256-GCM-SHA384",
"kem": "kyber512r3", "kem_group": None},

(Ciphers.PQ_SIKE_TEST_TLS_1_0_2019_11, Ciphers.KMS_PQ_TLS_1_0_2019_06):
{"cipher": "ECDHE-RSA-AES256-GCM-SHA384",
"kem": None, "kem_group": None},
(Ciphers.PQ_SIKE_TEST_TLS_1_0_2019_11, Ciphers.KMS_PQ_TLS_1_0_2020_02):
{"cipher": "ECDHE-RSA-AES256-GCM-SHA384",
"kem": None, "kem_group": None},
(Ciphers.PQ_SIKE_TEST_TLS_1_0_2019_11, Ciphers.KMS_PQ_TLS_1_0_2020_07):
{"cipher": "ECDHE-RSA-AES256-GCM-SHA384",
"kem": None, "kem_group": None},

(Ciphers.PQ_SIKE_TEST_TLS_1_0_2020_02, Ciphers.KMS_PQ_TLS_1_0_2019_06):
{"cipher": "ECDHE-RSA-AES256-GCM-SHA384",
"kem": None, "kem_group": None},
(Ciphers.PQ_SIKE_TEST_TLS_1_0_2020_02, Ciphers.KMS_PQ_TLS_1_0_2020_02):
{"cipher": "ECDHE-RSA-AES256-GCM-SHA384",
"kem": None, "kem_group": None},
(Ciphers.PQ_SIKE_TEST_TLS_1_0_2020_02, Ciphers.KMS_PQ_TLS_1_0_2020_07):
{"cipher": "ECDHE-RSA-AES256-GCM-SHA384",
"kem": None, "kem_group": None},

(Ciphers.KMS_PQ_TLS_1_0_2019_06, Ciphers.KMS_TLS_1_0_2018_10):
{"cipher": "ECDHE-RSA-AES256-GCM-SHA384",
"kem": None, "kem_group": None},
(Ciphers.KMS_PQ_TLS_1_0_2020_02, Ciphers.KMS_TLS_1_0_2018_10):
{"cipher": "ECDHE-RSA-AES256-GCM-SHA384",
"kem": None, "kem_group": None},
(Ciphers.KMS_PQ_TLS_1_0_2020_07, Ciphers.KMS_TLS_1_0_2018_10):
{"cipher": "ECDHE-RSA-AES256-GCM-SHA384",
"kem": None, "kem_group": None},

(Ciphers.KMS_TLS_1_0_2018_10, Ciphers.KMS_PQ_TLS_1_0_2019_06):
{"cipher": "ECDHE-RSA-AES256-GCM-SHA384",
"kem": None, "kem_group": None},
(Ciphers.KMS_TLS_1_0_2018_10, Ciphers.KMS_PQ_TLS_1_0_2020_02):
{"cipher": "ECDHE-RSA-AES256-GCM-SHA384",
"kem": None, "kem_group": None},
(Ciphers.KMS_TLS_1_0_2018_10, Ciphers.KMS_PQ_TLS_1_0_2020_07):
{"cipher": "ECDHE-RSA-AES256-GCM-SHA384",
"kem": None, "kem_group": None},

# The expected kem_group string for this case purposefully excludes a curve;
# depending on how s2n was compiled, the curve may be either x25519 or one
# of the NIST curves.
(Ciphers.PQ_TLS_1_0_2020_12, Ciphers.PQ_TLS_1_0_2020_12):
{"cipher": "TLS_AES_256_GCM_SHA384",
"kem": None, "kem_group": "_kyber-512-r3"},
(Ciphers.PQ_TLS_1_0_2020_12, Ciphers.PQ_TLS_1_0_2023_01):
{"cipher": "TLS_AES_256_GCM_SHA384",
"kem": None, "kem_group": "_kyber-512-r3"},
# The tuple keys have the form:
# (client_{cipher, kem_group}, server_{cipher, kem_group}): {"cipher": {expected_cipher}, "kem_group": {expected_kem_group}}
(Ciphers.PQ_TLS_1_0_2023_01, Ciphers.PQ_TLS_1_0_2023_01):
{"cipher": "TLS_AES_256_GCM_SHA384",
"kem": None, "kem_group": "_kyber-512-r3"},
(Ciphers.PQ_TLS_1_0_2023_01, Ciphers.PQ_TLS_1_0_2020_12):
{"cipher": "TLS_AES_256_GCM_SHA384",
"kem": None, "kem_group": "_kyber-512-r3"},
(Ciphers.PQ_TLS_1_0_2020_12, Ciphers.KMS_PQ_TLS_1_0_2020_07):
{"cipher": "ECDHE-KYBER-RSA-AES256-GCM-SHA384",
"kem": "kyber512r3", "kem_group": None},
(Ciphers.KMS_PQ_TLS_1_0_2020_07, Ciphers.PQ_TLS_1_0_2020_12):
{"cipher": "ECDHE-KYBER-RSA-AES256-GCM-SHA384",
"kem": "kyber512r3", "kem_group": None},
(Ciphers.PQ_TLS_1_0_2020_12, KemGroups.P256_KYBER512R3):
{"cipher": "AES256_GCM_SHA384", "kem": None,
"kem_group": "secp256r1_kyber-512-r3"},
(KemGroups.P256_KYBER512R3, Ciphers.PQ_TLS_1_0_2020_12):
{"cipher": "AES256_GCM_SHA384", "kem": None,
"kem_group": "secp256r1_kyber-512-r3"},
(KemGroups.P256_KYBER512R3, Ciphers.PQ_TLS_1_0_2023_01):
{"cipher": "AES256_GCM_SHA384", "kem": None,
"kem_group": "secp256r1_kyber-512-r3"},
(KemGroups.P256_KYBER512R3, Ciphers.PQ_TLS_1_3_2023_06_01):
{"cipher": "AES256_GCM_SHA384", "kem": None,
"kem_group": "secp256r1_kyber-512-r3"},
"kem_group": "_kyber-512-r3"},
(KemGroups.P384_KYBER768R3, Ciphers.PQ_TLS_1_3_2023_06_01):
{"cipher": "AES256_GCM_SHA384", "kem": None,
"kem_group": "secp384r1_kyber-768-r3"},
{"cipher": "AES256_GCM_SHA384",
"kem_group": "secp384r1_kyber-768-r3"},
(KemGroups.P521_KYBER1024R3, Ciphers.PQ_TLS_1_3_2023_06_01):
{"cipher": "AES256_GCM_SHA384", "kem": None,
"kem_group": "secp521r1_kyber-1024-r3"},
{"cipher": "AES256_GCM_SHA384",
"kem_group": "secp521r1_kyber-1024-r3"},
(Ciphers.PQ_TLS_1_3_2023_06_01, KemGroups.X25519Kyber768Draft00):
{"cipher": "TLS_AES_256_GCM_SHA384",
"kem": None,
"kem_group": "X25519Kyber768Draft00"},
(Ciphers.PQ_TLS_1_3_2023_06_01, KemGroups.SecP256r1Kyber768Draft00):
{"cipher": "TLS_AES_256_GCM_SHA384",
"kem": None,
"kem_group": "SecP256r1Kyber768Draft00"},
(Ciphers.PQ_TLS_1_3_2023_06_01, Ciphers.PQ_TLS_1_3_2023_06_01):
{"cipher": "TLS_AES_256_GCM_SHA384",
"kem_group": "SecP256r1Kyber768Draft00"},
(Ciphers.PQ_TLS_1_3_2023_06_01, Ciphers.KMS_TLS_1_0_2018_10):
{"cipher": "ECDHE-RSA-AES256-GCM-SHA384",
"kem_group": None},
(Ciphers.KMS_TLS_1_0_2018_10, Ciphers.PQ_TLS_1_3_2023_06_01):
{"cipher": "ECDHE-RSA-AES128-GCM-SHA256",
"kem_group": None},
(Ciphers.KMS_TLS_1_0_2018_10, Ciphers.KMS_TLS_1_0_2018_10):
{"cipher": "ECDHE-RSA-AES256-GCM-SHA384",
"kem_group": None},
}

"""
Expand Down Expand Up @@ -185,16 +90,12 @@ def assert_s2n_negotiation_parameters(s2n_results, expected_result):
if expected_result is not None:
assert to_bytes(
("Cipher negotiated: " + expected_result['cipher'])) in s2n_results.stdout
if expected_result['kem']:
assert to_bytes(
("KEM: " + expected_result['kem'])) in s2n_results.stdout
assert to_bytes(PQ_ENABLED_FLAG) in s2n_results.stdout
if expected_result['kem_group']:
# Purposefully leave off the "KEM Group: " prefix in order to perform partial matches
# without specifying the curve.
assert to_bytes(expected_result['kem_group']) in s2n_results.stdout
assert to_bytes(PQ_ENABLED_FLAG) in s2n_results.stdout
if not expected_result['kem'] and not expected_result['kem_group']:
if not expected_result['kem_group']:
assert to_bytes(PQ_ENABLED_FLAG) not in s2n_results.stdout
assert to_bytes("Curve:") in s2n_results.stdout

Expand Down Expand Up @@ -224,22 +125,6 @@ def test_nothing():
@pytest.mark.parametrize("other_provider", [S2N], ids=get_parameter_name)
def test_s2nc_to_s2nd_pq_handshake(managed_process, protocol, certificate, client_cipher, server_cipher, provider,
other_provider):
# Incorrect cipher is negotiated when both ciphers are PQ_TLS_1_0_2020_12 with
# openssl 1.0.2, boringssl, and libressl libcryptos
if all([
client_cipher == Ciphers.PQ_TLS_1_0_2020_12,
server_cipher == Ciphers.PQ_TLS_1_0_2020_12,
any([
libcrypto in get_flag(S2N_PROVIDER_VERSION)
for libcrypto in [
"boringssl",
"libressl",
"openssl-1.0.2"
]
])
]):
pytest.skip()

port = next(available_ports)

client_options = ProviderOptions(
Expand Down Expand Up @@ -267,7 +152,7 @@ def test_s2nc_to_s2nd_pq_handshake(managed_process, protocol, certificate, clien
# If PQ is not enabled in s2n, we expect classic handshakes to be negotiated.
# Leave the expected cipher blank, as there are multiple possibilities - the
# important thing is that kem and kem_group are NONE.
expected_result = {"cipher": "", "kem": None, "kem_group": None}
expected_result = {"cipher": "", "kem_group": None}

# Client and server are both s2n; can make meaningful assertions about negotiation for both
for results in client.get_results():
Expand Down Expand Up @@ -359,7 +244,7 @@ def test_s2nd_to_awslc_pq_handshake(managed_process, s2n_server_policy, awslc_cl

@pytest.mark.uncollect_if(func=invalid_test_parameters)
@pytest.mark.parametrize("protocol", [Protocols.TLS13], ids=get_parameter_name)
@pytest.mark.parametrize("cipher", [Ciphers.PQ_TLS_1_0_2020_12], ids=get_parameter_name)
@pytest.mark.parametrize("cipher", [Ciphers.PQ_TLS_1_3_2023_06_01], ids=get_parameter_name)
@pytest.mark.parametrize("kem_group", KEM_GROUPS, ids=get_parameter_name)
def test_s2nc_to_oqs_openssl_pq_handshake(managed_process, protocol, cipher, kem_group):
# If PQ is not enabled in s2n, there is no reason to test against oqs_openssl
Expand Down Expand Up @@ -401,7 +286,7 @@ def test_s2nc_to_oqs_openssl_pq_handshake(managed_process, protocol, cipher, kem

@pytest.mark.uncollect_if(func=invalid_test_parameters)
@pytest.mark.parametrize("protocol", [Protocols.TLS13], ids=get_parameter_name)
@pytest.mark.parametrize("cipher", [Ciphers.PQ_TLS_1_0_2020_12], ids=get_parameter_name)
@pytest.mark.parametrize("cipher", [Ciphers.PQ_TLS_1_3_2023_06_01], ids=get_parameter_name)
@pytest.mark.parametrize("kem_group", KEM_GROUPS, ids=get_parameter_name)
def test_oqs_openssl_to_s2nd_pq_handshake(managed_process, protocol, cipher, kem_group):
# If PQ is not enabled in s2n, there is no reason to test against oqs_openssl
Expand Down

0 comments on commit 1f9f343

Please sign in to comment.