Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does the key formatting here mean? The "{cipher, kem_group}" part? Isn't it just:

Suggested change
# (client_{cipher, kem_group}, server_{cipher, kem_group}): {"cipher": {expected_cipher}, "kem_group": {expected_kem_group}}
# (client_cipher, server_cipher): {"cipher": {expected_cipher}, "kem_group": {expected_kem_group}}

Copy link
Contributor Author

@alexw91 alexw91 Jan 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some of them are "Ciphers" (aka s2n Security Policies), others are "KemGroups" (aka AWS-LC/Boring/OpenSSL SupportedGroups).

(Ciphers.PQ_TLS_1_0_2023_01, Ciphers.PQ_TLS_1_0_2023_01) is a (Client_Cipher, Server_Cipher).

(KemGroups.P384_KYBER768R3, Ciphers.PQ_TLS_1_3_2023_06_01) is (Client_KemGroup, Server_Cipher).

(Ciphers.PQ_TLS_1_3_2023_06_01, KemGroups.X25519Kyber768Draft00) is (Client_Cipher, Server_KemGroup).

Copy link
Contributor

@lrstewart lrstewart Jan 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, THAT'S what it's trying to communicate! I wonder if it'd be clearer if it was "client_{policy|kem_group}", or even just "client". Other places in the same notation we're currently using "," as a list, not an "or".

Copy link
Contributor

@lrstewart lrstewart Jan 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Part of the confusion might also come from the fact that both security policies and kem groups are labeled "ciphers". So we're being specific that some ciphers are actually kem groups, but not that the other ciphers are actually security policies, and the same definition also later uses "cipher" as an actual cipher suite.

(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
Loading